和我一起學docker(三)映象的那些事兒

和我一起學docker(三)映象的那些事兒

docker

作者:DevOps旭

來自:DevOps探路者

一、映象是什麼?

作為最為火爆的容器技術,docker快速佔據市場的原因之一就是docker映象。那麼docker映象是什麼呢?docker映象可以簡單的理解為環境和應用的集合,是一種封裝方式,類似於java的jar包,centos的rpm包。這一打包格式使得透過docker封裝的應用可以快速的推廣,並且在任何環境下執行此應用。所以說,映象的規範是docker的最大的貢獻,那麼這一規範是什麼呢?

我們先從dockerhub上拉取一個映象

[root@k8s03 ~]# docker pull tomcatUsing default tag: latestlatest: Pulling from library/tomcatd6ff36c9ec48: Pull complete c958d65b3090: Pull complete edaf0a6b092f: Pull complete 80931cf68816: Pull complete bf04b6bbed0c: Pull complete 8bf847804f9e: Pull complete 6bf89641a7f2: Pull complete 3e97fae54404: Pull complete 10dee6830d45: Pull complete 680b26b7a444: Pull complete Digest: sha256:cbdcddc4ca9b47e42c7d0c2db78cbc0f7a8b4bbe1fa395f4a53c5a236db29146Status: Downloaded newer image for tomcat:latestdocker。io/library/tomcat:latest

這是一個從dockerhub上拉取的tomcat映象,可以看到,在拉取過程中映象分成了10層,下面可以檢視一下映象的詳情

[root@k8s03 ~]# docker inspect d5eef28cf41d 。。。           “Data”: {               “LowerDir”: “/mnt/docker-lib/overlay2/ad0fdd6e7fadd5b77a7383d47553f77a727fa85c70da136be40ea44c6944ab11/diff:/mnt/docker-lib/overlay2/7b7f957f86be54f7497129f4a5cf664fc1a6879a5a83d5f37d720decbb229d78/diff:/mnt/docker-lib/overlay2/bc72109526d4f1a45ebab8b1abe9a36ceb5841ec37bad3d5b69873b9a41bb687/diff:/mnt/docker-lib/overlay2/eea0db10d31a06a305dd9d980d5c18e42f04f9026e2367f273066bd0e53ef2a5/diff:/mnt/docker-lib/overlay2/67512ff785e66fe5401dd44f2791decd1111026fd39f0b0dd8017e5a2a3d98bc/diff:/mnt/docker-lib/overlay2/1f7e4902a79ef2038947523535192aeadd097ee16020a0c95a695311534b70d3/diff:/mnt/docker-lib/overlay2/a46448ddb1c30de01b7e8539a958203b202bca669ad62707a9aca818c7273548/diff:/mnt/docker-lib/overlay2/62dc4b28677571e3abef933b1f199a85e62105cbe62752b840cc7e535300755d/diff:/mnt/docker-lib/overlay2/7a1f7a7de4e054c05ff4513a30bf087385f74caf5fce4462fc14bfb177d47239/diff”,               “MergedDir”: “/mnt/docker-lib/overlay2/b6f983ae3751c3ea17d91c964060dd44d39430c75fc7821caac7eeb8871dfc77/merged”,               “UpperDir”: “/mnt/docker-lib/overlay2/b6f983ae3751c3ea17d91c964060dd44d39430c75fc7821caac7eeb8871dfc77/diff”,               “WorkDir”: “/mnt/docker-lib/overlay2/b6f983ae3751c3ea17d91c964060dd44d39430c75fc7821caac7eeb8871dfc77/work”           },。。。

而映象的資料就在這些目錄之內,而這也就是基於UnionS實現的映象的分層規範。同時除了最底層映象,每一層都有一個指向底層的索引,便於找到這一層映象的父層,而這就意味著,父層是可以進行復用的,透過這一共用父層的方式,可以降低儲存的使用,提高構建的速率。

和我一起學docker(三)映象的那些事兒

二、定製屬於你的映象

1、構建映象的方法

既然映象有這麼多的優勢,那麼應該如何製作映象呢?第一種是透過容器構建映象,即容器映象,透過docker commit 的方式進行構建,該方法本菜鳥並不推薦,原因有如下幾點:1)映象為分層結構,容器則為映象頂層加了一個可寫層,這一方式構建的映象極容易映象過大。2)容器映象無法確定這一層可寫層內的內容,對於安全性上,存在問題,而且也不易維護。第二種映象構建的方法則為dockerfile,透過dockerfile來控制映象的構建,這個也是官方推薦的方案。

2、深入理解dockerfile

