侧边栏壁纸
博主头像
问道

问道的小花园,总能给你带来惊喜

  • 累计撰写 68 篇文章
  • 累计创建 35 个标签
  • 累计收到 6 条评论

kubernetes实用操作:kubectl命令行工具使用详解

问道
2022-09-28 / 0 评论 / 0 点赞 / 999 阅读 / 13,031 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-11-01,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

kubectl作为客户端CLI工具,可以让用户通过命令行对Kubernetes集群进行操作。本节对kubectl的子命令和用法进行详细说明。

kubectl用法概述

kubectl [command] [TYPE] [NAME] [flags]

其中,command、TYPE、NAME、flags的含义如下。

(1)command:子命令,用于操作资源对象,例如create、get、describe、delete等。

(2)TYPE:资源对象的类型,区分大小写,能以单数、复数或者简写形式表示。例如以下3种TYPE是等价的。

(3)NAME:资源对象的名称,区分大小写。如果不指定名称,系统则将返回属于TYPE的全部对象的列表,例如运行kubectl get pods命令后将返回所有Pod的列表。

(4)flags:kubectl子命令的可选参数,例如使用-s或--server设置API Server的URL地址,而不使用默认值。

kubectl配置命令补全

[root@master halo-app]# yum install -y bash-completion
已加载插件:fastestmirror
Loading mirror speeds from cached hostfile

[root@master halo-app]# source /usr/share/bash-completion/bash_completion
[root@master halo-app]# source <(kubectl completion bash)
[root@master halo-app]# echo "source <(kubectl completion bash)" >> ~/.bashrc 
[root@master halo-app]# 

kubectl可操作的资源对象详解

kubectl格式化输出

命令简介

基本命令 (初级):
  create         从文件或标准输入创建资源
  expose         获取一个复制控制器, 服务, 部署或者暴露一个 POD 将其作为新的 Kubernetes 服务公开
  run            创建并运行特定的镜像, 创建使用 deployment 或 job 管理的容器
  set            设置对象的特定功能, 例如发布, 每次去set 不用的image tag

基本命令 (中级):
  explain        文档或者资源, 可以用来查看资源清单写法
  get            显示一个或多个资源
  edit           编辑服务器上的资源
  delete         按文件名, 标准输入, 资源和名称或资源和标签选择器删除资源

部署命令:
  rollout        管理资源的部署
  scale          为部署设置新大小, ReplicaSet, Replication Controller, Job
  autoscale      自动扩展一个部署, ReplicaSet, 或者 ReplicationController

群集管理命令:
  certificate    修改证书资源
  cluster-info   显示群集信息
  top            显示资源(CPU / 内存/ 存储)使用情况, 需要安装metrics-server
  cordon         将节点标记为不可调度
  uncordon       将节点标记为可调度
  drain          设定 node 进入维护模式
  taint          更新一个或多个节点上的污点

故障排除和调试命令:
  describe       显示特定资源或资源组的详细信息
  logs           在容器中打印容器的日志
  attach         附加到正在运行的容器
  exec           在容器中执行命令
  port-forward   将一个或多个本地端口转发到 pod
  proxy          运行代理到 Kubernetes API 服务器
  cp             将文件和目录复制到容器, 和从容器复制, 跨容器复制文件
  auth           检查授权

高级命令:
  diff           针对将要应用的版本的 Diff 实时版本
  apply          通过文件名或标准输入将配置应用于资源
  patch          使用策略合并补丁更新资源的字段
  replace        用文件名或标准输入替换资源
  wait           实验阶段命令: 在一个或多个资源上等待特定条件, 定义一个触发器
  convert        在不同的API版本之间转换配置文件
  kustomize      从目录或远程 URL 构建 kustomization 目标

设置命令:
  label          更新资源上的标签
  annotate       更新资源上的注释
  completion     命令补全相关功能

其他命令:
  api-resources  在服务器上打印支持的API资源
  api-versions   以 "group/version" 的形式在服务器上打印支持的API版本
  config         修改 kubeconfig 文件
  plugin         提供与插件交互的实用程序
  version        打印客户端和服务器版本信息

kubectl 常用资源对象命令操作

使用 Kubernetes 的过程中,kubectl 工具可能是最常用的工具,所以当我们花费大量的时间在使用 kubectl 上面的时候,那么我们就非常有必要去了解下如何高效的使用它了。

