<p>In a kubernetes I have a container X. I'd like to run a cronjob, that executes a command within a container X.</p>

<p>I have the following idea in mind:</p>

<ol>
<li>run a cronjob using busybox container,</li>
<li><p>from within busybox container execute a script that will:</p>

<ol>
<li>determine the pod name where the execution must happen,</li>
<li><p>run curl, <em>something like</em>:</p>

<pre><code> curl https://35.187.120.184/api/v1/namespaces/my_namespace/pods/my_pod_name/exec?command=my_sh_command&amp;container=my_container_name&amp;stdin=true&amp;stdout=true&amp;tty=true
</code></pre>

<p>Dynamic values here are:</p>

<ul>
<li>my_namespace</li>
<li>my_pod_name</li>
<li>my_sh_command</li>
<li>my_container_name</li>
</ul></li>
</ol></li>
</ol>

<p>I know I should probably use a token to access kubernetes API, but I can't figure out how to obtain / use that token in curl.</p>

<p>Is it possible to do that using <code>curl</code> and kubernetes API? If yes, how?</p>

<hr>

<p>There's a reason I want to do this weird thing. I have a compiled app, that recognizes CLI commands. I want to run a particular CLI command, without the hassle of exposing the CLI via a web-server route, that'd be subsequently accessed via k8s service.</p>

<p>Your general approach (calling the <code>{pod}/exec</code> endpoint on the Kubernetes API from within your container) seems totally valid to me. In general, I see two aspects to consider, here: 1) how to use <code>curl</code> to communicate with the Kubernetes API, and 2) how to authenticate against the API from within a Pod.</p>

<h3>Using <code>curl</code> for Kubernetes API access</h3>

<p>In general, the Kubernetes API is easily callable via <code>curl</code>. However, the <code>exec</code> endpoint is an exception to that rule, since the API server upgrades connections on that endpoint to an SPDY connection, which is not supported by <code>curl</code> (there even is a <a href="https://github.com/kubernetes/kubernetes/issues/24668" rel="nofollow noreferrer">discussion in the Kubernetes issue tracker</a> on that topic). For that reason, I'd recommend using kubectl (as already suggested by @sfgroups) or using one of the client SDKs (like for example, the <a href="https://github.com/kubernetes/client-go" rel="nofollow noreferrer">Go</a> or <a href="https://github.com/kubernetes-incubator/client-python" rel="nofollow noreferrer">Python</a> ones).</p>

<h3>Authenticating <code>exec</code> calls from within a Pod</h3>

<p>If you are using kubectl from within a Pod (or any of the client SDKs, or even curl, for that matter), you will need to authenticate against the API server. For this, your Pod needs to be associated with a <em>Service Account</em>, and that Service Account needs to be authorized to call the <code>/pods/{pod}/exec</code> endpoint. How this works, is largely dependent on your cluster configuration:</p>

<ol>
<li><p>In many cluster configurations, your Pod may have already been associated with a Service Account (with sufficient authorization) by default. In the Pod, you will find the credentials in the <code>/var/run/secrets/kubernetes.io/serviceaccount</code> directory. Both <code>kubectl</code> and the common client SDKs will find this directory automatically, allowing them to "just work" without any additional configuration. Using curl, you will need to extract the authentication token from the <code>token</code> file within that directory and use it in an <code>Authorization: Bearer &lt;token&gt;</code> header.</p>

<p>Your Pod may not have received a Service Account token, if it was created with the <code>automountServiceAccountToken: false</code> property.</p></li>
<li><p>If your cluster is configured <a href="https://kubernetes.io/docs/admin/authorization/rbac/" rel="nofollow noreferrer">to use RBAC</a>, your Pod may still be associated with a Service Account, but that account may not be authorized to execute commands in other Pods. To grant access, you can create your own Role that grants the required rights, and then create a Service Account and a RoleBinding:</p>

<pre><code>kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-exec
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
- apiGroups: [""]
  resources: ["pods/exec]
  verbs: ["create"]
---
kind: ServiceAccount
apiVersion: v1
metadata:
  name: cron
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: cron   
subjects:
- kind: ServiceAccount
  name: cron
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-exec
  apiGroup: rbac.authorization.k8s.io
</code></pre>

<p>Then, use the <code>serviceAccountName: cron</code> attribute in your <a href="https://kubernetes.io/docs/api-reference/v1.8/#podspec-v1-core" rel="nofollow noreferrer">PodSpec</a> to associate your cron runner pod with the newly created Service Account.</p></li>
</ol>
