Kubernetes

Open Questions

  1. As ConfigMaps are scoped in its namespace, how to have ConfigMaps in multiple namespaces without duplication?
  • One option is using high level of abstraction such as cdk8s

Networking

  • Container

    • Container communicates with another container in the same Pod over localhost.
    • As a Pod behaves like a virtual host, containers behave like applications, containers of the same Pod can't listen on the same port.
    • By default, containers can use a port of the Pod without explicitly specifying it, and po.spec.containers.ports.containerPort is only documentation.
    • Container crashes and restarts doesn't change Pod's IP address.
  • Pod

    • Each Pod has its own network namespace (opens in a new tab), behaving as if a virtual host.

    • A Pod gets assigned an IP address (ClusterIP) on creation and loses it on deletion.

    • Pod to Pod communication

      • Same cluster: use cluster IP Pod or Service
      • Different cluster: use Service
  • Port

    • po.spec.containers.ports.containerPort

      • Informational purpose, specifying which port of the Pod the container is using.
      • The port being unspecified does not stop it from being published by the container, e.g. nginx uses port 80 on the Pod no matter containerPort: 80 is specified or not.
    • po.spec.containers.ports.hostPort

      • Only bound on nodes that are actually running the Pod
    • svc.spec.ports.nodePort

      • Bound on all nodes
    • svc.spec.ports.port

      • The port of the Service
    • svc.spec.ports.targetPort

      • Should match po.spec.containers.ports.containerPort
      • If unspecified, the value of the svc.spec.ports.port will be used.
  • Resources

Kubernetes Object Manifest

spec

What state you desire for the object

  • selector (opens in a new tab)

    • Start with a ! to exclude a label, such as kubectl get pods -l '!app'
  • initContainers

    • Init containers are always executed before the main application containers, regardless of the definition order in the manifest.
  • spec.containers[].command

    Override the ENTRYPOINT instruction of Dockerfile of the container image

  • spec.containers[].args

    Override the CMD instruction of Dockerfile of the container image

    Two forms of array can be used for command or args.

    1. Array

      Array form needs more typing as every argument has to be quoted, but therefore also supports special characters better.

      args: ["wget", "-O", "-", "google.com"]
    2. List

      • Some arguments of special characters or numbers must be quoted. Rule of thumb: if any argument doesn't contain letter, it needs to be quoted.
      args:
        - wget
        - -O
        - "-"
        - google.com

Kubernetes Resource

Label

List resources with specific labels regardless of values

  • k get po -l environment,tier

  • Equality-based requirement

    kubectl get pods -l environment=production,tier=frontend

  • Set-based requirement

    Must be single-quoted

    kubectl get pods -l 'environment in (production),tier in (frontend)'

  • Two forms can be used together

    kubectl get pods -l 'environment in (production),tier in (frontend)',tier=frontend

Pod

  • Probe

    • Readiness Probe

      • When the probe returns Yes, the Pod will start receiving incoming traffic.
      • A Pod is considered ready when all of its containers are ready.
      • When a Pod is not ready, it is removed from Service load balancers.
    • Liveness Probe

      • When the probe returns No, the Pod will be restarted.
      • Configure initialDelaySeconds when using a liveness probe, as a liveness probe failure causes the Pod to restart. You need to make sure the probe doesn’t start until the app is ready.
    • Startup Probe

      • When the probe returns Yes, Readiness and Liveness probes will be enabled.
      • Only executed at startup
      • The kubelet uses startup probes to know when a container application has started. If such a probe is configured, it disables liveness and readiness checks until it succeeds, making sure those probes don't interfere with the application startup.
  • Node affinity

    • Taints apply to nodes, while affinity rules apply to Pods.

