LoginSignup
0
0

More than 1 year has passed since last update.

containerd コンテナランタイムで情報収集

Last updated at Posted at 2021-09-24

はじめに

先日 An experiment of how to detect OOMKilled events on Container-Optimized OS with containerd というタイトルでテックブログを執筆しました。ここでは必要最低限度の情報を取得するための方法だけ簡単に紹介しましたが、このブログを書くにあたって試行錯誤していたことを備忘録的に残しておきます。

環境

この実験に使用した環境は以下の通りです。

項目名
GKE node version v1.18.20-gke.901
OS Image Container-Optimized OS from Google
Kernel version 5.4.109+
Container runtime containerd://1.4.3

準備

テックブログと同じように default ネームスペースに nginx をデプロイしておきます。この nginx にはノード上のソケットファイル /run/containerd/containerd.sock をマウントしております。

kubectl apply -f k8s/nginx.yaml
kubectl get pods
コマンドの結果
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-7d87f6d94b-4d7bm   1/1     Running   0          3h54m

なおマニフェストファイルはこちらから入手可能です。

情報収集

コンテナに設定されているラベル

コンテナオブジェクトにはラベル情報を返す関数 Labels が用意されています(関数定義はこちらを参照)。これを使ってラベル情報を取得してみましょう。

label.go
package main

import (
    "context"
    "log"
    "fmt"
    "encoding/json"

    "github.com/containerd/containerd"
)

const (
    address = "/run/containerd/containerd.sock"
    namespace = "k8s.io"
)

func main() {
    client, err := containerd.New(
        address,
        containerd.WithDefaultNamespace(namespace),
    )

    if err != nil {
        log.Fatal(err)
    }

    defer client.Close()

    ctx := context.Background()

    containers, _ := client.Containers(ctx)
    for _, c := range containers {
        c_label, _ := c.Labels(ctx)
        label, _ := json.Marshal(c_label)

        fmt.Printf("%s\n", string(label))
    }
}
GOOS=linux GOARCH=amd64 go build label.go
kubectl cp label $(kubectl get pods -l app=nginx -o jsonpath='{.items[*].metadata.name}'):/root/label
kubectl exec $(kubectl get pods -l app=nginx -o jsonpath='{.items[*].metadata.name}') -- /root/label > label.json
jq '. | if ."io.kubernetes.pod.name" == "nginx-deployment-7d87f6d94b-4d7bm" then . else empty end' label.json

nginx に関連のあるものだけ表示すると以下のような結果を得ます。

{
  "io.cri-containerd.kind": "container",
  "io.kubernetes.container.name": "nginx",
  "io.kubernetes.pod.name": "nginx-deployment-7d87f6d94b-4d7bm",
  "io.kubernetes.pod.namespace": "default",
  "io.kubernetes.pod.uid": "1edc1c49-ab0a-4b99-b935-21a912624c2d"
}
{
  "app": "nginx",
  "io.cri-containerd.kind": "sandbox",
  "io.kubernetes.pod.name": "nginx-deployment-7d87f6d94b-4d7bm",
  "io.kubernetes.pod.namespace": "default",
  "io.kubernetes.pod.uid": "1edc1c49-ab0a-4b99-b935-21a912624c2d",
  "pod-template-hash": "7d87f6d94b"
}

ランタイム仕様情報

こちらもランタイム仕様情報を返す関数 Spec が用意されています(関数定義はこちら)。これを使ってランタイム仕様情報を取得してみましょう。呼ぶ関数が異なるだけで、基本的にやってることは同じです。

spec.go
package main

import (
    "context"
    "log"
    "fmt"
    "encoding/json"

    "github.com/containerd/containerd"
)

const (
    address = "/run/containerd/containerd.sock"
    namespace = "k8s.io"
)

