Kubernetes Container API

Container from PodSpec

The abstraction of the container is find inside a list of Container objects inside the PodSpec, it means the possibility to create multiple containers in a unique Pod.

// A single application container that you want to run within a pod.
type Container struct {
	// Name of the container specified as a DNS_LABEL.
	Name string `json:"name"`

	// Docker image name.
	// More info: https://kubernetes.io/docs/concepts/containers/images
	Image string `json:"image,omitempty"`

	// Entrypoint array.
	// More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
	Command []string `json:"command,omitempty"`

	// Arguments to the entrypoint.
	// More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
	Args []string `json:"args,omitempty"`

	// Periodic probe of container liveness. Container will be restarted if the probe fails.
	// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
	LivenessProbe *Probe `json:"livenessProbe,omitempty"`

	// Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails.
	// More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
	ReadinessProbe *Probe `json:"readinessProbe,omitempty"`

	// List of ports to expose from the container. Exposing a port here gives
	// the system additional information about the network connections a
	// container uses, but is primarily informational.
	Ports []ContainerPort `json:"ports,omitempty"`

	// List of sources to populate environment variables in the container.
	EnvFrom []EnvFromSource `json:"envFrom,omitempty"`

	// List of environment variables to set in the container.
	Env []EnvVar `json:"env,omitempty"`

	// Compute Resources required by this container.
	// More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
	Resources ResourceRequirements `json:"resources,omitempty"`

	// Pod volumes to mount into the container's filesystem. Cannot be updated.
	VolumeMounts []VolumeMount `json:"volumeMounts,omitempty"`

	// Image pull policy. One of Always, Never, IfNotPresent.
	// More info: https://kubernetes.io/docs/concepts/containers/images#updating-images
	ImagePullPolicy PullPolicy `json:"imagePullPolicy,omitempty"`

	// Security options the pod should run with.
	// More info: https://kubernetes.io/docs/concepts/policy/security-context/
	// More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
	SecurityContext *SecurityContext `json:"securityContext,omitempty"`
}

Image details

Name, image, command and args

The important thing to remeber about command is the equility with CMD from Dockerfile and args being the ENTRYPOINT. Image and name are straightforward. CMD is the default execution of the container and ENTRYPOINT the possible args executed for the CMD.

VolumeMount, SecurityContext

See previous post.

ImagePullPolicy

This is used to set the way the image will be pulled from the registry.

// shouldPullImage returns whether we should pull an image according to
// the presence and pull policy of the image.
func shouldPullImage(container *v1.Container, imagePresent bool) bool {
	if container.ImagePullPolicy == v1.PullNever {
		return false
	}

	if container.ImagePullPolicy == v1.PullAlways ||
		(container.ImagePullPolicy == v1.PullIfNotPresent && (!imagePresent)) {
		return true
	}

	return false
}

On kuberuntime_container.go:startContainer -> EnsureImageExists()

Multi-container

Container design can be split in 3 categories:

  • Sidecar pattern: extends and works with the primary container, detached.
  • Ambassor/Proxy pattern: run additional services together with your main application container but it does so through a proxy.
  • Adaptor pattern: transforms the output of the primary container into the output that fits the standards across apps. Multi-container definition example:
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        app: lab1
      name: busybox
    spec:
      containers:
      - image: busybox
        name: main
      - image: busybox
        name: sidecar

Ports and Probes

readinessProbe

Indicates whether the Container is ready to service requests. If the readiness probe fails, the endpoints controller removes the Pod’s IP address from the endpoints of all Services that match the Pod. The default state of readiness before the initial delay is Failure. If a Container does not provide a readiness probe, the default state is Success.

readinessProbe:
  exec:
    command:
      - cat
      - /tmp/health
  initialDelaySeconds: 5
  periodSeconds: 5

Ports and livenessProbe

Setting the port by name and value, this can be used to test the container via a liveness probe uses an HTTP GET request.

  ports:
  - name: liveness-port
    containerPort: 8080
    hostPort: 8080

  livenessProbe:
    httpGet:
      path: /healthz
      port: liveness-port
    failureThreshold: 1
    periodSeconds: 10

Environment variables

Secrets

See previous post.

ConfigMaps

Set the configMapRef, for a regular environment variable is possible to use env: - name, value.

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: special-config
  restartPolicy: Never
kubectl logs pod

Create the configmap and run the pod.

$ kubectl create configmap special-config --from-literal=var=value
$ kubectl create -f pod.yaml
$ kubectl logs dapi-test-pod
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=dapi-test-pod
SHLVL=1
HOME=/root
var=value

Resources

Each container of a pod can specify one or more of the following:

  • spec.containers[].resources.limits.cpu
  • spec.containers[].resources.limits.memory
  • spec.containers[].resources.limits.hugepages-<size>
  • spec.containers[].resources.requests.cpu
  • spec.containers[].resources.requests.memory
  • spec.containers[].resources.requests.hugepages-<size>

Creating a test pod with correct limits for CPU.

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo
  namespace: cpu-example
spec:
  containers:
  - name: cpu-demo-ctr
    image: vish/stress
    resources:
      limits:
        cpu: "1"
      requests:
        cpu: "0.5"
    args:
    - -cpus
    - "2"

Check the consume of the resource in the node.

$ kubectl describe node
Non-terminated Pods:         (10 in total)
  Namespace                  Name                                          CPU Requests  CPU Limits  Memory Requests  Memory Limits  AGE
  ---------                  ----                                          ------------  ----------  ---------------  -------------  ---
  default                    busybox                                       0 (0%)        0 (0%)      0 (0%)           0 (0%)         30m
  default                    cpu-demo                                      500m (12%)    1 (25%)     0 (0%)           0 (0%)         45s

Tasks

https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/

https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/

https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/

https://kubernetes.io/docs/tasks/debug-application-cluster/debug-init-containers/

https://kubernetes.io/docs/tasks/debug-application-cluster/debug-pod-replication-controller/

https://kubernetes.io/docs/tasks/debug-application-cluster/crictl/

https://kubernetes.io/docs/tasks/debug-application-cluster/determine-reason-pod-failure/

https://kubernetes.io/docs/tasks/debug-application-cluster/get-shell-running-container/

https://kubernetes.io/docs/tasks/access-application-cluster/list-all-running-container-images/

https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/

https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/

https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

https://kubernetes.io/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/

https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/

https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/