那麼dockerfile是什麼樣子的呢?

FROM centos:7ENV VERSION=8。5。43RUN yum install java-1。8。0-openjdk wget curl unzip iproute net-tools -y && \   yum clean all && \   rm -rf /var/cache/yum/*COPY apache-tomcat-${VERSION}。tar。gz /RUN tar zxf apache-tomcat-${VERSION}。tar。gz && \   mv apache-tomcat-${VERSION} /usr/local/tomcat && \   rm -rf apache-tomcat-${VERSION}。tar。gz /usr/local/tomcat/webapps/* && \   mkdir /usr/local/tomcat/webapps/test && \   echo “ok” > /usr/local/tomcat/webapps/test/status。html && \   sed -i ‘1a JAVA_OPTS=“-Djava。security。egd=file:/dev/。/urandom”’ /usr/local/tomcat/bin/catalina。sh && \   ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtimeENV PATH $PATH:/usr/local/tomcat/binWORKDIR /usr/local/tomcatEXPOSE 8080CMD [“catalina。sh”, “run”]

這是一個tomcat的dockerfile,裡面涉及到了dockerfile的專用語法,包括FROM、RUN、ENV、WORKDIR等等,那麼都有什麼作用呢?

2.1、FROM

FROM

映象是分層的,透過FROM可以引用一個基礎映象,這個是必須的模組,而映象是以此為基礎,每執行一條命令,就在此基礎上增加一層映象,所以基礎映象需要儘可能的精簡,同時要保證安全性。

2.2、WORKDIR

WORKDIR /path/to/workdir

這一模組用於指定工作目錄,如果指定後,透過exec進入容器後,便在WORKDIR中,同時需要注意,透過相對路徑執行命令時,一定要正確設定WORKDIR,避免出現因路徑導致的失敗。

2.3、COPY 和AND

COPY 原始檔 目標路徑ADD 原始檔 目標路徑

這兩個模組用處相同,都是將檔案複製到映象內,但是還是存在一些差異:

a、ADD 可以透過網路源下載檔案封入映象內。

b、ADD可以對tar、gzip、bzip2等檔案進行解壓。

2.4、RUN

RUN command1 。。。 commandN

RUN模組引導的是構建映象時執行的命令,每執行一次RUN,會生成一層映象,所以建議在使用中,透過&& 連結來減少映象層數,比如構建基礎映象時,透過一條RUN 將java和tomcat封裝在同一層內做基礎映象,那麼業務映象僅需要在基礎映象外再加一層,這樣便可以保障映象的精簡。

2.5、ENV

ENV key=value

ENV模組將環境變數注入到映象內。

2.6、EXPOSE

EXPOSE port XXXX

此模組用於聲名暴露的埠。

2.7、USER

USER app​USER app:app​USER 500​USER 500:500​USER app:500​USER 500:app

USER模組用於限定使用者,可以用來實現降權執行容器內的應用,提高安全性。在使用這個模組時,需要使用useradd建立使用者。

2.8、ENTRYPOINT

ENTRYPOINT [“command”,“param”]ENTRYPOINT command param

ENTRYPOINT模組用於設定容器啟動時的命令,設定一個不退出的前臺程序,同時,ENTRYPOINT設定的命令不會被docker run所覆蓋。

2.9、CMD

CMD [“command”,“param”]CMD command paramCMD [“param1”,“param2”]

CMD模組和ENTRYPOINT 使用方法一致,但是CMD模組可以被docker run所覆蓋,同時CMD 可以和ENTRYPOINT 配合使用,作為ENTRYPOINT 的引數出現。

3、構建屬於你的映象

構建映象是透過docker build來實現的,下面我們來構建一個tomcat的映象,先看一下dockerfile

FROM centos:7COPY apache-tomcat-8。5。56。tar。gz /mntCOPY jdk-8u261-linux-x64。tar。gz /mntRUN cd /mnt && \   tar zxf jdk-8u261-linux-x64。tar。gz && \ mv jdk1。8。0_261 /usr/local/java && \ tar zxf apache-tomcat-8。5。56。tar。gz && \ mv apache-tomcat-8。5。56 /usr/local/tomcat && \ rm -f apache-tomcat-8。5。56。tar。gz jdk-8u261-linux-x64。tar。gz && \   ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtimeENV JAVA_HOME=/usr/local/javaENV JRE_HOME=/usr/local/java/jreENV PATH $PATH:/usr/local/java/bin:/usr/local/tomcat/binWORKDIR /usr/local/tomcatEXPOSE 8080CMD [“catalina。sh”, “run”]​

開始構建映象

[root@k8s03 hgfs]# docker build -t tomcat8:base 。 Sending build context to Docker daemon 521。8MBStep 1/10 : FROM centos:7 ——-> 7e6257c9f8d8Step 2/10 : COPY apache-tomcat-8。5。56。tar。gz /mnt ——-> 154214a58ae1Step 3/10 : COPY jdk-8u261-linux-x64。tar。gz /mnt ——-> 94af330c2ab1Step 4/10 : RUN cd /mnt &&     tar zxf jdk-8u261-linux-x64。tar。gz &&   mv jdk1。8。0_261 /usr/local/java &&     tar zxf apache-tomcat-8。5。56。tar。gz &&       mv apache-tomcat-8。5。56 /usr/local/tomcat &&   rm -f apache-tomcat-8。5。56。tar。gz jdk-8u261-linux-x64。tar。gz &&     ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ——-> Running in a53326701fb1Removing intermediate container a53326701fb1 ——-> 926a7bd6dadeStep 5/10 : ENV JAVA_HOME=/usr/local/java ——-> Running in 3608b84318e5Removing intermediate container 3608b84318e5 ——-> c41f3ee011fbStep 6/10 : ENV JRE_HOME=/usr/local/java/jre ——-> Running in 4ed9b3a8fe13Removing intermediate container 4ed9b3a8fe13 ——-> c577b0979b9cStep 7/10 : ENV PATH $PATH:/usr/local/java/bin:/usr/local/tomcat/bin ——-> Running in a718feca40fbRemoving intermediate container a718feca40fb ——-> 18f66356c84eStep 8/10 : WORKDIR /usr/local/tomcat ——-> Running in 5bd80d012f28Removing intermediate container 5bd80d012f28 ——-> db5a93e1adb0Step 9/10 : EXPOSE 8080 ——-> Running in 488067edba1dRemoving intermediate container 488067edba1d ——-> 96a08d9468c9Step 10/10 : CMD [“catalina。sh”, “run”] ——-> Running in 703caa5216f1Removing intermediate container 703caa5216f1 ——-> e7d08a6fe4b6Successfully built e7d08a6fe4b6Successfully tagged tomcat8:base

這裡有一個很有意思的事情,當構建構成中,執行docker ps命令可以看到一個構件中的容器

[root@k8s03 hgfs]# docker ps CONTAINER ID       IMAGE                         COMMAND                 CREATED             STATUS             PORTS               NAMESd4621ccda168       df2785b6788e                 “/bin/sh -c ‘cd /mnt…”   4 seconds ago       Up 3 seconds                           interesting_yalow

而這個容器在做的事情就是構建這個映象,而當映象構建成功後,這個容器也會被刪掉。

下面我們驗證一下這個映象

[root@k8s03 hgfs]# docker run -d tomcat8:baseed0a14b3a86e6e96237ef84aed0229cad51ce3baa6125f28e16757178d67c01c[root@k8s03 hgfs]# docker ps CONTAINER ID       IMAGE                         COMMAND                 CREATED             STATUS             PORTS               NAMESed0a14b3a86e       tomcat8:base                 “catalina。sh run”       5 seconds ago       Up 5 seconds       8080/tcp

容器啟動成功,那麼進入容器內驗證一下環境變數

[root@k8s03 hgfs]# docker exec -it ed0a14b3a86e bash [root@ed0a14b3a86e tomcat]# echo $JAVA_HOME/usr/local/java[root@ed0a14b3a86e tomcat]# echo $JRE_HOME /usr/local/java/jre[root@ed0a14b3a86e tomcat]# echo $PATH    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/java/bin:/usr/local/tomcat/bin[root@ed0a14b3a86e tomcat]#

至此,一個基於java8 和 tomcat8的 centos7基礎映象構建完畢

三、映象管理

1、清理dangling映象

在日常工作中,常常會出現一個現象,就是針對一個部署包進行多次修改,每次修改都建立一個新的映象,但是tag和image都未修改,這樣每一次構建後,image和tag都會指向最新的映象,而之前的映象就會變成的樣式,也就是dangling映象

[root@k8s03 hgfs]# docker images -f “dangling=true”REPOSITORY         TAG                 IMAGE ID           CREATED             SIZE                         d4aa089b72f7       16 minutes ago     734MB                         e0d2d9814c3f       17 minutes ago     357MB

這一映象是需要頻繁清理以實現節約空間的目的

2、清理業務映象

業務映象理論上應謹慎清理,可定時清理超期映象,但是為了實現版本控制,製品庫內的映象進行歸檔封存,不建議徹底清理。

和我一起學docker(三)映象的那些事兒