func main() {
    client, err := containerd.New(
        address,
        containerd.WithDefaultNamespace(namespace),
    )

    if err != nil {
        log.Fatal(err)
    }

    defer client.Close()

    ctx := context.Background()

    containers, _ := client.Containers(ctx)
    for _, c := range containers {
        c_spec, _ := c.Spec(ctx)
        spec, _ := json.Marshal(c_spec)

        fmt.Printf("%s\n", string(spec))
    }
}
GOOS=linux GOARCH=amd64 go build spec.go
kubectl cp spec $(kubectl get pods -l app=nginx -o jsonpath='{.items[*].metadata.name}'):/root/spec
kubectl exec $(kubectl get pods -l app=nginx -o jsonpath='{.items[*].metadata.name}') -- /root/spec > spec.json
jq '. | if .annotations."io.kubernetes.cri.container-name" == "nginx" then . else empty end' spec.json
{
  "ociVersion": "1.0.2-dev",
  "process": {
    "user": {
      "uid": 0,
      "gid": 0
    },
    "args": [
      "/docker-entrypoint.sh",
      "nginx",
      "-g",
      "daemon off;"
    ],
    "env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
      "HOSTNAME=nginx-deployment-7d87f6d94b-4d7bm",
      "NGINX_VERSION=1.21.1",
      "NJS_VERSION=0.6.1",
      "PKG_RELEASE=1~buster",
      "KUBERNETES_PORT_443_TCP=tcp://10.4.0.1:443",
      "KUBERNETES_PORT_443_TCP_PROTO=tcp",
      "KUBERNETES_PORT_443_TCP_PORT=443",
      "KUBERNETES_PORT_443_TCP_ADDR=10.4.0.1",
      "KUBERNETES_SERVICE_HOST=10.4.0.1",
      "KUBERNETES_SERVICE_PORT=443",
      "KUBERNETES_SERVICE_PORT_HTTPS=443",
      "KUBERNETES_PORT=tcp://10.4.0.1:443"
    ],
    "cwd": "/",
    "capabilities": {
      "bounding": [
        "CAP_CHOWN",
        "CAP_DAC_OVERRIDE",
        "CAP_FSETID",
        "CAP_FOWNER",
        "CAP_MKNOD",
        "CAP_NET_RAW",
        "CAP_SETGID",
        "CAP_SETUID",
        "CAP_SETFCAP",
        "CAP_SETPCAP",
        "CAP_NET_BIND_SERVICE",
        "CAP_SYS_CHROOT",
        "CAP_KILL",
        "CAP_AUDIT_WRITE"
      ],
      "effective": [
        "CAP_CHOWN",
        "CAP_DAC_OVERRIDE",
        "CAP_FSETID",
        "CAP_FOWNER",
        "CAP_MKNOD",
        "CAP_NET_RAW",
        "CAP_SETGID",
        "CAP_SETUID",
        "CAP_SETFCAP",
        "CAP_SETPCAP",
        "CAP_NET_BIND_SERVICE",
        "CAP_SYS_CHROOT",
        "CAP_KILL",
        "CAP_AUDIT_WRITE"
      ],
      "inheritable": [
        "CAP_CHOWN",
        "CAP_DAC_OVERRIDE",
        "CAP_FSETID",
        "CAP_FOWNER",
        "CAP_MKNOD",
        "CAP_NET_RAW",
        "CAP_SETGID",
        "CAP_SETUID",
        "CAP_SETFCAP",
        "CAP_SETPCAP",
        "CAP_NET_BIND_SERVICE",
        "CAP_SYS_CHROOT",
        "CAP_KILL",
        "CAP_AUDIT_WRITE"
      ],
      "permitted": [
        "CAP_CHOWN",
        "CAP_DAC_OVERRIDE",
        "CAP_FSETID",
        "CAP_FOWNER",
        "CAP_MKNOD",
        "CAP_NET_RAW",
        "CAP_SETGID",
        "CAP_SETUID",
        "CAP_SETFCAP",
        "CAP_SETPCAP",
        "CAP_NET_BIND_SERVICE",
        "CAP_SYS_CHROOT",
        "CAP_KILL",
        "CAP_AUDIT_WRITE"
      ]
    },
    "apparmorProfile": "cri-containerd.apparmor.d",
    "oomScoreAdj": 1000
  },
  "root": {
    "path": "rootfs"
  },
  "mounts": [
    {
      "destination": "/proc",
      "type": "proc",
      "source": "proc",
      "options": [
        "nosuid",
        "noexec",
        "nodev"
      ]
    },
    {
      "destination": "/dev",
      "type": "tmpfs",
      "source": "tmpfs",
      "options": [
        "nosuid",
        "strictatime",
        "mode=755",
        "size=65536k"
      ]
    },
    {
      "destination": "/dev/pts",
      "type": "devpts",
      "source": "devpts",
      "options": [
        "nosuid",
        "noexec",
        "newinstance",
        "ptmxmode=0666",
        "mode=0620",
        "gid=5"
      ]
    },
    {
      "destination": "/dev/mqueue",
      "type": "mqueue",
      "source": "mqueue",
      "options": [
        "nosuid",
        "noexec",
        "nodev"
      ]
    },
    {
      "destination": "/sys",
      "type": "sysfs",
      "source": "sysfs",
      "options": [
        "nosuid",
        "noexec",
        "nodev",
        "ro"
      ]
    },
    {
      "destination": "/sys/fs/cgroup",
      "type": "cgroup",
      "source": "cgroup",
      "options": [
        "nosuid",
        "noexec",
        "nodev",
        "relatime",
        "ro"
      ]
    },
    {
      "destination": "/dev/shm",
      "type": "bind",
      "source": "/run/containerd/io.containerd.grpc.v1.cri/sandboxes/51bd1b3e0e7b3895351482fe93d182ce71bb7b7f245b536bb80d76ff09b304b5/shm",
      "options": [
        "rbind",
        "rprivate",
        "rw"
      ]
    },
    {
      "destination": "/etc/hosts",
      "type": "bind",
      "source": "/var/lib/kubelet/pods/1edc1c49-ab0a-4b99-b935-21a912624c2d/etc-hosts",
      "options": [
        "rbind",
        "rprivate",
        "rw"
      ]
    },
    {
      "destination": "/dev/termination-log",
      "type": "bind",
      "source": "/var/lib/kubelet/pods/1edc1c49-ab0a-4b99-b935-21a912624c2d/containers/nginx/020ba2a4",
      "options": [
        "rbind",
        "rprivate",
        "rw"
      ]
    },
    {
      "destination": "/etc/hostname",
      "type": "bind",
      "source": "/var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/51bd1b3e0e7b3895351482fe93d182ce71bb7b7f245b536bb80d76ff09b304b5/hostname",
      "options": [
        "rbind",
        "rprivate",
        "rw"
      ]
    },
    {
      "destination": "/etc/resolv.conf",
      "type": "bind",
      "source": "/var/lib/containerd/io.containerd.grpc.v1.cri/sandboxes/51bd1b3e0e7b3895351482fe93d182ce71bb7b7f245b536bb80d76ff09b304b5/resolv.conf",
      "options": [
        "rbind",
        "rprivate",
        "rw"
      ]
    },
    {
      "destination": "/run/containerd/containerd.sock",
      "type": "bind",
      "source": "/run/containerd/containerd.sock",
      "options": [
        "rbind",
        "rprivate",
        "rw"
      ]
    },
    {
      "destination": "/var/run/secrets/kubernetes.io/serviceaccount",
      "type": "bind",
      "source": "/var/lib/kubelet/pods/1edc1c49-ab0a-4b99-b935-21a912624c2d/volumes/kubernetes.io~secret/default-token-snxmc",
      "options": [
        "rbind",
        "rprivate",
        "ro"
      ]
    }
  ],
  "annotations": {
    "io.kubernetes.cri.container-name": "nginx",
    "io.kubernetes.cri.container-type": "container",
    "io.kubernetes.cri.sandbox-id": "51bd1b3e0e7b3895351482fe93d182ce71bb7b7f245b536bb80d76ff09b304b5"
  },
  "linux": {
    "resources": {
      "devices": [
        {
          "allow": false,
          "access": "rwm"
        }
      ],
      "memory": {},
      "cpu": {
        "shares": 2,
        "period": 100000
      }
    },
    "cgroupsPath": "/kubepods/besteffort/pod1edc1c49-ab0a-4b99-b935-21a912624c2d/287fc9c90bd187dee5a1628ac032f828fb99cc7e24c99eef72dcef27ce782b48",
    "namespaces": [
      {
        "type": "pid"
      },
      {
        "type": "ipc",
        "path": "/proc/15625/ns/ipc"
      },
      {
        "type": "uts",
        "path": "/proc/15625/ns/uts"
      },
      {
        "type": "mount"
      },
      {
        "type": "network",
        "path": "/proc/15625/ns/net"
      }
    ],
    "maskedPaths": [
      "/proc/acpi",
      "/proc/kcore",
      "/proc/keys",
      "/proc/latency_stats",
      "/proc/timer_list",
      "/proc/timer_stats",
      "/proc/sched_debug",
      "/proc/scsi",
      "/sys/firmware"
    ],
    "readonlyPaths": [
      "/proc/asound",
      "/proc/bus",
      "/proc/fs",
      "/proc/irq",
      "/proc/sys",
      "/proc/sysrq-trigger"
    ]
  }
}

