Alex's Slip-box

These are my org-mode notes in sort of Zettelkasten style

Kubernetes

:ID: 31929B00-829E-41F3-BEBF-2F5B77B53E35

See also https://kubernetes.io/

# Fundamental k8 objects

# Pods

  • k8s is all about managing pods.
  • A Pod can encapsulate multiple running containers and volumes

# Replica Set

Contains Pod replicas for redundancy.

# Deployment

This is the application. They contain the replica sets. Replica sets contain the pods. Deployments contain the scalability and availability configurations.

# Services

  • Used to expose container ports to other containers and host machine.
  • Can make containers reachable by other containers by name. DNS resolution happens automatically.
  • One type is like a load balancer – it distributes traffic to different pods in a deployment.

# Ingress

For http/https only. It provides URL access to services.

# YAML files

These are used to declare k8 cluster configuration as opposed to using the web interface or cli.

# Dashboard

A web interface for managing the k8 cluster. You get this with minikube.

minikube dashboard

Otherwise, use kubectl cli tool to manage the cluster.

# K9s GUI tool

Useful tool that provides a TUI (with vim key bindings) for doing comment commands to the cluster that you’d otherwise do using a GUI or CLI. https://k9scli.io/topics/commands/

# Kubectl cli tool

See also my notes/command reference on Kubectl

This is also for managing the k8 cluster.

# Some common commands for getting info

  • kubectl api-resources to see all the different types of resources that can be managed.
  • kubectl explain <object> to see the resource properties. You can drill into properties like kubectl explain pods.specs. This is useful when figuring out what you need when defining YAML files.
  • kubectl describe <resourceType> <resourceName>
  • kubectl get <resourceType> <resourceName> -o yaml This is super useful with --dry-run option and > my_resource.yml to quickly create yamls.

See also https://kubernetes.io/docs/reference/kubectl/cheatsheet/

# Create deployment

One way is to:

kubectl create deployment apache image=httpd

More often you’ll create from a yaml file (more on this below)

kubectl apply -f deployment.ym

# Updates and Rollbacks

Lets say you apply -f deployment.yaml with a newer version of a container image. This will by default be deployed as a rolling update. Then you can see the numbered revision history with:

kubectl rollout history deployment <deploymentName>

It can be rolled back with:

kubectl rollout undo deployment <deploymentName> --to-revision=n

# YAMLs

# Getting started

One easy way to build these yamls is to use the dashboard or cli to build deployments, then “export” the configuration to a yaml file.

kubectl get deployments foo-nginx -o yaml > foo-nginx.yml

There’s a bunch of things that are extraneous and can be deleted from this export:

  • creationTimestamp
  • resourceVersion
  • selfLink
  • uid
  • status and all the stuff nested in it

You can make further changes, delete the previous deployment and re-created it from the yaml file (see below)

# –dry-run

Or use the --dry-run if nothing has been build yet. Dry runs can be exported just the same.

kubectl create deployment mynginx --image=ngnix:1.8 --dry-run=server -o yaml > mynginx_deployment.yml

# Creating stuff from YAML

kubectl apply -f foo-nginx.yml

# Update stuff

Same as creating, use apply -f

# Labels

API objects use labels to connect to other objects

# Namespaces

  • Isolated environments, whereas a Context is a cluster (ie, you have have access to multiple clusters each with multiple namespaces).
  • You can have the same named resource in different namespaces
  • See https://github.com/ahmetb/kubectx for a handy cool kubens for switching between namespaces.

# Secrets

Secret values are Base64 encoded in the yamls/config but plain text in the containers.

# imagePullSecrets

Most likely I’ll be working with private container registries. To specify a private registry and auth details:

  1. create a docker-registry secret. See the docs. Example:

    kubectl create secret docker-registry dockerhub-regcred \
            --docker-server=https://index.docker.io/v1/ \
            --docker-username=USERNAME \
            --docker-password='PASSWORD' \
            --docker-email=EMAIL
    
  2. add the secret to a deployment or a pod

    apiVersion: apps/v1
    kind: Deployment
    spec:
      template:
        spec:
          containers:
          - image: username/someimage:latest
          imagePullSecrets:
            - name: dockerhub-regcred
    

