獲得 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
最後修改日期: 2020-05-01