Як я можу отримати інформацію про контейнери Docker Linux з самого контейнера?


135

Я хотів би docker containersповідомити про їх конфігурацію, так само, як ви можете отримувати інформацію про екземпляри EC2 за допомогою метаданих.

Я можу використовувати (за умови dockerпрослуховування на порту 4243)

curl http://172.17.42.1:4243/containers/$HOSTNAME/json

щоб отримати деякі свої дані, але хотілося б знати, чи є кращий спосіб принаймні отримати повний ідентифікатор контейнера, оскільки HOSTNAMEвін фактично скорочується до 12 символів, і докер, здається, виконує "найкращу відповідність" на ньому.

Крім того, як я можу отримати зовнішній IP-адресу хокера докера (крім доступу до метаданих EC2, специфічних для AWS)


2
ПОПЕРЕДЖАЙТЕ: ви повинні прочитати цей lvh.io/posts/… перед тим, як спробувати скористатися будь-яким із підходів нижче, що намагаються використовувати /var/run/docker.sock всередині контейнера
гарнітуру

1
У випадку розриву посилання @ harschware я підсумую тут: Надаючи доступ до контейнера /var/run/docker.sock, можна (тривіально) вирватися з вмісту, наданого докером, та отримати доступ до хост-машини. Очевидно, що це потенційно небезпечно.
Іван

1
Хтось знає, як отримати ту саму інформацію в контейнері докера Windows, якщо аргумент --hostname використовувався з командою run, щоб просто запущене ім'я хоста більше не дало вам контейнер?
Тимофі Джон Лард

Відповіді:


68

Я дізнався, що ідентифікатор контейнера можна знайти в / proc / self / cgroup

Таким чином, ви можете отримати ідентифікатор за допомогою:

cat /proc/self/cgroup | grep -o  -e "docker-.*.scope" | head -n 1 | sed "s/docker-\(.*\).scope/\\1/"

15
Довелося трохи її підправити, це працює для мене в Docker 1.4.1 cat /proc/self/cgroup | grep "docker" | sed s/\\//\\n/g | tail -1
ICas

5
Для докера 1.6.2 мені довелося скористатися:cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1
Джей Тейлор

14
Aaaaand Docker 1,12:cat /proc/1/cgroup | grep 'docker/' | tail -1 | sed 's/^.*\///' | cut -c 1-12
smets.kevin

24
Мені подобається basename "$(cat /proc/1/cpuset)"іbasename "$(head /proc/1/cgroup)"
madeddie

3
Надалі, якщо в docker будуть використані простір імен cgroup та cgroup v2, цей метод може більше не працювати.
Jing Qiu

69

Якщо не буде замінено, ім'я хоста, здається, є коротким ідентифікатором контейнера в Docker 1.12

root@d2258e6dec11:/project# cat /etc/hostname
d2258e6dec11

Зовнішньо

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED                 STATUS                      PORTS               NAMES
d2258e6dec11        300518d26271        "bash"              5 minutes ago       

$ docker -v
Docker version 1.12.0, build 8eab29e, experimental

4
Але це дозволило легко перетягувати інформацію в nodejs для мене. const os = require('os'); console.log(os.hostname());
pulkitsinghal

2
Щоб отримати ім'я хоста, яке відповідає ID контейнера на Java, використовуйте InetAddress.getLocalHost().getHostName().
Натан

2
Іноді простіше читати значення змінної середовища $HOSTNAME(наприклад, у скриптах оболонки).
Faheel

34

Ви можете спілкуватися з докером зсередини контейнера за допомогою unix socket через Docker Remote API:

https://docs.docker.com/engine/reference/api/docker_remote_api/

У контейнері ви можете дізнатися скорочений ідентифікатор докера, вивчивши $HOSTNAMEenv var. За словами доктора, є малий шанс зіткнення, я думаю, що за невеликої кількості контейнера вам не доведеться турбуватися про це. Я не знаю, як отримати повний ідентифікатор безпосередньо.

Ви можете оглянути контейнер подібним чином, як зазначено у відповіді banyan :

GET /containers/4abbef615af7/json HTTP/1.1

Відповідь:

HTTP/1.1 200 OK
Content-Type: application/json

{
         "Id": "4abbef615af7......  ",
         "Created": "2013.....",
         ...
}

Крім того, ви можете перенести ідентифікатор докера в контейнер у файлі. Файл розміщений на "встановленому томі", тому його передають у контейнер:

docker run -t -i -cidfile /mydir/host1.txt -v /mydir:/mydir ubuntu /bin/bash

Ідентифікатор докера (скорочений) буде у файлі /mydir/host1.txt у контейнері.


2
Дякую, але це той самий підхід, який я використовую в будь-якому випадку, і він порушиться, якщо ви встановите ім'я хоста з -h, коли ви запускаєте docker.
Алессандро

@Alessandro Я додав інформацію про параметр -cidfile до запуску докера. Це може допомогти вам передати ідентифікатор докера до контейнера замість використання $ HOSTNAME.
Іржі

Чудово! Так, я можу використати! Дякую!
Алессандро

Як не дивно, в 1.11.2, здається env, не перераховується HOSTNAME, але echo $HOSTNAMEпрацює.
Джессі Глік

Це взагалі не працює, і ваша URL-адреса зламана, і тепер переспрямовується на неправильну документацію. requests.exceptions.MissingSchema: Invalid URL '/containers/1d26a841bf07/json': No schema supplied. Perhaps you meant http:///containers/1d26a841bf07/json?
Серін

24

Це отримає повний ідентифікатор контейнера всередині контейнера:

cat /proc/self/cgroup | grep "cpu:/" | sed 's/\([0-9]\):cpu:\/docker\///g'


21

ПОПЕРЕДЖЕННЯ. Ви повинні зрозуміти ризики безпеки цього методу, перш ніж його розглядати. Зведення ризику Джона :

Надаючи доступ контейнеру до /var/run/docker.sockнього, [тривіально легко] вирватися з вмісту, який надає докер і отримати доступ до хост-машини. Очевидно, що це потенційно небезпечно.


Всередині контейнера dockerId - ваше ім'я хоста. Отже, ви могли:

  • встановіть пакет docker-io у свій контейнер з тією ж версією, що і хост
  • почніть з цього --volume /var/run/docker.sock:/var/run/docker.sock --privileged
  • нарешті, запустіть: docker inspect $(hostname)всередині контейнера

Уникайте цього. Робіть це лише в тому випадку, якщо ви розумієте ризики і чітко пом'якшуєте ризики.


1
Я підозрюю, що це не спрацює, якщо --hostnameбула використана опція запуску докера .
hairyhenderson

Якщо --hostnameвстановлено, ви можете використовувати комбінацію з цієї відповіді та коментаря @Jay Taylor у прийнятій відповіді: docker inspect $(cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1)щоб отримати всю інформацію про запущений контейнер.
Майкл К.

Ви можете покласти посилання на docker-io?
Бред П.

Я припускаю, що його npmjs.com/package/docker-io, але саме це мені сказало Google, і, можливо, це не те, що ви мали на увазі.
Бред П.

15

Щоб зробити це просто,

  1. Ідентифікатор контейнера - ваше ім’я хоста всередині докера
  2. Інформація про контейнери доступна всередині / proc / self / cgroup

Щоб отримати ім'я хоста,

hostname

або

uname -n

або

cat /etc/host

Вихід можна переспрямувати на будь-який файл і прочитати назад із програми Напр .: # hostname > /usr/src//hostname.txt


10

Я виявив, що в 17.09 є найпростіший спосіб зробити це в контейнері docker:

$ cat /proc/self/cgroup | head -n 1 | cut -d '/' -f3
4de1c09d3f1979147cd5672571b69abec03d606afcc7bdc54ddb2b69dec3861c

Або, як вже було сказано, коротша версія з

$ cat /etc/hostname
4de1c09d3f19

Або просто:

$ hostname
4de1c09d3f19

6

Docker встановлює ім'я хоста за ідентифікатором контейнера за замовчуванням, але користувачі можуть його замінити --hostname. Замість цього перевірте /proc:

$ more /proc/self/cgroup
14:name=systemd:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
13:pids:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
12:hugetlb:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
11:net_prio:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
10:perf_event:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
9:net_cls:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
8:freezer:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
7:devices:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
6:memory:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
5:blkio:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
4:cpuacct:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
3:cpu:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
2:cpuset:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
1:name=openrc:/docker

Ось зручний однолінійний інструмент для вилучення ідентифікатора контейнера:

$ grep "memory:/" < /proc/self/cgroup | sed 's|.*/||'
7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605

2

Ви можете використовувати цей командний рядок для ідентифікації поточного ідентифікатора контейнера (протестовано за допомогою докера 1.9).

awk -F"-|/." '/1:/ {print $3}' /proc/self/cgroup

Потім невеликий запит до API Docker (ви можете поділитися /var/run/docker.sock), щоб отримати всю інформацію.


1
awk -F "- | /." '/ 1: / {print $ 3}' / proc / self / cgroup
usil

2

Деякі опубліковані рішення перестали працювати через зміни формату /proc/self/cgroup. Ось одна команда grep GNU, яка має бути трохи надійнішою для форматування змін:

grep -o -P -m1 'docker.*\K[0-9a-f]{64,}' /proc/self/cgroup

Для довідки, ось фрагменти / proc / self / cgroup з внутрішніх контейнерів docker, які були протестовані за допомогою цієї команди:

Linux 4.4:

11:pids:/system.slice/docker-cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411.scope
...
1:name=systemd:/system.slice/docker-cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411.scope

Linux 4.8 - 4.13:

11:hugetlb:/docker/afe96d48db6d2c19585572f986fc310c92421a3dac28310e847566fb82166013
...
1:name=systemd:/docker/afe96d48db6d2c19585572f986fc310c92421a3dac28310e847566fb82166013


0

На відміну, якщо у вас є pid контейнера і ви хочете отримати ідентифікатор docker цього контейнера, хорошим способом є використання nsenter у поєднанні з магією sed вище:

nsenter -n -m -t pid -- cat /proc/1/cgroup | grep -o -e "docker-.*.scope" | head -n 1 | sed "s/docker-\(.*\).scope/\\1/"


-19

Використовуйте docker inspect.

$ docker ps # get conteiner id
$ docker inspect 4abbef615af7
[{
    "ID": "4abbef615af780f24991ccdca946cd50d2422e75f53fb15f578e14167c365989",
    "Created": "2014-01-08T07:13:32.765612597Z",
    "Path": "/bin/bash",
    "Args": [
        "-c",
        "/start web"
    ],
    "Config": {
        "Hostname": "4abbef615af7",
...

Можна отримати ip наступним чином.

$ docker inspect -format="{{ .NetworkSettings.IPAddress }}" 2a5624c52119
172.17.0.24

5
Це я не маю на увазі. Мені потрібно мати можливість отримати цю інформацію зсередини контейнера. В основному мені потрібен спосіб зрозуміти ідентифікатор контейнера, який я запускаю зсередини.
Алессандро
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.