ConfigMap

  • Usage

    • Environment variables for a container

    • Add a file in read-only volume, for the application to read

    • Write code to run inside the Pod that uses the Kubernetes API to read a ConfigMap

      • You have to write code to read the ConfigMap and its data. However, because you're using the Kubernetes API directly, your application can subscribe to get updates whenever the ConfigMap changes, and react when that happens. By accessing the Kubernetes API directly, this technique also lets you access a ConfigMap in a different namespace.
  • Sources

    • Literal values, which are key-value pairs as plain text

      --from-literal=<KEY>=<VALUE>

    • A file that contains key-value pairs and expects them to be environment variables

      --from-env-file=config.env

      Note: A running Pod must be destroyed and recreated for the updated environment variables to take effects.

    • A file with arbitrary contents

      --from-file=config.txt

    • A directory with one or many files

      --from-file=<CONFIG_DIR>

Job

  • job.spec.activeDeadlineSeconds

    The activeDeadlineSeconds applies to the duration of the job, no matter how many Pods are created.

    Once a Job reaches activeDeadlineSeconds, all of its running Pods are terminated and the Job status will become type: Failed with reason: DeadlineExceeded.

  • job.spec.backoffLimit

    Specify the number of retries before considering a Job as failed.

CronJob

Deployment

  • A Deployment ensures a desired state is maintained at any given time.

  • By default, a Deployment is created with a label app=<DEPLOYMENT_NAME>.

  • spec.selector.matchLabels must be the same as spec.template.metadata.labels.

  • Strategies

    • Recreate

      All existing Pods are killed before new ones are created. Successful removal is awaited before any Pod of the new revision is created.

      • + More economical
      • - Downtime
    • RollingUpdate

      • + No downtime
      • - More instances, more costs

PersistentVolume

  • spec.capacity

  • spec.accessModes

    • ReadWriteOnce
    • ReadOnlyMany
    • ReadWriteMany
  • StorageClassName

    Must match that of the intended PersistentVolumeClaim

PersistentVolumeClaim

  • Pods need to claim a PV by using PVC, which states the storage requirements but not the volume implementation.
  • The binding to an appropriate PersistentVolume happens automatically based on the criteria defined in PersistentVolumeClaim manifest.
  • PersistentVolumeClaim serves as the middle layer to decouple Pods and PersistentVolumes

ReplicaSet

  • A ReplicaSet ensures that a specified number of pod replicas are running at any given time.

  • Deployment is preferred over ReplicaSet.

  • Use kubectl scale command to manually scale up and down replicas

ResourceQuota

Secret

  • Create a Secret

    Secret value must be in plain text, kubernetes will encode it with base64.

    • Create a Secret from literal(s)

      • value: unencoded plain text

      • k create secret generic --from-literal=key=value

    • Create a Secret from file(s)

      • key: file name (including extension), can be overridden by explict key

      • value: file content (unencoded plain text)

      • k create secret generic --from-file=file-name

    • Create a Secret from file(s)

      • Similar to creation from files, and all files under the specified directory will be used for creation.

      • k create secret generic --from-file=dir-name

  • Get the contents of a Secret

    k get secret <secret_name> -o jsonpath='{.data}' | jq

  • Get the base64 encoded token:

    kubectl get secret <secret_name> -o yaml

  • Get the base64 decoded token:

    1. kubectl get secret <secret_name> -o yaml

    2. Copy & paste the encoded secret string

    3. Use base64 -d to decode the secret

Ingress

  • Resources

    • IngressClass

      • Usually installed as part of Ingress controller installation, used to register the associated Ingress controller into the cluster.
      • Global resource
    • Ingress

      • Ingress resources define routing rules and config. Will only take effect if Ingress controller is already deployed)
      • Namespaced, and must reside in the namespace where the app that they configure reside.
      • The IP of an Ingress (ing.status.loadBalancer.ingress.ip) is the external IP of the load balancer, therefore the entrypoint.
      • When multiple IngressClass exist or no default IngressClass specified, Ingress must explicitly choose an IngressClass with ing.spec.ingressClassName.
      • ing.spec.rules.host[] specify the FQDN expression which requests are matched against.
  • Ingress controller is essentially a separate Pod/Deployment along with a Service that implements Ingress functionality behind the scene such as routing and proxying.

  • Ingress is able to expose low-numbered ports. Services have been hard-coded not to expose ports lower than 1024.

  • Conflicting Ingress rules will cause Ingress resource not getting IP address.

  • If Ingress resource has no IngressClass, specify one by using ing.spec.ingressClassName. Available IngressClass can be retrieved with k get ingressclass.

