目錄
八、數(shù)據(jù)管理
九、數(shù)據(jù)卷備份恢復(fù)
十、Docker網(wǎng)絡(luò)模式
十一、opration not permmited
十二、配置橋接網(wǎng)絡(luò)
十三、Dockerfile
十四、Dockerfile格式
十五、Dockerfile示例(安裝nginx)
十六、用docker compose部署服務(wù)
十七、docker compose示例
八、數(shù)據(jù)管理
docker容器是由鏡像啟動的,容器存儲的數(shù)據(jù)還會隨著容器或鏡像的刪除而一并刪除,我們可以將宿主機的目錄掛載到docker容器下,這樣就算容器被銷毀了它的數(shù)據(jù)還會保留在宿主機磁盤上,數(shù)據(jù)安全一點。
- 掛載本地的目錄到容器里
docker run -tid -v /data/:/data centos bash //-v 用來指定掛載目錄,:前面的/data/為宿主機本地目錄,:后面的/data/為容器里的目錄,會在容器中自動創(chuàng)建- 掛載數(shù)據(jù)卷
其實我們掛載目錄的時候,可以指定容器name,如果不指定就隨機定義了。比如上面我們沒有指定,它就生成了一個名字為eager_bose,這個名字可以使用命令docker ps 看最右側(cè)一列
docker run -itd --volumes-from eager_bose centos6 bash
這樣,我們使用centos6鏡像創(chuàng)建了新的容器,并且使用了eager_bose容器的數(shù)據(jù)卷- 定義數(shù)據(jù)卷容器
有時候,我們需要多個容器之間相互共享數(shù)據(jù),類似于linux里面的NFS,所以就可以搭建一個專門的數(shù)據(jù)卷容器,然后其他容器直接掛載該數(shù)據(jù)卷。
首先建立數(shù)據(jù)卷容器
docker run -itd -v /data/ --name eager_bose centos6 bash //注意這里的/data/是容器的/data目錄,并非本地的/data/目錄。
然后讓其他容器掛載該數(shù)據(jù)卷
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目錄的數(shù)據(jù)變更會保存在宿主機data目錄
[root@minglinux-01 ~] ls /data/
123 ftp gitroot mongodb mysql redis redis2 redis_data svnroot wwwroot
#掛載數(shù)據(jù)卷
[root@minglinux-01 ~] docker run -itd --volumes-from eager_bose centos6 bash #這里用centos6鏡像創(chuàng)建了新的容器,并且使用eager_bose容器的數(shù)據(jù)卷
3a6809182d50cb665302ee49aa1a7bf3426b4fcbe7eac96d01e43a8e765c13e8
[root@minglinux-01 ~] docker exec -it 3a6809182d bash
[root@3a6809182d50 /]# ls /data/
123 ftp gitroot mongodb mysql redis redis2 redis_data svnroot wwwroot
#建立數(shù)據(jù)卷容器
#搭建一個專門的數(shù)據(jù)卷容器,然后其他容器直接掛載該數(shù)據(jù)卷
[root@minglinux-01 ~] docker run -itd -v /data/ --name eager_bose centos6 bash
#注意這里的/data/是容器的/data目錄,并非本地宿主機的/data/目錄
#前面的命令已經(jīng)把eager_bose搭建成一個數(shù)據(jù)卷容器 docker run -itd -v /data/:/data centos_with_net bash
#然后可以讓其他容器掛載該數(shù)據(jù)卷
[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
九、數(shù)據(jù)卷備份恢復(fù)
備份
mkdir /data/backup
docker run --volumes-from testvol -v /data/backup/:/backup centos tar cvf /backup/data.tar /data/
說明:首先我們需要使用eager_bose數(shù)據(jù)卷新開一個容器,新容器掛載了eager_bose數(shù)據(jù)卷,同時我們還需要把本地的/vol_data_backup/目錄掛載到該容器的/backup下,這樣在容器中/backup目錄里面新建的文件,我們就可以直接在/data/backup/目錄中看到了。 然后再把/data/目錄(需要備份的目標目錄)下面的文件打包到成data.tar文件放到/backup目錄下面??聪聢D。
恢復(fù)
思路: 先新建一個數(shù)據(jù)卷容器,再建一個新的容器并掛載該數(shù)據(jù)卷容器,然后再把tar包解包。
新建數(shù)據(jù)卷容器:docker run -itd -v /data/ --name testvol2 centos bash
掛載數(shù)據(jù)卷新建容器,并解包:docker run --volumes-from testvol2 -v /data/backup/:/backup centos tar xf /backup/data.tar

數(shù)據(jù)卷容器已經(jīng)映射宿主機目錄了就沒必要怎么做了
十、Docker網(wǎng)絡(luò)模式
host模式,使用docker run時使用--net=host指定
docker使用的網(wǎng)絡(luò)實際上和宿主機一樣,在容器內(nèi)看到的網(wǎng)卡ip是宿主機ip
container模式,使用--net=container:container_id/container_name
多個容器使用共同的網(wǎng)絡(luò),看到的ip是一樣的
none模式,使用--net=none指定
這種模式下,不會配置任何網(wǎng)絡(luò)
bridge模式,使用--net=bridge指定默認模式,不用指定默認就是這種網(wǎng)絡(luò)模式。這種模式會為每個容器分配一個獨立的Network Namespace。類似于vmware的nat網(wǎng)絡(luò)模式。同一個宿主機上的所有容器會在同一個網(wǎng)段下,相互之間是可以通信的。
- Docker網(wǎng)絡(luò)管理-外部訪問容器
首先使用centos鏡像新建一個容器,然后在該容器中安裝httpd服務(wù),并啟動
再把該容器導(dǎo)成一個新的鏡像(centos-httpd),然后再使用新鏡像創(chuàng)建容器,并指定端口映射
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)的網(wǎng)絡(luò)是無法訪問到容器中的
[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
#可以設(shè)置端口映射實現(xiàn)外部網(wǎng)絡(luò)訪問
[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服務(wù)
#把該容器導(dǎo)成一個新的鏡像
[root@63d95cb512c1 /]# exit
[root@minglinux-01 ~] docker commit -m "install httpd" -a "lucci" 63d95cb512c1 centos-httpd
sha256:0e0db8b6df55fead62ce78815ed865315a752949df192aba1b731a4381e48d51
#再使用新鏡像創(chuàng)建容器并指定端口映射
[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服務(wù)的時候會報錯
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
#重新創(chuàng)建端口映射的容器
[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 #容器內(nèi)訪問
[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">
···
···
十二、配置橋接網(wǎng)絡(luò)
為了使本地網(wǎng)絡(luò)中的機器和Docker容器更方便的通信,我們經(jīng)常會有將Docker容器配置到和主機同一網(wǎng)段的需求。這個需求其實很容易實現(xiàn),我們只要將Docker容器和宿主機的網(wǎng)卡橋接起來,再給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的網(wǎng)絡(luò)設(shè)置設(shè)置到這里來
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為網(wǎng)關(guān)ip,276b2a是容器id(此處也可以使用容器名)
docker exec -it 276b2a bash #再次進去后ifconfig查看就可以看到新添加的ip
#新建br0網(wǎng)卡跟ens33網(wǎng)卡橋接
[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/
#開啟一個容器,設(shè)置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工具為容器指定靜態(tài)ip地址,不過容器重啟之后靜態(tài)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
#在外部機器測試與容器的網(wǎng)絡(luò)連通性
[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
如果還想要增加橋接網(wǎng)卡配置,可以按以上的方法新建一個br1網(wǎng)卡配置跟ens37橋接
十三、Dockerfile
DockFile是一種能被Docker程序解釋的腳本,DockerFile由多條指令組成,每條指令對應(yīng)Linux系統(tǒng)中不同的命令,基于 DockerFile 可以自定義創(chuàng)建生產(chǎn)環(huán)境所需的 Docker鏡像,通過鏡像可以啟動所需的 Docker 容器。
Docker程序?qū)⑦@些 DockerFile指令翻譯為真正的Linux命令,DockerFile有特定的書寫格式和支持的命令,Docker 程序解決這些命令間的依賴關(guān)系,類似于 Linux系統(tǒng)中編譯軟件所使用的 MakeFile 文件。
Docker 程序可以讀取 DockerFile 文件,,根據(jù)指令生成定制的image,需要定制自己額外的需求時,只需在DockerFile上添加或修改指令,重新生成image即可,省去了敲命令的麻煩。
十四、Dockerfile格式
- FROM //指定基于哪個基礎(chǔ)鏡像
格式 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
這個用來指定要映射出去的端口,比如容器內(nèi)部我們啟動了sshd和nginx,所以我們需要把22和80端口暴漏出去。這個需要配合-P(大寫)來工作,也就是說在啟動容器時,需要加上-P,讓它自動分配。如果想指定具體的端口,也可以使用-p(小寫)來指定。- ENV
格式 ENV <key> <value>, 比如
ENV PATH /usr/local/mysql/bin:$PATH
它主要是為后續(xù)的RUN指令提供一個環(huán)境變量,我們也可以定義一些自定義的變量
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
容器啟動時要執(zhí)行的命令,它和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指定的命令要靠前執(zhí)行
ENTRYPOINT ["echo", "test"]
docker run -it ming 123
則會輸出 test 123 ,這相當(dāng)于要執(zhí)行命令 echo test 123- VOLUME
格式 VOLUME ["/data"]
創(chuàng)建一個可以從本地主機或其他容器掛載的掛載點。- USER
格式 USER daemon
指定運行容器的用戶- WORKDIR
格式 WORKDIR /path/to/workdir
為后續(xù)的RUN、CMD或者ENTRYPOINT指定工作目錄
十五、Dockerfile示例(安裝nginx)
先下載nginx的配置文件
wget http://www.apelearn.com/study_v2/.nginx_conf
vim Dockerfile //內(nèi)容如下
## 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
創(chuàng)建鏡像:
docker build -t centos_nginx .
docker images //可以看到我們新建的鏡像
docker run -itd -p 8088:80 centos_nginx bash
#創(chuàng)建Dockerfile
[root@minglinux-01 ~] vim Dockerfile
#加入內(nèi)容如下
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源碼包到當(dāng)前目錄下
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 #遠程下載配置文件,當(dāng)然也可以使用COPY命令復(fù)制保存在本地的配置文件
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啟動鏡像之后便會退出容器,需要一個長時間運行的命令使容器一直執(zhí)行。所以上面最后一個命令使用了tail -f /etc/passwd這個無限運行的命令來保證啟動的容器不會被退出。
#創(chuàng)建鏡像
[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部署服務(wù)
需求:有多個容器需要批量啟動和管理
docker compose可以方便我們快捷高效地管理容器的啟動、停止、重啟等操作,它類似于linux下的shell腳本,基于yaml語法,在該文件里我們可以描述應(yīng)用的架構(gòu),比如用什么鏡像、數(shù)據(jù)卷、網(wǎng)絡(luò)模式、監(jiān)聽端口等信息。我們可以在一個compose文件中定義一個多容器的應(yīng)用(比如jumpserver),然后通過該compose來啟動這個應(yīng)用。
安裝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區(qū)分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 //內(nèi)容到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
關(guān)于docker-compose語法的參考文檔 http://www.web3.xin/index/article/182.html
[root@minglinux-01 ~] vim docker-compose.yml
#j加入以下內(nèi)容
1 version: "2"
2 services:
3 app1:
4 image: centos_nginx #對應(yīng)鏡像
5 ports:
6 - "8080:80" #端口映射
7 networks:
8 - "net1" #使用的網(wǎng)絡(luò),在下面定義。不寫的話默認bridge
9 volumes:
10 - /data/:/data #目錄映射,如果不寫:只寫- /data/則是設(shè)置為數(shù)據(jù)卷共享
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 #只能刪除停止?fàn)顟B(tài)的容器
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