前言
Kubernetes 作为云原生时代的“操作系统”,熟悉和使用它是每名用户(User)的必备技能。如果你正在 Kubernetes 上工作,你需要正确的工具和技巧来确保 Kubernetes 集群的高可用以及工作负载的稳定运行。
随着 Kubernetes 的发展和演变,人们可以从内部来驯服它的无节制行为。但有些人并不情愿干等 Kubernetes 变得易于使用,并且为已投入生产的 Kubernetes 中遇到的很多常见问题制定了自己的解决方案。
这里我们将介绍一些提高操作效率的技巧,同时列举几个比较有用的开源 Kubernetes 工具,这些工具以各种方式简化 Kubernetes,包括简化命令行交互,简化应用程序部署语法等。
kubectl 自动补全
kubectl
这个命令行工具非常重要,与之相关的命令也很多,我们也记不住那么多的命令,而且也会经常写错,所以命令自动补全是很有必要的,kubectl 工具本身就支持自动补全,只需简单设置一下即可。
1bash 用户
大多数用户的 shell 使用的是 bash
,Linux 系统可以通过下面的命令来设置:
$ echo "source <(kubectl completion bash)" >> ~/.bashrc$ source ~/.bashrc
如果发现不能自动补全,可以尝试安装 bash-completion
然后刷新即可!
2zsh 用户
如果你使用的 shell 是 zsh
,可以通过下面的命令来设置:
$ echo "source <(kubectl completion zsh)" >> ~/.zshrc$ source ~/.zshrc
自定义 kubectl get 输出
kubectl get
相关资源,默认输出为 kubectl 内置,一般我们也可以使用 -o json
或者 -o yaml
查看其完整的资源信息。但是很多时候,我们需要关心的信息并不全面,因此我们需要自定义输出的列,那么可以使用 go-template
来进行实现。
go-template
是 golang 的一种模板,可以参考 template 的相关说明。
比如仅仅想要查看获取的 pods 中的各个 pod 的 uid
,则可以使用以下命令:
$ kubectl get pods --all-namespaces -o go-template='{{range .items}}{{.metadata.uid}}{{end}}'2ea418d4-533e-11e8-b722-005056a1bc837178b8bf-4e93-11e8-8175-005056a1bc83a0341475-5338-11e8-b722-005056a1bc83...
因为 get pods 的返回结果是 List
类型,获取的 pods 都在 items
这个的 value 中,因此需要遍历 items,也就有了 {{range .items}}
。而后通过模板选定需要展示的内容,就是 items 中的每个 {{.metadata.uid}}
。
这里特别注意,要做一个特别的处理,就是要把 {{end}}
前进行换行,以便在模板中插入换行符。
当然,如果觉得这样处理不优雅的话,也可以使用 printf
函数,在其中使用 \n
即可实现换行符的插入。
$ kubectl get pods --all-namespaces -o go-template --template='{{range .items}}{{printf "%s\n" .metadata.uid}}{{end}}'
或者可以这样:
$ kubectl get pods --all-namespaces -o go-template --template='{{range .items}}{{.metadata.uid}}{{"\n"}}{{end}}'
其实有了 printf
,就可以很容易的实现对应字段的输出,且样式可以进行自己控制。比如可以这样
$ kubectl get pods --all-namespaces -o go-template --template='{{range .items}}{{printf "|%-20s|%-50s|%-30s|\n" .metadata.namespace .metadata.name .metadata.uid}}{{end}}'|default |details-v1-64b86cd49-85vks |2e7a2a66-533e-11e8-b722-005056a1bc83||default |productpage-v1-84f77f8747-7tkwb |2eb4e840-533e-11e8-b722-005056a1bc83||default |ratings-v1-5f46655b57-qlrxp |2e89f981-533e-11e8-b722-005056a1bc83|...
下面举两个 go-template 高级用法的例子:
range 嵌套
# 列出所有容器使用的镜像名$ kubectl get pods --all-namespaces -o go-template --template='{{range .items}}{{range .spec.containers}}{{printf "%s\n" .image}}{{end}}{{end}}'istio/examples-bookinfo-details-v1:1.5.0istio/examples-bookinfo-productpage-v1:1.5.0istio/examples-bookinfo-ratings-v1:1.5.0...
条件判断
# 列出所有不可调度节点的节点名与 IP$ kubectl get no -o go-template='{{range .items}}{{if .spec.unschedulable}}{{.metadata.name}} {{.spec.externalID}}{{"\n"}}{{end}}{{end}}'
除了使用 go-template
之外,还可以使用逗号分隔的自定义列列表打印表格:
$ kubectl -n kube-system get pods coredns-64b597b598-7547d -o custom-columns=NAME:.metadata.name,hostip:.status.hostIPNAME hostipcoredns-64b597b598-7547d 192.168.123.250
也可以使用 go-template-file
自定义模板列表,模板不用通过参数传进去,而是写成一个文件,然后需要指定 template
指向该文件即可。
$ cat > test.tmpl << EOF NAME HOSTIPmetadata.name status.hostIPEOF$ kubectl -n kube-system get pods coredns-64b597b598-7547d -o custom-columns-file=test.tmplNAME HOSTIPcoredns-64b597b598-7547d 192.168.123.250
交互式 Kubernetes 客户端
Kube-prompt 可以让你在 Kubernetes 客户端输入相当于交互式命令会话的东西,并为每个命令提供自动填充的背景信息,你不必键入 kubectl 来为每个命令添加前缀。
生成 kubectl 别名
如果你需要频繁地使用 kubectl 和 kubernetes api 进行交互,使用别名将会为你节省大量的时间,开源项目 kubectl-aliases 可以通过编程的方式生成 kubectl 别名,别名生成规则如下:
简单别名示例
kd → kubectl describe
高级别名示例
kgdepallw → kubectl get deployment --all-namespaces --watch
校验配置文件
如果你手动写 Kubernetes manifest 文件,检查 manifest 文件的语法是很困难的,特别是当你有多个不同版本的 Kubernetes 集群时,确认配置文件语法是否正确更是难上加难。
Kubeval 是一个用于校验Kubernetes YAML或JSON配置文件的工具,支持多个Kubernetes版本,可以帮助我们解决不少的麻烦。
使用示例
简化 Kubernetes 部署定义
很多人都抱怨 Kubernetes manifest 文件的定义太复杂和冗长。它们很难写,而且很难维护,如果能够简化部署定义就会极大地降低维护难度。
Kedge 提供更简单、更简洁的语法,然后 kedge 将其转换为 Kubernetes manifest 文件。
使用示例
为高效 Ops 和 SRE 团队准备的 10 个开源 k8s 工具
打造高效的 Kubernetes 命令行终端
kubectl 创建 Pod 背后到底发生了什么?
Kubernetes Pod 驱逐详解
Kubernetes 内存资源限制实战