Table of Contents
- Fundamental k8 objects
- K9s GUI tool
- Kubectl cli tool
- Helm Charts
See also https://kubernetes.io/
# Fundamental k8 objects
- k8s is all about managing pods.
- A Pod can encapsulate multiple running containers and volumes
# Replica Set
Contains Pod replicas for redundancy.
This is the application. They contain the replica sets. Replica sets contain the pods. Deployments contain the scalability and availability configurations.
- 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.
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.
A web interface for managing the k8 cluster. You get this with minikube.
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-resourcesto 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 yamlThis is super useful with
> my_resource.ymlto quickly create yamls.
# 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
See https://github.com/sandervanvugt/kubernetes for examples
# 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:
statusand 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)
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
API objects use labels to connect to other objects
- 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
kubensfor switching between namespaces.
Secret values are Base64 encoded in the yamls/config but plain text in the containers.
Most likely I’ll be working with private container registries. To specify a private registry and auth details:
docker-registrysecret. 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
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:
Create a secret from a file, like a .env file with key value pairs:
kubectl create secret generic env-secrets --from-env-file=.env
Then just reference the secret using the
containers: - name: nginx image: nginx:latest envFrom: - secretRef: name: env-secrets
Pods and Services are the things that has the IP addresses. All the containers within the Pod will share the Pod’s IP address.
- How to running containers within a pod communicate with each other?
# Service object
There’s a bunch of different service types.
- Connects to Pods with labels
targetPortis the exposed port of the containers (the
# LoadBalancer example
Exposing an app.
Create one using
--dry-run. In this example export host 3000 to container
kubectl expose deployment kubetest-web --port=3000 --target-port=3000 --dry-run=client -o yaml > service.yml
minikube. You’ll need to start a tunnel and leave it open:
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.
Create the postgres database deployment. See Secrets above for how to use the
fromEnvproperty. 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
Create the service with the desired port
kubectl expose deployment postgres --port=5432 --target-port=5432 --dry-run=client -o yaml > service-database.yml
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
- So, now
postgreswill resolve to the postgres database. Just provide that as a
DATABASE_HOSTenv var to your app.
# Persistent Volume Claim
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.
- Create the persistent volume. This could use the host’s storage, NFS, cloud storage, etc.
- Create the persistent volume claim (eg, it claims some amount of the PV volume’s storage).
- Add the volume to the container spec that references the PVC created in step 2.
See examples in https://github.com/apmiller108/kubernetes_rails
ConfigMaps can be mounted as a volume and used to provide configuration files.
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).
Tiltfile can get up an running with
k8s_yaml(['deployment-web.yml', 'deployment-sidekiq.yml']) docker_build('apmiller/imagename, '.') k8s_resource('web', port_forwards='3000')
# Helm Charts
- 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