執行單一實例有狀態應用程式

本頁說明如何在 Kubernetes 中使用 PersistentVolume 和 Deployment 執行單一實例有狀態應用程式。此應用程式為 MySQL。

目標

  • 建立參考您環境中磁碟的 PersistentVolume。
  • 建立 MySQL Deployment。
  • 在已知的 DNS 名稱將 MySQL 公開給叢集中的其他 Pod。

準備開始

部署 MySQL

您可以藉由建立 Kubernetes Deployment 並使用 PersistentVolumeClaim 將其連線到現有的 PersistentVolume 來執行有狀態應用程式。例如,此 YAML 檔案描述一個執行 MySQL 並參考 PersistentVolumeClaim 的 Deployment。該檔案為 /var/lib/mysql 定義一個磁碟區掛載點,然後建立一個 PersistentVolumeClaim,尋找 20G 磁碟區。此宣告會由任何符合需求的現有磁碟區或動態佈建器滿足。

注意:密碼定義於組態 yaml 中,這是不安全的。請參閱 Kubernetes 密鑰 以取得安全解決方案。

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
  - port: 3306
  selector:
    app: mysql
  clusterIP: None
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
          # Use secret in real usage
        - name: MYSQL_ROOT_PASSWORD
          value: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mysql-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  1. 部署 YAML 檔案的 PV 和 PVC

    kubectl apply -f https://k8s.io/examples/application/mysql/mysql-pv.yaml
    
  2. 部署 YAML 檔案的內容

    kubectl apply -f https://k8s.io/examples/application/mysql/mysql-deployment.yaml
    
  3. 顯示關於 Deployment 的資訊

    kubectl describe deployment mysql
    

    輸出類似於此

    Name:                 mysql
    Namespace:            default
    CreationTimestamp:    Tue, 01 Nov 2016 11:18:45 -0700
    Labels:               app=mysql
    Annotations:          deployment.kubernetes.io/revision=1
    Selector:             app=mysql
    Replicas:             1 desired | 1 updated | 1 total | 0 available | 1 unavailable
    StrategyType:         Recreate
    MinReadySeconds:      0
    Pod Template:
      Labels:       app=mysql
      Containers:
        mysql:
        Image:      mysql:5.6
        Port:       3306/TCP
        Environment:
          MYSQL_ROOT_PASSWORD:      password
        Mounts:
          /var/lib/mysql from mysql-persistent-storage (rw)
      Volumes:
        mysql-persistent-storage:
        Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
        ClaimName:  mysql-pv-claim
        ReadOnly:   false
    Conditions:
      Type          Status  Reason
      ----          ------  ------
      Available     False   MinimumReplicasUnavailable
      Progressing   True    ReplicaSetUpdated
    OldReplicaSets:       <none>
    NewReplicaSet:        mysql-63082529 (1/1 replicas created)
    Events:
      FirstSeen    LastSeen    Count    From                SubobjectPath    Type        Reason            Message
      ---------    --------    -----    ----                -------------    --------    ------            -------
      33s          33s         1        {deployment-controller }             Normal      ScalingReplicaSet Scaled up replica set mysql-63082529 to 1
    
  4. 列出 Deployment 建立的 Pod

    kubectl get pods -l app=mysql
    

    輸出類似於此

    NAME                   READY     STATUS    RESTARTS   AGE
    mysql-63082529-2z3ki   1/1       Running   0          3m
    
  5. 檢查 PersistentVolumeClaim

    kubectl describe pvc mysql-pv-claim
    

    輸出類似於此

    Name:         mysql-pv-claim
    Namespace:    default
    StorageClass:
    Status:       Bound
    Volume:       mysql-pv-volume
    Labels:       <none>
    Annotations:    pv.kubernetes.io/bind-completed=yes
                    pv.kubernetes.io/bound-by-controller=yes
    Capacity:     20Gi
    Access Modes: RWO
    Events:       <none>
    

存取 MySQL 實例

先前的 YAML 檔案建立一個服務,允許叢集中的其他 Pod 存取資料庫。服務選項 clusterIP: None 讓服務 DNS 名稱直接解析為 Pod 的 IP 位址。當您只有一個 Pod 在服務後方,且不打算增加 Pod 數量時,這是最佳選擇。

執行 MySQL 用戶端以連線到伺服器

kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword

此命令會在叢集中建立一個新的 Pod,執行 MySQL 用戶端,並透過服務將其連線到伺服器。如果連線成功,您就知道有狀態 MySQL 資料庫已啟動並執行中。

Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.

mysql>

更新

映像檔或 Deployment 的任何其他部分都可以像平常一樣使用 kubectl apply 命令更新。以下是一些特定於有狀態應用程式的預防措施

  • 請勿擴充應用程式。此設定僅適用於單一實例應用程式。底層 PersistentVolume 只能掛載到一個 Pod。如需叢集有狀態應用程式,請參閱 StatefulSet 文件
  • 在 Deployment 組態 YAML 檔案中使用 strategy: type: Recreate。這會指示 Kubernetes 「不要」使用滾動更新。滾動更新將無法運作,因為您無法同時執行多個 Pod。Recreate 策略會在建立具有更新組態的新 Pod 之前,停止第一個 Pod。

刪除部署

依名稱刪除已部署的物件

kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv-volume

如果您手動佈建了 PersistentVolume,您也需要手動刪除它,以及釋放底層資源。如果您使用了動態佈建器,當它看到您刪除了 PersistentVolumeClaim 時,它會自動刪除 PersistentVolume。某些動態佈建器 (例如 EBS 和 PD 的佈建器) 也會在刪除 PersistentVolume 時釋放底層資源。

下一步

上次修改時間為 2023 年 8 月 24 日下午 6:38 PST: Use code_sample shortcode instead of code shortcode (e8b136c3b3)