本文发布已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已失效。

关于 kubectl 你可能不知道的一些事

kubectl 是与 Kubernetes 集群交互的命令行工具。许多人每天使用它将容器工作负载部署到生产集群。但是,除了 kubectl create -fkubectl rolling-update 之外,kubectl 还有更多功能。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 来表示模板(template),因此我们需要保留与现有 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 service:

$> 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

添加或移除标签 (Labels)

有时,你希望动态地向 Pod、Service 或 Replication Controller 添加或移除标签。也许你想将一个现有 Pod 添加到某个 Service,或者从某个 Service 中移除一个 Pod。无论你想做什么,都可以使用 kubectl label 子命令轻松动态地添加或移除标签:

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

为对象添加注解 (Annotations)

就像标签一样,你可以使用 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 的方法