使用custom-columns和jq,提取有用的Kubernetes集群信息

作者: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,以yamljson格式检索完整的对象。
命令输出如下:

{
   "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-columnsjq实用程序,可以从Kubernetes集群提取自定义信息。此外,借助使用文件来组装查询的选项,我们可以为集群创建几个有用的视图,并将它们存储在源代码控制系统中,以便与其他团队成员或社区共享。

 

文章来源:https://dzone.com/articles/extracting-useful-information-from-your-kubernetes

K8S中文社区微信公众号

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址