メタデータ情報

コンテナ型構造体には Extensions というメンバーが存在し、ここにはクライアントによって明示された情報が格納されております。これを取得するための関数として Extensions が用意されているので、これを使ってみましょう。ただしコンテナの情報がたくさん出てくると面倒なので、nginx の ID だけに絞っておきます(IDの値は予め調べておきます)。

extensions1.go
package main

import (
    "context"
    "log"
    "fmt"
    "encoding/json"

    "github.com/containerd/containerd"
)

const (
    address = "/run/containerd/containerd.sock"
    namespace = "k8s.io"
)

func main() {
    client, err := containerd.New(
        address,
        containerd.WithDefaultNamespace(namespace),
    )

    if err != nil {
        log.Fatal(err)
    }

    defer client.Close()

    ctx := context.Background()

    containers, _ := client.Containers(ctx)
    for _, c := range containers {
        if c.ID() == "51bd1b3e0e7b3895351482fe93d182ce71bb7b7f245b536bb80d76ff09b304b5" {
            ext, _ := c.Extensions(ctx)
            ext_metadata_json, _ := json.Marshal(ext)
            fmt.Printf("%s\n", string(ext_metadata_json))
        }
     }
}
GOOS=linux GOARCH=amd64 go build extensions1.go
kubectl cp extensions1 $(kubectl get pods -l app=nginx -o jsonpath='{.items[*].metadata.name}'):/root/extensions1
kubectl exec $(kubectl get pods -l app=nginx -o jsonpath='{.items[*].metadata.name}') -- /root/extensions1
{
  "io.cri-containerd.sandbox.metadata": {
    "type_url": "github.com/containerd/cri/pkg/store/sandbox/Metadata",
    "value": "eyJWZXJzaW9uIjoidjEiLCJNZXRhZGF0YSI6eyJJRCI6IjUxYmQxYjNlMGU3YjM4OTUzNTE0ODJmZTkzZDE4MmNlNzFiYjdiN2YyNDViNTM2YmI4MGQ3NmZmMDliMzA0YjUiLCJOYW1lIjoibmdpbngtZGVwbG95bWVudC03ZDg3ZjZkOTRiLTRkN2JtX2RlZmF1bHRfMWVkYzFjNDktYWIwYS00Yjk5LWI5MzUtMjFhOTEyNjI0YzJkXzAiLCJDb25maWciOnsibWV0YWRhdGEiOnsibmFtZSI6Im5naW54LWRlcGxveW1lbnQtN2Q4N2Y2ZDk0Yi00ZDdibSIsInVpZCI6IjFlZGMxYzQ5LWFiMGEtNGI5OS1iOTM1LTIxYTkxMjYyNGMyZCIsIm5hbWVzcGFjZSI6ImRlZmF1bHQifSwiaG9zdG5hbWUiOiJuZ2lueC1kZXBsb3ltZW50LTdkODdmNmQ5NGItNGQ3Ym0iLCJsb2dfZGlyZWN0b3J5IjoiL3Zhci9sb2cvcG9kcy9kZWZhdWx0X25naW54LWRlcGxveW1lbnQtN2Q4N2Y2ZDk0Yi00ZDdibV8xZWRjMWM0OS1hYjBhLTRiOTktYjkzNS0yMWE5MTI2MjRjMmQiLCJkbnNfY29uZmlnIjp7InNlcnZlcnMiOlsiMTAuNC4wLjEwIl0sInNlYXJjaGVzIjpbImRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJzdmMuY2x1c3Rlci5sb2NhbCIsImNsdXN0ZXIubG9jYWwiLCJjLnplYWxzLWFuYWx5dGljcy1kZXYuaW50ZXJuYWwiLCJnb29nbGUuaW50ZXJuYWwiXSwib3B0aW9ucyI6WyJuZG90czo1Il19LCJwb3J0X21hcHBpbmdzIjpbeyJjb250YWluZXJfcG9ydCI6ODB9XSwibGFiZWxzIjp7ImFwcCI6Im5naW54IiwiaW8ua3ViZXJuZXRlcy5wb2QubmFtZSI6Im5naW54LWRlcGxveW1lbnQtN2Q4N2Y2ZDk0Yi00ZDdibSIsImlvLmt1YmVybmV0ZXMucG9kLm5hbWVzcGFjZSI6ImRlZmF1bHQiLCJpby5rdWJlcm5ldGVzLnBvZC51aWQiOiIxZWRjMWM0OS1hYjBhLTRiOTktYjkzNS0yMWE5MTI2MjRjMmQiLCJwb2QtdGVtcGxhdGUtaGFzaCI6IjdkODdmNmQ5NGIifSwiYW5ub3RhdGlvbnMiOnsia3ViZXJuZXRlcy5pby9jb25maWcuc2VlbiI6IjIwMjEtMDktMjRUMDQ6Mzg6MjEuMTk5OTU1ODM5WiIsImt1YmVybmV0ZXMuaW8vY29uZmlnLnNvdXJjZSI6ImFwaSJ9LCJsaW51eCI6eyJjZ3JvdXBfcGFyZW50IjoiL2t1YmVwb2RzL2Jlc3RlZmZvcnQvcG9kMWVkYzFjNDktYWIwYS00Yjk5LWI5MzUtMjFhOTEyNjI0YzJkIiwic2VjdXJpdHlfY29udGV4dCI6eyJuYW1lc3BhY2Vfb3B0aW9ucyI6eyJwaWQiOjF9LCJzZWNjb21wX3Byb2ZpbGVfcGF0aCI6InJ1bnRpbWUvZGVmYXVsdCJ9LCJzeXNjdGxzIjp7Im5ldC5jb3JlLnNvbWF4Y29ubiI6IjEwMjQiLCJuZXQuaXB2NC5jb25mLmFsbC5hY2NlcHRfcmVkaXJlY3RzIjoiMCIsIm5ldC5pcHY0LmNvbmYuYWxsLmZvcndhcmRpbmciOiIxIiwibmV0LmlwdjQuY29uZi5hbGwucm91dGVfbG9jYWxuZXQiOiIxIiwibmV0LmlwdjQuY29uZi5kZWZhdWx0LmZvcndhcmRpbmciOiIxIiwibmV0LmlwdjQuaXBfZm9yd2FyZCI6IjEiLCJuZXQuaXB2NC50Y3BfZmluX3RpbWVvdXQiOiI2MCIsIm5ldC5pcHY0LnRjcF9rZWVwYWxpdmVfaW50dmwiOiI2MCIsIm5ldC5pcHY0LnRjcF9rZWVwYWxpdmVfcHJvYmVzIjoiNSIsIm5ldC5pcHY0LnRjcF9rZWVwYWxpdmVfdGltZSI6IjMwMCIsIm5ldC5pcHY0LnRjcF9ybWVtIjoiNDA5NiA4NzM4MCA2MjkxNDU2IiwibmV0LmlwdjQudGNwX3N5bl9yZXRyaWVzIjoiNiIsIm5ldC5pcHY0LnRjcF90d19yZXVzZSI6IjAiLCJuZXQuaXB2NC50Y3Bfd21lbSI6IjQwOTYgMTYzODQgNDE5NDMwNCIsIm5ldC5pcHY0LnVkcF9ybWVtX21pbiI6IjQwOTYiLCJuZXQuaXB2NC51ZHBfd21lbV9taW4iOiI0MDk2IiwibmV0LmlwdjYuY29uZi5kZWZhdWx0LmFjY2VwdF9yYSI6IjAiLCJuZXQubmV0ZmlsdGVyLm5mX2Nvbm50cmFja19nZW5lcmljX3RpbWVvdXQiOiI2MDAiLCJuZXQubmV0ZmlsdGVyLm5mX2Nvbm50cmFja190Y3BfYmVfbGliZXJhbCI6IjEiLCJuZXQubmV0ZmlsdGVyLm5mX2Nvbm50cmFja190Y3BfdGltZW91dF9jbG9zZV93YWl0IjoiMzYwMCIsIm5ldC5uZXRmaWx0ZXIubmZfY29ubnRyYWNrX3RjcF90aW1lb3V0X2VzdGFibGlzaGVkIjoiODY0MDAifX19LCJOZXROU1BhdGgiOiIvdmFyL3J1bi9uZXRucy9jbmktODY0ZjllNTktYjAzYS0zMTRhLTUzNmUtNGQ0OTIwODU1YjVlIiwiSVAiOiIxMC4wLjEuMTQiLCJBZGRpdGlvbmFsSVBzIjpudWxsLCJSdW50aW1lSGFuZGxlciI6IiIsIkNOSVJlc3VsdCI6eyJJbnRlcmZhY2VzIjp7ImV0aDAiOnsiSVBDb25maWdzIjpbeyJJUCI6IjEwLjAuMS4xNCIsIkdhdGV3YXkiOiIxMC4wLjEuMSJ9XSwiTWFjIjoiYjI6MTc6OWI6ZWI6MDY6MGEiLCJTYW5kYm94IjoiL3Zhci9ydW4vbmV0bnMvY25pLTg2NGY5ZTU5LWIwM2EtMzE0YS01MzZlLTRkNDkyMDg1NWI1ZSJ9LCJsbyI6eyJJUENvbmZpZ3MiOlt7IklQIjoiMTI3LjAuMC4xIiwiR2F0ZXdheSI6IiJ9LHsiSVAiOiI6OjEiLCJHYXRld2F5IjoiIn1dLCJNYWMiOiIwMDowMDowMDowMDowMDowMCIsIlNhbmRib3giOiIvdmFyL3J1bi9uZXRucy9jbmktODY0ZjllNTktYjAzYS0zMTRhLTUzNmUtNGQ0OTIwODU1YjVlIn0sInZldGg1MDViMjE2NiI6eyJJUENvbmZpZ3MiOm51bGwsIk1hYyI6IjkyOjY3OjQxOjBlOjY3OjdjIiwiU2FuZGJveCI6IiJ9fSwiRE5TIjpbe30se31dLCJSb3V0ZXMiOlt7ImRzdCI6IjAuMC4wLjAvMCJ9XX0sIlByb2Nlc3NMYWJlbCI6IiJ9fQ=="
  }
}

