用kubernetes对服务进行灰度发布和蓝绿部署
基本概念
灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。
蓝绿部署是不停老版本,部署新版本然后进行测试,确认OK,将流量切到新版本,然后老版本同时也升级到新版本。
灰度是不同版本共存,蓝绿是新旧版本切换,2种模式的出发点不一样。
环境准备
1. 下载安装minikube
minikube是一个可以快速在单机上部署kubernetes并运行容器的工具,由于条件有限,我都是用它来学习Kubernetes知识。
Mac OSX
1curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.13.0/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
Linux
1curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.13.0/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
2. 启动
本机环境需提前安装好docker-engine
1minikube start --driver=none
启动成功之后,查看启动的pods
1kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6c76c8bb89-nz22j 1/1 Running 2 24h
kube-system etcd-minikube 1/1 Running 2 24h
kube-system kube-apiserver-minikube 1/1 Running 2 24h
kube-system kube-controller-manager-minikube 1/1 Running 2 24h
kube-system kube-proxy-2qwq9 1/1 Running 2 24h
kube-system kube-scheduler-minikube 1/1 Running 2 24h
kube-system storage-provisioner 1/1 Running 3 24h
kubernetes-dashboard dashboard-metrics-scraper-c95fcf479-7qnhf 1/1 Running 0 24h
kubernetes-dashboard kubernetes-dashboard-5c448bc4bf-6gccm 1/1 Running 0 24h
3. 准备镜像
准备Dockerfile文件
FROM python:alpine
RUN pip install flask -i https://pypi.douban.com/simple
COPY app.py /app.py
EXPOSE 5000
ENTRYPOINT ["python", "/app.py"]
app.py
1from flask import Flask
2from flask import request
3from flask import jsonify
4import socket
5
6
7app = Flask(__name__)
8
9@app.route('/')
10def index():
11 return jsonify({'Version': 'v1',
12 'Hostname': socket.gethostname(),
13 'Address': socket.gethostbyname(socket.gethostname()),
14 'Message': 'Hello, World',
15 })
16
17
18
19if __name__ == '__main__':
20 app.run('0.0.0.0', 5000)
构建第一个镜像:
1docker build . -t flask-app:v1
构建第二个镜像:
先将app.py里面的v1改为v2
1docker build . -t flask-app:v2
如此我们便有了两个版本的镜像。
蓝绿部署
准备deployment和service文件,内容如下:
deployment-v1.yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: flask-app
5spec:
6 replicas: 1
7 selector:
8 matchLabels:
9 app: flask-app
10 version: v1
11 template:
12 metadata:
13 labels:
14 app: flask-app
15 version: v1
16 spec:
17 containers:
18 - image: flask-app:v1
19 name: flask-app
20 ports:
21 - containerPort: 5000
deployment-v2.yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: flask-app-v2
5spec:
6 replicas: 1
7 selector:
8 matchLabels:
9 app: flask-app
10 version: v2
11 template:
12 metadata:
13 labels:
14 app: flask-app
15 version: v2
16 spec:
17 containers:
18 - image: flask-app:v2
19 name: flask-app
20 ports:
21 - containerPort: 5000
service.yaml
1apiVersion: v1
2kind: Service
3metadata:
4 name: flask-app
5spec:
6 ports:
7 - name: "http"
8 port: 5000
9 protocol: TCP
10 targetPort: 5000
11 selector:
12 app: flask-app
13 version: v1
14 type: NodePort
执行: kubectl apply -f deployment-v1.yaml
执行: kubectl apply -f service.yaml
执行: minikube ip 查看节点ip, kubectl get svc查看nodeport端口
执行: curl $http://${node_ip}:${node_port}
输出:
{"Address":"172.17.0.4","Hostname":"flask-app-69cd76c45c-kpzn5","Message":"Hello, World","Version":"v1"}
执行: kubectl apply -f deployment-v2.yaml
将service.yaml里面的v1全部改为v2
执行: kubectl apply -f service.yaml
继续执行: curl $http://${node_ip}:${node_port}
输出:
{"Address":"172.17.0.8","Hostname":"flask-app-v2-6748f77677-vb4rx","Message":"Hello, World","Version":"v2"}
灰度发布
进行灰度发布之前先清理一下之前的deployment和service
1kubectl delete -f deployment-v1.yaml
2kubectl delete -f deployment-v2.yaml
3kubectl delete -f service.yaml
准备几个文件
deployment-canary-v1.yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: flask-app-v1
5spec:
6 replicas: 1
7 selector:
8 matchLabels:
9 app: flask-app
10 template:
11 metadata:
12 labels:
13 app: flask-app
14 spec:
15 containers:
16 - image: flask-app:v1
17 name: flask-app
18 ports:
19 - containerPort: 5000
deployment-canary-v2.yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4 name: flask-app-v2
5spec:
6 replicas: 1
7 selector:
8 matchLabels:
9 app: flask-app
10 template:
11 metadata:
12 labels:
13 app: flask-app
14 spec:
15 containers:
16 - image: flask-app:v2
17 name: flask-app
18 ports:
19 - containerPort: 5000
service-canary.yaml
1apiVersion: v1
2kind: Service
3metadata:
4 name: flask-app
5spec:
6 ports:
7 - name: "http"
8 port: 5000
9 protocol: TCP
10 targetPort: 5000
11 selector:
12 app: flask-app
13 type: NodePort
执行:
1kubectl apply -f deployment-canary-v1.yaml
2kubectl apply -f deployment-canary-v2.yaml
3kubectl apply -f service-canary.yaml
执行: kubectl get svc查看nodeport
执行:
1while true; do curl http://${node_ip}:${node_port}; done
输出:
{"Address":"172.17.0.7","Hostname":"flask-app-69cd76c45c-knn4c","Message":"Hello, World","Version":"v1"}
{"Address":"172.17.0.4","Hostname":"flask-app-v2-7c957654cc-2mtbb","Message":"Hello, World","Version":"v2"}
{"Address":"172.17.0.4","Hostname":"flask-app-v2-7c957654cc-2mtbb","Message":"Hello, World","Version":"v2"}
{"Address":"172.17.0.4","Hostname":"flask-app-v2-7c957654cc-2mtbb","Message":"Hello, World","Version":"v2"}
{"Address":"172.17.0.7","Hostname":"flask-app-69cd76c45c-knn4c","Message":"Hello, World","Version":"v1"}
{"Address":"172.17.0.7","Hostname":"flask-app-69cd76c45c-knn4c","Message":"Hello, World","Version":"v1"}
{"Address":"172.17.0.4","Hostname":"flask-app-v2-7c957654cc-2mtbb","Message":"Hello, World","Version":"v2"}
利用service roundrobin负载均衡,可以看到v1与v2的服务共存。

评论列表:
暂无评论 😭