Upgrade to Pro — share decks privately, control downloads, hide ads and more …

An Introduction To Kubernetes ☸

An Introduction To Kubernetes ☸

My talk from EuroPython 2021

Markus H

July 28, 2021
Tweet

More Decks by Markus H

Other Decks in Technology

Transcript

  1. @m_holtermann @m_holtermann Cluster Node 1 Node 2 Node 3 Pod

    Pod Pod Pod Pod Pod Pod Pod Pod Pod Pod Pod Pod
  2. @m_holtermann @m_holtermann Cluster Node 1 Node 2 Node 3 Pod

    Pod Pod Pod Pod Pod Pod Pod Pod Pod Pod Pod Pod
  3. @m_holtermann @m_holtermann Cluster Node 1 Node 2 Node 3 Pod

    Container Pod Container Container Pod Container Pod Container Pod Container Pod Container Pod Container Container Pod Container Container Pod Container Container Pod Container Container Pod Container Pod Container Pod Container
  4. @m_holtermann @m_holtermann apiVersion: v1 kind: Namespace metadata: name: myapp $

    kubectl get namespaces NAME STATUS AGE default Active 32d kube-system Active 32d $ kubectl apply -f k8s-namespace.yaml namespace/myapp created $ kubectl get namespaces NAME STATUS AGE default Active 32d kube-system Active 32d myapp Active 5s
  5. @m_holtermann @m_holtermann apiVersion: v1 kind: Pod metadata: name: whoami namespace:

    myapp labels: app.kubernetes.io/instance: whoami spec: containers: - image: traefik/whoami:latest name: whoami ports: - containerPort: 80 name: http protocol: TCP $ kubectl -n myapp get pods No resources found in myapp namespace. $ kubectl apply -f k8s-pod.yaml pod/whoami created $ kubectl -n myapp get pods NAME READY STATUS RESTARTS AGE whoami 1/1 Running 0 8s
  6. @m_holtermann @m_holtermann apiVersion: v1 kind: Service metadata: name: whoami namespace:

    myapp spec: ports: - name: http port: 8080 protocol: TCP targetPort: http selector: app.kubernetes.io/instance: whoami $ kubectl -n myapp get services No resources found in myapp namespace. $ kubectl apply -f k8s-service.yaml service/whoami created $ kubectl -n myapp get services NAME TYPE CLUSTER-IP PORT(S) AGE whoami ClusterIP 10.240.28.82 8080/TCP 2s
  7. @m_holtermann @m_holtermann apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: whoami namespace:

    myapp spec: rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: whoami port: name: http $ kubectl -n myapp get ingress No resources found in myapp namespace. $ kubectl -n myapp apply -f k8s-ingress.yaml ingress.networking.k8s.io/whoami created $ kubectl -n myapp get ingress NAME HOSTS ADDRESS PORTS AGE whoami example.com 80 3s
  8. @m_holtermann @m_holtermann apiVersion: v1 kind: ConfigMap metadata: name: whoami namespace:

    myapp data: WHOAMI_NAME: "Darth Vader" $ kubectl -n myapp get configmaps No resources found in myapp namespace. $ kubectl -n myapp apply -f k8s-configmap.yaml configmap/whoami created $ kubectl -n myapp get configmaps NAME DATA AGE whoami 1 3s apiVersion: v1 kind: Secret metadata: name: whoami namespace: myapp type: Opaque data: a-key: THVrZSwgSSdtIHlvdXIgZmF0aGVyIQo= $ kubectl -n myapp get secrets No resources found in myapp namespace. $ kubectl -n myapp apply -f k8s-secret.yaml secret/whoami created $ kubectl -n myapp get secrets NAME TYPE DATA AGE whoami Opaque 1 3s
  9. @m_holtermann @m_holtermann apiVersion: apps/v1 kind: Deployment ... spec: replicas: 3

    selector: matchLabels: app.kubernetes.io/instance: whoami template: metadata: labels: app.kubernetes.io/instance: whoami spec: containers: - image: traefik/whoami:latest name: whoami env: - name: SOME_SECRET valueFrom: secretKeyRef: name: whoami key: a-key envFrom: - configMapRef: name: whoami ports: - containerPort: 80 name: http protocol: TCP $ kubectl -n myapp get deployments No resources found in myapp namespace. $ kubectl -n myapp apply -f k8s-deployment.yaml deployment.apps/whoami created $ kubectl -n myapp get deployments NAME READY UP-TO-DATE AVAILABLE AGE whoami 3/3 3 3 4s $ kubectl -n myapp get pods NAME READY STATUS RESTART AGE whoami 1/1 Running 0 10m Whoami-66bc5b-jtpjs 1/1 Running 0 23s whoami-66bc5b-pv7kv 1/1 Running 0 23s Whoami-66bc5b-sk2f8 1/1 Running 0 23s
  10. @m_holtermann @m_holtermann --- apiVersion: v1 kind: ConfigMap metadata: name: myapp

    namespace: mynamespace data: ALLOWED_HOSTS: "myapp.com,myapp.mynamespace.svc.cluster.local " --- apiVersion: v1 kind: Secret metadata: name: myapp namespace: mynamespace type: Opaque data: # postgres://user:pw@pgserver:5432/dbname DATABASE_URL: cG9zdGdyZXM6Ly91c2VyOnB3QHBnc2VydmVyOjU0MzIvZGJuYW1l= SECRET_KEY: KzVAYmpkbXhqd2koYjQoeHFrOWwkdCZidjB5QCF4bXpfI2k3PSVlKmhpdnUqdTdmXng=
  11. @m_holtermann @m_holtermann import os import dj_database_url SECRET_KEY = os.environ["SECRET_KEY"] DEBUG

    = os.getenv("DEBUG", "") == "true" ALLOWED_HOSTS = os.getenv("ALLOWED_HOSTS", "").split(",") DATABASES = {"default": dj_database_url. config()}
  12. @m_holtermann @m_holtermann apiVersion: apps/v1 kind: Deployment metadata: name: myapp namespace:

    mynamespace spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name : myapp template: metadata: labels: app.kubernetes.io/name : myapp spec: containers: - envFrom: - configMapRef: name: myapp - secretRef: name: myapp image: path.to.my/docker/image:tag imagePullPolicy : IfNotPresent name: web ports: - containerPort: 8080 name: http protocol: TCP restartPolicy: Always
  13. @m_holtermann @m_holtermann # Dockerfile # ... ENTRYPOINT ["/entrypoint.sh "] CMD

    ["gunicorn", "-b", ":8080", "-w", "4", "--log-level", "INFO", "--access-logfile ", "-", "--error-logfile ", "-", "myapp.wsgi"] # ... # /entrypoint.sh #!/bin/sh set -e cmd="$@" until django-admin dbshell -- --command '\q'; do >&2 echo "Postgres is unavailable - sleeping " sleep 5 done django-admin migrate -v 2 django-admin collectstatic -v 2 --no-input exec $cmd