有状态应用容器化设计方案
有状态应用解释
在分布式应用中,它的多个实例之间,往往有依赖关系,比如主从关系,主备关系。还有就是数据存储类应用,它的多个示例,往往都会在本地磁盘上保存一份数据。而这些实例一但被杀掉,即使重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败。所以,这种实例不对等关系,以及实例对外部数据有依赖关系的应用,就被称为有状态应用 (Stateful Application)
有状态应用抽象
对于有状态应用,其实可以将其抽象为两种情况:
- 拓扑状态:这种情况意味着,应用的多个实例之间不是对等关系,这些应用实例,必须按照某种顺序启动,比如节点A要先于节点B启动。如果将AB两个pod都删掉,再次启动也依旧得按照这个顺序,而且新创建出来的Pod。必须和原来的Pod的网络标识一样。这样原先的访问者可以使用同样的方法。访问到新的Pod
- 存储状态:应用的多个实例分别绑定了不同的存储数据,对于这些应用实例来说。当应用因为某些原因导致了宕机,重启后依旧可以正常的读取到数据。
有状态应用特征
- 稳定且唯一的网络标识
- 稳定持久的存储
- 有序,优雅的部署和伸缩
- 有序,自动的更新
本次主要是针对数据存储类的有状态服务Mysql和Redis做在k8s的容器化,在第一阶段稳定后,可以继续拓展,囊括其他的服务如pika,influxdb 等。所以到这里我们可以先把目标缩小一点,改为存储应用容器化。
存储应用容器化关键点
实现存储应用容器化主要有三个关键点,而这个三个关键点可以有多种实现方式,而这三种方式完全解耦。可以进行各种方式的组合。比如想要一个快速用起来,不考虑高可用的,可以支持。想要一个稳定且能用于生产高可用的也可以支持。
关键点
-
唯一网络标识
-
服务依赖关系(一主一从,一主N从)
-
数据持久化
组合对比
网络 | 服务依赖关系 | 数据持久化 | 开发难度 | 稳定度 | 生产标准 |
---|---|---|---|---|---|
静态ip | 单个statefulset | localVolume | 最低 | 最差 | 不具备 |
DNS,VIP | Statefulset | LocalVolume,nfs | 中等 | 中等 | 基本具备 |
DNS,VIP | operator | ceph fs | 最高 | 最好 | 符合 |
对于Mysql和Redis, 网络标识和持久化存储是一致的,唯一的不同在于operator或者statefulset的不同,先将Mysql的容器化完成,并正常的运行起来。把坑踩完后可以快速的实现redis的容器化。
Mysql容器化
目前未找到大厂生产部署Mysql细节文档,都是简单的介绍如何用Statefulset或者用Helm快速。而且oracle官方开源的operator也基本不再更新了。生产环境数据重要且敏感,容器化部署上是否能达到要求还需实践。在测试环境使用已经足够了。经过前期探索基本上对各个部分进行了测试。
一、数据持久化
1. nfs (单机)
NFS是NetworkFileSystem的简写,即网络文件系统,网络文件系统是FreeBSD支持的文件系统中的一种,也被称为NFS.NFS允许一个系统在网络上与它人共享目录和文件。通过使用NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件。
优点
- 部署简单,linux命令一键部署
缺点
- 不支持分布式,如果挂载机器磁盘坏了可能会导致数据丢失
- 对于数据的备份和拓展不方便
2. Ceph fs 加 Rook (分布式)
Ceph
Ceph 是一个开源的分布式存储系统,包括对象存储、块设备、文件系统。它具有高可靠性、安装方便、管理简便、能够轻松管理海量数据。Ceph 存储集群具备了企业级存储的能力,它通过组织大量节点,节点之间靠相互通讯来复制数据、并动态地重分布数据,从而达到高可用分布式存储功能
Rook
Rook 是专用于 Cloud-Native 环境的文件、块、对象存储服务。它实现了一个自动管理的、自动扩容的、自动修复的分布式存储服务。Rook 支持自动部署、启动、配置、分配、扩容/缩容、升级、迁移、灾难恢复、监控以及资源管理。为了实现所有这些功能,Rook 需要依赖底层的容器编排平台,例如 kubernetes、CoreOS 等。Rook 目前支持 Ceph、NFS、Minio Object Store、Edegefs、Cassandra、CockroachDB 存储的搭建,后期会支持更多存储方案。
优点
- 分布式,可靠性强,拓展性强
- Rook 有dashboard。更好的管理能力。
缺点
- 学习成本较高,需要画更多的时间去了解细节和维护整个集群。光一个ceph + rook 就够学习大半个月了。
二、服务部署
1. 自定义StatefulSet
这种方式基本不太好维护,因为创建一个高可用的mysql集群涉及到的资源对象太多了。包括Service,StatefulSet,ConfigMap,PV,PVC 等。 需要编写大量的yaml文件,并且需要对Mysql 原理非常的清晰和了解。否则运维起来将非常痛苦,坑也特别多。
2. Helm 部署mysql集群
Helm 是 Kubernetes 的包管理器。包管理器类似于我们在 Ubuntu 中使用的apt、Centos中使用的yum 或者Python中的 pip 一样,能快速查找、下载和安装软件包。Helm 由客户端组件 helm 和服务端组件 Tiller 组成, 能够将一组K8S资源打包统一管理, 是查找、共享和使用为Kubernetes构建的软件的最佳方式。
使用helm部署Mysql。等于开发者已经把整个Mysql集群所需要的资源对象的yaml都已经写好了。并且对外暴露了足够多的参数可以自定义。通过一个命令的方式就可以快速的部署一个集群。
一个Helm包下的yaml文件如下图所示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0YpSQ36S-1587044858859)(./images/helm-1.jpg)]
部署命令如下:
helm install mysql-metrics-2 incubator/mysql --version 6.8.0 -f values-production.yaml --set root.password=test123,user.database=app_database,global.storageClass=managed-nfs-storage,replication.password=test123
优点
-
Helm 是一个通用的部署方式。只要有开发者提供了合适的包。其他的中间件也可以通过该方式部署。而且可以自己定义自己的chart。并且部署。
-
阿里云,AWS都提供了丰富的镜像。
三、网络唯一标识
因为Pod可能会重启或者重新调度。pod的ip是不固定的。但是对于使用方而言,不能每次都修改IP。所以得通过Service 来做请求的负载。部署在容器内部的服务可以通过内网IP访问Mysql即可。但是对于Mysql这样的服务。经常是需要开发者在自己的本机上连通的。所以需要提供k8s集群外部IP。
1.Service 通过NodePort 暴露服务
将Service的type声明为NodePort。并且设置一个宿主机(Node)的Port。在容器外部就可以通过宿主机IP + 暴露Port 访问到Service。进而通过Service转发到后端真正的Mysql上。
优点
- 创建简单,只需要修改一个Service的type
缺点
- Node节点需要暴露很多的端口不好管理
- Node节点挂掉了,对于上层应用同样无法正常访问
2. Ingress Controller 通过 VIP对外暴露
Ingress(在kubernetes v1.1时添加)暴露从集群外到集群内服务的HTTP
或HTTPS
路由。定义在ingress
资源上的规则控制流量的路由。简单点说。ingress-controller就是类似一个nginx。而ingress则是这个nginx的配置。通过修改ingress的对象来修改nginx的规则。
Ingress 其实是做7层的路由分发的,配置规则如下。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
Nginx-ingress 也支持了做了tcp和udp的分发。需要在tcp-configmap或者udp-configmap里面维护端口和对应的后端service的映射关系就可以了。如下。
apiVersion: v1
kind: ConfigMap
metadata:
name: tcp-services
namespace: ingress-nginx
data:
9000: "default/example-go:8080"
优点:
- 集群对外暴露服务的最好的方式。
- 对于我们有状态服务只需要做到tcp层的路由就可以了,未来可以通过ingress-controller做七层路由的分发。可以提前做技术储备
四、Cmdb-docker 后台可视化维护
查看所有资源
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
创建Mysql资源
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
查看StatefulSet 详情
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传