侧边栏壁纸
博主头像
孔子说JAVA博主等级

成功只是一只沦落在鸡窝里的鹰,成功永远属于自信且有毅力的人!

  • 累计撰写 292 篇文章
  • 累计创建 132 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

k8s入门教程-3:Kubectl 命令行工具

孔子说JAVA
2022-04-06 / 0 评论 / 0 点赞 / 131 阅读 / 14,331 字 / 正在检测是否收录...

kubectl是管理Kubernetes集群的命令行工具(CLI),是Kubernetes用户必备的管理工具。 kubectl在 $HOME/.kube 目录中查找一个名为config的配置文件。 你可以通过设置 KUBECONFIG 环境变量或设置 --kubeconfig 参数来指定其它 kubeconfig 文件。

1、kubectl语法

kubectl从终端窗口运行命令,语法如下所示:

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

其中 command、TYPE、NAME 和 flags 分别是:

  • command: 指定要对一个或多个资源执行的操作,例如 create、get、describe、delete。
  • TYPE: 指定资源类型。资源类型不区分大小写, 可以指定单数、复数或缩写形式。例如,以下命令输出相同的结果:
kubectl get pod pod1
kubectl get pods pod1
kubectl get po pod1
  • NAME: 指定资源的名称,名称也大小写敏感的。如果省略名称,则会显示所有的资源 kubectl get pods ,在对多个资源执行操作时,你可以按类型和名称指定每个资源,或指定一个或多个文件:
  1. 要按类型和名称指定资源:
  • 要对所有类型相同的资源进行分组,请执行以下操作:TYPE1 name1 name2 name<#>。例:kubectl get pod example-pod1 example-pod2
  • 分别指定多个资源类型:TYPE1/name1 TYPE1/name2 TYPE2/name3 TYPE<#>/name<#>。例:kubectl get pod/example-pod1 replicationcontroller/example-rc1
  1. 用一个或多个文件指定资源:-f file1 -f file2 -f file<#>
  • 使用 YAML 而不是 JSON 因为 YAML 更容易使用,特别是用于配置文件时。 例子:kubectl get -f ./pod.yaml
  • **flags: ** 指定可选的参数。例如,可以使用 -s-server 参数指定 Kubernetes API 服务器的地址和端口。

注意:

  • 从命令行指定的参数会覆盖默认值和任何相应的环境变量。
  • 如果你需要帮助,从终端窗口运行 kubectl help
  • kubectl -h 查看子命令列表
  • kubectl options 查看全局选项
  • kubectl <command> --help 查看子命令的帮助
  • kubectl [command] [PARAMS] -o=<format> 设置输出格式(如 json、yaml、jsonpath 等)
  • kubectl explain [RESOURCE] 查看资源的定义

2、K8s配置集群以及认证方式

使用 kubectl 的第一步是配置 Kubernetes 集群以及认证方式,包括

  1. cluster 信息:Kubernetes server 地址
  2. 用户信息:用户名、密码或密钥
  3. Context:cluster、用户信息以及 Namespace 的组合
kubectl config set-credentials myself --username=admin --password=secret
kubectl config set-cluster local-server --server=http://localhost:8080
kubectl config set-context default-context --cluster=local-server --user=myself --namespace=default
kubectl config use-context default-context
kubectl config view

3、kubectl常用命令格式

  1. 创建: kubectl run <name> --image=<image> 或者 kubectl create -f manifest.yaml
  2. 查询: kubectl get <resource>
  3. 更新: kubectl set 或者 kubectl patch
  4. 删除: kubectl delete <resource> <name> 或者 kubectl delete -f manifest.yaml
  5. 查询 Pod IP: kubectl get pod <pod-name> -o jsonpath='{.status.podIP}'
  6. 容器内执行命令: kubectl exec -ti <pod-name> sh
  7. 容器日志: kubectl logs [-f] <pod-name>
  8. 导出服务: kubectl expose deploy <name> --port=80
  9. Base64 解码: kubectl get secret SECRET -o go-template='{{ .data.KEY | base64decode }}'

