Có thể bắt đầu một phiên shell trong một container đang chạy (không có ssh)


341

Tôi đã ngây thơ mong đợi lệnh này để chạy bash shell trong một container đang chạy:

docker run "id of running container" /bin/bash

Có vẻ như không thể, tôi gặp lỗi:

2013/07/27 20:00:24 Internal server error: 404 trying to fetch remote history for 27d757283842

Vì vậy, nếu tôi muốn chạy bash shell trong một container đang chạy (ví dụ: cho mục đích chẩn đoán)

Tôi có phải chạy máy chủ SSH trong đó và đăng nhập qua ssh không?


1
docker run CONTAINERđược lên kế hoạch vào ngày 1
kolypto

7
Vì docker 1.3, bạn thực sự nên làm như được mô tả trong câu trả lời này
Thomasleveil

1
chỉdocker attach container_name
maxbellec

1
Nó có vẻ như câu trả lời thứ hai ngày nay tốt hơn nhiều so với câu trả lời - bạn có thể xem xét lại việc thay đổi câu trả lời được chấp nhận không?
jsbueno

Câu trả lời:


285

EDIT: Bây giờ bạn có thể sử dụng docker exec -it "id of running container" bash( doc )

Trước đây, câu trả lời cho câu hỏi này là:

Nếu bạn thực sự phải và bạn đang ở trong môi trường gỡ lỗi, bạn có thể làm điều này: sudo lxc-attach -n <ID> Lưu ý rằng id cần phải là toàn bộ ( docker ps -notrunc).

Tuy nhiên, tôi thực sự khuyên bạn nên chống lại điều này.

thông báo: -notrunckhông dùng nữa, nó sẽ được thay thế --no-truncsớm.


1
Tại sao bạn đề nghị chống lại nó?
Tối đa

7
Tôi khuyên bạn nên chống lại nó bởi vì 1) nó yêu cầu một hạt nhân rất gần đây, 2) Bạn đang làm những việc bên ngoài docker để bạn không thể theo dõi nó (nhật ký, đính kèm, v.v.). Ngoài ra, docker có thể sử dụng lxc ngay bây giờ, nhưng không có bảo hành, nó sẽ làm như vậy mãi mãi.
creack

1
Hãy thử cập nhật lên 0.7.6. Docker vẫn đang sử dụng lxc ngay bây giờ và lxc-attachsẽ hoạt động tốt. Tôi chỉ cần tăng gấp đôi kiểm tra và nó hoạt động cho tôi. (Lưu ý rằng nó sẽ không hoạt động với kernel trước 3.8).
creack

2
theo như docker 0.9 không còn chạy với LXC theo mặc định. Bạn sẽ phải khởi chạy docker -d -e lxc
docker

2
Max L., trường hợp sử dụng của bạn có thể được giải quyết với khối lượng dữ liệu . Ví dụ không được kiểm tra: 1) chạy container với nhật ký nginx trong khối lượng dữ liệu : docker run -v /var/log/nginx -name somename imagename command; 2) chạy một container khác để xem nội dung khối lượng dữ liệu : docker run -volumes-from somename -i -t busybox /bin/sh.
ciastek

615

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 "id of running container" bash

2
Nó hiệu quả tuyệt vời đối với tôi. Bổ sung rất hữu ích để chạy docker.
oraserrata

Điều gì xảy ra nếu tôi thực hiện các thay đổi trong khi thực hiện một container đang chạy và muốn phản ánh các thay đổi trực tuyến? thực hành tốt nhất là gì?
mediaroot

Rất hữu ích. Cảm ơn bạn
luongnv89

sử dụng docker psđể lấy id của các phiên bản đang chạy
muon

Lưu ý: Container có thể không có bash (»exec:" bash ": không tìm thấy tệp thực thi«). Sử dụng docker inspect <image>để xem những gì vỏ có sẵn. Ví dụ chạy docker exec -it <container id> /bin/shthay.
pixelbrackets

14

Cứ làm đi

docker attach container_name

Như đã đề cập trong các ý kiến, để tách khỏi container mà không dừng lại, gõ Ctrlprồi Ctrlq.


5
Cảm ơn!! Nó đã giúp đỡ. Và trong bối cảnh của câu hỏi thực tế, tôi muốn thêm một cái gì đó. Sau khi gỡ lỗi container của chúng tôi bằng cách sử dụng, docker attach container_namesử dụng ctrl pctrl qthay vì exit. exitlệnh dừng container, nơi ctrlpctrl qchỉ cần tách container đó và giữ cho nó chạy
phoenix

