Docker入門二

目錄

八、數(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ù)安全一點。

  1. 掛載本地的目錄到容器里
    docker run -tid -v /data/:/data centos bash //-v 用來指定掛載目錄,:前面的/data/為宿主機本地目錄,:后面的/data/為容器里的目錄,會在容器中自動創(chuàng)建
  2. 掛載數(shù)據(jù)卷
    其實我們掛載目錄的時候,可以指定容器name,如果不指定就隨機定義了。比如上面我們沒有指定,它就生成了一個名字為eager_bose,這個名字可以使用命令docker ps 看最右側(cè)一列
    docker run -itd --volumes-from eager_bose centos6 bash
    這樣,我們使用centos6鏡像創(chuàng)建了新的容器,并且使用了eager_bose容器的數(shù)據(jù)卷
  3. 定義數(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

Docker數(shù)據(jù)卷的備份與恢復(fù)

數(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格式

  1. FROM //指定基于哪個基礎(chǔ)鏡像
    格式 FROM <image> 或者 FROM <image>:<tag>, 比如
    FROM centos
    FROM centos:latest
  2. MAINTAINER //指定作者信息
    格式 MAINTAIN <name> ,比如
    MAINTAINER aming ming@minglinux.com
  3. RUN //鏡像操作指令
    格式為 RUN <command> 或者 RUN [“executable”, “param1”, “param2”],比如
    RUN yum install httpd
    RUN ["/bin/bash", "-c", "echo hello"]
  4. 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"]
  5. EXPOSE
    格式為 EXPOSE <port> [<port>...] , 比如
    EXPOSE 22 80 8443
    這個用來指定要映射出去的端口,比如容器內(nèi)部我們啟動了sshd和nginx,所以我們需要把22和80端口暴漏出去。這個需要配合-P(大寫)來工作,也就是說在啟動容器時,需要加上-P,讓它自動分配。如果想指定具體的端口,也可以使用-p(小寫)來指定。
  6. ENV
    格式 ENV <key> <value>, 比如
    ENV PATH /usr/local/mysql/bin:$PATH
    它主要是為后續(xù)的RUN指令提供一個環(huán)境變量,我們也可以定義一些自定義的變量
    ENV MYSQL_version 5.6
  7. ADD 格式 add <src> <dest>
    將本地的一個文件或目錄拷貝到容器的某個目錄里。 其中src為Dockerfile所在目錄的相對路徑,它也可以是一個url。比如
    ADD <conf/vhosts> </usr/local/nginx/conf>
  8. COPY
    格式同add
    使用方法和add一樣,不同的是,它不支持url
  9. 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
  10. VOLUME
    格式 VOLUME ["/data"]
    創(chuàng)建一個可以從本地主機或其他容器掛載的掛載點。
  11. USER
    格式 USER daemon
    指定運行容器的用戶
  12. 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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容