运行单个实例有状态应用程序
本页面演示了如何在 Kubernetes 中使用 PersistentVolume 和 Deployment 运行单实例有状态应用程序。应用程序是 MySQL。
目标
- 创建引用环境中磁盘的 PersistentVolume。
- 创建 MySQL Deployment。
- 将 MySQL 公开给集群中的其他 Pod,使其可通过已知 DNS 名称访问。
开始之前
您需要一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与您的集群通信。建议在至少有两个节点的集群上运行本教程,这些节点不充当控制平面主机。如果您还没有集群,可以使用 minikube 创建一个,也可以使用以下 Kubernetes 练习场之一
要检查版本,请输入kubectl version
。您需要具有一个 动态 PersistentVolume 提供程序,并具有默认的 StorageClass,或者 静态提供 PersistentVolume 以满足此处使用的 PersistentVolumeClaim。
部署 MySQL
您可以通过创建 Kubernetes Deployment 并使用 PersistentVolumeClaim 将其连接到现有的 PersistentVolume 来运行有状态应用程序。例如,此 YAML 文件描述了一个运行 MySQL 并引用 PersistentVolumeClaim 的 Deployment。该文件为 /var/lib/mysql 定义了一个卷挂载,然后创建一个 PersistentVolumeClaim,它会查找 20G 的卷。此声明会由任何满足要求的现有卷或动态提供程序来满足。
注意:密码是在配置 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: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 访问数据库。Service 选项 clusterIP: None
使 Service DNS 名称直接解析为 Pod 的 IP 地址。当您只有一个 Pod 在 Service 后面并且您不打算增加 Pod 数量时,这是最佳选择。
运行 MySQL 客户端以连接到服务器
kubectl run -it --rm --image=mysql:5.6 --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。
删除部署
按名称删除已部署的对象
kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv-volume
如果您手动提供了一个 PersistentVolume,则您还需要手动将其删除,以及释放底层资源。如果您使用的是动态提供程序,则它会在看到您删除 PersistentVolumeClaim 时自动删除 PersistentVolume。某些动态提供程序(例如 EBS 和 PD 的提供程序)也会在删除 PersistentVolume 时释放底层资源。
下一步
详细了解 Deployment 对象。
详细了解 部署应用程序