前面两节我们由浅入深介绍了不少kubernetes管理比较常用的命令.本节我们通过案例讲解一些需要更为复杂的操作才能完成的命令.
选择一个deployment下的所有pod前面讲到过,kubernetes的deployment和pod的命令上有关联关系,我们可以通过查看deployment的名称,然后记下来,然后再查找所有的pod通过grep输入deploy的名称为关键字进行过滤.
比如集群中有以下deployment
[centos@k8s-master ~]$ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE easymock-dep 1/1 1 1 21h helloworld 1/1 1 1 88m redis-cache 0/3 3 0 6h5m sagent 3/3 3 3 2d1h stodagent 3/3 3 3 6d23h trackingapi-gateway-dep 1/1 1 1 28d如果我们想要找helloworld所控制的pod,我们就可以通过以下命令来达到效果
[centos@k8s-master ~]$ kubectl get pod|grep helloworld helloworld-66fc98fd57-lc7tm 1/1 Running 0 89m但是这种匹配可能是不准确的,如果仅仅是查看可能没问题,但是在编程环境中这样做显然不是好的办法.前面我们提到过先通过kubectl get deploy helloworld -ojson然后通过jq工具拿到selector,然后使用kubectl get pod -l=查找到的标签.这里标签需要我们手动输入,因为选择器里过滤到的结果是"key":"value"格式,而-l接受的格式为key=value形式,当然我们也可以通过简单的命令转换以上两种格式.但是选择器里也可能包含多个标签(如下面示例),这样我们通过简单命令很难处理了.
[centos@k8s-master ~]$ kubectl get deploy helloworld -ojson|jq .spec.selector.matchLabels { "app": "helloworld", "version": "1.0" }下面我们一步步讲解如何通过可编程的方式根据以上信息选择名为helloworld的deployment所控制的所有pod
首先,以上的键app和version都是由用户定义的,并且不知道共有多少个,我们没法直接通过.属性名的方式获取到它,我们可以通过jq的to_entries把它转为键值数组,数组是可以遍历的.操作如下:
[centos@k8s-master ~]$ kubectl get deploy helloworld -ojson|jq '.spec.selector.matchLabels|to_entries' [ { "key": "app", "value": "helloworld" }, { "key": "version", "value": "1.0" } ]这样数组里的所有对象都包含两个键值,且键是固定的(分别为key和value),这样key我们就都全知道了.下面我们把它们组装成app=helloworld这样形式,以便kubectl get po的-l参数可用
[centos@k8s-master ~]$ kubectl get deploy helloworld -ojson|jq '.spec.selector.matchLabels|to_entries|.[]|"\(.key)=\(.value)"' "app=helloworld" "version=1.0"以上的操作有一点很关键那就是使用to_entries函数把对象转为数组.后面管道跟.[]获取数组对象.后面我们把结果放在""把结果拼接为字符串这里\为jq的语法,在字符串里使用""可以把后面跟的括号内的内容识别为命令,而不是普通字符串.
这样基本满足要求了,但是有多个label时,-l接收的参数形式为lable1=value1,label2=value2这样形式的.因此我们要删除这两个字符串的换行符,把它们合并到一行,并且中间加一个逗号.
以上字符串外面都包了一层引号(""),虽然-l变量也可以接收带引号的,但是也可以不要引号,jq里通过参数-r(aw)来获取原始字符串,要把结果合并为一行则使用-j(oin),改造后的命令如下
[centos@k8s-master ~]$ kubectl get deploy helloworld -ojson|jq -r -j '.spec.selector.matchLabels|to_entries|.[]|"\(.key)=\(.value),"' app=helloworld,version=1.0,以上结果基本上达到预期效果,只是最后面多了一个逗号,我们可以接一个sed管道把它去掉
kubectl get deploy helloworld -ojson|jq -r -j '.spec.selector.matchLabels|to_entries|.[]|"\(.key)=\(.value),"'|sed "s/.$//" app=helloworld,version=1.0我们把它赋值给一个变量,然后在选择pod的时候使用它
[centos@k8s-master ~]$ label=$( kubectl get deploy helloworld -ojson|jq -r -j '.spec.selector.matchLabels|to_entries|.[]|"\(.key)=\(.value),"'|sed "s/.$//") [centos@k8s-master ~]$ kubectl get pod -l=$label NAME READY STATUS RESTARTS AGE helloworld-66fc98fd57-lc7tm 1/1 Running 0 3h22m 显示集群中所有pod的标签把集群中所有的pod全部列出来非常容易.使用kubectl get pod --all-namespace即可.重要的是我们要循环遍历所有的pod,把它们的名称和标签信息过滤出来展示.
前面我们说过,在使用kubectl get pod时如果使用-o=name便可以只列出pod的名称.它并不是简单地把kubectl get po命令展示的名称过滤出来,而是通过资源类型/资源名称的方式展示.比如有个pod名称叫作consul-0,使用kubectl get pod -o=name展示出来它的名称为pod/consul-0,这样我们就可以直接使用kubectl get来获取到它
[centos@k8s-master ~]$ kubectl get pod/consul-0 NAME READY STATUS RESTARTS AGE consul-0 1/1 Running 0 3d2hk8s除了支持kubectl get+资源类型+资源名称外,还支持kubectl get 资源类型/资源名称这种形式.虽然平时我们不经常这样写,但是有特定场景下非常有用.