Bootstrap

Kubernetes——Kubectl详解

目录

前言

一、陈述式资源管理方法

二、Kubectl命令操作

1.查

1.1kubectl version——查看版本信息

1.2kubectl api-resources——查看资源对象简写

1.3kubectl cluster-info——查看集群信息 

1.4配置Kubectl补全

1.5journalctl -u kubelet -f——查看日志

1.6kubectl get cs(componentstatuses)——查看节点状态

1.7kubectl get ns——查看命名空间

1.8kubectl get all——查看default命名空间的所有资源

1.9kubectl get  --show-labels——查看节点标签

1.10kubectl get pod -l label(-A)——根据标签进行条件查找 

1.11kubectl get pod -n ——查看具体命名空间内信息

1.12kubectl describe [-o wide|json|yaml] [-n namespace]——查看资源详细信息

1.13kubectl logs ——查看资源日志

2.增

2.1kubectl create namespace ——创建命名空间

2.2kubectl run --image -n ——指定命名空间中创建资源

2.2.1拓展

2.3kubectl create deployment --image -n ——指定命名空间中创建自主式Pod资源

3.删

3.1kubectl delete namespace ——删除命名空间

3.2kubectl delete pod -n ——删除Pod资源

3.3删除副本控制器

4.改

5.扩缩容

5.1扩容——针对并发量增加

5.2缩容——针对并发量减少

三、项目生命周期

1.创建——kubectl create

2.发布——kubectl expose

2.1Service的Type类型

2.2Port——Kubernetes集群中的Port

2.3测试Service暴露在Cluster集群使其可以访问

2.4测试Port暴露在外部流量中可以使其可以访问

2.6Endpoint——端点

3.更新——kubectl set

4.回滚——kubectl rollout

5.删除——kubectl delete

四、主要发布过程

1.蓝绿发布

2.滚动发布

3.金丝雀发布(Canary Release)灰度发布

五、声明式资源管理方法

六、总结

1.命令操作

2.Port端口

3.数据流向

4.生命周期

5.声明式管理方法


前言

本章我们来深入了解一下关于Kubernetes的命令行工具Kubectl的使用,相信前面的几篇博客都已经见到了使用Kubectl命令行工具,现在我们使用测试环境对Kubectl命令行工具管理操作进行详细解答。

管理操作分为两大类,陈述式和声明式

一、陈述式资源管理方法

  • Kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 APIServer 的接口
  • Kubectl 是官方的CLI命令行工具,用于与 APIServer 进行通信,将用户在命令行输入的命令,组织并转化为 APIServer 能识别的信息,进而实现管理 k8s 各种资源的一种有效途径
  • Kubectl 的命令大全

kubectl --help
k8s中文文档:http://docs.kubernetes.org.cn/683.html

  • 对资源的增、删、查操作比较方便,但对改的操作就不容易了

二、Kubectl命令操作

1.查

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的资源

1.1kubectl version——查看版本信息

1.2kubectl api-resources——查看资源对象简写

1.3kubectl cluster-info——查看集群信息 

1.4配置Kubectl补全

echo "source <(kubectl completion bash)" >> /root/.bashrc

1.5journalctl -u kubelet -f——查看日志

 -u指定服务,-f实时查看日志

1.6kubectl get cs(componentstatuses)——查看节点状态

1.7kubectl get ns——查看命名空间

命令空间的作用:用于允许不同命令空间的相同类型的资源重名

1.8kubectl get all——查看default命名空间的所有资源

1.9kubectl get <resource> --show-labels——查看节点标签

Label类似于键值对,标签的键值对以逗号分隔

1.10kubectl get pod -l label(-A)——根据标签进行条件查找 

1.11kubectl get pod -n <namespace>——查看具体命名空间内信息

模糊查找 

1.12kubectl describe <resource> [-o wide|json|yaml] [-n namespace]——查看资源详细信息

1.13kubectl logs <resource>——查看资源日志

2.增

2.1kubectl create namespace <name>——创建命名空间

2.2kubectl run <image:name> --image -n <namespace>——指定命名空间中创建资源

2.2.1拓展

由此我们看到刚刚创建的pod是在Node节点上的,现在我们假设Node2节点出现了问题

我们看到Pod也挂掉了,我们再重启Node2节点,发现静态的Pod就不存在了

但是如果对于动态的Pod的话,如果Node2挂掉的话,会重新创建一个新的Pod,并有新的节点来接替Node2的工作,如果再重启Node2之后,那么原来的Pod就会删除

2.3kubectl create deployment <image:name> --image -n <namespace>——指定命名空间中创建自主式Pod资源

