目录
引言
随着云计算和容器技术的日益成熟,Kubernetes(通常简称为K8s)已经成为了管理容器化工作负载的首选平台。掌握K8s的基础命令对于运维工程师和开发者来说至关重要。本文将带您深入了解K8s的一些基础命令及其用法。
一、命令概述
(一)命令分类
Kubernetes命令主要分为以下三类
陈述式命令(命令式对象管理):这种方式类似于直接在Docker中使用docker run命令。你可以直接使用kubectl命令来操作Kubernetes资源。例如,kubectl run nginx-pod --image=nginx:1.17.1 --port=80,这条命令会在集群中运行一个Pod,并指定Pod使用的Docker镜像和端口号。
陈述式对象配置(命令式对象配置):这种方式类似于使用docker-compose.yml文件。你可以通过kubectl命令和配置文件来操作Kubernetes资源。例如,kubectl create/delete -f nginx-pod.yaml,这条命令会根据nginx-pod.yaml文件中的定义来创建或删除一个Pod。
声明式对象配置(声明式对象配置):这种方式使用apply命令和配置文件来操作Kubernetes资源。它类似于数据库的操作方式,如果配置文件中定义了一个资源,并且该资源在集群中不存在,那么kubectl就会创建它;如果该资源已经存在但配置不同,那么kubectl就会更新它。例如,kubectl apply -f nginx-pod.yaml
(二)基本语法
kubectl命令的语法如下
kubectl [command] [type] [name] [flags]
comand #指定要对资源执行的操作,例如create、 get、delete
type #指定资源类型,比如deployment、pod、 service
name #指定资源的名称,名称大小写敏感
flags #指定额外的可选参数
二、查看基本信息
命令 | 作用 |
kubectl version | 查看版本信息 |
kubectl api-resources | 查看资源对象简写 |
journalctl -u kubelet -f | node节点查看日志 |
source <(kubectl completion bash) | 配置kubectl自动补全 |
kubectl cluster-info | 查看集群信息 |
[root@master01 ~]#kubectl version
Client Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.11", GitCommit:"27522a29febbcc4badac257763044d0d90c11abd", GitTreeState:"clean", BuildDate:"2021-09-15T19:21:44Z", GoVersion:"go1.15.15", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.11", GitCommit:"27522a29febbcc4badac257763044d0d90c11abd", GitTreeState:"clean", BuildDate:"2021-09-15T19:16:25Z", GoVersion:"go1.15.15", Compiler:"gc", Platform:"linux/amd64"}
(一)环境指令
1.查看版本信息
[root@master01 ~]#kubectl version
2.查看资源对象简写
[root@master01 ~]#kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoint
events ev v1 true Event
limitranges limits v1 true LimitRange
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Pod
podtemplates v1 true PodTemplate
.......
NAME:资源类型全拼
SHORTNAMES :简写
APIVERSION :资源所属的 API 版本
NAMESPACED :是否支持命名空间,true表示支持,false表示不支持
KIND :资源的类型或种类
例如services与svc表示同一个指令
3.添加补全信息
配置kubectl自动补全,使用source <(kubectl completion bash)指令,执行此命令后,可以使用tab键,在kubectl进行资源操作时进行补全
[root@master01 ~]#source <(kubectl completion bash)
#可以将此命令加入开机自行加载的文件。如$HOME/.bashrc文件、/etc/profile文件
4.查看日志
[root@node01 ~]#journalctl -u kubelet -f
5.查看集群信息
[root@master01 ~]#kubectl cluster-info
(二)查看资源信息
命令 | 作用 |
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>: | 获取关于资源或资源字段的文档 |
1.获取资源相关信息
kubectl get <resource> [-o wide|json|yaml] [-n namespace]
resource可以是具体资源名称,如pod nginx-xxx;
也可以是资源类型,如pod;
或者all(仅展示几种核心资源,并不完整)
-o 指定输出格式
-n 指定命令空间
1.1 查看集群组件状态
kubectl get componentstatuses 或 kubectl get cs
在master节点进行操作
NAME #集群中的组件名称
STATUS #组件的健康状态,通常是 "Healthy" 或 "Unhealthy"。
MESSAGE #提供了关于组件状态的额外信息,通常是一个简单的 "ok" 或更详细的消息。
ERROR #在组件不健康时可能会显示错误详情,但在健康时通常为空。
1.2 查看命名空间
kubectl get namespace或者kubectl get ns
Kubernetes 使用命名空间来将集群中的资源划分到不同的逻辑组中。
在同一个命名空间当中,不允许有相同名称的资源信息,但是在不同的命名空间中可以创建
默认的命名空间是 "default",但通常还有其他命名空间,
如 "kube-system"(用于 Kubernetes 系统组件)和用户自定义的命名空间
NAME #命名空间的名称。
STATUS #命名空间的当前状态,通常是 "Active",表示命名空间是活动的并且可用。
AGE #命名空间自创建以来的时长
1.3 查看命名空间中的资源
kubectl get [resource] [-n namespace]
查看kube-system中的pod资源
all代表所有类型的资源
--all-namespaces 或 -A :表示显示所有命令空间
1.4 查看资源详细信息
kubectl describe <资源类型> <资源名称> [-n 命名空间]
kubectl describe是Kubernetes命令行工具kubectl的一个命令,用于获取关于指定资源的详细信息。
当你想要深入了解某个资源的状态时(比如它的配置、事件、容器日志等),这个命令会非常有用
<资源类型> #描述的资源的类型,比如 pod、service、deployment、statefulset 等。
<资源名称> #你想要描述的资源的名称。
[-n 命名空间] #可选参数,指定资源所在的命名空间。不指定则为当前默认命名空间,通常是default。
查看命名空间kube-system中名称为etcd-master01的pod资源详细信息
(三)标签
1.标签的作用
辅助筛选资源:通过标签,我们可以筛选出具有特定属性的资源,便于管理和操作。
实现资源的分组:标签可以将资源进行分组,从而合理组织资源结构,使得管理更加有序。
支持负载均衡:在Kubernetes中,Service的Selector会根据标签匹配来实现负载均衡,确保请求能够分发到合适的Pod上。当一个pod迭代或替换之后,新的pod实例IP地址也会改变,同时会将IP地址绑定在标签上,通过访问标签,实现负载均衡
支持Pod的扩容和缩容:Deployment等控制器会根据匹配的标签进行Pod的扩容和缩容,以满足应用的需求。
支持扩展性和灵活性:标签为Kubernetes提供了一种非常灵活的资源管理方式,可以根据需要添加、修改或删除标签,以适应应用的变化和演进。
版本管理:可以使用标签标记不同版本的应用,方便进行版本控制和回滚操作。
2.标签的特点
每个对象都可以定义一组键值标签。
每个键对于给定对象必须是唯一的。
标签能够支持高效的查询和监听操作,对于用户界面和命令行是很理想的。
3.标签操作
3.1 查看存在资源的标签
kubectl get <资源类型> [-n 命名空间] --show-labels
查看kube-system命名空间中,所有pod实例的标签
指定查看某一个资源的标签
3.2 查看指定标签中含有的资源
kubectl get <资源类型> [-n 命名空间] -l <标签名称>
[root@master01 ~]#kubectl get pods -n kube-system -l component
NAME READY STATUS RESTARTS AGE
etcd-master01 1/1 Running 2 2d7h
kube-apiserver-master01 1/1 Running 11 2d7h
kube-controller-manager-master01 1/1 Running 18 2d6h
kube-scheduler-master01 1/1 Running 17 2d6h
get pods:指定查看资源类型为pod
-n kube-system:指定查看kube-system的命名空间
-l component :仅显示标签为component的资源
#整条命令的结果为查看kube-system命名空间中,所有标签名称为component的pod资源
3.3 查看标签中指定的资源
[root@master01 ~]#kubectl get pods -n kube-system -l component=kube-apiserver
NAME READY STATUS RESTARTS AGE
kube-apiserver-master01 1/1 Running 11 2d7h
-l component=kube-apiserver:指定查看包含component标签,且值为kube-apiserver的资源
三、创建和删除资源
1.创建命名空间
kubectl create ns <自定义名称>
2.创建pod实例
创建pod实例,其方法有两种
kubectl run:用于快速运行一个新的Pod。不需要进行繁琐的添加追加,一般快速运行与测试pod
kubectl create:是一个更通用的命令,可以与其他子命令一起使用,以创建特定的资源,
例如可以通过创建Deployment来启动pod
它还可以用于从文件、目录中创建资源。如YAML或JSON文件,这些文件描述了要创建的资源
2.1 使用run创建
通过kubectl run --help查看使用方法
[root@master01 ~]#kubectl run nginx --image=nginx -n china
kubectl run:创建一个pod资源
nginx:指定名称为nginx
--image=nginx:指定镜像名称
-n china:指定在china命名空间中创建
指定标签
web(键):键是一个标识符
true(值):值是与键相关联的数据
可以通过查看web标签中值为true的值,获取该pod实例的信息
2.2 使用create创建
kubectl create --help
#查看帮助说明
kubectl create <资源类型> <pod名称> --image=imagename [-n ns] ...
#标准输入创建
kubectl create -f <filename>
#使用YAML或JSON文件创建资源
[root@master01 ~]#kubectl create deployment nginx-01 --image=nginx --replicas=3 -n china
kubectl create:创建资源
deployment:创建deployment控制器,用于启动pod,并控制pod的预期值
nginx-01:deployment控制器名称
--image=nginx:指定了要在Pod中运行的Docker镜像的名称
--replicas=3: 这指定了 Deployment 应该运行多少个Pod的副本,不指定默认为1个
-n china:指定创建deployment所在的命名空间
# 查看 Deployment
kubectl get deployments -n china
# 查看 Deployment 的详细信息
kubectl describe deployment nginx-01 -n china
# 查看 Pod 的详细信息(例如,查看名为 nginx-01-xxxx-xxxx 的 Pod)
kubectl describe pod nginx-01-xxxx-xxxx -n china
3.删除资源
3.1 删除pod
上述两种方法创建的pod实例,在删除时候是有很大区别的
使用kubectl run创建的pod实例,使用kubectl delete可以直接删除
而使用delpoyment启动的pod实例,直接去删除pod是无法删除的
这是因为delpoyment控制器,是一种pod控制器,它建立在ReplicaSet之上的控制器,用于管理无状态应用,同时管理和控制Pod与ReplicaSet,确保pod实例,一直保持在replicaset设置的预期值上
想要删除pod实例,只能通过删除控制器来删除它管理的pod实例
删除副本控制器
[root@master01 ~]#kubectl delete deployments nginx-01 -n china
//若pod无法删除,总是处于terminate状态,则要强行删除pod
kubectl delete pod <pod-name> -n <namespace> --force --grace-period=0
#grace-period表示过渡存活期,默认30s,在删除pod之前允许POD慢慢终止其上的容器进程,从而优雅退出,0表示立即终止pod
3.2 删除命名空间
基本语法为
kubectl delete namespace <nsname>
注意事项:
①在删除命名空间之前,请确保该命名空间中没有正在运行的重要应用程序,以免影响集群的稳定性和可用性。
②有些命名空间可能是由Kubernetes系统自动生成的,不允许被删除。在删除之前,请确认命名空间是否允许被删除。
③在执行删除操作之前,请确保已经备份了必要的数据和配置
4.扩容与缩容
在Kubernetes中,扩容(Scaling Up)和缩容(Scaling Down)是管理集群中工作负载(如Pods)数量的重要操作
手动扩容与缩容都是通过scale指令来完成
kubectl scale <资源类型> <资源名称> --replicas=num [-n ns]
4.1 扩容
扩容意味着增加集群中运行Pod的数量,以满足更高的负载需求
首先使用deployment控制器创建三个pod实例
[root@master01 ~]#kubectl create deployment nginx --image=nginx --replicas=3 -n china
[root@master01 ~]#kubectl get pod -n china
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-tj2pb 1/1 Running 0 94s
nginx-6799fc88d8-tns95 1/1 Running 0 94s
nginx-6799fc88d8-wntct 1/1 Running 0 94s
当负载量过高时,可以通过扩容的方式来增加负载均很需求
[root@master01 ~]#kubectl get pod -n china
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-tj2pb 1/1 Running 0 94s
nginx-6799fc88d8-tns95 1/1 Running 0 94s
nginx-6799fc88d8-wntct 1/1 Running 0 94s
[root@master01 ~]#kubectl scale deployment nginx --replicas=6 -n china
#扩容到6个pod实例
deployment.apps/nginx scaled
[root@master01 ~]#kubectl get pod -n china
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-4gqvj 1/1 Running 0 65s
nginx-6799fc88d8-9m5lw 1/1 Running 0 65s
nginx-6799fc88d8-hpb8m 1/1 Running 0 65s
nginx-6799fc88d8-tj2pb 1/1 Running 0 8m31s
nginx-6799fc88d8-tns95 1/1 Running 0 8m31s
nginx-6799fc88d8-wntct 1/1 Running 0 8m31s
4.2 缩容
缩容意味着减少集群中运行Pod的数量,以节省资源或响应降低的负载需求
[root@master01 ~]#kubectl get pod -n china
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-4gqvj 1/1 Running 0 65s
nginx-6799fc88d8-9m5lw 1/1 Running 0 65s
nginx-6799fc88d8-hpb8m 1/1 Running 0 65s
nginx-6799fc88d8-tj2pb 1/1 Running 0 8m31s
nginx-6799fc88d8-tns95 1/1 Running 0 8m31s
nginx-6799fc88d8-wntct 1/1 Running 0 8m31s
[root@master01 ~]#kubectl scale deployment nginx --replicas=2 -n china
#将pod实例缩容到2个
deployment.apps/nginx scaled
[root@master01 ~]#kubectl get pod -n china
NAME READY STATUS RESTARTS AGE
nginx-6799fc88d8-tj2pb 1/1 Running 0 10m
nginx-6799fc88d8-tns95 1/1 Running 0 10m
注意事项
在进行扩容或缩容操作之前,请确保你的应用程序可以处理这些更改。例如,如果你的应用程序使用了外部存储或数据库连接,并且这些连接是静态的(即不是由Kubernetes管理的),那么增加或减少Pod数量可能会导致连接问题。
监控你的应用程序和集群的性能和健康状况,以确保扩容或缩容操作不会导致问题或性能下降。
使用HPA时,请确保你选择了合适的指标和目标值,以便正确地触发Pod的扩展和缩减。
在进行垂直扩展时,请确保你了解你的应用程序的资源需求,并避免设置过低的资源限制,这可能会导致性能问题或容器崩溃
5.发布服务
kubectl expose 允许你基于一个运行中的 Pod、Service、ReplicationController、ReplicaSet、Deployment 或 Job 来快速创建一个新的 Service
5.1 创建service的作用
将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的目的。
5.2 创建pod控制器
首先通过创建deployment控制器来启动nginx的pod实例,暴露容器端口 80,设置副本数3
此时只有集群当中的服务器可以进行访问,因为它们都启动了fiannel网络插件与网络代理,所以做到节点直接互相通信,且可以访问pod实例
使用其它服务器连接时会被拒绝,因为它现在只是一个pod实例,并没有形成service对外提供服务
所以,我们可以通过kubectl expose命令,将服务对外进行发布,使其它主机,可以访问到pod实例
5.3 创建service
kubectl expose deployment nginx --port=80 --target-port=80 --name=nginx-server --type=NodePort -n china
kubectl
#Kubernetes的命令行工具,用于与集群进行交互。
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 china
#-n(--namespace的缩写),用于指定命令应该在哪个命名空间(namespace)中执行
知识扩展
ClusterIP(默认类型)
为 Service 分配一个内部 IP 地址,这个 IP 地址是集群内部的虚拟 IP 地址,只能在集群内部访问。
通过这个 IP 地址,Kubernetes 会将流量路由到与 Service 关联的一组 Pod。
这种类型的服务最适合那些仅需要在集群内部调用的应用。
NodePort
在 ClusterIP 的基础上,为 Service 在每个 Node 上分配一个端口(范围通常为 30000-32767)。
通过 NodeIP:NodePort 的形式,可以从集群外部访问 Service。
任何请求到这个端口的流量都会被转发到 Service 背后的相关 Pod。
LoadBalancer
通常由云服务提供商支持(例如 AWS、GKE 等)。
为 Service 分配一个外部 IP 地址,通过外部 IP 地址可以访问 Service。
通常还包括负载均衡的功能,将外部请求分发到集群内部的 Pod。
在 NodePort 的基础上,向云服务提供商申请负载均衡器,并将负载均衡器的后端映射到各 Node 节点的 NodePort 上。
ExternalName
这是 Service 的一种特例形式。
不创建集群内的代理,而是返回一个 CNAME 记录指向指定的 DNS 名称。
此类型的服务主要用于将集群内的服务映射到集群外的某个服务。
使用endpoints指令,查看后端关联的后端节点
[root@master01 ~]#kubectl get endpoints -n china
NAME ENDPOINTS AGE
nginx-server 10.244.1.41:80,10.244.1.42:80,10.244.2.54:80 78m
也可以通过kubectl describe 指令查看service的描述信息
[root@master01 ~]#kubectl describe svc nginx-server -n china
Name: nginx-server #serivce名称
Namespace: china #所在命名空间
Labels: app=nginx #标签名称
Annotations: <none> #服务没有注解
Selector: app=nginx #服务的选择器,表示所有具有app=nginx标签的Pod都将作为此服务的后端
Type: NodePort #服务的类型是NodePort
IP Families: <none> #服务没有指定特定的 IP 地址族
IP: 10.96.47.51 #服务的 ClusterIP
IPs: 10.96.47.51 #同上,列出了服务的 ClusterIP
Port: <unset> 80/TCP #<unset> 表示没有为服务定义命名端口,默认的端口和协议(80/TCP)被列在了后面
TargetPort: 80/TCP #流量将被转发到 Pod 上的 80/TCP 端口
NodePort: <unset> 32444/TCP #NodePort端口号为32444
Endpoints: 10.244.1.41:80,10.244.1.42:80,10.244.2.54:80 #该服务提供服务的 Pod 的 IP 地址和端口
Session Affinity: None #没有启用会话亲和性,这意味着对于客户端的连续请求,可能会被路由到不同的 Pod
External Traffic Policy: Cluster #设置为 Cluster。路由外部流量到集群的所有Pods上
Events: <none> #显示为 <none>,表示没有与该服务相关的事件
使用客户端浏览器访问任意一个节点ip的32444端口,都可以访问到nginx的pod实例
6.负载均衡
当上述条件以及service创建好后,会以默认轮询的方式实现负载均衡
在任意node节点上下载ipvsadm,使用ipvsadm命令查看负载均衡端口
[root@node01 ~]#yum install ipvsadm -y
[root@node01 ~]#ipvsadm -Ln
修改各pod访问界面为自定义界面,验证负载均衡
kubectl exec可以跨主机登录容器,docker exec 只能在容器所在主机上登录
kubectl exec -it <pod-name> <-n ns> bash
但是,使用curl浏览器与web浏览器访问结果不一样,需要注意
在集群内部使用curl访问集群集群service的IP地址
使用集群节点的web浏览器访问时,它会将多次请求转发到同一个pod实例上。这通常是由浏览器行为或网络配置导致的,主要原因可能在与连接复用
现代浏览器通常会复用 TCP 连接,以减少延迟和开销。这意味着,如果浏览器已经与某个 Pod 的某个端口建立了连接,并且这个连接仍然处于打开状态,那么浏览器可能会继续使用这个连接发送请求,而不是尝试与集群中的其他 Pod 建立新的连接
使用客户端访问节点IP的效果一样
7.更新版本
kubectl set是一个用于设置资源字段的命令行工具,它提供了一种直接修改 Kubernetes 资源字段的方式,而无需直接编辑 YAML 或 JSON 文件。kubectl set 命令通常用于快速修改资源的某些属性,如环境变量、标签、注解等
[root@master01 ~]#kubectl set --help
#获取帮助信息
7.1 查看版本更新策略
set指令版本滚动策略,可以使用kubectl describe来进行查看
[root@master01 ~]#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。
7.2 更新版本过程
set更新版本过程,以三个pod为例
首先在确保正常提供服务的情况下,在三个pod实例正常运行的情况下,生成一个新的指定版本呢的pod实例,等到新的pod实例创建成功后,会删除第一个pod实例,而后再生成第二个新版本的pod实例,再删除第二个,依此类推,一直到该deployment下的所有pod资源全部升级完毕。
需要注意的是,资源更新后,其原本pod实例中的数据并不会被继承。如果有需要的话,可以先对数据进行备份,等到升级完毕后,再同步数据
7.3 版本更新
首先获取当前版本信息
[root@master01 ~]#kubectl get pod,svc -n china -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/nginx-579fdb4c89-ghsbb 1/1 Running 1 64m 10.244.2.54 node02 <none> <none>
pod/nginx-579fdb4c89-hqkcw 1/1 Running 1 64m 10.244.1.41 node01 <none> <none>
pod/nginx-579fdb4c89-wxwz5 1/1 Running 1 64m 10.244.1.42 node01 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/nginx-server NodePort 10.96.47.51 <none> 80:32444/TCP 63m app=nginx
[root@master01 ~]#curl 192.168.83.40:32444 -I #获取当前版本信息
HTTP/1.1 200 OK
Server: nginx/1.18.0 #当前版本为nginx/1.18.0
Date: Mon, 20 May 2024 04:24:46 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Apr 2020 14:09:01 GMT
Connection: keep-alive
ETag: "5e9efe7d-264"
Accept-Ranges: bytes
set升级版本
[root@master01 ~]#kubectl set image deployment nginx nginx=nginx:1.20.2 -n china
[root@master01 ~]#kubectl get pods -n china
NAME READY STATUS RESTARTS AGE
nginx-5777589579-xw769 0/1 ContainerCreating 0 2s #创建指定版本的nginx
nginx-579fdb4c89-ghsbb 1/1 Running 1 67m
nginx-579fdb4c89-hqkcw 1/1 Running 1 67m
nginx-579fdb4c89-wxwz5 1/1 Running 1 67m
[root@master01 ~]#kubectl get pods -n china
NAME READY STATUS RESTARTS AGE
nginx-5777589579-6ln4f 1/1 Running 0 3s
nginx-5777589579-v2zgf 0/1 ContainerCreating 0 0s
nginx-5777589579-xw769 1/1 Running 0 5s
nginx-579fdb4c89-ghsbb 0/1 Terminating 1 68m #新版本创建完毕后优雅退出
nginx-579fdb4c89-hqkcw 1/1 Running 1 68m
nginx-579fdb4c89-wxwz5 1/1 Terminating 1 68m
[root@master01 ~]#kubectl get pods -n china -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-5777589579-6ln4f 1/1 Running 0 2m12s 10.244.2.73 node02 <none> <none>
nginx-5777589579-v2zgf 1/1 Running 0 2m9s 10.244.1.65 node01 <none> <none>
nginx-5777589579-xw769 1/1 Running 0 2m14s 10.244.1.64 node01 <none> <none>
#所有版更新完毕,对应的IP地址也会改变,但是service对外暴露的端口不会改变
[root@master01 ~]#curl 192.168.83.40:32444 -I
HTTP/1.1 200 OK
Server: nginx/1.20.2 #版本更新为1.20.2
Date: Mon, 20 May 2024 04:37:35 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 16 Nov 2021 14:44:02 GMT
Connection: keep-alive
ETag: "6193c3b2-264"
Accept-Ranges: bytes
8.版本回滚
kubectl rollout 是一个用于管理 Kubernetes 部署(Deployments)和其他资源的滚动更新的命令。通过 kubectl rollout,你可以触发滚动更新、检查状态、撤销更新等操作
[root@master01 ~]#kubectl rollout --help
#查看回滚指令帮助说明
8.1 查看历史版本
kubectl rollout history deployment/my-deployment
用于查看资源的滚动更新历史。例如,可以查看Deployment的所有历史版本。
kubectl rollout history deployment/my-deployment --revision=num
查看特定版本的详细信息
------------------------------------------------------------------------------------
[root@master01 ~]#kubectl rollout history deployment nginx -n china
deployment.apps/nginx
REVISION CHANGE-CAUSE
1 <none>
2 <none>
------------------------------------------------------------------------------------
REVISION #显示历史中的每个版本,最多记录三次
CHANGE-CAUSE #显示触发该版本变更的原因。显示为 <none>,表示没有明确的变更原因被记录
#Kubernetes本身不会自动为每次Deployment的更新填充CHANGE-CAUSE字段。
#这个字段通常是通过设置 Deployment 的注解(annotation)来填充的
#特别是 kubernetes.io/change-cause 这个注解。
#当使用某些工具进行更新时,这些工具可能会自动设置这个注解
8.2 撤销上一次更新
kubectl rollout undo
用于撤销资源的上一个滚动更新。
例如,如果最近的Deployment更新有问题,可以使用此命令回滚到上一个版本。
----------------------------------------------------------------------------
[root@master01 ~]#curl 192.168.83.40:30941 -I
HTTP/1.1 200 OK
Server: nginx/1.20.2 #现在的版本为1.20.2
Date: Mon, 20 May 2024 04:54:42 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 16 Nov 2021 14:44:02 GMT
Connection: keep-alive
ETag: "6193c3b2-264"
Accept-Ranges: bytes
[root@master01 ~]#kubectl rollout undo deployment nginx -n china #回滚到上一次版本
deployment.apps/nginx rolled back
[root@master01 ~]#curl 192.168.83.40:30941 -I
HTTP/1.1 200 OK
Server: nginx/1.18.0 #上一次版本为1.18.0
Date: Mon, 20 May 2024 04:54:53 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Apr 2020 14:09:01 GMT
Connection: keep-alive
ETag: "5e9efe7d-264"
Accept-Ranges: bytes
---------------------------------------------------------------------------
也可以通过 kubectl rollout undo deployment/my-deployment --to-revision=num
指定回滚到某一个历史版本,num对应kubectl rollout history查看的revision的值
---------------------------------------------------------------------------
[root@master01 ~]#kubectl rollout status deployment nginx -n china
deployment "nginx" successfully rolled out
----------------------------------------------------------------------------
kubectl rollout status
用于检查一个资源的滚动更新状态。例如,可以用它来检查Deployment的Pods是否都已更新到新的版本
9.金丝雀发布
金丝雀发布(Canary Release),也被称为灰度发布或金丝雀部署,是一种降低在生产环境中引入新软件版本风险的技术。它允许在将更改全面推广到整个基础架构之前,先将这些更改缓慢地推广到一小部分用户,以验证新版本的稳定性和可靠性。
金丝雀发布的名称来源于矿工使用金丝雀来检测矿井中是否存在有毒气体的做法。同样地,金丝雀发布允许团队在将新版本软件发布给所有用户之前,先将其发布给一小部分用户,以检测新版本是否存在问题
在Kubernetes(K8s)中,金丝雀发布(Canary Release)是一种用于在生产环境中逐步推出新版本应用程序的策略。它的主要目标是在不影响所有用户的情况下,先让一小部分用户或流量使用新版本,以便测试和验证新版本的稳定性和性能。如果新版本出现问题,可以迅速回滚到旧版本,从而避免影响整个生产环境
Deployment控制器支持自定义控制更新过程中的滚动节奏,如“暂停(pause)”或“继续(resume)”更新操作。比如等待第一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布
kubectl rollout pause deployment/my-deployment
#用于暂停一个资源的滚动更新。这在你想要暂停更新过程并稍后继续时很有用
kubectl rollout resume deployment/my-deployment
#用于恢复一个之前被暂停的滚动更新。
在新的命名空间中创建pod实例并暴露端口,对外提供服务
[root@master01 ~]#kubectl create deployment nginx --image=nginx:1.18 --replicas=3 -n nginx-test
deployment.apps/nginx created
[root@master01 ~]#kubectl expose deployment nginx --port=80 --target-port=80 --name=nginx-svc --type=NodePort -n nginx-test
service/nginx-svc exposed
[root@master01 ~]#kubectl get pod -n nginx-test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-84b9b46f96-6vz9b 1/1 Running 0 7m35s 10.244.1.74 node01 <none> <none>
nginx-84b9b46f96-7qmv4 1/1 Running 0 7m35s 10.244.2.88 node02 <none> <none>
nginx-84b9b46f96-8fkfk 1/1 Running 0 7m35s 10.244.2.87 node02 <none> <none>
[root@master01 ~]#kubectl get service nginx-svc -n nginx-test -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx-svc NodePort 10.96.182.14 <none> 80:31088/TCP 2m2s app=nginx
查看版本
9.1 暂停更新
更新deployment的版本,并配置暂停deployment
[root@master01 ~]#kubectl set image deployment nginx nginx=nginx:1.20.2 -n nginx-test && kubectl rollout pause deployment nginx -n nginx-test
------------------------------------------------------------------------------
kubectl set image
#用于更新 Kubernetes 资源(如 Deployment、StatefulSet 等)中的容器镜像。
deployment nginx
#指定要更新的 Deployment 的名称为 nginx。
nginx=nginx:1.20.2
#指定要更新的容器名称为 nginx,并将其镜像设置为 nginx:1.20.2。
-n nginx-test
#指定命名空间为 nginx-test。
kubectl rollout pause deployment nginx -n nginx-test
#这个命令用于暂停 nginx-test 命名空间中的 nginx Deployment 的滚动更新。
kubectl rollout pause
#用于暂停 Kubernetes Deployment 的滚动更新。
deployment nginx
#指定要暂停滚动的 Deployment 的名称为 nginx。
-n nginx-test
#指定命名空间为 nginx-test。
此时,客户端的访问流量会分配一部分给新版本的pod实例
9.2 pod隔离
流量控制:为了实现金丝雀发布,需要控制流量,使得只有一小部分用户或流量能够访问到新版本的应用程序。
使用Service的selector和labels来选择性地路由流量到不同的Deployment。可以创建一个新的Service,其selector只匹配新版本的Pods,然后将一小部分流量路由到这个Service。
9.2.1 创建service
创建service并暴露端口
[root@master01 mnt]#kubectl get svc -n nginx-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc NodePort 10.96.182.14 <none> 80:31088/TCP 21h
[root@master01 mnt]#kubectl expose deployment nginx --name=new-nginx --port=80 --target-port=80 --type=NodePort -n nginx-test
service/new-nginx exposed
#创建一个service用于暴露新版本的pod实例的端口
[root@master01 mnt]#kubectl get svc -n nginx-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
new-nginx NodePort 10.96.60.122 <none> 80:30209/TCP 11s
nginx-svc NodePort 10.96.182.14 <none> 80:31088/TCP 24h
[root@master01 mnt]#curl 10.96.60.122 -I
HTTP/1.1 200 OK
Server: nginx/1.18.0
Date: Tue, 21 May 2024 06:01:33 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 21 Apr 2020 14:09:01 GMT
Connection: keep-alive
ETag: "5e9efe7d-264"
Accept-Ranges: bytes
[root@master01 mnt]#curl 10.96.60.122 -I
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Tue, 21 May 2024 06:01:34 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 16 Nov 2021 14:44:02 GMT
Connection: keep-alive
ETag: "6193c3b2-264"
Accept-Ranges: bytes
......
#新的serviceIP是可以访问,并且会将访问请求,平均分配到三个旧的pod实例与一个新的pod实例上
9.2.2 获取service信息
[root@master01 mnt]#kubectl edit svc new-nginx -n nginx-test
#使用edit进入新建的service资源的编辑界面,并复制5-28行的内容
1 # Please edit the object below. Lines beginning with a '#' will be ignored,
2 # and an empty file will abort the edit. If an error occurs while saving this file will be
3 # reopened with the relevant failures.
4 #
5 apiVersion: v1
6 kind: Service
7 metadata:
8 creationTimestamp: "2024-05-21T05:58:29Z"
9 labels:
10 app: nginx
11 name: new-nginx
12 namespace: nginx-test
13 resourceVersion: "167872"
14 uid: 4d285e5c-b133-4f12-86fa-154c4d9dc89b
15 spec:
16 clusterIP: 10.96.60.122
17 clusterIPs:
18 - 10.96.60.122
19 externalTrafficPolicy: Cluster
20 ports:
21 - nodePort: 30209
22 port: 80
23 protocol: TCP
24 targetPort: 80
25 selector:
26 app: nginx
27 sessionAffinity: None
28 type: NodePort
29 status:
30 loadBalancer: {}
获取所有pod实例的标签
可以看到,下面三个pod实例的标签是一样的,因为它们同属与一个replicaset,当使用deployment等控制器时,控制器会创建一个或多个 ReplicaSet,每个 ReplicaSet 负责管理一组具有相同 Pod 模板的 Pod。当有新的pod实例建立时,它不属于该replicaset,所以它的标签值也不相同
9.2.3 建立yaml文件
[root@master01 mnt]#cat new-nginx.yaml
apiVersion: v1 #Kubernetes资源的API版本。通常是v1
kind: Service #定义了这个资源的类型
metadata: #定义Service的元数据
labels: #定义标签
app: nginx #标签键值
name: new-nginx #Service 的名称,必须在其命名空间中唯一
namespace: nginx-test #指定service所在的命名空间
spec: #描述了 Service 的规格和配置
clusterIP: 10.96.60.122 #Service 的集群内部 IP 地址
clusterIPs: #这是一个包含所有集群 IP 地址的列表,通常有且只有一个
- 10.96.60.122
externalTrafficPolicy: Cluster #指定当Service如何处理外部流量Cluster 意味着流量首先被路由到集群中的一个节点,然后转发到 Service 的后端 Pod
ports: #定义Service暴露的端口
- nodePort: 30209 #当Service的类型是NodePort时,节点上暴露的端口号
port: 80 #Service暴露在集群内部的端口号
protocol: TCP #用于此端口的TCP
targetPort: 80 #Pod上实际接收流量的端口号
selector: #键值对标签选择器,用于确定哪些Pod应该被包含在Service的后端集合中
pod-template-hash: "5777589579" #定义为新的pod实例的标签,将此pod实例分离出去
sessionAffinity: None #无会话亲和性,ClientIP 意味着来自同一客户端 IP 的流量将被发送到同一个 Pod
type: NodePort #定义Service的类型为NodePort
9.2.4 生成service
删除建立的新的service,并使用yaml重新生成
[root@master01 mnt]#kubectl get svc -n nginx-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
new-nginx NodePort 10.96.60.122 <none> 80:30209/TCP 76m
nginx-svc NodePort 10.96.182.14 <none> 80:31088/TCP 25h
[root@master01 mnt]#kubectl delete svc new-nginx -n nginx-test
service "new-nginx" deleted
[root@master01 mnt]#kubectl get svc -n nginx-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc NodePort 10.96.182.14 <none> 80:31088/TCP 25h
[root@master01 mnt]#kubectl apply -f new-nginx.yaml
service/new-nginx created
[root@master01 mnt]#kubectl get svc -n nginx-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
new-nginx NodePort 10.96.60.122 <none> 80:30209/TCP 29s
nginx-svc NodePort 10.96.182.14 <none> 80:31088/TCP 25h
此时该service只会关联指定标签的pod
[root@master01 mnt]#kubectl get endpoints new-nginx -n nginx-test #查看新建service关联的后端节点
NAME ENDPOINTS AGE
new-nginx 10.244.2.93:80 2m30s
[root@master01 mnt]#curl 10.244.2.93 -I
HTTP/1.1 200 OK
Server: nginx/1.20.2
Date: Tue, 21 May 2024 07:21:27 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 16 Nov 2021 14:44:02 GMT
Connection: keep-alive
ETag: "6193c3b2-264"
Accept-Ranges: bytes
--------------------------------------------------------------------------
#此时,该service只会将流量转发到新建的pod实例上
9.3 修改源service的关联节点
同样的方法,将之前的service信息,保存到新的yaml文件当中
9.3.1 建立yaml文件
[root@master01 mnt]#kubectl edit svc nginx-svc -n nginx-test
Edit cancelled, no changes made.
[root@master01 mnt]#vim nginx-svc.yaml
[root@master01 mnt]#cat nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx-svc
namespace: nginx-test
spec:
clusterIP: 10.96.182.14
clusterIPs:
- 10.96.182.14
externalTrafficPolicy: Cluster
ports:
- nodePort: 31088
port: 80
protocol: TCP
targetPort: 80
selector:
pod-template-hash: "84b9b46f96" #修改为replicaset管理的旧版本的pod标签
sessionAffinity: None
type: NodePort
9.3.2 生成service
[root@master01 mnt]#kubectl describe endpoints nginx-svc -n nginx-test
Name: nginx-svc
Namespace: nginx-test
Labels: app=nginx
Annotations: endpoints.kubernetes.io/last-change-trigger-time: 2024-05-21T03:25:16Z
Subsets:
Addresses: 10.244.1.76,10.244.2.91,10.244.2.92,10.244.2.93 #后端关联地址
NotReadyAddresses: <none>
Ports:
Name Port Protocol
---- ---- --------
<unset> 80 TCP
Events: <none>
删除原service,并建立重新建立
[root@master01 mnt]#kubectl get svc -n nginx-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-svc NodePort 10.96.182.14 <none> 80:31088/TCP 25h
new-nginx NodePort 10.96.60.122 <none> 80:30209/TCP 17m
[root@master01 mnt]#kubectl delete svc nginx-svc -n nginx-test
service "nginx-svc" deleted
#删除service
[root@master01 mnt]#kubectl apply -f nginx-svc.yaml
service/nginx-svc created
#重新建立service
[root@master01 mnt]#kubectl get svc -n nginx-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
new-nginx NodePort 10.96.60.122 <none> 80:30209/TCP 17m
nginx-svc NodePort 10.96.182.14 <none> 80:31088/TCP 58s
[root@master01 mnt]#kubectl get endpoints nginx-svc -n nginx-test
NAME ENDPOINTS AGE
nginx-svc 10.244.1.76:80,10.244.2.91:80,10.244.2.92:80 21s
#查看后端关联地址
完成上述操作,相当于把旧版的Pod与新版本的Pod实例进行了分割,而后再通过关注新版本的性能和稳定性,来确保新版本能够正常运行。在确定新版本的pod实例能够正常使用,且没有漏洞时,再恢复更新
9.4 恢复更新
[root@master01 mnt]#kubectl rollout resume deployment nginx -n nginx-test
deployment.apps/nginx resumed
#恢复更新
[root@master01 mnt]#kubectl rollout status deployment nginx -n nginx-test
deployment "nginx" successfully rolled out
#查看更新状态人
[root@master01 mnt]#kubectl get pod -n nginx-test
NAME READY STATUS RESTARTS AGE
nginx-5777589579-895j8 1/1 Running 0 35s
nginx-5777589579-lx85b 1/1 Running 0 4h16m
nginx-5777589579-xx9hc 1/1 Running 0 37s
9.5 访问测试
相当于在新的service环境下建立的新的pod实例,而后将旧版本的从旧的service中删除
注释:旧的service最好不要删除,当新版本出现问题,需要回滚时,旧版的pod还是会关联在旧的service当中
10.删除资源
删除副本控制器
[root@master01 ~]#kubectl delete deployment nginx -n china
deployment.apps "nginx" deleted
[root@master01 ~]#kubectl get pod -n china
No resources found in china namespace.
删除service
[root@master01 ~]#kubectl get service -n china
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-server NodePort 10.96.47.51 <none> 80:30941/TCP 116m
[root@master01 ~]#kubectl delete service nginx-server -n china
service "nginx-server" deleted
[root@master01 ~]#kubectl get service -n china
No resources found in china namespace.
四、命令总结
(一)查看基本信息
命令 | 作用 |
kubectl version | 查看版本信息 |
kubectl api-resources | 查看资源对象简写 |
journalctl -u kubelet -f | node节点查看日志 |
source <(kubectl completion bash) | 配置kubectl自动补全 |
kubectl cluster-info | 查看集群信息 |
(二)获取资源信息
命令 | 作用 |
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>: | 获取关于资源或资源字段的文档 |
(三)创建和删除资源
命令 | 作用 |
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 |
(四)更新资源
命令 | 作用 |
kubectl apply -f <filename> | 应用配置文件中的更改 |
kubectl replace -f <filename> | 替换现有的资源配置 |
kubectl set SUBCOMMAND [options] | 快速修改资源属性 |
kubectl set image deployment/<deployment-name> <container-name>=<image> | 更新Deployment中的容器镜像 |
(五)执行命令
命令 | 作用 |
kubectl exec -it <pod-name> -- <command> | 在Pod中的一个容器中执行命令 |
(六)日志和事件
命令 | 作用 |
kubectl logs <pod-name> | 获取Pod中容器的日志 |
kubectl get events | 获取集群中的事件信息 |
(七)扩容与缩容
命令 | 作用 |
kubectl scale --replicas=<replicas> deployment/<deployment-name> | 缩放Deployment的副本集大小 |
(八)更新版本与回滚
命令 | 作用 |
kubectl set image deployment/<deployment-name> <container-name>=<image> | 更新Deployment中的容器镜像 |
kubectl rollout status deployment/<deployment-name> | 检查Deployment的滚动更新状态 |
kubectl rollout undo deployment/<deployment-name> | 回滚Deployment的更改 |
(九)其他常用命令
命令 | 作用 |
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> | 设置当前上下文的命名空间 |
(十)高级命令
命令 | 作用 |
kubectl autoscale | 自动扩展Pod的数量,基于CPU使用率或其他指标 |
kubectl cordon <node-name>: | 将节点标记为不可调度 |
kubectl drain <node-name> | 安全地排空节点,以便进行维护 |
kubectl taint nodes <node-name> key=value:NoSchedule | 给节点添加污点,防止Pod调度到该节点上 |