# Environment variables

There are many ways to supply env vars to containers. Here is one:

  1. Create a secret from a file, like a .env file with key value pairs:

    kubectl create secret generic env-secrets --from-env-file=.env
    
  2. Then just reference the secret using the envFrom property

    containers:
      - name: nginx
        image: nginx:latest
        envFrom:
          - secretRef:
              name: env-secrets
    

# Networking

Pods and Services are the things that have IP addresses. All the containers within the Pod will share the Pod’s IP address.

  • How do running containers within a pod communicate with each other?

# Service object

There’s a bunch of different service types.

  • Connects to Pods with labels
  • targetPort is the exposed port of the containers (the containerPort property)

# LoadBalancer example

Exposing an app.

Create one using --dry-run. In this example export host 3000 to container port 3000

kubectl expose deployment kubetest-web --port=3000 --target-port=3000 --dry-run=client -o yaml > service.yml

When using minikube. You’ll need to start a tunnel and leave it open:

minikube tunnel

Then, find the EXTERNAL-IP and ports with kubectl get svc. See also this example.

# Database example

How to connect an app deployment to a database deployment?

Assuming there is a deployment with an app that needs to make a connection to a Postgres database. Also, assumes the Kubernetes DNS cluster addon is running in the cluster.

  1. Create the postgres database deployment. See Secrets above for how to use the fromEnv property. It will be needed to set the postgres user and password.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: postgres
      name: postgres
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: postgres
      template:
        metadata:
          labels:
            app: postgres
        spec:
          containers:
          - image: postgres:12
            name: postgres
            ports:
              - containerPort: 5432
            envFrom:
              - secretRef:
                  name: env-secrets
    
  2. Create the service with the desired port

    kubectl expose deployment postgres --port=5432 --target-port=5432 --dry-run=client -o yaml > service-database.yml
    
  3. Test it out with nslookup. If the K8s DNS cluster is running, you should now be able to use the service name to reach the database.

    kubectl run curl --image=radial/busyboxplus:curl -i --tty
    nslookup postgres
    
  4. So, now postgres will resolve to the postgres database. Just provide that as a DATABASE_HOST env var to your app.

# hostNetwork

spec.template.spec.hostNetwork

# Volumes

# Persistent Volume Claim

When using minikube, it is the host. So, the directory to which the volume is mounted should exist there. So do minikube ssh and sudo mkdir /mydata.

  1. Create the persistent volume. This could use the host’s storage, NFS, cloud storage, etc.
  2. Create the persistent volume claim (eg, it claims some amount of the PV volume’s storage).
  3. Add the volume to the container spec that references the PVC created in step 2.

See examples in https://github.com/apmiller108/kubernetes_rails

# ConfigMap

ConfigMaps can be mounted as a volume and used to provide configuration files.

See https://kubernetes.io/docs/concepts/configuration/configmap/#using-configmaps

# Tilt

Tilt is cool for doing local development against a local or remote K8s cluster. It handles exposing rebuilding the image with code changes and deploying to the cluster automatically. It will also expose resources (ie, a web app reachable from your host machines browser).

A simple Tiltfile can get up an running with tilt up

k8s_yaml(['deployment-web.yml', 'deployment-sidekiq.yml'])

docker_build('apmiller/imagename, '.')

k8s_resource('web', port_forwards='3000')

# Helm Charts

https://helm.sh/docs/intro/install/

  • A package manager for bundled Kubernetes manifests
  • A tar archive in a repo
  • requires the use of a Helm client

# The files

  • chart.yml: metadata about the chart
  • values.yml: key/value pairs
  • templates: yaml manifests that define the application

# Resources

Search Results