运行单个实例有状态应用程序
本页面演示了如何在 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 对象。
详细了解 部署应用程序