注意:

  • kubectl run 仅支持 Pod、Replication Controller、Deployment、Job 和 CronJob 等几种资源。具体的资源类型是由参数决定的,默认为 Deployment:
创建的资源类型 参数
Pod –restart=Never
Replication Controller –generator=run/v1
Deployment –restart=Always
Job –restart=OnFailure
CronJob --schedule=<cron>
  • 1.用minikube对k8s集群的管理性操作
# 用minikube对k8s集群的管理性操作:
# 用类似如下命令设置minikube的各种参数
minikube config set memory 4096 # minikube默认情况下仅分配2GB的RAM,需扩内存可使用此命令
# 访问minikube的dashboard 
minikube dashboard # 访问minikube集群中运行的Kubernetes仪表

# 使用minikube可在浏览器中轻松打开此开放节点
minikube service hello-minikube

# minikube默认启动一个单节点k8s集群,下面命令可以启动另外一个k8s集群,当然,也是单节点的。
minikube start -p cluster2 # 启动第二个本地集群(注意:裸机启动(本次实验环境)不适用)

# 停止本地集群
minikube stop 

# 删除本地集群
minikube delete 

  • 2.kubectl客户端的各种操作,它是对单个集群的访问性操作
kubectl run hello-minikube --image=k8s.gcr.io/echoserver:1.4 --port=8080 # 启动服务器
kubectl get po -A # 查看pod状态
kubectl expose deployment hello-minikube --type=NodePort # 将服务公开为NodePort

# 查看集群信息
kubectl cluster-info

# 查看节点信息
kubectl get node

# 查看内部服务组件
kubectl get pod -A

#应用一个object配置, 至于部署什么,就看yaml配置文件定义了什么, 这里部署一个pod
kubectl apply -f ./pod.yaml
 
#kubectl get子命令用户展示k8s资源,k8s资源就是我们通过object部署的东西。
#展示所有pod
kubectl get pods
 
#展示kube-system名字空间下的所有pod, 默认kubectl命令只是操作default默认名字空间,可以通过-n参数指定名字空间
kubectl get pods -n kube-system
 
#展示所有deployment
kubectl get deploy
 
#展示所有service(服务)
kubectl get svc
 
#展示所有ingress
kubectl get ingress
 
#以yaml格式,展示具体的ingress资源的配置, 展示任意资源具体的yaml配置命令格式:kubectl get 资源类型 资源名字 -o yaml
kubectl get ingress 资源名字 -o yaml
 
#删除指定的资源,具体删除内容由配置文件object定义
kubectl delete -f ./pod.yaml
 
#在容器中执行命令格式
kubectl exec 容器id  命令
 
#在admin-app-5f84f57f7-vthlf容器中,执行ls /alidata/www 命令
kubectl exec admin-app-5f84f57f7-vthlf ls /alidata/www
 
#在admin-app-5f84f57f7-vthlf容器中,打开shell交互窗口, 需要加上-it参数
kubectl exec -it admin-app-5f84f57f7-vthlf bash

4、kubectl命令详解

通过在.bashrc或者.zshrc添加以下配置,给kubectl创建一个简便的别称k,以简化操作(懒)。

alias k="kubectl"
complete -F __start_kubectl k

4.1 帮助命令help

如果对某些生疏的命令,通过执行 k <command> --help 获取其基本帮助(这里的k代表kubectl)。例如 k label --help

  • 帮助文档会有命令的详细解释和示例可供选择。
  • 另外,尽量减少命令式命令的使用。比如 create, expose, scale, set image, rollout等。最好以声明方式处理Kubernetes配置。

4.2 获取基本信息get

k get命令可以获取任何 Kubernetes API 资源(这里的k代表kubectl)。

k get pods

k get nodes

k get services

# 可以用sort进行排序

k get pods --sort-by=.status.startTime

# 可以使用标签过滤:

