目录

一、K8s 资源管理操作分类

1.1. 陈述式

1.2. 声明式

二、陈述式资源管理方法

二、基本信息查看

端口总结:

三、项目的生命周期

3.1.创建 kubectl create 命令

3.2.发布 kubectl expose 命令

3.2.1.将资源暴露为新的 Service

3.2.2.Kubernetes 之所以需要 Service

3.2.2 service 的 type 类型

3.2..3 无头模式 headless clusterIP

3.2.4 端口类型

3.3.1查看 pod 网络状态详细信息和 Service 暴露的端口

3.3.2.查看关联后端的节点

3.3.3.查看 service 的描述信息

3.3.4.查看负载均衡端口

3.3.5.验证负载均衡

3.4.更新版本 kubectl set

3.4.1. 查看当前 nginx 的版本号

3.4.2.获取修改模板

3.4.3.滚动更新

3.5. 回滚 kubectl rollout

3.5.1.查看回滚指令帮助说明

3.5.2.查看历史版本

3.5.3.执行回滚到上一个版本

3.5.4.执行回滚到指定版本

3.5.5.检查回滚状态 

3.6.删除 kubectl delete

3.6.1 删除副本控制器

3.6.2.删除 service

3.7. 金丝雀发布(灰度发布) 

3.7.1. 更新 deployment 的版本,并配置暂停 deployment  

3.7.2.开启另一个窗口查看 pod 信息

3.7.3.确保更新的 pod 没问题,继续更新

3.7.4.查看最后的更新情况

3.7.5.分阶段访问 

3.8.蓝绿发布

发布方式总结


一、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.对资源的增、删、查操作比较方便,但对改的操作就不容易了

//查看版本信息
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的资源

//查看 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

[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。 

[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 暴露的端口

[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实例

[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.查看关联后端的节点

[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 的描述信息

[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.查看负载均衡端口

[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访问界面为自定义界面:

[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.验证负载均衡

[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 的版本号

[root@master01 ~]# curl 10.96.153.145 -I
Server: nginx/1.14.2

3.4.2.获取修改模板

[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 版本

[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.查看回滚指令帮助说明

kubectl rollout --help

3.5.2.查看历史版本

[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.执行回滚到上一个版本

[root@master01 ~]# kubectl rollout undo deployment/nginx-01 -n fql
deployment.apps/nginx-01 rolled back

3.5.4.执行回滚到指定版本

格式:
kubectl rollout undo deployment/nginx --to-revision=1
# 将名为nginx的部署回滚到版本1,即撤销最近的更改并还原到特定的先前版本。

3.5.5.检查回滚状态 

[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 删除副本控制器

[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

[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资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布。

准备工作:

[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  

[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 暂停命令

[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 版本信息:

[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 没问题,继续更新

[root@master01 ~]# kubectl rollout resume deployment nginx-01 -n fql
deployment.apps/nginx-01 resumed

3.7.4.查看最后的更新情况

[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)。即将流量逐步引导到新版本的过程,以确保新版本的稳定性和可靠性。

[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 实现新的实例与旧实例访问分流:

[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 文件,修改标签选择器内容:

[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 资源,并根据配置文件创建或更新资源:

[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,查看流量调度是否正确:

[root@master01 yaml]# curl -I 10.244.1.27
Server: nginx/1.16.1

同样的,编辑(查看)位于命名空间 fql 中的名为 nginx-server 的 Service 资源对象,复制文本内容,并创建对应 yaml 文件,修改标签选择器内容:

[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,查看流量调度是否正确: 

[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 来进行测试;

当测试没有问题后再扩大比例,直到全部更新完成为止。

③ 蓝绿发布

蓝:正在运行的稳定版本

绿:新版本的副本

进行新旧版本的切换,用户无感知、业务稳定;但是需要大量的资源、成本高。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