前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes 「驾驶舱」 kubectl 知多少?

Kubernetes 「驾驶舱」 kubectl 知多少?

作者头像
用户5166556
发布2020-04-22 15:08:08
7070
发布2020-04-22 15:08:08
举报

如果你的 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请求。具体查看如下日志:

代码语言:javascript
复制
[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。

代码语言:javascript
复制
[root@k8s-master ~]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://12.18.7.23:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

Kubectl常见问题如何排除

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

代码语言:javascript
复制
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、执行

代码语言:javascript
复制
swapoff -a

2、执行

代码语言:javascript
复制
vi /etc/fstab

代码语言:javascript
复制
/dev/mapper/centos-swap swap swap default 0 0

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

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

代码语言:javascript
复制
 kubectl restart docker

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

本质上来说 kubectl 命令不能正常运行,很可能是 kubectl 依赖的系统环境不正常导致,日志可以解决一切。

总结

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-04-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档