作者:André Luiz De Gusmão 编译:沈建苗
使用Kubernetes时这种情况很常见:我们对集群对象(比如节点、部署、构建和pod)执行几次查询,但并不总是能获得所需的一组信息——默认情况下信息通过kubeclt get来公开,这种情况下就只好搜索整个对象,结果带来了不需要的过多信息。
我们可以使用kubectl的custom-columns输出选项和jq工具,创建仅仅提供所需信息的查询。我们在本文中将探讨这两者,并学习如何创建自己的查询集合。
问题
不妨考虑需要从kubernetes集群提取信息的两种常见场景:
•获取集群节点的健康信息,比如内存、cpu和磁盘负载。
•针对集群中的部署,从环境变量(env)和资源限制(resource和limits)检索信息。
为了从集群对象检索信息,我们通常可以使用该命令:
kubectl get <OBJECT>
为了查询节点,我们可以运行该命令:
~ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME ip-10-0-135-204.xyz.compute.internal Ready master 11d v1.21.1+6438632 10.0.135.204 <none> RHEL CoreOS 48.84.202110270303-0 4.18.0-305.19.1.el8_4.x86_64 cri-o://1.21.3-8.rhaos4.8.git7415a53.el8 ip-10-0-142-176.xyz.compute.internal Ready worker 11d v1.21.1+6438632 10.0.142.176 <none> RHEL CoreOS 48.84.202110270303-0 4.18.0-305.19.1.el8_4.x86_64 cri-o://1.21.3-8.rhaos4.8.git7415a53.el8 ip-10-0-160-187.xyz.compute.internal Ready master 11d v1.21.1+6438632 10.0.160.187 <none> RHEL CoreOS 48.84.202110270303-0 4.18.0-305.19.1.el8_4.x86_64 cri-o://1.21.3-8.rhaos4.8.git7415a53.el8 ip-10-0-176-188.xyz.compute.internal Ready worker 11d v1.21.1+6438632 10.0.176.188 <none> RHEL CoreOS 48.84.202110270303-0 4.18.0-305.19.1.el8_4.x86_64 cri-o://1.21.3-8.rhaos4.8.git7415a53.el8 ip-10-0-214-226.xyz.compute.internal Ready master 11d v1.21.1+6438632 10.0.214.226 <none> RHEL CoreOS 48.84.202110270303-0 4.18.0-305.19.1.el8_4.x86_64 cri-o://1.21.3-8.rhaos4.8.git7415a53.el8 ip-10-0-219-74.xyz.compute.internal Ready worker 11d v1.21.1+6438632 10.0.219.74 <none> RHEL CoreOS 48.84.202110270303-0 4.18.0-305.19.1.el8_4.x86_64 cri-o://1.21.3-8.rhaos4.8.git7415a53.el8
为了查询部署,我们可以使用该命令,比如:
# You can also use -o wide to retrieve more information ~ kubectl get deployments --all-namespaces NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE openshift-apiserver-operator openshift-apiserver-operator 1/1 1 1 11d openshift-apiserver apiserver 3/3 3 3 11d openshift-cluster-storage-operator cluster-storage-operator 1/1 1 1 11d openshift-cluster-storage-operator csi-snapshot-controller 2/2 2 2 11d openshift-cluster-version cluster-version-operator 1/1 1 1 11d openshift-console-operator console-operator 1/1 1 1 11d openshift-console console 2/2 2 2 11d
尽管这两个命令提供了很多信息,但没有包含我们所寻找的信息。要检索所需的信息,我们可以使用命令:kubectl get deployments –all-namespaces -o json,以yaml或json格式检索完整的对象。
命令输出如下:
{ "apiVersion":"v1", "items":[ { "apiVersion":"apps/v1", "kind":"Deployment", "metadata":{ "name":"openshift-apiserver-operator", "namespace":"openshift-apiserver-operator" }, "spec":{ "template":{ "spec":{ "containers":[ { "env":[ { "name":"IMAGE", "value":"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f532d4e20932e1e6664b1b7003691d44a511bb626bc339fd883a624f020ff399" }, { "name":"OPERATOR_IMAGE", "value":"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a24bdc7bae31584af5a7e0cb0629dda9bb2b1d613a40e92e227e0d13cb326ef4" }, { "name":"OPERATOR_IMAGE_VERSION", "value":"4.8.19" }, { "name":"OPERAND_IMAGE_VERSION", "value":"4.8.19" }, { "name":"KUBE_APISERVER_OPERATOR_IMAGE", "value":"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:0e56e34f980552a7ce3d55429a9a265307dc89da11c29f6366b34369cc2a9ba0" } ], "resources":{ "requests":{ "cpu":"10m", "memory":"50Mi" } } } ] } } } } # other informations ], "kind":"List", "metadata":{ "resourceVersion":"", "selfLink":"" } }
使用custom-columns来查询节点
不妨探究kubectl get命令的custom-columns输出选项,仅检索我们所需的信息。custom-columns选项让我们可以通过映射列标题和所需字段,定义将提取哪些数据。
使用节点json作为基础,以构建我们的查询:
{ "apiVersion":"v1", "kind":"Node", "metadata":{ "name":"ip-10-0-219-74.xyz.compute.internal" }, "status":{ "addresses":[ { "address":"10.0.219.74", "type":"InternalIP" }, { "address":"ip-10-0-219-74.xyz.compute.internal", "type":"Hostname" }, { "address":"ip-10-0-219-74.xyz.compute.internal", "type":"InternalDNS" } ], "conditions":[ { "message":"kubelet has sufficient memory available", "reason":"KubeletHasSufficientMemory", "status":"False", "type":"MemoryPressure" }, { "message":"kubelet has no disk pressure", "reason":"KubeletHasNoDiskPressure", "status":"False", "type":"DiskPressure" }, { "message":"kubelet has sufficient PID available", "reason":"KubeletHasSufficientPID", "status":"False", "type":"PIDPressure" }, { "message":"kubelet is posting ready status", "reason":"KubeletReady", "status":"True", "type":"Ready" } ], "nodeInfo":{ "architecture":"amd64", "bootID":"327671fc-3d6f-4bc4-ab5f-fa012687e839", "containerRuntimeVersion":"cri-o://1.21.3-8.rhaos4.8.git7415a53.el8", "kernelVersion":"4.18.0-305.19.1.el8_4.x86_64", "kubeProxyVersion":"v1.21.1+6438632", "kubeletVersion":"v1.21.1+6438632", "machineID":"ec2e23b2f3d554c78f67dc2e30ba230a", "operatingSystem":"linux", "osImage":"Red Hat Enterprise Linux CoreOS 48.84.202110270303-0 (Ootpa)", "systemUUID":"ec2e23b2-f3d5-54c7-8f67-dc2e30ba230a" } } }
使用custom-columns的简单查询,以返回集群节点名称:
~ kubectl get nodes -o custom-columns="Name:.metadata.name" Name ip-10-0-135-204.xyz.compute.internal ip-10-0-142-176.xyz.compute.internal ip-10-0-160-187.xyz.compute.internal ip-10-0-176-188.xyz.compute.internal ip-10-0-214-226.xyz.compute.internal ip-10-0-219-74.xyz.compute.internal
如果我们想要来自一个组的特定值,可以使用所需的索引,然后创建我们的节点健康查询:
~ kubectl get nodes -o custom-columns="Name:.metadata.name,InternalIP:.status.addresses[0].address,Kernel:.status.nodeInfo.kernelVersion,MemoryPressure:.status.conditions[0].status,DiskPressure:.status.conditions[1].status,PIDPressure:.status.conditions[2].status,Ready:.status.conditions[3].status" Name Kernel InternalIP MemoryPressure DiskPressure PIDPressure Ready ip-10-0-135-204.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.135.204 False False False True ip-10-0-142-176.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.142.176 False False False True ip-10-0-160-187.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.160.187 False False False True ip-10-0-176-188.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.176.188 False False False True ip-10-0-214-226.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.214.226 False False False True ip-10-0-219-74.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.219.74 False False False True
创建查询集合
自定义查询已准备就绪,我们可以保存字段映射以方便重用。该文件遵循标题和值的特定格式:
HEADER1 HEADER2 HEADER3 .field.value1 .field.value2 .field.value3
就我们的查询而言,名为cluster-nodes-health.txt的文件将是:
Name Kernel InternalIP MemoryPressure DiskPressure PIDPressure Ready .metadata.name .status.nodeInfo.kernelVersion .status.addresses[0].address .status.conditions[0].status .status.conditions[1].status .status.conditions[2].status .status.conditions [3].status
我们可以使用custom-columns-file选项来执行查询:
~ kubectl get nodes -o custom-columns-file=cluster-nodes-health.txt Name Kernel InternalIP MemoryPressure DiskPressure PIDPressure Ready ip-10-0-135-204.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.135.204 False False False True ip-10-0-142-176.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.142.176 False False False True ip-10-0-160-187.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.160.187 False False False True ip-10-0-176-188.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.176.188 False False False True ip-10-0-214-226.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.214.226 False False False True ip-10-0-219-74.xyz.compute.internal 4.18.0-305.19.1.el8_4.x86_64 10.0.219.74 False False False
使用jq从部署中查询env
为了查询环境,我们将探究jq实用程序,我们将用它来获取JSON之类的对象,并进行过滤,仅显示我们所需的信息。
关于jq
jq是一个灵活的轻量级JSON命令行处理工具。
jq页面这样描述:“jq就像JSON数据的sed——您可以用它拆分、过滤、映射和转换结构化数据,就像sed、awk、grep一样轻松。”
可在此处找到它:https://stedolan.github.io/jq/
细述jq命令的结构
不妨用jq展示一个基本的查询。它与.items[]部署进行交互,从.metadata.name仅提取其名称。
~ kubectl get deployments --all-namespaces -o json | jq -r '.items[] | .metadata.name ' openshift-apiserver-operator apiserver authentication operator # other projects...
不妨稍稍改进我们的查询,构建含有‘name’、‘namespace’和‘env’信息的json:
~ kubectl get deployments --all-namespaces -o json | jq -r '.items[] | { namespace: .metadata.namespace, name: .metadata.name, env: .spec.template.spec.containers[].env}'
{ "namespace":"openshift-apiserver-operator", "name":"openshift-apiserver-operator", "env":[ { "name":"IMAGE", "value":"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:f532d4e20932e1e6664b1b7003691d44a511bb626bc339fd883a624f020ff399" }, { "name":"OPERATOR_IMAGE", "value":"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:a24bdc7bae31584af5a7e0cb0629dda9bb2b1d613a40e92e227e0d13cb326ef4" }, { "name":"OPERATOR_IMAGE_VERSION", "value":"4.8.19" }, { "name":"OPERAND_IMAGE_VERSION", "value":"4.8.19" }, { "name":"KUBE_APISERVER_OPERATOR_IMAGE", "value":"quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:0e56e34f980552a7ce3d55429a9a265307dc89da11c29f6366b34369cc2a9ba0" } ] } { "namespace":"openshift-apiserver", "name":"apiserver", "env":[ { "name":"POD_NAME", "valueFrom":{ "fieldRef":{ "apiVersion":"v1", "fieldPath":"metadata.name" } } }, { "name":"POD_NAMESPACE", "valueFrom":{ "fieldRef":{ "apiVersion":"v1", "fieldPath":"metadata.namespace" } } } ] } { "namespace":"openshift-apiserver", "name":"apiserver", "env":[ { "name":"POD_NAME", "valueFrom":{ "fieldRef":{ "apiVersion":"v1", "fieldPath":"metadata.name" } } }, { "name":"POD_NAMESPACE", "valueFrom":{ "fieldRef":{ "apiVersion":"v1", "fieldPath":"metadata.namespace" } } } ] } # fields hidden for reading....
为了获得有效格式的json,不妨将结果包装在数组‘[]’中,并使用jq的‘map’函数。
~ kubectl get deployments --all-namespaces -o json | jq -r '.items | [ map(.) | .[] | { namespace: .metadata.namespace, name: .metadata.name, env: .spec.template.spec.containers[].env }]'
~ kubectl get deployments --all-namespaces -o json | jq -r '.items | [ map(.) | .[] | { namespace: .metadata.namespace, name: .metadata.name, env: .spec.template.spec.containers[].env }]'
# shortened output for reading... [ { "namespace":"openshift-operator-lifecycle-manager", "name":"catalog-operator", "env":[ { "name":"RELEASE_VERSION", "value":"4.8.19" } ] }, { "namespace":"openshift-operator-lifecycle-manager", "name":"olm-operator", "env":[ { "name":"RELEASE_VERSION", "value":"4.8.19" }, { "name":"OPERATOR_NAMESPACE", "valueFrom":{ "fieldRef":{ "apiVersion":"v1", "fieldPath":"metadata.namespace" } } }, { "name":"OPERATOR_NAME", "value":"olm-operator" } ] }, { "namespace":"openshift-operator-lifecycle-manager", "name":"packageserver", "env":[ { "name":"OPERATOR_CONDITION_NAME", "value":"packageserver" } ] } ]
使用jq文件进行查询
就像使用custom-columns一样,使用jq,我们就可以选择传递包含过滤器的文件而不是内联数据。因此,不妨创建一个名为jq-deployments-envs.txt的文件,内容如下:
.items | [ map(.) | .[] | { namespace: .metadata.namespace, name: .metadata.name, env: .spec.template.spec.containers[].env }]
我们的查询可以使用该命令来执行:
~ kubectl deployments --all-namespaces -o json | jq -f jq-deployments-envs.txt
结论
借助kubectl的原生选项custom-columns和jq实用程序,可以从Kubernetes集群提取自定义信息。此外,借助使用文件来组装查询的选项,我们可以为集群创建几个有用的视图,并将它们存储在源代码控制系统中,以便与其他团队成员或社区共享。
文章来源:https://dzone.com/articles/extracting-useful-information-from-your-kubernetes