Cách nhập vào bộ chứa Docker đã chạy với TTY mới


545

Tôi có một container đang chạy dịch vụ Apache ở phía trước. Tôi muốn có thể truy cập vào container từ một shell khác để "chọc quanh" bên trong nó và kiểm tra các tập tin. Hiện tại, nếu tôi gắn vào container, tôi sẽ nhìn vào daemon Apache và không thể chạy bất kỳ lệnh nào.

Có thể gắn một tty khác vào một container đang chạy không? Có thể, tôi có thể tận dụng thực tế là Docker thực sự chỉ quấn quanh các container LXC? Tôi đã thử sudo lxc-console -n [container-id] -t [1-4]nhưng có vẻ như chỉ có một tty được tạo sẵn và đó là cái chạy daemon apache. Có lẽ có một cách để kích hoạt nhiều bảng điều khiển lxc trong quá trình xây dựng?

Tôi thà không cấu hình và xây dựng container với dịch vụ openssh nếu có thể.


7
Bạn đã thử docker attach [conainer-id]chưa
shabbychef

13
@shabbychef trừ khi docker đính kèm đã thay đổi, lệnh đính kèm sẽ gắn vào tty đang chạy, không phải là một cái mới, do đó tiêu đề câu hỏi là "... với TTY mới". Đây là lý do tại sao câu trả lời dưới đây không sử dụng lệnh đính kèm.
Chương trình

1
Kể từ 1.3, có một cách dễ dàng hơn như được mô tả trong câu trả lời này
Thomasleveil

Câu trả lời:


1061

Với docker 1.3, có một lệnh mới docker exec. Điều này cho phép bạn nhập một docker đang chạy:

docker exec -it [container-id] bash

30
Tôi đã thay đổi đây thành câu trả lời chính xác (từ chính tôi) bởi vì phương pháp mới này, không có ở thời điểm của câu hỏi, là phương pháp tốt nhất hiện tại IMO.
trình viên

3
Tuy nhiên, lưu ý rằng execnó không hoạt động như một thiết bị đầu cuối bình thường. Ví dụ: bạn không thể thay đổi người dùng một lần trong container.
Pithikos

3
@Pithikos: Tôi có thể sử dụng exec để chạy shell và sau đó su someuserthay đổi người dùng. Chạy Docker 1.4.1
lsh

2
Lưu ý cho bất cứ ai đọc cuộc thảo luận này. Tôi chắc chắn docker exec -itcuối cùng sẽ cung cấp một giả giả đầy đủ chức năng, nhưng hiện tại (phiên bản Docker 1.9.1), có một số thiếu sót: github.com/docker/docker/issues/8755
blong

18
nếu bạn gặp lỗi 'exec: "bash": không thể tìm thấy tệp thực thi trong $ PATH', bạn có thể thử điều này: docker exec -it [container-id] / bin / sh
Dai Kaixian

42

Bạn nên sử dụng công cụ của Jérôme Petazzoni có tên 'nsenter' để vào một container mà không cần sử dụng SSH. Xem: https://github.com/jpetazzo/nsenter

Cài đặt chỉ với việc chạy: docker run -v /usr/local/bin:/target jpetazzo/nsenter

Sau đó sử dụng lệnh docker-enter <container-id>để vào container.


Đây là cách đúng đắn. Xem blog .
Jesse Glick

5
Với docker 1.3, có một lệnh mới docker exec. Điều này cho phép bạn nhập một docker đang chạy: docker exec -it <container-id> bash(xem câu trả lời của tôi bên dưới)
Michael_Scharf

5
docker-entercòn tồn tại? Nó mang lại cho tôi command not found.
Snowcrash

22

Cập nhật

Kể từ docker 0.9, để các bước bên dưới hoạt động, giờ đây người ta phải cập nhật /etc/default/dockertệp với '-e lxc'tùy chọn khởi động docker daemon trước khi khởi động lại daemon (tôi đã làm điều này bằng cách khởi động lại máy chủ).

cập nhật tập tin / etc / default / docker

Tất cả là vì ...

