传统的单机应用发布方式会导致服务中断,用户请求会收到受影响,如果并发量较大用户体验就比较差,出了问题回退也慢。使用kubernetes零宕机发布,发布过程中服务和请求不会中断,平稳的更新版本,用户五感知,出现问题快速回。
探针是K8s对Pod内运行的应用的一种保护和预检监控机制,能够保障Pod和Pod内应用的正常运行。
K8s 1.16版本后新增的探测方式,用于判断容器内应用程序是否已经启动。如果配置了StartupProbe,会先禁止其他探测,直到其成功为止。成功后将不再进行探测(只会探测一次),成功后交由其它探针进行探测。StartupProbe主要保护启动慢的应用,比如一些初始化时间较长的应用。
存活性探针,用于探测容器是否运行,检测应用实例当前是否处于正常运行状态,如果不是,K8s会重启容器。
就绪性探针,用于探测容器内的程序是否健康,检测应用实例当前是否可以接收请求,如果不能,K8s不会转发流量。
Kubernetes在主容器的启动后和停止前提供了两个钩子函数:
Exec:在容器内执行一个命令,如果返回值为0,则认为容器健康。 TCPSocket:通过TCP连接检查容器内的端口是否通畅,如果通畅则认为容器健康。 HTTPGet:通过应用程序暴露的API地址检查程序是否正常,如果状态码为200~400之间,则认为容器健康。
示例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: carterwang/k8s-gin:1.0.0
ports:
- containerPort: 8080
livenessProbe:
exec:
command:
- cat
- /tmp/healthy.txt
initialDelaySeconds: 5
periodSeconds: 2
successThreshold: 1
readinessProbe:
httpGet:
path: /ping
port: 8080
initialDelaySeconds: 10
timeoutSeconds: 2
lifecycle:
postStart:
exec:
command: [ "/bin/sh", "-c", "echo start... > /tmp/healthy.txt" ]
preStop:
exec:
command: [ "/bin/sh", "-c", "echo postStop... > /tmp/stop.txt" ]
进入容器查看:
kubectl exec -it my-pod sh
滚动更新指的是在更新多副本的Deployment版本时,逐步创建新版本的Pod,逐步停止旧版本的Pod,以便应用一直处于可用状态。这个过程中,Service能够监视Pod的状态,将流量始终转发到可用的Pod上。
apiVersion: apps/v1
kind: Deployment
metadata:
name: pc-deployment
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
replicas: 5
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.2
maxSurge:升级过程中存在的pod数可超过replicas的个数。(值高时,保持高可用性) maxUnavailable:升级过程中可用的pod数不能小于maxUnavailable值。(值高时,侧重快速更新)
推荐配置:maxSurge: 1 和 maxUnavailable: 0 通过命令行修改镜像版本:
kubectl set image deployment pc-deployment nginx=nginx:1.17.3
使用 watch 查看滚动更新的状态:
watch kubectl get pods -l app=nginx-pod
kubectl rollout:版本升级相关功能,支持以下选项:
status:显示当前升级状态
kubectl rollout status deploy pc-deployment
history:显示升级历史记录
kubectl rollout history deploy pc-deployment
undo:回滚到上一级版本(可以使用--to-revision回滚到指定版本)
kubectl rollout undo deployment pc-deployment --to-revision=1
pause:暂停版本升级过程 resume:继续已暂停的版本升级过程 restart:重启版本升级过程
即控制Pod的数量,直接修改副本数即可。 方式一:
kubectl scale deploy pc-deployment --replicas=5
方式二:修改yaml文件中副本数,然后通过 kubectl apply -f 应用。
扩展知识:矿井中的金丝雀 17世纪,英国矿井工人发现金丝雀对瓦斯气体十分敏感。空气中哪怕有极微量的瓦斯气体,金丝雀也会停止唱歌;当瓦斯含量超过一定限度时,人类依旧毫无察觉,而金丝雀却早已毒发身亡。当时在采矿设备相对简陋的条件下,工人们每次下井都会带上一只金丝雀作为瓦斯检测工具,以便在危险情况下紧急撤离。 金丝雀发布步骤
老版本Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- name: nginx-port
protocol: TCP
port: 80
nodePort: 32600
targetPort: 80
type: NodePort
方式一:
kubectl set image deployments nginx-deployment nginx=nginx:1.8.0 && kubectl rollout pause deployments nginx-deployment
继续全部更新:
kubectl rollout resume deployments nginx-deployment
方式二: 调整镜像版本,新建一个Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-canary
labels:
app: nginx
track: canary
spec:
replicas: 1
selector:
matchLabels:
app: nginx
track: canary
template:
metadata:
labels:
app: nginx
track: canary
spec:
containers:
- name: nginx
image: nginx:1.8.0
Service的LabelSelector 是 app: nginx,由nginx-deployment和nginx-deployment-canary创建的Pod都带有标签app: nginx,所以Service的流量将会在两个release之间分配。 在新旧版本之间,流量分配的比例为两个版本副本数的比例,此处为1:3。
nginx.ingress.kubernetes.io/canary-weight
基于服务权重的流量切分,适用于蓝绿部署,权重范围0-100按百分比将请求路由到Canary Ingress中指定的服务。权重为0意味着该金丝雀规则不会向Canary入口的服务发送任何请求。权重为100意味着所有请求都将被发送到Canary入口。
for i in {1..20}; do curl demo.nginx.test; done;
nginx.ingress.kubernetes.io/canary-by-header:
基于Request Header的流量切分,适用于灰度发布以及A/B测试。当Request Header设置为"key:value"(自定义)时,请求将会被一直发送到Canary版本;对于任何其他Header值,将忽略Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较。 curl demo.nginx.test -H "region: zh"
nginx.ingress.kubernetes.io/canary-by-cookie
基于Cookie的流量切分,适用于灰度发布与A/B测试。用于通知Ingress将请求路由到Canary Ingress中指定的服务的cookie。当cookie值设置为always时,它将被路由到Canary入口; 当cookie值设置为never时,请求不会被发送到Canary入口;对于任何其他值,将忽略cookie并将请求与其他金丝雀规则进行优先级的比较。
curl demo.nginx.test --cookie "user_from_bj=always"
金丝雀规则优先顺序 canary-by-header canary-by-cookie canary-weight
示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-v1
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: carterwang/k8s-gin:1.0.0
ports:
- containerPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-v2
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: carterwang/k8s-gin:2.0.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- name: nginx-port
protocol: TCP
port: 80
nodePort: 80
targetPort: 8080
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service-v2
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- name: nginx-port
protocol: TCP
port: 80
nodePort: 81
targetPort: 8080
type: NodePort
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress-v1
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: demo.nginx.test
http:
paths:
- path: /
backend:
serviceName: nginx-service
servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress-v2
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "50"
#nginx.ingress.kubernetes.io/canary-by-header: "region"
#nginx.ingress.kubernetes.io/canary-by-header-value: "zh"
#nginx.ingress.kubernetes.io/canary-by-cookie: "canary-cookie"
spec:
rules:
- host: demo.nginx.test
http:
paths:
- path: /
backend:
serviceName: nginx-service-v2
servicePort: 80
蓝绿发布指的是一次只有一个版本处于活动状态。在创建和测试绿色部署时,流量被路由到蓝色部署。完成测试后,我们将流量路由到新版本,遇到问题时全部回滚。 正常时:
遇到异常时:
缺点: 成本高昂,因为它需要双倍的资源。
如果您喜欢我的文章,请点击下面按钮随意打赏,您的支持是我最大的动力。
最新评论