这里可以明显看到使用kubectl run创建的资源只有指定的名称,但是我们使用kubectl create deployment创建的资源就会有携带的ID。

 Kubectl run创建的资源是存放在节点当中的;Kubectl create deployment创建的资源是存放在etcd中的

3.删

3.1kubectl delete namespace <name>——删除命名空间

此命令谨慎使用,因为如果命名空间中有资源存在,那么该命名空间直接被删除的话,该命名空间中的资源也不复存在了。

3.2kubectl delete pod <name> -n <namespace>——删除Pod资源

如果是删除kubectl run命令创建的资源,一旦删除不会再创建;如果是删除kubectl create deployment 命令创建的资源,一旦删除又会重新创建新的Pod资源;

若pod无法删除,总是处于terminate状态,则要强行删除pod
kubectl delete pod <pod-name> -n <namespace> --force --grace-period=0
#grace-period表示过渡存活期,默认30s,在删除pod之前允许POD慢慢终止其上的容器进程,从而优雅退出,0表示立即终止pod

  • kubectl run:创建自助式静态Pod
  • kubectl create deployment:创建deployment控制器管理的Pod

3.3删除副本控制器

kubectl delete deployment nginx-wl -n kube-public
kubectl delete deployment/nginx-wl -n kube-public

4.改

如果容器报错的话,可以跨主机登入相对应的Pod资源内对配置进行修改

5.扩缩容

5.1扩容——针对并发量增加

5.2缩容——针对并发量减少

三、项目生命周期

1.创建——kubectl create

  • 创建并运行一个或多个容器镜像。
  • 创建一个deployment 或job 来管理容器。
kubectl create --help
#启动 nginx 实例,暴露容器端口 80,设置副本数 3 ,设置所处命名空间为 cxk
kubectl create deployment nginx-cxk --image=nginx:1.14 --port=80 --replicas=3 -n cxk

kubectl get all -n cxk

2.发布——kubectl expose

将资源暴露为新的 Service

kubectl expose --help
#查看发布帮助

2.1Service的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 

CNAME:别名记录,多个别名记录在一台主机上,用于防止外部攻击,相当于Web服务的防火墙

  • headless clusterIP  无头模式   名称

2.2Port——Kubernetes集群中的Port

  • Port:是 k8s 集群内部访问service的端口,即通过 ClusterIP: Port 可以从 Pod 所在的 Node 上访问到 Service
  • NodePort:是外部访问 K8s 集群中 Service 的端口,通过 NodeIP: NodePort 可以从外部访问到某个 Service。
  • TargetPort:是 Pod 的端口,从 Port 或 NodePort 来的流量经过 Kube-Proxy 反向代理负载均衡转发到后端 Pod 的 TargetPort 上,最后进入容器。
  • ContainerPort:是 Pod 内部容器的端口,TargetPort 映射到 ContainerPort。

Port和NodePort都是属于四层;整体数据流向为TargetPort接收来自于Port和NodePort传来的情求,再转发给ContainerPort,TargetPort可以理解为Port的防火墙(Pod的防火墙)。

如果想修改Pod端口,要使用TargetPort

2.3测试Service暴露在Cluster集群使其可以访问

kubectl expose deployment nginx-cxk --port=8080 --target-port=80 -n cxk
#创建一个自主式Pod 可以通过8080端口转发至容器的80端口
service/nginx-cxk exposed

kubectl get svc -n cxk
NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
nginx-cxk   ClusterIP   10.108.238.71   <none>        8080/TCP   9s


curl 10.108.238.71:8080

这里可以看出基本是负载均衡轮询调度算法

2.4测试Port暴露在外部流量中可以使其可以访问

kubectl expose deployment nginx-cxk --port=80 --target-port=80 --type=NodePort -n cxk
service/nginx-cxk exposed


kubectl get svc -n cxk
NAME        TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
nginx-cxk   NodePort   10.99.40.137   <none>        80:31119/TCP   7s

这里是算法的问题,按照负载均衡的分流算法  

2.6Endpoint——端点

kubectl get endpoints -n cxk
NAME        ENDPOINTS                                      AGE
nginx-cxk   10.244.1.13:80,10.244.1.14:80,10.244.1.15:80   9m5s

kubectl get pod -n cxk
NAME                         READY   STATUS    RESTARTS   AGE
nginx-cxk-84b96ddc7b-2qbzx   1/1     Running   0          83m
nginx-cxk-84b96ddc7b-fl6xl   1/1     Running   0          83m
nginx-cxk-84b96ddc7b-rcmtn   1/1     Running   0          83m

