文章目录
一、Kubernetes实现蓝绿部署
1.1 什么是蓝绿部署
蓝绿部署,英文名Blue Green Deployment,是一种可以保证系统在不间断提供服务的情况下上线的部署方式。
蓝绿部署的模型中包含两个集群,就好比海豚的左脑和右脑。
在没有上线的正常情况下,集群A和集群B的代码版本是一致的,并且同时对外提供服务。
在系统升级的时候下,我们首先把一个集群(比如集群A)从负载列表中摘除,进行新版本的部署。集群B仍然继续提供服务。
当集群A升级完毕,我们把负载均衡重新指向集群A,再把集群B从负载列表中摘除,进行新版本的部署。集群A重新提供服务。
1.2 滚动更新
// 创建模块
[root@master ~]# mkdir apache
// 编写 dockerfile文件
[root@master ~]# cat apache/Dockerfile
FROM busybox
RUN mkdir /data && \
echo "hello amu,This is test1" > /data/index.html
ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
#v1版本
// 创建两个不同版本的镜像
[root@master ~]# docker build -t gaofan1225/httpd:v1 apache/
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM busybox
latest: Pulling from library/busybox
3cb635b06aa2: Pull complete
Digest: sha256:b5cfd4befc119a590ca1a81d6bb0fa1fb19f1fbebd0397f25fae164abe1e8a6a
Status: Downloaded newer image for busybox:latest
---> ffe9d497c324
Step 2/3 : RUN mkdir /data && echo "hello amu,This is test1" > /data/index.html
---> Running in 2400a9edc3b7
Removing intermediate container 2400a9edc3b7
---> b596ff036149
Step 3/3 : ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
---> Running in 9bad15d04393
Removing intermediate container 9bad15d04393
---> 21d6bd11fd0d
Successfully built 21d6bd11fd0d
Successfully tagged gaofan1225/httpd:v1
#v2版本
// 创建之前修改dockerfile这一行:echo "hello amu,This is test2" > /data/index.html
[root@master ~]# cat apache/Dockerfile
FROM busybox
RUN mkdir /data && \
echo "hello amu,This is test2" > /data/index.html // 修改这里
ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
[root@master ~]# docker build -t gaofan1225/httpd:v2 apache/
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM busybox
---> ffe9d497c324
Step 2/3 : RUN mkdir /data && echo "hello amu,This is test2" > /data/index.html
---> Using cache
---> b596ff036149
Step 3/3 : ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
---> Using cache
---> 21d6bd11fd0d
Successfully built 21d6bd11fd0d
Successfully tagged gaofan1225/httpd:v2
// 登录 docker.hub仓库
[root@master ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: gaofan1225
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
// 上传镜像当 docker.hub仓库
[root@master ~]# docker push gaofan1225/httpd:v1
The push refers to repository [docker.io/gaofan1225/httpd]
88be387e4d70: Pushed
64cac9eaf0da: Mounted from library/busybox
v1: digest: sha256:074bdf0f11e9ee6f4efb2c12f67fdfab4eae8472fae1a75eb5004f3e5884ad3e size: 734
[root@master ~]# docker push gaofan1225/httpd:v2
The push refers to repository [docker.io/gaofan1225/httpd]
88be387e4d70: Pushed
64cac9eaf0da: Layer already exists
v2: digest: sha256:074bdf0f11e9ee6f4efb2c12f67fdfab4eae8472fae1a75eb5004f3e5884ad3e size: 734
// 创建一个httpd容器,使用v1版本的,并复制成三个
[root@master ~]# kubectl create deployment httpd --image gaofan1225/httpd:v1 --replicas 3
deployment.apps/httpd created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-8556845dfd-gct9q 1/1 Running 0 58s
httpd-8556845dfd-hcqrk 1/1 Running 0 58s
httpd-8556845dfd-zv9qz 1/1 Running 0 58s
// 暴露端口
[root@master ~]# kubectl expose deployment httpd --port 80 --target-port 80
service/httpd exposed
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
httpd ClusterIP 10.96.192.41 <none> 80/TCP 6s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3m35s
// 访问测试
[root@master ~]# curl 10.96.192.41
hello amu,This is test1
// 做一个死循环
[root@master ~]# while :;do curl 10.96.192.41;done
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1 // v1版本这里会一直滚动
......以下省略
// 升级版本
[root@master ~]# kubectl set image deployment/httpd httpd=gaofan1225/httpd:v2
deployment.apps/httpd image updated
// 正在升级中
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-59b875c9dc-kkbdh 1/1 Running 0 4s
httpd-59b875c9dc-lhpjz 1/1 Running 0 6s
httpd-59b875c9dc-s7gmz 1/1 Running 0 8s
httpd-8556845dfd-fb887 1/1 Terminating 0 5m9s
httpd-8556845dfd-fhvlx 1/1 Terminating 0 5m6s
httpd-8556845dfd-l4rww 1/1 Terminating 0 5m7s
[root@master ~]# while :;do curl 10.96.192.41;done
hello amu,This is test1
hello amu,This is test2
hello amu,This is test1
hello amu,This is test2
hello amu,This is test1
hello amu,This is test2
hello amu,This is test1
hello amu,This is test2
......以下省略 // 升级过程中,两个版本的服务会同时滚动
// 升级结束
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-59b875c9dc-kkbdh 1/1 Running 0 71s
httpd-59b875c9dc-lhpjz 1/1 Running 0 73s
httpd-59b875c9dc-s7gmz 1/1 Running 0 75s
// 升级完成再去看死循环
[root@master ~]# while :;do curl 10.96.192.41;done
hello amu,This is test2
hello amu,This is test2
hello amu,This is test2
hello amu,This is test2
hello amu,This is test2
hello amu,This is test2
hello amu,This is test2
hello amu,This is test2
......以下省略 // 升级完成,v2版本一直滚动
1.2 回滚
// 回滚,返回上个版本
[root@master ~]# kubectl rollout undo deployment/httpd
deployment.apps/nginx rolled back
// 开始回滚
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-59b875c9dc-kkbdh 1/1 Terminating 0 3m
httpd-59b875c9dc-lhpjz 1/1 Terminating 0 3m2s
httpd-59b875c9dc-s7gmz 1/1 Running 0 3m4s
httpd-8556845dfd-nzkvg 1/1 Running 0 1s
httpd-8556845dfd-zqqz4 1/1 Running 0 3s
httpd-8556845dfd-zt4b2 0/1 ContainerCreating 0 0s
// 回滚成功
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
httpd-8556845dfd-nzkvg 1/1 Running 0 44s
httpd-8556845dfd-zqqz4 1/1 Running 0 46s
httpd-8556845dfd-zt4b2 1/1 Running 0 43s
// 回滚完成再去看死循环
[root@master ~]# while :;do curl 10.96.192.41;done
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1
hello amu,This is test1· // 回滚成功,这里 v1 版本会一直滚动
......以下省略
二、使用yaml(yml)文件创建、删除容器
k8s是一个容器编排引擎,使用YAML文件编排要部署应用,因此在学习之前,应先了解YAML语法格式:
- 缩进表示层级关系
- 不支持制表符 ”tab“ 缩进,使用空格缩进
- 通常开头缩进 2 个空格
- 字符后缩进 1 个空格,如冒号、逗号等
- “—” 表示YAML格式,一个文件的开始
- “#” 注释
必写参数:
参数名字 | 意思 |
---|---|
apiVersion | API版本 |
Kind | 资源类型 |
metadata | 资源元数据 |
spec | 资源规格 |
replicas | 副本数量 |
selector | 标签选择器 |
template | Pod模板 |
metadata | Pod元数据 |
spec | Pod规格 |
containers | 容器配置 |
当你不知道命令怎么编写的时候使用 explain查看注释
下面这个就是查看 metadata的注释Pod容器的字段拼写 kubectl + explain + 类型 + 对象命令 kubectl + explain + 类型 + 对象命令 + 对象命令分类 // 查看 metadata使用方式 [root@master ~]# kubectl explain deployment.metadata // 查看 metadata对象的namespace的使用方式 [root@master ~]# kubectl explain deployment.metadata.namespace // 列表对象开头必须添加 "-" <[]Object>
可参考的一个yaml文件图:
实例中
[root@master ~]# cd /opt/
// 创建目录
[root@master opt]# mkdir manifes
[root@master opt]# cd manifest/
// 编写 dockerfile
# v1.1
[root@master manifest]# cat /root/apache/Dockerfile
FROM busybox
RUN mkdir /data && \
echo "Hi amu,This is v1" > /data/index.html
ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
[root@master manifest]# docker build -t gaofan1225/httpd:v1.1 /root/apache/
# v1.2
[root@master manifest]# cat /root/apache/Dockerfile
FROM busybox
RUN mkdir /data && \
echo "Hi amu,This is v2" > /data/index.html
ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
[root@master manifest]# docker build -t gaofan1225/httpd:v1.2 /root/apache/
// 查看镜像
ENTRYPOINT ["/bin/httpd","-f","-h","/data"]
[root@master manifest]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
gaofan1225/httpd v1.2 c69e150e53dd 4 hours ago 1.24MB
gaofan1225/httpd v1.1 234a7ae0ec78 4 hours ago 1.24MB
// 编写 deployment类型的 yaml文件
[root@master manifest]# vi deploy.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
selector: #选择
matchLabels: #匹配标签
app: amu
template: #模板
metadata: #元数据
labels: #标签
app: amu
spec:
containers:
- image: gaofan1225/httpd:v1.1 #容器对象
imagePullPolicy: IfNotPresent #镜像拉取策略
name: httpd
等同于:kubectl create deployment web --image=gaofan1225/httpd:v1.1 --replicas=3 -n default
[root@master manifest]# vi svc-deploy.yaml
apiversion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
ports:
- port: 8001
protocol: TCP #协议
targetPort: 80
selector:
app: amu
type: NodePort #类型
等同于:kubectl expose deployment web --port=8001 --target-port=80
// 查看pod、svc、deployment类型容器
[root@master manifest]# kubectl get pods
No resources found in default namespace.
[root@master manifest]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 28m
[root@master ~]# kubectl get deployment
No resources found in default namespace.
// 创建容器
[root@master manifest]# kubectl create -f deploy.yaml
deployment.apps/web created
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-685c878c69-jkz62 1/1 Running 0 7s
web-685c878c69-nf968 1/1 Running 0 7s
web-685c878c69-vb7x6 1/1 Running 0 7s
[root@master ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
web 3/3 3 3 79s
[root@master manifest]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6h11m
web NodePort 10.108.194.44 <none> 8001:30531/TCP 9s
// 访问测试
[root@master manifest]# curl 10.108.194.44:8001
Hi amu,This is v1
页面访问
访问:本机IP + 30531
// 版本升级
[root@master manifest]# vi deploy.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: amu
template:
metadata:
labels:
app: amu
spec:
containers:
- image: gaofan1225/httpd:v1.2 // 修改版本,删除 imagePullPolicy
name: httpd
[root@master manifest]# kubectl apply -f deploy.yaml
Warning: resource deployments/web is missing the kubectlt-applied-configuration annotation which is required by ectl apply should only be used on resources created declr kubectl create --save-config or kubectl apply. The misll be patched automatically.
deployment.apps/web configured
[root@master manifest]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6h46m
web NodePort 10.108.194.44 <none> 8001:30531/TCP 35m
[root@master manifest]# curl 10.108.194.44:8001
Hi amu,This is v2
// 删除资源
[root@master manifest]# kubectl delete -f deploy.yaml
deployment.apps "web" deleted
[root@master manifest]# kubectl delete -f svc-deploy.yaml
service "web" deleted
[root@master manifest]# kubectl get pods
No resources found in default namespace.
// 文件还是存在的
[root@master manifest]# ls
deploy.yaml svc-deploy.yaml
页面访问
注意:版本更新只需要更改文件里面的容器名字版本,升级也是一样,所以使用yaml文件部署容器,非常方便!!!
两个文件也可以合并写
[root@master manifest]# vi deploy.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: amu
template:
metadata:
labels:
app: amu
spec:
containers:
- image: gaofan1225/httpd:v1.1
imagePullPolicy: IfNotPresent
name: httpd
--- // 中间使用 “---”隔开
apiversion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
ports:
- port: 8001
protocol: TCP
targetPort: 80
selector:
app: amu
type: NodePort
三、自动创建 YAML文件
4.1 用create命令生成
kubectl create deployment nginx –image==nginx:1.16 -o yaml –dry-run=client > my-deploy.yaml
示例:
[root@master manifest]# kubectl create deployment nginx --image=nginx --dry-run=client -o yaml > nginx.yaml
[root@master manifest]# ls
deploy.yaml nginx.yaml svc-deploy.yaml
[root@master manifest]# cat nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
4.2 用get命令导出
kubectl get deployment nginx -o yaml > my-deploy.yaml
示例:
[root@master manifest]# kubectl create deployment nginx --image nginx --replicas 3
deployment.apps/nginx created
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-85b98978db-8b9xj 0/1 ContainerCreating 0 11s
nginx-85b98978db-dds2s 0/1 ContainerCreating 0 11s
nginx-85b98978db-sg9qn 0/1 ContainerCreating 0 11s
[root@master manifest]# kubectl get deployment nginx -o yaml > nginx.yaml
# get获取的信息比create获取的信息更详细
[root@master manifest]# cat nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2021-12-21T09:16:57Z"
generation: 1
labels:
app: nginx
name: nginx
namespace: default
resourceVersion: "85342"
uid: ea5653ea-9fd2-424e-9267-2b1112771835
spec:
progressDeadlineSeconds: 600
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
conditions:
- lastTransitionTime: "2021-12-21T09:16:57Z"
lastUpdateTime: "2021-12-21T09:16:57Z"
message: Deployment does not have minimum availability.
reason: MinimumReplicasUnavailable
status: "False"
type: Available
- lastTransitionTime: "2021-12-21T09:16:57Z"
lastUpdateTime: "2021-12-21T09:16:57Z"
message: ReplicaSet "nginx-85b98978db" is progressing.
reason: ReplicaSetUpdated
status: "True"
type: Progressing
observedGeneration: 1
replicas: 3
unavailableReplicas: 3
updatedReplicas: 3
注意:不建议使用以上两种方法,还是建议手写,手写使用起来会更方便!
将你需要创建的资源描述到YAML文件中
部署:kubectl apply -f xxx.yaml
卸载:kubectl delete -f xxx.yaml
四、名称空间创建
// 没有pod就没有控制器
[root@master manifest]# kubectl get pods
No resources found in default namespace.
// 干跑查看格式
[root@master manifest]# kubectl create namespace runtime --dry-run=client
namespace/runtime created (dry run)
[root@master manifest]# kubectl create namespace runtime --dry-run=client -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: null
name: runtime
spec: {}
status: {}
[root@master manifest]# cat test.yaml
---
apiVersion: v1
kind: Namespace // 名称空间
metadata:
name: runtime
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: amu
template:
metadata:
labels:
app: amu
spec:
containers:
- image: gaofan1225/httpd:v1.1
imagePullPolicy: IfNotPresent
name: httpd
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: default
spec:
ports:
- port: 8001
protocol: TCP
targetPort: 80
selector:
app: amu
type: NodePort
[root@master manifest]# kubectl create -f test.yaml
namespace/runtime created
deployment.apps/web created
service/web created
[root@master manifest]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-6f5fb9dd4d-5bmnl 1/1 Running 0 6s
web-6f5fb9dd4d-5rzg5 1/1 Running 0 6s
web-6f5fb9dd4d-vvcbf 1/1 Running 0 6s
// runtime名称空间创建成功
[root@master manifest]# kubectl get ns
NAME STATUS AGE
default Active 3d5h
kube-node-lease Active 3d5h
kube-public Active 3d5h
kube-system Active 3d5h
runtime Active 14s
[root@master manifest]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
web 3/3 3 3 5m55s
[root@master manifest]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7h53m
web NodePort 10.111.5.34 <none> 8001:31860/TCP 9m59s
// 访问测试
[root@master manifest]# curl 10.111.5.34:8001
Hi amu,This is v1
// 删除名称空间
[root@master manifest]# kubectl delete -f test.yaml
namespace "runtime" deleted
deployment.apps "web" deleted
service "web" deleted
[root@master manifest]# kubectl get ns
NAME STATUS AGE
default Active 3d5h
kube-node-lease Active 3d5h
kube-public Active 3d5h
kube-system Active 3d5h
总结:创建名称空间也可以靠yaml文件实现,不需要的时候直接删除yaml文件资源就可以删除,启用的时候直接指定yaml文件就行,非常方便!
五、健康检查
强大的自愈能力是 Kubernetes 这类容器编排引擎的一个重要特性。自愈的默认实现方式是自动重启发生故障的容器。除此之外,用户还可以利用 Liveness 和 Readiness 探测机制设置更精细的健康检查,进而实现如下需求:
零停机部署。
避免部署无效的镜像。
更加安全的滚动升级。
六、探针类型
Liveness探测:
- Liveness 探测让用户可以自定义判断容器是否健康的条件。如果探测失败,Kubernetes 就会重启容器。
Readiness探测:
-
除了 Liveness 探测,Kubernetes Health Check 机制还包括 Readiness 探测。
-
用户通过 Liveness 探测可以告诉 Kubernetes 什么时候通过重启容器实现自愈;Readiness 探测则是告诉 Kubernetes 什么时候可以将容器加入到 Service 负载均衡池中,对外提供服务。
Liveness 和 Readiness的比较:
-
Liveness 探测和 Readiness 探测是两种 Health Check 机制,如果不特意配置,Kubernetes 将对两种探测采取相同的默认行为,即通过判断容器启动进程的返回值是否为零来判断探测是否成功。
-
两种探测的配置方法完全一样,支持的配置参数也一样。不同之处在于探测失败后的行为:Liveness 探测是重启容器;Readiness 探测则是将容器设置为不可用,不接收 Service 转发的请求。
-
Liveness 探测和 Readiness 探测是独立执行的,二者之间没有依赖,所以可以单独使用,也可以同时使用。用 Liveness 探测判断容器是否需要重启以实现自愈;用 Readiness 探测判断容器是否已经准备好对外提供服务。
七、应用自修复
重启策略+监控检查
重启策略:
- Always:当容器终止退出后,总是重启容器,默认策略。
- OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。
- Never:当容器终止退出,从不重启容器。
健康检查类型:
- livenessProbe(存货检查):如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。
- readinessProbe(就绪检查):如果检查失败,Kubernetes会把Pod从service endpoints中剔除。
支持的检查方法:
- httpGet:发送HTTP请求,返回200-400范围状态码为成功。
- exec:执行Shell命令返回状态码是0为成功。
- tcpSocket:发起TCP Socket建立成功。
下一篇 Kubernetes进阶(二)已经发布了,主要说明了 Pod调度以及污点、污点容忍。欢迎有兴趣的小伙伴们前来指点。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/5569.html