獲得 Shell 後可以對容器內容做一些修改及監控,或是進一步了解作者在 Image 中包了哪些東西,Docker 容器服務若已經啟動,在不影響服務正常運行的情況下想要獲得 Shell 的話,最方便的應該就是容器開發模式中使用 nsenter 的方式。網路上眾多安裝 nsenter 方式以這個命令最簡便,不需額外套件與編譯直接安裝:
安裝方法
docker run -v /usr/local/bin:/target jpetazzo/nsenter
其 Github 的項目地址在:https://github.com/jpetazzo/nsenter 有興趣的朋友可以多多關注這個項目。
使用方式
先取得容器的 PID
PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
根據 PID 獲得 Shell
$ sudo nsenter --target $PID --mount --uts --ipc --net --pid
簡化為 Shell Script <enter-cnt.sh>:
#!/bin/bash echo "Looking PID for $1: " PID=$(docker inspect --format {{.State.Pid}} $1) echo $PID sudo nsenter --target $PID --mount --uts --ipc --net --pid ss_2016-02-28_21-08-56
網路上也有網友提供一個較複雜的 Shell 腳本 (轉自 http://www.hjue.me/post/docker-nsenter) 需要的朋友也可以參考:
#!/bin/sh if [ -e $(dirname "$0")/nsenter ]; then # with boot2docker, nsenter is not in the PATH but it is in the same folder NSENTER=$(dirname "$0")/nsenter else NSENTER=nsenter fi if [ -z "$1" ]; then echo "Usage: `basename "$0"` CONTAINER [COMMAND [ARG]...]" echo "" echo "Enters the Docker CONTAINER and executes the specified COMMAND." echo "If COMMAND is not specified, runs an interactive shell in CONTAINER." else PID=$(docker inspect --format "{{.State.Pid}}" "$1") if [ -z "$PID" ]; then exit 1 fi shift OPTS="--target $PID --mount --uts --ipc --net --pid --" if [ -z "$1" ]; then # No command given. # Use su to clear all host environment variables except for TERM, # initialize the environment variables HOME, SHELL, USER, LOGNAME, PATH, # and start a login shell. "$NSENTER" $OPTS su - root else # Use env to clear all host environment variables. "$NSENTER" $OPTS env --ignore-environment -- "$@" fi fi