Kubernetes - ttulka/technologies GitHub Wiki

kubectl get all   # shows all objects
kubectl get nodes # shows k8s nodes
kubectl delete deployment,services -l app=nginx # bulk delete by label
kubectl cluster-info
kubectl config view

Node (Minion) - a physical or virtual machine.

Cluster - a set of nodes grouped together.

Pod - a basic kind of k8s objects, a group of containers (typically of different kind).

Pods

  • Each pod has a unique IP address in the Kubernetes cluster.
  • Pod can have multiple containers. The containers share the same port space, as such they can communicate via localhost.
  • Containers in a pod share the same volume, same ip, port space, IPC namespace.
kubectl get pods   # lists pods
kubectl get pods -o=wide   # wide output
kubectl get pods -l environment=production,tier=frontend   # by labels
kubectl run mypod --image=myimage   # runs myimage docker container as a pod
kubectl get pods mypod   # shows info about the pod
kubectl describe pod mypod   # describes the pod
kubectl edit pod mypod   # edit currently running config
kubectl exec -it mypod -- sh   # executes 'sh' command on the pod interactively
kubectl logs mypod   # shows log messages for the pod
# pod-definition.yml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    app: myapp
    type: back-end
spec:
  containers:
  - name: myimage-container
    image: myimage
    env:
    - name: MY_VAR
      value: test123
kubectl create -f pod-definition.yml
kubectl delete pod mypod

ReplicaSets

A new recommended alternative to Replication Controllers.

# replicaset.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myreplica
spec:
  selector:
    machLabels:
      app: myapp
  replicas: 3
  template:
    metadata:
      name: mypod
      labels:
        app: myapp
    spec:
      containers:
      - name: myimage-container
        image: myimage
kubectl create -f replicaset.yml
kubectl get replicaset   # shows the set
kubectl describe replicaset myreplica
kubectl get pods   # shows three pods
kubectl edit replicaset myreplica   # edit currently running config
kubectl scale replicaset --replicas=5 myreplica   # scales the replicaset

Deployments

Deployments are ReplicaSets with rolling updates.

  • Seamlesly deploys k8s objects.

The Deployment resource automates the process of moving from one version of the application to the next, with zero downtime and in case of failures, it enables us to quickly roll back to the previous version.

# deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydeployment
spec:
  selector:
    machLabels:
      app: myapp
  replicas: 3
  template:
    metadata:
      name: mypod
      labels:
        app: myapp
    spec:
      containers:
      - name: myimage-container
        image: myimage
kubectl create -f deployment.yml
kubectl get deployments
kubectl scale deployment --replicas=3 mydeployment

Update and Rollout

Rolling update is the default deployment strategy.

kubectl rollout status deployment mydeployment   # status log
kubectl apply -f deployment.yml   # updates deployment
kubectl rollout history deployment mydeployment   # shows revisions
kubectl rollout undo deployment mydeployment   # rollbacks changes
kubectl delete deployment mydeployment   # deletes deployment

Services

Stable network abstraction points that provide TCP and UDP load-balancing across a dynamic set of Pods. Are access points for users.

  • Pods are not meant to be visible from inside the cluster.
  • Services must be used to expose the pods to other services or external users.
  • Services are long-running objects, pods are short-living.

Services do the heavy lifting, of discovering services and load balancing between Pods (instances).

Services bring stable IP addresses and DNS names to the unstable world of Pods.

# service.yml
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  type: NodePort
  ports:
  - targetPort: 80
    port: 80
    nodePort: 30008
  selector:
    app: myapp

Types can be:

  • ClusterIP - only accessible from inside the cluster, not externally.
    • Typical choice for microservices.
  • NodePort - exposed to the ouside world.
    • Typical choice for webapps.

minikube service <service-name> --url prints URL of exposed service.

Ingress

Ingres exposes multiple Services through a single cloud load-balancer.

It creates a LoadBalancer Service, on port 80 or 443, and uses host-based and path-based routing to send traffic to the correct backend Service.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-example
spec:
  ingressClassName: nginx
  rules:
  - host: hello.example.org
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: hello
            port:
              number: 8080
  - host: example.org
    http:
      paths:
      - path: /hello
        pathType: Prefix
        backend:
          service:
            name: hello
            port:
              number: 8080

Networking

Every Pod gets its own IP address. Pods on a Node can communicate with all Pods on all Nodes without NAT.

Containers within a Pod share their network namespaces - including their IP address and MAC address. Containers within a Pod can all reach each other's ports on localhost.

DNS address is assigned to a Pod <service>.<namespace>.svc.cluster.local.

nslookup db
cat /etc/resolv.conf

Namespaces

K8s uses directories for objects.

Namespaces a good way of sharing a single cluster among different departments and environments like DEV, QA, PROD.

kubectl get ns   # shows namespaces
kubectl get po -n kube-system
# permanently save the namespace for commands in the context:
kubectl config set-context --current --namespace=<myns>

DNS is formed from namespaces: <service-name>.<namespace-name>.svc.cluster.local

Low-level resources, such as nodes and persistentVolumes, are not in any namespace:

kubectl api-resources --namespaced=false

Persistent Volumes

PersistentVolume (PV) - Storing data locally in a directory of the host.

# db-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
  labels:
    app: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
      - name: db
        image: postgres:9.4
        volumeMounts:
        - name: db-data
          mountPath: /var/lib/postgresql/data
      volumes:
      - name: db-data
        hostPath:
          path: /mnt/some/dir/data/
          type: DirectoryOrCreate

