Kruise Rollout金丝雀发布
实验环境
安装好k8s集群
环境准备
1、部署OpenKruise
(1)部署helm
下载或上传helm-v3.13.2-linux-amd64.tar.gz包到/root目录
下载方法:wget https://get.helm.sh/helm-v3.13.2-linux-amd64.tar.gz
tar xf helm-v3.13.2-linux-amd64.tar.gz
mv linux-amd64/helm /usr/bin/
helm version
(2)添加openkruise仓库
helm repo add openkruise https://openkruise.github.io/charts/
helm repo update
helm repo list
(3)使用helm安装kruise
helm search repo openkruise
这里使用本地包安装
上传kruise-manager.tar镜像包到/root目录(master1、worker1、worker2)也可以执行下面命令联网下载镜像
docker load -i kruise-manager.tar
上传kruise-1.8.0.tgz包到/root目录(master1)
helm install kruise kruise-1.8.0.tgz --set daemon.socketLocation=/var/run --set daemon.socketFile=cri-dockerd.sock --set featureGates="InPlaceUpdateEnvFromMetadata=true\,PreDownloadImageForInPlaceUpdate=true"
kubectl get all -n kruise-system
2、Kruise Rollouts 安装
(1)使用helm安装kruise-rollout
helm search repo kruise-rollout
使用openkruise仓库安装(需要连接VPN)
helm install kruise-rollout openkruise/kruise-rollout --version 0.5.0
这里使用本地包安装
上传kruise-rollout.tar镜像包到/root目录(master1、worker1、worker2)也可以执行下面命令联网下载镜像
docker load -i kruise-rollout.tar
上传kruise-rollout-0.5.0.tgz包到/root目录(master1)
helm install kruise-rollout kruise-rollout-0.5.0.tgz
kubectl get ns
kubectl get pod -n kruise-rollout
(2)kubectl plugin安装(master1)
下载或上传kubectl-kruise-linux-amd64.tar.gz包到/root目录
下载方法(需要连接VPN):wget https://github.com/openkruise/kruise-tools/releases/download/v1.1.2/kubectl-kruise-linux-amd64.tar.gz
tar xf kubectl-kruise-linux-amd64.tar.gz
mv linux-amd64/kubectl-kruise /usr/bin/
kubectl-kruise version或kubectl-kruise version --output=yaml
一、金丝雀发布简介
需要负载均衡器metallb及ingress nginx配合
1、发布流程
2、推荐配置(此处仅为示例说明)
金丝雀策略仅适用于Deployment
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-demo
annotations:
rollouts.kruise.io/rolling-style: canary
spec:
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: workload-demo
strategy:
canary:
steps:
- weight: 20
pause: { duration: 10m }
- weight: 50
pause: {}
- weight: 100
trafficRoutings:
- service: service-demo
ingress:
classType: nginx
name: ingress-demo
failurePolicy:
action: rollback
3、案例解析
(1)触发发布
当 workload-demo Deployment 被更新(如修改镜像版本)时,Rollout 会接管发布流程。
(2)金丝雀阶段
创建新版本的 Pod,但仅将 20% 的流量 路由到新版本(通过 NGINX Ingress 的 canary 功能实现)。
旧版本 Pod 仍接收 80% 流量。
将创建一个新的金丝雀Deployment,其副本数为workload-demo的“20%”(现在总计将有120%的Pods);20%的流量将被引导到新的金丝雀Deployment的Pods。
(3)后续操作
当你认为金丝雀验证已经通过并确认进行下一步时:
workload-demo工作负载将使用本机滚动更新策略进行升级(分别是150%、200%的pods);
流量将恢复到原始的负载均衡策略;
金丝雀Deployment和Pods将被删除。
二、负载均衡器metallb部署
部署ingress最好先部署metalLB
nginx-ingress:解决服务暴露与负载均衡问题
metallb:为k8s集群的service提供LoadBalancer类型的支持,分配群集虚拟ip
客户-->ingress(metalLB辅助提供vip)-->service-->pod
1、修改kube-proxy代理模式
kubectl get configmap -n kube-system
编辑 Kubernetes 中 kube-proxy 的 ConfigMap
kubectl edit configmap kube-proxy -n kube-system
修改添加:
重启 Kubernetes 中 kube-proxy DaemonSet
kubectl rollout restart daemonset kube-proxy -n kube-system
2、metallb部署
此处使用离线下载后的文件部署
上传metallb-native.yaml文件到/root目录(master1)
上传metallb_speaker.tar和metallb-controller.tar镜像包到/root目录并导入镜像(master1、worker1、worker2)
docker load -i metallb_speaker.tar
docker load -i metallb-controller.tar
创建资源(master1)
kubectl apply -f metallb-native.yaml
查看指定命名空间(metallb-system)中所有 Pod
kubectl get pod -n metallb-system
3、准备IP地址池
vim ippool.yaml
添加:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: ippool
namespace: metallb-system
spec:
addresses:
- 192.168.10.240-192.168.10.250
kubectl apply -f ippool.yaml
查看 MetalLB 中名为 ippool 的 IPAddressPool 资源详细信息
kubectl describe ipaddresspools.metallb.io ippool -n metallb-system
4、开启二层通告
vim L2.yaml
添加:
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: example
namespace: metallb-system
kubectl apply -f L2.yaml
三、服务代理ingress nginx部署
1、下载或上传所需文件和包
下载地址(需要连接VPN):wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml
上传deploy.yaml文件到/root目录(master1)
上传ingress-nginx.tar包到/root目录并导入(master1、worker1、worker2)
docker load -i ingress-nginx.tar
2、修改配置文件(master1)
vim deploy.yaml
修改:
LoadBalancer
Nginx ingress controller本身也是以一个服务的方式运行在k8s群集中
改为LoadBalancer的目的是让metallb给nginx ingress分配一个群集ip
3、部署deploy.yaml文件(master1)
kubectl apply -f deploy.yaml
4、查看部署状态(master1)
kubectl get pod -n ingress-nginx
5、查看nginx-ingress-controller的IP
kubectl get svc -n ingress-nginx
四、金丝雀部署应用
这是echoserver 应用程序示例,其中包含 ingress, service, 和 deployment crd 资源
vim 01-deploy.yaml
添加:
apiVersion: apps/v1
kind: Deployment
metadata:
name: echoserver
labels:
app: echoserver
spec:
replicas: 5
selector:
matchLabels:
app: echoserver
template:
metadata:
labels:
app: echoserver
spec:
containers:
- name: echoserver
image: cilium/echoserver:1.10.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
env:
- name: PORT
value: '8080'
---
apiVersion: v1
kind: Service
metadata:
name: echoserver
labels:
app: echoserver
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: echoserver
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echoserver
spec:
ingressClassName: nginx
rules:
- host: www.test.com
http:
paths:
- backend:
service:
name: echoserver
port:
number: 80
path: /apis/echo
pathType: Exact
kubectl apply -f 01-deploy.yaml
kubectl get pod
kubectl get deployment
查看nginx-ingress-controller的IP
kubectl get service -n ingress-nginx
添加域名解析
vim /etc/hosts
添加:
192.168.10.240 www.test.com
curl http://www.test.com/apis/echo
(1)创建rollout策略
Kruise Rollout CRD 定义了 deployment rollout 发布过程,如下是一个金丝雀发布的例子,第一步是 20% 的 pod,以及路由 5% 的 traffics 到新版本。
vim 02-rollout.yaml
添加:
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-demo-echoserver
namespace: default
annotations:
rollouts.kruise.io/rolling-style: canary
spec:
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: echoserver
strategy:
canary:
steps:
- weight: 5
pause: {}
replicas: 20%
trafficRoutings:
- service: echoserver
ingress:
classType: nginx
name: echoserver
kubectl apply -f 02-rollout.yaml
查看 Kubernetes 集群中已部署的 Rollout 资源
kubectl get rollout
返回字段解析:
NAME: rollouts-demo-echoserver Rollout 资源的名称。
STATUS: Healthy Rollout 的当前状态为 Healthy,表示发布成功,应用运行正常。
CANARY_STEP: 1 Canary 发布的当前步骤为第 1 步(已完成所有步骤)。
CANARY_STATE: Completed Canary 发布的状态为 Completed,表示发布流程已经完成。
MESSAGE: workload deployment is completed 附加信息,表示相关的工作负载(如 Deployment)已经成功部署。
(2)更新版本发布
将部署中的镜像版本从 1.10.2 改为 1.10.3,然后 kubectl apply -f 01-deploy.yaml 到 k8s 集群,如下所示。
Kruise Rollout Controller 会监听上述行为并在 webhook 中设置部署 paused=true,然后根据用户定义的部署、服务和入口配置生成相应的 canary 资源。
如下所示,replicas(5)*replicas(20%)=1 新版本的 Pod 被发布,5% 的流量被路由到新版本
vim 01-deploy.yaml
修改:
kubectl apply -f 01-deploy.yaml
kubectl get deployment
kubectl describe deployment echoserver-5hhwm
kubectl get pod
查看 Kubernetes 集群中已部署的 Rollout 资源
kubectl get rollout
STATUS: Progressing Rollout 的当前状态为 Progressing,表示发布流程正在进行中。
CANARY_STEP: 1 Canary 发布的当前步骤为第 1 步(总共 1 步)。
CANARY_STATE: StepPaused Canary 发布的状态为 StepPaused,表示发布流程已暂停,需要手动确认才能进入下一步。
MESSAGE: Rollout is in step(1/1), and you need manually confirm to enter the next step 附加信息,明确提示当前处于第 1 步(总共 1 步),需要手动确认才能继续。
(3)批准发布
Rollout 状态显示,当前的 rollout 状态是 StepPaused,这意味着前 20% 的 Pod 被发布成功,5%的流量被路由到新版本上之后,开发人员可以使用一些其他方法,如 Prometheus metrics 业务指标,确定发布符合预期,然后通过 kubectl-kruise rollout approve rollout/rollouts-demo-echoserver -n default 和等待部署发布完成
手动确认并继续 OpenKruise Rollout 的发布流程
kubectl-kruise rollout approve rollout/rollouts-demo-echoserver
字段解析:
kubectl-kruise:OpenKruise 提供的扩展 CLI 工具,用于管理 OpenKruise 的自定义资源(如 Rollout)。
rollout approve:用于手动确认 Rollout 的当前步骤,使其进入下一个阶段。
rollout/rollouts-demo-echoserver:指定要操作的 Rollout 资源,名称为 rollouts-demo-echoserver。
kubectl get rollout
返回字段解析:
STATUS: Healthy Rollout 的当前状态为 Healthy,表示发布成功,应用运行正常。
CANARY_STEP: 1 Canary 发布的当前步骤为第 1 步(已完成所有步骤)。
CANARY_STATE: Completed Canary 发布的状态为 Completed,表示发布流程已经完成。
MESSAGE: Rollout progressing has been completed 附加信息,表示 Rollout 发布流程已经成功完成。
kubectl get deployment
kubectl get pod
查看器Pod使用的镜像
kubectl describe pod echoserver-57569db688-9vj8w | grep image
kubectl describe deployment echoserver | grep -i image