阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

如何进入 Docker 容器

182次阅读
没有评论

共计 3307 个字符,预计需要花费 9 分钟才能阅读完成。

在前几篇文章 [1,2,3] 里,Lukas Pustina 简单地介绍了使用 Docker 进行系统级虚拟化。在这篇文章里,我将讨论四种连接 Docker 容器并与其进行交互的方法。例子中所有的代码都可以在 GitHub 中找到,你可以亲自对它们进行测试。

nsenter

从 util-linux 版本 2.23 开始,nsenter 工具就包含在其中。它用来访问另一个进程的名字空间。nsenter 要正常工作需要有 root 权限。很不幸,Ubuntu 14.4 仍然使用的是 util-linux 版本 2.20。安装最新版本的 util-linux(2.24)版,请按照以下步骤:

cd /tmp

为了连接到容器,你还需要找到容器的第一个进程的 PID。

docker inspect –format “{{.State.Pid}}” <container-id>

通过这个 PID,你就可以连接到这个容器:

nsenter –target $PID –mount –uts –ipc –net –pid

nsinit

从 0.9 版本开始,Docker 自身就具有一个管理容器的库,名字为 libcontainer。libcontainer 中的 nsinit 工具允许用户直接访问 linux 名字空间和 cgroup 内核。在安装 nsinit 之前,你首先需要安装 Go 运行时环境:

apt-get install git golang-go
mkdir -p $HOME/go-dev/binmkdir -p $HOME/go-dev/src
echo "export GOPATH=\$HOME/go-dev" >> ~/.profileecho "PATH=\$PATH:\$GOPATH/bin" >> ~/.profile
source ~/.profile

为了连接到容器,你还需要找到容器的第一个进程的 PID。

docker inspect –format “{{.State.Pid}}” <container-id>

通过这个 PID,你就可以连接到这个容器:

nsenter –target $PID –mount –uts –ipc –net –pid

nsinit

从 0.9 版本开始,Docker 自身就具有一个管理容器的库,名字为 libcontainer。libcontainer 中的 nsinit 工具允许用户直接访问 linux 名字空间和 cgroup 内核。在安装 nsinit 之前,你首先需要安装 Go 运行时环境:

apt-get install git golang-go

mkdir -p $HOME/go-dev/binmkdir -p $HOME/go-dev/src
echo "export GOPATH=\$HOME/go-dev" >> ~/.profileecho "PATH=\$PATH:\$GOPATH/bin" >> ~/.profile
source ~/.profile

接下来才安装 nsinit:

mkdir -p $GOPATH/src/github.com/dotcloudcd $GOPATH/src/github.com/dotcloud
git clone https://github.com/dotcloud/docker.gitcd $GOPATH/src/github.com/dotcloud/docker
/usr/bin/go get -v github.com/dotcloud/docker/vendor/src/github.com/docker/libcontainer/nsinit

nsinit 读取的是位于 /var/lib/docer/execdriver/native/<container-id> 容器目录下的配置数据。要运行 nsinit,你需要切换到容器目录下。由于 /var/lib/docker 目录对于 root 用户是只读权限,因此你还需要 root 权限。通过 docker 的 ps 命令,你可以确定容器 ID。一旦你进入 /var/lib/docker 目录,你就可以连接容器了:

nsinit exec /bin/bash

lxc(-attach)

直到 Docker 0.8.1 版本为止,LXC 一直是管理容器的基本工具,Docker 一直支持这个工具。但是从 0.9.0 版本开始,Docker 默认使用 libcontainer 管理容器,不再依赖 LXC 了。因此默认情况下,你不能使用 lxc-attach 了。

如果你仍然希望使用 lxc-attach,那么你需要使用 -e lxc 选项来重新启动 Docker 服务进程。使用这个选项,Docker 的内部将再次使用 LXC 管理容器了。完成这个任务最简单的做法就是创建 /etc/default/docker 文件(如果这个文件仍然不存在),并添加以下内容:

DOCKER_OPTS=” -e lxc”

现在你可以重新启动 Docker 服务了。要连接容器,你需要知道完整的容器 ID:

docker ps –no-trunc

接下来,你就可以连接这个容器了。要完成下面工作,你还需要 root 权限:

lxc-attach -n <container-id> — /bin/bash

sshd

上面所有三种方法都要求具有主机系统的 root 权限。为了不采用 root 权限,通过 ssh 访问容器将是一个很好的选择。

要做到这一点,你需要构建一个支持 SSH 服务的基础映像。此时,我们可能遇到这样的问题:我们是不是用 Docker CMD 或者 ENTRYPOINT 运行一条命令就可以了?如果此时有 sshd 进程运行,那么我们就不要再运行其他进程了。接下来的工作是创建一个脚本或者使用像 supervisord 这样的进程管理工具来启动其它所有需要启动的进程。有关如何使用 supervisord 的 优秀的文档可以在 Docker 的 web 站点上找到。一旦你启动了具有 sshd 进程的容器,你就可以像以往一样通过 ssh 客户端了连接这个容器了。

结论

sshd 方法可能是最简单的连接容器的方法,而且大多数用户习惯通过 ssh 连接虚拟机。另外,连接容器时你也不需要一定使用 root 权限。不过,对于是否一个容器是否应当管理不止一个进程仍然存在许多争议。这种方法最终使得每个容器了多了一个 sshd 进程,这从根本上来说不是进程虚拟化的所提倡的。

另外三种方法都需要 root 权限。到 0.8.1 版本为止,Docker 都是使用 LXC 来管理容器的。正是由于这个原因,使用 lxc-attach 连接容器就非常容易。不过从版本 0.9.0 开始 Docker 服务就必须使用 -e lxc 选项启动才能在内部支持 LXC 管理容器。不过,由于设置了这个选项,Docker 将再次依赖 LXC,而 LXC 可能随着发布或者安装的不同可能被剔除。

nsenter 和 nsinit 总的来说是相同的。这两个工具的主要区别是 nsinit 在本身的容器了建立了一个新的进程,而 nsenter 只是访问了名字空间。Jerome Petazzoni 在 Docker 博客文章里对这一点说的很透彻。

开源项目 Docker,Red Hat 新的虚拟化选择 http://www.linuxidc.com/Linux/2013-10/91051.htm

dockerlite: 轻量级 Linux 虚拟化 http://www.linuxidc.com/Linux/2013-07/87093.htm

Docker 的搭建 Gitlab CI 全过程详解 http://www.linuxidc.com/Linux/2013-12/93537.htm

Docker 和一个正常的虚拟机有何区别? http://www.linuxidc.com/Linux/2013-12/93740.htm

在 Docker 中使用 MySQL http://www.linuxidc.com/Linux/2014-01/95354.htm

Docker 将改变所有事情 http://www.linuxidc.com/Linux/2013-12/93998.htm

Docker 安装应用(CentOS 6.5_x64) http://www.linuxidc.com/Linux/2014-07/104595.htm

Docker 的详细介绍:请点这里
Docker 的下载地址:请点这里

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-20发表,共计3307字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中