导读:
kubernetes集群搭建其实仅仅是第一步,不是为了部署而部署,当然是需要实战使用啦。在实际的生产活动中和测试活动中,kubernetes的使用是不相同的,本文试图从一个贴近实际的生产活动来讲述如何优雅的,正确的使用kubernetes。
部署前的相关知识简介:
由于是单实例的MySQL,因此,本文暂时不使用StatefulSet.。
StatefulSet的简介
在本文中,我们将在Kubernetes中部署数据库,因此我们必须了解什么是StatefulSet。是用于管理有状态应用程序的工作负载。它管理一组Pod的实现和扩展,并保证这些Pod的顺序和唯一性。
像Deployment一样,StatefulSet也管理具有相同容器规范的一组Pod。由StatefulSets维护的Pod具有唯一的,持久的身份和稳定的主机名,而不用管它们位于哪个节点上。如果我们想要一个跨存储的持久性,我们可以创建一个持久性卷并将StatefulSet用作解决方案的一部分。即使StatefulSet中的Pod容易发生故障,存储卷与新Pod进行匹配也很容易。
StatefulSet对于需要以下一项或多项功能的应用程序很有价值:
- 稳定的唯一网络标识符。
- 稳定,持久的存储。
- 有序,顺畅的部署和扩展。
- 有序的自动滚动更新。
在Kubernetes上部署数据库时,我们需要使用StatefulSet,但是使用StatefulSet有一些局限性:
- 需要使用持久性存储卷为Pod提供存储。
- 删除副本或按比例缩小副本将不会删除附加到StatefulSet的存储卷。存储卷确保数据的安全性。
- StatefulSet当前需要Headless Service 来负责Pod的网络标识。
- 与Deployment 不同,StatefulSet不保证删除StatefulSet资源时删除所有Pod,而Deployment在被删除时会删除与Deployment关联的所有Pod。在删除StateFul之前,你必须将pod副本数量缩小到0 。
实践正文:
一,部署一个使用本地存储卷的单机MySQL
MySQL版本是5.7.23----通常用在测试环境,生产是不允许这样做的哦
这个部署示例将使用最为简单的本地存储,MySQL的相关配置文件和相关账号密码等敏感信息将使用明文存储在资源清单文件内,部署方式为deployment。
(1)StorageClass---存储类
这个可以不使用,因为我们下面将使用的是静态存储:
[root@master mysql]# cat mysql-sc.yaml kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: local-storage provisioner: kubernetes.io/no-provisioner # no-provisioner代表不会自动创建PV,创建PV步骤不可省略 volumeBindingMode: immutable #立刻绑定
(2)pv---存储卷定义
在node2节点,新建目录,mkdir -p /mnt/mysql-data,因为在此文件内做了亲和度调度,指定是在node2存储数据卷。
- volumeMode: Filesystem 这个其实是默认的,可以不写,但写了也没错。
- persistentVolumeReclaimPolicy: Delete 数据卷回收策略,这里是删除,也就是pvc删除了,数据卷跟随删除,是默认策略,但不建议使用这个,建议使用Retain。
- persistentVolumeReclaimPolicy: Recycle:不保留数据。经测试pvc删除后,在nfs服务端的数据也会随机删除。只有hostPath和NFS支持这种方式
- Retain:不清理保留数据。即删除pvc或者pv后,在插件上的数据(nfs服务端)不会被删除。这种方式是最常用的,可以避免误删pvc或者pv而造成数据的丢失。
- 本例使用了节点亲和度,这里比较容易出错的地方是,如果有亲和度策略,该pv无法更新,只能删除重新生成。说人话就是,比如,上面的删除策略想要调整,OK,必须删除pv,不能patch它,然后重新执行清单文件才可以,否则报错报到你怀疑人生。
cat mysql-pv.yaml apiVersion: v1 kind: PersistentVolume metadata: name: mysql-pv spec: capacity: storage: 15Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Delete # storageClassName: local-storage local: # 指定它是一个 Local Persistent Volume path: /mnt/mysql-data # PV对应的本地磁盘路径 nodeAffinity: # 亲和性标志 required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - k8s-node1 # 必须部署在node1上
(3)pvc---存储卷需求清单
没什么好说的了,只需要记住这个name: mysql-pv-claim,一会部署的时候引用这个名字即可。
[root@master mysql]# cat mysql-pvc.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim spec: # storageClassName: local-storage accessModes: - ReadWriteOnce resources: requests: storage: 5Gi
(4)deployment方式部署
数据库密码是password
strategy:
type: Recreate
是一种部署方式,停止旧版本部署新版本,说人话就是,旧的去了,新的就来。当然,本例无所谓了。
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 -->一次可以添加多少个实例
maxUnavailable: 0 -->能够容忍多少个实例无法使用,0表示不容忍
rollingupdae是另一种部署方式--见名思意,滚动更新通过逐个替换实例来逐步部署新版本的应用,直到所有实例都被替换完成为止。它通常遵循以下过程:在负载均衡器后面使用版本 A 的实例池,然后部署版本 B 的一个实例,当服务准备好接收流量时(Readiness Probe 正常),将该实例添加到实例池中,然后从实例池中删除一个版本 A 的实例并关闭。
通常生产环境是使用滚动更新或者蓝绿更新策略。
- image: mysql:5.7.23 imagePullPolicy: IfNotPresent
镜像拉取策略是本地有就用本地的,如果没有该镜像就去网络上拉取,通常生产环境也是用这个的,毕竟很多项目是在内网中的,获取镜像是有问题的。
- name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claim
这个name写了两次,保证一致就可以,但可以随便定义, claimName: mysql-pv-claim这个是引用的上面的pvc的名字,不能乱写。
[root@master mysql]# cat deploy-mysql.yaml apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: mysql spec: selector: matchLabels: app: mysql strategy: type: Recreate template: metadata: labels: app: mysql spec: containers: - image: mysql:5.7.23 imagePullPolicy: IfNotPresent name: mysql env: - 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
(5)编写服务清单
这个service的作用只是一会测试的时候使用,端口暴露3306,集群内部使用。
[root@master mysql]# cat mysql-svc.yaml apiVersion: v1 kind: Service metadata: name: mysql spec: ports: - port: 3306 selector: app: mysql clusterIP: None
应用这些文件(这个顺序是建立顺序,注意,StorageClass文件不需要执行,因为,我已经将关于它的地方注释掉了):
k apply -f mysql-pv.yaml -f mysql-pvc.yaml -f deploy-mysql.yaml