Marshalize されているようなので、typeurl.UnmarshalAny() で Unmarshal できそうに思うのですが、ビルド時に以下のエラーメッセージが出て使えなさそうです。なぜかわかりません。

cannot use ext["io.cri-containerd.sandbox.metadata"] (type "github.com/gogo/protobuf/types".Any) as type *"github.com/gogo/protobuf/types".Any in argument to typeurl.UnmarshalAny

そこで以下のようにコードを修正してみます。

extensions2.go
package main

import (
    "context"
    "log"
    "fmt"
    "encoding/json"

    "github.com/containerd/containerd"
    "github.com/containerd/cri/pkg/store/container"
)

const (
    address = "/run/containerd/containerd.sock"
    namespace = "k8s.io"
)

type Metadata struct {
    TypeUrl string `json:"type_url"`
    Value   []byte `json:"value"`
}

func main() {
    client, err := containerd.New(
        address,
        containerd.WithDefaultNamespace(namespace),
    )

    if err != nil {
        log.Fatal(err)
    }

    defer client.Close()

    ctx := context.Background()

    containers, _ := client.Containers(ctx)
    for _, c := range containers {
        if c.ID() == "51bd1b3e0e7b3895351482fe93d182ce71bb7b7f245b536bb80d76ff09b304b5" {
            ext, _ := c.Extensions(ctx)
            ext_metadata := ext["io.cri-containerd.sandbox.metadata"]
            ext_metadata_json, _ := json.Marshal(ext_metadata)

            var m Metadata
            err := json.Unmarshal(ext_metadata_json, &m)
            if err != nil {
                log.Fatal(err)
            }
            if m.TypeUrl == "" {
                continue
            }

            var cri_metadata container.Metadata
            err = cri_metadata.UnmarshalJSON(m.Value)
            if err != nil {
                log.Fatal(err)
            }
            cri_md, _ := json.Marshal(cri_metadata)

            fmt.Printf("%s\n", string(cri_md))
        }
    }
}
GOOS=linux GOARCH=amd64 go build extensions2.go
kubectl cp extensions2 $(kubectl get pods -l app=nginx -o jsonpath='{.items[*].metadata.name}'):/root/extensions2
kubectl exec $(kubectl get pods -l app=nginx -o jsonpath='{.items[*].metadata.name}') -- /root/extensions2 | jq '.'
コマンドの結果
{
  "ID": "51bd1b3e0e7b3895351482fe93d182ce71bb7b7f245b536bb80d76ff09b304b5",
  "Name": "nginx-deployment-7d87f6d94b-4d7bm_default_1edc1c49-ab0a-4b99-b935-21a912624c2d_0",
  "SandboxID": "",
  "Config": {
    "metadata": {
      "name": "nginx-deployment-7d87f6d94b-4d7bm"
    },
    "labels": {
      "app": "nginx",
      "io.kubernetes.pod.name": "nginx-deployment-7d87f6d94b-4d7bm",
      "io.kubernetes.pod.namespace": "default",
      "io.kubernetes.pod.uid": "1edc1c49-ab0a-4b99-b935-21a912624c2d",
      "pod-template-hash": "7d87f6d94b"
    },
    "annotations": {
      "kubernetes.io/config.seen": "2021-09-24T04:38:21.199955839Z",
      "kubernetes.io/config.source": "api"
    },
    "linux": {
      "security_context": {
        "namespace_options": {
          "pid": 1
        },
        "seccomp_profile_path": "runtime/default"
      }
    }
  },
  "ImageRef": "",
  "LogPath": "",
  "StopSignal": "",
  "ProcessLabel": ""
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0