Làm cách nào để vào trong vỏ của Docker?


1163

Tôi đang bắt đầu làm việc với Docker. Tôi đang sử dụng hình ảnh cơ sở WordPress và docker-compose.

Tôi đang cố gắng ssh vào một trong các container để kiểm tra các tệp / thư mục đã được tạo trong quá trình xây dựng ban đầu. Tôi đã cố chạy docker-compose run containername ls -la, nhưng điều đó không làm gì cả. Ngay cả nếu có, tôi muốn có một bàn điều khiển nơi tôi có thể duyệt qua cấu trúc thư mục, thay vì chạy một lệnh. Cách đúng đắn để làm điều này với Docker là gì?


Vì vậy, nó có vẻ như câu trả lời là docker đính kèm. Nhưng làm thế nào tôi có thể nhận được điều đó từ docker-compose?
Andrew

3
Sử dụng docker exec Askubfox.com/a/543057/35816 . Nhận id container bằng cách sử dụngdocker ps
Mauricio Scheffer

26
sudo docker run -it --entrypoint /bin/bash <container_name>đưa bạn vào container tương tác. Sau đó, người ta có thể kiểm tra hệ thống tệp trong container bằng cách sử dụngcd <path>
Sergei

Câu trả lời:


1734

docker attachsẽ cho phép bạn kết nối với bộ chứa Docker của bạn, nhưng điều này thực sự không giống như ssh. Ví dụ, nếu bộ chứa của bạn đang chạy một máy chủ web, docker attachcó thể sẽ kết nối bạn với thiết bị xuất chuẩn của quy trình máy chủ web. Nó sẽ không nhất thiết phải cung cấp cho bạn một vỏ.

Các docker execlệnh có lẽ là những gì bạn đang tìm kiếm; điều này sẽ cho phép bạn chạy các lệnh tùy ý bên trong một container hiện có. Ví dụ:

docker exec -it <mycontainer> bash

Tất nhiên, bất cứ lệnh nào bạn đang chạy đều phải tồn tại trong hệ thống tệp chứa.

Trong lệnh trên <mycontainer> là tên hoặc ID của thùng chứa đích. Không quan trọng bạn có sử dụng hay không docker compose; chỉ cần chạy docker psvà sử dụng ID (chuỗi thập lục phân được hiển thị trong cột đầu tiên) hoặc tên (được hiển thị trong cột cuối cùng). Ví dụ: đã cho:

$ docker ps
d2d4a89aaee9        larsks/mini-httpd   "mini_httpd -d /cont   7 days ago          Up 7 days                               web                 

Tôi có thể chạy:

$ docker exec -it web ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
18: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:3/64 scope link 
       valid_lft forever preferred_lft forever

Tôi có thể hoàn thành điều tương tự bằng cách chạy:

$ docker exec -it d2d4a89aaee9 ip addr

Tương tự, tôi có thể bắt đầu một cái vỏ trong container;

$ docker exec -it web sh
/ # echo This is inside the container.
This is inside the container.
/ # exit
$

76
Ngoài ra, docker execchỉ hoạt động trên các container đang chạy (nếu không sử dụng docker run -it --entrypoint /bin/bashhoặc tương tự).
L0j1k

59
để thuận tiện cho bạn, -itlà sự kết hợp của -i-ttương ứng --interactive("Giữ STDIN mở ngay cả khi không được đính kèm") --tty("Phân bổ giả TTY").
Adrian Föder

23
Trên các thùng chứa dựa trên Alpine Linux, bạn có thể không có bash, vì vậy nếu vậy, hãy sử dụng sh thay thế.
Robin Green

9
@ L0j1k, đó là docker run -it --entrypoint /bin/bash <imageid> --any --more --args, chỉ để làm rõ cho mọi người
Alexander Mills