k get pods -l app=kombucha-service

# 用wathc观察服务

k get pods -l app=kombucha-service --watch

# 浏览事件

k get events

4.3 资源和缩写api-resources

命令中通常支持缩写。要查看可以获得哪些资源及其缩写,使用 api-resources 命令。 这对于自定义资源也很有帮助。

k api-resources

# 如果不确定某些资源是什么,可以使用 k explain。

k explain deployment

4.4 获取日志logs(用于故障排除)

kubectl logs 用于显示 pod 运行中,容器内程序输出到标准输出的内容。跟 docker 的 logs 命令类似。

# Return snapshot logs from pod nginx with only one container
kubectl logs nginx

# Return snapshot of previous terminated ruby container logs from pod web-1
kubectl logs -p -c ruby web-1

# 用logs获取日志,-f实时刷新日志

k logs -f <pod-name> -c <container-name>

# 也支持 `--tail=n`,获取最后n行日志

k logs <pod-name> -c <container-name> --tail=50

# 支持,一次打印多个pod日志

k logs -l foo=bar

:kubectl 只可以查看单个容器的日志,如果想要同时查看多个 Pod 的日志,可以使用 stern。比如: stern --all-namespaces -l run=nginx。

4.5 连接到一个正在运行的容器

kubectl attach 用于连接到一个正在运行的容器。跟 docker 的 attach 命令类似。

Options:

  • -c, --container=‘’: Container name. If omitted, the first container in the pod will be chosen
  • -i, --stdin=false: Pass stdin to the container
  • -t, --tty=false: Stdin is a TTY
# Get output from running pod 123456-7890, using the first container by default
kubectl attach 123456-7890

# Get output from ruby-container from pod 123456-7890
kubectl attach 123456-7890 -c ruby-container

# Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-7890
# and sends stdout/stderr from 'bash' back to the client
kubectl attach 123456-7890 -c ruby-container -i -t

4.6 在容器内部执行命令

kubectl exec 用于在一个正在运行的容器执行命令。跟 docker 的 exec 命令类似。

多容器 Pod 可通过 kubectl.kubernetes.io/default-container annotation 配置 kubectl 命令的默认容器。
Options:

  • -c, --container=‘’: Container name. If omitted, the first container in the pod will be chosen
  • -p, --pod=‘’: Pod name
  • -i, --stdin=false: Pass stdin to the container
  • -t, --tty=false: Stdin is a TT
# Get output from running 'date' from pod 123456-7890, using the first container by default
kubectl exec 123456-7890 date

# Get output from running 'date' in ruby-container from pod 123456-7890
kubectl exec 123456-7890 -c ruby-container date

# Switch to raw terminal mode, sends stdin to 'bash' in ruby-container from pod 123456-7890
# and sends stdout/stderr from 'bash' back to the client
kubectl exec 123456-7890 -c ruby-container -i -t -- bash -il

4.7 文件拷贝

kubectl cp 支持从容器中拷贝,或者拷贝文件到容器中

Options:

  • -c, --container='': Container name. If omitted, the first container in the pod will be chosen
  # Copy /tmp/foo_dir local directory to /tmp/bar_dir in a remote pod in the default namespace
  kubectl cp /tmp/foo_dir <some-pod>:/tmp/bar_dir

  # Copy /tmp/foo local file to /tmp/bar in a remote pod in a specific container
  kubectl cp /tmp/foo <some-pod>:/tmp/bar -c <specific-container>

  # Copy /tmp/foo local file to /tmp/bar in a remote pod in namespace <some-namespace>
  kubectl cp /tmp/foo <some-namespace>/<some-pod>:/tmp/bar

  # Copy /tmp/foo from a remote pod to /tmp/bar locally
  kubectl cp <some-namespace>/<some-pod>:/tmp/foo /tmp/bar

注意:文件拷贝依赖于 tar 命令,所以容器中需要能够执行 tar 命令

4.8 API Server 代理

