- Docker鏡像除了是Docker的核心之外,也是應用釋出的标準格式。一個完整的Docker鏡像可以支撐一個Docker容器的運作,在整個Docker使用過程中,進入一個已經定型的容器之後,就可以在容器裡進行操作,最常見的操作就是在容器裡安裝應用服務等,如果要把已安裝的服務進行遷移,就需要把環境及搭建的服務生成新的鏡像。
-
建立鏡像的方法有三種,分别為“基于已有鏡像建立”,"基于本地模闆建立","基于Docekr建立"。
1.基于已有鏡像建立
安裝Docker所需鏡像:連結: https://pan.baidu.com/s/1t0ZuEUn4UU8ApQxMRv1q0g
提取碼: bcxv
[root@localhost ~]# mkdir /yumbeifen [root@localhost ~]# mv /etc/yum.repos.d/* /yumbeifen/ [root@localhost ~]# vim /etc/yum.repos.d/a.repo [Docker] name=docker baseurl=file:///media gpgcheck=0 [root@localhost ~]# eject [root@localhost ~]# mount /dev/cdrom /media/ mount: /dev/sr0 is write-protected, mounting read-only [root@localhost ~]# yum -y install docker [root@localhost ~]# systemctl start docker //啟動Docker [root@localhost ~]# systemctl enable docker //開機自啟Docker
1.1所需CD光牒鏡像連結: https://pan.baidu.com/s/1JMYMlG04ZHEeLmB93kmkVQ
提取碼: mkyj
[root@localhost ~]# eject [root@localhost ~]# mount /dev/cdrom /media/ [root@localhost ~]# cd /media/ [root@localhost media]# ls apache-tomcat-8.5.16.tar.gz dhcp jdk-8u91-linux-x64.tar.gz centos httpd registry.tar.gz centos6 httpd_centos ubuntu-12.04-x86_64-minimal.tar.gz [root@localhost media]# docker load < dhcp //将CD光牒所需檔案導入本地 [root@localhost ~]# docker images //檢視鏡像 REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/centos latest 75835a67d134 13 months ago 200 MB docker.io/networkboot/dhcpd latest 6f98b6b9b486 19 months ago 125 MB [root@localhost ~]# docker create -it docker.io/networkboot/dhcpd /bin/bash //基于鏡像建立容器 586a78aef06b243ff95a341a6c7d0b1b5f1e87bc3a65973345cbb1a4de5c070c [root@localhost ~]# docker ps -a //檢視容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 586a78aef06b docker.io/networkboot/dhcpd "/entrypoint.sh /b..." 5 seconds ago Created [root@localhost ~]# docker start 586a78aef06b //啟動容器 586a78aef06b [root@localhost ~]# docker exec -it 586a78aef06b /bin/bash //進入容器touch兩個檔案 root@586a78aef06b:/# touch haha hhh root@586a78aef06b:/# ls bin core entrypoint.sh haha home lib64 mnt proc run srv tmp var boot dev etc hhh lib media opt root sbin sys usr [root@localhost ~]# docker commit -m "mewdhcp" -a "wyjx" 586a78aef06b docker:mydhcp //使用dockercommit指令建立新的鏡像 sha256:657f27fc22ca4ae8d1ca766843539a42eadc9dd6b11c46313a338a943fb44cec [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE docker mydhcp 657f27fc22ca 18 seconds ago 125 MB docker.io/centos latest 75835a67d134 13 months ago 200 MB docker.io/networkboot/dhcpd latest 6f98b6b9b486 19 months ago 125 MB
2、基于本地模闆建立
通過導入作業系統模闆檔案可以生成鏡像,模闆可以從 OPENVZ 開源項目下載下傳,下載下傳位址為:http://openvz.org/Download/template/precreated
[root@test /]# wget http://download.openvz.org/template/precreated/ubuntu-14.04-x86_64-minimal.tar.gz
# 下載下傳一個迷你版的Ubuntu模闆
[root@test /]# cat ubuntu-14.04-x86_64-minimal.tar.gz | docker import - docker:new
sha256:7457fecee0fb28ab06d935e7a9a5a040d9d6ec8931959b752f596cde76a5d647
# 将模闆導入
[root@test /]# docker images |grep new # 檢視已經導入
docker new 7457fecee0fb About a minute ago 215 MB
3、基于 Dockerfile 建立
dockerfile是由一組指令組成的檔案,其中每條指令對應Linux中的一條指令,docker程式将讀取dockerfile中的指令生成指定鏡像。
dockerfile結構大緻分為四個部分:基礎鏡像資訊、維護者資訊、鏡像操作指令和容器啟動時執行指令。dockerfile每行支援一條指令,每條指令可攜帶多個參數,支援使用“#”号開頭的注釋。
dockerfile中的配置項介紹:
[root@localhost ~]# docker tag docker:new centos7:system
#将上面下載下傳的centos 7迷你鏡像更改下名字及标簽,以便區分
[root@localhost ~]# docker images | grep system
#确認基礎鏡像已經準備好(就是一個centos 7的迷你系統進行)
centos7 system c065d5c0571d About an hour ago 435 MB
[root@localhost ~]# vim Dockerfile #編輯一個Dockerfile檔案,注意:檔案名最好就是Dockerfile
FROM centos #第一行必須指明基于的基礎鏡像(該鏡像必須存在)
MAINTAINER The centos project <[email protected]> #維護該鏡像的使用者資訊
#以下是鏡像的操作指令
RUN yum -y update
RUN yum -y install openssh-server
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
EXPOSE 22 #開啟22端口
CMD ["/usr/sbin/sshd","-D"] #啟動容器時執行指令
在編寫dockerfile時,有嚴格的格式需要遵循:第一行必須使用FROM指令指明所基于的鏡像名稱;之後使用MAINTAINER指令說明維護該鏡像的使用者資訊;然後是鏡像操作相關指令,如RUN指令,每運作一條指令,都會給基礎鏡像添加新的一層;最後使用CMD指令來指定啟動容器時要運作的指令操作。
dockerfile有十幾條指令可用于建構鏡像,其中常見的指令如下:
例:使用dockerfile建立apache鏡像并在容器中運作
[root@test /]# mkdir apache # 建立工作目錄
[root@test /]# cd /apache/
[root@test apache]# vim Dockerfile # 建立并編寫 Dockerfile檔案
FROM centos # 基于的基礎鏡像centos
MAINTAINER the centos # 維護該鏡像的使用者資訊
RUN yum -y update # 鏡像操作指令安裝 Apache 軟體包
RUN yum -y install httpd
EXPOSE 80 # 開啟80端口
ADD index.html /var/www/html/index.html # 複制網站首頁檔案
ADD run.sh /run.sh # 将執行腳本複制到鏡像中
RUN chmod 775 /run.sh
RUN systemctl disable httpd # 設定Apache服務不自行啟動
CMD ["/run.sh"] # 啟動容器時執行腳本
[root@test apache]# vim run.sh # 編寫執行腳本内容
#!/bin/bash
rm -rf /run/httpd/* # 清理 httpd 緩存
exec /usr/sbin/apachectl -D FOREGROUND # 啟動Apache服務
[root@test apache]# echo "www.test.com" > index.html # 建立測試頁面
[root@test apache]# ls
Dockerfile index.html run.sh
[root@test apache]# docker build -t httpd:centos .
............................ // 省略部分内容
# 注意注意注意:這條指令後面有一個“.” 代表目前路徑,否則會報錯,切記千萬不要忘記
[root@test apache]# docker run -d -p 12345:80 httpd:centos # 使用新的鏡像運作容器,-p 選項實作從本地端口12345到容器的80端口映射
0721b1641ce0651d618a393b85d34606180dd33d4795621db320865cda8f3a0a
[root@test apache]# docker ps -a # 檢視容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0721b1641ce0 httpd:centos "/run.sh" 6 seconds ago Up 6 seconds 0.0.0.0:12345->80/tcp sad_mcclintock
通路容器中的apache服務
二、搭建私有庫及其使用方法
随着建立的鏡像增多,就需要有一個儲存鏡像的地方,這就是倉庫,目前有兩種倉庫:公共倉庫和私有倉庫,公司的生産環境中大多數都是儲存到私有倉庫的,最簡單的還是在公共倉庫上下載下傳鏡像,若是上傳鏡像至公共倉庫,還需要注冊并登陸,關于公共倉庫的上傳,可以參考https://blog.51cto.com/14227204/2453408
怎麼建構私有倉庫呢?可以使用registry來搭建本地私有倉庫
[root@test ~]# docker search registry #查詢關鍵字“registry”
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/registry The Docker Registry 2.0 implementation for... 2679 [OK]
..................#省略部分内容
[root@localhost ~]# docker pull docker.io/registry #下載下傳排名靠前的鏡像
..................#省略部分内容
Status: Downloaded newer image for docker.io/registry:latest #下載下傳成功
[root@localhost ~]# vim /etc/sysconfig/docker
#修改docker配置檔案指定私有倉庫URL,否則在自定義的私有倉庫中上傳鏡像時會報錯
# /etc/sysconfig/docker
# Modify these options if you want to change the way the docker daemon runs
OPTIONS='--selinux-enabled --insecure-registry=192.168.1.1:5000'
#更改上面一行内容,其中的IP位址是作為私有倉庫伺服器的IP位址,這裡就是本機的IP位址。
..................#省略部分
#修改完畢後儲存退出
[root@test ~]# systemctl restart docker #重新開機docker
使用下載下傳好的registry鏡像啟動一個容器,預設情況下倉庫存放于容器内的/tmp/registry目錄下,使用-v選項可以将本地目錄挂載到容器内的/tmp/registry目錄下使用,這樣就不怕容器被删除後鏡像也會随之丢失。在本地啟動一個私有倉庫服務,監聽端口号為5000。
[root@test ~]# df -hT /data/registry/ #檢視我這個目錄所使用的檔案系統
檔案系統 類型 容量 已用 可用 已用% 挂載點
node4:dis-stripe fuse.glusterfs 80G 130M 80G 1% /data/registry
[root@test ~]# docker run -d -p 5000:5000 -v /data/registry/:/tmp/registry docker.io/registry
#啟動私有倉庫,并做端口映射到主機的5000端口,将本地的/data/registry目錄挂載到容器中的/tmp/registry目錄
#docker.io/registry是剛才下載下傳的私有倉庫鏡像。
a6bf726c612b826e203d6a5bc9eaba26c36195913d3ea546c2111ce290a5524d
[root@test ~]# docker tag docker.io/registry 192.168.1.1:5000/registry
#使用docker tag指令将要上傳的鏡像docker.io/registry改一下标記,其中的IP及端口為固定的,否則無法連接配接到私有倉庫
#因為在上面運作容器時,做了端口映射,将私有倉庫的端口号映射到了主控端的5000端
口,
#是以直接通路主控端的5000端口,就相當于通路了私有倉庫。
[root@test ~]# docker images | grep 5000 #找到要上傳的鏡像
192.168.1.1:5000/registry latest f32a97de94e1 6 months ago 25.8 MB
[root@test ~]# docker push 192.168.1.1:5000/registry #上傳至剛剛運作的私有倉庫
The push refers to a repository [192.168.1.1:5000/registry]
73d61bf022fd: Pushed
5bbc5831d696: Pushed
d5974ddb5a45: Pushed
f641ef7a37ad: Pushed
d9ff549177a9: Pushed
latest: digest: sha256:b1165286043f2745f45ea637873d61939bff6d9a59f76539d6228abf79f87774 size: 1363
#下面再上傳一個鏡像,進行測試。
[root@test ~]# docker images | grep mynamed #就上傳它了
docker mynamed e178f320e482 4 hours ago 323 MB
[root@test ~]# docker tag docker:mynamed 192.168.1.1:5000/named:test
#老規矩,必須改倉庫名,注意:若标簽不是預設的latest,那麼還需要在倉庫名後面接上标簽名
[root@test ~]# docker images | grep 192.168.1.1:5000/named #确定更改成功
192.168.1.1:5000/named test e178f320e482 4 hours ago 323 MB
[root@test ~]# docker push 192.168.1.1:5000/named:test #上傳至私有倉庫
The push refers to a repository [192.168.1.1:5000/named]
c756b9ec7fb0: Pushed
7d8d01394159: Pushed
72b7cd87d69b: Pushed
3be48ef75683: Pushed
9b28c58ad64b: Pushed
75e70aa52609: Pushed
dda151859818: Pushed
fbd2732ad777: Pushed
ba9de9d8475e: Pushed
test: digest: sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f size: 2403
[root@test ~]# df -hT /data/registry/ #先檢視本地/data/registry/ 挂載的檔案系統
檔案系統 類型 容量 已用 可用 已用% 挂載點
node4:dis-stripe fuse.glusterfs 80G 130M 80G 1% /data/registry
[root@test ~]# docker exec -it a6bf726c612b /bin/sh
#進入私有倉庫的容器中,該容器沒有/bin/bash,是以使用的是/bin/sh。
/ # df -hT /tmp/registry/ #檢視發現,該目錄挂載的和主控端挂載的檔案系統是同一個,說明沒問題。
Filesystem Type Size Used Available Use% Mounted on
node4:dis-stripe fuse.glusterfs
80.0G 129.4M 79.8G 0% /tmp/registry
——————————————————————
#那麼如何檢視上傳至私有倉庫的鏡像呢?請看下面:
[root@test ~]# curl -XGET http://192.168.1.1:5000/v2/_catalog
#檢視已經上傳的鏡像,可以看到剛剛上傳的那兩個鏡像
{"repositories":["named","registry"]}
#隻知道鏡像名還不夠,若要下載下傳,還需要鏡像對應的标簽,那麼怎麼檢視某個鏡像的标簽呢?
[root@test ~]# curl -XGET http://192.168.1.1:5000/v2/named/tags/list
#就這樣檢視咯,上面URL路徑中的named就是鏡像名,檢視的就是鏡像named對應的标簽
{"name":"named","tags":["test"]}
[root@test ~]# docker pull 192.168.1.1:5000/named:test #将私有倉庫中的鏡像下載下傳下來
#前面必須指定私有倉庫的通路位址,就是上傳時的名字是什麼,下載下傳時就是什麼,哪怕查詢的鏡像名中沒有IP位址。
Trying to pull repository 192.168.1.1:5000/named ...
sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f: Pulling from 192.168.1.1:5000/named
Digest: sha256:44894a684eac72a518ae5fa66bcbe4e4a9429428ef7ac6f4761022f8ac45ac5f
Status: Downloaded newer image for 192.168.1.1:5000/named:test
[root@node1 ~]# echo '{ "insecure-registries":["xxx.xxx.xxx.xxx:5000"] }' > /etc/docker/daemon.json
#其中xxx.xxx.xxx.xxx:5000代表通路私有倉庫的IP位址及端口,根據自己的伺服器情況來定
[root@node1 ~]#systemctl restart docker #重新開機docker服務