如果你的 PaaS 平台是基于容器云 Kubernetes 搭建,那么 kubectl  一定是你经常使用的工具之一,每当你花费大量时间使用某个工具时,你都非常有必要去了解它的工作原理和有效使用。

什么是 kubectl

从用户的角度来说 kubectl 是 Kubernetes 的驾驶舱,用户可以通过 kubectl 控制 kubernetes 允许的所有操作。从技术的角度来说,kubectl 是 kubernetes 的客户端。Kubernetes API 是一个 HTTP REST API。此 API 是真正的 Kubernetes 用户接口。通过 API 我们可以完全控制 Kubernetes。这意味着每个 Kubernetes 操作都作为 API 端点公开,并且可以通过对此端点的 HTTP 请求来执行。因此,kubectl 的主要工作是对Kubernetes API 执行 HTTP 请求。

执行一个 kubectl get pod 背后发生了什么

kubectl 充当 Kubernetes 客户端,直接跟 API Server 交互,通过添加 -v 可以查看执行日志,如下所示:其中 -v = 9 是 trace 最高跟踪级别。通过如下日志可以看出 kubectl 实际上是对 Kubernetes APIServer的 6443 端口通过 curl 执行了 GET请求。具体查看如下日志:

[root@k8s-master ~]# kubectl get pod -A -v=9
I0410 16:48:36.823772   18735 loader.go:359] Config loaded from file /root/.kube/config
I0410 16:48:36.827223   18735 round_trippers.go:419] curl -k -v -XGET  -H "Accept: application/json;as=Table;v=v1beta1;g=meta.k8s.io, application/json" -H "User-Agent: kubectl/v1.14.3 (linux/amd64) kubernetes/5e53fd6" 'https://12.18.7.23:6443/api/v1/pods?limit=500'
I0410 16:48:36.832563   18735 round_trippers.go:438] GET https://12.18.7.23:6443/api/v1/pods?limit=500 200 OK in 5 milliseconds
I0410 16:48:36.832579   18735 round_trippers.go:444] Response Headers:
I0410 16:48:36.832585   18735 round_trippers.go:447]     Content-Type: application/json
I0410 16:48:36.832590   18735 round_trippers.go:447]     Date: Fri, 10 Apr 2020 08:48:36 GMT
I0410 16:48:36.832654   18735 request.go:942] Response Body: {"kind":"Table","apiVersion":"meta.k8s.io/v1beta1","metadata":{"selfLink":"/api/v1/pods","resourceVersion":"60404"},"columnDefinitions":[{"name":"Name","type":"string","format":"name","description":"Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names","priority":0},{"name":"Ready","type":"string","format":"","description":"The aggregate readiness state of this pod for accepting traffic.","priority":0},{"name":"Status","type":"string","format":"","description":"The aggregate status of the containers in this pod.","priority":0},{"name":"Restarts","type":"integer","format":"","description":"The number of times the containers in this pod have been restarted.","priority":0},{"name":"Age","type":"string","format":"","description":"CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata","priority":0},{"name":"IP","type":"string","format":"","description":"IP address allocated to the pod. Routable at least within the cluster. Empty if not yet allocated.","priority":1},{"name":"Node","type":"string","format":"","description":"NodeName is a request to schedule this pod onto a specific node. If it is non-empty, the scheduler simply schedules this pod onto that node, assuming that it fits resource requirements.","priority":1},{"name":"Nominated Node","type":"string","format":"","description":"nominatedNodeName is set only when this pod preempts other pods on the node, but it cannot be scheduled right away as preemption victims receive their graceful termination periods. This field does not guarantee that the pod will be scheduled on this node. Scheduler may decide to place the pod elsewhere if other nodes become available sooner. Scheduler may also decide to give the resources on this node to a higher priority pod that is created after preemption. As a result, this field may be different than PodSpec.nodeName when the pod is scheduled.","priority":1},{"name":"Readiness Gates","type":"string","format":"","description":"If specified, all readiness gates will be evaluated for pod readiness. A pod is ready when all its containers are ready AND all conditions specified in the readiness gates have status equal to \"True\" More info: https://git.k8s.io/enhancements/keps/sig-network/0007-pod-ready%2B%2B.md","priority":1}],"rows":[{"cells":["coredns-fb8b8dccf-2hpgr","1/1","Running",3,"13h","10.244.0.7","k8s-master","\u003cnone\u003e","\u003cnone\u003e"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1beta1","metadata":{"name":"coredns-fb8b8dccf-2hpgr","generateName":"coredns-fb8b8dccf-","namespace":"kube-system","selfLink":"/api/v1/namespaces/kube-system/pods/coredns-fb8b8dccf-2hpgr","uid":"18503b67-7a96-11ea-a7f5-509a4c36e19d","resourceVersion":"2352","creationTimestamp":"2020-04-09T19:12:45Z","labels":{"k8s-app":"kube-dns","pod-template-hash":"fb8b8dccf"},"ownerReferences":[{"apiVersion":"apps/v1","kind":"ReplicaSet","name":"coredns-fb8b8dccf","uid":"184ecff7-7a96-11ea-a7f5-509a4c36e19d","controller":true,"blockOwnerDeletion":true}]}}},{"cells":["coredns-fb8b8dccf-jg7s2","1/1","Running",3,"13h","10.244.0.6","k8s-master","\u003cnone\u003e","\u003cnone\u003e"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1beta1","metadata":{"name":"coredns-fb8b8dccf-jg7s2","generateName":"coredns-fb8b8dccf-","namespace":"kube-system","selfLink":"/api/v1/namespaces/kube-system/pods/coredns-fb8b8dccf-jg7s2","uid":"184fbad1-7a96-11ea-a7f5-509a4c36e19d","resourceVersion":"2391","creationTimestamp":"2020-04-09T19:12:45Z","labels":{"k8s-app":"kube-dns","pod-template-hash":"fb8b8dccf"},"ownerReferences":[{"apiVersion":"apps/v1","kind":"ReplicaSet","name":"coredns-fb8b8dccf","uid":"184ecff7-7a96-11ea-a7f5-509a4c36e19d","controller":true,"blockOwnerDeletion":true}]}}},{"cells":["etcd-k8s-master","1/1","Running",2,"13h","12.18.7.23","k8s-master","\u003cnone\u003e","\u003cnone\u003e"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1beta1","metadata":{"name":"etcd-k8s-master","namespace":"kube-system","selfLink":"/api/v1/namespaces/kube-system/pods/etcd-k8s-master","uid":"368900c8-7a96-11ea-a7f5-509a4c36e19d","resourceVersion":"2273","creationTimestamp":"2020-04-09T19:13:36Z","labels":{"component":"etcd","tier":"control-plane"},"annotations":{"kubernetes.io/config.hash":"6758e898d84f674fbf6006af1d686f72","kubernetes.io/config.mirror":"6758e898d84f674fbf6006af1d686f72","kubernetes.io/config.seen":"2020-04-10T03:12:22.675406659+08:00","kubernetes.io/config.source":"file"}}}},{"cells":["kube-apiserver-k8s-master","1/1","Running",2,"13h","12.18.7.23","k8s-master","\u003cnone\u003e","\u003cnone\u003e"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1beta1","metadata":{"name":"kube-apiserver-k8s-master","namespace":"kube-system","selfLink":"/api/v1/namespaces/kube-system/pods/kube-apiserver-k8s-master","uid":"401276d9-7a96-11ea-a7f5-509a4c36e19d","resourceVersion":"2305","creationTimestamp":"2020-04-09T19:13:52Z","labels":{"component":"kube-apiserver","tier":"control-plane"},"annotations":{"kubernetes.io/config.hash":"ca0a720781e095859088c1b50d34ec38","kubernetes.io/config.mirror":"ca0a720781e095859088c1b50d34ec38","kubernetes.io/config.seen":"2020-04-10T03:12:22.675410299+08:00","kubernetes.io/config.source":"file"}}}},{"cells":["kube-controller-manager-k8s-master","1/1","Running",2,"13h","12.18.7.23","k8s-master","\u003cnone\u003e","\u003cnone\u003e"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1beta1","metadata":{"name":"kube-controller-manager-k8s-master","namespace":"kube-system","selfLink":"/api/v1/namespaces/kube-system/pods/kube-controller-manager-k8s-master","uid":"2ffb0bea-7a96-11ea-a7f5-509a4c36e19d","resourceVersion":"2314","creationTimestamp":"2020-04-09T19:13:25Z","labels":{"component":"kube-controller-manager","tier":"control-plane"},"annotations":{"kubernetes.io/config.hash":"c96931c62b3df0232e2dbe44485232fe","kubernetes.io/config.mirror":"c96931c62b3df0232e2dbe44485232fe","kubernetes.io/config.seen":"2020-04-10T03:12:22.675411341+08:00","kubernetes.io/config.source":"file"}}}},{"cells":["kube-flannel-ds-amd64-jpl22","1/1","Running",2,"13h","12.18.7.23","k8s-master","\u003cnone\u003e","\u003cnone\u003e"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1beta1","metadata":{"name":"kube-flannel-ds-amd64-jpl22","generateName":"kube-flannel-ds-amd64-","namespace":"kube-system","selfLink":"/api/v1/namespaces/kube-system/pods/kube-flannel-ds-amd64-jpl22","uid":"6df0717d-7a97-11ea-a7f5-509a4c36e19d","resourceVersion":"2320","creationTimestamp":"2020-04-09T19:22:19Z","labels":{"app":"flannel","controller-revision-hash":"587c98f784","pod-template-generation":"1","tier":"node"},"ownerReferences":[{"apiVersion":"apps/v1","kind":"DaemonSet","name":"kube-flannel-ds-amd64","uid":"6def7733-7a97-11ea-a7f5-509a4c36e19d","controller":true,"blockOwnerDeletion":true}]}}},{"cells":["kube-proxy-6dgjz","1/1","Running",2,"13h","12.18.7.23","k8s-master","\u003cnone\u003e","\u003cnone\u003e"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1beta1","metadata":{"name":"kube-proxy-6dgjz","generateName":"kube-proxy-","namespace":"kube-system","selfLink":"/api/v1/namespaces/kube-system/pods/kube-proxy-6dgjz","uid":"18532a7a-7a96-11ea-a7f5-509a4c36e19d","resourceVersion":"2308","creationTimestamp":"2020-04-09T19:12:46Z","labels":{"controller-revision-hash":"7999c6dd97","k8s-app":"kube-proxy","pod-template-generation":"1"},"ownerReferences":[{"apiVersion":"apps/v1","kind":"DaemonSet","name":"kube-proxy","uid":"0f90946f-7a96-11ea-a7f5-509a4c36e19d","controller":true,"blockOwnerDeletion":true}]}}},{"cells":["kube-scheduler-k8s-master","1/1","Running",2,"13h","12.18.7.23","k8s-master","\u003cnone\u003e","\u003cnone\u003e"],"object":{"kind":"PartialObjectMetadata","apiVersion":"meta.k8s.io/v1beta1","metadata":{"name":"kube-scheduler-k8s-master","namespace":"kube-system","selfLink":"/api/v1/namespaces/kube-system/pods/kube-scheduler-k8s-master","uid":"3689017b-7a96-11ea-a7f5-509a4c36e19d","resourceVersion":"2317","creationTimestamp":"2020-04-09T19:13:36Z","labels":{"component":"kube-scheduler","tier":"control-plane"},"annotations":{"kubernetes.io/config.hash":"124f5bab49bf26c80b1c1be19641c3e8","kubernetes.io/config.mirror":"124f5bab49bf26c80b1c1be19641c3e8","kubernetes.io/config.seen":"2020-04-10T03:12:22.675412214+08:00","kubernetes.io/config.source":"file"}}}}]}
I0410 16:48:36.833641   18735 get.go:570] no kind is registered for the type v1beta1.Table in scheme "k8s.io/kubernetes/pkg/api/legacyscheme/scheme.go:29"
NAMESPACE     NAME                                 READY   STATUS    RESTARTS   AGE
kube-system   coredns-fb8b8dccf-2hpgr              1/1     Running   3          13h
kube-system   coredns-fb8b8dccf-jg7s2              1/1     Running   3          13h
kube-system   etcd-k8s-master                      1/1     Running   2          13h
kube-system   kube-apiserver-k8s-master            1/1     Running   2          13h
kube-system   kube-controller-manager-k8s-master   1/1     Running   2          13h
kube-system   kube-flannel-ds-amd64-jpl22          1/1     Running   2          13h
kube-system   kube-proxy-6dgjz                     1/1     Running   2          13h
kube-system   kube-scheduler-k8s-master            1/1     Running   2          13h

kubectl命令怎么知道应该把请求发送到哪个API server呢

运行命令kubectl config view, 显示内容里的 server 后面的地址就是API server 的 url。

[root@k8s-master ~]# kubectl config view
apiVersion: v1
clusters:
- cluster:certificate-authority-data: DATA+OMITTEDserver: https://12.18.7.23:6443name: kubernetes
contexts:
- context:cluster: kubernetesuser: kubernetes-adminname: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-adminuser:client-certificate-data: REDACTEDclient-key-data: REDACTED

Kubectl常见问题如何排除

在安装配置好 Kubernetes 后,正常情况下服务器关机重启,kubelet 也会自动启动的。一次关机重启后提示如下错误:

The connection to the server 12.18.7.23:6443 was refused - did you specify the right host or port?

通过systemctl status kubelet 命令查看 kubelet 的情况,发现 kubelet 确实没有启动,其中原因是因为由于 K8s 必须保持全程关闭交换内存,之前安装是只是使用 swapoff -a 命令暂时关闭 swap。而机器重启后,swap 还是会自动启用,从而导致 kubelet 无法启动。

可以通过如下方式进行解决开机不能自启动问题

1、执行

swapoff -a

2、执行

vi /etc/fstab

/dev/mapper/centos-swap swap swap default 0 0

这一行前面加个 # 号将其注释掉。编辑完毕后保存退出。这样机器重启后 kubelet 也可以正常自动启动了。

如果以上修改完成后,还是不能自动启动,因为 Kubernetes 底层 依赖docker服务,可以查看docker 是否正常,如果不正常可以通过

 kubectl restart docker

如果重启docker 完成以后,还是不能正常使用,这时可以 df -h 查看磁盘资源占用是否正常,如果磁盘打满也可能导致 kubectl 不能正常运行。

本质上来说 kubectl 命令不能正常运行,很可能是 kubectl 依赖的系统环境不正常导致,日志可以解决一切。如本文所示进行问题排除:Kubernetes排障指南

总结

如上所示,介绍了 kubectl 工作原理,通过 kubectl 客户端完成对 Kubernetes 控制,如果你还是不明白 kubectl 如何使用,那么直接在安装完成 Kubernetes 环境 shell 上执行 kubectl ,它会提示你如何操作,当然你也可以配置自动补全或简写功能,提升你的工作效率。

回顾往期内容


Jenkins配合Kubernetes实现服务持续集成的实践和建议

云计算交付模型知多少IaaS、PaaS、SaaS

docker到k8s pod跨节点网络通信机制演进

Kubernetes中如何使用ClusterDNS进行服务发现?

Kubernetes入门培训(内含PPT)

从Ice到Kubernetes容器技术,微服务架构经历了什么?


原创不易,随手关注或者”在看“,诚挚感谢!

Kubernetes 「驾驶舱」 kubectl 知多少?相关推荐

  1. android string拼接字符串_「JAVA」细述合理创建字符串,分析字符串的底层存储,你不该错过...

    Java基础之字符串操作--String 字符串 什么是字符串?如果直接按照字面意思来理解就是多个字符连接起来组合成的字符序列.为了更好的理解以上的理论,我们先来解释下字符序列,字符序列:把多个字符按 ...

  2. 什么是「最小二乘法」

    什么是「最小二乘法」? 最小二乘法主要用于解决函数模型最优解问题,是测量工作及其他科学工程领域中,应用最早也是最广泛的算法. 在生产实践中,经常会遇到利用一组观测数据来估计某些未知参数的问题. 举个栗 ...

  3. 关于Python3.9,看这张16岁高中生做的「新特性必知图」就够了

    金磊 发自 凹非寺 量子位 报道 | 公众号 QbitAI Python3.9,「千呼万唤始出来」. 先来速看下此次发布版本的重点. 新语法特性: PEP 584,为 dict 增加合并运算符. PE ...

  4. 知乎热议:杨辉团队公开否认抄袭,网友:避重就轻仍谎称「首创」

    导读:近日,加州大学圣地亚哥分校付向东教授实名举报中科院上海神经所杨辉抄袭事件又有了新进展,杨辉团队做出书面回应否认抄袭,引发知乎网友热议. 杨辉团队回应,不存在抄袭 此前,Bioart报道了杨辉团队 ...

  5. 知乎要用AI打造智能社区,专治「答非所问」的瓦力机器人已上线

    允中 发自 凹非寺  量子位 报道 | 公众号 QbitAI 知乎涉足AI,已然不是新消息. 去年7月,量子位专文报道过知乎在机器学习方面的运用.当时知乎合伙人李大海,分享了AI在知乎内容分发中的具体 ...

  6. 真是「狗」了,知乎「吃相」太难看了

    loonggg 读完需要 7 分钟 速读仅需 3 分钟 大家好,我是校长. 最近我发现一件事,感觉知乎作为一个知识类问答创作平台,真的是一点也不尊重创作者,或许知乎刚上市吧,需要赚钱回报股东,提振市值 ...

  7. 从事计算机视觉必知的「大牛」有哪些?

    点击上方"AI算法与图像处理",选择加"星标"或"置顶" 重磅干货,第一时间送达 推荐文章[点击下面可直接跳转]: 2020 年校招,最值得 ...

  8. 从知乎「悟空」看一个成熟的Anti-Spam系统演进之路

    Hi there! 距离 2015 年 4 月「悟空」正式与大家见面,已经整整三个年头了.随着知乎的不断发展壮大,过去的一段时间,「悟空」不断面临着新的考验,并持续地在优化升级.接下来跟大家系统分享一 ...

  9. 2017Android面试回忆录「下」(今日头条/小米/网易/知乎...)

    前言 面试合集 之 滴滴.美团.腾讯.阿里.头条.小米.网易- PS: 时间周期:[2017/6 – 2017/7] 来源: [本部分由「洛廷」和「剑胆诗魂」提供] 没有严格按照面试轮次来区分 今日头 ...

最新文章

  1. 2015最流行的Android组件、工具、框架大全
  2. MCU实战经验:多种的按键处理
  3. ssm+mysql+jsp打造在线考试系统WeKnow-学生端
  4. C语言的time函数
  5. 遇到问题描述:Android Please ensure that adb is correctly located at问题解决
  6. 天翼云从业认证(1.4)计算机网络
  7. jsp+tomcat程序helloworld
  8. Java 监听器,国际化
  9. es6 Class 的继承简介
  10. 深度的卷积神经网络CNN(MNIST数据集示例)
  11. ASP.NET路由系统实现原理:HttpHandler的动态映射
  12. win10和win7游戏测试软件,Win10系统和Win7玩游戏哪个更快?评测在这里!
  13. arcgis python实例_科学网—ArcGIS,Python,网络数据集中查询两点最短路径 - 余露的博文...
  14. MySQL窗口函数OVER()
  15. android坐标画图软件下载,地图坐标app下载-地图坐标软件下载v4.8.15 安卓版-西西软件下载...
  16. pdf文件大小怎样压缩
  17. Seagull island
  18. UnicodeDecodeError: 'gbk' codec can't decode byte 0x91 in position 8: illegal multibyte sequence
  19. DirectX12_入门之三角形
  20. 小技巧!微信发朋友圈长文字怎样才能避免被折叠成一行?

热门文章

  1. 另一个.lua文件中的全局变量可以被其它.lua文件读取
  2. 十五、Typora官方主题 + 自定义主题
  3. Python 二项分布(三)
  4. python中字典的索引是什么_Python中的字典索引
  5. 在线影视平台优酷视频 v7.8.7.10120 绿色便携版
  6. 探秘硅谷精英们的海天盛筵
  7. 关于手机屏幕的一些知识(1)
  8. php函数中过滤单双数,(excel中如何将偶数筛选出来)EXCEL表中怎么筛选单数双数?...
  9. 怎么样可以搭建自己的腾讯云服务器
  10. 腾讯云 + MySQL