Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to get the container id in pod? #50309

Closed
Bobi-zhou opened this issue Aug 8, 2017 · 43 comments
Closed

how to get the container id in pod? #50309

Bobi-zhou opened this issue Aug 8, 2017 · 43 comments
Labels
sig/node Categorizes an issue or PR as relevant to SIG Node.

Comments

@Bobi-zhou
Copy link

i want to get the container info in my pod,i tried to inject data into env but failed,it tips:

* spec.template.spec.containers[0].env[0].valueFrom.fieldRef.fieldPath: Invalid value: "status.containerStatuses[0].containerID": error converting fieldPath: field label not supported: status.containerStatuses[0].containerID

how to get it?

@k8s-github-robot k8s-github-robot added the needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. label Aug 8, 2017
@drinktee
Copy link
Contributor

drinktee commented Aug 8, 2017

You can access the kubernetes api in pod. Pod's name is in env. And containerID is in containerStatuses.

@Bobi-zhou
Copy link
Author

@drinktee how to access the kubernetes api in shell?

@dixudx
Copy link
Member

dixudx commented Aug 8, 2017

@Bobi-zhou
Copy link
Author

@dixudx yup,but supported values:metadata.name, metadata.namespace, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP;
Unsupported value status.containerStatuses[0].containerID

@xiangpengzhao
Copy link
Contributor

/sig api-machinery node

@k8s-ci-robot k8s-ci-robot added sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/node Categorizes an issue or PR as relevant to SIG Node. labels Aug 9, 2017
@k8s-github-robot k8s-github-robot removed the needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. label Aug 9, 2017
@drinktee
Copy link
Contributor

drinktee commented Aug 9, 2017

@caesarxuchao caesarxuchao removed the sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. label Aug 9, 2017
@StevenACoffman
Copy link
Contributor

@Bobi-zhou you can pull in the pod's namespace and name as environment variables using what's called the "Downward API", adding a field on the container like:

env:
    - name: MY_POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name

@fejta-bot
Copy link

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Mar 15, 2018
@gpoirier
Copy link

So is it not possible to get that container ID?

@arunkumar9050
Copy link

I am running 3 kafka pods in statefulsets. if i give metadata.name in the place of fieldpath, then i will get kafka-0,kafka-1,kafka-2 for three pods.. How can i get just the ID instead of whole name? (i.e. 0,1,2)
env:
- name: ID
valueFrom:
fieldRef:
fieldPath: ????

@4c74356b41
Copy link

4c74356b41 commented May 3, 2018

@arunkumar9050 I think you can't (according to this)

@fejta-bot
Copy link

Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle rotten
/remove-lifecycle stale

@k8s-ci-robot k8s-ci-robot added lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. and removed lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. labels Jun 2, 2018
@fejta-bot
Copy link

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/close

@integrii
Copy link

integrii commented Jul 6, 2018

This is an incredibly huge workaround, but I was able to get the container IDs with the following:

  • Put a cAdvisor daemonset in the cluster
  • Setup a cAdvisor service with externalTrafficPolicy: Local set
  • Use the downwards API to expose the pod's name as an environment variable
  • From the program, query the cAdvisor service URL for all containers (you get all containers on your node because of the external traffic policy)
  • From the list of containers, find those with the annotation "io.kubernetes.pod.name": "POD_NAME",
  • Fetch the ID of the container from the cAdvisor information in the object

I was able to put this all together in order to create a metrics tracking system that has up to the second metrics for containers and pods.

@integrii
Copy link

integrii commented Jul 6, 2018

For my situation, I was actually just looking to call the cAdvisor API to get stats on pods rapidly. I needed the docker container name to do that, which is not the metadata.uid.

I think this issue was created to find container IDs, which is also not metadata.uid. Thanks for looking, though!

@dims
Copy link
Member

dims commented Jul 6, 2018

ah thanks @integrii

@chrissnell
Copy link