kubectl delete pod nginx-cxk-84b96ddc7b-2qbzx -n cxk
pod "nginx-cxk-84b96ddc7b-2qbzx" deleted

kubectl get pod -n cxk
NAME                         READY   STATUS    RESTARTS   AGE
nginx-cxk-84b96ddc7b-fl6xl   1/1     Running   0          84m
nginx-cxk-84b96ddc7b-rcmtn   1/1     Running   0          84m
nginx-cxk-84b96ddc7b-tdj5w   1/1     Running   0          37s

kubectl get endpoints -n cxk
NAME        ENDPOINTS                                      AGE
nginx-cxk   10.244.1.13:80,10.244.1.15:80,10.244.1.16:80   12m
#kubectl create deployment创建的自主式Pod在删除后会自动新建一个新的Pod,那么Endpoint会自动更新其IP地址

#查看关联后端的节点
kubectl get endpoints -n cxk
NAME        ENDPOINTS                                      AGE
nginx-cxk   10.244.1.13:80,10.244.1.15:80,10.244.1.16:80   15m

#查看 service 的描述信息
kubectl describe svc nginx

#查看负载均衡端口
yum install ipvsadm -y
ipvsadm -Ln

#外部访问的IP和端口
TCP  192.168.241.11:31119 rr
  -> 10.244.1.13:80               Masq    1      0          0         
  -> 10.244.1.15:80               Masq    1      0          0         
  -> 10.244.1.16:80               Masq    1      0          0         

#pod集群组内部访问的IP和端口
TCP  10.99.40.137:80 rr
  -> 10.244.1.13:80               Masq    1      0          0         
  -> 10.244.1.15:80               Masq    1      0          0         
  -> 10.244.1.16:80               Masq    1      0          0         

3.更新——kubectl set

更改现有应用资源一些信息

#获取修改模板
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
kubectl get pod -n cxk -owide

curl -I 10.244.1.13

kubectl set image deployment nginx-cxk nginx=nginx:1.15 -n cxk

kubectl get svc,pod -n cxk -owide

kubectl get pod -n cxk -owide

kubectl get pod -n cxk -owide

curl -I 10.244.1.17

25%规则,更新的测试无问题之后再删除旧版本,不会重新启动,只会先创建后删除

#处于动态监听 pod 状态,由于使用的是滚动更新方式,所以会先生成一个新的pod,然后删除一个旧的pod,往后依次类推
kubectl get pods -w

4.回滚——kubectl rollout

对资源进行回滚管理

kubectl rollout --help
#查看历史版本
kubectl rollout history deployment/nginx 

#执行回滚到上一个版本
kubectl rollout undo deployment/nginx

#执行回滚到指定版本
kubectl rollout undo deployment/nginx --to-revision=1

#检查回滚状态
kubectl rollout status deployment/nginx

5.删除——kubectl delete

#删除副本控制器
kubectl delete deployment/nginx

#删除service
kubectl delete svc/nginx-service

四、主要发布过程

1.蓝绿发布

蓝绿发布需要对服务的新版本进行冗余部署,一般新版本的机器规格和数量与旧版本保持一致,相当于该服务有两套完全相同的部署环境,只不过此时只有旧版本在对外提供服务,新版本作为热备。当服务进行版本升级时,我们只需将流量全部切换到新版本即可,旧版本作为热备。由于冗余部署的缘故,所以不必担心新版本的资源不够。如果新版本上线后出现严重的程序 BUG,那么我们只需将流量全部切回至旧版本,大大缩短故障恢复的时间。待新版本完成 BUG 修复并重新部署之后,再将旧版本的流量切换到新版本。

优点:用户无感知,业务稳定;缺点:资源消耗大,成本比较高 

2.滚动发布

按照比例分批进行滚动更新,K8S的默认更新机制就是滚动发布,无需创建一定比例的Pod,先创建再删除一定旧的Pod

3.金丝雀发布(Canary Release)灰度发布

Deployment控制器支持自定义控制更新过程中的滚动节奏,如“暂停(pause)”或“继续(resume)”更新操作。比如等待第一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布。

先安排一部分Pod,然后暂停更新,安排一小部分用户流量去访问更新的Pod来进行测试,当测试没问题后再扩大比例更新,直至全部更新完成为止

我们新建的Pod的版本为1.14.2的版本

将Pod资源的端口暴露在Service环境中,使得ClusterIP可以访问我们的Pod资源,此时访问的版本也是1.14.2版本

kubectl set image deployment/nginx nginx=nginx:1.15 && kubectl rollout pause deployment/nginx
#更新deployment/nginx nginx镜像变更为1.15版本  且 暂停deployment

监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为使用了pause暂停命令

