concept

Kubenete Concepts

k8s

Concept Description
Control Plane Responsible for the state of the cluster
Worker node run the containerized application workloads
Pod the smallest deployable units in Kubernetes
A pod hosts one or more containers,
and provides shared storage and networking for them
Control Plane Description
Controller Manager running controllers that manage the state of the cluster
ReplicationController, DeploymentController
Scheduler Scheduling pods onto the worker nodes in the cluster
etcd a distributed key-value store, stores the cluster's persistent state
API Server primary interface between control plane & the rest of the cluster
Worker node Description
kubelet a daemon runs on each worker node, communicating with the control plane
receives the control plane about which pods to run on the node
and ensures that the desired state of the pods is maintained
kube-proxy network proxy runs on each worker node, routing traffic to the correct
pods. provides load balancing for the pods & ensures the traffic is distributed
evenly across the pods
container runtime runs the containers on the worker node, pulling image form registry,
start & stops a container & manage the container's resources

Configuration Type

Container Images

Container Image Supported Architectures
registry.k8s.io/kube-apiserver:v1.27.1 amd64, arm, arm64, ppc64le, s390x
registry.k8s.io/kube-controller-manager:v1.27.1 amd64, arm, arm64, ppc64le, s390x
registry.k8s.io/kube-proxy:v1.27.1 amd64, arm, arm64, ppc64le, s390x
registry.k8s.io/kube-scheduler:v1.27.1 amd64, arm, arm64, ppc64le, s390x
registry.k8s.io/conformance:v1.27.1 amd64, arm, arm64, ppc64le, s390x

Workloads

Using Deployments

Understanding DaemonSets

kubectl create deply daemon --image=nginx --dry-run=client -o yaml > daemon.yml
vim daemon.yml
# change kind to `DaemonSet`, remove replicas & strategy
kubectl apply -f daemon.yaml
kubectl get all

Using StatefulSet

# statefulset.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  minReadySeconds: 10 # by default is 0
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: registry.k8s.io/nginx-slim:0.24
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "standard"
      resources:
        requests:
          storage: 1Gi
kubectl get storageclass
# standard
kubectl apply -f statefulset.yaml

Running individual Pods

Running individual Pods has disadvantages:

Using Init containers

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app.kubernetes.io/name: MyApp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377

Create ConfigMap

kubectl create configmap <map-name> <data-source>
## Create the local directory:
mkdir -p configure-pod-container/configmap/
# Download the sample files into `configure-pod-container/configmap/` directory
wget https://kubernetes.io/examples/configmap/game.properties -O configure-pod-container/configmap/game.properties
wget https://kubernetes.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties
# use properties
kubectl create configmap game-config --from-file=configure-pod-container/configmap/
kubectl describe configmaps game-config
kubectl get configmaps game-config -o yaml
# use env file
kubectl create configmap game-config-env-file --from-env-file=kube/configmap/game-env-file.properties

## literal values
kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm

## delete
kubectl delete configmap

## Define container environment variables with data from multiple ConfigMaps
kubectl create -f https://kubernetes.io/examples/configmap/configmaps.yaml

Create Secret

# use raw data
kubectl create secret generic db-user-pass \
    --from-literal=username=admin \
    --from-literal=password='S!B\*d$zDsb='
# use source files
kubectl create secret generic db-user-pass \
    --from-file=./username.txt \
    --from-file=./password.txt

kubectl get secret db-user-pass -o jsonpath='{.data}'

echo 'UyFCXCpkJHpEc2I9' | base64 --decode

# create a TLS Secret
kubectl create secret tls my-tls-secret \
  --cert=path/to/cert/file \
  --key=path/to/key/file

QoS class

accessModes

Static Pods

Static Pod use cases

kubectl run <staticpodname> --image=nginx --dry-run=client -o yaml > staticpod.yaml
sudo cp staticpod.yaml /etc/kubernetes/manifests/
kubectl get pods -o wide

Managing Node State

Managing Node Services

ps aux | grep kubelet
ps aux | grep containerd
systemctl status kubelet
sudo systemctl stop kubelet
sudo systemctl start kubelet

Scaling Applications

# kubectl scale is used to manually scale Deployment, ReplicaSet, or StatefulSet
kubectl scale deployment myapp --replicas=3
# Alternatively HorizontalPodAutoscaler(HPA) can be used
kubectl autoscale deployment myapp --min=5 --max=10
# HPA is an API resource that manages autoscaling of workloads, it works based on usage statistics that have been gathered by the metrics server
kubectl get hpa

