執行單一實例有狀態應用程式
本頁說明如何在 Kubernetes 中使用 PersistentVolume 和 Deployment 執行單一實例有狀態應用程式。此應用程式為 MySQL。
目標
- 建立參考您環境中磁碟的 PersistentVolume。
- 建立 MySQL Deployment。
- 在已知的 DNS 名稱將 MySQL 公開給叢集中的其他 Pod。
準備開始
您需要有一個 Kubernetes 叢集,並且必須設定 kubectl 命令列工具以與您的叢集通訊。建議在至少有兩個節點且未充當控制平面主機的叢集上執行本教學課程。如果您還沒有叢集,可以使用 minikube 建立一個,或者您可以使用下列 Kubernetes 實驗環境
若要檢查版本,請輸入kubectl version
。您需要有一個具有預設 StorageClass 的動態 PersistentVolume 佈建器,或者自行靜態佈建 PersistentVolume 以滿足此處使用的 PersistentVolumeClaims。
部署 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
部署 YAML 檔案的 PV 和 PVC
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-pv.yaml
部署 YAML 檔案的內容
kubectl apply -f https://k8s.io/examples/application/mysql/mysql-deployment.yaml
顯示關於 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
列出 Deployment 建立的 Pod
kubectl get pods -l app=mysql
輸出類似於此
NAME READY STATUS RESTARTS AGE mysql-63082529-2z3ki 1/1 Running 0 3m
檢查 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 時釋放底層資源。
下一步
深入了解 Deployment 物件。
深入了解 部署應用程式