Làm cách nào để đưa bash hoặc ssh vào một container đang chạy ở chế độ nền?


933

Tôi muốn ssh hoặc bash vào một container đang chạy. Xin vui lòng, xem ví dụ:

$ sudo docker run -d webserver
webserver is clean image from ubuntu:14.04
$ sudo docker ps
CONTAINER ID  IMAGE            COMMAND    CREATED STATUS  PORTS          NAMES
665b4a1e17b6  webserver:latest /bin/bash  ...     ...     22/tcp, 80/tcp loving_heisenberg 

bây giờ tôi muốn nhận được một cái gì đó như thế này (đi vào container đang chạy):

$ sudo docker run -t -i webserver (or maybe 665b4a1e17b6 instead)
$ root@665b4a1e17b6:/# 
However when I run the line above I get new CONTAINER ID
$ root@42f1e37bd0e5:/#

Tôi đã sử dụng Vagrant và tôi muốn có một hành vi tương tự như vagrant ssh.


cách khác sudo docker exec -i -t 665b4a1e17b6 /bin/shđể có thể cài đặt các chương trình và gói apt
fonjeekay

1
Lưu ý rằng sử dụng SSH để bash vào container đang chạy là một cách thực hành kém - xem lý do tại đây . sudo docker exec -i -t container-name /bin/bashlà một cách để đi
patryk.beza

Câu trả lời:


1307

Câu trả lời là attachlệnh của Docker . Vì vậy, với ví dụ của tôi ở trên, giải pháp sẽ là:

$ sudo docker attach 665b4a1e17b6 #by ID
or
$ sudo docker attach loving_heisenberg #by Name
$ root@665b4a1e17b6:/#

Đối với Docker phiên bản 1.3 trở lên: Nhờ người dùng WiR3D , người đã đề xuất một cách khác để lấy vỏ của người chứa. Nếu chúng ta sử dụng, attachchúng ta chỉ có thể sử dụng một thể hiện của trình bao. Vì vậy, nếu chúng ta muốn mở một thiết bị đầu cuối mới với phiên bản mới của vỏ chứa, chúng ta chỉ cần chạy như sau:

$ sudo docker exec -i -t 665b4a1e17b6 /bin/bash #by ID

hoặc là

$ sudo docker exec -i -t loving_heisenberg /bin/bash #by Name
$ root@665b4a1e17b6:/#

5
Hoặc, thực hiệnsudo docker attach loving_heisenberg
Thiago Perrotta

51
lệnh đính kèm không hoạt động đối với tôi, nó làm cho docker đóng băng .. có ý tưởng nào tại sao nó xảy ra không?
Mo J. Mughrabi

10
Một lời nhắc cho người dùng boot2docker: xóa sudo :)
Henno

17
-i -tbằng-it
pasha.zhukov

47
Đây là một câu trả lời nguy hiểm được lựa chọn và rất được bình chọn. docker attachví dụ, vào một cá thể MongoDB, sẽ giết cá thể đó. Như đã giải thích chi tiết hơn trong câu hỏi này attachexeclà những động vật khác nhau.
fwc

675

Từ Docker 1.3 trở đi:

docker exec -it <containerIdOrName> bash

Về cơ bản, nếu bộ chứa Docker đã được bắt đầu bằng /bin/bashlệnh bạn có thể truy cập nó bằng cách sử dụng attach. Nếu không, thì bạn cần phải thực thi lệnh để tạo một cá thể Bash bên trong container bằng cách sử dụng exec.

Ngoài ra để thoát Bash mà không để Bash chạy trong một quá trình giả mạo:

exit

Đúng, nó đơn giản.


vẫn chưa tìm ra cách để nano hoạt động. Điều này có thể liên quan đến docker-ssh từ phusion
WiR3D

Có cách nào để đặt bash theo mặc định trong docker không?
ipeacocks

@ipeacocks có, nếu RUNlệnh trong dockerfile là /bin/bash. Nhưng phụ thuộc vào ý của bạn. Nếu bạn muốn chạy container và có sẵn bash ngay trong cùng một thiết bị đầu cuối thì hãy chạy với -it
WiR3D

10
Sử dụng nhóm docker là thực hành xấu. Bất kỳ người dùng nào trong nhóm docker về cơ bản được sử dụng với quyền root mà không cần sử dụng sudo. projectatomic.io/blog/2015/08/ từ
Maiku Mori

1
Tôi nghĩ rằng nó không tạo ra nhiều khác biệt, từ quan điểm bảo mật máy chủ, cho dù bạn sử dụng sudoso với dockernhóm. Dù bằng cách nào, có một lỗ hổng bảo mật được tích hợp trong docker có thể cung cấp đầy đủ các đặc quyền trong hệ thống tệp máy chủ từ khách - bất kể bạn sử dụng nhóm docker hay sudođể khởi chạy container.
tộc

123

Mặc dù tác giả của câu hỏi nói cụ thể họ quan tâm đến một container đang chạy, nhưng cũng đáng lưu ý rằng nếu container không chạy, nhưng bạn muốn chạy nó để chọc xung quanh bạn có thể chạy:

docker run -i -t --entrypoint /bin/bash <imageID>


10
Điều đó mang lại một container khác, giống như câu trả lời của @ kraxor.
Blaisorblade


19

Dựa trên câu trả lời của @ Timur Tôi đã tạo tập lệnh tiện dụng sau đây

Thiết lập

Đặt docker-sshtệp trong của bạn $PATHvới các nội dung sau đây

#!/bin/bash -xe

# docker container id or name might be given as a parameter
CONTAINER=$1

if [[ "$CONTAINER" == "" ]]; then
  # if no id given simply just connect to the first running container
  CONTAINER=$(docker ps | grep -Eo "^[0-9a-z]{8,}\b")