2
@AlexanderMills Có, và để làm rõ hơn, những người --any --more --argsbạn sẽ được đưa vào bất cứ thứ gì hình ảnh được xác định là của nó CMDvà không phải là Docker (hoặc nếu hình ảnh của bạn chỉ xác định một ENTRYPOINTvà không CMD, thì các tùy chọn này sẽ được đưa vào /bin/bashnhư bạn đã chỉ định ở đây ). Vì vậy, ví dụ, bất kỳ docker runtùy chọn nào khác (ví dụ --net "host") cần phải đi trước <imageid>.
L0j1k

302

Để bash vào một container đang chạy, gõ này:

docker exec -t -i container_name /bin/bash

hoặc là

docker exec -ti container_name /bin/bash

hoặc là

docker exec -ti container_name sh

Giả sử nó là một container Linux?
Peter Mortensen

5
/ bin / bash không bắt buộc chỉ cần bash đã làm điều đó cho tôi
Anand Varkey Philips

6
Tôi thích docker exec -itthay vìdocker exec -t -i
VaTo

sự khác biệt @VaTo
AATHITH RAJENDRAN 23/07/19

@AATHITHRAJENDRANI chỉ thích một dạng lệnh ngắn hơn thay vì có hai cờ, bạn có thể bao gồm hai tùy chọn đó trong cùng một đối số -it.
VaTo 23/07/19

85

Giả sử, vì những lý do là của riêng bạn, bạn thực sự muốn sử dụng SSH. Phải mất một vài bước, nhưng nó có thể được thực hiện. Dưới đây là các lệnh mà bạn sẽ chạy bên trong container để thiết lập nó ...

apt-get update
apt-get install openssh-server

mkdir /var/run/sshd
chmod 0755 /var/run/sshd
/usr/sbin/sshd

useradd --create-home --shell /bin/bash --groups sudo username ## includes 'sudo'
passwd username ## Enter a password

apt-get install x11-apps ## X11 demo applications (optional)
ifconfig | awk '/inet addr/{print substr($2,6)}' ## Display IP address (optional)

Bây giờ bạn thậm chí có thể chạy các ứng dụng đồ họa (nếu chúng được cài đặt trong bộ chứa) bằng cách sử dụng chuyển tiếp X11 đến máy khách SSH:

ssh -X username@IPADDRESS
xeyes ## run an X11 demo app in the client

Dưới đây là một số tài nguyên liên quan:


34

Nếu bạn đang ở đây để tìm kiếm một câu trả lời dành riêng cho Docker Compose như tôi, thì nó cung cấp một cách dễ dàng mà không cần phải tìm ID container được tạo.

docker-compose execlấy tên của dịch vụ theo docker-compose.ymltập tin của bạn .

Vì vậy, để có được vỏ Bash cho dịch vụ 'web' của bạn, bạn có thể làm:

$ docker-compose exec web bash

docker-compose runcũng hoạt động, nếu container của bạn chưa tồn tại.
Paul

23

Để ý : câu trả lời này thúc đẩy một công cụ tôi đã viết.

Tôi đã tạo một máy chủ SSH được đóng gói mà bạn có thể 'dính' vào bất kỳ vùng chứa nào đang chạy. Bằng cách này bạn có thể tạo các tác phẩm với mọi container. Yêu cầu duy nhất là container có Bash.

Ví dụ sau đây sẽ khởi động một máy chủ SSH được gắn vào một thùng chứa có tên 'my-container'.

docker run -d -p 2222:22 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e CONTAINER=my-container -e AUTH_MECHANISM=noAuth \
  jeroenpeeters/docker-ssh

ssh localhost -p 2222

Khi bạn kết nối với dịch vụ SSH này (với ứng dụng khách SSH mà bạn chọn), phiên Bash sẽ được bắt đầu trong vùng chứa có tên 'my-container'.

Để biết thêm về con trỏ và tài liệu, hãy xem: https://github.com/jeroenpeeter/docker-ssh


