1、运行ubuntu等容器
- 后台运行系统镜像
docker run -it -d ubuntu
- 直接运行镜像,退出后这个镜像也停止
docker run -it ubuntu
- 映射端口(22端口映射出来,一般代表可以通过ssh登录)
docker run -it -p 80:80 2222:22 -d ubuntu
- 映射文件夹
docker run -it -v /outer/tmp:/inner/tmp -d ubuntu
- 选择网络模式
docker run -it --net="host" -d ubuntu
2、操作容器
- 直接运行命令
docker exec -it Container-ID /bin/cat flag
- attach到容器中(限制极大,多个终端同时进行操纵时,容易发生冲突)
docker attach-it Container-ID
- 进入容器中运行指令
docker exec -it Container-ID /bin/bash
- 从容器内拷贝文件到主机上
docker cp \<containerId>:/file/path/within/container /host/path/target
- 从容器内拷贝文件到主机上
docker cp /host/path/target \<containerId>:/file/path/within/container
3、网络模式
(1) bridge模式
使用—net=bridge指定,为Docker的默认设置。这种模式是将容器用docker的网桥连接起来。
作为最常规的格式,bridge模式已经可以满足Docker容器最基本的使用需求。然而其在于外界通信使用NAT协议,增加了通信的复杂性,在复杂的场景下使用会有诸多限制。
(2) host模式
host模式下,容器不会拥有自己的网络命名空间。Docker容器中的进程处于宿主机的网络环境中,此时Docker容器和宿主机之间网络没有映射关系,外界可以通过该主机的IP地址、端口等进行Docker容器的访问。当然,除了network namespace外,其他内容宿主机是隔离的。host模式不用地址映射,可以直接使用宿主机的IP。但是也降低了隔离性,而且由于网络资源一直被竞争,所以可能造成网络的短暂不可用问题。
(3) container模式
container模式是指新创建的容器与已有的容器共享网络信息。在此种模式下,新创建的容器与指定的容器共享IP、端口等。当然,两个容器之间除了网络信息共享外,其它内容均不可共用。由于在这种模式下,两个容器的进程使用回环网卡通信,所以通讯速率加快了。container模式的主要用于部署多个相关的应用,最好能成为一个整体。由于container模式的特点,导致了这种模式隔离性不强,可能会存在安全隐患。
(4) none模式
none模式时,Docker拥有网络协议栈,但是没有对协议栈进行配置。这时,Docker容器的网卡以及IP,均为用户所配置。一般而言,当未给使用这种模式的容器进行网络配置时,用户无法正常使用容器进程,但是优点也很明显,它给用户最大的自由度来自定义容器的网络环境。
4、docker CMD执行 容器内没有后台服务的概念
提到 CMD 就不得不提容器中应用在前台执行和后台执行的问题。这是初学者常出现的一个混
淆。
Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,
用 upstart/systemd 去启动后台服务,容器内没有后台服务的概念。
一些初学者将 CMD 写为:
CMD service nginx start
然后发现容器执行后就立即退出了。甚至在容器内去使用 systemctl 命令结果却发现根本执
行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在
以传统虚拟机的角度去理解容器。
对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退
出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。
而使用 service nginx start 命令,则是希望 upstart 来以后台守护进程形式启动 nginx 服
务。而刚才说了 CMD service nginx start 会被理解为 CMD [ "sh", "-c", "service nginx
start"] ,因此主进程实际上是 sh 。那么当 service nginx start 命令结束后, sh 也就结
束了, sh 作为主进程退出了,自然就会令容器退出。
正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行。比如:
CMD ["nginx", "-g", "daemon off;"]
或者:
nginx -g "daemon off;"
5、解决上述问题的办法
5.1 supervisor
最近看了一个github项目,完美解决这类问题
https://github.com/nickistre/docker-lamp/tree/ubuntu-14.04
主要做法是加入了supervisd。CMD中的指令一般只有一条,所以建议使用run.sh
|
|
改密码的方法
|
|
而语法规则可以参考文档http://supervisord.org/configuration.html
|
|
5.2 无限循环
main.sh
|
|
run.sh
|
|
Start-apache2.sh
|
|
Start-mysql.sh
|
|
在脚本中,最好使用下面的这类后台指令
|
|
在shell中,内建(builtin)命令exec,格式如下:
|
|
exec命令,如果指定了command,它就会取代当前的shell而不是创建新的进程,所以命令执行完毕后shell也就退出了。如果设置了“-l”即login选项,在command的第0个参数前会添加符号“-”,这是login所需的。如果设置了“-c”即clear选项,command命令将在一个空的环境中执行。如果指定了“-a name”选项,name会作为第0个参数传给command。若没有指定command,可以使用重定向来影响当前的shell。重定向成功时退出状态为0,否则为1。
exec后面的命令如果是多个简单命令组合而成的复合命令,只执行第一个命令,可以把这些符合命令写入shell脚本中,然后通过exec执行这个脚本,此时脚本中所有的命令都会执行。