fi

# start an interactive bash inside the container
# note some containers don't have bash, then try: ash (alpine), or simply sh
# the -l at the end stands for login shell that reads profile files (read man)
docker exec -i -t $CONTAINER bash -l

Lưu ý : Một số container không chứa bash, nhưng ash, shv.v ... Trong những trường hợp này bashsẽ được thay thế trong đoạn script trên.

Sử dụng

Nếu bạn chỉ có một phiên bản đang chạy, chỉ cần chạy

$> docker-ssh 

Mặt khác, cung cấp cho nó một tham số id docker mà bạn nhận được từ docker ps(col đầu tiên)

$> docker-ssh 50m3r4nd0m1d

Tôi có thể biết tại sao chúng ta cần -l vào cuối không?
Nam G VU

để bắt đầu bash như một vỏ đăng nhập, đọc các tham số môi trường (được mô tả trong dòng phía trên lệnh)
Matyas

13

Nếu container của bạn chưa cài đặt bash, bạn có thể thử sh:

docker exec -it CONTAINER /bin/sh

Hoặc tìm vỏ trong / bin trước:

docker export CONTAINER|tar -t|egrep ^bin/

Là gì "lãnh" ? Bạn có một tài liệu tham khảo cho nó? Bạn có nghĩa là "bàn điều khiển" ?
Peter Mortensen

9

Tôi đã tạo một máy chủ SSH được đóng gói cung cấp khả năng SSH cho bất kỳ vùng chứa nào đang chạy. Bạn không cần phải thay đổi container của bạn. Yêu cầu duy nhất là container có bash.

Nếu bạn có một thùng chứa có tên 'web-server1'. Lệnh chạy docker sau đây sẽ bắt đầu một container thứ hai sẽ cung cấp SSH cho container đầu tiên.

docker run -ti --name sshd-web-server1 -e CONTAINER=web-server1 -p 2222:22 \
-v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker \
jeroenpeeters/docker-ssh

Để biết thêm con trỏ, hãy kiểm tra https://github.com/jeroenpeeter/docker-ssh


Đây phải là câu trả lời được chấp nhận ^
Nam G VU

Nhân tiện, làm thế nào chúng ta có thể tải .bashrc tự động khi bắt đầu phiên ssh bằng giải pháp của bạn? Cũng đã đăng một vấn đề trên github github.com/jeroenpeeter/docker-ssh/issues/30
Nam G VU

6

@jpetazzo có một bài viết tuyệt vời về chủ đề này . Câu trả lời ngắn sẽ là sử dụng nsenter:

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

PS: Đừng quên kiểm tra các cuộc thảo luận trong các bình luận của bài viết ...

Chúc mừng


1
Đó là một bài viết khá cũ mà không còn thực sự cần thiết . docker execGiải pháp của @ WiR3D khá thuận tiện.
drevicko

4

Bạn cũng có thể cung cấp cho bộ chứa Docker một địa chỉ IP có thể định tuyến bằng Pipework và sau đó SSH vào máy có địa chỉ IP mới đó.

Điều này sẽ mang tính "truyền thống" hơn (ssh), thay vì sử dụng một lệnh dành riêng cho ứng dụng như thế docker attach, và cuối cùng sẽ làm cho nó trở nên 'di động' hơn trên các hệ thống và phiên bản.


Xin vui lòng, thêm các cách mô phỏng làm thế nào để làm điều đó. Nếu thành thật mà nói, tôi thực sự cần nó, nhưng tôi không có thời gian để tìm kiếm giải pháp đơn giản nhất cho việc đó. Bạn có thể gửi câu trả lời của bạn ở đây? Nó sẽ rất tuyệt ..
Timur Fayzrakhmanov

2
Có 2 cách để thực hiện điều này, nhưng nó không đơn giản và sẽ trở thành một bài viết lớn. Bạn có thể tự kiểm tra liên kết này , để sử dụng pipework hoặc liên kết này , phù thủy về cơ bản hoàn thành giống như Pipework và đơn giản hơn một chút, nhưng bạn cần thực hiện thủ công. Vì vậy, nó phụ thuộc vào bao nhiêu máy chủ nói chuyện. Nếu bạn không thể tìm ra một cái gì đó cụ thể hơn, hãy cho tôi biết. Nhưng tôi cũng không có thời gian để viết một bài hướng dẫn đầy đủ.
radriaanse

Bạn đã đúng - không có cách rõ ràng và đơn giản để làm điều đó (Cảm ơn các liên kết, tôi nghĩ rằng tôi sẽ xem lại sau.
Timur Fayzrakhmanov



1

ĐI VÀO BÊN TRONG

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 đầu cuối thích hợp với:

goinside docker_container_name

để biết thêm chi tiết kiểm tra này .


0

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

docker exec -t -i container_name /bin/bash

1
đây là câu trả lời tương tự như @AdamKalnas
Bruni

0

Chỉ để biết thông tin. Nếu bạn cần đăng nhập vào một thùng chứa đơn giản không phải là daemon, bạn cần sử dụng các lệnh sau:

docker start {id}
docker attach {id}

-1

nếu bộ chứa bị dừng như ví dụ bộ chứa chỉ có dữ liệu thì một giải pháp tốt là chạy bộ chứa bỏ đi mỗi khi bạn muốn gắn vào bộ chứa dữ liệu. Trong trường hợp này, bộ chứa dữ liệu có thể hoàn toàn trống, vì bộ chứa tạm thời sẽ có các công cụ HĐH.

$ docker run --rm --volumes-from mydata -it ubuntu bash
root@645045d3cc87:/# ls /mydata
root@645045d3cc87:/# touch /mydata/foo
root@645045d3cc87:/# exit
exit
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.