namespace管理

#创建命名空间
[root@mayi-master ~]# kubectl create namespace app
#查看命名空间
[root@mayi-master ~]# kubectl get ns          #缩写
[root@mayi-master ~]# kubectl get namespace
#查看命名空间详细信息
[root@mayi-master ~]# kubectl get ns app -o yaml
#删除命令空间
[root@mayi-master ~]# kubectl delete namespace app

deployment管理

#查看命名空间下所有deployment
[root@mayi-master ~]# kubectl get deployment -o wide -n app
#查看指定deployment的详细信息
[root@mayi-master ~]# kubectl get deployment nginx -o yaml -n app
[root@mayi-master ~]# kubectl get deployment nginx -o json -n app
#编辑deployment【修改后,相应pod会滚动重启】
[root@mayi-master ~]# kubectl edit deployment nginx -n app
#查看deployment详细信息
[root@mayi-master ~]# kubectl describe deployment nginx -n app
#pod伸缩,增加pod
[root@mayi-master ~]# kubectl scale deployment/nginx --replicas=2 -n app
#pod伸缩,停止pod
[root@mayi-master ~]# kubectl scale deployment/nginx --replicas=0 -n app

pod管理

#查看pod资源使用
[root@mayi-master ~]# kubectl top pod -n app 
#查看命名空间下所有pod
[root@mayi-master ~]# kubectl get pod -o wide -n app
#查看指定service的详细信息
[root@mayi-master ~]# kubectl get pod nginx -o yaml -n app
#查看pod日志
[root@mayi-master ~]# kubectl logs nginx-6bfcb9b549-fs2zt -n app
[root@mayi-master ~]# kubectl logs -f nginx-6bfcb9b549-fs2zt -n app
#查看pod详细信息
[root@mayi-master ~]# kubectl describe pod  nginx-6bfcb9b549-fs2zt -n app
#进入到pod容器内
[root@mayi-master ~]# kubectl exec -it nginx-6bfcb9b549-fs2zt bash -n app
#将文件或文件夹拷入pod
[root@mayi-master ~]# kubectl cp /tmp/foo_dir nginx-6bfcb9b549-fs2zt:/tmp/bar_dir -n app
#将文件或文件夹从pod拷出
[root@mayi-master ~]# kubectl cp nginx-6bfcb9b549-fs2zt:/tmp/bar_dir /tmp/foo_dir -n app
#删除pod[重启]
[root@mayi-master ~]# kubectl delete pod  nginx-6bfcb9b549-fs2zt -n app
#Terminating状态的Pod删不掉,强制删除pod
[root@mayi-master ~]# kubectl delete pod  nginx-6bfcb9b549-fs2zt --grace-period=0 --force -n app
#批量删除不是Running的pod
[root@mayi-master ~]# kubectl get pod -o wide | grep -v Running | awk '{print $1}'|grep -v NAME|xargs kubectl -n mayi delete pod --grace-period=0 --force -n app

service管理

#查看命名空间下所有service
[root@mayi-master ~]# kubectl get svc  -o wide -n app
#查看指定service的详细信息
[root@mayi-master ~]# kubectl get service nginx  -o yaml -n app
#编辑service【修改后,service会立即重启】
[root@mayi-master ~]# kubectl edit svc nginx -n app

rollout版本回滚

#查看deployment所有历史版本
[root@mayi-master ~]# kubectl rollout history deployment/nginx -n app
#查看deployment历史版本的详细信息
[root@mayi-master ~]# kubectl rollout history deployment/nginx --revision=1 -n app
#回滚到上一个版本
[root@mayi-master ~]# kubectl rollout undo deployment nginx -n app
#指定版本回滚
[root@mayi-master ~]# kubectl rollout undo deployment/nginx --to-revision=3 -n app
[root@mayi-master ~]# kubectl rollout undo 资源类型 资源名称 --to-revision=版本号 -n app

kubectl set image deployment/frontend www=image:v2               # 滚动更新 "frontend" Deployment 的 "www" 容器镜像
kubectl rollout history deployment/frontend                      # 检查 Deployment 的历史记录,包括版本
kubectl rollout undo deployment/frontend                         # 回滚到上次部署版本
kubectl rollout undo deployment/frontend --to-revision=2         # 回滚到特定部署版本
kubectl rollout status -w deployment/frontend                    # 监视 "frontend" Deployment 的滚动升级状态直到完成
kubectl rollout restart deployment/frontend                      # 轮替重启 "frontend" Deployment

