Docker鏡像除了是Docker的核心技術以外也是應用發佈的標準格式。一個完整的Docker鏡像能夠支撐一個Docker容器的運行,在Docker的整個使用過程當中,進入一個已經定型的容器以後,就能夠在容器中進行操做,最多見的就是在容器中安裝應用服務,若是要把已經 安裝的服務進行遷移,就須要把環境以及搭建的服務生成新的鏡像。html
建立鏡像的方法有三種:web
使用docker commit命令,把一個容器裏面運行的程序以及該程序的運行環境打包起來生成新對的鏡像。docker
命令格式:docker commit [選項] 容器 ID/ 名稱 倉庫名稱 :[標籤]apache
經常使用選項:json
-a :做者信息
-m :說明信息
-p :生成過程當中中止容器的運行vim
[root@localhost ~]# docker ps -a #查看容器的ID CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 06bbfa9e79b8 11426a19f1a2 "/bin/bash" 7 seconds ago Created nostalgic_boyd [root@localhost ~]# docker commit -m "new" -a "daoke" 06bbfa9e79b8 daoke:test #建立新的鏡像 sha256:eb0c9295c27a4efc020bc7985476b45a9d2e2cb6d80f4f9d8cdd4d9bcc87b4e1 [root@localhost ~]# docker images #查看鏡像的信息 REPOSITORY TAG IMAGE ID CREATED SIZE daoke test eb0c9295c27a 15 seconds ago 178 MB docker.io/httpd latest 11426a19f1a2 12 days ago 178 MB
經過導入操做系統模板文件能夠生成鏡像,模板能夠從OPENVZ開源項目下載,下載地址爲http://openvz.org/Download/template/precreatedcentos
使用docker導入命令將下載的debian模板壓縮包導入爲本地鏡像緩存
[root@localhost ~]# wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz [root@localhost ~]# cat debian-7.0-x86-minimal.tar.gz | docker import - daoke:new sha256:528e1b210e8477dafaeb6d76dd7551c8b9906230d2ddaea4d149d6868964cec6 [root@localhost ~]# docker images | grep new #查看新建的鏡像信息 daoke new 528e1b210e84 5 minutes ago 215 MB
除了手動刪除Docker鏡像以外,還可使用Dockerfile自動生成鏡像。Dockerfile是由一組指令組成的文件,其中每條指令對應Linux中的一條命令,Docker程序將讀取Dockerfile中的指令生成指定鏡像。安全
Dockerfile結構大體分爲四個部分:基礎鏡像信息、維護者信息、鏡像操做指令和容器啓動時執行指令。Dockerfile每行支持一條指令,每條指令可攜帶多個參數,支持使用以「#」號開頭的註釋。bash
編寫Dockerfile的格式要求:
1.創建工做目錄
[root@localhost ~]# mkdir apache [root@localhost ~]# cd apache/
2.建立並編寫Dockerfile文件
[root@localhost apache]# vim Dockerfile #基於的基礎鏡像 FROM centos #維護鏡像的用戶信息 MAINTAINER The porject <cloud-ops@centos.org> #鏡像操做指令安裝apache軟件 RUN yum -y update RUN yum -y install httpd #開啓 80 端口 EXPOSE 80 #複製網站首頁文件 ADD index.html /var/www/html/index.html #將執行腳本複製到鏡像中 ADD run.sh /run.sh RUN chmod 755 /run.sh #啓動容器時執行腳本 CMD ["/run.sh"]
3.編寫執行腳本
[root@localhost apache]# vim run.sh #!/bin/bash rm -rf /run/httpd/* #清理httpd的緩存 exec /usr/sbin/apachectl -D FOREGROUND #啓動apache服務
4.建立測試頁面
[root@localhost apache]# echo "web test" > index.html [root@localhost apache]# ls Dockerfile index.html run.sh
5.使用Dockerfile生成鏡像
經常使用選項:
-t :指定鏡像的標籤信息
[root@localhost apache]# docker build -t httpd:centos .
6.使用新的鏡像運行容器
將新生成的鏡像加載到容器中運行
[root@localhost apache]# docker run -d -p 1216:80 httpd:centos
其中-p選項實現從本地端口1216(自定義)到容器中80端口的映射
[root@localhost ~]# docker run -d -p 1216:80 httpd:centos 773fca3991ff3364783ba6ea58080d50729277bea8a4db024d8797243d80e212
訪問容器中的apache服務,如圖所示:
7.將鏡像上傳到倉庫中
倉庫分爲:公有倉庫和私有倉庫。使用公有倉庫下載鏡像是不須要註冊的較爲方便,可是上傳就行則須要註冊,下載地址是https://hub.docker.com 。使用私有倉庫須要在構建私有倉庫的服務器上下載registry鏡像。
1)下載registry鏡像
[root@localhost ~]# docker pull registry 如下是顯示下載完成信息 latest: Pulling from docker.io/library/registry 4064ffdc82fe: Pull complete c12c92d1c5a2: Pull complete 4fbc9b6835cc: Pull complete 765973b0f65f: Pull complete 3968771a7c3a: Pull complete Digest: sha256:51bb55f23ef7e25ac9b8313b139a8dd45baa832943c8ad8f7da2ddad6355b3c8 Status: Downloaded newer image for docker.io/registry:latest
2)在/etc/docker目錄下建立一個json文件,不然在往自定義的私有倉庫中上傳鏡像是會報錯。
[root@localhost ~]# vim /etc/docker/daemon.json { "insecure-registries":["192.168.126.141:5000"]} [root@localhost ~]# systemctl restart docker.service [root@localhost ~]# docker create -it registry /bin/bash #建立容器 0835c45afb5e33135362242347356b65f572198a773e2a3d60f81d938d8b301f root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0835c45afb5e registry "/entrypoint.sh /b..." 8 seconds ago Created upbeat_elion 773fca3991ff httpd:centos "/run.sh" 8 minutes ago Exited (137) About a minute ago pedantic_pasteur 511e945fc770 11426a19f1a2 "/bin/bash" 16 minutes ago Exited (0) About a minute ago ecstatic_hamilton [root@localhost ~]# docker start 0835c45afb5e #開啓容器 0835c45afb5e
3)使用下載好的registry鏡像啓動一個容器,默認狀況下倉庫存放於容器內的/tmp/registry目錄下,使用-v選項能夠將本地目錄掛載到容器內的/tmp/registry下 使用,這樣就不怕容器被刪除後鏡像也會隨之丟失。
[root@localhost ~]# docker run -d -p 5000:5000 -v /data/registry:/tmp/registry registry
4)使用docker tag命令將要上傳的鏡像標記爲
[root@localhost ~]# docker tag docker.io/httpd 192.168.126.141:5000/httpd
5)用docker push上傳標記的鏡像
[root@localhost ~]# docker push 192.168.126.141:5000/httpd The push refers to a repository [192.168.126.141:5000/httpd] 28eaf9ee6b41: Pushed dcaeabd68175: Pushed 94519f51ae61: Pushed 74e07a1c6b07: Pushed 611673f0c323: Pushed f6ff89d562dc: Pushed dd1eb1fd7e08: Pushed latest: digest: sha256:a2eeb4eece5b956cbd6fae9ec2d5f9fd083a197ae6f1ed68ccb01bb034893c65 size: 1780
6)獲取私有倉庫列表
[root@localhost ~]# curl -XGET http://192.168.126.141:5000/v2/_catalog {"repositories":["httpd"]}
管理Docker容器中數據主要有兩種方式:數據卷(Data Volumes)和數據卷容器(Data volumes Containers)。
數據卷是一個供容器使用的特殊目錄,位於容器中,可將宿主機的目錄掛載到數據捲上,對數據卷的修改操做馬上可見,而且更新數據不會影響鏡像,從而實現數據在宿主機與容器之間的遷移。
1.建立數據卷
在docker run 命令中使用-v 選項能夠在容器內建立數據卷。屢次使用-v能夠建立多個數據卷。使用--name選項能夠給容器建立一個友好的自定義名稱。
1)使用httpd:centos鏡像建立一個名爲web1的容器,並將宿主機的/var/www目錄掛載到容器的/data1目錄上,如:
[root@localhost ~]# docker run -v /var/www:/data1 --name web1 -it centos /bin/bash [root@7b584c5f1d20 /]# ls anaconda-post.log bin data1 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
2)在宿主機本地/var/www目錄中建立一個文件,進入運行的容器中。在相應的掛載目錄下能夠看到剛纔在宿主機上建立的文件,實現了從宿主機到容器的數據遷移。
[root@localhost ~]# cd /var/www/ [root@localhost www]# ls [root@localhost www]# touch test123 [root@localhost www]# ls test123 [root@localhost www]# docker start 7b584c5f1d20 #啓動容器 [root@localhost www]# docker exec -it web1 /bin/bash [root@7b584c5f1d20 /]# cd data1/ [root@7b584c5f1d20 data1]# ls test123
同理在容器數據卷中建立的數據在宿主機相應的掛載目錄中也能夠訪問。
數據卷容器就是一個普通的容器,專門提供數據卷給其餘容器掛載使用。
1.建立一個新的數據卷容器爲web100,其中所建立的數據卷分別掛載到了/data1與/data2目錄上。
[root@localhost www]# docker run --name web100 -v /data1 -v /data2 -it centos /bin/bash [root@ab7632329eee /]# ls anaconda-post.log bin data1 data2 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
2.使用--volumes-from 來掛載web100容器中的數據捲到新的容器,新的容器名爲db1。
[root@localhost www]# docker run --name db1 --volumes-from web100 -it centos /bin/bash [root@eb56026f763c /]# ls anaconda-post.log bin data1 data2 dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
3.在db1容器數據卷/data2目錄中建立一個文件file。在web100容器中的/data2目錄中能夠查看到文件file。
[root@eb56026f763c /]# cd data2 [root@eb56026f763c data2]# ls [root@eb56026f763c data2]# touch file [root@localhost www]# docker start ab7632329eee #啓動web100容器 ab7632329eee [root@localhost www]# docker exec -it ab7632329eee /bin/bash #進入容器 [root@ab7632329eee /]# ls data2/ #數據遷移成功 file
Docker提供了映射容器端口到宿主機和容器互聯機制來爲容器提供網絡服務。
在啓動容器的時候,若是不指定對應的端口,在容器外將沒法經過網絡來訪問容器內的服務。Docker提供端口映射機制來將容器內的服務提供給外部網絡訪問,實質上就是將宿主機的端口映射到容器中,使得外部網絡訪問主機的端口即可訪問容器內的服務。
1.實現端口映射,須要在運行docker run命令時使用-P(大寫)選項實現隨機映射,Docker會隨機映射一個端口範圍在49000~49900的端口到容器內部開放的網絡端口。
[root@localhost ~]# docker run -d -P httpd:centos 4749e5d0ac4b7b42f74e27e0aebf611ce11fb1f92248751c8e66349f7ada4019
2.查看本機的32768端口是否被映射到了容器中的80端口。
[root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4749e5d0ac4b httpd:centos "/run.sh" 16 seconds ago Up 14 seconds 0.0.0.0:32768->80/tcp romantic_mcclintock
3.還能夠在運行docker run命令時使用-p(小寫)選項指定要映射的端口,例如:
[root@localhost ~]# docker run -d -p 49280:80 httpd:centos [root@localhost ~]# docker ps -a #端口映射成功 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 17251b86a2b0 httpd:centos "/run.sh" 3 seconds ago Up 1 second 0.0.0.0:49280->80/tcp keen_rosalind
容器互聯就是經過容器的名稱在容器間創建一條專門的網絡通訊隧道從而實現容器的互聯。
注意:若是已經命名了一個相同的容器,當要再次使用這個名稱時,須要使用docker rm命令刪除以前建立的同名容器。
1.建立源容器
使用docker run命令創建容器,使用--name指定容器的名稱爲web1。
[root@localhost ~]# docker run -P --name web1 -it httpd:centos /bin/bash [root@localhost ~]# docker start ec056f796f5c #開啓容器web1 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ec056f796f5c httpd:centos "/bin/bash" 8 minutes ago Up 5 minutes 0.0.0.0:32771->80/tcp web1 .....//省略
2.建立接收容器
使用docker run命令創建容器,使用--name指定容器的名稱爲web2,使用--link指定鏈接容器以實現容器互聯。
[root@localhost ~]# docker run -P --name web2 --link web1:web1 -it httpd:centos /bin/bash [root@localhost ~]# docker start 853da4a8f368 #開啓容器web2 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 853da4a8f368 httpd:centos "/bin/bash" 6 minutes ago Up 3 minutes 0.0.0.0:32774->80/tcp web2 .....//省略
3.測試容器互聯
進入容器web2中,使用ping命令查看容器web2是否能互相連通。
[root@localhost ~]# docker exec -it 853da4a8f368 /bin/bash [root@853da4a8f368 /]# ping web1 PING web1 (172.17.0.3) 56(84) bytes of data. 64 bytes from web1 (172.17.0.3): icmp_seq=1 ttl=64 time=0.282 ms 64 bytes from web1 (172.17.0.3): icmp_seq=2 ttl=64 time=0.118 ms 64 bytes from web1 (172.17.0.3): icmp_seq=3 ttl=64 time=0.121 ms 64 bytes from web1 (172.17.0.3): icmp_seq=4 ttl=64 time=0.118 ms ^C --- web1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3003ms rtt min/avg/max/mdev = 0.118/0.159/0.282/0.072 ms
此時/能夠看到容器web2與容器web1已經創建互聯關係。Docker在兩個互聯的容器之間建立了一條安全隧道,並且不用映射它們的端口到宿主機上,從而避免暴露端口給外部網絡。