執行單例項有狀態應用程式
本頁面展示瞭如何使用 PersistentVolume 和 Deployment 在 Kubernetes 中執行單例項有狀態應用。本應用是 MySQL。
目標
- 建立引用環境中磁碟的 PersistentVolume。
- 建立 MySQL Deployment。
- 在叢集中以已知的 DNS 名稱向其他 Pod 暴露 MySQL。
準備工作
你需要擁有一個 Kubernetes 叢集,並且 kubectl 命令列工具已被配置為與你的叢集通訊。建議你在至少有兩個不作為控制平面主機的節點組成的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用這些 Kubernetes 演練場中的一個。
要檢查版本,請輸入
kubectl version
。你需要擁有一個具有預設 StorageClass 的 動態 PersistentVolume 供應器,或者 靜態預配 PersistentVolumes,以滿足此處使用的 PersistentVolumeClaims。
部署 MySQL
你可以透過建立 Kubernetes Deployment 並使用 PersistentVolumeClaim 將其連線到現有的 PersistentVolume 來執行有狀態應用。例如,此 YAML 檔案描述了一個執行 MySQL 並引用 PersistentVolumeClaim 的 Deployment。該檔案定義了 /var/lib/mysql 的卷掛載,然後建立一個尋找 20G 卷的 PersistentVolumeClaim。此宣告由任何滿足要求的現有卷或動態供應器滿足。
注意:密碼在 config yaml 中定義,這是不安全的。有關安全解決方案,請參閱 Kubernetes Secrets。
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:9
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:9 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 訪問資料庫。Service 選項 clusterIP: None
允許 Service DNS 名稱直接解析到 Pod 的 IP 地址。當你只有一個 Pod 在 Service 後面並且不打算增加 Pod 的數量時,這是最佳選擇。
執行 MySQL 客戶端連線到伺服器
kubectl run -it --rm --image=mysql:9 --restart=Never mysql-client -- mysql -h mysql -ppassword
此命令在叢集中建立一個執行 MySQL 客戶端的新 Pod,並透過 Service 將其連線到伺服器。如果連線成功,你就知道你的有狀態 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>
更新
可以使用 kubectl apply
命令像往常一樣更新 Deployment 的映象或任何其他部分。以下是一些有狀態應用特有的注意事項:
- 不要擴縮應用。此設定僅適用於單例項應用。底層的 PersistentVolume 只能掛載到一個 Pod。對於叢集有狀態應用,請參閱 StatefulSet 文件。
- 在 Deployment 配置 YAML 檔案中使用
strategy:
type: Recreate
。這會指示 Kubernetes 不要 使用滾動更新。滾動更新將不起作用,因為你不能同時執行多個 Pod。Recreate
策略將在建立具有更新配置的新 Pod 之前停止第一個 Pod。
刪除 Deployment
按名稱刪除已部署的物件
kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv-volume
如果你手動預配了 PersistentVolume,還需要手動刪除它並釋放底層資源。如果你使用了動態供應器,它會在你刪除 PersistentVolumeClaim 時自動刪除 PersistentVolume。一些動態供應器(例如 EBS 和 PD 的供應器)在刪除 PersistentVolume 時也會釋放底層資源。
下一步
瞭解更多關於 Deployment 物件 的資訊。
瞭解更多關於 部署應用 的資訊。