目录
前言
一、K8s 资源管理操作方式
1、声明式资源管理方式
2、陈述式资源管理方式
二、陈述式资源管理方式
1、kubectl 命令基本语法
2、查看基本信息
2.1 查看版本信息
2.2 查看资源对象简写
2.3 配置kubectl命令自动补全
2.4 查看node节点日志
2.5 查看集群信息
3、查看资源的基本信息
3.1 查看集群组件状态
3.2 查看命名空间
3.3 查看命名空间中的资源
3.4 查看资源详细信息
3.5 查看特定命名空间中所有部署的信息
3.6 查看资源标签信息
3.6.1 查看存在资源的标签
3.6.2 查看指定标签中含有的资源
3.6.3 查看标签中指定的资源
4、创建和删除命名空间
4.1 创建命名空间
4.2 删除命名空间
5、创建、登录和删除 pod 实例
5.1 创建 pod 实例
5.2 跨主机登录容器
5.3 删除 pod 实例
6、扩容与缩容
6.1 扩容
6.2 缩容
三、项目的生命周期
1、 创建 kubectl create 命令
2、发布 kubectl expose 命令
2.1 Service 的概念
2.2 将资源暴露为新的 Service
2.3 负载均衡效果
3、更新版本 kubectl set(滚动发布)
3.1 查看版本更新策略
3.2 版本更新过程
3.3 版本更新
4、回滚 kubectl rollout
4.1 查看历史版本
4.2 执行回滚到上一个版本
4.3 执行回滚到指定版本
4.4 检查回滚状态
5、删除 kubectl delete
5.1 删除副本控制器
5.2 删除 service
四、项目更新发布方式
1、蓝绿发布
2、滚动发布
3、灰度发布(金丝雀发布)
3.1 暂停更新
3.2 pod 隔离
3.2.1 修改新service的关联节点
3.2.1 修改旧service的关联节点
3.3 测试 pod 隔离效果
3.4 恢复更新
3.5 测试是否更新为新版本
五、总结
1、陈述式资源管理方式
2、项目的生命周期
3、项目更新发布方式
前言
本合集旨在提供一个全面的kubectl命令合集,帮助您更好地理解和使用Kubernetes中的陈述式资源管理。Kubernetes是一个强大的容器编排平台,而资源管理是其中至关重要的一部分。通过使用kubectl命令,您可以轻松地创建、更新和删除各种资源,以及查看它们的状态
陈述式资源管理是一种通过定义所需状态来实现自动化管理的方法。通过使用kubectl命令,您可以将集群状态与所需状态保持一致,从而简化管理过程,提高可靠性和可维护性
本合集将介绍各种kubectl命令,包括创建、更新、删除资源,以及查看资源状态等。我们鼓励您通过学习和掌握这些命令,以便能够更有效地管理和操作Kubernetes集群
一、K8s 资源管理操作方式
1、声明式资源管理方式
- 概念
声明式管理是指通过定义所需的状态,让Kubernetes自动将集群状态与所需状态保持一致的管理方式。用户只需描述所需的最终状态,而不需要关心实现的具体步骤
- 操作方式
用户通过编写YAML文件来描述资源对象的配置和规范。然后使用kubectl apply命令将这些YAML文件应用到集群中,Kubernetes会根据文件中定义的状态进行操作,确保集群达到所需状态
2、陈述式资源管理方式
- 概念:
① kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口
② kubectl 是官方的CLI命令行工具,用于与 apiserver 进行通信,将用户在命令行输入的命令,组织并转化为 apiserver 能识别的信息,进而实现管理 k8s 各种资源的一种有效途径
③ 陈述式资源管理是指通过直接给出操作指令来管理资源的方式。用户需要明确指定每个操作的具体步骤,包括创建、更新、删除等。
- 操作方式
用户通过kubectl命令直接操作资源对象,例如使用kubectl create、kubectl apply、kubectl delete等命令来创建、更新、删除资源。用户需要逐步指定每个操作的参数和选项。
二、陈述式资源管理方式
1、kubectl 命令基本语法
kubectl命令的语法如下
kubectl [command] [type] [name] [flags]
comand #指定要对资源执行的操作,例如create、 get、delete
type #指定资源类型,比如deployment、pod、 service
name #指定资源的名称,名称大小写敏感
flags #指定额外的可选参数
kubectl --help #可查询 kubectl 命令的用法
k8s中文文档:http://docs.kubernetes.org.cn/683.html
2、查看基本信息
命令 | 说明 |
---|---|
kubectl version | 查看版本信息 |
kubectl api-resources | 查看资源对象简写 |
journalctl -u kubelet -f | node节点查看日志 |
source <(kubectl completion bash) | 配置kubectl自动补全 |
kubectl cluster-info | 查看集群信息 |
2.1 查看版本信息
kubectl version
2.2 查看资源对象简写
kubectl api-resources
注:
NAME:资源类型全拼
SHORTNAMES :简写
APIVERSION :资源所属的 API 版本
NAMESPACED :是否支持命名空间,true表示支持,false表示不支持
KIND :资源的类型或种类
services与svc表示同一个指令,svc是services的简写
2.3 配置kubectl命令自动补全
配置kubectl自动补全,使用source <(kubectl completion bash)指令,执行此命令后,可以使用tab键,在kubectl进行资源操作时进行补全
[root@master ~]#source <(kubectl completion bash)
#可以将此命令加入开机自行加载的文件。如$HOME/.bashrc文件、/etc/profile文件
2.4 查看node节点日志
journalctl -u kubelet -f
2.5 查看集群信息
kubectl cluster-info
3、查看资源的基本信息
命令 | 说明 |
---|---|
kubectl get <resource_type> [-o wide|json|yaml] [-n namespace] | 获取指定类型的资源信息,如kubectl get pods获取所有Pod信息。-n 指定命令空间 -o 指定输出格式 |
kubectl describe <resource_type> <resource_name> | 显示指定资源的详细信息 |
kubectl explain <resource>: | 获取关于资源或资源字段的文档 |
#获取资源的相关信息,-n 指定命令空间,-o 指定输出格式
kubectl get <resource> [-o wide|json|yaml] [-n namespace]
#resource可以是具体资源名称,如pod nginx-xxx;也可以是资源类型,如pod;或者all(仅展示几种核心资源,并不完整)
#--all-namespaces 或 -A :表示显示所有命令空间,
#--show-labels :显示所有标签
#-l app :仅显示标签为app的资源
#-l app=nginx :仅显示包含app标签,且值为nginx的资源
3.1 查看集群组件状态
kubectl get componentstatuses
简写:
kubectl get cs
注:
- NAME:集群中的组件名称
- STATUS:组件的健康状态,通常是 "Healthy" 或 "Unhealthy"
- MESSAGE:提供了关于组件状态的额外信息,通常是一个简单的 "ok" 或更详细的消息
- ERROR:在组件不健康时可能会显示错误详情,但在健康时通常为空。
3.2 查看命名空间
kubectl get namespace
简写:
kubectl get ns
#Kubernetes 使用命名空间来将集群中的资源划分到不同的逻辑组中
#在同一个命名空间当中,不允许有相同名称的资源信息,但是在不同的命名空间中可以创建
#默认的命名空间是 "default",但通常还有其他命名空间,如 "kube-system"(用于 Kubernetes 系统组件)和用户自定义的命名空间
注:
- NAME:命名空间的名称
- STATUS:命名空间的当前状态,通常是 "Active",表示命名空间是活动的并且可用
- AGE:命名空间自创建以来的时长
3.3 查看命名空间中的资源
(1)查看某一命名空间具体的某一资源信息
#查看命名空间 kube-system 中的pod资源
kubectl get pod -n kube-system
#查看命名空间 kube-system 中的pod资源的详细信息
kubectl get pod -n kube-system -owide
(2) 查看某一命名空间所有的资源
#查看命名空间 kube-system 中的所有资源,all代表所有类型的资源
kubectl get all -n kube-system
(3)查看所有命名空间中的资源
kubectl get all -A
#--all-namespaces 或 -A :表示显示所有命名空间
3.4 查看资源详细信息
kubectl describe <资源类型> <资源名称> [-n 命名空间]
<资源类型> #描述的资源的类型,比如 pod、service、deployment、statefulset 等
<资源名称> #你想要描述的资源的名称
[-n 命名空间] #可选参数,指定资源所在的命名空间。不指定则为当前默认命名空间,通常是default
#kubectl describe是Kubernetes命令行工具kubectl的一个命令,用于获取关于指定资源的详细信息
#当你想要深入了解某个资源的状态时(比如它的配置、事件、容器日志等),这个命令会非常有用
#查看命名空间 kube-system 中名称为 etcd-master 的 pod 资源详细信息
kubectl describe pod etcd-master -n kube-system
#查看默认命名空间中 default 名称为 kubernetes 的 service 资源详细信息
kubectl describe svc kubernetes
3.5 查看特定命名空间中所有部署的信息
kubectl get deployments -n <命名空间>
kubectl get deployments -n <命名空间> -owide
#在名为 "app" 的命名空间中获取所有的部署(Deployments)
kubectl get deployments -n app
kubectl get deployments -n app -owide
3.6 查看资源标签信息
标签的作用:
- 辅助筛选资源:通过标签,我们可以筛选出具有特定属性的资源,便于管理和操作
- 实现资源的分组:标签可以将资源进行分组,从而合理组织资源结构,使得管理更加有序
- 支持负载均衡:在Kubernetes中,Service的Selector会根据标签匹配来实现负载均衡,确保请求能够分发到合适的Pod上。当一个pod迭代或替换之后,新的pod实例IP地址也会改变,同时会将IP地址绑定在标签上,通过访问标签,实现负载均衡
- 支持Pod的扩容和缩容:Deployment等控制器会根据匹配的标签进行Pod的扩容和缩容,以满足应用的需求
- 支持扩展性和灵活性:标签为Kubernetes提供了一种非常灵活的资源管理方式,可以根据需要添加、修改或删除标签,以适应应用的变化和演进
- 版本管理:可以使用标签标记不同版本的应用,方便进行版本控制和回滚操作
标签的特点
- 每个对象都可以定义一组键值标签
- 每个键对于给定对象必须是唯一的
- 标签能够支持高效的查询和监听操作,对于用户界面和命令行是很理想的
3.6.1 查看存在资源的标签
kubectl get <资源类型> [-n 命名空间] --show-labels
(1)查看某一命名空间内所有 pods 实例的标签
#获取指定命名空间(namespace)中的所有 Pod,并显示它们的标签(labels)信息
kubectl get pod -n kube-system --show-labels
(2) 查看某一命名空间内指定的某一 pod 实例的标签
#获取指定命名空间(namespace)中的 etcd-master 信息,并显示它的标签(labels)信息
kubectl get pod etcd-master -n kube-system --show-labels
3.6.2 查看指定标签中含有的资源
kubectl get <资源类型> [-n 命名空间] -l <标签名称>
#列出kube-system命名空间中具有名为"component"的标签的所有Pod
kubectl get pods -n kube-system -l component
#get pods:指定查看资源类型为pod
#-n kube-system:指定查看kube-system的命名空间
#-l component :仅显示标签为component的资源
3.6.3 查看标签中指定的资源
kubectl get pods -n kube-system -l component=kube-apiserver
#-l component=kube-apiserver:指定查看包含component标签,且值为kube-apiserver的资源
4、创建和删除命名空间
4.1 创建命名空间
kubectl create namespace <自定义名称>
简写:
kubectl create ns <自定义名称>
kubectl create ns dh #创建新的命名空间为dh
kubectl create ns app #创建新的命名空间为app
kubectl get ns #查看当前所有的命名空间
4.2 删除命名空间
kubectl delete namespace <namespace_name>
简写:
kubectl delete ns <namespace_name>
kubectl delete ns dh #删除一个名为dh的命名空间
注:
- 在删除命名空间之前,请确保该命名空间中没有正在运行的重要应用程序,以免影响集群的稳定性和可用性
- 有些命名空间可能是由Kubernetes系统自动生成的,不允许被删除。在删除之前,请确认命名空间是否允许被删除
- 在执行删除操作之前,请确保已经备份了必要的数据和配置
5、创建、登录和删除 pod 实例
5.1 创建 pod 实例
创建pod实例,其方法有以下两种:
- kubectl run:用于快速运行一个新的Pod。不需要进行繁琐的添加追加,一般快速运行与测试pod。静态创建的pod实例,不保存在etcd,只存储在相应的node节点里
- kubectl create:是一个更通用的命令,可以与其他子命令一起使用,以创建特定的资源,例如可以通过创建Deployment来启动pod,它还可以用于从文件、目录中创建资源。如YAML或JSON文件,这些文件描述了要创建的资源
(1)kubectl run 静态创建并启动 pod 实例
可通过 kubectl run --help 查看使用方法
kubectl run nginx --image=nginx -n app
#kubectl run:创建一个pod资源
#nginx:指定名称为nginx
#--image=nginx:指定镜像名称
#-n app:指定在 app 命名空间中创建
创建时可指定标签:
#创建一个名为 nginx-test 的 Pod,并为该 Pod 添加一个标签 web=true
kubectl run nginx-test --image=nginx --labels=web=true
#kubectl run: 运行一个新的 Pod 或 Deployment。
#nginx-test: 新 Pod 的名称。
#--image=nginx: 使用 nginx 镜像作为新 Pod 的容器镜像。
#--labels=web=true: 为新 Pod 添加一个标签 web=true,这个标签可以用于后续的 Pod 筛选和管理
#用于获取名为 nginx-test 的 Pod 的详细信息,并显示其标签信息和更广泛的输出
kubectl get pod nginx-test --show-labels -owide
(2)kubectl create创建副本控制器(deployment)来启动 pod 实例
kubectl create --help
#查看帮助说明
kubectl create <资源类型> <pod名称> --image=imagename [-n ns] ...
#标准输入创建
kubectl create -f <filename>
#使用YAML或JSON文件创建资源
kubectl create deployment nginx-01 --image=nginx --replicas=3 -n app
#kubectl create:创建资源
#deployment:创建deployment控制器,用于启动pod,并控制pod的预期值
#nginx-01:deployment控制器名称
#--image=nginx:指定了要在Pod中运行的Docker镜像的名称
#--replicas=3: 这指定了 Deployment 应该运行多少个Pod的副本,不指定默认为1个
#-n app:指定创建deployment所在的命名空间
查看 Deployment:
#在名为 "app" 的命名空间中获取所有的部署(Deployments)
kubectl get deployments -n app
kubectl get deployments -n app -owide
查看 deployment 详细信息:
#在名为 "app" 的命名空间中描述(describe)名为 "nginx-01" 的部署(Deployment)
kubectl describe deployment nginx-01 -n app
查看 pod 详细信息:
kubectl get pod -n app #查看所有的pod的NAME
#获取有关该 Pod 的各种信息,例如 Pod 的状态、容器的状态、事件日志等。这对于故障排除和了解 Pod 的运行状况非常有用
kubectl describe pod nginx-01-796cd9986d-9c8jn -n app
5.2 跨主机登录容器
kubectl exec可以跨主机登录容器,docker exec 只能在容器所在主机上登录
kubectl get pod -n app #查看所有的pod的NAME
#跨主机登录容器
kubectl exec -it nginx-01-796cd9986d-9c8jn bash -n app
#kubectl exec 是用于在 Kubernetes 中执行命令的工具
#-it 标志告诉 Kubernetes 执行一个交互式的命令,并将其连接到当前的终端
#nginx-01-796cd9986d-9c8jn 是要执行命令的 Pod 的名称
#bash 是要在该 Pod 上执行的命令,这里是一个交互式的 bash shell
#-n app 指定了 Pod 所在的命名空间为 app
5.3 删除 pod 实例
kubectl run 和 kubectl create 这两种方法创建的 pod 实例,在删除时是有很大区别的
(1)使用 kubectl delete pod 删除实例
使用kubectl run创建的 pod 实例,使用kubectl delete pod 可以直接删除
kubectl delete pod nginx -n app #命名空间 app 中删除名为 nginx 的 Pod
kubectl get pod -n app -owide #查看 pod 实例详细信息
而使用 delpoyment 启动的 pod 实例,直接去删除 pod 是无法删除的,会重启启动一个 pod 实例
kubectl delete pod nginx-01-796cd9986d-6fvft -n app
注:
这是因为delpoyment控制器,是一种pod控制器,它建立在ReplicaSet之上的控制器,用于管理无状态应用,同时管理和控制Pod与ReplicaSet,确保pod实例,一直保持在replicaset设置的预期值上
(2)使用 kubectl delete deployment 删除副本控制器管理的pod实例
kubectl delete deployments nginx-01 -n app
(3)若 pod 无法删除,总是处于 terminate 状态,则要强行删除 pod
kubectl delete pod <pod-name> -n <namespace> --force --grace-period=0
# grace-period表示过渡存活期,默认30s,在删除pod之前允许POD慢慢终止其上的容器进程,从而优雅退出
# 0表示立即终止pod
6、扩容与缩容
扩容和缩容是指调整应用程序的副本数,以满足应用程序的负载需求。扩容是增加应用程序的副本数,而缩容是减少应用程序的副本数
可使用 kubectl scale
命令来扩容或缩容应用程序的副本数
kubectl scale <资源类型> <资源名称> --replicas=num [-n ns]
6.1 扩容
扩容意味着增加集群中运行Pod的数量,以满足更高的负载需求
首先使用 Deployment 控制器创建三个 pod 实例
kubectl create deployment nginx-02 --image=nginx --replicas=3 -n app
kubectl get pod -n app -owide #查看所有的 pod 实例
当负载量过高时,可以通过扩容的方式来增加负载均很需求
#将命名空间 app 中名为 nginx-02 的 Deployment 的副本数扩展到 6 个
kubectl scale deployment nginx-02 --replicas=6 -n app
#kubectl scale 是 Kubernetes 命令行工具,用于扩展或缩容应用程序的副本数
#deployment nginx-02 指定了要扩展的 Deployment 的名称为 nginx-02
#--replicas=6 指定了要扩展到的副本数为 6 个
#-n app 指定了命名空间为 app,表示在该命名空间中执行操作
6.2 缩容
缩容意味着减少集群中运行Pod的数量,以节省资源或响应降低的负载需求
#将命名空间 app 中名为 nginx-02 的 Deployment 的副本数缩减到 2 个
kubectl scale deployment nginx-02 --replicas=2 -n app
#kubectl scale 是 Kubernetes 命令行工具,用于扩展或缩容应用程序的副本数
#deployment nginx-02 指定了要缩容的 Deployment 的名称为 nginx-02
#--replicas=2 指定了要缩减到的副本数为 2 个
#-n app 指定了命名空间为 app,表示在该命名空间中执行操作
注:
- 在进行扩容或缩容操作之前,请确保你的应用程序可以处理这些更改。例如,如果你的应用程序使用了外部存储或数据库连接,并且这些连接是静态的(即不是由Kubernetes管理的),那么增加或减少Pod数量可能会导致连接问题
- 监控你的应用程序和集群的性能和健康状况,以确保扩容或缩容操作不会导致问题或性能下降
- 使用HPA时,请确保你选择了合适的指标和目标值,以便正确地触发Pod的扩展和缩减
- 在进行垂直扩展时,请确保你了解你的应用程序的资源需求,并避免设置过低的资源限制,这可能会导致性能问题或容器崩溃
三、项目的生命周期
Kubernetes 项目的生命周期包括设计、开发、部署、运行和维护等阶段。在设计和开发阶段,需要定义应用程序的架构和容器镜像,以及创建 Kubernetes 资源对象。在部署和运行阶段,需要使用 kubectl 命令将应用程序部署到 Kubernetes 集群中,并进行监控和维护。
即:创建-->发布-->更新-->回滚-->删除
1、 创建 kubectl create 命令
- 创建并运行一个或多个容器镜像
- 创建一个 deployment 或 job 来管理容器
启动 nginx 实例,暴露容器端口 80,设置副本数 3
kubectl create deployment nginx --image=nginx:1.14 --port=80 --replicas=3 -n app
此时只有集群当中的服务器可以进行访问,因为它们都启动了fiannel网络插件与网络代理,所以做到节点直接互相通信,且可以访问pod实例
使用其他除k8s集群外的机器访问连接时会被拒绝,因为它现在只是一个pod实例,并没有形成service对外提供服务
所以,我们可以通过kubectl expose命令,将服务对外进行发布,使其它主机,可以访问到pod实例
2、发布 kubectl expose 命令
kubectl expose 允许你基于一个运行中的 Pod、Service、ReplicationController、ReplicaSet、Deployment 或 Job 来快速创建一个新的 Service
2.1 Service 的概念
(1)将 Pod 实例创建为 Service 的作用主要体现在以下几个方面:
- 提供服务的稳定入口:Service为前端的应用程序或ingress提供了稳定的服务入口,这个入口拥有一个全局唯一的虚拟IP地址。前端的应用可以通过这个IP地址访问后端的Pod集群,而无需关心Pod的实际IP地址,因为Pod的IP地址可能会经常变化
- 实现负载均衡:Service内部实现了负载均衡机制,它可以将所有进入的请求均匀地分配给后端的Pod副本,确保每个请求都能得到正确的响应。这对于提高系统的可扩展性和可用性非常重要
- 实现故障隔离:当某个Pod发生故障时,Service会自动将该Pod从服务池中剔除,保证请求不会被故障的Pod处理,从而实现了故障隔离。这有助于保持系统的稳定性和可靠性
- 实现服务发现:Service允许前端的应用程序通过Label Selector来找到提供特定服务的Pod,从而实现了服务的自动发现。这使得在复杂的分布式系统中,服务之间的调用变得更加简单和高效
- 对Pod IP的跟踪:由于Pod经常处于用后即焚状态,Pod经常被重新生成,因此Pod对应的IP地址也会经常变化。通过创建Service,可以将Pod的IP地址添加到Service对应的端点列表(Endpoints)中,实现对Pod IP的跟踪。这样,无论Pod怎样变化,只要有Label,就可以让Service能够联系上Pod,进而实现通过Service访问Pod的目的
(2)Kubernetes 之所以需要 Service 的原因
- 一方面是因为 Pod 的 IP 不是固定的(Pod可能会重建)
- 另一方面则是因为一组 Pod 实例之间总会有负载均衡的需求
- 对于容器应用而言,Kubernetes 提供了基于 VIP(虚拟IP) 的网桥的方式访问 Service,再由 Service 重定向到相应的 Pod
(3)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去访问集群外部的资源,它本身没有绑定任何的资源
(4)无头模式 headless clusterIP
是Kubernetes中一种特殊类型的服务,它不会为服务创建ClusterIP,而是直接将DNS解析指向服务的每个Pod的IP地址。这种模式适用于需要直接与每个Pod进行通信的场景,而不需要负载均衡或代理
(5)ports(端口)类型
- 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
2.2 将资源暴露为新的 Service
kubectl expose deployment nginx --port=80 --target-port=80 --name=nginx-server --type=NodePort -n app
#expose:用于根据资源(如 Deployment)创建一个新的 Service。
#deployment nginx:指定了名称为nginx的Deployment来创建Service。
#--port=80:这指定了Service的端口,即集群内部其他Pods可以通过这个端口访问Service
#--target-port=80:这指定了Service将流量转发到的目标端口,即Pods上实际运行的服务的端口,--target-port和--port可以是相同的,但也可以不同,具体取决于部署配置。
#--name=nginx-server:指定了新创建的Service的名称
#--type=NodePort:指定了Service 的类型。NodePort类型意味着Service会在集群的每个节点上打开一个特定的端口(称为 NodePort,端口范围为30000-32767之间的一个随机数),这样外部流量就可以通过该端口访问Service。这是将服务暴露给集群外部的一种方式
#-n app:-n(--namespace的缩写),用于指定命令应该在哪个命名空间(namespace)中执行
kubectl get pod,svc -owide -n app #获取service对外暴露的端口
使用外部客户端浏览器访问任意一个节点ip的32093端口,都可以访问到nginx的pod实例
使用endpoints指令,查看后端关联的后端节点
kubectl get endpoints -n app
也可以通过kubectl describe 指令查看service的描述信息
[root@master ~]#kubectl describe svc nginx-server -n app
Name: nginx-server #serivce名称
Namespace: app #所在命名空间
Labels: app=nginx #标签名称
Annotations: <none> #服务没有注解
Selector: app=nginx #服务的选择器,表示所有具有app=nginx标签的Pod都将作为此服务的后端
Type: NodePort #服务的类型是NodePort
IP Families: <none> #服务没有指定特定的 IP 地址族
IP: 10.96.198.166 #服务的 ClusterIP
IPs: 10.96.198.166 #同上,列出了服务的 ClusterIP
Port: <unset> 80/TCP #<unset> 表示没有为服务定义命名端口,默认的端口和协议(80/TCP)被列在了后面
TargetPort: 80/TCP #流量将被转发到 Pod 上的 80/TCP 端口
NodePort: <unset> 32093/TCP #NodePort端口号为32444
Endpoints: 10.244.2.21:80,10.244.2.22:80,10.244.2.23:80 #该服务提供服务的 Pod 的 IP 地址和端口
Session Affinity: None #没有启用会话亲和性,这意味着对于客户端的连续请求,可能会被路由到不同的 Pod
External Traffic Policy: Cluster #设置为 Cluster。路由外部流量到集群的所有Pods上
Events: <none> #显示为 <none>,表示没有与该服务相关的事件
2.3 负载均衡效果
当上述条件以及service创建好后,会以默认轮询的方式实现负载均衡
在任意 node 节点上下载 ipvsadm ,使用 ipvsadm 命令查看负载均衡端口
yum install ipvsadm -y
ipvsadm -Ln
使用kubectl exec可以跨主机登录容器,并修改各pod访问界面为自定义界面,验证负载均衡
kubectl get pod -n app #查看所有的pod的NAME
#跨主机登录容器
kubectl exec -it nginx-d9d8cf5c7-2kqxk bash -n app
#kubectl exec 是用于在 Kubernetes 中执行命令的工具
#-it 标志告诉 Kubernetes 执行一个交互式的命令,并将其连接到当前的终端
#nginx-d9d8cf5c7-2kqxk 是要执行命令的 Pod 的名称
#bash 是要在该 Pod 上执行的命令,这里是一个交互式的 bash shell
#-n app 指定了 Pod 所在的命名空间为 app
测试负载均衡效果:
① 集群内部访问,使用CLUSTER-IP地址
② 外部访问,使用集群随便一个node节点地址+端口号
3、更新版本 kubectl set(滚动发布)
kubectl set是一个用于设置资源字段的命令行工具,它提供了一种直接修改 Kubernetes 资源字段的方式,而无需直接编辑 YAML 或 JSON 文件。kubectl set 命令通常用于快速修改资源的某些属性,如环境变量、标签、注解等
kubectl set --help #获取帮助信息
3.1 查看版本更新策略
kubectl set指令版本滚动策略,可以使用kubectl describe来进行查看
[root@master ~]#kubectl describe deployments.apps nginx -n china
......
RollingUpdateStrategy: 25% max unavailable, 25% max surge
......
--------------------------------------------------------------------------------
RollingUpdateStrategy
#Deployment资源的一个字段,它用于定义滚动更新的策略
#滚动更新允许你逐步替换Pod,以确保在更新过程中服务的高可用性
maxUnavailable
#这是一个可选字段,用于指定在滚动更新过程中可以有多少个Pod处于不可用状态
#这个值可以是一个整数(表示具体的Pod数量)或者一个百分比
#例如,25%的maxUnavailable意味着在更新过程中,可以有最多25%的Pod处于不可用状态
maxSurge
#这也是一个可选字段,用于指定在滚动更新过程中可以有多少个额外的Pod同时运行
#这个值也可以是一个整数或百分比。例如25%的maxSurge意味着在更新过程中
#可以比期望的Pod数量多运行最多25%的Pod
3.2 版本更新过程
kubectl set更新版本过程,以三个pod为例:
- 首先在确保正常提供服务的情况下,在三个pod实例正常运行的情况下,生成一个新的指定版本呢的pod实例
- 等到新的pod实例创建成功后,会删除第一个pod实例
- 而后再生成第二个新版本的pod实例,再删除第二个,依此类推,一直到该deployment下的所有pod资源全部升级完毕
需要注意的是,资源更新后,其原本pod实例中的数据并不会被继承。如果有需要的话,可以先对数据进行备份,等到升级完毕后,再同步数据
3.3 版本更新
首先获取当前版本信息
curl 172.16.12.11:32093 -I #获取当前nginx版本
然后使用 kubectl set 升级成 1.15 版本
#在指定的命名空间中更新名为 "nginx" 的 Deployment 中的所有 Pod 的镜像为 "nginx:1.15" 版本
kubectl set image deployment nginx nginx=nginx:1.15 -n app
最后验证是否更新成功
4、回滚 kubectl rollout
Kubernetes 中的回滚操作通常使用 kubectl rollout 命令,该命令允许用户回退到先前的部署版本,同时保留集群的稳定性。这包括查看历史记录、回滚到特定版本以及监视回滚过程
kubectl rollout --help #查看回滚指令帮助说明
4.1 查看历史版本
#用于查看资源的滚动更新历史。例如,可以查看Deployment的所有历史版本
kubectl rollout history deployment/<deployment-name>
#查看特定版本的详细信息,num对应kubectl rollout history查看的revision的值
kubectl rollout history deployment/<deployment-name> --revision=num
#查看名为 "nginx" 的 Deployment 在 "app" 命名空间中的升级历史记录
kubectl rollout history deployment nginx -n app
#查看特定版本的详细信息
kubectl rollout history deployment nginx -n app --revision=4
注:
- REVISION:显示历史中的每个版本,最多记录三次
- CHANGE-CAUSE:显示触发该版本变更的原因。显示为 <none>,表示没有明确的变更原因被记录
# Kubernetes本身不会自动为每次Deployment的更新填充CHANGE-CAUSE字段
# 这个字段通常是通过设置 Deployment 的注解(annotation)来填充的
# 特别是 kubernetes.io/change-cause 这个注解
4.2 执行回滚到上一个版本
kubectl rollout undo:用于撤销资源的上一个滚动更新
例如,如果最近的Deployment更新有问题,可以使用此命令回滚到上一个版本
#将名为 "nginx" 的 Deployment 在 "app" 命名空间中的升级回滚到上一个版本
kubectl rollout undo deployment/nginx -n app
4.3 执行回滚到指定版本
#回滚名为"nginx"的部署到修订版本号为4的状态,并且该部署位于"app"命名空间中
kubectl rollout undo deployment/nginx --to-revision=4 -n app
#kubectl: 这是Kubernetes命令行工具的名称,用于与Kubernetes集群进行交互
#rollout undo: 这是kubectl命令的一部分,用于执行回滚操作
#deployment/nginx: 这是要回滚的部署的名称。在这个例子中,部署的名称是"nginx"
#--to-revision=4: 这是回滚到的特定修订版本的标志。在这个例子中,它指定要回滚到修订版本号为4的部署状态
#-n app: 这是指定命名空间的标志。在这个例子中,它指定了命名空间为"app"
4.4 检查回滚状态
#用于检查一个资源的滚动更新状态。例如,可以用它来检查Deployment的Pods是否都已更新到新的版本
kubectl rollout status deployment nginx -n app
5、删除 kubectl delete
kubectl delete 命令用于删除 Kubernetes 集群中的资源,可以是 pod、service、deployment 等。用户可以通过指定资源类型和名称来删除特定的资源,也可以使用标签选择器来批量删除符合条件的资源
5.1 删除副本控制器
kubectl delete deployment nginx -n app
5.2 删除 service
kubectl delete service nginx-server -n app
四、项目更新发布方式
1、蓝绿发布
蓝绿发布是一种部署新版本应用程序的策略,旨在减少对用户造成的影响。在蓝绿发布中,两个相同的生产环境并行存在,一个被标记为"蓝色"(Blue),另一个被标记为"绿色"(Green)
- 蓝色环境:当前稳定的生产环境
- 绿色环境:新版本的生产环境
在初始阶段,所有的用户流量都会指向蓝色环境。当新版本准备就绪时,流量可以逐渐转移到绿色环境。这种逐步迁移流量的方式允许进行实时监控,并在出现问题时快速回滚到蓝色环境。一旦绿色环境被验证为稳定可靠,蓝色环境可以被废弃或者保留作为备份
2、滚动发布
滚动发布是一种更新部署的方式,它允许您逐步更新应用程序的副本,以确保在整个更新过程中应用程序保持可用性。滚动发布通常通过部署(Deployment)资源来实现。
具体来说,滚动发布通过以下步骤来更新应用程序的副本:
-
逐步替换:滚动发布首先会创建新版本的Pod,并逐步将其替换掉旧版本的Pod。这确保了在整个更新过程中,至少有一定数量的旧版本Pod保持运行,从而保证应用程序的可用性
-
健康检查:在替换Pod的过程中,滚动发布会执行健康检查,确保新版本的Pod已经准备就绪并且能够处理流量。只有在新版本Pod被确认为健康之后,才会继续替换其他旧版本Pod
-
回滚支持:如果更新引入了问题,滚动发布还支持快速回滚操作,将部署回滚到之前的稳定状态
-
版本控制:滚动发布还可以根据需要控制并发更新的数量,以及更新的速率,从而更好地控制整个更新过程
通过滚动发布,Kubernetes能够以一种可控的方式更新应用程序,确保在更新过程中尽可能减少对应用程序的影响,并最大程度地保证应用程序的可用性。
3、灰度发布(金丝雀发布)
金丝雀发布(Canary Release),也被称为灰度发布或金丝雀部署,是一种降低在生产环境中引入新软件版本风险的技术。它允许在将更改全面推广到整个基础架构之前,先将这些更改缓慢地推广到一小部分用户,以验证新版本的稳定性和可靠性
金丝雀发布的名称来源于矿工使用金丝雀来检测矿井中是否存在有毒气体的做法。同样地,金丝雀发布允许团队在将新版本软件发布给所有用户之前,先将其发布给一小部分用户,以检测新版本是否存在问题
在Kubernetes(K8s)中,金丝雀发布(Canary Release)是一种用于在生产环境中逐步推出新版本应用程序的策略。它的主要目标是在不影响所有用户的情况下,先让一小部分用户或流量使用新版本,以便测试和验证新版本的稳定性和性能。如果新版本出现问题,可以迅速回滚到旧版本,从而避免影响整个生产环境
Deployment控制器支持自定义控制更新过程中的滚动节奏,如“暂停(pause)”或“继续(resume)”更新操作。比如等待第一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布
- 比如等待第一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本
- 然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行
- 确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布
#用于暂停一个资源的滚动更新。这在你想要暂停更新过程并稍后继续时很有用
kubectl rollout pause deployment/<deployment-name>
#用于恢复一个之前被暂停的滚动更新
kubectl rollout resume deployment/<deployment-name>
3.1 暂停更新
要在创建(kubectl create)和发布(kubectl expose)项目的基础上,进行以下的更新步骤
(1)先查看当前 pod 实例的版本,确保其都是旧版本
(2)然后更新 deployment 的版本,并配置暂停 deployment
然后监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为使用了 pause 暂停命令
kubectl set image deployment nginx nginx=nginx:1.20.2 -n app && kubectl rollout pause deployment nginx -n app
#kubectl set image:用于更新 Kubernetes 资源(如 Deployment、StatefulSet 等)中的容器镜像
#deployment nginx:指定要更新的 Deployment 的名称为 nginx
#nginx=nginx:1.20.2:指定要更新的容器名称为 nginx,并将其镜像设置为 nginx:1.20.2
#-n app:指定命名空间为 app
#这个命令用于暂停 nginx-test 命名空间中的 nginx Deployment 的滚动更新
kubectl rollout pause deployment nginx -n app
#kubectl rollout pause:用于暂停 Kubernetes Deployment 的滚动更新
#deployment nginx:指定要暂停滚动的 Deployment 的名称为 nginx
#-n app:指定命名空间为 app
(3)再测试当前所有实例的版本
(4)使用kubectl exec可以跨主机登录容器,并修改各pod访问界面为自定义界面,验证负载均衡
kubectl get pod -n app -owide #查看所有的pod的NAME
#跨主机登录容器
kubectl exec -it nginx-cc4b758d6-gm8sv bash -n app
此时外部客户端访问的流量会分摊一部分在新版本的pod实例上,但在实际环境中,新版本的pod实例是供测试的环境,而不是能给外部访问的。
接下来就会配置 pod 隔离,使新版本的 pod 实例只能供一小部分的测试人员访问
3.2 pod 隔离
流量控制:为了实现金丝雀发布,需要控制流量,使得只有一小部分用户或流量能够访问到新版本的应用程序
使用Service的selector和labels来选择性地路由流量到不同的Deployment。可以创建一个新的Service,其selector只匹配新版本的Pods,然后将一小部分流量路由到这个Service
3.2.1 修改新service的关联节点
(1)创建一个新的service
#创建一个service用于暴露新版本的pod实例的端口
kubectl expose deployment nginx --name=new-nginx --port=80 --target-port=80 --type=NodePort -n app
注:
新的serviceIP是可以访问,并且会将访问请求,平均分配到三个旧的pod实例与一个新的pod实例上
(2)获取 service 信息
#使用edit进入新建的service资源的编辑界面,并复制第 5-28 行的内容
kubectl edit svc new-nginx -n app
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: new-nginx
namespace: app
spec:
clusterIP: 10.96.210.201
clusterIPs:
- 10.96.210.201
externalTrafficPolicy: Cluster
ports:
- nodePort: 32194
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: NodePort
(3)获取所有 pod 实例的标签
kubectl get pod --show-labels -n app
注:
观察可得,下面三个pod实例的标签是一样的,因为它们同属与一个replicaset,当使用deployment 等控制器时,控制器会创建一个或多个 ReplicaSet,每个 ReplicaSet 负责管理一组具有相同 Pod 模板的 Pod。当有新的pod实例建立时,它不属于该replicaset,所以它的标签值也不相同
(4)创建 yaml 文件
[root@master ~]#vim new-nginx.yml
apiVersion: v1 #Kubernetes资源的API版本。通常是v1
kind: Service #定义了这个资源的类型
metadata: #定义Service的元数据
labels: #定义标签
app: nginx #标签键值
name: new-nginx #Service 的名称,必须在其命名空间中唯一
namespace: app #指定service所在的命名空间
spec: #描述了 Service 的规格和配置
clusterIP: 10.96.210.201 #Service 的集群内部 IP 地址
clusterIPs: #这是一个包含所有集群 IP 地址的列表,通常有且只有一个
- 10.96.210.201
externalTrafficPolicy: Cluster #指定当Service如何处理外部流量Cluster 意味着流量首先被路由到集群中的一个节点,然后转发到 Service 的后端 Pod
ports: #定义Service暴露的端口
- nodePort: 32194 #当Service的类型是NodePort时,节点上暴露的端口号
port: 80 #Service暴露在集群内部的端口号
protocol: TCP #用于此端口的TCP
targetPort: 80 #Pod上实际接收流量的端口号
selector: #键值对标签选择器,用于确定哪些Pod应该被包含在Service的后端集合中
pod-template-hash: "cc4b758d6" #定义为新的pod实例的标签,将此pod实例分离出去
sessionAffinity: None #无会话亲和性,ClientIP 意味着来自同一客户端 IP 的流量将被发送到同一个 Pod
type: NodePort #定义Service的类型为NodePort
(5)删除建立的新的service,并使用yaml重新生成
kubectl delete svc new-nginx -n app #删除之前创建的新的 service
kubectl apply -f new-nginx.yml #使用yaml文件重新生成新的service
此时该service只会关联指定标签的pod ,即新版本的pod
3.2.1 修改旧service的关联节点
同样的方法,将之前的 service 信息,保存到新的 yaml 文件当中
(1)创建 yaml 文件
[root@master ~]#vim old-nginx.yml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx-server
namespace: app
spec:
clusterIP: 10.96.198.166
clusterIPs:
- 10.96.198.166
externalTrafficPolicy: Cluster
ports:
- nodePort: 32093
port: 80
protocol: TCP
targetPort: 80
selector:
pod-template-hash: "d9d8cf5c7"
sessionAffinity: None
type: NodePort
(2)删除原来的service
kubectl delete svc nginx-server -n app #删除原来的 service
(3)使用yaml重新生成service
kubectl apply -f old-nginx.yml #使用yaml文件重新生成service
3.3 测试 pod 隔离效果
完成上述操作,相当于把旧版的Pod与新版本的Pod实例进行了分割,而后再通过关注新版本的性能和稳定性,来确保新版本能够正常运行
测试人员访问:
外部普通用户访问:
3.4 恢复更新
在确定新版本的pod实例能够正常使用,且没有漏洞时,再恢复更新
#用于恢复名为 "nginx" 的 Deployment 的滚动更新
#在 Kubernetes 中,您可以通过执行这条命令来恢复之前被暂停的滚动更新过程
#一旦执行此命令,Kubernetes 将继续滚动更新,以确保新的 Pod 实例逐步替换旧的 Pod 实例,从而实现应用的高可用性
kubectl rollout resume deployment nginx -n app
3.5 测试是否更新为新版本
相当于在新的service环境下建立的新的pod实例,而后将旧版本的从旧的service中删除
所以现在更新完的新版本的项目,使用的是新的service环境
注:
旧的service最好不要删除,当新版本出现问题,需要回滚时,旧版的pod还是会关联在旧的service当中
五、总结
1、陈述式资源管理方式
(1)查看基本信息
命令 | 说明 |
---|---|
kubectl version | 查看版本信息 |
kubectl api-resources | 查看资源对象简写 |
journalctl -u kubelet -f | node节点查看日志 |
source <(kubectl completion bash) | 配置kubectl自动补全 |
kubectl cluster-info | 查看集群信息 |
(2)获取资源信息
命令 | 作用 |
---|---|
kubectl get <resource_type> [-o wide|json|yaml] [-n namespace] | 获取指定类型的资源信息,如kubectl get pods获取所有Pod信息。-n 指定命令空间 -o 指定输出格式 |
kubectl describe <resource_type> <resource_name> | 显示指定资源的详细信息。 |
kubectl explain <resource> | 获取关于资源或资源字段的文档 |
(3)创建和删除资源
命令 | 说明 |
---|---|
kubectl create -f <filename> | 使用YAML或JSON文件创建资源。 |
kubectl create <resource> <resource_name> [-n ns]...... | 使用命令创建 |
kubectl delete <resource_type> <resource_name> | 删除指定类型的资源 |
kubectl run <pod-name> --image=<image> | 在集群中运行一个指定的镜像并创建一个Deployment或Pod |
(4)远程登录到容器内部
命令 | 作用 |
---|---|
kubectl exec -it <pod-name> -- <command> | 在Pod中的一个容器中执行命令 |
(5)扩容与缩容
命令 | 说明 |
---|---|
kubectl scale --replicas=<replicas> deployment/<deployment-name> | 缩放Deployment的副本集大小 |
(6)日志和事件
命令 | 说明 |
---|---|
kubectl logs <pod-name> | 获取Pod中容器的日志 |
kubectl get events | 获取集群中的事件信息 |
(7)其他常用命令
命令 | 说明 |
---|---|
kubectl top node | 显示节点的资源(CPU/内存/存储)使用情况 |
kubectl top pod | 显示Pod的资源使用情况 |
kubectl config use-context <context-name> | 切换到指定的上下文 |
kubectl set SUBCOMMAND [options] | 快速修改资源属性 |
kubectl config set-context --current --namespace=<namespace-name> | 设置当前上下文的命名空间 |
2、项目的生命周期
生命周期: 创建、发布、更新、回滚、删除
生命周期 | 说明 |
---|---|
创建 | kubelet create <资源类型> <资源名称> --image=镜像名称 --port=端口 --replicas=num |
发布 | kubelet expose <资源类型> <资源名称> --port= --targetport= type= clusterip或NodePort |
更新 | kubelet set image <资源类型> <资源名称> 容器名=镜像名:标签版本 |
回滚 | kubelet rollout undo <资源类型> <资源名称> (默认是回滚到上一个版本) kubelet rollout history 或status <资源类型> <资源名称> (查看回滚历史记录或者状态) |
删除 | kubelet delete <资源类型> <资源名称> |
3、项目更新发布方式
- 蓝绿发布
蓝:正在运行的稳定版本
绿:新版本的副本
进行新旧版本的切换,用户无感知、业务稳定;但是需要大量的资源、成本高。
- 滚动发布
按照比例一部分一部分的滚动更新;创建一定比例的 pod,先创建再删除旧的 pod。
- 金丝雀发布(灰度发布)
先更新一部分 pod,然后暂停更新;
安排一小部分的用户流量取访问更新的 pod 来进行测试;
当测试没有问题后再扩大比例,直到全部更新完成为止。