... nó [docker 0.9] chứa một bản tóm tắt "trình điều khiển động cơ" mới để có thể sử dụng API khác ngoài LXC để bắt đầu các thùng chứa. Nó cũng cung cấp trình điều khiển công cụ mới dựa trên thư viện API mới (libcontainer) có thể xử lý các Nhóm điều khiển mà không cần sử dụng các công cụ LXC. Vấn đề chính là nếu bạn đang dựa vào lxc-Đính kèm để thực hiện các hành động trên thùng chứa của mình, như khởi động một lớp vỏ bên trong thùng chứa, điều này cực kỳ hữu ích cho môi trường phát triển ...

nguồn

Xin lưu ý rằng điều này sẽ ngăn máy chủ mới chỉ kết nối tính năng tùy chọn của docker 0.11 khỏi "hoạt động" và bạn sẽ chỉ thấy giao diện loopback. báo cáo lỗi


Hóa ra giải pháp cho một câu hỏi khác cũng là giải pháp cho câu hỏi này:

... Bạn có thể sử dụng ps -notruncdocker để lấy ID container lxc đầy đủ và sau đó sử dụng lxc-attach -n <container_id>run bash trong container đó làm root.

Cập nhật: Bạn sẽ sớm cần sử dụng ps --no-truncthay vì ps -notruncbị phản đối.

nhập mô tả hình ảnh ở đây Tìm ID container đầy đủ

nhập mô tả hình ảnh ở đây Nhập lệnh đính kèm lxc.

nhập mô tả hình ảnh ở đây Top cho thấy quá trình apache của tôi chạy mà docker bắt đầu.


Vì vậy, không có cách nào để làm điều này chỉ với Docker, phải không? Cá nhân tôi không thích trộn lẫn trong LXC.
qkrijger

Có cách nào để chạy một lệnh với lxc-Đính kèm để khởi chạy bash không? cám ơn!!
joselo

@qkrijger theo như tôi biết là đúng. Tại sao lo lắng về "trộn" LXC? Bạn nhận ra rằng docker được xây dựng trên đỉnh LXC phải không?
trình viên

@joselo Tôi không hiểu câu hỏi của bạn, nhưng tôi đề nghị bạn tạo một bài viết mới với nhiều chi tiết hơn? Có nhiều cách để bắt đầu một quá trình docker, chẳng hạn như với bash hoặc như một daemon với -d, v.v.
trình viên

@programster vâng, tôi nhận ra rằng :) Tuy nhiên, sử dụng LXC trực tiếp kết hợp với Docker cho cảm giác như hack. Vui, nhưng không thực sự duy trì. Nói chung, người ta nên mã hóa trong lớp trừu tượng mà người ta đã chọn để làm việc. Nếu bạn thực sự cần LXC, có lẽ đã đến lúc yêu cầu kéo trên Docker :)
qkrijger

7

Bước đầu tiên nhận id container:

docker ps

Điều này sẽ cho bạn thấy một cái gì đó như

CONTAINER ID HÌNH ẢNH TÌNH TRẠNG TÌNH TRẠNG TẠO TÊN

1170fe9e9460 localhost: 5000 / python: env-7e847468c4d73a0f35e9c5164046ad88 "./run_notebook.sh" 26 giây trước Lên 25 giây 0.0.0.0:8989->9999/tcp SLURM

1170fe9e9460 là id container trong trường hợp này.

Thứ hai , nhập docker:

docker exec -it [container_id] bash

vì vậy trong trường hợp trên: docker exec -it 1170fe9e9460 bash


5

Còn việc chạy màn hình tmux / GNU trong container thì sao? Có vẻ như cách dễ dàng hơn để truy cập nhiều vty như bạn muốn với một cách đơn giản:

$ docker attach {container id}

Đây là một giải pháp ổn nếu bạn biết rằng bạn sẽ muốn có quyền truy cập vào một thùng chứa (ví dụ để gỡ lỗi), nhưng điều này sẽ không giúp OP nói rằng họ muốn nhìn xung quanh một container hiện có.
Luca Spiller

1
Vấn đề của tôi với câu trả lời này là mọi người đã hỏi về việc sử dụng docker attachvà tôi đã chỉ ra rằng:...the attach command attaches to the running tty, not a new one, hence the question title is "...with new TTY"
trình viên