kubectl proxy 命令提供了一个 Kubernetes API 服务的 HTTP 代理。

$ kubectl proxy --port=8080
Starting to serve on 127.0.0.1:8080

可以通过代理地址 http://localhost:8080/api/ 来直接访问 Kubernetes API,比如查询 Pod 列表

curl http://localhost:8080/api/v1/namespaces/default/pods

注意,如果通过 --address 指定了非 localhost 的地址,则访问 8080 端口时会报未授权的错误,可以设置 --accept-hosts 来避免这个问题( 不推荐生产环境这么设置 ):

kubectl proxy --address='0.0.0.0' --port=8080 --accept-hosts='^*$'

4.9 端口转发

kubectl port-forward 用于将本地端口转发到指定的 Pod。

# Listen on ports 5000 and 6000 locally, forwarding data to/from ports 5000 and 6000 in the pod
kubectl port-forward mypod 5000 6000

# Listen on port 8888 locally, forwarding to 5000 in the pod
kubectl port-forward mypod 8888:5000

# Listen on a random port locally, forwarding to 5000 in the pod
kubectl port-forward mypod :5000

# Listen on a random port locally, forwarding to 5000 in the pod
kubectl port-forward mypod 0:5000
# 也可以将本地端口转发到服务、复制控制器或者部署的端口。

# Forward to deployment
kubectl port-forward deployment/redis-master 6379:6379

# Forward to replicaSet
kubectl port-forward rs/redis-master 6379:6379

# Forward to service
kubectl port-forward svc/redis-master 6379:6379

4.10 kubectl drain

kubectl drain NODE [Options]

  • 它会删除该 NODE 上由 ReplicationController, ReplicaSet, DaemonSet, StatefulSet or Job 创建的 Pod
  • 不删除 mirror pods(因为不可通过 API 删除 mirror pods)
  • 如果还有其它类型的 Pod(比如不通过 RC 而直接通过 kubectl create 的 Pod)并且没有 --force 选项,该命令会直接失败
  • 如果命令中增加了 --force 选项,则会强制删除这些不是通过 ReplicationController, Job 或者 DaemonSet 创建的 Pod
  1. 有的时候不需要 evict pod,只需要标记 Node 不可调用,可以用 kubectl cordon 命令。
  2. 恢复的话只需要运行 kubectl uncordon NODE 将 NODE 重新改成可调度状态。

4.11 权限检查

kubectl auth 提供了两个子命令用于检查用户的鉴权情况:

1. kubectl auth can-i 检查用户是否有权限进行某个操作,比如

# Check to see if I can create pods in any namespace
kubectl auth can-i create pods --all-namespaces

# Check to see if I can list deployments in my current namespace
kubectl auth can-i list deployments.extensions

# Check to see if I can do everything in my current namespace ("*" means all)
kubectl auth can-i '*' '*'

# Check to see if I can get the job named "bar" in namespace "foo"
kubectl auth can-i list jobs.batch/bar -n foo

2. kubectl auth reconcile 自动修复有问题的 RBAC 策略,如

# Reconcile rbac resources from a file
kubectl auth reconcile -f my-rbac-rules.yaml

4.12 模拟其他用户

kubectl 支持模拟其他用户或者组来进行集群管理操作,比如

kubectl drain mynode --as=superman --as-group=system:masters

# 这实际上就是在请求 Kubernetes API 时添加了如下的 HTTP HEADER:

Impersonate-User: superman
Impersonate-Group: system:masters

4.13 获取pod详细信息(用于故障排除)

# 可以帮助我们找出pod崩溃的原因。比如,正在尝试将不存在的配置映射注入到其环境

k describe pod <pod-name>

4.14 调试 DNS 和服务

# 使用DNS调试应用镜像(dnsutils)运行一个pod

k run dnsutils --image=gcr.io/kubernetes-e2e-test-images/dnsutils:1.3 -- sleep 3600

# 然后在该pod运行DNS命令