1
Điều đó thật ngọt ngào. Ưu điểm lớn của việc làm theo cách này là bạn có được một thiết bị đầu cuối đầy đủ chức năng. Khi tôi sử dụng phương pháp "docker exec" thì tôi không thể xóa nội dung của thiết bị đầu cuối, lessđã hiển thị cảnh báo mỗi khi tôi chạy nó, v.v ... Sử dụng container của Jeroen cho tôi trải nghiệm tốt hơn nhiều cho đến nay. Chỉ cần chắc chắn để kiểm tra các tài liệu . Lệnh mẫu trong phản hồi dường như không còn hợp lệ nữa.
Rafał G.

1
nó là một dụng cụ hữu ích. Bạn có biết làm thế nào tôi có thể sử dụng nó như là một đại lý docker đường ống jenkins? Tôi muốn jenkins chuyển một số tệp bằng SCP sang một máy chủ từ xa và thực thi chúng bằng SSH
Gilson

21

Nếu bạn đang sử dụng Docker trên Windows và muốn có quyền truy cập shell vào một container, hãy sử dụng điều này:

winpty docker exec -it <container_id> sh

Rất có thể, bạn đã cài đặt Git Bash . Nếu bạn không, hãy chắc chắn để cài đặt nó.


1
Giả sử một container Linux Docker?
Peter Mortensen

1
docker exec -ti <container_id> cmd hoạt động tốt
PBo

17

Nếu container đã thoát (có thể do một số lỗi), bạn có thể làm

$ docker run --rm -it --entrypoint /bin/ash image_name

hoặc là

$ docker run --rm -it --entrypoint /bin/sh image_name

hoặc là

$ docker run --rm -it --entrypoint /bin/bash image_name

để tạo một thùng chứa mới và lấy một cái vỏ vào nó. Vì bạn đã chỉ định --rm, vùng chứa sẽ bị xóa khi bạn thoát khỏi trình bao.


16

Trong một số trường hợp, hình ảnh của bạn có thể dựa trên Alps. Trong trường hợp này, nó sẽ ném:

Thực thi thời gian chạy OCI không thành công: exec fail: container_linux.go: 348: bắt đầu quá trình container gây ra "exec: \" bash \ ": không thể tìm thấy tệp thực thi trong $ PATH": không xác định

Bởi vì /bin/bashkhông tồn tại. Thay vì điều này, bạn nên sử dụng:

docker exec -it 9f7d99aa6625 ash

hoặc là

docker exec -it 9f7d99aa6625 sh

15

SSH vào container Docker bằng lệnh này:

sudo docker exec -i -t (container ID) bash

12

Để kết nối với cmd trong bộ chứa Windows, hãy sử dụng

docker exec -it d8c25fde2769 cmd

Trong đó d8c25fde2769 là id container.


11

Thật đơn giản !

Liệt kê tất cả các hình ảnh Docker của bạn:

sudo docker images

Trên hệ thống của tôi, nó hiển thị đầu ra sau:

REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
bash                latest              922b9cc3ea5e        9 hours ago
14.03 MB
ubuntu              latest              7feff7652c69        5 weeks ago         81.15 MB

Tôi có hai hình ảnh Docker trên PC. Hãy nói rằng tôi muốn chạy cái đầu tiên.

sudo docker run -i -t ubuntu:latest /bin/bash

Điều này sẽ cung cấp cho bạn kiểm soát thiết bị đầu cuối của container. Bây giờ bạn có thể thực hiện tất cả các loại hoạt động vỏ bên trong container. Giống như làm lssẽ xuất ra tất cả các thư mục trong thư mục gốc của hệ thống tập tin.

bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

11

Để kiểm tra các tập tin, chạy docker run -it <image> /bin/shđể có được một thiết bị đầu cuối tương tác. Danh sách các hình ảnh có thể được lấy bằng docker images. Ngược lại với docker execgiải pháp này cũng hoạt động trong trường hợp khi một hình ảnh không bắt đầu (hoặc thoát ngay sau khi chạy).


Giả sử một hình ảnh Docker Linux?
Peter Mortensen

10

GIẢI PHÁP GOINIDE