Did anybody ever figure this out? I'm trying to debug some short-lived Job containers that are crashing and I need to be able to log the container ID from within the job in order to correlate it with Docker logs.

@wtan825
Copy link

wtan825 commented Dec 13, 2018

So is it not possible to get that container ID? I want to collect stdout logs by using fluent-bit as a sidecar mode. So I need the app's container ID.

@TylerEady
Copy link

So is it not possible to get that container ID? I want to collect stdout logs by using fluent-bit as a sidecar mode. So I need the app's container ID.

Did you get anywhere with this i am trying to do the same?

@wtan825
Copy link

wtan825 commented May 5, 2019

So is it not possible to get that container ID? I want to collect stdout logs by using fluent-bit as a sidecar mode. So I need the app's container ID.

Did you get anywhere with this i am trying to do the same?

Eventually,I gave up using container ID. Instead, I used the soft link path "/var/log/pods/${POD_UID}/{{$ContainerName}}/*.log", and I mount the following directories to main Container:
ubuntu
/var/log // /var/log/pods->/data/docker/containers
/data/docker/containers
CentOS
/var/log // /var/log/pods->/var/lib/docker/containers
/var/lib/docker/containers

@mitar
Copy link
Contributor

mitar commented Jul 19, 2019

/reopen
/remove-lifecycle rotten

@k8s-ci-robot
Copy link
Contributor

@mitar: You can't reopen an issue/PR unless you authored it or you are a collaborator.

In response to this:

/reopen
/remove-lifecycle rotten

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot k8s-ci-robot removed the lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. label Jul 19, 2019
@mitar
Copy link
Contributor

mitar commented Jul 19, 2019

I would like to access status.containerStatuses[0].imageID but it seems this is not possible.

@mitar
Copy link
Contributor

mitar commented Jul 19, 2019

I opened #80346 for imageID.

@samos123
Copy link

The container ID and image ID are available locally on each node using the kubelet apiserver that exposes the following endpoint: localhost:10255/pods. You can query this endpoint from a pod as well depending on your environment.

@mitar
Copy link
Contributor

mitar commented Jan 6, 2020

But how does pod know how to find itself on the apiserver?

@samos123
Copy link

samos123 commented Jan 7, 2020

That's a good question :) it doesn't know so guess my response isn't useful in that case. It would assume the executing pod knows it's own pod name.

@mitar
Copy link
Contributor

mitar commented Jan 7, 2020

Name maybe, but not ID?

@DevasiaThomas
Copy link

DevasiaThomas commented Jan 7, 2020

Here is something that I cooked up, works on my k8 installation. Does the below work for you guys?

kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{"pod: "}{.metadata.name}{"\n"}{range .status.containerStatuses[*]}{"\tname: "}{.containerID}{"\n\timage: "}{.image}{"\n"}{end}'

[root@gtfo-master ~]# kubectl version Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:18:23Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:09:08Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}
[root@gtfo-master ~]# kubectl api-versions admissionregistration.k8s.io/v1 admissionregistration.k8s.io/v1beta1 apiextensions.k8s.io/v1 apiextensions.k8s.io/v1beta1 apiregistration.k8s.io/v1 apiregistration.k8s.io/v1beta1 apps/v1 authentication.k8s.io/v1 authentication.k8s.io/v1beta1 authorization.k8s.io/v1 authorization.k8s.io/v1beta1 autoscaling/v1 autoscaling/v2beta1 autoscaling/v2beta2 batch/v1 batch/v1beta1 certificates.k8s.io/v1beta1 coordination.k8s.io/v1 coordination.k8s.io/v1beta1 crd.projectcalico.org/v1 events.k8s.io/v1beta1 extensions/v1beta1 networking.k8s.io/v1 networking.k8s.io/v1beta1 node.k8s.io/v1beta1 policy/v1beta1 rbac.authorization.k8s.io/v1 rbac.authorization.k8s.io/v1beta1 scheduling.k8s.io/v1 scheduling.k8s.io/v1beta1 storage.k8s.io/v1 storage.k8s.io/v1beta1 v1