get和describe查看和查找资源

# get 命令的基本输出
kubectl get services                          # 列出当前命名空间下的所有 services
kubectl get pods --all-namespaces             # 列出所有命名空间下的全部的 Pods
kubectl get pods -o wide                      # 列出当前命名空间下的全部 Pods,并显示更详细的信息
kubectl get deployment my-dep                 # 列出某个特定的 Deployment
kubectl get pods                              # 列出当前命名空间下的全部 Pods
kubectl get pod my-pod -o yaml                # 获取一个 pod 的 YAML

# describe 命令的详细输出
kubectl describe nodes my-node
kubectl describe pods my-pod

# 列出当前名字空间下所有 Services,按名称排序
kubectl get services --sort-by=.metadata.name

# 列出 Pods,按重启次数排序
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

# 列举所有 PV 持久卷,按容量排序
kubectl get pv --sort-by=.spec.capacity.storage

# 获取包含 app=cassandra 标签的所有 Pods 的 version 标签
kubectl get pods --selector=app=cassandra -o \
  jsonpath='{.items[*].metadata.labels.version}'

# 检索带有 “.” 键值,例: 'ca.crt'
kubectl get configmap myconfig \
  -o jsonpath='{.data.ca\.crt}'

# 检索一个 base64 编码的值,其中的键名应该包含减号而不是下划线。
kubectl get secret my-secret --template='{{index .data "key-name-with-dashes"}}'

# 获取所有工作节点(使用选择器以排除标签名称为 'node-role.kubernetes.io/control-plane' 的结果)
kubectl get node --selector='!node-role.kubernetes.io/control-plane'

# 获取当前命名空间中正在运行的 Pods
kubectl get pods --field-selector=status.phase=Running

# 获取全部节点的 ExternalIP 地址
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'

# 列出属于某个特定 RC 的 Pods 的名称
# 在转换对于 jsonpath 过于复杂的场合,"jq" 命令很有用;可以在 https://stedolan.github.io/jq/ 找到它。
sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}
echo $(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name})

# 显示所有 Pods 的标签(或任何其他支持标签的 Kubernetes 对象)
kubectl get pods --show-labels

# 检查哪些节点处于就绪状态
JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}' \
 && kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"

# 不使用外部工具来输出解码后的 Secret
kubectl get secret my-secret -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"\n"}}{{$v|base64decode}}{{"\n\n"}}{{end}}'

# 列出被一个 Pod 使用的全部 Secret
kubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq

# 列举所有 Pods 中初始化容器的容器 ID(containerID)
# 可用于在清理已停止的容器时避免删除初始化容器
kubectl get pods --all-namespaces -o jsonpath='{range .items[*].status.initContainerStatuses[*]}{.containerID}{"\n"}{end}' | cut -d/ -f3

# 列出事件(Events),按时间戳排序
kubectl get events --sort-by=.metadata.creationTimestamp

# 比较当前的集群状态和假定某清单被应用之后的集群状态
kubectl diff -f ./my-manifest.yaml

# 生成一个句点分隔的树,其中包含为节点返回的所有键
# 在复杂的嵌套JSON结构中定位键时非常有用
kubectl get nodes -o json | jq -c 'paths|join(".")'

# 生成一个句点分隔的树,其中包含为pod等返回的所有键
kubectl get pods -o json | jq -c 'paths|join(".")'

# 假设你的 Pods 有默认的容器和默认的名字空间,并且支持 'env' 命令,可以使用以下脚本为所有 Pods 生成 ENV 变量。
# 该脚本也可用于在所有的 Pods 里运行任何受支持的命令,而不仅仅是 'env'。 
for pod in $(kubectl get po --output=jsonpath={.items..metadata.name}); do echo $pod && kubectl exec -it $pod -- env; done

# 获取一个 Deployment 的 status 子资源
kubectl get deployment nginx-deployment --subresource=status

patch部分更新资源

# 部分更新某节点
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'

# 更新容器的镜像;spec.containers[*].name 是必须的。因为它是一个合并性质的主键。
kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'

