The Kubernetes Series - Container Images

(Photo by chuttersnap on Unsplash)

The previous post dealt with User and Cluster Roles. Now, let's take a step back and look at how containers are loaded from repositories, whether private or public.

When we create Pods, ReplicaSets or Deployments, we reference a container image for the the resource to build. Let's look at a Pod YAML file again;

apiVersion: v1
kind: Pod
metadata:
 name: my-awesome-app
 labels:
   app: awesome-app
spec:
 containers:
   - name: awesome-app-container
     image: awesome-app

The image key under spec:containers is the reference to our container image file. Container images actually follow the naming convention registry/account-name/repository-name.

If you don't explicitly write the account name, like we did with our awesome-app image above, Kubernetes(and Docker) assumes it to be the same as the repository name –> awesome-app/awesome-app.

Likewise, if you don't supply the registry, Docker/Kubernetes assumes it to be docker.io, Docker's public registry. –> docker.io/awesome-app/awesome-app.

But what if we want to pull an image from a private registry with authentication? Let's have a look;

First we need to save the credentials in a Secret object to make it easier to reference(remember that stored Secret values must be converted to base64 strings first);

apiVersion: v1
kind: Secret
metadata:
  name: private-registry-auth
data:
  docker-server: cmlrcy1yZWdpc3RyeS5jb20K
  docker-username: UmlrTmlldQo=
  docker-password: cmFuZG9tcGFzc3dvcmQK
  docker-email: cmlrbmlldUBnbWFpbC5jb20K
type: kubernetes.io/dockerconfigjson <-- important!

Create it with kubectl create and then you can reference it in your Pod definition file by name.

apiVersion: v1
kind: Pod
metadata:
 name: my-awesome-app
 labels:
   app: awesome-app
spec:
 containers:
   - name: awesome-app-container
     image: riks-registry.com/riks-account/awesome-app
 imagePullSecrets:
 - name: private-registry-auth

Container Security Context

You might want to define a particular Linux user a container should use to launch with, or to give a Pod or container certain Linux capabilities. To do so you would add a Security Context key to your Pod or container(if both are set the container settings will override the Pod).  Security Context on Pods will be applicable to all containers running on it.

To see an example of a User, enter a running Pod and print the processes

kubectl exec-it my-awesome-app sh

then find the user ID of the user you'd like to run as;

id -u Rik

Now you have an integer number as user ID

Let's look at defining Security Context on a Pod level;

apiVersion: v1
kind: Pod
metadata:
 name: my-awesome-app
 labels:
   app: awesome-app
spec:
 securityContext:
   runAsUser: 1010 <-- A linux user on the Pod
   capabilities:
     add: ["NET_ADMIN", "SYS_TIME"]
 containers:
   - name: awesome-app-container
     image: riks-registry.com/riks-account/awesome-app
 imagePullSecrets:
 - name: private-registry-auth

On a container level, it would look like this;

apiVersion: v1
kind: Pod
metadata:
 name: my-awesome-app
 labels:
   app: awesome-app
spec:
   capabilities:
     add: ["NET_ADMIN", "SYS_TIME"]
 containers:
   - name: awesome-app-container
     securityContext:
       runAsUser: 1010 <-- A linux user on the Pod
     image: riks-registry.com/riks-account/awesome-app
 imagePullSecrets:
 - name: private-registry-auth

Conclusion

We had a brief look at how container image references get parsed by Kubernetes and Docker, and how to reference images on a private registry with authentication requirements.

We also looked at some Linux-based Security Context settings possible on Pod files and containers.

The next topic would be about Storage on a cluster.