@DevasiaThomas
Copy link

Oh, you want to get the container ID within a process running in the container? If you can mount the docker.sock file you can access the docker api through that. If you just want the container id and nothing else /proc/self/cgroup should have a line that begins with docker followed by a string that contains the ID.

@mitar
Copy link
Contributor

mitar commented Jan 8, 2020

So I can use container ID to resolve to the pod ID using the Kubernetes API?

@DevasiaThomas
Copy link

@mitar I'm not sure about that. From a higher layer perspective, getting info about lower layers is feasible and logical. The other way around is the opposite of that. As a container there is no guarantee of understanding what your outer environment is, apart from the outer layers exposing info to the lower layer (The downward api) - mounting files is an example of that.

@mitar
Copy link
Contributor

mitar commented Jan 8, 2020

Yes, so I think the question is what all is exposed through downward API. I opened #80346 for imageID, for example.

@shaoner
Copy link

shaoner commented May 31, 2020

docker sets HOSTNAME automatically, and this matches the container's name usually, so if you need a unique id for your container, you can probably use this along with the namespace i guess

@lpgc
Copy link

lpgc commented Apr 1, 2021

its truly inconceivable to me that the Open Container Initiative specs do not provide any mechanism for processes within a container context to portably obtain either their image or container id ... both of which are INCREDIBLY useful even just for the purposes of logging and tracing ....

@CharlieReitzel
Copy link

docker sets HOSTNAME automatically, and this matches the container's name usually, so if you need a unique id for your container, you can probably use this along with the namespace i guess

I'm seeing $HOSTNAME matches the Pod name (vs. container). But, if metadata can be used to create an environment variable of your choosing (based on discussion above), would the following work?

env:
    - name: MY_CONTAINER_ID
      valueFrom:
        fieldRef:
          fieldPath: metadata.uid

@larry-cable
Copy link

docker sets HOSTNAME automatically, and this matches the container's name usually, so if you need a unique id for your container, you can probably use this along with the namespace i guess

I'm seeing $HOSTNAME matches the Pod name (vs. container). But, if metadata can be used to create an environment variable of your choosing (based on discussion above), would the following work?

env:
    - name: MY_CONTAINER_ID
      valueFrom:
        fieldRef:
          fieldPath: metadata.uid

Hi @CharlieReitzel @alexlren thanks for the suggestions, however I do not wish to rely upon implementation convention for this, since that is not a reliable API commitment that the Java platform could rely upon.

@sai-kolluru
Copy link

sai-kolluru commented Jul 14, 2021

There's no direct method for this, but I found a dirty hack. proc fs exposes cgroups of a process under /proc/self/cgroup file.

> cat /proc/self/cgroup
11:cpuset:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
10:devices:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
9:hugetlb:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
8:perf_event:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
7:blkio:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
6:memory:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
5:freezer:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
4:net_cls,net_prio:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
3:pids:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
2:cpu,cpuacct:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
1:name=systemd:/kubepods/burstable/pod35b82523-06c1-48e7-9e61-2521a89b703b/b5fa49123b796b99fe605af0f8d019f3b3a8cb445b529b892e0d3788682469af
0::/

kubernetes follows a convention for creating a cgroup directory,

/kubepods/<qos>/pod<pod-id>/<containerId>

With some shell scripting foo you can extract the containerId of a running process.

EDIT This wont work if kubernetes creates every container in its own cgroup namespace. Just learnt that runc and moby already support this feature for sometime now. I dont know if kubernetes also had this support.

@XSAM
Copy link

XSAM commented Jan 13, 2022

its truly inconceivable to me that the Open Container Initiative specs do not provide any mechanism for processes within a container context to portably obtain either their image or container id ... both of which are INCREDIBLY useful even just for the purposes of logging and tracing ....