# 使用带位置数组的 JSON patch 更新容器的镜像
kubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'

# 使用带位置数组的 JSON patch 禁用某 Deployment 的 livenessProbe
kubectl patch deployment valid-deployment  --type json   -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]'

# 在带位置数组中添加元素
kubectl patch sa default --type='json' -p='[{"op": "add", "path": "/secrets/1", "value": {"name": "whatever" } }]'

# 通过修正 scale 子资源来更新 Deployment 的副本数
kubectl patch deployment nginx-deployment --subresource='scale' --type='merge' -p '{"spec":{"replicas":2}}'

scale对资源进行伸缩

kubectl scale --replicas=3 rs/foo                                 # 将名为 'foo' 的副本集伸缩到 3 副本
kubectl scale --replicas=3 -f foo.yaml                            # 将在 "foo.yaml" 中的特定资源伸缩到 3 个副本
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql  # 如果名为 mysql 的 Deployment 的副本当前是 2,那么将它伸缩到 3
kubectl scale --replicas=5 rc/foo rc/bar rc/baz                   # 伸缩多个副本控制器

delete删除资源

kubectl delete -f ./pod.json                                              # 删除在 pod.json 中指定的类型和名称的 Pod
kubectl delete pod,service baz foo                                        # 删除名称为 "baz" 和 "foo" 的 Pod 和服务
kubectl delete pods,services -l name=myLabel                              # 删除包含 name=myLabel 标签的 pods 和服务
kubectl -n my-ns delete pod,svc --all                                     # 删除在 my-ns 名字空间中全部的 Pods 和服务
# 删除所有与 pattern1 或 pattern2 awk 模式匹配的 Pods
kubectl get pods  -n mynamespace --no-headers=true | awk '/pattern1|pattern2/{print $1}' | xargs  kubectl delete -n mynamespace pod

logs打印容器日志

kubectl logs my-pod                                 # 获取 pod 日志(标准输出)
kubectl logs -l name=myLabel                        # 获取含 name=myLabel 标签的 Pods 的日志(标准输出)
kubectl logs my-pod --previous                      # 获取上个容器实例的 pod 日志(标准输出)
kubectl logs my-pod -c my-container                 # 获取 Pod 容器的日志(标准输出, 多容器场景)
kubectl logs -l name=myLabel -c my-container        # 获取含 name=myLabel 标签的 Pod 容器日志(标准输出, 多容器场景)
kubectl logs my-pod -c my-container --previous      # 获取 Pod 中某容器的上个实例的日志(标准输出, 多容器场景)
kubectl logs -f my-pod                              # 流式输出 Pod 的日志(标准输出)
kubectl logs -f my-pod -c my-container              # 流式输出 Pod 容器的日志(标准输出, 多容器场景)
kubectl logs -f -l name=myLabel --all-containers    # 流式输出含 name=myLabel 标签的 Pod 的所有日志(标准输出)

logs打印日志

kubectl logs my-pod                                 # 获取 pod 日志(标准输出)
kubectl logs -l name=myLabel                        # 获取含 name=myLabel 标签的 Pods 的日志(标准输出)
kubectl logs my-pod --previous                      # 获取上个容器实例的 pod 日志(标准输出)
kubectl logs my-pod -c my-container                 # 获取 Pod 容器的日志(标准输出, 多容器场景)
kubectl logs -l name=myLabel -c my-container        # 获取含 name=myLabel 标签的 Pod 容器日志(标准输出, 多容器场景)
kubectl logs my-pod -c my-container --previous      # 获取 Pod 中某容器的上个实例的日志(标准输出, 多容器场景)
kubectl logs -f my-pod                              # 流式输出 Pod 的日志(标准输出)
kubectl logs -f my-pod -c my-container              # 流式输出 Pod 容器的日志(标准输出, 多容器场景)
kubectl logs -f -l name=myLabel --all-containers    # 流式输出含 name=myLabel 标签的 Pod 的所有日志(标准输出)
kubectl logs deploy/my-deployment                         # 获取一个 Deployment 的 Pod 的日志(单容器例子)
kubectl logs deploy/my-deployment -c my-container         # 获取一个 Deployment 的 Pod 的日志(多容器例子)

exec在容器中执行命令