PersistentVolumeClaim (PVC) - Separate configuration of volumes to be referenced from the deployment.

  • K8s search all volume definitions to satisfy the claim.
  • storageClassName can optionaly be used to select a particular volume.
# db-deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
  labels:
    app: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
      - name: db
        image: postgres:9.4
        volumeMounts:
        - name: db-data
          mountPath: /var/lib/postgresql/data
      volumes:
      - name: db-data
        persistentVolumeClaim:
          claimName: postgres-pvc
# db-storage.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pvc
spec:
  storageClassName: mylocalstorage
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-storage
spec:
  storageClassName: mylocalstorage
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteOnce
  hostPath:
    path: /mnt/some/dir/data/
    type: DirectoryOrCreate

ConfigMaps

Used to store non-confidential data in key-value pairs.

  • Pods can consume ConfigMaps as environment variables, command-line arguments, or as configuration files in a volume.
  • Decouple environment-specific configuration from your container images.
apiVersion: v1
kind: ConfigMap
metadata:
  name: myconfigmap
data:
  # property-like keys; each key maps to a simple value
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"

  # file-like keys
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true

Used in a Pod:

apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]
      env:
        # Define the environment variable
        - name: PLAYER_INITIAL_LIVES # Notice that the case is different here
                                     # from the key name in the ConfigMap.
          valueFrom:
            configMapKeyRef:
              name: myconfigmap         # The ConfigMap this value comes from.
              key: player_initial_lives # The key to fetch.
        - name: UI_PROPERTIES_FILE_NAME
          valueFrom:
            configMapKeyRef:
              name: myconfigmap
              key: ui_properties_file_name
      volumeMounts:
      - name: config
        mountPath: "/config"
        readOnly: true
  volumes:
    # You set volumes at the Pod level, then mount them into containers inside that Pod
    - name: config
      configMap:
        # Provide the name of the ConfigMap you want to mount.
        name: myconfigmap
        # An array of keys from the ConfigMap to create as files
        items:
        - key: "game.properties"
          path: "game.properties"
        - key: "user-interface.properties"
          path: "user-interface.properties"

Kubernetes API

The core of Kubernetes' control plane is the API server. The API server exposes an HTTP API that lets end users, different parts of your cluster, and external components communicate with one another.

kubectl cluster-info
# shows cluster endpoint addresses

kubectl proxy --port 9000 &
# exposes the API on localhost and takes care of authentication

curl http://localhost:9000/api/v1/pods
# call the API

without kubectl proxy:

APISERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
SECRET_NAME=$(kubectl get serviceaccount default -o jsonpath='{.secrets[0].name}')
TOKEN=$(kubectl get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)

curl -k $APISERVER/api -H "Authorization: Bearer $TOKEN"

RBAC (Role-Based Access Control)

Kubernetes is a least-privilege deny-by-default system - all actions are denied by default, it supports only allow-rules.

  • Roles define a set of permissions:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: shield
  name: read-deployments
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "watch", "list"]
  • RoleBindings grant those permissions to users:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-deployments
  namespace: shield
subjects:
- kind: User
  name: sky ### the authenticated user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: read-deployments ### the Role to bind to the user
  apiGroup: rbac.authorization.k8s.io

Roles and RoleBindings are namespaced objects. ClusterRoles and ClusterRoleBindings are cluster-wide objects and apply to all Namespaces.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: tomas
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Custom Resources

Custom resources are extensions of the Kubernetes API.

A resource is an endpoint in the Kubernetes API that stores a collection of API objects of a certain kind; for example, the built-in pods resource contains a collection of Pod objects.

A custom resource is an extension of the Kubernetes API that is not necessarily available in a default Kubernetes installation. It represents a customization of a particular Kubernetes installation.

Kubernetes Operator

The Operator pattern combines custom resources and custom controllers.

A Kubernetes operator is a method of packaging, deploying, and managing a Kubernetes application. A Kubernetes application is both deployed on Kubernetes and managed using the Kubernetes API (application programming interface) and kubectl tooling.

It is a way to run complex stateful applications on Kubernetes with control of their life-cycle.

A Kubernetes operator is an application-specific controller that extends the functionality of the Kubernetes API to create, configure, and manage instances of complex applications on behalf of a Kubernetes user.

An operator is a custom Kubernetes controller that uses custom resources (CR) to manage applications and their components.

Service Catalog

Service Catalog is an extension API that enables applications running in Kubernetes clusters to easily use external managed software offerings, such as a datastore service offered by a cloud provider.

Service Account

A service account provides an identity for processes that run in a Pod.

kubectl get serviceaccounts

A credential (token), certificate bundle, default namespace for the service account is placed into the filesystem of a Pod:

  • /var/run/secrets/kubernetes.io/serviceaccount/token
  • /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
  • /var/run/secrets/kubernetes.io/serviceaccount/namespace
APISERVER=https://kubernetes.default.svc
SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
TOKEN=$(cat ${SERVICEACCOUNT}/token)
CACERT=${SERVICEACCOUNT}/ca.crt

curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api

Every namespace has a default service account resource called default. When not specified, the default service account is assigned to a Pod automatically.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: build-robot
---
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: build-robot

Resources

⚠️ **GitHub.com Fallback** ⚠️