Chà, nếu container đang chạy thì giải pháp này sẽ không giúp ích gì cho bạn, nhưng nếu trước đó bạn quan tâm đến việc để một bộ ghép kênh đang chạy, bạn sẽ không cần thêm ttys nữa ... Thực tế kể từ khi tôi bắt đầu sử dụng tmux, tôi sử dụng một tty và chỉ có một để làm mọi thứ tôi cần kể từ khi vào tmux tôi có thể sinh ra nhiều vty như tôi muốn.
cig0

4

nsenterlàm điều đó Tuy nhiên tôi cũng cần phải nhập một container theo cách đơn giản và nsenter không đủ cho nhu cầu của tôi. Nó đã bị lỗi trong một số trường hợp (màn hình đen cộng với cờ -wd không hoạt động). Hơn nữa, tôi muốn đăng nhập như một người dùng cụ thể và trong một thư mục cụ thể.

Tôi đã kết thúc việc làm công cụ của riêng tôi để nhập container. Bạn có thể tìm thấy nó tại: https://github.com/Pithikos/docker-enter

Cách sử dụng của nó dễ dàng như

./docker-enter [-u <user>] [-d <directory>] <container ID>

Chỉ cần cố gắng, rất mát mẻ! Trên Ubuntu đã phải chạy sudo apt-get build-Essential -y gcc docker-enter.c -o docker-enter sudo ./docker-enter <short-container-id> Rất vui vì tôi không phải lấy ID đầy đủ như với lxc-Đính kèm -n Codebase đủ ngắn để người ta có thể quét toàn bộ một cách nhanh chóng để tìm kiếm bất cứ thứ gì độc hại.
Chương trình

Tôi đã tạo một ebuild có sẵn trên gentoo tại github.com/steveeJ/personal-portage-overlay dưới dạng mô phỏng ứng dụng / docker-enter.
stefanjunker

Tôi đã thêm một hướng dẫn / tập lệnh để tự động này cho người dùng ubfox tại chương
Chương trình

2

Cách "nsinit" là:

cài đặt nsinit

git clone git@github.com:dotcloud/docker.git
cd docker
make shell

từ bên trong container:

go install github.com/dotcloud/docker/pkg/libcontainer/nsinit/nsinit

từ bên ngoài:

docker cp id_docker_container:/go/bin/nsinit /root/

sử dụng nó

cd /var/lib/docker/execdriver/native/<container_id>/
nsinit exec bash

2
docker exec -t -i container_name /bin/bash

Sẽ đưa bạn đến giao diện điều khiển container.


Tôi đáp xuống câu hỏi này vì tôi có cùng một vấn đề. Câu trả lời có vẻ tương tự không có tác dụng với tôi cho đến khi tôi sửa đổi. Tôi có thể xóa điều này mặc dù.
Danstan

2
docker exec -ti 'CONTAINER_NAME' sh

or

docker exec -ti 'CONTAINER_ID' sh

1

Tôi đã bắt đầu powershell trên microsoft / iis đang chạy dưới dạng daemon bằng cách sử dụng

docker exec -it <nameOfContainer> powershell

Có vẻ như câu hỏi là về một container dựa trên linux. Câu trả lời này có thể sẽ chỉ hoạt động nếu bạn có bộ chứa dựa trên windows -hoặc- nếu bạn đã cài đặt phiên bản .NET Core của PowerShell, ví dụ PowerShell 6 trở lên.
Manfred

0

Trên Windows 10 , tôi đã cài đặt docker. Tôi đang chạy Jnekins trên một container và tôi gặp phải thông báo lỗi tương tự. Dưới đây là hướng dẫn từng bước để giải quyết vấn đề này:

Bước 1: Mở gitbash và chạy docker chạy -p 8080: 8080 -p 50000: 50000 jenkins.

Bước 2: Mở một thiết bị đầu cuối mới.

Bước 3: Làm "docker ps" để lấy danh sách container đang chạy. Sao chép id container.

Bước 4: Bây giờ nếu bạn thực hiện "docker exec -it {container id} sh" hoặc "docker exec -it {container id} bash", bạn sẽ nhận được thông báo lỗi tương tự "thiết bị đầu vào không phải là TTY. Nếu bạn là bằng cách sử dụng mintty, hãy thử tiền tố lệnh với 'winpty' "

Bước 5: Chạy lệnh " $ winpty docker exec -it {container id} sh "

tập !! Bây giờ bạn đang ở trong nhà ga.

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.