Làm cách nào tôi có thể lấy thông tin bộ chứa Docker Linux từ bên trong bộ chứa?


135

Tôi muốn làm cho tôi docker containersbiết về cấu hình của họ, giống như cách bạn có thể nhận thông tin về các phiên bản EC2 thông qua siêu dữ liệu.

Tôi có thể sử dụng (với điều kiện dockerlà nghe trên cổng 4243)

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

để có được một số dữ liệu của nó, nhưng muốn biết liệu có cách nào tốt hơn ít nhất là lấy ID đầy đủ của container không, bởi vì HOSTNAMEthực sự được rút ngắn xuống còn 12 ký tự và docker dường như thực hiện "kết hợp tốt nhất" trên đó.

Ngoài ra, làm cách nào tôi có thể nhận IP bên ngoài của máy chủ docker (ngoài việc truy cập siêu dữ liệu EC2, dành riêng cho AWS)


2
THƯỞNG: bạn nên đọc lvh.io/posts/ này trước khi thử bất kỳ cách tiếp cận nào dưới đây để sử dụng /var/run/docker.sock bên trong container
harschware

1
Trong trường hợp liên kết của @ harschware bị phá vỡ, tôi sẽ tóm tắt ở đây: Bằng cách cấp cho bộ chứa quyền truy cập /var/run/docker.sock, có thể (tầm thường) thoát ra khỏi ngăn chặn được cung cấp bởi docker và có quyền truy cập vào máy chủ. Rõ ràng điều này có khả năng nguy hiểm.
Giăng

1
Có ai biết làm thế nào để có được thông tin tương tự trong bộ chứa docker của windows nếu đối số --hostname được sử dụng với lệnh run để việc chạy 'hostname' không còn cung cấp cho bạn containerid không?
Timothy John Laird

Câu trả lời:


68

Tôi đã phát hiện ra rằng id container có thể được tìm thấy trong / Proc / self / cgroup

Vì vậy, bạn có thể lấy id với:

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

15
Phải điều chỉnh nó một chút, điều này hoạt động với tôi trong Docker 1.4.1 cat /proc/self/cgroup | grep "docker" | sed s/\\//\\n/g | tail -1
ICas

5
Đối với docker 1.6.2 tôi phải sử dụng:cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1
Jay Taylor

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

24
Tôi thích basename "$(cat /proc/1/cpuset)"basename "$(head /proc/1/cgroup)"
madeddie

3
Trong tương lai, nếu không gian tên cgroup và cgroup v2 được sử dụng trong docker, phương thức này có thể không hoạt động nữa.
Jing Qiu

69

Trừ khi bị ghi đè, tên máy chủ dường như là id container ngắn trong Docker 1.12

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

Bên ngoài

$ 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
Yup điều này làm cho nó dễ dàng để kéo thông tin trong nodejs cho tôi. const os = require('os'); console.log(os.hostname());
pulkitsinghal

2
Để có được tên máy chủ phù hợp với Id Container trong Java, hãy sử dụng InetAddress.getLocalHost().getHostName().
Nathan

2
Đôi khi việc đọc giá trị của biến môi trường đơn giản hơn $HOSTNAME(ví dụ trong tập lệnh shell).
Faheel

34

Bạn có thể giao tiếp với docker từ bên trong một container bằng cách sử dụng socket unix thông qua Docker Remote API:

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

Trong một container, bạn có thể tìm ra id docker rút gọn bằng cách kiểm tra $HOSTNAMEenv var. Theo doc, có một cơ hội va chạm nhỏ, tôi nghĩ rằng đối với số lượng container nhỏ, bạn không phải lo lắng về điều đó. Tôi không biết làm thế nào để có được id đầy đủ trực tiếp.

Bạn có thể kiểm tra container theo cách tương tự như được nêu trong câu trả lời của Banyan :

GET /containers/4abbef615af7/json HTTP/1.1

Phản ứng:

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

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

Ngoài ra, bạn có thể chuyển id docker sang container trong một tệp. Các tập tin được đặt trên "khối lượng gắn kết" để nó được chuyển đến container:

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

Id docker (rút ngắn) sẽ có trong tệp /mydir/host1.txt trong vùng chứa.


2
Cảm ơn nhưng dù sao đây cũng là cách tiếp cận tôi đang sử dụng và sẽ bị hỏng nếu bạn đặt tên máy chủ với -h khi bạn chạy docker.
Alessandro

@Alessandro Tôi đã thêm thông tin về tham số -cidfile để chạy docker. Nó có thể giúp bạn chuyển id docker vào container thay vì sử dụng $ HOSTNAME.
Jiri

Tuyệt quá! Vâng, đó là thứ tôi có thể sử dụng! Cảm ơn bạn!
Alessandro