我们如果访问ServiceIP的话,会将我们调度到新的服务器上,但是这样其实是不允许的,我们要将旧版本的Nginx服务和新版本的Nginx服务进行分离

kubectl expose deployment nginx --name=new-nginx --port=80 --target-port=80 --type=NodePort

我们可以看到新版本的Nginx服务和旧版本的Nginx服务的标签不同,可以根据标签进行分离新旧版本

找到新服务的标签,将其标签写入yaml文件中,使其生效

vim new-nginx.yaml 

将selector标签选择器的内容修改为新版本的服务的标签

先删除原来的Sevice,再使用new-nginx.yaml文件生成新的Sevice,那就是此Sevice中只有新版本的一个Pod,做到了新版本的分离。

但是我们访问旧的集群的时候还是会调度到新的版本中,那么我们如何再将旧集群中的新版本进行剔除。

我们还是和新版本一样的建立方法,将标签选择器的内容指定为旧版本的标签

我们发现至此,旧版本集群中不会调度到新版本,新版本也不会调度到旧版本,新旧版本就此完成隔离,这个就是金丝雀发布!

kubectl rollout resume deployment nginx 

 我们继续将所有的Pod资源完成更新版本升级

五、声明式资源管理方法

  • 适合于对资源的修改操作
  • 声明式资源管理方法依赖于资源配置清单文件对资源进行管理

资源配置清单文件有两种格式:yaml(人性化,易读),json(易于api接口解析)

  • 对资源的管理,是通过事先定义在统一资源配置清单内,再通过陈述式命令应用到k8s集群里
  • 语法格式:kubectl create/apply/delete -f xxxx.yaml

create创建的是一次性的;apply可用于创建也可用于更新资源;delete -f yaml通过yaml格式文件对创建的资源进行统一删除

#查看资源配置清单
kubectl get deployment nginx -o yaml

#解释资源配置清单
kubectl explain deployment.metadata

#修改资源配置清单并应用


离线修改:
kubectl apply -f xxxx.yaml
#注意:当apply不生效时,先使用delete清除资源,再apply创建资源

在线修改:
直接使用 kubectl edit service nginx 在线编辑资源配置清单并保存退出即时生效(如port: 888)
PS:此修改方式不会对yaml文件内容修改
#删除资源配置清单
#陈述式删除:
kubectl delete service nginx

#声明式删除:
kubectl delete -f nginx-svc.yaml

六、总结

1.命令操作

命令含义
kubectl get (pod、service、namespace、all) -owide查看资源类型输出详细信息,也可以输出yaml、json格式
kubectl get --all-namespace 或 kubectl get -A查看所有的命名空间下的资源
kubectl create namespace <name>查看命名空间
kubectl delete namespace <name>删除命名空间
kubectl run <image:name> --image -n <namespace>创建自主式静态Pod
kubectl create deployment <image:name> --image -n <namespace>用于创建deployment控制器管理的Pod
kubectl delete pod <name> -n <namespace>删除Pod资源
kubectl scale --replicas=扩缩容
kubectl describe <resource> [-o wide|json|yaml] [-n namespace]查看pod/deployment 副本详细信息,根据信息查看pod故障

2.Port端口

Port:为Service在ClusterIP在网络中暴露端口

TargetPort:对容器映射在Pod上的端口

NodePort:可以通过K8S集群外部使用NodeIP+NodePort访问Service

ContainerPort:容器内部进程使用的端口

3.数据流向

  • Kubernetes内部:客户端----->ClusterIP:port----->Targetport----->Pod:IP----->Container:IP
  • Kubernetes外部:客户端----->NodeIP:Nodeport----->Targetport----->Pod:IP----->Container:IP

4.生命周期

  • 创建:kubectl create <资源类型> <资源名称> --image=<镜像名称> --port=端口 --replication
  • 发布:kubectl expose <资源类型> <资源名称> --port --targetport type=ClusterIP|NodePort
  • 更新:kubectl set image <资源类型> <资源名称> <容器名>-<镜像名> 标签版本
  • 回滚:kubectl rollout undo <资源类型> <资源名称>默认回滚到上一个版本
    • kubectl rollout undo <资源类型> <资源名称> --to-revision回滚到指定版本
    • kubectl rollout history|status <资源类型> <资源名称>查看历史信息
  • 删除:kubectl delete <资源类型> <资源名称>

5.声明式管理方法

当YAML配置文件发生改动后,使用Create创建资源如果想更新内容的话,需要先删除原有资源再进行通过YAML进行创建;如果使用Apply创建的资源想更新内容的话,可直接执行kubectl apply -f更新即可。

;