k exec -it dnsutils -- nslookup kubernetes.default

Server: 10.11.0.10
Address: 10.11.0.10#53
Name: kubernetes.default.svc.cluster.local
Address: 10.11.0.1

如果想知道是否正确创建了服务,还可以查看 k get endpoints,并仔细检查标签选择器。 例如

k get svc alex-echo -o wide

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR

alex-echo ClusterIP 10.11.101.85 <none> 80/TCP 161d app=alex-echo-server

k get pods -l app=alex-echo-server

NAME READY STATUS RESTARTS AGE

alex-echo-server-7c47c5698c-zfhwg 1/1 Running 0 20h

4.15 查询Pod 正运行镜像

k get pod dnsutils -o jsonpath='{ .spec.containers[*].image }'

gcr.io/kubernetes-e2e-test-images/dnsutils:1.3

4.16 解码和复制秘钥

# 解码一个秘钥,并复制

k get secrets <secret-name> -o jsonpath='{ .data.<key> }' | base64 --decode | pbcopy

4.17 监控指标

k top pods --all-namespaces --sort-by=memory

k top pods --all-namespaces --sort-by=cpu

k top nodes --sort-by=memory

k top nodes --sort-by=cpu

4.18 在Pod或节点上执行命令

k exec -it nginx -- echo 'hello'

hello

# 启动一个shell进程

k exec -it nginx -- /bin/bash

root@nginx:/# echo hi!

hi!

# 在一个特定节点启用一个shell进程,使用kubectl-node-shell (github/kvaps/kubectl-node-shell)

k node-shell <node> -- echo 123

# 在 pod 或节点上启动 shell 会话后,可以使用curl, nslookup, ping 和 env等。

4.19 查询Pod的IP

k get pod nginx -o=jsonpath='{ .status.podIPs[0].ip }'

4.20 验证Kubernetes资源

# 对要给写好的 YAML进行验证,可以用Helm chart语法。

helm template . | kubeval -

# 可以用 kubeval校验yaml配置文件:

kubeval pod.yaml

4.21 集群扩容/收缩

k scale --replicas=n statefulset/<stateful-set-name>

k scale --replicas=n deployment/<deployment-name>

4.22 重新启动/清理

如果 Pod 不属于任何发布,删除后就不会再出现了。删除一个发布下的pods是不安全的,会自动重启。

k delete pod <deployment-pod-a>

# 删除有状态的pod也类似:

k delete pod <stateful-set-pod-0>

# 创建一个CronJob触发器

k create job --from=cronjob/hello-world hello-world-now

# 要清理测试时候使用的nginx pods,可以使用

kubectl get pods -o custom-columns='NAME:metadata.name' --no-headers | grep nginx | xargs nginx-alex nginx-bobby-cox nginx-freddie-freeman nginx-ozzie-albies nginx-ronald-acuna

# 可以将其作为一个子命令使用

k delete pod $(kubectl get pods -o custom-columns='NAME:metadata.name' --no-headers | grep nginx | xargs) --dry-run=client

pod "nginx-alex" deleted (dry run)

pod "nginx-bobby-cox" deleted (dry run)

pod "nginx-freddie-freeman" deleted (dry run)

pod "nginx-ozzie-albies" deleted (dry run)

pod "nginx-ronald-acuna" deleted (dry run)

4.23 插件

kubectl 插件机制基于krew。可以通过如下方式安装插件:

kubectl krew install ctxkubectl krew install ns

# 使用kubectx 插件,

k config use-context <context-name>
# 就可以简写为:
k ctx <context-name>

#其他值得推荐的插件:kubens 与 kubectx相同,但用于命名空间。

ksniff ——使用 tcpdump 和 Wireshark 在任何 pod上启动远程数据抓包。可以用于网络调试等。

kubectl-node-shell ——在 Kubernetes 节点上运行 shell。请注意,有很多特权执行不支持,必须使用插件来运行特权容器。

