<p>I have a Django app that uses the <a href="https://github.com/kubernetes-client/python" rel="nofollow noreferrer">official Kubernetes client for python</a> and works fine but it only deploys (rightly) public registries.</p>
<p>Is there a way to execute a login and then let Kubernetes client pull a private image freely? I wouldn't like to execute direct <code>cmd</code> commands for the login and the image pull.. Thanks!</p>

<p>Actually it's pretty easy to do using official Kubernetes Python Client.  You need to do two steps:</p>
<ul>
<li>create a secret of type <code>dockerconfigjson</code> (could be done by command line or using Python client) - you are putting here your credentials</li>
<li>add this secret into your deployment / pod definition using <code>imagePullSecrets</code> so Kubernetes client can pull images from private repositories</li>
</ul>
<p><strong>Create secret of type <code>dockerconfigjson</code>:</strong></p>
<p>Replace <code>&lt;something&gt;</code> with your data.</p>
<p>Command line:</p>
<pre class="lang-sh prettyprint-override"><code>kubectl create secret docker-registry private-registry \
 --docker-server=&lt;your-registry-server&gt; --docker-username=&lt;your-name&gt; \
 --docker-password=&lt;your-pword&gt; --docker-email=&lt;your-email&gt;
</code></pre>
<p>Equivalent in Kubernetes Python Client (remember to pass in secure way variable <code>password</code>, for example check <a href="https://stackoverflow.com/questions/15209978/where-to-store-secret-keys-django">this</a>):</p>
<pre class="lang-py prettyprint-override"><code>import base64
import json
from kubernetes import client, config

config.load_kube_config()
v1 = client.CoreV1Api()

# Credentials
username = &lt;your-name&gt;
password = &lt;your-pword&gt;
mail = &lt;your-email&gt;
secret_name = &quot;private-registry&quot;
namespace = &quot;default&quot;

# Address of Docker repository - in case of Docker Hub just use https://index.docker.io/v1/
docker_server = &lt;your-registry-server&gt;

# Create auth token
auth_decoded = username + &quot;:&quot; + password
auth_decoded_bytes = auth_decoded.encode('ascii')
base64_auth_message_bytes = base64.b64encode(auth_decoded_bytes)
base64_auth_message = base64_auth_message_bytes.decode('ascii')

cred_payload = {
    &quot;auths&quot;: {
        docker_server: {
            &quot;username&quot;: username,
            &quot;password&quot;: password,
            &quot;email&quot;: mail,
            &quot;auth&quot;: base64_auth_message
        }
    }
}

data = {
    &quot;.dockerconfigjson&quot;: base64.b64encode(
        json.dumps(cred_payload).encode()
    ).decode()
}

secret = client.V1Secret(
    api_version=&quot;v1&quot;,
    data=data,
    kind=&quot;Secret&quot;,
    metadata=dict(name=secret_name, namespace=namespace),
    type=&quot;kubernetes.io/dockerconfigjson&quot;,
)

v1.create_namespaced_secret(namespace, body=secret)
</code></pre>
<p><strong>Add this secret into your deployment / pod definition using <code>imagePullSecrets</code>: option</strong></p>
<p>Now, let's move to using newly created secret - depends how you want to deploy pod / deployment in Python code there are two ways:  apply <code>yaml</code> file or create pod / deployment manifest directly in the code. I will show both ways. As before, replace <code>&lt;something&gt;</code> with your data.</p>
<p>Example <code>yaml</code> file:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Pod
metadata:
  name: private-registry-pod
spec:
  containers:
  - name: private-registry-container
    image: &lt;your-private-image&gt;
  imagePullSecrets:
  - name: private-registry
</code></pre>
<p>In last line we are referring to secret <code>docker-registry</code> created in previous step.</p>
<p>Let's apply this <code>yaml</code> file using Kubernetes Python client:</p>
<pre><code>from os import path
import yaml
from kubernetes import client, config

config.load_kube_config()
v1 = client.CoreV1Api()

config_yaml = &quot;pod.yaml&quot;

with open(path.join(path.dirname(__file__), config_yaml)) as f:
        dep = yaml.safe_load(f)
        resp = v1.create_namespaced_pod(body=dep, namespace=&quot;default&quot;)
        print(&quot;Deployment created. status='%s'&quot; % str(resp.status))
</code></pre>
<p>All in Python code -  both pod definition and applying process:</p>
<pre class="lang-py prettyprint-override"><code>from kubernetes import client, config
import time

config.load_kube_config()
v1 = client.CoreV1Api()

pod_name = &quot;private-registry-pod&quot;
secret_name = &quot;private-registry&quot;
namespace = &quot;default&quot;
container_name = &quot;private-registry-container&quot;
image = &lt;your-private-image&gt;

# Create a pod
print(&quot;Creating pod...&quot;)

pod_manifest= {
  &quot;apiVersion&quot;: &quot;v1&quot;,
  &quot;kind&quot;: &quot;Pod&quot;,
  &quot;metadata&quot;: {
    &quot;name&quot;: pod_name
  },
  &quot;spec&quot;: {
    &quot;containers&quot;: [
      {
        &quot;name&quot;: container_name,
        &quot;image&quot;: image
      }
    ],
    &quot;imagePullSecrets&quot;: [
      {
        &quot;name&quot;: secret_name
      }
    ]
  }
}

resp = v1.create_namespaced_pod(body=pod_manifest, namespace=namespace)

# Wait for a pod
while True:
    resp = v1.read_namespaced_pod(name=pod_name, namespace=namespace)
    if resp.status.phase != 'Pending':
        break
    time.sleep(1)
    
print(&quot;Done.&quot;)
</code></pre>
<p>Sources:</p>
<ul>
<li><a href="https://github.com/kubernetes-client/python/issues/501" rel="nofollow noreferrer">Github thread</a></li>
<li><a href="https://stackoverflow.com/questions/56673919/kubernetes-python-api-client-execute-full-yaml-file">Stackoverflow topic</a></li>
<li><a href="https://github.com/kubernetes-client/python/blob/master/examples/pod_exec.py" rel="nofollow noreferrer">Official Kubernetes Python client example</a></li>
<li><a href="https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#inspecting-the-secret-regcred" rel="nofollow noreferrer">Kubernetes docs</a></li>
<li><a href="https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/" rel="nofollow noreferrer">Another Kubernetes docs</a></li>
<li><a href="https://github.com/kubeflow/kubeflow/issues/1748" rel="nofollow noreferrer">Github topic</a></li>
</ul>