Service

  • A Service is an abstraction layer which defines a logical set of Pods and enables external traffic exposure, load balancing and service discovery for those Pods.

  • Type

    • ClusterIP

      Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default value.

      Service option clusterIP: None lets the Service DNS name resolve directly to the Pod's IP address. This is optimal when you have only one Pod behind a Service and you don't intend to increase the number of Pods.

    • NodePort

      A Service of the type NodePort includes the functionality of the type ClusterIP. Traffic is routed from the NodePort to the ClusterIP. Only high ports can be used.

      • Obtain Node IP

        • minikube: minikube ip
    • LoadBalancer

      A Service of the type LoadBalancer includes the functionality of the type NodePort.

      Exposes the Service externally using a cloud provider's load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.

    • ExternalName

      A special type of service without selectors, is used to point to an external DNS server.

      Use of the service returns a CNAME record.

  • Selector

    • Select any Pods having the specified Labels (intersection)
  • DNS (opens in a new tab)

    • Services in Kubernetes expose their endpoint using a common DNS pattern: <Service Name>.<Namespace Name>.svc.cluster.local

    • Normally, the Service name is adequate. If you need to access a Service in another Namespace just use the Service name plus the Namespace name.

    • Service name must be DNS compliant, which is lower case alphanumeric characters or -, start with an alphabetic character, and end with an alphanumeric character.

  • Expose a Service for a Resoruce

    1. Use kubectl expose command, with following flags:

      • --name: a DNS compliant name
      • --type: the type of Service, if not explicitly set, ClusterIP would be used.
      • --port: the Service port
      • --target-port: target port on containers

      Note: the Resource being exposed must already exist

    2. Use kubectl create service <service_name> <service_type> command, with following flags:

      • --tcp=<port>:<targetPort>: the Service port and target port on containers

      and edit the manifest or Resource:

      • spec.selector must be the same as Deployment's spec.selector.matchLabels
  • Resources

EndPoint

  • An EndPoint is created when selector of a Service finds matching Pods, and no EndPoint will be created if no matching Pod exists.
  • An EndPoint IP address is a Pod IP address, meaning traffic will be directed by Service to this Pod.
  • Service controls Endpoint. If an EndPoint is deleted, a new one will be created by Service. If a Service is deleted, the corresponding EndPoint will be deleted too.
  • Use EndPoint to check if the Service has found any matching Pod to serve traffic.

NetworkPolicy

  • Must install a Network Policy provider (opens in a new tab) first for NetworkPolicy to work

  • You can only write rules that allow traffic.

    spec:
      podSelector: {} # empty selector selects all Pods
      ingress: [] # empty array indicates nothing is whitelisted
  • NetworkPolicy are scoped to the namespace they are deployed to, so networkpolicy.spec.podSelector does not select Pods from other namespaces.

  • By default, Pods are non-isolated; they accept traffic from any source. Pods become isolated by having a NetworkPolicy that selects them. Once there is any NetworkPolicy in a Namespace selecting a particular Pod, that Pod will reject any connections that are not allowed by any NetworkPolicy. Other Pods in the namespace that are not selected by any NetworkPolicy will continue to accept all traffic.

  • Network policies do not conflict; they are additive. If any policy or policies select a Pod, the Pod is restricted to what is allowed by the union of those policies' ingress/egress rules. Thus, order of evaluation does not affect the policy result.

ClusterRole & ClusterRoleBinding

  • Both ClusterRole and ClusterRoleBinding are global, not scoped to a namespace
  • ClusterRole via a RoleBinding is also confined to its namespace.
  • ClusterRoleBinding can not reference Roles.
  • ClusterRole can define common permissions expressed in a single namespace when referenced by a RoleBinding. This removes the need to have duplicated Roles in many namespaces.

