others-prepare for cks exam with me 14: Container Image Security in Docker and Kubernetes

1. Purpose

In this post, I would continue to write about preparing for the CKS (Certified Kubernetes Security Specialist) exam. I would write my own notes about the exam, and you can refer to these articles to prepare your own.

List of the series of posts:

-prepare for cks exam with me 1: Linux user and group management

-prepare for cks exam with me 2: Linux ssh hardening

-prepare for cks exam with me 3: Linux remove obsolete packages and services

-prepare for cks exam with me 4: Linux kernal hardening

-prepare for cks exam with me 5: Linux UFW(Uncomplicated firewall)

-prepare for cks exam with me 6: Seccomp in Linux, Docker and Kubernetes

-prepare for cks exam with me 7: Apparmor in Linux, Docker and Kubernetes

-prepare for cks exam with me 8: Security context in Kubernetes

-prepare for cks exam with me 9: Admission controllers in Kubernetes

-prepare for cks exam with me 10: Pod security policy in Kubernetes

-prepare for cks exam with me 11: Open policy agent in Kubernetes

-prepare for cks exam with me 12: Secrets in Kubernetes

-prepare for cks exam with me 13: Container runtimes(gvisor/kata containers) in Kubernetes

-prepare for cks exam with me 14: Container Image security in Docker and Kubernetes

-prepare for cks exam with me 15: How to print docker images of all pods in kubernetes

2. Environment

  • CKS
  • Ubuntu System

3. Container image security in Docker and Kubernetes

3.1 What is container image?

A Container image e.g. Docker image is a read-only template that contains a set of instructions for creating a container that can run on the Docker platform. It provides a convenient way to package up applications and preconfigured server environments, which you can use for your own private use or share publicly with other Docker users

image-20210603154819091

A docker image abstracts the apps from its dependencies, you can download/stop/start any container without knowing its dependencies and libraries. That’s the key value of containerization.

3.2 The format of image path in kubernetes

When we define a pod in kubernetes as follows:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
   - image: nginx
     name: nginx

The line about the image:

- image: nginx

is equals to this line:

- image: docker.io/nginx/nginx

The format is:

- image: <repository_address>/<user_account>/<image_name>

If you omit the , then the system would set it as the same value as the

If you omit the , then it's default value is dockerhub.

3.3 How to use private repository with Docker?

If you cannot access Dockerhub from your host, then you can setup a private docker registry , e.g. Harbor, But how to access it from your host?

image-20210603165107931

We should login before using docker push/run/start command:

$ docker login <private-registry>

3.4 Use private docker registry in Kubernetes

If you want to use a private registry in the k8s environment, in addition to specifying the address of the Image in the pod as a private library, you also need to deal with the authentication problem of the private image repository. This is solved by the secret of k8s:

$ kubectl create secret docker-registry myreg —-docker-server= —-docker-username= —-docker-password= —-docker-email=

For example:

$ kubectl create secret docker-registry my-reg-docker \
  --docker-username=tiger \
  --docker-password=pass113 \
  --docker-email=[email protected]

Then we can change the yaml of the pod to use the above secret:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  imagePullSecrets:
    - name: my-reg-docker
  containers:
   - image: nginx
     name: nginx

3.5 Set docker image policy with admission controller in kubernetes

When we sumbit request to kube-apiserver, after authentication and authorization, kubernetes also check the request with a list of admission controllers, which might mutate the request and validate the request ,just as the following picture shows:

image-20210603172245073

The ImagePolicyWebhook would refer to the pocliy server to validate the request, just as the following picture shows:

image-20210603172734814

We can enable the ImagePolicyWebhook as follows:(change the options of kube-apiserver):

—-enable-webhook-plugins=ImagePolicyWebhook
—-admission-control-config-file=xxxx.yaml

In the xxxx.yaml, we should tell it how to connect to the policy server and optionally append the content of the policy:

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: ImagePolicyWebhook
  configuration:
    imagePolicy:
      kubeConfigFile: <path-to-kubeconfig-file>
      allowTTL: 50
      denyTTL: 50
      retryBackoff: 200
      defaultAllow: true

3.6 Scan the yaml of kubernetes with kubesec

Kubesec is a tool that can do security risk analysis for Kubernetes resources.

We can scan the deployment yamls as follows:

 $ kubesec scan k8s-deployment.yaml
 
 [
  {
    "object": "Pod/security-context-demo.default",
    "valid": true,
    "message": "Failed with a score of -30 points",
    "score": -30,
    "scoring": {
      "critical": [
        {
          "selector": "containers[] .securityContext .capabilities .add == SYS_ADMIN",
          "reason": "CAP_SYS_ADMIN is the most privileged capability and should always be avoided"
        }
      ],
      "advise": [
        {
          "selector": "containers[] .securityContext .runAsNonRoot == true",
          "reason": "Force the running image to run as a non-root user to ensure least privilege"
        },
        {
          // ...
        }
      ]
    }
  }
]

3.7 Scan the docker image by using trivy

Trivy is a comprehensive and easy-to-use open source vulnerability scanner for container images. Unlike other open source scanners, Trivy covers both OS packages and language-specific dependencies and is extremely easy to integrate into organizations’ software development pipelines

You can use trivy (from aqua security) to scan images or other components, as shown below, to save only high-level vulnerability information.

$ trivy image -o /root/output.txt -s HIGH python:3.7.12-alpine3.11

Or scan tarball file and output the result as json as follows:

$ trivy image --input myimage.tar --format json --output /root/output.json

4. Summary

In this post, I write some examples about container image security(private registry/trivy/kubesec) in Docker and Kubernetes.