Kubernetes原生支持重建、滚动更新两种部署策略。通过修改Service的label,切换流量转发可以实现蓝绿部署、金丝雀部署。
部署前的准备
1、需要有一个k8s集群。没有可查看此博客 https://blog.csdn.net/u010606397/article/details/89817958
2、安装ingress控制器。下载mandatory.yaml、service-nodeport.yaml文件可能会被墙,请走代理。
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml
kubectl apply -f mandatory.yaml
kubectl get pod -n ingress-nginx
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/baremetal/service-nodeport.yaml
vim service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
# 修改此处,绑定裸机端口为30080
nodePort: 30080
- name: https
port: 443
targetPort: 443
protocol: TCP
# 修改此处,绑定裸机端口30443
nodePort: 30443
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
kubectl apply -f service-nodeport.yaml
kubectl get svc -n ingress-nginx
3、ingress的host不支持使用ip,修改集群master节点的/etc/hosts,将127.0.0.1映射给k8s01.com,使用其他域名也可以,不是非得用k8s01.com
vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 k8s01.com
重建部署策略
重建部署策略是先把旧的pod全部停掉,然后新建pod。由于部署期间出现服务中断,这种部署策略很少用。
新建yaml文件,写好Deployment、Service、Ingress配置。注意:master的hosts配置了127.0.0.1映射到k8s01.com,所以ingress的host值是k8s01.com。
vim 08-recreate.yaml
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
strategy:
# 使用重建部署策略
type: Recreate
selector:
matchLabels:
app: myapp
replicas: 2
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: containers-myapp
image: ikubernetes/myapp:v1
ports:
- containerPort: 80
resources:
requests:
memory: 256Mi
cpu: 500m
limits:
memory: 512Mi
cpu: 1000m
lifecycle:
preStop:
exec:
command:
- /bin/bash
- '-c'
- sleep 10
readinessProbe:
httpGet:
path: /index.html
port: 80
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 1
livenessProbe:
httpGet:
path: /index.html
port: 80
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 1
---
#Service
apiVersion: v1
kind: Service
metadata:
name: service-myapp
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: myapp
type: ClusterIP
---
# Ingress
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-my
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
# host不支持IP,必须是域名
- host: k8s01.com
http:
paths:
- path: /
backend:
serviceName: service-myapp
servicePort: 80
08-recreate.yaml有几个注意点
strategy:
# 使用重建部署策略
type: Recreate
rules:
# host不支持IP,必须是域名。注意master节点的hosts配置了127.0.0.1映射到k8s01.com
- host: k8s01.com
部署
kubectl apply -f 08-recreate.yaml
新开一个master节点的终端,执行如下命令,循环请求服务。
while true; do curl http://k8s01.com:30080/index.html; sleep 0.1; done
开始升级服务,将ikubernetes/myapp升级到v2版本,查看服务是否会间断。
vim 08-recreate.yaml
image: ikubernetes/myapp:v2
升级v2版本
kubectl apply -f 08-recreate.yaml
使用重建部署策略服务会间断。
滚动更新部署
滚动更新部署策略使用新的实例逐步更新旧实例。要实现零间断更新,必须配置就绪探针readinessProbe、存活探针livenessProbe,结束容器前要休眠一小段时间。
使用08-recreate.yaml复制出08-rollingUpdate.yaml
mv 08-recreate.yaml 08-rollingUpdate.yaml
修改08-rollingUpdate.yaml的部署策略为滚动更新,并将image: ikubernetes/myapp版本改为1,只需要修改以下的红色部分即可:
spec:
strategy:
# 使用滚动更新策略
type: RollingUpdate
rollingUpdate:
# 更新期间超过期望的Pod数量为1
maxSurge: 1
# 更新期间不可用pod数量为0,即更新期间所有pod都可用
maxUnavailable: 0
selector:
matchLabels:
app: myapp
image: ikubernetes/myapp:v1
使用滚动更新部署
kubectl apply -f 08-rollingUpdate.yaml
滚动更新的过程如下图
1、myapp-7dff599968-smcgd 启动完成,处于Running状态,但是还未接收流量。READY为0/1表示pod启动完成但还没接收流量。
2、myapp-7dff599968-smcgd开始接收流量,READY为1/1;旧的myapp-697df9594f-gsl8d被中止,状态为Terminating,且不接收流量,READY为0/1。
3、旧的myapp-697df9594f-gsl8d被删除。
蓝绿部署
kubernetes实现蓝绿部署的步骤如下:
1、Deployment和Service的yaml分开写在两个文件中;Pod的标签多加一个键值对version: v1,Deployment的名称带上版本号,selector多加一个键值对version: v1;Service的selector也加一个键值对version: v1。
2、部署Deployment和Service。
3、修改Pod的标签为version: v2,镜像也改成v2版本,修改Deployment的名称,selector改为version: v2。
4、部署修改好的Deployment文件,等待v2版本的pod启动完毕,此时v1、v2版本同时在运行,但只有v1版本接收流量。
5、测试v2版本是否可用,若可用,则修改Service的selector为version: v2,将流量转给v2版本的服务。
6、若系统运行正常,删除v1版本;若系统运行不正常,修改Service的selector,将流量切换回v1。
实战
1、编写Deployment的配置文件08-blue-greed-deploy.yaml,与滚动更新部署的不同之处在于name、selector、labels做了修改,如下面红色字体所示。
# deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
spec:
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: myapp
version: v1
replicas: 2
template:
metadata:
labels:
app: myapp
version: v1
spec:
containers:
- name: containers-myapp
image: ikubernetes/myapp:v1
ports:
- containerPort: 80
resources:
requests:
memory: 256Mi
cpu: 500m
limits:
memory: 512Mi
cpu: 1000m
lifecycle:
preStop:
exec:
command:
- /bin/bash
- '-c'
- sleep 10
readinessProbe:
httpGet:
path: /index.html
port: 80
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 1
livenessProbe:
httpGet:
path: /index.html
port: 80
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 1
Service和Ingress的配置文件写在08-blue-greed-svc-ingress.yaml中,与滚动更新的不同之处是Service的selector多了版本标识,后面可通过修改版本号实现流量切换。
#service
apiVersion: v1
kind: Service
metadata:
name: service-myapp
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: myapp
version: v1
type: ClusterIP
---
# ingress
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-my
annotations:
# 控制器使用nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
# host不支持IP,必须是域名
- host: k8s01.com
http:
paths:
- path: /
backend:
serviceName: service-myapp
servicePort: 80
2、执行部署
kubectl apply -f 08-blue-greed-deploy.yaml
kubectl apply -f 08-blue-greed-svc-ingress.yaml
3、修改Deployment的配置文件为v2版本,如下面红色字体所示。
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v2
省略部分配置
selector:
matchLabels:
app: myapp
version: v2
省略部分配置
labels:
app: myapp
version: v2
spec:
省略部分配置
image: ikubernetes/myapp:v2
4、部署v2版本的Deployment。注意:只部署Deployment即可,Service暂时不切换流量。
kubectl apply -f 08-blue-greed-deploy.yaml
myapp-v1、myapp-v2同时在运行,但只有myapp-v1接收流量。
5、测试myapp-v2是否正常,若正常,则修改Service的selector,将流量转给myapp-v2,如下面红色字体所示
selector:
app: myapp
version: v2
重新部署service
kubectl apply -f 08-blue-greed-svc-ingress.yaml
6、若新版本服务正常,删除myapp-v1;若系统运行不正常,修改Service的selector,将流量切换回v1。
删除myapp-v1
kubectl delete deployment myapp-v1
使用蓝绿部署,服务不会中断。
金丝雀部署
在蓝绿部署的基础上稍加修改,就可以实现金丝雀部署。例如,删除service的selector的版本标识,让流量同时转到v1、v2版本。
#service
apiVersion: v1
kind: Service
metadata:
name: service-myapp
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: myapp
# version: v2 selector 删除版本
type: ClusterIP
两个版本都接收流量
如果要控制v1、v2版本的比例,修改deployment部署的节点数即可。