<p>I'm pretty new to Kubernetes/Dockers and planning to create a simple Python pod
that runs on a cluster and maps the cluster nodes and pods in a constant interval (for example once a day).</p>
<p>I'm planning to do it using the Kubernetes Python client which have easy access to the kube-apiserver.</p>
<p>What things I need to configure to be able to achieve it?</p>

<p><strong>Kubernetes user creation :</strong></p>
<ol>
<li>Create a service account  [ To access the kube-apiserver from inside a container ]</li>
</ol>
<pre class="lang-bash prettyprint-override"><code>$ kubectl create serviceaccount sampleuser
serviceaccount/sampleuser created
</code></pre>
<ol start="2">
<li>create a clusterrolebinding linking service account created in step #1 to cluster role called cluster-admin:</li>
</ol>
<pre><code>$ kubectl create clusterrolebinding sampleuserrolebinding  --clusterrole=cluster-admin --serviceaccount=default:sampleuser
clusterrolebinding.rbac.authorization.k8s.io/sampleuserrolebinding created
</code></pre>
<p><strong>Creating a python container :</strong></p>
<ol>
<li>create a file called &quot;requirements.txt&quot; and add &quot;kubernetes&quot; in it:</li>
</ol>
<pre><code>$ cat requirements.txt
kubernetes
</code></pre>
<ol start="2">
<li>Check Following <a href="https://github.com/kubernetes-client/python/blob/master/examples/remote_cluster.py" rel="nofollow noreferrer">sample program</a> change the IP Address to your cluster IP and save the file as program.py. Modify following 2 lines</li>
</ol>
<pre><code>aToken =  open('/var/run/secrets/kubernetes.io/serviceaccount/token','r').read()
aConfiguration.host = &quot;https://&lt;maternode IP&gt;:6443&quot;
</code></pre>
<ol start="3">
<li>create Dockerfile with following contents :</li>
</ol>
<pre><code>FROM python:alpine3.7
WORKDIR /app
COPY requirements.txt .
COPY program.py
RUN pip install -r requirements.txt
CMD python ./program.py
</code></pre>
<ol start="4">
<li>Build and push the image :</li>
</ol>
<pre><code>$ docker build -t sample .

Sending build context to Docker daemon   46.8MB
Step 1/6 : FROM python:alpine3.7
alpine3.7: Pulling from library/python
...
Successfully built e98cea8cb850
Successfully tagged sample:latest
</code></pre>
<pre><code>$ docker image ls 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample              latest              e98cea8cb850        2 minutes ago       126MB
python              alpine3.7           00be2573e9f7        21 months ago       81.3MB 
</code></pre>
<pre><code>$ docker tag e98cea8cb850 prasasai/sample
</code></pre>
<pre><code>$ docker push prasasai/sample
The push refers to repository [docker.io/prasasai/sample]
515f285319c0: Pushed 
b39d02c0a6c7: Pushed 
3c22209f875e: Pushed 
2ea55fcfd611: Pushed 
5fa31f02caa8: Mounted from library/python 
88e61e328a3c: Mounted from library/python 
9b77965e1d3f: Mounted from library/python 
50f8b07e9421: Mounted from library/python 
629164d914fc: Mounted from library/python 
latest: digest: sha256:93c7317f966fa723e406932221f0f1563243eba603c79fba2e113362cc22b4d8 size: 2200
</code></pre>
<p><strong>Writing a Pod Manifest , running and checking logd to see the output :</strong></p>
<pre><code>$ cat samplepod.yaml
---
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
spec:
  containers:
  - image: prasasai/sample
    name: samplepod
  serviceAccountName: sampleuser
</code></pre>
<pre><code>$ kubectl apply -f samplepod.yaml
pod/samplepod created
</code></pre>
<pre><code>$ kubectl logs samplepod
Listing pods with their IPs:
192.168.67.65   default first-6fb86b947d-68zzz
192.168.67.66   default first-6fb86b947d-74vtf
192.168.121.1   default first-6fb86b947d-hb6l6
192.168.121.2   default first-6fb86b947d-rlqk9
192.168.67.67   default first-6fb86b947d-tdnbf
192.168.121.6   default hello-bd5c66899-8dchl
192.168.121.4   default hello-bd5c66899-9ssrc
192.168.121.5   default hello-bd5c66899-pjk7k
192.168.67.68   default hello-bd5c66899-pwpsm
192.168.67.69   default hello-bd5c66899-whjdt
192.168.121.7   default samplepod
192.168.67.75   default test1
</code></pre>
<p><strong>To meet your requirement ( periodically running this pod) , we can create a cronJob (Following runs once after one minute)</strong></p>
<pre><code>$ cat samplecron.yaml
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: sample-job
spec:
  jobTemplate:
    metadata:
      name: sample-job
    spec:
      template:
        metadata:
        spec:
          containers:
          - image: prasasai/sample
            name: sample-job
          serviceAccountName: sampleuser
          restartPolicy: OnFailure
  schedule: '*/1 * * * *'
</code></pre>
<pre><code>$ kubectl apply -f samplecron.yaml
cronjob.batch/sample-job created

$ kubectl get cronjobs
NAME         SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
sample-job   */1 * * * *   False     0        &lt;none&gt;          8s

$ kubectl get cronjobs
NAME         SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
sample-job   */1 * * * *   False     0        &lt;none&gt;          19s

$ kubectl get cronjobs
NAME         SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
sample-job   */1 * * * *   False     1        25s             40s

</code></pre>