kubectl exec my-pod -- ls /                         # 在已有的 Pod 中运行命令(单容器场景)
kubectl exec --stdin --tty my-pod -- /bin/sh        # 使用交互 shell 访问正在运行的 Pod (一个容器场景)
kubectl exec my-pod -c my-container -- ls /         # 在已有的 Pod 中运行命令(多容器场景)

cp从容器中复制文件和目录

kubectl cp /tmp/foo_dir my-pod:/tmp/bar_dir            # 将 /tmp/foo_dir 本地目录复制到远程当前命名空间中 Pod 中的 /tmp/bar_dir
kubectl cp /tmp/foo my-pod:/tmp/bar -c my-container    # 将 /tmp/foo 本地文件复制到远程 Pod 中特定容器的 /tmp/bar 下
kubectl cp /tmp/foo my-namespace/my-pod:/tmp/bar       # 将 /tmp/foo 本地文件复制到远程 “my-namespace” 命名空间内指定 Pod 中的 /tmp/bar
kubectl cp my-namespace/my-pod:/tmp/foo /tmp/bar       # 将 /tmp/foo 从远程 Pod 复制到本地 /tmp/bar

cordon和drain节点亲和性处理

kubectl cordon my-node                                                # 标记 my-node 节点为不可调度
kubectl drain my-node                                                 # 对 my-node 节点进行清空操作,为节点维护做准备
kubectl uncordon my-node                                              # 标记 my-node 节点为可以调度

# 查看当前节点上存在的现有污点。
kubectl get nodes -o=custom-columns=NodeName:.metadata.name,TaintKey:.spec.taints[*].key,TaintValue:.spec.taints[*].value,TaintEffect:.spec.taints[*].effect

# 如果已存在具有指定键和效果的污点,则替换其值为指定值。
kubectl taint nodes foo dedicated=special-user:NoSchedule

实用操作

查看某个命名空间下所有资源

[root@master /]# kubectl api-resources -o name --verbs=list --namespaced | xargs -n 1 kubectl get --show-kind --ignore-not-found -n default
NAME                         DATA   AGE
configmap/kube-root-ca.crt   1      3d2h
NAME                   ENDPOINTS            AGE
endpoints/kubernetes   192.168.0.100:6443   3d2h
endpoints/nginx        <none>               47h
endpoints/tomcat       <none>               31h
NAME                         TYPE                                  DATA   AGE
secret/default-token-smncq   kubernetes.io/service-account-token   3      3d2h
NAME                     SECRETS   AGE
serviceaccount/default   1         3d2h
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          3d2h
service/nginx        NodePort    10.101.160.138   <none>        80:31595/TCP     47h
service/tomcat       NodePort    10.100.116.78    <none>        8080:31613/TCP   31h
NAME                                          ADDRESSTYPE   PORTS     ENDPOINTS       AGE
endpointslice.discovery.k8s.io/kubernetes     IPv4          6443      192.168.0.100   3d2h
endpointslice.discovery.k8s.io/nginx-rpb4g    IPv4          <unset>   <unset>         47h
endpointslice.discovery.k8s.io/tomcat-4qbpm   IPv4          <unset>   <unset>         31h

Node 资源占用高,如果快速定位是哪个服务占用高。

#获取占用cpu最高的PID
[root@mayi-master ~]# ps -aux | sort -k4nr|head -1|awk '{print $2}'
#根据pid获取容器ID
[root@mayi-master ~]# CID=$(docker inspect -f '{{.State.Pid}} {{.Id}}' $(docker ps -a -q)|grep $pid|awk '{print $2}'|cut -b 1-12)
#根据容器ID获取容器名称
[root@mayi-master ~]# docker inspect -f '{{index .Config.Labels "io.kubernetes.pod.name"}}' $CID
#根据容器ID获取相应的namespace
[root@mayi-master ~]# docker inspect -f '{{index .Config.Labels "io.kubernetes.pod.namespace"}}' $CID

#获取node主机上占用CPU最高的pod[以上命令合并]
[root@mayi-master ~]# inspect -f '{{index .Config.Labels "io.kubernetes.pod.name"}}' $(docker inspect -f '{{.State.Pid}} {{.Id}}' $(docker ps -a -q)|grep $(ps -aux | sort -k4nr|head -1|awk '{print $2}')|awk '{print $2}'|cut -b 1-12)
0

评论区