docker_practice/container/enter.md

87 lines
3.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

## 进入容器
在使用 `-d` 参数时,容器启动后会进入后台。
某些时候需要进入容器进行操作,有很多种方法,包括使用 `docker attach` 命令或 `nsenter` 工具等。
### attach 命令
`docker attach` 是 Docker 自带的命令。下面示例如何使用该命令。
```bash
$ docker run -idt ubuntu
243c32535da7d142fb0e6df616a3c3ada0b8ab417937c853a9e1c251f499f550
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
243c32535da7 ubuntu:latest "/bin/bash" 18 seconds ago Up 17 seconds nostalgic_hypatia
$ docker attach nostalgic_hypatia
root@243c32535da7:/#
```
但是使用 `attach` 命令有时候并不方便。当多个窗口同时 attach 到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。
### nsenter 命令
#### 安装
`nsenter` 工具在 util-linux 包2.23版本后包含。
如果系统中 util-linux 包没有该命令,可以按照下面的方法从源码安装。
```bash
$ cd /tmp; curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-; cd util-linux-2.24;
$ ./configure --without-ncurses
$ make nsenter && sudo cp nsenter /usr/local/bin
```
#### 使用
`nsenter` 启动一个新的shell进程(默认是/bin/bash), 同时会把这个新进程切换到和目标(target)进程相同的命名空间这样就相当于进入了容器内部。nsenter 要正常工作需要有 root 权限。
很不幸Ubuntu 14.04 仍然使用的是 util-linux 2.20。安装最新版本的 util-linux2.29)版,请按照以下步骤:
```bash
$ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.29/util-linux-2.29.tar.xz; tar xJvf util-linux-2.29.tar.xz
$ cd util-linux-2.29
$ ./configure --without-ncurses && make nsenter
$ sudo cp nsenter /usr/local/bin
```
为了连接到容器,你还需要找到容器的第一个进程的 PID可以通过下面的命令获取。
```bash
PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
```
通过这个 PID就可以连接到这个容器
```bash
$ nsenter --target $PID --mount --uts --ipc --net --pid
```
如果无法通过以上命令连接到这个容器有可能是因为宿主的默认shell在容器中并不存在比如zsh可以使用如下命令显式地使用bash。
```bash
$ nsenter --target $pid --mount --uts --ipc --net --pid -- /usr/bin/env \
--ignore-environment HOME=/root /bin/bash --login
```
下面给出一个完整的例子。
```bash
$ docker run -idt ubuntu
243c32535da7d142fb0e6df616a3c3ada0b8ab417937c853a9e1c251f499f550
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
243c32535da7 ubuntu:latest "/bin/bash" 18 seconds ago Up 17 seconds nostalgic_hypatia
$ PID=$(docker-pid 243c32535da7)
10981
$ sudo nsenter --target 10981 --mount --uts --ipc --net --pid
root@243c32535da7:/#
```
更简单的,建议大家下载
[.bashrc_docker](https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker),并将内容放到 .bashrc 中。
```bash
$ wget -P ~ https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker;
$ echo "[ -f ~/.bashrc_docker ] && . ~/.bashrc_docker" >> ~/.bashrc; source ~/.bashrc
```
这个文件中定义了很多方便使用 Docker 的命令,例如 `docker-pid` 可以获取某个容器的 PID`docker-enter` 可以进入容器或直接在容器内执行命令。
```bash
$ echo $(docker-pid <container>)
$ docker-enter <container> ls
```