10

Vì mọi thứ đang nhức nhối, hiện tại cách thức được khuyến nghị truy cập vào một container đang chạy đang sử dụng nsenter.

Bạn có thể tìm thêm thông tin về kho github này . Nhưng nói chung bạn có thể sử dụng nsenter như thế này:

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

hoặc bạn có thể sử dụng trình bao bọc docker-enter:

docker-enter <container_name_or_ID>

Một lời giải thích hay về chủ đề này có thể được tìm thấy trên mục blog của Jérôme Petazzoni: Tại sao bạn không cần chạy sshd trong các thùng chứa docker của bạn


Thật không may, các biến env bị rối khi sử dụng phương pháp này (nếu bạn muốn kiểm tra các biến được tạo bởi liên kết). Tôi đề nghị làm source /proc/*/environ.
Tomas Tomecek

8

Điều đầu tiên bạn không thể chạy

docker run "existing container" command

Bởi vì lệnh này đang mong đợi một hình ảnh chứ không phải một container và dù sao nó cũng sẽ dẫn đến một container mới được sinh ra (vì vậy không phải là thứ bạn muốn xem)

Tôi đồng ý với thực tế là với docker, chúng ta nên thúc đẩy bản thân suy nghĩ theo một cách khác (vì vậy bạn nên tìm cách để bạn không cần phải đăng nhập vào container), nhưng tôi vẫn thấy nó hữu ích và đây là cách tôi làm việc xung quanh nó.

Tôi chạy các lệnh của mình thông qua người giám sát trong chế độ DEAMON.

Sau đó, tôi thực hiện những gì tôi gọi docker_loop.sh Nội dung là khá nhiều này:

#!/bin/bash
/usr/bin/supervisord
/usr/bin/supervisorctl
while ( true )
    do
    echo "Detach with Ctrl-p Ctrl-q. Dropping to shell"
    sleep 1
    /bin/bash
done

Những gì nó làm là cho phép bạn "đính kèm" vào container và được trình bày với supervisorctlgiao diện để dừng / khởi động / khởi động lại và kiểm tra nhật ký. Nếu điều đó không đủ, bạn có thể Ctrl+Dvà bạn sẽ rơi vào một cái vỏ cho phép bạn có một cái nhìn xung quanh như thể đó là một hệ thống bình thường.

XIN VUI LÒNG CÒN VÀO TÀI KHOẢN rằng hệ thống này không an toàn như có container mà không có vỏ, vì vậy hãy thực hiện tất cả các bước cần thiết để bảo vệ container của bạn.


5

Theo dõi yêu cầu kéo này: https://github.com/docker/docker/pull/7409

Mà thực hiện các docker exec <container_id> <command>tiện ích sắp tới . Khi điều này khả dụng, có thể bắt đầu và dừng dịch vụ ssh bên trong một container đang chạy.

Ngoài ra còn có nsinitđể làm điều này: "nsinit cung cấp một cách thuận tiện để truy cập shell trong không gian tên của bộ chứa đang chạy" , nhưng có vẻ khó chạy. https://gist.github.com/ubergarm/ed42ebbea293350c30a6


docker exechạ cánh trong Docker 1.3, vì vậy giờ đây có thể tạo và tham gia phiên shell mới trong một container đang chạy
foz


1

Thực sự có một cách để có một vỏ trong container.

Giả sử bạn /root/run.shkhởi chạy quy trình, người quản lý quy trình (người giám sát) hoặc bất cứ điều gì.

Tạo /root/runme.shvới một số thủ thuật màn hình gnu:

# Spawn a screen with two tabs
screen -AdmS 'main' /root/run.sh
screen -S 'main' -X screen bash -l
screen -r 'main'

Bây giờ, bạn có trình nền của mình trong tab 0 và trình bao tương tác trong tab 1. docker attachbất cứ lúc nào để xem những gì đang xảy ra bên trong container.

Một lời khuyên khác là tạo một hình ảnh "gói phát triển" trên đầu của hình ảnh sản xuất với tất cả các công cụ cần thiết, bao gồm cả thủ thuật màn hình này.


1

đây là giải pháp của tôi

một phần của DOckerfile:

...
RUN mkdir -p /opt
ADD initd.sh /opt/
RUN chmod +x /opt/initd.sh
ENTRYPOINT ["/opt/initd.sh"]

một phần của "initd.sh"

#!/bin/bash
...
/etc/init.d/gearman-job-server start
/etc/init.d/supervisor start
#very important!!!
/bin/bash

Sau khi hình ảnh được xây dựng, bạn có hai tùy chọn bằng cách sử dụng exec và đính kèm:

  1. với exec (mà tôi sử dụng), chạy:

chạy docker - tên $ CONTAINER_NAME -dt $ IMAGE_NAME

sau đó

người thực hiện docker -it $ CONTAINER_NAME / bin / bash

Và sử dụng

CTRL + D để tách

  1. với đính kèm, chạy:

chạy docker --name $ CONTAINER_NAME -dit $ IMAGE_NAME

sau đó

docker đính kèm $ CONTAINER_NAME

Và sử dụng

CTRL + P và CTRL + Q để tách ra

sự khác biệt giữa các tùy chọn là trong tham số -i


1

Có hai cách.

Có đính kèm

$ sudo docker attach 665b4a1e17b6 #by ID

Với exec

$ sudo docker exec - -t 665b4a1e17b6 #by ID


0

Tên gán hữu ích khi chạy container. Bạn không cần tham khảo container_id.

docker run --name container_name yourimage docker exec -it container_name bash


0

đầu tiên, lấy id container của container mong muốn bằng cách

docker ps

bạn sẽ nhận được một cái gì đó như thế này:

CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                          PORTS                    NAMES
3ac548b6b315        frontend_react-web     "npm run start"     48 seconds ago      Up 47 seconds                   0.0.0.0:3000->3000/tcp   frontend_react-web_1

Bây giờ sao chép id container này và chạy lệnh sau:

docker exec -it container_id sh

docker exec -it 3ac548b6b315 sh


-2

Có lẽ bạn đã lầm tưởng như chính tôi khi nghĩ về máy ảo khi phát triển container. Lời khuyên của tôi: Cố gắng không.

Container cũng giống như bất kỳ quá trình khác. Thật vậy, bạn có thể muốn "đính kèm" với chúng cho mục đích gỡ lỗi (nghĩ về / Proc // env hoặc strace -p) nhưng đó là một trường hợp rất đặc biệt.

Thông thường bạn chỉ "chạy" quy trình, vì vậy nếu bạn muốn sửa đổi cấu hình hoặc đọc nhật ký, chỉ cần tạo một thùng chứa mới và đảm bảo bạn viết nhật ký bên ngoài nó bằng cách chia sẻ thư mục, ghi vào thiết bị xuất chuẩn (để nhật ký docker hoạt động) hoặc điều tương tự.

Đối với mục đích gỡ lỗi, bạn có thể muốn bắt đầu một trình bao, sau đó là mã của bạn, sau đó nhấn CTRL-p + CTRL-q để giữ nguyên trình bao. Bằng cách này bạn có thể gắn lại bằng cách sử dụng:

docker attach <container_id>

Nếu bạn muốn gỡ lỗi container vì nó đang làm điều gì đó mà bạn không mong đợi, hãy thử gỡ lỗi: /server/596994/how-can-i-debug-a-docker-container -initialization


Điều này là hoàn toàn sai. Có thể hướng nội không gian tên LXC mà ứng dụng của bạn đang chạy không phải là "trường hợp rất đặc biệt", đây là hoạt động phổ biến / hàng ngày cho bất kỳ nhà phát triển nào.
ngủ

@s ngủycal "bất kỳ nhà phát triển" nghe có vẻ hơi thiên vị. Trong mọi trường hợp, tôi sử dụng hướng nội của các quy trình để điều tương tự áp dụng cho các container. Đó là ý tưởng đằng sau việc gỡ lỗi. Bạn đính kèm trình gỡ lỗi vào quy trình (có thể có cli). Nghĩ rằng bạn "đang" đăng nhập vào thùng chứa âm thanh vẫn gây hiểu lầm cho tôi.
estani

-4

Không, điều này là không thể. Sử dụng một cái gì đó như supervisordđể có được một máy chủ ssh nếu cần thiết. Mặc dù, tôi chắc chắn đặt câu hỏi về sự cần thiết.

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.