目录
[一、K8s 资源管理操作分类](#一、K8s 资源管理操作分类)
[1.1. 陈述式](#1.1. 陈述式)
[1.2. 声明式](#1.2. 声明式)
[3.1.创建 kubectl create 命令](#3.1.创建 kubectl create 命令)
[3.2.发布 kubectl expose 命令](#3.2.发布 kubectl expose 命令)
[3.2.1.将资源暴露为新的 Service](#3.2.1.将资源暴露为新的 Service)
[3.2.2.Kubernetes 之所以需要 Service](#3.2.2.Kubernetes 之所以需要 Service)
[3.2.2 service 的 type 类型](#3.2.2 service 的 type 类型)
[3.2..3 无头模式 headless clusterIP](#3.2..3 无头模式 headless clusterIP)
[3.2.4 端口类型](#3.2.4 端口类型)
[3.3.1查看 pod 网络状态详细信息和 Service 暴露的端口](#3.3.1查看 pod 网络状态详细信息和 Service 暴露的端口)
[3.3.3.查看 service 的描述信息](#3.3.3.查看 service 的描述信息)
[3.4.更新版本 kubectl set](#3.4.更新版本 kubectl set)
[3.4.1. 查看当前 nginx 的版本号](#3.4.1. 查看当前 nginx 的版本号)
[3.5. 回滚 kubectl rollout](#3.5. 回滚 kubectl rollout)
[3.6.删除 kubectl delete](#3.6.删除 kubectl delete)
[3.6.1 删除副本控制器](#3.6.1 删除副本控制器)
[3.6.2.删除 service](#3.6.2.删除 service)
[3.7. 金丝雀发布(灰度发布)](#3.7. 金丝雀发布(灰度发布))
[3.7.1. 更新 deployment 的版本,并配置暂停 deployment](#3.7.1. 更新 deployment 的版本,并配置暂停 deployment)
[3.7.2.开启另一个窗口查看 pod 信息](#3.7.2.开启另一个窗口查看 pod 信息)
[3.7.3.确保更新的 pod 没问题,继续更新](#3.7.3.确保更新的 pod 没问题,继续更新)
一、K8s 资源管理操作分类
1.1. 陈述式
通过 kubectl 命令的方式来实现对资源进行管理,简而言之,就是通过一条命令来实现操作,如查看节点信息等;对资源的增、删、查操作比较方便,但对改的操作就不容易了。
kubectl 是官方的 CLI 命令行工具,用于与 apiserver 进行通信,将用户在命令行输入的命令,组织并转化为 apiserver 能识别的信息,进而实现管理 k8s 各种资源的一种有效途径。
kubectl 的命令大全
k8s中文文档:Kubernetes kubectl 命令表 _ Kubernetes(K8S)中文文档_Kubernetes中文社区
1.2. 声明式
通过使用 yaml 或 josn 文件对资源配置,然后再实现对资源的管理。
二、陈述式资源管理方法
1.kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口
2.kubectl 是官方的CLI命令行工具,用于与 apiserver 进行通信,将用户在命令行输入的命令,组
织并转化为 apiserver 能识别的信息,进而实现管理 k8s 各种资源的一种有效途径
3.kubectl 的命令大全
kubectl --help
k8s中文文档:http://docs.kubernetes.org.cn/683.html
4.对资源的增、删、查操作比较方便,但对改的操作就不容易了
css
//查看版本信息
kubectl version
//查看资源对象简写
kubectl api-resources
//查看集群信息
kubectl cluster-info
//配置kubectl自动补全
source <(kubectl completion bash)
//node节点查看日志
journalctl -u kubelet -f
二、基本信息查看
kubectl get <resource> [-o wide|json|yaml] [-n namespace]
获取资源的相关信息,-n 指定命令空间,-o 指定输出格式
resource可以是具体资源名称,如pod nginx-xxx;也可以是资源类型,如pod;或者all(仅展示几种核心资源,并不完整)
--all-namespaces 或 -A :表示显示所有命令空间,
--show-labels :显示所有标签
-l app :仅显示标签为app的资源
-l app=nginx :仅显示包含app标签,且值为nginx的资源
css
//查看 master 节点状态
kubectl get componentstatuses
kubectl get cs
//查看命令空间
kubectl get namespace
kubectl get ns
//命令空间的作用:用于允许不同 命令空间 的 相同类型 的资源 重名的
//查看default命名空间的所有资源
kubectl get all [-n default]
//创建命名空间app
kubectl create ns app
kubectl get ns
//删除命名空间app
kubectl delete namespace app
kubectl get ns
//在命名空间kube-public 创建副本控制器(deployment)来启动Pod(nginx-wl)
kubectl create deployment nginx-wl --image=nginx -n kube-public
//描述某个资源的详细信息
kubectl describe deployment nginx-wl -n kube-public
kubectl describe pod nginx-wl-d47f99cb6-hv6gz -n kube-public
//查看命名空间kube-public 中的pod 信息
kubectl get pods -n kube-public
NAME READY STATUS RESTARTS AGE
nginx-wl-d47f99cb6-hv6gz 1/1 Running 0 24m
//kubectl exec可以跨主机登录容器,docker exec 只能在容器所在主机上登录
kubectl exec -it nginx-wl-d47f99cb6-hv6gz bash -n kube-public
//删除(重启)pod资源,由于存在deployment/rc之类的副本控制器,删除pod也会重新拉起来
kubectl delete pod nginx-wl-d47f99cb6-hv6gz -n kube-public
//若pod无法删除,总是处于terminate状态,则要强行删除pod
kubectl delete pod <pod-name> -n <namespace> --force --grace-period=0
#grace-period表示过渡存活期,默认30s,在删除pod之前允许POD慢慢终止其上的容器进程,从而优雅退出,0表示立即终止pod
//扩缩容
kubectl scale deployment nginx-wl --replicas=2 -n kube-public # 扩容
kubectl scale deployment nginx-wl --replicas=1 -n kube-public # 缩容
//删除副本控制器
kubectl delete deployment nginx-wl -n kube-public
kubectl delete deployment/nginx-wl -n kube-public
端口总结:
port:为service在clusterp暴露的端口
targetport:对应容器映射在pod上的端口
nodeport:可以通过k8s集群外部使用的NodeIp+Nodeport访问servicecontainerPort容器内部进程使用的端
k8s集群内部 客户端--》clusterIp:port--》通过targetport--》pod:ip containerPortk8s集群外部 客户端--》nodeip:nodeport--》通过targetport--》pod:ip containerPort
三、项目的生命周期
Kubernetes 项目的生命周期包括设计、开发、部署、运行和维护等阶段。在设计和开发阶段,需要定义应用程序的架构和容器镜像,以及创建 Kubernetes 资源对象。在部署和运行阶段,需要使用 kubectl 命令将应用程序部署到 Kubernetes 集群中,并进行监控和维护。即:创建-->发布-->更新-->回滚-->删除。
3.1.创建 kubectl create 命令
- 创建并运行一个或多个容器镜像
- 创建一个 deployment 或 job 来管理容器
启动 nginx 实例,暴露容器端口 80,设置副本数 3
css
[root@master01 ~]# kubectl create deployment nginx-01 --image=nginx:1.14 --port=80 --replicas=3 -n fql
deployment.apps/nginx-01 created
[root@master01 ~]# kubectl get pod -o wide -n fql
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-01-799fb6fb65-296dl 1/1 Running 0 24s 10.244.1.18 node01 <none> <none>
nginx-01-799fb6fb65-jhqt2 1/1 Running 0 24s 10.244.1.19 node01 <none> <none>
nginx-01-799fb6fb65-kqbc2 1/1 Running 0 24s 10.244.2.13 node02 <none> <none>
3.2.发布 kubectl expose 命令
3.2.1.将资源暴露为新的 Service
为 deployment 的 nginx 创建 service,并通过 Service 的80端口转发至容器的80端口上,Service的名称为 nginx-service,类型为 NodePort。
css
[root@master01 ~]# kubectl expose deployment nginx-01 -n fql --port=80 --target-port=80 --name=nginx-server --type=NodePort
service/nginx-server exposed
3.2.2.Kubernetes 之所以需要 Service
一方面是因为 Pod 的 IP 不是固定的(Pod可能会重建)
另一方面则是因为一组 Pod 实例之间总会有负载均衡的需求
对于容器应用而言,Kubernetes 提供了基于 VIP(虚拟IP) 的网桥的方式访问 Service,再由 Service 重定向到相应的 Pod
3.2.2 service 的 type 类型
ClusterIP:提供一个集群内部的虚拟IP以供Pod访问(service默认类型)
NodePort:在每个Node上打开一个端口以供外部访问,Kubernetes将会在每个Node上打开一个端口并且每个Node的端口都是一样的,通过 NodeIp:NodePort 的方式Kubernetes集群外部的程序可以访问Service
每个端口只能是一种服务,端口范围只能是 30000-32767
LoadBalancer:通过设置LoadBalancer映射到云服务商提供的LoadBalancer地址。这种用法仅用于在公有云服务提供商的云平台上设置Service的场景。通过外部的负载均衡器来访问,通常在云平台部署LoadBalancer还需要额外的费用
在service提交后,Kubernetes就会调用CloudProvider在公有云上为你创建一个负载均衡服务,并且把被代理的Pod的IP地址配置给负载均衡服务做后端
externalName:将service名称映射到一个DNS域名上,相当于DNS服务的CNAME记录,用于让Pod去访问集群外部的资源,它本身没有绑定任何的资源。 tgc.benet.com www.benet.com
3.2..3 无头模式 headless clusterIP
是Kubernetes中一种特殊类型的服务,它不会为服务创建ClusterIP,而是直接将DNS解析指向服务的每个Pod的IP地址。这种模式适用于需要直接与每个Pod进行通信的场景,而不需要负载均衡或代理。
3.2.4 端口类型
① port
port 是 k8s 集群内部访问 service 的端口,即通过 clusterIP: port 可以从 Pod 所在的 Node 上访问到 service(四层)
② nodePort
nodePort 是外部访问 k8s 集群中 service 的端口,通过 nodeIP: nodePort 可以从外部访问到某个 service
③ targetPort
targetPort 是 Pod 的端口,从 port 或 nodePort 来的流量经过 kube-proxy 反向代理负载均衡转发到后端 Pod 的 targetPort 上,最后进入容器
④ containerPort
containerPort 是 Pod 内部容器的端口,targetPort 映射到 containerPort
3.3.1查看 pod 网络状态详细信息和 Service 暴露的端口
css
[root@master01 ~]# kubectl get pod,svc -o wide -n fql
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/nginx-01-799fb6fb65-296dl 1/1 Running 0 90s 10.244.1.18 node01 <none> <none>
pod/nginx-01-799fb6fb65-jhqt2 1/1 Running 0 90s 10.244.1.19 node01 <none> <none>
pod/nginx-01-799fb6fb65-kqbc2 1/1 Running 0 90s 10.244.2.13 node02 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/nginx-server NodePort 10.96.153.145 <none> 80:32591/TCP 32s app=nginx-01
使用客户端浏览器访问任意一个节点ip的32591端口,都可以访问到nginx的pod实例
css
[root@master01 ~]# curl 192.168.190.101:32591
<title>Welcome to nginx!</title>
[root@master01 ~]# curl 192.168.190.102:32591
<title>Welcome to nginx!</title>
3.3.2.查看关联后端的节点
css
[root@master01 ~]# kubectl get endpoints -n fql
NAME ENDPOINTS AGE
nginx-server 10.244.1.18:80,10.244.1.19:80,10.244.2.13:80 75s
3.3.3.查看 service 的描述信息
css
[root@master01 ~]# kubectl describe svc nginx -n fql
Name: nginx-server # Service的名称为nginx-server
Namespace: fql # Service位于fql命名空间中
Labels: app=nginx-01 # Service的标签为app=nginx-01
Annotations: <none> # Service没有任何注释信息
Selector: app=nginx-01 # Service通过标签选择器app=nginx-01选择与之匹配的Pod
Type: NodePort # Service的类型为NodePort,表示将Service暴露到集群外部,并使用Node的IP地址和端口号来访问Service
IP Families: <none> # Service没有指定IP地址族
IP: 10.96.153.145 # Service的IP地址为10.96.153.145
IPs: 10.96.153.145 # Service的IP地址为10.96.153.145
Port: <unset> 80/TCP # Service暴露的端口号为80,使用TCP协议
TargetPort: 80/TCP # Service将请求转发到Pod的端口号为80,使用TCP协议
NodePort: <unset> 32591/TCP # Service将使用Node的IP地址和端口号32591来暴露Service,使用TCP协议
Endpoints: 10.244.1.18:80,10.244.1.19:80,10.244.2.13:80 # Service的后端是3个Pod
Session Affinity: None # Service没有启用会话亲和性
External Traffic Policy: Cluster # Service的外部流量策略为Cluster
Events: <none> # Service没有任何事件记录
3.3.4.查看负载均衡端口
css
[root@node01 ~]# yum install ipvsadm -y
[root@node01 ~]# ipvsadm -Ln
TCP 172.17.0.1:32591 rr
-> 10.244.1.18:80 Masq 1 0 0
-> 10.244.1.19:80 Masq 1 0 0
-> 10.244.2.13:80 Masq 1 0 0
# docker网桥
TCP 192.168.190.101:32591 rr
-> 10.244.1.18:80 Masq 1 0 0
-> 10.244.1.19:80 Masq 1 0 0
-> 10.244.2.13:80 Masq 1 0 1
# 外部访问的ip和端口
TCP 10.96.153.145:80 rr
-> 10.244.1.18:80 Masq 1 0 0
-> 10.244.1.19:80 Masq 1 0 0
-> 10.244.2.13:80 Masq 1 0 0
# pod集群组内部访问的ip和端口
在 node02 节点上操作,同样方式也可以查看负载均衡端口
修改各pod访问界面为自定义界面:
css
[root@master01 ~]# kubectl get pod -n fql
NAME READY STATUS RESTARTS AGE
nginx-01-799fb6fb65-296dl 1/1 Running 0 28m
nginx-01-799fb6fb65-jhqt2 1/1 Running 0 28m
nginx-01-799fb6fb65-kqbc2 1/1 Running 0 28m
[root@master01 ~]# kubectl exec -it nginx-01-799fb6fb65-296dl bash -n fql
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-01-799fb6fb65-296dl:/# echo web01 > /usr/share/nginx/html/index.html
[root@master01 ~]# kubectl exec -it nginx-01-799fb6fb65-jhqt2 bash -n fql
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-01-799fb6fb65-jhqt2:/# echo web02 > /usr/share/nginx/html/index.html
[root@master01 ~]# kubectl exec -it nginx-01-799fb6fb65-kqbc2 bash -n fql
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-01-799fb6fb65-kqbc2:/# echo web03 > /usr/share/nginx/html/index.html
3.3.5.验证负载均衡
css
[root@master01 ~]# kubectl get svc -n fql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-server NodePort 10.96.153.145 <none> 80:32591/TCP 30m
[root@master01 ~]# curl 10.96.153.145
web03
[root@master01 ~]# curl 10.96.153.145
web02
[root@master01 ~]# curl 10.96.153.145
web01
3.4.更新版本 kubectl set
Kubernetes 更新版本通常会涉及 kubectl set 命令的功能改进和参数扩展,以便更方便地管理和更新资源的字段,如扩展副本数量、更改镜像标签等。
3.4.1. 查看当前 nginx 的版本号
css
[root@master01 ~]# curl 10.96.153.145 -I
Server: nginx/1.14.2
3.4.2.获取修改模板
css
[root@master01 ~]# kubectl set image --help
Examples:
# Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox
container image to 'busybox'.
kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
3.4.3.滚动更新
将nginx 版本更新为 1.15 版本
css
[root@master01 ~]# kubectl set image deployment/nginx-01 nginx=nginx:1.15 -n fql
deployment.apps/nginx-01 image updated
[root@master01 ~]# kubectl get pod -n fql
NAME READY STATUS RESTARTS AGE
nginx-01-78cb4c6b78-2h46w 1/1 Running 0 28s
nginx-01-78cb4c6b78-fwvkv 0/1 ContainerCreating 0 10s
nginx-01-799fb6fb65-jhqt2 1/1 Running 0 41m
nginx-01-799fb6fb65-kqbc2 1/1 Running 0 41m
[root@master01 ~]# kubectl get pod -n fql
NAME READY STATUS RESTARTS AGE
nginx-01-78cb4c6b78-2h46w 1/1 Running 0 55s
nginx-01-78cb4c6b78-2ldxl 1/1 Running 0 7s
nginx-01-78cb4c6b78-fwvkv 1/1 Running 0 37s
nginx-01-799fb6fb65-jhqt2 0/1 Terminating 0 41m
......
......
处于动态监听 pod 状态,由于使用的是滚动更新方式,所以会先生成一个新的pod,然后删除一个旧的pod,往后依次类推:
kubectl get pods -w
# 更新好后的Pod的ip会改变
[root@master01 ~]# curl 10.96.153.145 -I
Server: nginx/1.15.12
首先在确保正常提供服务的情况下,在三个 pod 实例正常运行的情况下,生成一个新的指定版本的 pod 实例
等到新的 pod 实例创建成功后并验证可用性,会删除第一个 pod 实例
而后再生成第二个新版本的 pod 实例,再删除第二个,依此类推,一直到该 deployment 下的所有 pod 资源全部升级完毕
需要注意的是,资源更新后,其原本 pod 实例中的数据并不会被继承。如果有需要的话,可以先对数据进行备份,等到升级完毕后,再同步数据。
3.5. 回滚 kubectl rollout
Kubernetes 中的回滚操作通常使用 kubectl rollout 命令,该命令允许用户回退到先前的部署版本,同时保留集群的稳定性。这包括查看历史记录、回滚到特定版本以及监视回滚过程
3.5.1.查看回滚指令帮助说明
css
kubectl rollout --help
3.5.2.查看历史版本
css
[root@master01 ~]# kubectl rollout history deployment/nginx-01 -n fql
deployment.apps/nginx-01
REVISION CHANGE-CAUSE
1 <none>
2 <none>
REVISION #显示历史中的每个版本,最多记录三次
CHANGE-CAUSE #显示触发该版本变更的原因。显示为 <none>,表示没有明确的变更原因被记录
# Kubernetes本身不会自动为每次Deployment的更新填充CHANGE-CAUSE字段。
# 这个字段通常是通过设置 Deployment 的注解(annotation)来填充的
# 特别是 kubernetes.io/change-cause 这个注解。
3.5.3.执行回滚到上一个版本
css
[root@master01 ~]# kubectl rollout undo deployment/nginx-01 -n fql
deployment.apps/nginx-01 rolled back
3.5.4.执行回滚到指定版本
css
格式:
kubectl rollout undo deployment/nginx --to-revision=1
# 将名为nginx的部署回滚到版本1,即撤销最近的更改并还原到特定的先前版本。
3.5.5.检查回滚状态
css
[root@master01 ~]# kubectl rollout status deployment/nginx-01 -n fql
deployment "nginx-01" successfully rolled out
[root@master01 ~]# curl 10.96.153.145 -I
Server: nginx/1.14.2
3.6.删除 kubectl delete
kubectl delete 命令用于删除 Kubernetes 集群中的资源,可以是 pod、service、deployment 等。用户可以通过指定资源类型和名称来删除特定的资源,也可以使用标签选择器来批量删除符合条件的资源。
3.6.1 删除副本控制器
css
[root@master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-7dc776dfc6-4vm79 1/1 Running 0 60m
nginx-deployment-7dc776dfc6-b7qvn 1/1 Running 0 60m
nginx-deployment-7dc776dfc6-lzzvb 1/1 Running 0 60m
[root@master01 ~]# kubectl delete deployment nginx-deployment
deployment.apps "nginx-deployment" deleted
3.6.2.删除 service
css
[root@master01 ~]# kubectl get service -n fql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-server NodePort 10.96.153.145 <none> 80:32591/TCP 60m
[root@master01 ~]# kubectl delete service nginx-server -n fql
service "nginx-server" deleted
3.7. 金丝雀发布(灰度发布)
Deployment 控制器支持自定义控制更新过程中的滚动节奏,如"暂停(pause)"或"继续(resume)"更新操作。
1.比如等待第一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本;
2.然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行;
3.确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布。
准备工作:
css
[root@master01 ~]# kubectl delete deployments.apps nginx-01 -n fql
# 删除名为"nginx-01"的部署(Deployment)在命名空间(Namespace)"fql"中的实例
[root@master01 ~]# kubectl delete svc nginx
[root@master01 ~]# kubectl delete svc nginx-deployment
[root@master01 ~]# kubectl delete svc nginx-service -n fql
# 删除 Kubernetes 集群中的服务(Service)
[root@master01 ~]# kubectl create deployment nginx-01 --image=nginx:1.14 --port=80 --replicas=3 -n fql
deployment.apps/nginx-01 created
[root@master01 ~]# kubectl get pod -o wide -n fql
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-01-799fb6fb65-7c29k 1/1 Running 0 15s 10.244.1.23 node01 <none> <none>
nginx-01-799fb6fb65-b6dvg 1/1 Running 0 15s 10.244.1.24 node01 <none> <none>
nginx-01-799fb6fb65-k2dlz 1/1 Running 0 15s 10.244.2.23 node02 <none> <none>
# 创建了一个名为nginx-01的部署(Deployment),使用了nginx:1.14镜像,并将容器的端口设置为80,创建三个副本
[root@master01 ~]# kubectl expose deployment nginx-01 --port=80 --target-port=80 --name=nginx-service -n fql --type=NodePort
service/nginx-service exposed
[root@master01 ~]# kubectl get svc -n fql -o wide
[root@master01 ~]# kubectl get svc -n fql -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx-service NodePort 10.96.128.93 <none> 80:31217/TCP 11s app=nginx-01
[root@master01 ~]# curl -I 10.96.128.93
Server: nginx/1.14.2
3.7.1. 更新 deployment 的版本,并配置暂停 deployment
css
[root@master01 ~]# kubectl set image deployment nginx-01 nginx=nginx:1.15 -n fql && kubectl rollout pause deployment nginx-01 -n fql
deployment.apps/nginx-01 image updated
deployment.apps/nginx-01 paused
[root@master01 ~]# kubectl rollout status deployment nginx-01 -n fql
Waiting for deployment "nginx-01" rollout to finish: 1 out of 3 new replicas have been updated...
# 更新名为"nginx-01"的部署(Deployment)中的 "nginx" 容器的镜像版本为"nginx:1.15
# 暂停名为"nginx-01"的部署的滚动更新,这意味着在执行这个命令后,将不会继续推进新的副本集,并且当前的副本集将保持不变
3.7.2.开启另一个窗口查看 pod 信息
监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为使用了 pause 暂停命令
css
[root@master01 ~]# kubectl get pods -w -n fql
NAME READY STATUS RESTARTS AGE
nginx-01-78cb4c6b78-w6s2l 1/1 Running 0 31s
nginx-01-799fb6fb65-7c29k 1/1 Running 0 2m21s
nginx-01-799fb6fb65-b6dvg 1/1 Running 0 2m21s
nginx-01-799fb6fb65-k2dlz 1/1 Running 0 2m21s
# -w 选项,它会使命令进入监视模式,实时显示资源的变化情况
查看 nginx 版本信息:
css
[root@master01 ~]# kubectl get pod -n fql -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-01-78cb4c6b78-w6s2l 1/1 Running 0 106s 10.244.2.24 node02 <none> <none>
nginx-01-799fb6fb65-7c29k 1/1 Running 0 3m36s 10.244.1.23 node01 <none> <none>
nginx-01-799fb6fb65-b6dvg 1/1 Running 0 3m36s 10.244.1.24 node01 <none> <none>
nginx-01-799fb6fb65-k2dlz 1/1 Running 0 3m36s 10.244.2.23 node02 <none> <none>
[root@master01 ~]# kubectl get svc -n fql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service NodePort 10.96.128.93 <none> 80:31217/TCP 3m12s
[root@master01 ~]# curl -I 10.244.2.24
Server: nginx/1.15.12
[root@master01 ~]# curl -I 10.244.1.23
Server: nginx/1.14.2
[root@master01 ~]# curl -I 10.244.1.24
Server: nginx/1.14.2
[root@master01 ~]# curl -I 10.244.2.23
Server: nginx/1.14.2
3.7.3.确保更新的 pod 没问题,继续更新
css
[root@master01 ~]# kubectl rollout resume deployment nginx-01 -n fql
deployment.apps/nginx-01 resumed
3.7.4.查看最后的更新情况
css
[root@master01 ~]# kubectl get pod -w -n fql
[root@master01 ~]# kubectl get pod -n fql -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-01-78cb4c6b78-jb5vq 1/1 Running 0 54s 10.244.1.25 node01 <none> <none>
nginx-01-78cb4c6b78-w6s2l 1/1 Running 0 7m27s 10.244.2.24 node02 <none> <none>
nginx-01-78cb4c6b78-xqm9z 1/1 Running 0 52s 10.244.1.26 node01 <none> <none>
3.7.5.分阶段访问
在金丝雀发布中,将流量分流到新旧版本的这个过程被称为分阶段访问(Staged Access),也可以称为阶段性流量调度(Staged Traffic Shifting)。即将流量逐步引导到新版本的过程,以确保新版本的稳定性和可靠性。
css
[root@master01 ~]# kubectl set image deployment nginx-01 nginx=nginx:1.16 -n fql && kubectl rollout pause deployment nginx-01 -n fql
[root@master01 ~]# kubectl get pod -n fql
NAME READY STATUS RESTARTS AGE
nginx-01-78cb4c6b78-jb5vq 1/1 Running 0 6h54m
nginx-01-78cb4c6b78-w6s2l 1/1 Running 0 7h1m
nginx-01-78cb4c6b78-xqm9z 1/1 Running 0 6h54m
nginx-01-85c54f54dc-gn67s 1/1 Running 0 36s # 新增实例
默认情况下,访问 server 流量将会负载均衡至4个实例上,新增 server 实现新的实例与旧实例访问分流:
css
[root@master01 ~]# kubectl expose deployment nginx-01 -n fql --port=80 --target-port=80 --name=new-nginx --type=NodePort
[root@master01 ~]# kubectl get svc -n fql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
new-nginx NodePort 10.96.255.43 <none> 80:31923/TCP 68s
nginx-service NodePort 10.96.128.93 <none> 80:31217/TCP 7h7m
查看 pod 实例标签名;编辑(查看)位于命名空间 fql 中的名为 new-nginx 的 Service 资源对象,复制文本内容,并创建对应 yaml 文件,修改标签选择器内容:
css
[root@master01 ~]# kubectl get pod --show-labels -n fql
NAME READY STATUS RESTARTS AGE LABELS
nginx-01-78cb4c6b78-jb5vq 1/1 Running 0 7h9m app=nginx-01,pod-template-hash=78cb4c6b78
nginx-01-78cb4c6b78-w6s2l 1/1 Running 0 7h15m app=nginx-01,pod-template-hash=78cb4c6b78
nginx-01-78cb4c6b78-xqm9z 1/1 Running 0 7h9m app=nginx-01,pod-template-hash=78cb4c6b78
nginx-01-85c54f54dc-gn67s 1/1 Running 0 15m app=nginx-01,pod-template-hash=85c54f54dc
[root@master01 ~]# kubectl edit svc new-nginx -n fql #编辑复制文本
[root@master01 ~]# mkdir yaml;cd yaml
[root@master01 yaml]# vim new-nginx.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-01
name: new-nginx
namespace: fql
spec:
clusterIP: 10.96.255.43
clusterIPs:
- 10.96.255.43
externalTrafficPolicy: Cluster
ports:
- nodePort: 31923
port: 80
protocol: TCP
targetPort: 80
selector:
pod-template-hash: 85c54f54dc # 修改为对应标签
sessionAffinity: None
type: NodePort
删除 Kubernetes svc 资源,并根据配置文件创建或更新资源:
css
[root@master01 yaml]# kubectl delete svc new-nginx -n fql
service "new-nginx" deleted
[root@master01 yaml]# kubectl get svc -n fql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service NodePort 10.96.128.93 <none> 80:31217/TCP 7h23m
[root@master01 yaml]# kubectl apply -f new-nginx.yaml -n fql
service/new-nginx created
[root@master01 yaml]# kubectl get svc -n fql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
new-nginx NodePort 10.96.255.43 <none> 80:31923/TCP 2s
nginx-service NodePort 10.96.128.93 <none> 80:31217/TCP 7h24m
[root@master01 yaml]# kubectl get endpoints new-nginx -n fql
NAME ENDPOINTS AGE
new-nginx 10.244.1.27:80 75s # 对应的后端节点ip为10.244.1.27:80
访问升级版本 pod,查看流量调度是否正确:
css
[root@master01 yaml]# curl -I 10.244.1.27
Server: nginx/1.16.1
同样的,编辑(查看)位于命名空间 fql 中的名为 nginx-server 的 Service 资源对象,复制文本内容,并创建对应 yaml 文件,修改标签选择器内容:
css
[root@master01 yaml]# vim nginx-server.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-01
name: nginx-service
namespace: fql
spec:
clusterIP: 10.96.128.93
clusterIPs:
- 10.96.128.93
externalTrafficPolicy: Cluster
ports:
- nodePort: 31217
port: 80
protocol: TCP
targetPort: 80
selector:
pod-template-hash: 78cb4c6b78
sessionAffinity: None
type: NodePort
[root@master01 yaml]# kubectl get svc -n fql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
new-nginx NodePort 10.96.255.43 <none> 80:31923/TCP 10m
nginx-service NodePort 10.96.128.93 <none> 80:31217/TCP 7h35m
[root@master01 yaml]# kubectl delete svc nginx-service -n fql
service "nginx-service" deleted
[root@master01 yaml]# kubectl apply -f nginx-server.yaml -n fql
service/nginx-service created
[root@master01 yaml]# kubectl get svc -n fql
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
new-nginx NodePort 10.96.255.43 <none> 80:31923/TCP 11m
nginx-service NodePort 10.96.128.93 <none> 80:31217/TCP 2s
[root@master01 yaml]# kubectl get endpoints nginx-service -n fql
NAME ENDPOINTS AGE
nginx-service 10.244.1.25:80,10.244.1.26:80,10.244.2.24:80 3m33s
访问旧版本 pod,查看流量调度是否正确:
css
[root@master01 yaml]# curl 10.96.128.93 -I
Server: nginx/1.15.12
[root@master01 yaml]# curl 10.96.128.93 -I
Server: nginx/1.15.12
[root@master01 yaml]# curl 10.96.128.93 -I
Server: nginx/1.15.12
至此,通过不同 server 对应标签,完成金丝雀发布中,将流量分流到新旧版本的过程。
3.8.蓝绿发布
蓝绿发布是一种部署新版本应用程序的策略,旨在减少对用户造成的影响。在蓝绿发布中,两个相同的生产环境并行存在,一个被标记为"蓝色"(Blue),另一个被标记为"绿色"(Green)。
- 蓝色环境:当前稳定的生产环境
- 绿色环境:新版本的生产环境
在初始阶段,所有的用户流量都会指向蓝色环境。当新版本准备就绪时,流量可以逐渐转移到绿色环境。这种逐步迁移流量的方式允许进行实时监控,并在出现问题时快速回滚到蓝色环境。一旦绿色环境被验证为稳定可靠,蓝色环境可以被废弃或者保留作为备份。
发布方式总结
① 滚动发布
按照比例一部分一部分的滚动更新;创建一定比例的 pod,先创建再删除旧的 pod。
② 金丝雀发布(灰度发布)
先更新一部分 pod,然后暂停更新;
安排一小部分的用户流量取访问更新的 pod 来进行测试;
当测试没有问题后再扩大比例,直到全部更新完成为止。
③ 蓝绿发布
蓝:正在运行的稳定版本
绿:新版本的副本
进行新旧版本的切换,用户无感知、业务稳定;但是需要大量的资源、成本高。