kubecolor——对k输出进行美化,只需在.zshrc添加alias k=kubecolor即可。

4.24 查看事件(events)

# 查看所有事件
kubectl get events --all-namespaces

# 查看名为nginx对象的事件
kubectl get events --field-selector involvedObject.name=nginx,involvedObject.namespace=default

# 查看名为nginx的服务事件
kubectl get events --field-selector involvedObject.name=nginx,involvedObject.namespace=default,involvedObject.kind=Service

# 查看Pod的事件
kubectl get events --field-selector involvedObject.name=nginx-85cb5867f-bs7pn,involvedObject.kind=Pod

# 按时间对events排序
kubectl get events --sort-by=.metadata.creationTimestamp

# 自定义events输出格式
kubectl get events  --sort-by='.metadata.creationTimestamp'  -o 'go-template={{range .items}}{{.involvedObject.name}}{{"\t"}}{{.involvedObject.kind}}{{"\t"}}{{.message}}{{"\t"}}{{.reason}}{{"\t"}}{{.type}}{{"\t"}}{{.firstTimestamp}}{{"\n"}}{{end}}'

4.25 原始 URI

kubectl 也可以用来直接访问原始 URI,比如要访问 Metrics API 可以

kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes
kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes/<node-name>
kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/<namespace-name>/pods/<pod-name>

5、Docker 与 kubectl命令比较

如果您熟悉 Docker 命令行工具,则使用 kubectl 非常简单。但是,Docker 命令和 kubectl 命令之间有一些区别。以下显示了 Docker 子命令,并描述了等效的 kubectl 命令。

  • Docker 命令和 Kubectl 命令有很多相似的地方,Docker 操作容器,Kubectl 操作 Pod(容器的集合)等。
docker命令 kubernetes命令
运行容器 docker run kubectl run
查看已运行的容器 docker ps kubectl ps
连接到一个正在运行的容器 docker attach kubectl attach
交互式进入容器 docker exec kubectl exec
打印日志 docker logs kubectl logs
停止和删除容器 docker stop & docker rm kubectl delete
查看版本 docker version kubectl version
查看环境信息 docker info kubectl cluster-info

5.1 运行容器

  • docker:
docker run -d --restart=always -e DOMAIN=cluster --name nginx-app -p 80:80 nginx
  • kubectl:
kubectl run --image=nginx nginx-app --port=80 -- env="DOMAIN=cluster"
kubectl expose deployment nginx-app --port=80 --name=nginx-http

注意: kubectl run 会创建一个 Deployment并且默认会在后台运行,以上面的代码为例它的名称为 nginx-app。默认情况 Deployment 并不会将端口暴露出去,所以我们还需要使用 kubectl expose 暴露端口以供访问,此时还会创建一个同名的 Service

5.2 查看已运行的容器

  • docker:
docker ps

docker ps|grep 关键字
  • kubectl:
kubetcl get pods -n 项目名|grep 关键字

kubectl get pods
kubectl get deployment
kubectl get service

5.3 交互式进入容器

  • docker:
docker exec -it <容器 ID/NAME> /bin/bash
  • kubectl:
kubectl exec -it <容器名> -- /bin/bash -n 项目名

5.3 查看版本

  • docker:
docker verison
  • kubectl:
kubectl version

5.4 打印日志

  • docker:
docker logs -f <容器 ID/NAME>
  • kubectl:
kubectl logs -f <容器名>

5.5 停止和删除容器

  • docker:
docker stop <容器 ID/NAME>
docker rm <容器 ID/NAME>
  • kubectl:
kubectl delete deployment <Deployment 名称>
kubectl delete service <Service 名称>
# 或
kubectl delete rc <rc 名称>

注意: 不要直接删除 Pod,使用 kubectl 请删除拥有该 Pod 的 Deployment。如果直接删除 Pod,则 Deployment 将会重新创建该 Pod。

5.6 查看环境信息

  • docker:
docker info
  • kubectl:
kubectl cluster-info
0

评论区