I have a Django app that uses the official Kubernetes client for python and works fine but it only deploys (rightly) public registries.
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 cmd commands for the login and the image pull.. Thanks!
Actually it's pretty easy to do using official Kubernetes Python Client. You need to do two steps:
dockerconfigjson (could be done by command line or using Python client) - you are putting here your credentialsimagePullSecrets so Kubernetes client can pull images from private repositoriesCreate secret of type dockerconfigjson:
Replace <something> with your data.
Command line:
kubectl create secret docker-registry private-registry \
--docker-server=<your-registry-server> --docker-username=<your-name> \
--docker-password=<your-pword> --docker-email=<your-email>
Equivalent in Kubernetes Python Client (remember to pass in secure way variable password, for example check this):
import base64
import json
from kubernetes import client, config
config.load_kube_config()
v1 = client.CoreV1Api()
# Credentials
username = <your-name>
password = <your-pword>
mail = <your-email>
secret_name = "private-registry"
namespace = "default"
# Address of Docker repository - in case of Docker Hub just use https://index.docker.io/v1/
docker_server = <your-registry-server>
# Create auth token
auth_decoded = username + ":" + 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 = {
"auths": {
docker_server: {
"username": username,
"password": password,
"email": mail,
"auth": base64_auth_message
}
}
}
data = {
".dockerconfigjson": base64.b64encode(
json.dumps(cred_payload).encode()
).decode()
}
secret = client.V1Secret(
api_version="v1",
data=data,
kind="Secret",
metadata=dict(name=secret_name, namespace=namespace),
type="kubernetes.io/dockerconfigjson",
)
v1.create_namespaced_secret(namespace, body=secret)
Add this secret into your deployment / pod definition using imagePullSecrets: option
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 yaml file or create pod / deployment manifest directly in the code. I will show both ways. As before, replace <something> with your data.
Example yaml file:
apiVersion: v1
kind: Pod
metadata:
name: private-registry-pod
spec:
containers:
- name: private-registry-container
image: <your-private-image>
imagePullSecrets:
- name: private-registry
In last line we are referring to secret docker-registry created in previous step.
Let's apply this yaml file using Kubernetes Python client:
from os import path
import yaml
from kubernetes import client, config
config.load_kube_config()
v1 = client.CoreV1Api()
config_yaml = "pod.yaml"
with open(path.join(path.dirname(__file__), config_yaml)) as f:
dep = yaml.safe_load(f)
resp = v1.create_namespaced_pod(body=dep, namespace="default")
print("Deployment created. status='%s'" % str(resp.status))
All in Python code - both pod definition and applying process:
from kubernetes import client, config
import time
config.load_kube_config()
v1 = client.CoreV1Api()
pod_name = "private-registry-pod"
secret_name = "private-registry"
namespace = "default"
container_name = "private-registry-container"
image = <your-private-image>
# Create a pod
print("Creating pod...")
pod_manifest= {
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": pod_name
},
"spec": {
"containers": [
{
"name": container_name,
"image": image
}
],
"imagePullSecrets": [
{
"name": 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("Done.")
Sources:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With