Kubernetes: k8s 高级篇-中间件容器化-k8s包管理工具Operator和helm
- TAGS: Kubernetes
k8s 高级篇-k8s包管理工具Operator和helm
中间件容器化说明
中间件:
- rabbitmq
- zookeeper
- redis
- mysql
- kafka
- mongoDB
每个中间件都有单实例模式和集群模式。
部署应用至K8s通用步骤
如何部署一个应用至K8s?
- 必须要了解你要部署的这个东西
- 架构
- 配置
- 端口号
- 启动命令
- 其次要有这个东西的镜像
- 镜像谁来做
- 找到最合适的部署方式
- 是否是有状态
- 配置分离
- 部署文件来源
- 如何部署
- 这个程序如何被使用
- 什么协议
- 内部还是外部
部署单实例中间件至K8s
- 找到官方镜像:https://hub.docker.com/
- 确认需要的配置:环境变量或配置文件
- 选择部署方式:Deployment或其他的
- 配置访问:TCP或HTTP
K8s和传统架构管理中间件集群区别
传统架构如何管理中间件集群?
- 新建集群
- 申请服务器
- 下载软件包
- 配置相关配置文件
- 启动服务
- 建立集群
K8s如何管理中间件集群?
包管理工具:一句话总结功能就是可以很方便管理一些比较复杂的应用,比如MySQL集群、Redis集群等,可以一键式创建集群、扩容、备份等。常用的两种包管理工具是Operator和Helm。
- Helm:更倾向于无状态应用的部署,比如公司的服务、某些不需要持久化数据的中间件、不需要实现额外功能的服务,比如备份、回滚等。
- Operator:管理更为复杂的有状态服务,比如MySQL集群、Redis集群、Rook等。并且可以利用Operator实现扩容、备份、回滚等功能。这些功能需要自己开发。
K8s如何管理集群?
选择部署方式:helm、operator
helm
- 安装 helm 客户端工具
- 添加 helm 仓库
- helm install 一键启动
operator
- 创建 operator 控制器
- 创建自定义资源
- 执行相关逻辑
中间件到底要不要部署至K8s集群
非生产环境:使用K8s管理比较推荐
生产环境:需要考虑性能、持久化、稳定性等问题。
k8s包管理工具Operator
使用Operator创建Redis集群
Redis集群使用和扩容
- redis-cluster-operator 安装
文档:https://github.com/ucloud/redis-cluster-operator
master01
#1、创建Operator git clone https://github.com/ucloud/redis-cluster-operator.git kubectl create -f deploy/crds/redis.kun_distributedredisclusters_crd.yaml kubectl create -f deploy/crds/redis.kun_redisclusterbackups_crd.yaml kubectl create ns redis-cluster kubectl create -f deploy/service_account.yaml -n redis-cluster kubectl create -f deploy/namespace/role.yaml -n redis-cluster kubectl create -f deploy/namespace/role_binding.yaml -n redis-cluster kubectl create -f deploy/namespace/operator.yaml -n redis-cluster #2、创建Redis集群 #Namespace级别的需要更改配置: # if your operator run as cluster-scoped, add this annotations # redis.kun/scope: cluster-scoped kubectl create -f deploy/example/redis.kun_v1alpha1_distributedrediscluster_cr.yaml -n redis-cluster #【可选】提示:如果集群规模不大,资源少,可以自定义资源,把请求的资源降低 kubectl create -f deploy/example/custom-resources.yaml -n redis-cluster #3、查看集群状态 kubectl get distributedrediscluster -n redis-cluster # view $ kubectl get distributedrediscluster $ kubectl get all -l redis.kun/name=example-distributedrediscluster $ kubectl get po $ kubectl get svc # entry $ kubectl get svc $ kubectl exec -it pod/drc-example-distributedrediscluster-0-0 -- sh $ redis-cli -h example-distributedrediscluster $ redis-cli -h 10.244.58.255 $ 10.244.58.255:6379> set a b $ 10.244.58.255:6379> get a
Redis集群扩容注意事项及删除
- redis-cluster扩容缩容
扩容
kubectl edit Distributedrediscluster example-distributedrediscluster
apiVersion: redis.kun/v1alpha1 kind: DistributedRedisCluster metadata: annotations: # if your operator run as cluster-scoped, add this annotations redis.kun/scope: cluster-scoped name: example-distributedrediscluster spec: # Increase the masterSize to trigger the scaling. masterSize: 4 # 找到这个,修改为4 ClusterReplicas: 1 image: redis:5.0.4-alpine
缩容
apiVersion: redis.kun/v1alpha1 kind: DistributedRedisCluster metadata: annotations: # if your operator run as cluster-scoped, add this annotations redis.kun/scope: cluster-scoped name: example-distributedrediscluster spec: # Increase the masterSize to trigger the scaling. masterSize: 3 # 找到这个,修改为3 ClusterReplicas: 1 image: redis:5.0.4-alpine
- 清除
kubectl delete -f deploy/example/redis.kun_v1alpha1_distributedrediscluster_cr.yaml -n redis-cluster kubectl delete -f deploy/cluster/operator.yaml -n redis-cluster kubectl delete -f deploy/cluster/cluster_role_binding.yaml -n redis-cluster kubectl delete -f deploy/cluster/cluster_role.yaml -n redis-cluster kubectl delete -f deploy/service_account.yaml -n redis-cluster kubectl delete -f deploy/crds/redis.kun_redisclusterbackups_crd.yaml -n redis-cluster kubectl delete -f deploy/crds/redis.kun_distributedredisclusters_crd.yaml -n redis-cluster
k8s包管理工具helm
Helm创建Kafka、Zookeeper集群
Helm客户端安装:https://helm.sh/docs/intro/install/
添加bitnami和官方helm仓库:
helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add stable https://charts.helm.sh/stable helm repo list
安装方式一:先下载后安装
# 下载包 helm pull bitnami/zookeeper # 修改values.yaml相应配置:副本数、auth、持久化 helm install -n public-service zookeeper .
安装方式二:直接安装
helm install kafka bitnami/kafka --set zookeeper.enabled=false --set replicaCount=3 --set externalZookeeper.servers=zookeeper --set persistence.enabled=false -n public-service
Kafka集群测试
svc 中 kafka 是外部连接地址,kafka-headless 是内部通信使用的。
kubectl run kafka-client --restart='Never' --image docker.io/bitnami/kafka:2.8.0-debian-10-r30 --namespace public-service --command -- sleep infinity kubectl exec --tty -i kafka-client --namespace public-service -- bash 生产者: kafka-console-producer.sh \ --broker-list kafka-0.kafka-headless.public-service.svc.cluster.local:9092,kafka-1.kafka-headless.publicservice.svc.cluster.local:9092,kafka-2.kafka-headless.public-service.svc.cluster.local:9092 \ --topic test 消费者: kafka-console-consumer.sh \ --bootstrap-server kafka.public-service.svc.cluster.local:9092 \ --topic test \ --from-beginning
Kafka集群扩容及删除
helm upgrade kafka bitnami/kafka --set zookeeper.enabled=false --set replicaCount=5 --set externalZookeeper.servers=zookeeper --set persistence.enabled=false -n public-service
helm 基础命令
下载一个包:helm pull 创建一个包:helm create 安装一个包:helm install 查看:helm list 查看安装参数:helm get values 查看原始参数:helm show values prometheus-community/kube-prometheus-stack 更新:helm upgrade 删除:helm delete 查看对应版本:helm search repo -l gitlab/gitlab-runner
helm upgrade --install -n gitlab-xcw gitlab . \ --timeout 600s \ --dry-run \ -f customize_conf/values-prod.yaml \ --set global.hosts.gitlab.name='git-xcw.tech.com' \ `#--外部postgresql--` \ `#--set postgresql.install=false` \ `#--set global.psql.host=production.postgress.hostname.local` \ `#--set global.psql.password.secret=gitlab-pg` \ `#--set global.psql.password.key='password'` \ `#--外部redis--` \ `#--set redis.enabled=false` \ `#--set global.redis.host='redis.example.com'` \ `#--set global.redis.password.secret=gitlab-redis` \ `#--set global.redis.password.key='password'` \ --set gitlab.migrations.enabled=true
Helm v3 Chart目录层级解析
创建一个Chart: helm create helm-test
├── charts # 依赖文件,如果依赖其它包可把对应包放这里 ├── Chart.yaml # 当前chart的基本信息 apiVersion:Chart的apiVersion,目前默认都是v2 name:Chart的名称 type:图表的类型[可选] version:Chart自己的版本号 appVersion:Chart内应用的版本号[可选] description:Chart描述信息[可选] ├── templates # 模板位置 │ ├── deployment.yaml │ ├── _helpers.tpl # 自定义的模板或者函数 │ ├── ingress.yaml │ ├── NOTES.txt #Chart安装完毕后的提醒信息 │ ├── serviceaccount.yaml │ ├── service.yaml │ └── tests # 测试文件 │ └── test-connection.yaml └── values.yaml #配置全局变量或者一些参数
如 templates/deployment.yaml 中 .Values.podAnnotations
代表使用values.yaml文件中 podAnnotations 变量。
Helm内置变量的使用
- Release.Name: 实例的名称,helm install指定的名字
- Release.Namespace: 应用实例的命名空间
- Release.IsUpgrade: 如果当前对实例的操作是更新或者回滚,这个变量的值就会被置为true
- Release.IsInstall: 如果当前对实例的操作是安装,则这边变量被置为true
- Release.Revision: 此次修订的版本号,从1开始,每次升级回滚都会增加1
- Chart: Chart.yaml文件中的内容,可以使用Chart.Version表示应用版本,Chart.Name表示Chart的名称
Helm常用函数的使用
helm 模板
查看所有安装的服务
helm list -A
Helm检索版本并查看实际加载的模板
helm get manifest <ReleaseName>
模板命令要括在 {{ 和 }} 之间
{{ .Release.Name }}
将发布名称注入了模板 。值作为一个 命名空间对象 传给了模板,用点 ( .
) 分隔每个命名空间的元素。
Release前面的点表示从作用域最顶层的命名空间开始. .Release.Name
就可解读为“通顶层命名空间开始查找 Release对象,然后在其中找Name对象”。
helm install --debug --dry-run goodly-guppy ./mychart
测试模板渲染的内容但又不想安装任何实际应用
内置对象
官方文档: https://helm.sh/docs/chart_template_guide/builtin_objects/
- Release: Release对象描述了版本发布本身。包含了以下对象:
- Release.Name: release名称
- Release.Namespace: 版本中包含的命名空间(如果manifest没有覆盖的话)
- Release.IsUpgrade: 如果当前操作是升级或回滚的话,该值将被设置为true
- Release.IsInstall: 如果当前操作是安装的话,该值将被设置为true
- Release.Revision: 此次修订的版本号。安装时是1,每次升级或回滚都会自增
- Release.Service: 该service用来渲染当前模板。在helm中,这个值始终为
Helm
- Values: Values对象是从values.yaml文件和用户提供的文件传进模板的。默认为空
- Chart: Chart.yaml文件内容. 访问Chart.yaml中的数据如
{{ .Chart.Name }}
- Files: 在chart中提供访问所有的非特殊文件的对象
- Capabilities: 提供关于Kubernetes集群支持功能的信息
- Template: 包含当前被执行的当前模板信息
- Template.Name: 当前模板的命名空间文件路径 (e.g. mychart/templates/mytemplate.yaml)
- Template.BasePath: 当前chart模板目录的路径 (e.g. mychart/templates)
include 引用.tpl中模板
#deplyment.yaml: apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "archery.fullname" . }} #_help.tpl {{/* Create a default fully qualified app name. We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). If release name contains chart name it will be used as a full name. */}} {{- define "archery.fullname" -}} {{- if .Values.fullnameOverride -}} {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} {{- else -}} {{- $name := default .Chart.Name .Values.nameOverride -}} {{- if contains $name .Release.Name -}} {{- .Release.Name | trunc 63 | trimSuffix "-" -}} {{- else -}} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} {{- end -}} {{- end -}} {{- end -}}
定义下面的辅助模板
#_help.tpl {{- define "imagePullSecret" }} {{- with .Values.imageCredentials }} {{- printf "{\"auths\":{\"%s\":{\"username\":\"%s\",\"password\":\"%s\",\"email\":\"%s\",\"auth\":\"%s\"}}}" .registry .username .password .email (printf "%s:%s" .username .password | b64enc) | b64enc }} {{- end }} {{- end }} #values.yaml imageCredentials: registry: quay.io username: someone password: sillyness email: [email protected] #secret.yaml apiVersion: v1 kind: Secret metadata: name: myregistrykey type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: {{ template "imagePullSecret" . }}
Helm提供了以下类型转换函数:
- toYaml: 将列表,切片,数组,字典或对象转换成已缩进的yaml,可以从任意源拷贝yaml块。
范例:toYaml
#values.yaml deployment: labels: {} annotations: {} #清单文件 ## 转换为yaml格式, 并缩进4个空格, apiVersion: apps/v1 kind: Deployment metadata: {{- with .Values.deployment.annotations }} annotations: {{- toYaml . | nindent 4 }} {{- end }}
使用StatefulSet安装RabbitMQ集群
下载基本文件:
git clone https://github.com/dotbalo/k8s.git
cd k8s/k8s-rabbitmq-cluster ; kubectl create ns public-service ; kubectl apply -f .
编写Chart一键安装RabbitMQ集群
创建一个Chart:
helm create rabbitmq-cluster
删除无用文件
rm -fr deployment.yaml hpa.yaml serviceaccount.yaml service.yaml tests
安装一个Chart helm install XXXXX . 测试无误后删除Chart helm delete XXXXX