Role & RoleBinding

  • The permissions can only be given to the resources that are in the same namespace as the Role and the RoleBinding.

  • A RoleBinding can only reference a Role in the same namespace.

  • But subjects of a Role can be from a different namespace.

  • User Impersonation

    kubectl <verb> <resource> --as=<user/serviceaccount>

  • Verify API Access

    kubectl auth can-i <verb> <resource> --as=<user/serviceaccount>

ServiceAccount

  • If not assigned explicitly, a Pod uses the default Service Account. The default Service Account has the same permissions as an unauthenticated user. This means that the Pod cannot view or modify the cluster state nor list or modify any of its resources.

  • Specify a custom Service Account when running a Pod

    kubectl run nginx --image=nginx --serviceaccount=custom

  • The authentication token of Service Account with which a Pod is run can be found at the path /var/run/secrets/kubernetes.io/serviceaccount in the containers.

  • --as global option

    --as=system:serviceaccount:{namespace}:{service-account-name}

StatefulSet

Node

Taint

kubectl

  • kubeconfig (opens in a new tab)

    • A file that is used to configure access to clusters is called a kubeconfig file. This is a generic way of referring to configuration files. It does not mean that there is a file named kubeconfig.
    • kubectl command-line tool uses kubeconfig files to find the information it needs to choose a cluster and communicate with the API server of a cluster.
    • Each context has three parameters: cluster, namespace, and user.
    • By default, the kubectl command-line tool uses parameters from the current context to communicate with the cluster.
  • kubectl [command] [TYPE] [NAME] [flags]

    • command

      • create

        • Not every RESOURCE type is supported to be created from command line. Use -h to check supported RESOURCE.
    • TYPE

      • TYPE is case-insensitive and can be abbreviated, e.g. Pod: po. Use kubectl api-resources for full list of abbreviations.
    • -o wide

      Display extra columns in output, such as IP, NODE, SELECTOR, IMAGES, etc.

  • Use cases

    • Pod

      • Create and run (opens in a new tab) a Pod

        Using run command to create a Pod will assign the Pod a label run=<POD_NAME>.

        • Options

          • --labels

            A comma-separated list of labels to apply to the Pod, eg: --labels="app=hazelcast,env=prod"

          • --port

            The port to expose on the container, equivalent to $.spec.containers[0].ports[0].containerPort in object

          • --env

            • Specify environment variables of the container

              e.g. --env="DNS_DOMAIN=cluster".

            • To specify multiple environment variables use multiple --env options

              e.g. --env="DNS_DOMAIN=cluster" --env="POD_NAMESPACE=default"

          • --command -- <COMMAND> <arg1> ... <argN>

            Start the Pod using a different command

            If --command is present, the first argument follow -- will become command in manifest, and the remaining arguments will become args.

            If --command is absent, the following arguments will become the array of args.

          • --rm

            If true, delete resources created in this command for attached containers.

            Use this option to run a temporary one-off Pod

          • --restart=Never

            By default, --restart=Always, setting it to Never will prevent a Pod from restarting.

  • JSONPath Support

    • Use double quotes to quote text inside JSONPath expressions.
    • Use the range, end operators to iterate lists.
    • Use negative slice indices to step backwards through a list. Negative indices do not "wrap around" a list and are valid as long as -index + listLength >= 0.
    • The $ operator is optional since the expression always starts from the root object by default.
    • The result object is printed as its String() function.
    • JSONPath regular expressions are not supported.

    e.g.

    • -ojsonpath='{range .items[*]}{.metadata.name}{","}{.spec.containers[0].image}{"\n"}{end}'

      range and end defines a loop to iterate all eligible items.

    • -ojsonpath='{range .items[*]}{.metadata.name}{","}{.spec.containers[0].image}{"\n"}{end}'

      Use a JSONPath expression to specify an object field

    • -ojsonpath='{range .items[*]}{.metadata.name}{","}{.spec.containers[0].image}{"\n"}{end}'

      Use any string as delimiter. Also, use line separator at the end of line. String must be double quoted.

  • Resources

