Skip to main content

Concepts

YAML File

myapp.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo
  namespace: mem-example
spec:
  containers:
  - name: memory-demo-ctr
    image: polinux/stress
    resources:
      requests:
        memory: "100Mi"
      limits:
        memory: "200Mi"
    command: ["stress"]
    args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
# Create a pod by applying a yaml file
kubectl apply -f myapp.yaml

# 建立一個部署用的初始 YAML 格式內容
kubectl create deploy nginx-deployment --image=nginx --dry-run=client -o yaml

Get the complete manifest of the deployed Kubernetes object.

kubectl get deploy nginx -n nginx-demo -o yaml
kubectl get svc <service-name> -n <name-space> -o yaml
kubectl get deployment <deployment-name> -n <name-space> -o yaml

Kubectl Configuration

kubectl version
kubectl cluster-info
kubectl config view
kubectl config view --minify --raw

Namespace & Node (ns)

    Namespace 命名規則:名稱會用於內部的 subdomain,開頭與結尾必須字母數字,不可超過 253 個字元,只能包含小寫字母數字及 hyphen, dot 符號。 
    # Create a namespace mem-example
    kubectl create namespace mem-example
    kubectl get ns
    
    # Check the nodes
    kubectl get nodes
    kubectl describe node

    Pod (po)

    # Create a pod memory-demo
    kubectl apply -f myapp.yaml
    
    # Check the pods
    kubectl get pods
    kubectl get all -A
    kubectl get pod memory-demo --namespace=mem-example
    kubectl get pod memory-demo --output=yaml --namespace=mem-example
    kubectl top pod memory-demo --namespace=mem-example
    kubectl describe pod memory-demo --namespace=mem-example
    # Get a list of pods and the node they run on
    kubectl get po -o=custom-columns=NODE:.spec.nodeName,NAME:.metadata.name
    # Get the name of the containers of a running pod
    kubectl get pod MYPOD -o 'jsonpath={.spec.containers[*].name}'
    
    # Delete a pod
    kubectl delete pod memory-demo --namespace=mem-example
    
    # Run Shell in the Pod
    kubectl exec -it <pod-name> -n <namespace> -- bash
    
    # Attach the pod
    kubectl attach <pod-name> -n <namespace> -i
    
    # Force to delete a pod
    kubectl delete pod <pod-name> --force --grace-period=0
    
    # Copy a file from a pod to a local file
    kubectl cp <namespace>/<pod>:<file_path> <local_file_path>

    Deployment (deploy)

    kubectl get deployments
    kubectl rollout status deployment/nginx-deployment
    kubectl describe deployment <deployment-name>
    
    # Update a new image
    kubectl set image deployment/nginx-deployment nginx=nginx:sometag
    
    # Scale a deployment
    kubectl scale deployment deployment --replicas=X

    Delete a deployment

    NOTE: 刪除 deployment 後,底層的其他相關資源,例如 container, PersistentVolumes, image, kubernetes secrets 仍然存在,必須手動移除。

    # Delete the specified deployment
    kubectl delete deployment <deployment name> --namespace <namespace name>
    
    # Delete all deployments for the specified namespace
    kubectl delete deployment --all --namespace=<namespace name>
    
    # Using yaml file to delete the deployment
    kubectl delete -f blog-deployment-1.yaml -f blog-deployment-2.yaml
    
    # Using label selector
    kubectl get deployment -l app=my-app
    kubectl get all --selector app=[app-label]
    
    kubectl delete deployment -l app=my-app
    kubectl delete all --selector app=[app-label]
    
    # Force-delete a hung deployment
    kubectl delete deployment <deployment-name> --grace-period=0 --force
    kubectl delete replicaset -l app=<label>
    kubectl delete pods -l app=<label>

    Deployment with health-check

      initialDelaySeconds: 

      設定當 service 剛啟動時,要延遲幾秒再開始做 health check

      periodSeconds: 代表每隔幾秒訪問一次,預設值為 10秒 timeoutSeconds: 連線愈時 successThreshold: 可以設置訪問幾次就代表目前 service 還正常運行 failureThreshold: 連線失敗的次數
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: my-deployment
      ...
          spec:
            containers:
            - name: webapp
              image: zxcvbnius/docker-demo
              ports:
              - name: webapp-port
                containerPort: 3000
              livenessProbe:
                httpGet:
                  path: /
                  port: webapp-port
                initialDelaySeconds: 15
                periodSeconds: 15
                timeoutSeconds: 30  
                successThreshold: 1
                failureThreshold: 3

      Secret

        變數的值以 yaml 格式輸出時,會以 base64 編碼顯示。
        # Create a secret as environment variables
        kubectl create secret generic [secret-name] \
          --from-literal=APP_API_KEY='your-api-key' \
          --from-literal=EXTERNAL_SERVICE_API_KEY='your-external-key' \
          -n [your-namespace]

        Pull Docker Images from Private Docker Registries

        # Create
        # Usage: kubectl create secret docker-registry [secret-name] \
        #  --docker-server:[address] \
        #  --docker-username=[username] \
        #  --docker-password=[password] \
        #  -n [namespace]
        
        # For Docker Hub Registry
        kubectl create secret docker-registry dockerhub-pull-secret \
          --docker-server=docker.io \
          --docker-username=yourusername \
          --docker-password='Your-Personal-Key' \
          -n my-devops-prod

        Check the secret

        kubectl get secret [secret-name] -n [namespace] -o yaml
        
        # get the value of a secret (if you have the base64 command available)
        kubectl -n mynamespace get secret MYSECRET -o 'jsonpath={.data.DB_PASSWORD}' | base64 -d 

        字串轉 base64

        # String to Base64
        echo -n 'ThisIsSecretStrings' | base64
        
        # Base64 to String
        echo -n 'VGhpc0lzU2VjcmV0U3RyaW5ncw==' | base64 -d

        secret.yaml

        apiVersion: v1
        kind: Secret
        metadata:
          name: mysql-secret
        type: Opaque
        data:
          db-password: cm9vdHBhc3M=

        deployment.yaml

        apiVersion: apps/v1beta2
        kind: Deployment
        metadata:
          name: mysql-server
        ...
            spec:
              containers:
              - name: mysql
                image: mysql:5.7
                args:
                  - "--ignore-db-dir=lost+found"
                ports:
                - name: mysql-port
                  containerPort: 3306
                env:
                - name: MYSQL_ROOT_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: mysql-secret
                      key: db-password
                volumeMounts:
        ...

        Volume

        PVC

        PersistentVolumeClaim

        kubectl get pvc -n <namespace>
        
        kubectl delete pvc <pvc-name> -n <namespace>

        掛載 node 端的本地磁碟

        apiVersion: v1
        kind: PersistentVolume
        metadata:
          name: ollama-pv
          labels:
            type: local
        spec:
          storageClassName: localvol-ollama
          capacity:
            storage: 10Gi
          accessModes:
            - ReadWriteOnce
          hostPath:
            path: "/mnt/k8svol/ollama"
        
        ---
        apiVersion: v1
        kind: PersistentVolumeClaim
        metadata:
          name: ollama-pvc
          namespace: ollama
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 3Gi
          storageClassName: localvol-ollama

        Label

        常用 Labels:

          app: myapp release: stable, release: qa env: dev, env: prod tier: backend, tier: frontend depart: enginerring, depart: marketing
          # 動態新增標籤
          kubectl label pods <pod-name> <label-key>=<label-value>
          
          # Show labels
          kubectl get pods  --show-labels -n <namespace>
          
          # Remove an existed label 'app=XXXX'
          kubectl label pods <pod-name> app-

          Annotations: 其他註解資訊

          apiVersion: v1
          kind: Pod
          metadata:
            name: my-pod
            labels:
              app: webserver
              tier: backend   
            annotations:
              version: latest
              release_date: 2017/12/28
              contact: zxcvbnius@gmail.com
          spec:
            containers:
          ...

          Service

            nodePort range: 3000 ~ 32767
            # Check service
            kubectl get svc -n <name-space>
            
            # Create a service to expose the port of a pod
            kubectl expose pod <pod-name> --port=<pod-port> --name=<service-name> -n <name-space>
            
            # Create s service to expose a random port of a pod/deploy
            kubectl expose pod <pod-name> --type=NodePort --name=<service-name> -n <name-space>
            kubectl export deploy <deploy-name> --type=NodePort --name=<service-name> -n <name-space>
            
            # Forward a port from a service to a local port
            kubectl port-forward svc/<service-name> <local-port>:<remote-port>

            ConfigMap

              一個 ConfigMap 物件可以存入整個 configuration
              像是 webserver config file, Nginx config file 無需修改 container 程式碼,可以替換不同環境的 Config 統一存放所有的 configuration ConfigMap v.s Secret: 我們可以將機密的資料存在 Secret 中,且 Secret 會將這些值經過 Base64 加密,機密的資料像是 API 或是 database 的密碼;而將非機密但屬於部署面的資料放在 ConfigMap,好比資料庫的 port number 或是 Redis 的 config file。
              # Create from a file
              # kubectl create configmap <configmap-name> --from-file=/path/to/file
              kubectl create configmap redis-config --from-file=my-redis.conf
              kubectl create configmap nginx-conf --from-file=./my-nginx.conf
              
              kubectl get configmap
              kubectl describe configmap <configmap-name>
              
              # Create with a command
              # Usgae: kubectl create configmap <configmap-name> --from-literal=<key>=<value>
              kubectl create configmap mysql-host --from-literal=ip=127.0.0.1

              Apply to pod

              apiVersion: v1
              kind: Pod
              metadata:
                name: apiserver
                labels:
                  app: webserver
                  tier: backend
              spec:
                containers:
                - name: nodejs-app
                  image: zxcvbnius/docker-demo
                  ports:
                  - containerPort: 3000
                - name: nginx
                  image: nginx:1.13
                  ports:
                  - containerPort: 80
                  volumeMounts:
                  - name: nginx-conf-volume
                    mountPath: /etc/nginx/conf.d
                volumes:
                - name: nginx-conf-volume
                  configMap:
                    name: nginx-conf
                    items:
                    - key: my-nginx.conf
                      path: my-nginx.conf

              ResourceQuota

              對特定 namespace 限制 CPU/RAM 使用 

              apiVersion: v1
              kind: ResourceQuota
              metadata:
                name: quota-cpu-mem
              spec:
                hard:
                  requests.cpu: "1"
                  requests.memory: 1Gi
                  limits.cpu: "2"
                  limits.memory: 2Gi
              

              限制物件使用,例如 secrets, services

              apiVersion: v1
              kind: ResourceQuota
              metadata:
                name: object-quotas
                namespace: hellospace
              spec:
                hard:
                  services: "2"
                  services.loadbalancers: "1"
                  secrets: "1"
                  configmaps: "1"
                  replicationcontrollers: "10"

              Apply to the namespace

              kubectl apply -f quota-cpu-mem.yaml -n <namespace>

              Check the resourcequota

              kubectl get resourcequotas -n <namespace>
              
              kubectl describe resourcequotas <resourcequotas-name> -n <namespace>

              Node

              # List nodes
              kubectl get nodes
              kubectl get nodes,pods,deploy -o wide
              
              # Node 維護
              kubectl drain <node-name>
              kubectl drain <node-name> --force
              
              # Node 恢復
              kubectl uncordon <node-name>

              Logs

              kubectl logs -f deployment/<deployment-name> -n <name-space>
              kubectl logs -f pod/<pod-name> -n <name-space>
              kubectl logs -l app=xyz

              環境變數 (env)

              kubectl get deployment your-app-name -n your-namespace-prod -o yaml | grep EXTERNAL_SERVICE_URL
              
              kubectl set env <resource>/<resource-name> --list