• 什么是Kubernetes分布式容器管理平台
  • PaaS平台redis-sentinel集群架构简介
  • PaaS平台部署redis哨兵集群
  • redis-sentinel容器测试及验证
  • redis-sentienl容器集群之客户端程序实现


Kubernetes分布式容器管理平台

Kubernetes是一个开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护更新等功能,是当下较热门的PSSA集群技术之一。

Kubernetes的主要核心组件:

●Apiserver:

apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制,封装了核心对象的增删改查操。

●scheduler:

负责集群资源的调度和管理,按照预定的调度策略将Pod调度到相应的机器上。

●controller-manager:

负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。

●kubelet:

运行在minion节点,负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理,例如启停容器,监控运行状态等。

●etcd:

etcd是一个高可用的键值存储系统。

●flannel:

为集群中的所有节点重新规划IP地址的使用规则。

●pod:

它是Kubernetes资源中最小的调度单元,也是基础单元。

Kubernetes架构图:

k8s部署单节点redis 暴露外部 k8s 部署redis集群_k8s部署单节点redis 暴露外部

Kubernetes中创建pod过程:

k8s部署单节点redis 暴露外部 k8s 部署redis集群_k8s部署单节点redis 暴露外部_02

  • 用户通过 REST API 创建一个 Pod。
  • apiserver 将其写入 Etcd数据库。
  • scheduluer 检测到未绑定 Node 的 Pod,开始调度并更新 Pod 的 Node 绑定。
  • kubelet 检测到有新的 Pod 调度过来,通过 container runtime 运行该 Pod。
  • kubelet 通过 container runtime 获取取到 Pod 状态并更新到 apiserver 中。

使用Kubernetes部署服务的几个好处:

1)服务自动故障迁移;

2)自动资源调度;

3)实现资源隔离;

4)采用docker容器;

5)RBAC认证增加了Kubernetes的安全。

Kubernetes的优势:

 1)可移动:公有云、私有云、混合云、多态云;

 2)可扩展:模块化、插件化、可挂载、可组合;

 3)自修复:自动部署、自动重启、自动复制、自动伸缩。


PaaS平台redis-sentinel集群架构简介

redis哨兵架构介绍:

●  Redis Sentinel是一个分布式系统,RedisSentinel为Redis提供高可用性。可以在没有人为干预的情况下阻止某种类型的故障。

●可以在一个架构中运行多个Sentinel,这些进程使用gossip协议来接收关于主服务器是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。

PaaS平台redis-sentinel架构图工作流程图:

k8s部署单节点redis 暴露外部 k8s 部署redis集群_redis 哨兵_03


PaaS平台部署redis哨兵集群过程

redis-sentinel镜像准备,使用dockerfile构建如下镜像:

  • Redis Sentienl镜像

al_redis_sentinel_v2_4.0.10.tar

  • Redis master镜像

al_redis-sentinel_master_4.0.10.tar

  • Redis slave镜像

al_redis_slave_4.0.10.tar

编写redis-sentinel网络清单文件:

vim redis_sentinel.yaml
---
apiVersion:extensions/v1beta1
kind:Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "2"
labels:
service_name: redis-sentinel1
name: redis-sentinel1
namespace: core-610
spec:
replicas: 1
revisionHistoryLimit: 5
selector:
matchLabels:
service_name: redis-sentinel1
strategy:
rollingUpdate:
maxSurge: 0%
maxUnavailable: 100%
type: RollingUpdate
template:
metadata:
annotations:
service.alauda.io/version: "5"
labels:
service_name: redis-sentinel1
namespace: core-610
spec:
affinity:
podAffinity: {}
podAntiAffinity: {}
containers:
- env:
- name: REDIS_SENTINEL_PORT
value: "26378"
- name: MASTER_NAME
value: mymaster
- name: MASTER_HOST
value: 192.168.1.94
- name: MASTER_PORT
value: "6378"
- name: QUONUM
value: "1"
- name: DOWN_AFTER_MILLSECONDS
value: "8000"
- name: NUMSLAVES
value: "1"
- name: FAILOVER_TIMEOUT
value: "60000"
- name: AUTH_PASS
value: xxxxxx  
image:xxx.xxx.xxx.xxx/pro568/al_redis_sentinel:4.0.10
imagePullPolicy: Always
name: redis-sentinel1
resources:
limits:
cpu: "0.5"
memory: 512Mi
requests:
cpu: "0.5"
memory: 512Mi
terminationMessagePath:/dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data
name: redis-sentinel1
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 10
volumes:
- name: redis-sentinel1
persistentVolumeClaim:
claimName: redis-sentinel1
---
apiVersion:extensions/v1beta1
kind:Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
labels:
service_name: redis-master1
name: redis-master1
namespace: core-610
spec:
replicas: 1
revisionHistoryLimit: 5
selector:
matchLabels:
service_name: redis-master1
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
annotations:
service.alauda.io/version: "1"
labels:
service_name: redis-master1
namespace: core-610
spec:
affinity:
podAffinity: {}
podAntiAffinity: {}
containers:
- env:
- name: REDIS_PORT
value: "6378"
- name: REDIS_PASSWORD
value: xxxxxx
- name: __ALAUDA_FULL_NAME__
- name: __CREATE_TIME__
value: "2020-01-10T15:10:24"
- name: __ALAUDA_APP_NAME__
value: gzky-sentinel
- name: REDIS_MAXMEMORY
value: "536870912"
- name: __ALAUDA_SERVICE_NAME__
value: redis-master1
- name: __ALAUDA_SERVICE_VERSION__
value: "1060"
- name: __ALAUDA_OVER_COMMIT_CPU__
value: "512"
- name: __ALAUDA_OVER_COMMIT_MEM__
value: "512"
- name: MASTER_AUTH
value: xxxxxx
- name: MAXCLIENTS
value: "8000"
- name: __ALAUDA_CONTAINER_SIZE__
value: "0.5"
- name: __ALAUDA_REGION_NAME__
- name: __ALAUDA_SERVICE_ID__
value: redis-master1
image:xxx.xxx.xxx.xxx/pro568/al_redis-sent_master:4.0.10
imagePullPolicy: Always
name: redis-master1
resources:
limits:
cpu: 250m
memory: 512Mi
requests:
cpu: 250m
memory: 512Mi
terminationMessagePath:/dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data
name: redis-rep1
dnsPolicy: ClusterFirst
hostNetwork: true
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 10
volumes:
- name: redis-rep1
persistentVolumeClaim:
claimName: redis-rep1
---
apiVersion:extensions/v1beta1
kind:Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "2"
labels:
service_name: redis-slave-1
name: redis-slave-1
namespace: core-610
spec:
replicas: 1
revisionHistoryLimit: 5
selector:
matchLabels:
service_name: redis-slave-1
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
annotations:
service.alauda.io/version: "2"
labels:
service_name: redis-slave-1
namespace: core-610
spec:
affinity:
podAffinity: {}
podAntiAffinity: {}
containers:
- env:
- name: REDIS_PORT
value: "6378"
- name: REDIS_PASSWORD
value: xxxxxx
- name: __ALAUDA_FULL_NAME__
- name: __CREATE_TIME__
value: "2020-01-10T15:10:24"
- name: __ALAUDA_APP_NAME__
value: gzky-sentinel
- name: REDIS_MAXMEMORY
value: "536870912"
- name: __ALAUDA_SERVICE_NAME__
value: redis-slave-1
- name: __ALAUDA_SERVICE_VERSION__
value: "1057"
- name: __ALAUDA_OVER_COMMIT_CPU__
value: "512"
- name: __ALAUDA_OVER_COMMIT_MEM__
value: "512"
- name: REDIS_SLAVE_OF
value: 192.168.1.94 6378
- name: MASTER_AUTH
value: xxxxxx
- name: MAXCLIENTS
value: "8000"
- name: __ALAUDA_CONTAINER_SIZE__
value: "0.5"
- name: __ALAUDA_REGION_NAME__
- name: __ALAUDA_SERVICE_ID__
value: redis-slave-1
image:xxx.xxx.xxx.xxx/pro568/al_redis_slave:4.0.10
imagePullPolicy: Always
name: redis-slave-1
resources:
limits:
cpu: 250m
memory: 512Mi
requests:
cpu: 250m
memory: 512Mi
terminationMessagePath:/dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data
name: redis-rep1
dnsPolicy: ClusterFirst
hostNetwork: true
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 10
volumes:
- name: redis-rep1
persistentVolumeClaim:
claimName: redis-rep1

在PaaS平台使用清单文件部署redis-sentinel容器集群。

执行部署命令:

kubectl  apply -fredis_sentinel.yaml

PaaS平台查看redis-sentinelPOD运行状态:

k8s部署单节点redis 暴露外部 k8s 部署redis集群_redis架构图_04


redis-sentinel容器测试及验证

查看sentinel集群节点信息:

redis-cli -h 192.168.1.92 -p 26379

192.168.1.92:26379>sentinel master mymaster    #查看主节点信息

k8s部署单节点redis 暴露外部 k8s 部署redis集群_redis架构图_05

192.168.1.92:26379>sentinelmaster slaves     #查看从节点信息

k8s部署单节点redis 暴露外部 k8s 部署redis集群_redis 哨兵_06

k8s部署单节点redis 暴露外部 k8s 部署redis集群_k8s部署单节点redis 暴露外部_07

客户端写入测试数据:

#客户端连接master节点,写入一条数据
[root@node3~]# redis-cli -h 192.168.1.94 -p 6378
192.168.1.94:6378>set foo bar
OK
192.168.1.94:6379>get foo
"bar"
#然后客户端再连接任意slave节点,通过get获取上面的那条数据
[root@node1~]# redis-cli -h 192.168.1.95 -p 6379
192.168.1.95:6378>get foo
"bar"

master节点可以写入和读取;而slave节点默认只能读取而不能写入。以此实现主从复制、读写分离。


redis-sentienl容器集群之客户端程序实现

客户端实现原理:

k8s部署单节点redis 暴露外部 k8s 部署redis集群_k8s部署单节点redis 暴露外部_08

redis哨兵模式客户端程序实现过程描述:

  • 连接所有的Sentinel的节点,返回可一个可用的sentinel结合列表。
  • 向可用的sentinel节点发送get-master-addr-by-name masterName请求;获取redis节点(master/salve)和信息。
  • 返回信息中会验证节点是否是master角色。
  • 如果sentinel检测到master节点变化,会failover。
  • 实现读写分离;读走Slave,写走Master。

以上是今天带来的基于K8S的redis哨兵模式的扫盲和实验案例,后续会继续给大家带来具体使用中碰到的问题,趟过的坑。