目录
八、数据管理
九、数据卷备份恢复
十、Docker网络模式
十一、opration not permmited
十二、配置桥接网络
十三、Dockerfile
十四、Dockerfile格式
十五、Dockerfile示例(安装nginx)
十六、用docker compose部署服务
十七、docker compose示例
八、数据管理
docker容器是由镜像启动的,容器存储的数据还会随着容器或镜像的删除而一并删除,我们可以将宿主机的目录挂载到docker容器下,这样就算容器被销毁了它的数据还会保留在宿主机磁盘上,数据安全一点。
- 挂载本地的目录到容器里
docker run -tid -v /data/:/data centos bash //-v 用来指定挂载目录,:前面的/data/为宿主机本地目录,:后面的/data/为容器里的目录,会在容器中自动创建- 挂载数据卷
其实我们挂载目录的时候,可以指定容器name,如果不指定就随机定义了。比如上面我们没有指定,它就生成了一个名字为eager_bose,这个名字可以使用命令docker ps 看最右侧一列
docker run -itd --volumes-from eager_bose centos6 bash
这样,我们使用centos6镜像创建了新的容器,并且使用了eager_bose容器的数据卷- 定义数据卷容器
有时候,我们需要多个容器之间相互共享数据,类似于linux里面的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂载该数据卷。
首先建立数据卷容器
docker run -itd -v /data/ --name eager_bose centos6 bash //注意这里的/data/是容器的/data目录,并非本地的/data/目录。
然后让其他容器挂载该数据卷
docker run -itd --volumes-from eager_bose centos6 bash
#挂载宿主机的目录到容器中
[root@minglinux-01 ~] docker run -itd -v /data/:/data centos_with_net bash
63d95cb512c15c7775a9bdb5eeb25482f1215d2c37dc09c0625ec96e50f3442a
[root@minglinux-01 ~] ls /data/
ftp gitroot mongodb mysql redis redis2 redis_data svnroot wwwroot
[root@minglinux-01 ~] docker exec -it 63d95cb5 bash
[root@63d95cb512c1 /]#
[root@63d95cb512c1 /]# ls data/
ftp gitroot mongodb mysql redis redis2 redis_data svnroot wwwroot
[root@63d95cb512c1 /]# mkdir /data/123
[root@63d95cb512c1 /]# ls data/
123 ftp gitroot mongodb mysql redis redis2 redis_data svnroot wwwroot
[root@63d95cb512c1 /]# exit
#容器中data目录的数据变更会保存在宿主机data目录
[root@minglinux-01 ~] ls /data/
123 ftp gitroot mongodb mysql redis redis2 redis_data svnroot wwwroot
#挂载数据卷
[root@minglinux-01 ~] docker run -itd --volumes-from eager_bose centos6 bash #这里用centos6镜像创建了新的容器,并且使用eager_bose容器的数据卷
3a6809182d50cb665302ee49aa1a7bf3426b4fcbe7eac96d01e43a8e765c13e8
[root@minglinux-01 ~] docker exec -it 3a6809182d bash
[root@3a6809182d50 /]# ls /data/
123 ftp gitroot mongodb mysql redis redis2 redis_data svnroot wwwroot
#建立数据卷容器
#搭建一个专门的数据卷容器,然后其他容器直接挂载该数据卷
[root@minglinux-01 ~] docker run -itd -v /data/ --name eager_bose centos6 bash
#注意这里的/data/是容器的/data目录,并非本地宿主机的/data/目录
#前面的命令已经把eager_bose搭建成一个数据卷容器 docker run -itd -v /data/:/data centos_with_net bash
#然后可以让其他容器挂载该数据卷
[root@minglinux-01 ~] docker run -itd --volumes-from eager_bose centos6 bash
#如果某个容器想要使用home目录,可以建立软连接
[root@3a6809182d50 /]# ls /data/
123 ftp gitroot mongodb mysql redis redis2 redis_data svnroot wwwroot
[root@3a6809182d50 /]# ls /home/
[root@3a6809182d50 /]# mv /home /home.1
[root@3a6809182d50 /]# ln -s /data /home
[root@3a6809182d50 /]# ls /home
123 ftp gitroot mongodb mysql redis redis2 redis_data svnroot wwwroot
[root@3a6809182d50 /]# ll home.1/
total 0
[root@3a6809182d50 /]# ll /home
lrwxrwxrwx 1 root root 5 Mar 16 12:24 /home -> /data
九、数据卷备份恢复
备份
mkdir /data/backup
docker run --volumes-from testvol -v /data/backup/:/backup centos tar cvf /backup/data.tar /data/
说明:首先我们需要使用eager_bose数据卷新开一个容器,新容器挂载了eager_bose数据卷,同时我们还需要把本地的/vol_data_backup/目录挂载到该容器的/backup下,这样在容器中/backup目录里面新建的文件,我们就可以直接在/data/backup/目录中看到了。 然后再把/data/目录(需要备份的目标目录)下面的文件打包到成data.tar文件放到/backup目录下面。看下图。
恢复
思路: 先新建一个数据卷容器,再建一个新的容器并挂载该数据卷容器,然后再把tar包解包。
新建数据卷容器:docker run -itd -v /data/ --name testvol2 centos bash
挂载数据卷新建容器,并解包:docker run --volumes-from testvol2 -v /data/backup/:/backup centos tar xf /backup/data.tar
数据卷容器已经映射宿主机目录了就没必要怎么做了
十、Docker网络模式
host模式,使用docker run时使用--net=host指定
docker使用的网络实际上和宿主机一样,在容器内看到的网卡ip是宿主机ip
container模式,使用--net=container:container_id/container_name
多个容器使用共同的网络,看到的ip是一样的
none模式,使用--net=none指定
这种模式下,不会配置任何网络
bridge模式,使用--net=bridge指定默认模式,不用指定默认就是这种网络模式。这种模式会为每个容器分配一个独立的Network Namespace。类似于vmware的nat网络模式。同一个宿主机上的所有容器会在同一个网段下,相互之间是可以通信的。
- Docker网络管理-外部访问容器
首先使用centos镜像新建一个容器,然后在该容器中安装httpd服务,并启动
再把该容器导成一个新的镜像(centos-httpd),然后再使用新镜像创建容器,并指定端口映射
docker run -itd -p 5123:80 centos-httpd bash //-p 可以指定端口映射,本例中将容器的80端口映射为本地的5123端口
docker exec -it container_id bash
启动httpd: httpd -k start
编辑1.html: vi /var/www/html/1.html 随便写点东西
退出该容器:exit
测试: curl 127.0.0.1:5123/1.html
-p后面也支持IP:port:ip:port 的格式,比如
-p 127.0.0.1:8080:80
也可以不写本地的端口,只写ip,这样会随意分配一个端口
-p 127.0.0.1::80 //注意这里是两个冒号
#宿主机外的机器(如minglinux-02)的网络是无法访问到容器中的
[root@63d95cb512c1 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
···
[root@minglinux-02 ~] ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
^C
--- 172.17.0.3 ping statistics ---
16 packets transmitted, 0 received, 100% packet loss, time 15015ms
#可以设置端口映射实现外部网络访问
[root@minglinux-01 ~] docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a6809182d50 centos6 "bash" 16 hours ago Exited (137) 4 minutes ago reverent_feistel
63d95cb512c1 centos_with_net "bash" 17 hours ago Exited (137) 4 minutes ago eager_bose
da9add7e5695 registry "/entrypoint.sh /etc…" 18 hours ago Exited (2) 4 minutes ago jovial_sammet
ef8c00af1fd7 registry "/entrypoint.sh /etc…" 18 hours ago Exited (2) 18 hours ago awesome_heyrovsky
[root@minglinux-01 ~] docker start 63d95cb512c1
63d95cb512c1
[root@minglinux-01 ~] docker exec -it 63d95cb512c1 bash
[root@63d95cb512c1 /]#
[root@63d95cb512c1 /]# yum install -y httpd #安装好httpd服务
#把该容器导成一个新的镜像
[root@63d95cb512c1 /]# exit
[root@minglinux-01 ~] docker commit -m "install httpd" -a "lucci" 63d95cb512c1 centos-httpd
sha256:0e0db8b6df55fead62ce78815ed865315a752949df192aba1b731a4381e48d51
#再使用新镜像创建容器并指定端口映射
[root@minglinux-01 ~] docker run -itd -p 5123:80 centos-httpd bash #将容器的80端口映射为本地的5123端口
d1cd8a40c21cbfa2192fc9a24428a4a341323a44b0ad7879fda012d15bd27b16
[root@minglinux-01 ~] docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1cd8a40c21c centos-httpd "bash" 39 seconds ago Up 38 seconds 0.0.0.0:5123->80/tcp festive_mirzakhani
63d95cb512c1 centos_with_net "bash" 17 hours ago Up 11 minutes eager_bose
#访问测试留到下一章
十一、opration not permmited
新建的容器,启动nginx或者httpd服务的时候会报错
Failed to get D-Bus connection: Operation not permitted
这是因为dbus-daemon没有启动,解决该问题可以这样做
启动容器时,要加上--privileged -e "container=docker" ,并且最后面的命令改为/usr/sbin/init
docker run -itd --privileged -e "container=docker" centos_with_nginx /usr/sbin/init
[root@minglinux-01 ~] docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d1cd8a40c21c centos-httpd "bash" 39 seconds ago Up 38 seconds 0.0.0.0:5123->80/tcp festive_mirzakhani
63d95cb512c1 centos_with_net "bash" 17 hours ago Up 11 minutes eager_bose
[root@minglinux-01 ~] docker exec -it d1cd8a40c21c bash
[root@d1cd8a40c21c /]# systemctl start httpd
Failed to get D-Bus connection: Operation not permitted
#重新创建端口映射的容器
[root@minglinux-01 ~] docker rm -f d1cd8a40c21c
d1cd8a40c21c
[root@minglinux-01 ~] docker run -itd --privileged -e "container=docker" -p 5123:80 centos-httpd /usr/sbin/init
b9be419d5bd17bb09d8a38ae66868fa269833b27d876bad9db11536aa2f727bc
[root@minglinux-01 ~] docker exec -it b9be419 bash
[root@b9be419d5bd1 /]# systemctl start httpd
[root@b9be419d5bd1 /]# ps aux |grep httpd
root 3149 1.5 0.2 224052 4980 ? Ss 08:30 0:00 /usr/sbin/httpd -DFOREGROUND
apache 3150 0.0 0.1 224052 2948 ? S 08:30 0:00 /usr/sbin/httpd -DFOREGROUND
apache 3151 0.0 0.1 224052 2948 ? S 08:30 0:00 /usr/sbin/httpd -DFOREGROUND
apache 3152 0.0 0.1 224052 2948 ? S 08:30 0:00 /usr/sbin/httpd -DFOREGROUND
apache 3153 0.0 0.1 224052 2948 ? S 08:30 0:00 /usr/sbin/httpd -DFOREGROUND
apache 3154 0.0 0.1 224052 2948 ? S 08:30 0:00 /usr/sbin/httpd -DFOREGROUND
root 3156 0.0 0.0 9088 672 pts/1 S+ 08:30 0:00 grep --color=auto httpd
#访问测试
[root@b9be419d5bd1 /]# curl localhost #容器内访问
[root@minglinux-01 ~] curl localhost:5123 #宿主机访问
[root@minglinux-02 ~] curl 192.168.162.130:5123 #其他外部机器访问
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Apache HTTP Server Test Page powered by CentOS</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
···
···
十二、配置桥接网络
为了使本地网络中的机器和Docker容器更方便的通信,我们经常会有将Docker容器配置到和主机同一网段的需求。这个需求其实很容易实现,我们只要将Docker容器和宿主机的网卡桥接起来,再给Docker容器配上IP就可以了。
cd /etc/sysconfig/network-scripts/
cp ifcfg-ens33 ifcfg-br0
vi ifcfg-ens33 //增加BRIDGE=br0,删除 IPADDR,NETMASK,GATEWAY,DNS1
vi ifcfg-br0 //修改DEVICE为br0,Type为Bridge,把eth0的网络设置设置到这里来
systemctl restart network
安装pipwork
git clone https://github.com/jpetazzo/pipework
cp pipework/pipework /usr/local/bin/
开启一个容器
docker run -itd --net=none centos-httpd bash
pipework br0 276b2a 192.168.162.135/24@192.168.162.2 #135为容器的ip,@后面的ip为网关ip,276b2a是容器id(此处也可以使用容器名)
docker exec -it 276b2a bash #再次进去后ifconfig查看就可以看到新添加的ip
#新建br0网卡跟ens33网卡桥接
[root@minglinux-01 ~] rpm -aq |grep bridge
bridge-utils-1.5-9.el7.x86_64
[root@minglinux-01 ~] cd /etc/sysconfig/network-scripts/
[root@minglinux-01 /etc/sysconfig/network-scripts] ls
ifcfg-ens33 ifdown-ippp ifdown-sit ifup-bnep ifup-plip ifup-Team network-functions-ipv6
ifcfg-ens37 ifdown-ipv6 ifdown-Team ifup-eth ifup-plusb ifup-TeamPort
ifcfg-lo ifdown-isdn ifdown-TeamPort ifup-ippp ifup-post ifup-tunnel
ifdown ifdown-post ifdown-tunnel ifup-ipv6 ifup-ppp ifup-wireless
ifdown-bnep ifdown-ppp ifup ifup-isdn ifup-routes init.ipv6-global
ifdown-eth ifdown-routes ifup-aliases ifup-lo ifup-sit network-functions
[root@minglinux-01 /etc/sysconfig/network-scripts] cp ifcfg-ens33 ifcfg-br0
[root@minglinux-01 ~] cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
#UUID=c0f01c3c-028a-4219-86db-bc442037da9b
DEVICE=ens33
ONBOOT=yes
#IPADDR=192.168.162.130
#GATEWAY=192.168.162.2
#NETMASK=255.255.255.0
#BROADCAST=192.168.162.255
#DNS1=119.29.29.29
BRIDGE=br0
[root@minglinux-01 ~] cat /etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=br0
#UUID=c0f01c3c-028a-4219-86db-bc442037da9b
DEVICE=br0
ONBOOT=yes
IPADDR=192.168.162.130
GATEWAY=192.168.162.2
NETMASK=255.255.255.0
BROADCAST=192.168.162.255
DNS1=119.29.29.29
DNS2=8.8.8.8
[root@minglinux-01 ~] ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
link/ether 00:0c:29:de:c1:12 brd ff:ff:ff:ff:ff:ff
inet6 fe80::20c:29ff:fede:c112/64 scope link
valid_lft forever preferred_lft forever
3: ens37: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 00:0c:29:de:c1:1c brd ff:ff:ff:ff:ff:ff
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:0c:29:de:c1:12 brd ff:ff:ff:ff:ff:ff
inet 192.168.162.130/24 brd 192.168.162.255 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fede:c112/64 scope link
valid_lft forever preferred_lft forever
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:c5:30:e7:b0 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
#安装pipwork
[root@minglinux-01 ~] git clone https://github.com/jpetazzo/pipework
正克隆到 'pipework'...
remote: Enumerating objects: 501, done.
remote: Total 501 (delta 0), reused 0 (delta 0), pack-reused 501
接收对象中: 100% (501/501), 172.97 KiB | 10.00 KiB/s, done.
处理 delta 中: 100% (264/264), done.
[root@minglinux-01 ~] ls pipework/
docker-compose.yml doctoc LICENSE pipework pipework.spec README.md
[root@minglinux-01 ~] cp pipework/pipework /usr/local/bin/
#开启一个容器,设置none模式
[root@minglinux-01 ~] docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b9be419d5bd1 centos-httpd "/usr/sbin/init" 2 hours ago Exited (137) About an hour ago peaceful_thompson
3a6809182d50 centos6 "bash" 18 hours ago Exited (137) 2 hours ago reverent_feistel
63d95cb512c1 centos_with_net "bash" 19 hours ago Exited (137) About an hour ago eager_bose
da9add7e5695 registry "/entrypoint.sh /etc…" 20 hours ago Exited (2) 2 hours ago jovial_sammet
ef8c00af1fd7 registry "/entrypoint.sh /etc…" 20 hours ago Exited (2) 20 hours ago awesome_heyrovsky
[root@minglinux-01 ~] docker run -itd --net=none centos-httpd bash
276b2a4606a2e67f43eaaaf8ef6db9e9055ed47cc18a164f38096a25f1412354
[root@minglinux-01 ~] docker exec -it 276b2a bash
[root@276b2a4606a2 /]# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
#通过pipwork工具为容器指定静态ip地址,不过容器重启之后静态ip会丢失
[root@276b2a4606a2 /]# exit
[root@minglinux-01 ~] pipework br0 276b2a 192.168.162.135/24@192.168.162.2
[root@minglinux-01 ~] docker exec -it 276b2a bash
[root@276b2a4606a2 /]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.162.135 netmask 255.255.255.0 broadcast 192.168.162.255
ether 86:08:f4:15:f4:4c txqueuelen 1000 (Ethernet)
RX packets 27 bytes 1608 (1.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1 bytes 42 (42.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
#在外部机器测试与容器的网络连通性
[root@minglinux-02 ~] ping 192.168.162.135
PING 192.168.162.135 (192.168.162.135) 56(84) bytes of data.
64 bytes from 192.168.162.135: icmp_seq=1 ttl=64 time=1.42 ms
64 bytes from 192.168.162.135: icmp_seq=2 ttl=64 time=0.355 ms
64 bytes from 192.168.162.135: icmp_seq=3 ttl=64 time=0.335 ms
^C
--- 192.168.162.135 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.335/0.704/1.424/0.509 ms
如果还想要增加桥接网卡配置,可以按以上的方法新建一个br1网卡配置跟ens37桥接
十三、Dockerfile
DockFile是一种能被Docker程序解释的脚本,DockerFile由多条指令组成,每条指令对应Linux系统中不同的命令,基于 DockerFile 可以自定义创建生产环境所需的 Docker镜像,通过镜像可以启动所需的 Docker 容器。
Docker程序将这些 DockerFile指令翻译为真正的Linux命令,DockerFile有特定的书写格式和支持的命令,Docker 程序解决这些命令间的依赖关系,类似于 Linux系统中编译软件所使用的 MakeFile 文件。
Docker 程序可以读取 DockerFile 文件,,根据指令生成定制的image,需要定制自己额外的需求时,只需在DockerFile上添加或修改指令,重新生成image即可,省去了敲命令的麻烦。
十四、Dockerfile格式
- FROM //指定基于哪个基础镜像
格式 FROM <image> 或者 FROM <image>:<tag>, 比如
FROM centos
FROM centos:latest- MAINTAINER //指定作者信息
格式 MAINTAIN <name> ,比如
MAINTAINER aming ming@minglinux.com- RUN //镜像操作指令
格式为 RUN <command> 或者 RUN [“executable”, “param1”, “param2”],比如
RUN yum install httpd
RUN ["/bin/bash", "-c", "echo hello"]- CMD // 三种格式:
CMD ["executable", "param1", "param2"]
CMD command param1 param2
CMD ["param1", "param2"]
RUN和CMD看起来挺像,但是CMD用来指定容器启动时用到的命令,只能有一条。比如
CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c", "/usr/local/nginx/conf/nginx.conf"]- EXPOSE
格式为 EXPOSE <port> [<port>...] , 比如
EXPOSE 22 80 8443
这个用来指定要映射出去的端口,比如容器内部我们启动了sshd和nginx,所以我们需要把22和80端口暴漏出去。这个需要配合-P(大写)来工作,也就是说在启动容器时,需要加上-P,让它自动分配。如果想指定具体的端口,也可以使用-p(小写)来指定。- ENV
格式 ENV <key> <value>, 比如
ENV PATH /usr/local/mysql/bin:$PATH
它主要是为后续的RUN指令提供一个环境变量,我们也可以定义一些自定义的变量
ENV MYSQL_version 5.6- ADD 格式 add <src> <dest>
将本地的一个文件或目录拷贝到容器的某个目录里。 其中src为Dockerfile所在目录的相对路径,它也可以是一个url。比如
ADD <conf/vhosts> </usr/local/nginx/conf>- COPY
格式同add
使用方法和add一样,不同的是,它不支持url- ENTRYPOINT 格式类似CMD
容器启动时要执行的命令,它和CMD很像,也是只有一条生效,如果写多个只有最后一条有效。和CMD不同是:
CMD 是可以被 docker run 指令覆盖的,而ENTRYPOINT不能覆盖。比如,容器名字为ming
我们在Dockerfile中指定如下CMD:
CMD ["/bin/echo", "test"]
启动容器的命令是 docker run ming 这样会输出 test
假如启动容器的命令是 docker run -it ming /bin/bash 什么都不会输出
ENTRYPOINT不会被覆盖,而且会比CMD或者docker run指定的命令要靠前执行
ENTRYPOINT ["echo", "test"]
docker run -it ming 123
则会输出 test 123 ,这相当于要执行命令 echo test 123- VOLUME
格式 VOLUME ["/data"]
创建一个可以从本地主机或其他容器挂载的挂载点。- USER
格式 USER daemon
指定运行容器的用户- WORKDIR
格式 WORKDIR /path/to/workdir
为后续的RUN、CMD或者ENTRYPOINT指定工作目录
十五、Dockerfile示例(安装nginx)
先下载nginx的配置文件
wget http://www.apelearn.com/study_v2/.nginx_conf
vim Dockerfile //内容如下
## Set the base image to CentOS
FROM centos
# File Author / Maintainer
MAINTAINER aming ming@minglinux.com
# Install necessary tools
RUN yum install -y pcre-devel wget net-tools gcc zlib zlib-devel make openssl-devel
# Install Nginx
ADD http://nginx.org/download/nginx-1.8.0.tar.gz .
RUN tar zxvf nginx-1.8.0.tar.gz
RUN mkdir -p /usr/local/nginx
RUN cd nginx-1.8.0 && ./configure --prefix=/usr/local/nginx && make && make install
RUN rm -fv /usr/local/nginx/conf/nginx.conf
COPY .nginx_conf /usr/local/nginx/conf/nginx.conf
# Expose ports
EXPOSE 80
# Set the default command to execute when creating a new container
ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /etc/passwd
创建镜像:
docker build -t centos_nginx .
docker images //可以看到我们新建的镜像
docker run -itd -p 8088:80 centos_nginx bash
#创建Dockerfile
[root@minglinux-01 ~] vim Dockerfile
#加入内容如下
1 ## Set the base image to CentOS #FROM本机的镜像
2 FROM centos
3 # File Author / Maintainer #
4 MAINTAINER ming ming@minglinux.com
5 # Install necessary tools
6 RUN yum install -y pcre-devel wget net-tools gcc zlib zlib-devel make openssl-devel
7 # Install Nginx
8 ADD http://nginx.org/download/nginx-1.8.0.tar.gz . #下载nginx源码包到当前目录下
9 RUN tar zxvf nginx-1.8.0.tar.gz
10 RUN mkdir -p /usr/local/nginx
11 RUN cd nginx-1.8.0 && ./configure --prefix=/usr/local/nginx && make && make install
12 RUN rm -fv /usr/local/nginx/conf/nginx.conf
13 ADD http://www.apelearn.com/study_v2/.nginx_conf /usr/local/nginx/conf/nginx.conf #远程下载配置文件,当然也可以使用COPY命令复制保存在本地的配置文件
14 # Expose ports
15 EXPOSE 80
16 # Set the default command to execute when creating a new container
17 ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /etc/passwd
#默认DockerFile run启动镜像之后便会退出容器,需要一个长时间运行的命令使容器一直执行。所以上面最后一个命令使用了tail -f /etc/passwd这个无限运行的命令来保证启动的容器不会被退出。
#创建镜像
[root@minglinux-01 ~] docker build -t centos_nginx . #centos_nginx跟.之间只有一个空格才行,有两个就包下面的错了
unable to prepare context: path "\u00a0." not found
[root@minglinux-01 ~] docker build -t centos_nginx .
[root@minglinux-01 ~] docker images #可以看到我们新建的镜像啦
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_nginx latest a79f32526599 About a minute ago 350MB
centos-httpd latest 0e0db8b6df55 8 hours ago 390MB
192.168.162.130:5000/centos6 latest 28927c522726 46 hours ago 512MB
centos6 latest 28927c522726 46 hours ago 512MB
centos_with_net latest 9655a540a99e 2 days ago 280MB
lucci_linux latest 9f38484d220f 2 days ago 202MB
centos latest 9f38484d220f 2 days ago 202MB
ubuntu latest 94e814e2efa8 5 days ago 88.9MB
registry latest f32a97de94e1 9 days ago 25.8MB
#启动这个镜像并将宿主机8088端口映射到容器的80端口
[root@minglinux-01 ~] docker run -itd -p 8088:80 centos_nginx bash
f581a66a8780576b9f121c1bd864e4a86e12953bee4f0ce91a97d9e3984c6373
[root@minglinux-01 ~] docker exec -it f581a6 bash
[root@f581a66a8780 /]# ps aux |grep nginx
root 1 0.1 0.0 11680 1352 pts/0 Ss+ 15:57 0:00 /bin/sh -c /usr/local/nginx/sbin/nginx && tail -f /etc/passwd bash
root 7 0.0 0.0 24880 784 ? Ss 15:57 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nobody 9 0.0 0.1 27324 3360 ? S 15:57 0:00 nginx: worker process
nobody 10 0.0 0.1 27324 3360 ? S 15:57 0:00 nginx: worker process
root 25 0.0 0.0 9088 672 pts/1 S+ 15:57 0:00 grep --color=auto nginx
[root@minglinux-01 ~] curl 127.0.0.1:8088
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
···
···
十六、用docker compose部署服务
需求:有多个容器需要批量启动和管理
docker compose可以方便我们快捷高效地管理容器的启动、停止、重启等操作,它类似于linux下的shell脚本,基于yaml语法,在该文件里我们可以描述应用的架构,比如用什么镜像、数据卷、网络模式、监听端口等信息。我们可以在一个compose文件中定义一个多容器的应用(比如jumpserver),然后通过该compose来启动这个应用。
安装compose方法如下
curl -L https://github.com/docker/compose/releases/download/1.17.0-rc1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod 755 !$
docker-compose version 查看版本信息
Compose区分Version 1和Version 2(Compose 1.6.0+,Docker Engine 1.10.0+)。Version 2支持更多的指令。yml中没有声明版本则默认是"version 1"。Version 1将来会被弃用。
#安装compose
[root@minglinux-01 ~] curl -L https://github.com/docker/compose/releases/download/1.17.0-rc1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 617 0 617 0 0 16 0 --:--:-- 0:00:37 --:--:-- 165
100 8649k 100 8649k 0 0 84059 0 0:01:45 0:01:45 --:--:-- 126k
[root@minglinux-01 ~] du -sh !$
du -sh /usr/local/bin/docker-compose
8.5M /usr/local/bin/docker-compose
[root@minglinux-01 ~] chmod 755 !$
chmod 755 /usr/local/bin/docker-compose
[root@minglinux-01 ~] docker-compose version
docker-compose version 1.17.0-rc1, build a0f95af
docker-py version: 2.5.1
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t 3 May 2016
十七、docker compose示例
vim docker-compose.yml //内容到https://coding.net/u/aminglinux/p/yuanke_centos7/git/blob/master/25docker/docker-compose.yml 查看
docker-compose up -d 可以启动两个容器
docker-compose --help
docker-compose ps/down/stop/start/rm
关于docker-compose语法的参考文档 http://www.web3.xin/index/article/182.html
[root@minglinux-01 ~] vim docker-compose.yml
#j加入以下内容
1 version: "2"
2 services:
3 app1:
4 image: centos_nginx #对应镜像
5 ports:
6 - "8080:80" #端口映射
7 networks:
8 - "net1" #使用的网络,在下面定义。不写的话默认bridge
9 volumes:
10 - /data/:/data #目录映射,如果不写:只写- /data/则是设置为数据卷共享
11 app2:
12 image: centos_with_net
13 networks:
14 - "net2"
15 volumes:
16 - /data/:/data1
17 entrypoint: tail -f /etc/passwd #不让容器退出。这里不加这行会使得第一个app1正常启动而app2启动后马上退出
18 networks:
19 net1:
20 driver: bridge
21 net2:
22 driver: bridge
#使用docker-compose启动两个容器
[root@minglinux-01 ~] docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f581a66a8780 centos_nginx "/bin/sh -c '/usr/lo…" 44 minutes ago Up 44 minutes 0.0.0.0:8088->80/tcp nostalgic_banzai
[root@minglinux-01 ~] docker-compose up -d #不加d则在前台显示
Creating root_app2_1 ...
Creating root_app1_1 ...
Creating root_app2_1 ... done
Creating root_app1_1 ... done
[root@minglinux-01 ~] docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7f3d20a71be8 centos_nginx "/bin/sh -c '/usr/lo…" 4 seconds ago Up 2 seconds 0.0.0.0:8080->80/tcp root_app1_1
d239233fda97 centos_with_net "tail -f /etc/passwd" 4 seconds ago Up 2 seconds root_app2_1
f581a66a8780 centos_nginx "/bin/sh -c '/usr/lo…" 44 minutes ago Up 44 minutes 0.0.0.0:8088->80/tcp nostalgic_banzai
#查看docker-compose可以使用的指令
[root@minglinux-01 ~] docker-compose --help
#docker-compose ps/down/stop/start/rm等
[root@minglinux-01 ~] docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------
root_app1_1 /bin/sh -c /usr/local/ngin ... Up 0.0.0.0:8080->80/tcp
root_app2_1 tail -f /etc/passwd Up
[root@minglinux-01 ~] docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------
root_app1_1 /bin/sh -c /usr/local/ngin ... Up 0.0.0.0:8080->80/tcp
root_app2_1 tail -f /etc/passwd Up
[root@minglinux-01 ~] docker-compose rm -f #只能删除停止状态的容器
No stopped containers
[root@minglinux-01 ~] docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------
root_app1_1 /bin/sh -c /usr/local/ngin ... Up 0.0.0.0:8080->80/tcp
root_app2_1 tail -f /etc/passwd Up
[root@minglinux-01 ~] docker-compose stop
Stopping root_app1_1 ... done
Stopping root_app2_1 ... done
[root@minglinux-01 ~] docker-compose rm
Going to remove root_app1_1, root_app2_1
Are you sure? [yN] y
Removing root_app1_1 ... done
Removing root_app2_1 ... done