Search code examples
dockerkubernetesgoogle-kubernetes-enginegcloud

GKE: get a command which pod is running


Is there a way to get a command and image which the pod is running in GKE? To my knowledge kubectl does not have this facility. Maybe it's possible to do so with some dedicated gcloud tool? docker ps, kubectl exec ps is not an option unfortunately.


Solution

  • kubectl gives you a variety of options, among those is describe, which let's you get the information you are looking for like so:

    $ kubectl describe pods etcd-minikube
    Name:                 etcd-minikube
    Namespace:            kube-system
    Priority:             2000001000
    Priority Class Name:  system-node-critical
    Node:                 minikube/192.168.49.2
    Start Time:           Fri, 21 Apr 2023 14:57:11 +0200
    Labels:               component=etcd
                          tier=control-plane
    Annotations:          kubeadm.kubernetes.io/etcd.advertise-client-urls: https://192.168.49.2:2379
                          kubernetes.io/config.hash: 9d3d310935e5fabe942511eec3e2cd0c
                          kubernetes.io/config.mirror: 9d3d310935e5fabe942511eec3e2cd0c
                          kubernetes.io/config.seen: 2023-04-21T12:57:10.854200840Z
                          kubernetes.io/config.source: file
                          seccomp.security.alpha.kubernetes.io/pod: runtime/default
    Status:               Running
    SeccompProfile:       RuntimeDefault
    IP:                   192.168.49.2
    IPs:
      IP:           192.168.49.2
    Controlled By:  Node/minikube
    Containers:
      etcd:
        Container ID:  docker://172b7490d79dcb36f2c81e3ce82611b18c09f128b5030c7b225636b345d5c7d4
        Image:         k8s.gcr.io/etcd:3.5.1-0
        Image ID:      docker-pullable://k8s.gcr.io/etcd@sha256:64b9ea357325d5db9f8a723dcf503b5a449177b17ac87d69481e126bb724c263
        Port:          <none>
        Host Port:     <none>
        Command:
          etcd
          --advertise-client-urls=https://192.168.49.2:2379
          --cert-file=/var/lib/minikube/certs/etcd/server.crt
          --client-cert-auth=true
          --data-dir=/var/lib/minikube/etcd
          --initial-advertise-peer-urls=https://192.168.49.2:2380
          --initial-cluster=minikube=https://192.168.49.2:2380
          --key-file=/var/lib/minikube/certs/etcd/server.key
          --listen-client-urls=https://127.0.0.1:2379,https://192.168.49.2:2379
          --listen-metrics-urls=http://127.0.0.1:2381
          --listen-peer-urls=https://192.168.49.2:2380
          --name=minikube
          --peer-cert-file=/var/lib/minikube/certs/etcd/peer.crt
          --peer-client-cert-auth=true
          --peer-key-file=/var/lib/minikube/certs/etcd/peer.key
          --peer-trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt
          --proxy-refresh-interval=70000
          --snapshot-count=10000
          --trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt
    

    If you need to access things programmatically, you can also use get and json format the output to then pipe into utilities like jq like so:

    $ kubectl get pod etcd-minikube -o json
    {
        "apiVersion": "v1",
        "kind": "Pod",
        "metadata": {
            "annotations": {
                "kubeadm.kubernetes.io/etcd.advertise-client-urls": "https://192.168.49.2:2379",
                "kubernetes.io/config.hash": "9d3d310935e5fabe942511eec3e2cd0c",
                "kubernetes.io/config.mirror": "9d3d310935e5fabe942511eec3e2cd0c",
                "kubernetes.io/config.seen": "2023-04-21T12:57:10.854200840Z",
                "kubernetes.io/config.source": "file",
                "seccomp.security.alpha.kubernetes.io/pod": "runtime/default"
            },
            "creationTimestamp": "2023-04-21T12:57:11Z",
            "labels": {
                "component": "etcd",
                "tier": "control-plane"
            },
            "name": "etcd-minikube",
            "namespace": "kube-system",
            "ownerReferences": [
                {
                    "apiVersion": "v1",
                    "controller": true,
                    "kind": "Node",
                    "name": "minikube",
                    "uid": "cfe42b77-7cfc-4248-af39-1dec62196242"
                }
            ],
            "resourceVersion": "294",
            "uid": "58dced46-2ac0-4986-bced-5e7f9a097cf9"
        },
        "spec": {
            "containers": [
                {
                    "command": [
                        "etcd",
                        "--advertise-client-urls=https://192.168.49.2:2379",
                        "--cert-file=/var/lib/minikube/certs/etcd/server.crt",
                        "--client-cert-auth=true",
                        "--data-dir=/var/lib/minikube/etcd",
                        "--initial-advertise-peer-urls=https://192.168.49.2:2380",
                        "--initial-cluster=minikube=https://192.168.49.2:2380",
                        "--key-file=/var/lib/minikube/certs/etcd/server.key",
                        "--listen-client-urls=https://127.0.0.1:2379,https://192.168.49.2:2379",
                        "--listen-metrics-urls=http://127.0.0.1:2381",
                        "--listen-peer-urls=https://192.168.49.2:2380",
                        "--name=minikube",
                        "--peer-cert-file=/var/lib/minikube/certs/etcd/peer.crt",
                        "--peer-client-cert-auth=true",
                        "--peer-key-file=/var/lib/minikube/certs/etcd/peer.key",
                        "--peer-trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt",
                        "--proxy-refresh-interval=70000",
                        "--snapshot-count=10000",
                        "--trusted-ca-file=/var/lib/minikube/certs/etcd/ca.crt"
                    ],
    

    If for a given image that a pod uses, you would like to get the command of the actual container image and not the one that is passed via its spec, you can use the information about the image and then docker inspect. The following image is deployed as per the kubernetes documentation, so it does not have a command in the spec but still runs nginx.

    Get the right pods (they are both the same in our case)

    $ kubectl get pods | grep nginx
    nginx-deployment-9456bbbf9-gqzhp   1/1     Running   0             10m
    nginx-deployment-9456bbbf9-lthrc   1/1     Running   0             10m
    

    Use one of them and get the container image:

    $ kubectl get pod nginx-deployment-9456bbbf9-gqzhp -o jsonpath="{.spec.containers[*].image}"
    nginx:1.14.2
    

    Use docker image inspect to analyze the image (not that you have to have it pulled)

    $ docker pull nginx:1.14.2
    1.14.2: Pulling from library/nginx
    007027d142c8: Pull complete
    925342e1fcde: Pull complete
    668b9ac9804b: Pull complete
    Digest: sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
    Status: Downloaded newer image for nginx:1.14.2
    docker.io/library/nginx:1.14.2
    
    $ docker image inspect nginx:1.14.2
    [
        {
            "Id": "sha256:7bbc8783b8ecfdb6453396805cc0fb5fcdaf1b16cbb907c8ab1b8685732d50a4",
            "RepoTags": [
                "nginx:1.14.2"
            ],
            "RepoDigests": [
                "nginx@sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d"
            ],
            "Parent": "",
            "Comment": "",
            "Created": "2019-03-27T09:51:29.346495571Z",
            "Container": "877b55d528f890d650358f37048a361f24b8c4d1e414c79e4d2c82bb8d186310",
            "ContainerConfig": {
                "Hostname": "877b55d528f8",
                "Domainname": "",
                "User": "",
                "AttachStdin": false,
                "AttachStdout": false,
                "AttachStderr": false,
                "ExposedPorts": {
                    "80/tcp": {}
                },
                "Tty": false,
                "OpenStdin": false,
                "StdinOnce": false,
                "Env": [
                    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                    "NGINX_VERSION=1.14.2-1~stretch",
                    "NJS_VERSION=1.14.2.0.2.6-1~stretch"
                ],
                "Cmd": [
                    "/bin/sh",
                    "-c",
                    "#(nop) ",
                    "CMD [\"nginx\" \"-g\" \"daemon off;\"]"
    

    Now make it a one-line using jq:

    $ docker pull $(kubectl get pod nginx-deployment-9456bbbf9-gqzhp -o jsonpath="{.spec.containers[*].image}") && docker image inspect $(kubectl get pod nginx-deployment-9456bbbf9-gqzhp -o jsonpath="{.spec.containers[*].image}") | jq .[].ContainerConfig.Cmd
    1.14.2: Pulling from library/nginx
    Digest: sha256:f7988fb6c02e0ce69257d9bd9cf37ae20a60f1df7563c3a2a6abe24160306b8d
    Status: Image is up to date for nginx:1.14.2
    docker.io/library/nginx:1.14.2
    [
      "/bin/sh",
      "-c",
      "#(nop) ",
      "CMD [\"nginx\" \"-g\" \"daemon off;\"]"
    ]