如何避免Dockerdocker 容器启动退出脚本运行后自动退出

如何进入 Docker 容器 - 技术翻译 - 开源中国社区
如何进入 Docker 容器
【已翻译100%】
英文原文:
推荐于 2年前 (共 5 段, 翻译完成于 07-24)
参与翻译&(2人)&: ,
在前几篇文章[,,]里,简单地介绍了使用Docker进行系统级虚拟化。在这篇文章里,我将讨论四种连接Docker容器并与其进行交互的方法。例子中所有的代码都可以在中找到,你可以亲自对它们进行测试。
从util-linux版本2.23开始,nsenter工具就包含在其中。它用来访问另一个进程的名字空间。nsenter要正常工作需要有root权限。很不幸,Ubuntu 14.4仍然使用的是util-linux版本2.20。安装最新版本的util-linux(2.24)版,请按照以下步骤:
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-ncursesmake&nsentercp&nsenter&/usr/local/bin
为了连接到容器,你还需要找到容器的第一个进程的PID。
docker&inspect&--format&"{{&.State.Pid&}}"&&container-id&
通过这个PID,你就可以连接到这个容器:
nsenter&--target&$PID&--mount&--uts&--ipc&--net&--pid
&翻译得不错哦!
从0.9版本开始,Docker自身就具有一个管理容器的库,名字为 。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//dotcloudcd&$GOPATH//dotcloud
&git&clone&/dotcloud/docker.gitcd&$GOPATH//dotcloud/docker
&/usr/bin/go&get&-v&/dotcloud/docker/vendor//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
&翻译得不错哦!
上面所有三种方法都要求具有主机系统的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 容器操作退出后进入解决办法
作者:小白ing
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了Docker 容器操作退出后进入解决办法的相关资料,需要的朋友可以参考下
在我们对Docker容器操作的时候,有时候会误操作或者其他的原因无意间退出了正在操作的容器,也许你会担忧你在其中的一些操作未保存下来,无须担忧,本文中将会提供各种方法供你参考(我的建议使用最后一种)。在本文,我们将讨论五种(4+1)连接Docker容器并与其进行交互的方法。例子中所有的代码都可以在GitHub中找到,你可以亲自对它们进行测试。
nsenter 工具在 util-Linux 包2.23版本后包含。 如果系统中 util-linux 包没有该命令,可以按照下面的方法从源码安装。
你也可以点击此链接进行下载& /s/1FEt8y
$ cd / curl
| tar -zxf-; cd util-linux-2.24;&
$ ./configure --without-ncurses&
$ make nsenter && sudo cp nsenter /usr/local/bin&
nsenter 可以访问另一个进程的名字空间。nsenter 要正常工作需要有 root 权限。 很不幸,Ubuntu 14.4 仍然使用的是 util-linux 2.20。安装最新版本的 util-linux(2.24)版,请按照以下步骤:
$ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar. tar xzvf util-linux-2.24.tar.gz
$ cd util-linux-2.24
$ ./configure --without-ncurses && make nsenter
$ sudo cp nsenter /usr/local/bin
从util-linux版本2.23开始,nsenter工具就包含在其中。它用来访问另一个进程的名字空间。nsenter要正常工作需要有root权限。很不幸,Ubuntu 14.4仍然使用的是util-linux版本2.20。安装最新版本的util-linux(2.24)版,请按照以下步骤:
为了连接到容器,你还需要找到容器的第一个进程的PID,通过这个PID,你就可以连接到这个容器:
$ docker inspect --format "{{ .State.Pid }}" &container-id&
//or run 'docker inspect -f "{{ .State.Pid }}" &container-id&'
$ nsenter --target $PID --mount --uts --ipc --net --pid
从0.9版本开始,Docker自身就具有一个管理容器的库,名字为 libcontainer。libcontainer中的nsinit工具允许用户直接访问linux名字空间和cgroup内核。在安装nsinit之前,你首先需要安装Go运行时环境:
$ apt-get installgit 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:
$ apt-get installgit 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读取的是位于/var/lib/docer/execdriver/native/&Container-id&容器目录下的配置数据。要运行nsinit,你需要切换到容器目录下。由于/var/lib/docker目录对于root用户是只读权限,因此你还需要root权限。通过docker的ps命令,你可以确定容器ID。一旦你进入/var/lib/docker目录,你就可以连接容器了:
nsinit exec /bin/bash&
3.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&
上面所有三种方法都要求具有主机系统的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博客文章里对这一点说的很透彻。&
上面的几种方法我也曾试过,他们基本上都是进入正在运行中的容器,nsenter还可实现多终端对一个容器的操作。如果进入已经终止的容器,第一次安装执行的时候是可以的,可以得到PID的值,不过之后再执行的时候发现PID的值为0,如果你接着执行
&del&nsenter --target $PID --mount --uts --ipc --net --pid&/del&&
你会发现 切换到了宿主机的超级管理员权限。
正确的方法会在下面介绍,首先先补充一下一些命令的参数的含义:
&&& docker images: 列出images
&&& docker images -a :列出所有的images(包含历史)
&&& docker images --tree :显示镜像的所有层(layer)
&&& docker rmi& &image ID&: 删除一个或多个image
&&& docker ps :列出当前所有正在运行的container
&&& docker ps -l :列出最近一次启动的container
&&& docker ps -a :列出所有的container(包含历史,即运行过的container)
&&& docker ps -q :列出最近一次运行的container ID
&5.重点来了:
$ docker ps -a
CONTAINER ID
9cff554fb6d7
ubuntuold:14.04
About an hour ago
Up About an hour
condescending_blackwell
e5c5498881ed
ubuntuold:14.04
About an hour ago
Exited (0) 55 minutes ago backstabbing_bardeen
&&& 通过以上的信息可以看出两者之间的差别:前者是正在运行的容器;而后者是已经终止的容器(Exited(0))。
&&& docker start/stop/restart&container& :开启/停止/重启container
&&& docker start [container_id] :再次运行某个container(包括历史container)
&&& docker attach [container_id]:连接一个正在运行的container实例(即实例必须为start状态,可以多个窗口同时attach一个container实例)
&&& docker start -i &container&:启动一个container并进入交互模式(相当于先start,在attach)&
就以后者e5c5498881ed为例:首先执行
$ docker start e5c5498881ed
//之后再一次查看的时候Exited(0)已经没有了,也就是说明该容器已经从终止的状态变为了正在运行的状态
$docker attach e5c5498881ed
//你会的发现已经进入该容器了,而且之前的操作的文件依然存在
//如果没有反应的话,再一次点击回车即可
&&& docker run -i -t &image& /bin/bash:使用image创建container并进入交互模式, login shell是/bin/bash
&&& docker run -i -t -p &host_port:contain_port&:映射 HOST 端口到容器,方便外部访问容器内服务,host_port 可以省略,省略表示把 container_port映射到一个动态端口。
&& 注:使用start是启动已经创建过得container,使用run则通过image开启一个新的container。
查看root密码
&& docker容器启动时的root用户的密码是随机分配的。所以,通过这种方式就可以得到容器的root用户的密码了。
docker logs f6e 2&&1 | grep 'User: ' | tail -n1&
&感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具在Linux下的Docker中新建容器的方法
作者:佚名
字体:[ ] 来源:开源中文社区 时间:05-28 16:14:49
这篇文章主要介绍了在Linux下的Docker中新建容器的方法,文中的示例基于CentOS系统和Apache服务器,需要的朋友可以参考下
大家好,今天我们来学习如何使用一个docker镜像交互式地创建一个Docker容器。当我们从镜像中启动一个Docker进程,Docker就会获取该镜像及其父镜像,并重复这个过程,直到到达基础镜像。然后联合文件系统(UFS)会在其顶层添加一个读写层。读写层被称之为容器,它包含了一些关于父镜像信息及一些其他的信息,如唯一ID,网络配置和资源限制等。容器是有状态的,其状态可以从 运行态 切换到 退出态。一个处于 运行态的容器包含了在CPU上面运行的进程树,于其它在该主机上运行的进程相隔离,而退出态是指文件系统的状态,并保留了其退出值。你可以使用它来启动,停止和重启一个容器。
Docker技术为IT界带来了巨大的改变,它使得云服务可以用来共享应用和工作流程自动化,使得应用可以用组件快速组合,消除了开发、品质保证、产品环境间的摩擦。在这篇文章中,我们将会建立CentOS环境,然后用Apache网络服务器提供一个网站服务。这是一个快速且容易的教程,讨论我们怎样使用交互的shell,以交互的方式来创建一个容器。1. 运行一个Docker实例
Docker首先会尝试从本地取得并运行所需的镜像,如果在本地主机上没有发现,它就会从Docker公共注册中心拉取。这里,我们将会拉取镜像并在 Docker 容器中创建一个fedora实例,并连接到它的 tty 上的bash shell。
&&&代码如下:# docker run -i -t fedora bash&&&&
&&& 2.安装Apache网络服务器
现在,在我们的Fedora基本镜像实例准备好后,我们将会开始交互式地安装Apache网络服务器,而不是为它创建Dockerfile。为了做到这点,我们需要在终端或者shell运行以下命令。
&&&代码如下:# yum update
&&&代码如下: # yum install httpd &&&
&&& 退出容器的 tty。
&&&代码如下:# exit
3.保存镜像
现在,我们要去保存在Fedora实例里做的修改。要做到这个,我们首先需要知道实例的容器ID。而为了得到ID,我们又需要运行以下命令(LCTT 译注:在容器外执行该命令)。
&&&代码如下:# docker ps -a
&&& 然后,我们会保存这些改变为一个新的镜像,请运行以下命令。
&&&代码如下:# docker commit cfe fedora-httpd
&&& 这里,修改已经通过使用容器ID保存起来了,镜像名字叫fedora-httpd。为了确认新的镜像是否在运行,我们将运行以下命令。
&&&代码如下:# docker images&&&&
&&& 4. 添加内容到新的镜像
我们自己新的Fedora Apache镜像正成功的运行,现在我们想添加一些我们网站的网页内容到Apache网络服务器,使得网站能够开箱即用。为做到这点,我们需要创建一个新的Dockerfile,它会处理从复制网页内容到启用80端口的所有操作。要达到这样的目的,我们需要使用我们最喜欢的文本编辑器创建Dockerfile文件,像下面演示的一样。
&&&代码如下:# nano Dockerfile
现在,我们需要添加以下的命令行到文件中。
&&&代码如下: FROM fedora-httpd
ADD mysite.tar /tmp/
RUN mv /tmp/mysite/* /var/www/html
ENTRYPOINT [ "/usr/sbin/httpd" ]
CMD [ "-D", "FOREGROUND" ]
&&& 这里,上述的Dockerfile中,放在mysite.tar里的网页内容会自动解压到/tmp/文件夹里。然后,整个站点会被移动到Apache的网页根目录/var/www/html/,命令expose 80会打开80端口,这样网站就能正常访问了。其次,入口点放在了/usr/sbin/https里面,保证Apache服务器能够执行。5. 构建并运行一个容器 
现在,我们要用刚刚创建的Dockerfile创建我们的容器,以便将我们的网站添加到上面。为做到这,我们需要运行以下命令。
&&&代码如下: # docker build -rm -t mysite&&&&
&&& 建立好我们的新容器后,我们需要要用下面的命令来运行容器。
&&&代码如下:# docker run -d -P mysite&&
大家感兴趣的内容
12345678910
最近更新的内容Kill 容器内进程后_docker容器云吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:18贴子:
Kill 容器内进程后
让Docker使用更方便的Exec我们在应用容器的过程中,无论是在通过Dockerfile在调试构建镜像的过程,还是容器运行一段时间想查看内部结构,我们还是希望能像操作本地机器一样,实时的查看容器内部文件,代码或者日志。或是修改文件,拷贝文件目录等等。1.Docker自带的exec命令访问容器内部,目前有两种方法2. Nsenter工具来说说Docker exec 命令方式访问如图所示,简单的ls命令。Linux系统自带的命令都可以通过这种方式运行。文件放错位置了,mv一下,查看log,就cat log.log一下,等等。
有容云docker容器云平台,实现企业应用商店,友好图形化界面管理,多环境管理,混合云支持,容器持久存储,容器可扩展性,API接口支持等,全国咨询热线:400 998 1227
Exec加点料简单的操作不能满足我们对他的好奇...我们运行一下 docker exec -ti 61f ps -ef
发现只有3个进程,进程1是CMD命令启动的脚本;进程2是脚本启动的程序;进程3是我们运行ps -ef的进程。出于好奇,我又docker exec 9fe0 kill 15容器从此就停止了...原因是杀掉进程后,Dockerfile指定的CMD[&/run.sh&]脚本运行结束,CMD入口已经退出,导致容器退出。问题还没结束
Kubernetes是一个基于docker的容器集群管理系统,它的一大特点是拥有Replication Controllers,他的作用主要是保持所起动的Pod数量不变(pod里面装的是container)。我猜想如果类似的kill掉容器内部的进程,那么kubernetes应该会让这个container重新启动。于是就来动手试试。时速云他们应用了kubernetes,并且提供了客户端tce可以使用exec功能。运行 tce exec bbb-145fv-zkdqz ps -eftce exec bbb-145fv-zkdqz kill 15没有重启??再次运行 tce exec bbb-145fv-zkdqz ps -ef又出现了。由此可见Kubernentes的Replication Controllers还是很强大的。保证了集群中有指定数量的pod副本在运行。
原文链接:
作者:软件工程师丁麒伟
贴吧热议榜
使用签名档&&
保存至快速回贴

我要回帖

更多关于 docker 容器启动脚本 的文章

 

随机推荐