本文来自正在规划的Go语言&云原生自我提升系列,欢迎关注后续文章。
kubectl
命令行工具非常强大,在接下来的文章中,我们会使用它来创建对象并与Kubernetes API进行交互。但在此之前,我们先过一遍可用于所有Kubernetes对象的基础kubectl
命令。
命名空间
Kubernetes使用命名空间来组织集群中的对象。可以把命名空间看成是存储一组对象的文件夹。默认kubectl
命令行与default
命名空间交互。如果希望使用其它命名空间,可对kubectl
传递--namespace
标记。例如kubectl --namespace=mystuff
指向mystuff
命名空间中的对象。如果想要简洁些的话可以使用短标记-n
。如果想要与所有命名空间交互,比如说列举出集群中所有的Pod,可传递--all-namespaces
标记。
上下文
如果希望永久修改默认命名空间的话,可以使用上下文。这会在kubectl
配置文件中进行记录,通常放在$HOME/.kube/config文件中。这个配置文件中还存储了查找、验证集群的信息。例如,可以使用如下命令kubectl
创建其它默认命名空间的上下文:
1 |
$ kubectl config set-context my-context --namespace=mystuff |
这会新建一个下文,但暂未启用。可运行如下命令来使用新建的上下文:
1 |
$ kubectl config use-context my-context |
上下文还可对set-context
命令使用--users
或--clusters
标记用于管理其它集群或验证集群的其它用户。
查看Kubernetes API对象
Kubernetes的所有内容都表现为RESTful资源。在本系列文章中我们看将这些资源称为Kubernetes对象。每个 K8S 对象都有独立的HTTP路径,例如https://your-k8s.com/api/v1/namespaces/default/pods/my-pod指向默认命名空间中名为my-pod
的Pod。kubectl
命令通过这些URL来访问路径中的Kubernetes对象。
通过kubectl
查看Kubernetes对象最基础的命令是get
。如果运行kubectl get <resource-name>
,会列出当前命名空间中的所有资源。而若想获取指定资源,可使用kubectl get <resource-name> <obj-name>
。
默认,kubectl
使用对人类友好的响应来查看API服务端,但这种响应在命令行中去除了很多对象相互之间的详情。获取更多信息的一种方式是添加-o wide
参数,这样信息更多,行也更长。如果希望查看完整的对象,可以分别使用-o json
或-o yaml
参数按原生JSON或YAML查看对象。
对kubectl
输出的常见操作是删除头信息,在将kubectl
与Unix管道(如kubectl ... | awk ...
)合并时经常很有用。若指定--no-headers
参数,kubectl
在人类易读的表格顶部会跳过头部信息。
另一种常见任务是提取对象中的指定字段,kubectl
使用JSONPath查询语言选取返回对象中的字段。JSONPath的完整详情不在本文讨论范围内,我们通过一个示例来了解,以下命令提取、打印出指定Pod的IP地址:
1 |
$ kubectl get pods my-pod -o jsonpath --template={.status.podIP} |
我们也可以使用逗号分隔类型的列表来查看不同类型的多个对象,例如:
1 |
$ kubectl get pods,services |
这会显示给定命名空间的所有Pod和服务。
如果想获取具体对象的详细信息,可使用describe
命令:
1 |
$ kubectl describe <resource-name> <obj-name> |
它会输出更丰富的多行人类易读的对象描述以及Kubernetes集群中相关对象、事件的信息。
如果想要查看Kubernetes各支持类型所支持字段列表,可使用explain
命令:
1 |
$ kubectl explain pods |
有时我们希望持续观察特定Kubernetes资源的状态,以发现资源所发生的改变。例如,你可能在等待应用的重启。--watch
参数可用于完成这一任务。可对任意的kubectl get
命令添加这一参数来持续监测指定资源的状态。
创建、更新及销毁Kubernetes对象
Kubernetes API中的对象表现为JSON或YAML文件。这些文件要么对查询以服务端响应返回,要么作为API请求体提交到服务端。可以使用这些YAML或JSON文件来创建、更新或删除Kubernetes服务端的对象。
假定在obj.yaml中存储了一个简单的对象。可以运行kubectl
命令来在Kubernetes中创建该对象:
1 |
$ kubectl apply -f obj.yaml |
注意我们不需要指定对象的类型,这会从对象文件中获取。
类似地,向对象作出修改时,我们可以再次使用apply
来更新该对象:
1 |
$ kubectl apply -f obj.yaml |
apply
工具仅会进行与当前集群中对象有差别的修改。如果集群中已存在所要创建的对象,只会成功退出而不作出任何修改。这对于希望保证集群状态和文件系统状态保持一致的循环非常有用。可以反复地使用reconcile来同步状态。
如果希望查看apply
命令所要做的操作,而不进行实际修改,可以使用--dry-run
参数在终端中打印对象,而不将它们发送给服务端。
注:如果想进行交互式的编辑而不是编辑本地文件,可以使用edit
命令,它会下载最新的对象状态,然后启动包含定义的编辑器:
1 |
$ kubectl edit <resource-name> <obj-name> |
保存文件后,它会自动上传回Kubernetes集群。
apply
命令还会在对象中用注解记录此前的历史配置。可以使用edit-last-applied
、set-last-applied
和view-last-applied
命令来操作这些记录。例如:
1 |
$ kubectl apply -f myobj.yaml view-last-applied |
会显示应用于对象的最新状态。
如果想要删除对象,只需运行:
1 |
$ kubectl delete -f obj.yaml |
注意kubectl
不会弹出确认删除。执行命令后,对象就会被删除。
同样可以使用资源类型和名称删除对象:
1 |
$ kubectl delete <resource-name> <obj-name> |
标记和注解对象
标记和注解是对象的标签。我们会在标记和注解一文中进行讨论,但现在我们先使用label
和annotate
命令来更新Kubernetes对象的标记和注解。例如,对名为bar
的Pod添加color=red
标记,可运行:
1 |
$ kubectl label pods bar color=red |
注解的用法与其类似。
默认,label
和annotate
不会重写已有的标签。要进行重写,需要添加--overwrite
参数。
如果想要删除标记,可使用<label-name>-
:
1 |
$ kubectl label pods bar color- |
它会对名为bar
的Pod删除color
标记。
调试命令
kubectl
还有一些命令可调试容器。可使用如下命令查看运行中容器的日志:
1 |
$ kubectl logs <pod-name> |
如果Pod中有多个容器,可以使用-c
参数选择要查看的容器。
默认,kubectl logs
列出当前日志并退出。如果不希望退出,持续在终端中显示日志流,可在命令行参数中添加-f
(follow的简写)。
还可以使用exec
命令在运行中的容器中执行命令:
1 |
$ kubectl exec -it <pod-name> -- bash |
以上会提供一个容器内的交互shell,通过它可开展更多的调试工作。
如果容器中不存在bash或其它的终端命令,可对运行中的进程应用attach
:
1 |
$ kubectl attach -it <pod-name> |
attach
命令类似kubectl logs
,但允许我们对进程发送输入内容,比如进程配置了读取标准输入的功能。
我们还可以使用cp
命令对容器拷入或拷出文件:
1 |
$ kubectl cp <pod-name>:</path/to/remote/file> </path/to/local/file> |
以上会将容器中的文件拷贝至本机。还可以指定目录或使用反向的语句将本机文件拷贝到容器中。
如果想通过网络访问Pod,可以使用port-forward
命令将本机网络流量转发至Pod。这样我们可以安全地将流量发往容器而又容器又不暴露到公网中。例如,如下的命令:
1 |
$ kubectl port-forward <pod-name> 8080:80 |
会打开连接将本机8080端口的流量转发至远程容器的80端口。
注:还可使用services/<service-name>
代替<pod-name>
来对服务使用port-forward
命令,注意如果是转发至服务,请求只会转发到该服务的某个Pod上。不会经过服务的负载均衡。
如果想查看Kubernetes事件,可以使用kubectl get events
命令查看给定命名空间中所有对象的近10个事件:
1 |
$ kubectl get events |
也可对kubectl get events
命令添加--watch
参数流式查看事件。我们还可以添加-A
查看所有命名空间中的事件。
最后,如果想了解集群是如何使用资源的,可以使用top
命令来查看节点或Pod所使用的资源列表。命令如下:
1 |
$ kubectl top nodes |
以上命令会显示节点所使用的总CPU和内存,包含绝对量(如核数)和可用资源(如总核数)占比。类似的,使用如下命令:
1 |
$ kubectl top pods |
以上命令会显示所有Pod及其资源使用量。默认它会显示当前命令空间中的Pod,但如果添加--all-namespaces
参数可以看到集群中所有Pod的资源使用量。
这些top
命令仅在集群中运行有度量服务时才可使用。在每个托管的Kubernetes环境及大部分非托管Kubernetes环境中几乎都存在度量(metrics)服务。但如果命令失败的话,原因可能是需要安装度量服务。
集群管理
kubectl
工具还可用于管理集群本身。管理集群最常见的操作是隔离和清空具体节点。在隔离(cordon)节点时,会阻止接下来将Pod调度到当前的机器上。而在清空(drain)节点时,会删除当前在该机器上运行的所有Pod。一个很好的使用场景是删除一个物理机以供维修或升级。此时可使用kubectl cordon
再接kubectl drain
安全地从集群中删除该机器。机器修好后,可使用kubectl uncordon
重新允许将Po调度至该节点。并不存在undrain
,在节点完成创建后Pod会自动地调度到该节点。对于一些短暂影响节点的情况(比如说重启),通常不需要进行隔离和清空,仅在机器会较长时间无法提供服务需要将Pod转到其它机器时才需要这么做。
命令自动补全
kubectl
支持集成shell来启用对命令和资源的tab补全。根据环境的不同,可能需要在启用命令补全之前安装bash-completion
。可通过如下方式安装相应的包管理器:
1 2 3 4 5 6 7 8 |
# macOS $ brew install bash-completion # CentOS/Red Hat $ yum install bash-completion # Debian/Ubuntu $ apt-get install bash-completion |
在macOS上安装时,请确保按照brew
的教程使用${HOME}/.bash_profile启用tab补全。
安装好bash-completion
之后,可以在终端中使用如下命令临时启用:
1 |
$ source <(kubectl completion bash) |
如果要在每个终端中自动启用,可将其添加至${HOME}/.bashrc文件中:
1 |
$ echo "source <(kubectl completion bash)" >> ${HOME}/.bashrc |
如果使用的是zsh
,请参照网上教程。
查看集群的其它方式
除了使用kubectl
,还有一些其它工具可对接Kubernetes集群。例如,一些编辑器有插件可集成Kubernetes和编辑器环境,有:
如果使用了托管的Kubernetes服务,大部都带有图形界面用于在网页中集成Kubernetes。公有云的托管Kubernetes还集成了强大的监控工具,帮助我们了解所运行应用的状态。
针对Kubernetes还有一些开源图形界面,如Rancher Dashboard和Headlamp项目。
小结
kubectl
是一款用于管理Kubernetes集群中应用的强大工具。本文讲述了很多常见用法,但kubectl
的内置帮助中还有很多内容。可以通过如下命令查看帮助文档:
1 |
$ kubectl help |
或是
1 |
$ kubectl help <command-name> |