I totally agree with you @lpgc. I am trying to solve this problem by making an OCI specification for fetching container id within the container. Here is the comment.

@ohads-MSFT
Copy link

ohads-MSFT commented Feb 22, 2023

The container ID and image ID are available locally on each node using the kubelet apiserver that exposes the following endpoint: localhost:10255/pods. You can query this endpoint from a pod as well depending on your environment.

This won't help when you're running inside the container - as @DevasiaThomas mentioned above, you'd need to mount docker.sock to access this API which is bad for security (especially if you don't use auth/z which adds yet another complication)...

@larry-cable
Copy link

The container ID and image ID are available locally on each node using the kubelet apiserver that exposes the following endpoint: localhost:10255/pods. You can query this endpoint from a pod as well depending on your environment.

This won't help when you're running inside the container - as @DevasiaThomas mentioned above, you'd need to mount docker.sock to access this API which is bad for security (especially if you don't use auth/z which adds yet another complication)...

thanks, again this is not suitable for something like the JVM to depend upon in order to capture container and image id and expose that to application code therein.

this needs to be "standardized" preferably such that it functions regardless of which container engine r/t or OS is hosting

@mac2000
Copy link

mac2000 commented Feb 18, 2024

In my case - i want to get image - aka nginx:alpine here is what I have ended up (not pretty, little bit overcomplicated, BUT, will allow to get any info, just wanna save it for future reference)

Here is an deployment definition:

deployment.yaml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mactemp
  namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: mactemp
  namespace: production
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: mactemp
  namespace: production
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: mactemp
subjects:
  - kind: ServiceAccount
    name: mactemp
    namespace: production
---
# https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mactemp
  namespace: production
  labels:
    app: mactemp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mactemp
  template:
    metadata:
      labels:
        app: mactemp
    spec:
      serviceAccountName: mactemp
      containers:
        - name: mactemp
          image: nginx:alpine
          ports:
            - containerPort: 80
          resources:
            requests:
              memory: "64Mi"
              cpu: "10m"
            limits:
              memory: "128Mi"
              cpu: "500m"
          # https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/
          env:
            # # ANY COMBINATIONS OF FOLLOWING ARE NOT WOKRING
            # - name: MY_IMAGE
            #   valueFrom:
            #     fieldRef:
            #       fieldPath: spec.containers[0].image
            - name: MY_NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: MY_POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: MY_POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: MY_POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: MY_POD_SERVICE_ACCOUNT
              valueFrom:
                fieldRef:
                  fieldPath: spec.serviceAccountName
            - name: MY_MEM_REQUEST
              valueFrom:
                resourceFieldRef:
                  containerName: mactemp
                  resource: requests.memory
            - name: MY_MEM_LIMIT
              valueFrom:
                resourceFieldRef:
                  containerName: mactemp
                  resource: limits.memory

there is nothing special inside deployment itselft, the difference is that we are going to run our deployment with dedicated service account that is binded to a role with privileges to talk to kubernetes api

from now one, inside the pod we can do:

curl "https://$KUBERNETES_SERVICE_HOST/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods/$(echo $HOSTNAME)" \
  --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
  -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"

which will give us access to anything we want

notes:

  • /var/run/secrets/kubernetes.io/serviceaccount/ will contain everything we need for us to talk to api
  • by default $HOSTNAME is our pod name
  • role rules can be restricted even further if needed

the good and bad part here is that it is little bit overcomplicated, but sooner or later, dedicated service accounts will be needed so why not just start using that

and if thats critical to have it as environment we always can play with init containers - aka inside init container start and container with our service account, talk to api, get wanted info, store it in file which will be accessible in the pod

even more complex workwaround will be to use admission webhook that will just modify spec before its being applied but it is way beyond the scope

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sig/node Categorizes an issue or PR as relevant to SIG Node.
Projects
None yet
Development

No branches or pull requests