本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

一些你不知道的关于 kubectl 的事情

kubectl 是与 Kubernetes 集群交互的命令行工具。许多人每天都用它将容器工作负载部署到生产集群中。但 kubectl 的功能远不止 kubectl create -f 或 kubectl rolling-update。kubectl 实际上是一个多功能容器编排和管理工具。下面我们将介绍一些您可能没见过 kubectl 功能。

运行交互式命令

kubectl run 自 kubectl 1.0 版本发布以来一直存在,但最近我们增加了在集群中运行交互式容器的功能。这意味着在您的 Kubernetes 集群中,只需一个命令即可获得交互式 shell:

$> kubectl run -i --tty busybox --image=busybox --restart=Never -- sh
Waiting for pod default/busybox-tv9rm to be running, status is Pending, pod ready: false
Waiting for pod default/busybox-tv9rm to be running, status is Running, pod ready: false
$> # ls 
bin dev etc home proc root sys tmp usr var 
$> # exit

上面的 kubectl 命令等同于 docker run -i -t busybox sh。遗憾的是,我们在 kubectl 1.0 中错误地将 -t 用作模板,因此我们需要保留与现有 CLI 用户的向后兼容性。但 -t 的现有用法已被弃用,我们最终会将 --tty 缩短为 -t

在此示例中,-i 表示您希望为容器分配 stdin 并表示您希望进行交互式会话,--restart=Never 表示在您退出终端后容器不应重新启动,--tty 请求为该会话分配一个 TTY。

查看 Pod 日志

有时您只是想查看服务器上正在发生什么。为此,请使用 kubectl logs 子命令。添加 -f 标志可以实时将新日志流式传输到您的终端,就像 tail -f 一样。

$> kubectl logs -f redis-izl09

连接到现有容器

除了交互式执行命令之外,您现在还可以连接到任何正在运行的进程。像 kubectl logs 一样,您将获得 stderr 和 stdout 数据,但使用 attach,您还可以将 stdin 从您的终端发送到程序。这对于交互式调试,甚至只是向行为不当的应用程序发送 ctrl-c 都非常有用。

$> kubectl attach redis -i

1:C 12 Oct 23:05:11.848 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf

                _._                
           _.-``__''-._            
      _.-`` `. `_. ''-._ Redis 3.0.3 (00000000/0) 64 bit
  .-`` .-```. ```\/ _.,_ ''-._     
 ( ' , .-` | `, ) Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
 | `-._ `._ / _.-' | PID: 1
  `-._ `-._ `-./ _.-' _.-'         
 |`-._`-._ `-.__.-' _.-'_.-'|      
 | `-._`-._ _.-'_.-' | https://redis.ac.cn
`-._ `-._`-.__.-'_.-' _.-'         
 |`-._`-._ `-.__.-' _.-'_.-'|      
 | `-._`-._ _.-'_.-' |             
  `-._ `-._`-.__.-'_.-' _.-'       
      `-._ `-.__.-' _.-'           
          `-._ _.-'                
              `-.__.-'             

1:M 12 Oct 23:05:11.849 # Server started, Redis version 3.0.3

将端口从 Pod 转发到本地计算机

出于安全原因,您通常希望能够临时与集群中的应用程序进行通信,而无需将它们暴露给公共互联网。为此,port-forward 命令允许您通过 Kubernetes API 服务器将本地计算机上的端口安全地转发到集群中运行的 Pod。例如:

$> kubectl port-forward redis-izl09 6379

在您的本地机器上打开端口 6379,并将流向该端口的通信转发到集群中的 Pod 或 Service。例如,您可以使用 telnet 命令探测集群中的 Redis 服务

$> telnet localhost 6379 
INCR foo
:1
INCR foo 
:2

在现有容器中执行命令

除了能够附加到容器内部的现有进程之外,exec 命令还允许您在现有容器内部生成新进程。这对于调试或检查您的 pod 以查看内部情况而不会中断正在运行的服务很有用。kubectl execkubectl run 不同,因为它在**现有**容器内部运行命令,而不是生成一个新容器来执行。

$> kubectl exec redis-izl09 -- ls /
bin
boot
data
dev
entrypoint.sh
etc
home

添加或删除标签

有时您需要动态地从 Pod、Service 或 Replication controller 添加或删除标签。也许您想将现有 Pod 添加到 Service 中,或者您想从 Service 中删除 Pod。无论您想要什么,您都可以使用 kubectl label 子命令轻松动态地添加或删除标签

`$> kubectl label pods redis-izl09 mylabel=awesome `
`pod "redis-izl09" labeled`

为您的对象添加注解

与标签一样,您可以使用 kubectl annotate 子命令从 API 对象添加或删除注解。与标签不同,注解用于描述您的对象,但不用于通过标签查询识别 pod(更多关于注解的详细信息)。例如,您可以添加一个图标注解,供 GUI 用于显示您的 pod。

$> kubectl annotate pods redis-izl09 icon-url=http://goo.gl/XXBTWq
pod "redis-izl09" annotated

输出自定义格式

有时,您希望自定义 kubectl 汇总集群中的对象时显示的字段。为此,您可以使用 custom-columns-file 格式。custom-columns-file 接受一个用于渲染输出的模板文件。同样,模板中使用 JSONPath 表达式来指定 API 对象中的字段。例如,以下模板首先显示重启次数,然后显示对象的名称

$> cat cols.tmpl
RESTARTS                                   NAME
.status.containerStatuses[0].restartCount .metadata.name

如果您将此模板传递给 kubectl get pods 命令,您将获得一个包含指定字段的 pod 列表。

$> kubectl get pods redis-izl09 -o=custom-columns-file --template=cols.tmpl                 RESTARTS           NAME   
 0                  redis-izl09   
 1                  redis-abl42  

轻松管理多个 Kubernetes 集群

如果您运行多个 Kubernetes 集群,您会知道管理不同集群的所有凭证可能很棘手。使用 kubectl config 子命令,在不同集群之间切换就像以下操作一样简单:

$> kubectl config use-context

不确定有哪些集群可用?您可以通过以下方式查看当前配置的集群:

$> kubectl config view

呼,这输出了一大堆文本。为了将其限制在我们感兴趣的内容,我们可以使用 JSONPath 模板

$> kubectl config view -o jsonpath="{.context[*].name}"

啊,这样好多了。

结论

就是这样,您可以通过 Kubernetes 集群和 kubectl 命令行完成九件激动人心的新事情。如果您刚刚开始使用 Kubernetes,请查看 Google Container Engine 或其他 Kubernetes 入门方式