kubectl - Cheatsheet

Display the current context

  • k config current-context

or

  • kccc

Switch context

Set the current-context to CONTEXT_NAME in a kubeconfig file

  • k config use[-context] <CONTEXT_NAME>

or

  • kcuc <CONTEXT_NAME>

Describe one or many contexts

  • k config get-contexts

or

  • kcgc

Show merged kubeconfig settings

  • kubectl config view

Get Kubernetes cluster information

  • kubectl cluster-info

List all available Resource types

  • kubectl api-resources

List every instance of every Resource type in a specified Namespace

  • kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -n <NAMESPACE>

List all namespaces

kubectl get ns
# or
kgns

List resources filtered by the specified namespace

  • kubectl get <...RESOURCE> -n <NAMESPACE>

List resources across all namespaces

kubectl get $RESOURCE_TYPE1, $RESOURCE_TYPE2, ... -A

Create a namespace

kubectl create ns $NAMESPACE

Change current namespace

k config set-context --current --namespace=$NAMESPACE

Change current namespace of a specified context

  • kubectl config set-context <CONTEXT_NAME> --namespace=<NAMESPACE>

Delete a namespace

kubectl delete $NAMESPACE

Note: deleting a namespace also deletes all resources in it.

List resources filtered by the specified Label

  • kubectl get all -l <KEY1>=<VALUE1>[,<KEY2>=<VALUE2>]

    kubectl get all -l '<KEY> in (<VALUE1>, <VALUE2>...)'

List Resources with their Labels

  • kubectl get all --show-labels

List Resources with specified Labels as additional columns

  • kubectl get all -L <LABEL_KEY_1>[,<LABEL_KEY_2>...]

Pretty print all Labels of a specified Resource

  • kubectl get <TYPE> <RESOURCE> -o jsonpath='{.items[*].metadata.labels}' | jq

Update existing Label

  • kubectl label <TYPE> <RESOURCE> <KEY1=VALUE1...> --overwrite

Remove existing Label

  • kubectl label <TYPE> <RESOURCE> <KEY_1>-

List resources

  • kubectl get <...RESOURCES>

    e.g. kubectl get <..po,svc|all>

Get specified resource details

  • kubectl describe <RESOURCE_TYPE> <RESOURCE_NAME_PREFIX>

Get documentation for a field in manifest

  • kubectl explain <RESOURCE>[.<FIELD>]...

    • e.g. kubectl explain po.spec.containers.volumeMounts.mountPath

    • e.g. kubectl explain po.spec.containers.envFrom.configMapRef | grep -P '\s+<.+>'

      Print all fields of the specified field.

    • e.g. kubectl explain po.spec --recursive | vim -R -

      Print all fields of the specified field recursively, and open with vim for easier navigation, which should be used as the main manifest reference method.

Print Events of all Resources in the current Namespace

  • kubectl get ev

Update Kubernetes object

  • Use kubectl edit directly update resources

    Set up KUBE_EDITOR before using the command.

    In the event of an error, the changes would be lost.

  • Edit and save local manifest, then use kubectl apply -f <manifest>

    Less directly, but the changes are saved first.

  • Use kubectl patch

  • kubectl replace --force -f <filename>

    Delete and recreate the Resource specified in the manifest

Update annotations

  • kubectl annotate <TYPE> <RESOURCE...> <KEY1>=<VALUE1>...

    e.g. kubectl annotate po pod-1 pod-2 env=dev

Update labels

  • kubectl label <TYPE> <RESOURCE...> <KEY1>=<VALUE1>...

    e.g. kubectl label po pod-1 pod-2 env=dev

Apply all manifests in a directory recursively

  • kubectl apply -R -f <directory>

List all Pods in the current namespace

  • kubectl get po

Get a running Pod's manifest

  • kubectl get po <POD> -o yaml

    Note: -o yaml can also be -oyaml.