cài đặt goinsidecông cụ dòng lệnh với:

sudo npm install -g goinside

và đi vào bên trong một container docker với kích thước thiết bị đầu cuối thích hợp với:

goinside docker_container_name

câu trả lời cũ

Chúng tôi đã đặt đoạn trích này vào ~/.profile:

goinside(){
    docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f goinside

Điều này không chỉ khiến mọi người có thể vào trong một container đang chạy với:

goinside containername

Nó cũng giải quyết một vấn đề tồn tại lâu dài về kích thước thiết bị đầu cuối container Docker cố định . Điều này rất khó chịu nếu bạn phải đối mặt với nó.

Ngoài ra nếu bạn theo liên kết, bạn cũng sẽ hoàn thành lệnh cho tên thùng chứa docker của mình.


1
Cảm ơn. Nó hoạt động như một bùa mê, ít nhất là đối với những hình ảnh đã có bash. Có thể không hoạt động đối với hình ảnh dựa trên núi cao, tuy nhiên, có thể được sửa bằng một chức năng khác được viết riêng cho sh / ash, v.v.
Gaurav Bhaskar

8
$ docker exec -it <Container-Id> /bin/bash

Hoặc tùy thuộc vào vỏ, nó có thể

$ docker exec -it <Container-Id> /bin/sh

Bạn có thể lấy Id container thông qua docker pslệnh

-i = tương tác

-t = để phân bổ một psuedo-TTY


8

Tôi đã tạo một chức năng thiết bị đầu cuối để truy cập dễ dàng hơn đến thiết bị đầu cuối chứa. Có lẽ nó cũng hữu ích cho các bạn:

Vì vậy, kết quả là, thay vì gõ:

docker exec -it [container_id] /bin/bash

bạn sẽ viết:

dbash [container_id]

Đặt phần sau vào ~ / .bash_profile (hoặc bất cứ thứ gì phù hợp với bạn), sau đó mở cửa sổ terminal mới và tận hưởng phím tắt:

#usage: dbash [container_id]
dbash() {
    docker exec -it "$1" /bin/bash
}

7

bạn có thể tương tác với thiết bị đầu cuối trong container docker bằng cách chuyển tùy chọn -ti

docker run --rm -ti <image-name>
eg: docker run --rm -ti ubuntu

-t là viết tắt của terminal -i là viết tắt của tương tác


6

docker execchắc chắn sẽ là một giải pháp. Một cách dễ dàng để làm việc với câu hỏi bạn đã hỏi là gắn thư mục bên trong Docker vào thư mục của hệ thống cục bộ .

Vì vậy, bạn có thể xem các thay đổi trong đường dẫn cục bộ ngay lập tức.

docker run -v /Users/<path>:/<container path> 

1
lệnh của bạn thực sự gắn thư mục của máy chủ vào container.
Demonbane

Vâng! Lấy một bản sao lưu vào một thư mục khác và sau đó gắn kết âm lượng, sau đó di chuyển bản sao lưu vào thư mục được gắn kết.
Pratik

6

Sử dụng:

docker attach <container name/id here>

Một cách khác, mặc dù có một mối nguy hiểm cho nó, là sử dụng attach, nhưng nếu bạn Ctrl+ Cthoát khỏi phiên, bạn cũng sẽ dừng container. Nếu bạn chỉ muốn xem những gì đang xảy ra, sử dụng docker logs -f.

:~$ docker attach --help
Usage:  docker attach [OPTIONS] CONTAINER

Attach to a running container

Options:
      --detach-keys string   Override the key sequence for detaching a container
      --help                 Print usage
      --no-stdin             Do not attach STDIN
      --sig-proxy            Proxy all received signals to the process (default true)


4

Nếu bạn đã cài đặt Docker Kitematic, bạn có thể sử dụng GUI. Mở Kitematictừ biểu tượng Docker và trong Kitematiccửa sổ chọn thùng chứa của bạn, sau đó bấm vào execbiểu tượng.

Bạn cũng có thể thấy nhật ký vùng chứa và nhiều thông tin vùng chứa (trong tab cài đặt) trong GUI này.

Chọn Kitical từ menu

Bấm vào thực hiện


2

Trong trường hợp của tôi, vì một số lý do, tôi cần kiểm tra tất cả các thông tin liên quan đến mạng trong mỗi container. Vì vậy, các lệnh sau phải hợp lệ trong một thùng chứa ...

ip
route
netstat
ps
...

Tôi đã kiểm tra tất cả các câu trả lời này, không có câu trả lời nào hữu ích cho tôi. Tôi đã tìm kiếm thông tin trong các trang web khác. Tôi sẽ không thêm một siêu liên kết ở đây, vì nó không được viết bằng tiếng Anh. Vì vậy, tôi chỉ đưa lên bài đăng này với một giải pháp tóm tắt cho những người có cùng yêu cầu như tôi.

Giả sử bạn có một container đang chạy có tên là light-test. Làm theo các bước dưới đây.

  • docker inspect light-test -f {{.NetworkSettings.SandboxKey}}. Lệnh này sẽ nhận được trả lời như thế nào /var/run/docker/netns/xxxx.
  • Sau đó ln -s /var/run/docker/netns/xxxx /var/run/netns/xxxx. Các thư mục có thể không tồn tại, làm mkdir /var/run/netnsđầu tiên.
  • Bây giờ bạn có thể thực hiện ip netns exec xxxx ip addr showđể khám phá thế giới mạng trong container.

Tái bút xxxxluôn luôn có cùng giá trị nhận được từ lệnh đầu tiên. Và tất nhiên, bất kỳ lệnh nào khác là hợp lệ, tức là ip netns exec xxxx netstat -antp|grep 8080.


1

Một lựa chọn khác là sử dụng nsenter .

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid

2
Có một số vấn đề với nsenter. Đầu tiên là nó yêu cầu bạn phải có quyền truy cập vật lý vào máy chủ docker, đây không phải là một thứ nhất định (bạn có thể đang làm việc với API docker từ xa). Ngoài ra, việc chạy theo nsentergiúp bạn thoát khỏi một số hạn chế về bảo mật và tài nguyên mà Docker đặt ra (có thể là pro hoặc con, tùy thuộc vào môi trường của bạn).
larsks 11/05/2015

1
Ngay cả tác giả của nsenter nói rằng sử dụng docker execnhững ngày này.
L0j1k

1
@larsks Vâng, cả hai đều có lợi ích riêng của họ. Ví dụ, cái này là một lợi ích của nsenter hơn docker exec. docker exectrông thanh lịch hơn đối với tôi.
xuhdev

2
@ L0j1k Để bớt khó hiểu hơn: bài đăng bạn giới thiệu không phải bởi tác giả của nsenter, mà là tác giả của hình ảnh Docker chạy nsenter.
xuhdev 11/05/2015

1

Nếu bạn đang sử dụng Docker Compose thì điều này sẽ đưa bạn vào trong một Docker container.

docker-compose run container_name /bin/bash

Bên trong container, nó sẽ đưa bạn đến WORKDIR được xác định trong Dockerfile. Bạn có thể thay đổi thư mục công việc của bạn bằng cách

WORKDIR directory_path # E.g  /usr/src -> container's path

0

Để thực thi vào một container đang chạy có tên test, bên dưới là các lệnh sau

Nếu container có bashvỏ

docker exec -it test /bin/bash

Nếu container có bournevỏ và hầu hết các trường hợp nó có mặt

docker run -it test /bin/sh

-3

Dành cho docker-compose up (Docker4Drupal)

docker-compose exec php bash

Tôi sử dụng Docker cho Drupal trên máy tính xách tay Linux. Sau khi chạy container, tôi sử dụng ' docker-compose exec php bash' để kết nối với container để tôi có thể chạy các lệnh biệt kích. Việc này ổn với tôi.

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.