Điều kỳ lạ là, trong 1.11.2 có vẻ như envkhông liệt kê HOSTNAME, nhưng echo $HOSTNAMEhoạt động.
Jesse Glick

Điều này hoàn toàn không hoạt động và URL của bạn bị hỏng và hiện chuyển hướng đến tài liệu sai. requests.exceptions.MissingSchema: Invalid URL '/containers/1d26a841bf07/json': No schema supplied. Perhaps you meant http:///containers/1d26a841bf07/json?
Cerin

24

Điều này sẽ nhận được id container đầy đủ từ trong một container:

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

22

Một nhận xét của madeddie có vẻ thanh lịch nhất đối với tôi:

CID=$(basename $(cat /proc/1/cpuset))

21

CẢNH BÁO: Bạn nên hiểu các rủi ro bảo mật của phương pháp này trước khi bạn xem xét nó. Tóm tắt về rủi ro của John :

Bằng cách cấp cho bộ chứa quyền truy cập /var/run/docker.sock, thật dễ dàng để thoát ra khỏi ngăn chứa được cung cấp bởi docker và có quyền truy cập vào máy chủ. Rõ ràng điều này có khả năng nguy hiểm.


Bên trong container, dockerId là tên máy chủ của bạn. Vì vậy, bạn có thể:

  • cài đặt gói docker-io trong thùng chứa của bạn với cùng phiên bản với máy chủ
  • bắt đầu với --volume /var/run/docker.sock:/var/run/docker.sock --privileged
  • cuối cùng, chạy: docker inspect $(hostname)bên trong container

Tránh điều này. Chỉ làm điều đó nếu bạn hiểu các rủi ro và có một giảm thiểu rõ ràng cho các rủi ro.


1
Tôi nghi ngờ điều này sẽ không hoạt động nếu --hostnametùy chọn chạy docker đã được sử dụng.
hairyhenderson

Nếu --hostnameđược đặt, bạn có thể sử dụng kết hợp từ câu trả lời này và nhận xét từ @Jay Taylor trong câu trả lời được chấp nhận: docker inspect $(cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1)để có được tất cả thông tin về container đang chạy.
Michael K.

bạn có thể đặt một tài liệu tham khảo đến docker-io?
Brad P.

Tôi giả sử npmjs.com/package/docker-io nhưng đó chỉ là những gì Google nói với tôi và có lẽ đó không phải là ý bạn.
Brad P.

15

Để làm cho nó đơn giản,

  1. Container ID là tên máy chủ của bạn bên trong docker
  2. Thông tin về container có sẵn bên trong / Proc / self / cgroup

Để có được tên máy chủ,

hostname

hoặc là

uname -n

hoặc là

cat /etc/host

Đầu ra có thể được chuyển hướng đến bất kỳ tập tin nào và đọc lại từ ứng dụng Eg: # hostname > /usr/src//hostname.txt


10

Tôi đã thấy rằng vào ngày 17 tháng 9, có một cách đơn giản nhất để làm điều đó trong container docker:

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

Hoặc giống như nó đã được nói, một phiên bản ngắn hơn với

$ cat /etc/hostname
4de1c09d3f19

Hoặc đơn giản:

$ hostname
4de1c09d3f19

6

Docker đặt tên máy chủ thành ID container theo mặc định, nhưng người dùng có thể ghi đè tên này bằng --hostname. Thay vào đó, hãy kiểm tra /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

Đây là một lớp lót tiện dụng để giải nén ID container:

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

2

Bạn có thể sử dụng dòng lệnh này để xác định ID container hiện tại (được thử nghiệm với docker 1.9).

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

Sau đó, một yêu cầu nhỏ với Docker API (bạn có thể chia sẻ /var/run/docker.sock) để lấy tất cả thông tin.


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

2

Một số giải pháp được đăng đã ngừng hoạt động do thay đổi định dạng /proc/self/cgroup. Đây là một lệnh GNU grep duy nhất nên mạnh mẽ hơn một chút để định dạng các thay đổi:

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

Để tham khảo, đây là đoạn trích của / Proc / self / cgroup từ bên trong các container docker đã được thử nghiệm với lệnh này:

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

1
awk -F'[:/]' '(($4 == "docker") && (lastId != $NF)) { lastId = $NF; print $NF; }' /proc/self/cgroup

0

Bên cạnh đó, nếu bạn có pid của container và muốn lấy id docker của container đó, một cách tốt là sử dụng nsenter kết hợp với phép thuật sed ở trên:

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


-19

Sử dụng 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",
...

Có thể nhận ip như sau.

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

5
Đây không phải là ý tôi. Tôi cần có thể lấy thông tin này từ bên trong container. Về cơ bản tôi cần một cách để hiểu ID của một container tôi đang chạy từ bên trong.
Alessandro
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.