Use JSONPath expression to extract information

  • kubectl get po <POD> -o jsonpath='{<JSONPATH_EXPRESSION>}'

Compares the current state of the cluster against the state that the cluster would be in if the manifest was applied

  • kubectl diff -f <manifest>

Print the API objects into manifest file with dry run

  • kubectl run <POD> --image=<IMAGE:TAG> -o yaml --dry-run=client > pod.yaml

Execute a command in the container

  • Options

    • -c

      Specify the container name to run the command in the case of multi-containers

Get logs from a Pod

  • Options

    • --all-containers=true

      Get logs from all containers in the Pod

    • -c

      Specify a container name that you want to retrieve logs from

      This can be omitted by directly appending container name: kubectl logs <POD_NAME> <CONTAINER_NAME>

    • -f

      Specify if the logs should be streamed

Delete a Pod

  • Options

    • --force, false by default

      Force delete a Pod

Run a command one-off

  • kubectl exec <POD> -- <COMMAND> <...args>

Open a shell interactively to a running Pod

  • kubectl exec <POD> -it -- <SHELL>

Attach to a running Pod's main process

  • kubectl attach <POD> -it [-c <CONTAINER>]

    When exiting, the Pod could be completed and restarted.

Copy a file out of a Pod

Path in Pod cannot have leading slash.

  • kubectl cp <POD>:<SRC_PATH> <TARGET_PATH>

    e.g. kubectl cp b3:etc/passwd ./passwd

Forward a port on a Pod to a port on localhost

  • kubectl port-forward <RESOURCE_NAME> <LOCALHOST_PORT>:<SERVICE_PORT/POD_PORT>

List revisions

  • kubectl rollout history deployment <DEPLOYMENT_NAME>

Roll back to a previous revision

  • kubectl rollout undo deployment <DEPLOYMENT_NAME> --to-revision=<REVISION_NUMBER>

Create a Service when running a Pod

  • kubectl run nginx --image=nginx --restart=Never --port=80 --expose

    Note the --expose option

Expose a Service for a specified Resource

  • kubectl expose <RESOURCE_TYPE> <RESOURCE_NAME> --type=LoadBalancer --port 80 --target-port 8080

Configure application resources

  • kubectl set <SUBCOMMAND>

    Append the --record flag to save the kubectl command that is making changes to the resource, because imperative commands do not keep changes.

Update environment variables of a Resource

  • kubectl set env <RESOURCE_TYPE> <RESOURCE_NAME> KEY1=VALUE1 [KEY2=VALUE2] ...

    You cannot change environment variables of a Pod, but you can change that of a Deployment.

List all environment variables across all instances of a Resource type

  • kubectl set env <RESOURCE_TYPE> --all --list

    If you want to inspect a specific instance, replace --all with Resource name.

Update image of a Resource

  • kubectl set image <POD/RC/DEPLOY/RS/DS> <Resource_name> <container_name>=<image>:<tag>

Observability

  • Test connectivity from inside of a container

    kubectl run t --image=busybox -it --rm --restart=Never -- wget -O - <IP:PORT>

Production

  • Challenges

    • Integration with cloud or on-premises infrastructure
    • Management across teams, learning curve

Administration

Kompose

Kustomize

Helm

  • Install

  • Setup

    • helm repo add stable https://charts.helm.sh/stable
  • Repo

  • Cheatsheet

    • Get the list of chart repositories

      helm repo list

    • Search for charts in a repository

      helm search <keyword>

    • List releases

      helm list

    • Install a chart

      helm install <release-name> <chart-name>

    • Download a chart archive without installing it

      helm pull <repo/chart> -d <dir>

  • Pros

    • The grouping of related Kubernetes manifests in a single entity (the chart)
    • Basic templating and value support for Kubernetes manifests
    • Dependency declaration between applications (chart of charts)
    • A registry of available applications to be deployed (Helm repository)
    • A view of a Kubernetes cluster in the application/chart level
    • Management of installation/upgrades of charts as a whole
    • Built-in rollback of a chart to a previous version without running a CI/CD pipeline again
  • Resources