## Demo: Configuring HorizontalPodAutoscaler
# 部署 metrics-server(HPA 依赖它采集 CPU/内存指标)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 编辑 metrics-server,添加启动参数 --kubelet-insecure-tls=true(跳过 kubelet 证书校验,实验环境用)
kubectl edit -n kube-system deploy metrics-server
# 查看各 Pod 的资源使用情况,确认 metrics-server 生效
kubectl top pods
# 创建用于压测的 Deployment
kubectl create deploy webstress --image=nginx
# 配置 HPA:CPU 超过 80% 时扩容,副本数在 2~5 之间
kubectl autoscale deploy webstress --min=2 --max=5 --cpu-percent=80
# 查看 HPA 状态
kubectl get hpa
# 查看 Deployment 副本变化
kubectl get deploy webstress
behavior:
  scaleDown:
    stabilizationWindowSeconds: 300
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
  scaleUp:
    stabilizationWindowSeconds: 0
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
    - type: Pods
      value: 4
      periodSeconds: 15
    selectPolicy: Max
# /etc/kubernetes/manifests/kube-controller-manager.yaml
spec:
  containers:
  - command:
    - kube-controller-manager
    - --horiontal-pod-autoscaler-downscale-delay=30s

Understanding Multi-container Pods

How to Setup a Sidecar Container for Logging

# sidecar.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sidecar
spec:
  containers:
  - image: busybox
    name: test-container
    volumeMounts:
    - mountPath: /messages
      name: cache-volume
    args:
    - sh
    - -c
    - echo hello > /messages/index.html
  - image: nginx
    name: whatever
    volumeMounts:
    - mountPath: /usr/lib/nginx/html
      name: cache-volume
  volumes:
  - name: cache-volume
    emptyDir:
      sizeLimit: 500Mi

Managing Scheduling

Understanding Scheduling

From Scheduler to Kubelet

Setting Node Preferences

Understanding Affinity and Anti-Affinity

How it Works

Setting Node Affinity

Defining Affinity Labels

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: type
          operator: In
          values:
          - blue
          - green
nodeSelectorTerms:
- matchExpressions:
  - key: storage
    operator: Exists
# pod-with-node-affinity.yaml
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: k8s.gcr.io/pause:2.0
# pod-with-node-antiaffinity.yaml
# kubectl label nodes node01 disktype=ssd
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: NotIn
            values:
            - ssd
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
# redis-with-pod-affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-cache
spec:
  selector:
    matchLabels:
      app: store
  replicas: 3
  template:
    metadata:
      labels:
        app: store
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - store
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: redis-server
        image: redis:3.2-alpine
# web-with-pod-affinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  selector:
    matchLabels:
      app: web-store
  replicas: 3
  template:
    metadata:
      labels:
        app: web-store
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - web-store
            topologyKey: "kubernetes.io/hostname"
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - store
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: web-app

Managing taints and tolerations

Understanding Taints

Understanding Taint Types

Setting Taints

# 添加污点
kubectl taint nodes worker1 key1=value1:NoSchedule
# 移除污点(末尾加 - 表示删除)
kubectl taint nodes worker1 key1=value1:NoSchedule-

Tolerations

kubectl taint nodes worker1 storage=ssd:NoSchedule
tolerations:
- key: "storage"
  operator: "Equal"
  value: "ssd"

Node Conditions and Automatic Taints

Taint & Toleration Demo

kubectl taint nodes worker1 storage=ssd:NoSchedule
kubectl describe nodes worker1
kubectl create deployment nginx-taint --image=nginx
kubectl scale deployment nginx-taint --replicas=3
kubectl get pods -o wide
kubectl create -f taint-toleration.yaml
kubectl create -f taint-toleration2.yaml

Understanding Quota

Understanding LimitRange

Quota Demo

kubectl create quota qtest --hard pods=3,cpu=100m,memory=500Mi --namespace limited
kubectl describe quota --namespace limited
kubectl create deploy nginx --image=nginx:latest --replicas=3 -n limited
kubectl get all -n limited
kubectl describe rs/nginx-xxx -n limited
kubectl set resources deploy nginx --requests cpu=100m,memory=5Mi --limits cpu=200m,memory=20Mi -n limited
kubectl get pods -n limited

Understanding Scheduling Priorities

PriorityClass Demo

kubectl create priorityclass high-priority --value=1000 --description="high priority" --preemption-policy="Never"
kubectl create priorityclass mid-priority --value=125 --description="mid priority" --global-default=true
kubectl run testpod --image=nginx
kubectl get pod testpod -o yaml | grep -B 2 -i priorityclass
kubectl create deploy highprio --image=nginx
kubectl edit deploy highprio
# spec.template.spec.priorityClassName: high-priority

Page Source