Skaffold

minikube

Access a LoadBalancer Service in minikube cluster from host

  • Run minikube tunnel, and the terminal must stay open.

    This will open connection to LoadBalancer services.

  • Update the Service type to LoadBalancer if not.

  • Run kubectl get svc <service_name>, and use the EXTERNAL-IP to access the service from host.

Getting the IP of minikube node

  • minikube ip

Access Kubernetes Dashboard

  • minikube dashboard

Mount host path to the minikube node

  • minikube mount <source directory>:<target directory>

Access host from within minikube

  • Use domain name host.minikube.internal

Network Policy Provider

  • Calico: minikube start --network-plugin=cni --cni=calico

Shell completion

  • minikube completion <SHELL>

Switch to minikube's Docker daemon

  • eval $(minikube -p minikube docker-env)

Switch back to host Docker daemon

  • eval $(minikube -p minikube docker-env -u)

Push an image to minikube's Docker daemon

  • minikube image load <image>:<tag> [--daemon]

    This avoid the need to download images again.

minikube's Docker daemon

  • minikube runs its own instance of Docker daemon process.

    Use ps -fww -p $(pidof dockerd) to check. While minikube running, there should be 2 dockerd process, one of minikube, the other of Docker engine.

  • Containers started by minikube Docker Daemon can be access from minikube host IP ( Can be retrieved by minikube ip)

    e.g.

    d run --name=jenkins -p 8080:8080 -d jenkins/jenkins:lts-jdk17`
    curl -I http://$(minikube ip):8080

krew

Certifications

CKAD

  • Outline (2021 (opens in a new tab))

    • Application Design and Build – 20%

      • Define, build and modify container images
      • Understand Jobs and CronJobs
      • Understand multi-container Pod design patterns (e.g. sidecar, init and others)
      • Utilize persistent and ephemeral volumes
    • Application Environment, Configuration and Security – 25%

      • Discover and use resources that extend Kubernetes (CRD)
      • Understand authentication, authorization and admission control
      • Understanding and defining resource requirements, limits and quotas
      • Understand ConfigMaps
      • Create & consume Secrets
      • Understand ServiceAccounts
      • Understand SecurityContexts
    • Application Deployment – 20%

      • Use Kubernetes primitives to implement common deployment strategies (e.g. blue/green or canary)
      • Understand Deployments and how to perform rolling updates
      • Use the Helm package manager to deploy existing packages
    • Services and Networking – 20%

      • Demonstrate basic understanding of NetworkPolicies
      • Provide and troubleshoot access to applications via services
      • Use Ingress rules to expose applications
    • Application Observability and Maintenance – 15%

      • Understand API deprecations
      • Implement probes and health checks
      • Use provided tools to monitor Kubernetes applications
      • Utilize container logs
      • Debugging in Kubernetes
  • Shell setup

    • .bashrc

      • alias k=kubectl
      • alias kg='k get'
      • alias kga='kg all'
      • alias kgp='kg po'
      • alias kaf='k apply -f'
      • alias kex='k explain'
      • alias ke='k exec'
      • alias kc='k create'
      • alias kr='k run'
      • alias kd='k describe'
      • alias kl='k logs'
      • alias kdel='k delete'
      • alias kpf='k port-forward'
      • source <(kubectl completion bash)
      • complete -F __start_kubectl k
      • export EDITOR=vim
      • export KUBE_EDITOR=vim
      • export do="--dry-run=client -oyaml"
      • alias v=vim
    • .vimrc

      • se et
      • se ts=2
      • se shiftwidth=2
      • se nopaste
      • se is
      • se hls

Patterns

Multi-container Pods

  • Init container

    po.spec.initContainers defines init containers

  • Adapter

  • Sidecar

  • Ambassador (opens in a new tab)

    • As a proxy, responsible for splitting reads & writes, and sending them on to the appropriate servers
    • Application just needs to open a connection on localhost and find the proxy without any service discovery.
    • Commonly used with databases

Resources