1 . 創建鏡像
有兩種方法構建鏡像:
- docker commit :將運行的容器保存成鏡像
- Dockerfile:自動構建
使用docker commit 創建鏡像分為三步:
- 運行容器
- 修改容器
- 將容器保存為鏡像
舉例:
[root@docker ~]# docker load -i busybox.tar # 導入鏡像
8a788232037e: Loading layer 1.37MB/1.37MB
Loaded image: busybox:latest
[root@docker ~]# docker run -it --name test busybox # 運行
/ # ls
bin dev etc home proc root sys tmp usr var
/ # ^C
/ # [root@docker ~]#
[root@docker ~]#
修改容器
/ # echo "hello toto" > testfile
/ # ls
bin etc proc sys tmp var
dev home root testfile usr
將容器保存為新的鏡像:
docker commit test busybox:v2
查看新生成的鏡像:無法看新鏡像層的操作
IMAGE CREATED CREATED BY SIZE COMMENT
0cdf20286e29 About a minute ago sh 46B
59788edf1f3e 9 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:63eebd629a5f7558c… 1.15MB
直接運行新生成的鏡像容器:
docker run -it --name test busybox:v2 / # ls
bin etc proc sys tmp var
dev home root testfile usr # 里面保存了之前操作的數據。
以Dockerfile 創建鏡像
Dockerfile的詳細介紹:
1 、FROM:
用于指定base鏡像,本地不存在會從遠程倉庫進行下載
2、MAINTAINER
MAINTAINER:設置鏡像的作者,如用戶郵箱等(不是必須的)
3、COPY
把文件從build context復制到鏡像
支持兩種形式:COPY src dest和COPY [" src" ,"dest "]
src必須指定build context中的文件或目錄
dest為容器中的路徑
4 、ADD
用法與COPY類似,不同的是src可以是歸檔壓縮文件,文件會被自動解壓到dest,也可自動下載URL并拷貝到鏡像
DD html.tar /var/www ##解壓
ADD http://ip/html.tar /var/www ##下載
5 EXPOSE
如果容器中運行應用服務,則可以包服務端口暴露出去
6 、VOLUME
聲明數據卷,通常指定應用數據掛載點
- 一般VOLUME指定掛載點,沒有此路徑就會新建路徑。
- 在運行docker宿主機上,可以根據命令docker inspect 容器名的具體信息,可以查看封裝容器,聲明的數據卷,Source會存在此容器目錄掛接到本地_data目錄
- 由于自動掛載的路徑很長,不太方便記,也可以在運行的時候指定掛載路徑
7 、WORKDIR
為RUN、CMD、ENTRYPOINT、ADD和COPY指令設置鏡像中的當前工作目錄,如果目錄不存在也會自動創建
8 、RUN
RUN 在容器中運行命令并創建新的鏡像層,常用于安裝軟件包:每個run 都會多一層
9 、ENV:
設置環境變量,變量可以被后續的指令使用
10 、CMD 與 ENTRYPOINT
設置容器啟動后執行的命令,但是CMD會被docker run 后面的命令覆蓋,但ENTRYPOINT不會
Dockerfile中只能指定一個ENTRYPOINT,如果指定過多則只有最后一個有效
docke run后面的參數可以傳遞給ENTRYPOINT指令當作參數;
舉例:
創建空目錄以及Dockerfile文件
[root@docker docker]# ls
dockerfile
[root@docker docker]# pwd
/root/docker
[root@docker docker]# vim dockerfileFROM busybox # 以已經存在的busybox進行為base鏡像
RUN echo 'hello world' # 新加的操作,每一個RUN產生一個新的鏡像層
RUN echo 'westos linux'
創建新的鏡像:. 表示Dockerfile所在的路徑
[root@docker docker]# docker build -t busybox:v2 .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM busybox---> 59788edf1f3e
Step 2/3 : RUN echo 'hello world'---> Running in aeb63ff2b255
hello world
Removing intermediate container aeb63ff2b255---> 2f50636190bd
Step 3/3 : RUN echo 'westos linux'---> Running in 80071f12fdbb
westos linux
Removing intermediate container 80071f12fdbb---> 4b51d8f9a94b
Successfully built 4b51d8f9a94b
Successfully tagged busybox:v2
成功之后再次查看鏡像,已經成功生成鏡像
[root@docker docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox v2 4b51d8f9a94b 59 seconds ago 1.15MB
busybox latest 59788edf1f3e 9 months ago 1.15MB
game2048 latest 19299002fdbe 2 years ago 55.5MB
查看新生成的鏡像分層結構:
能清楚的看到每一層鏡像進行的操作,使用者可以對鏡像進行審計
[root@docker docker]# docker history busybox:v2
IMAGE CREATED CREATED BY SIZE COMMENT
4b51d8f9a94b 2 minutes ago /bin/sh -c echo 'westos linux' 0B
2f50636190bd 2 minutes ago /bin/sh -c echo 'hello world' 0B
59788edf1f3e 9 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:63eebd629a5f7558c… 1.15MB
當不修改剛才的Dockerfile的基礎上再次添加內容創建鏡像的時候
FROM busybox
RUN echo 'hello world'
RUN echo 'westos linux'
RUN echo haha > hahafile # 添加一條新的語句
再上一次的基礎上構建新的鏡像
[root@docker docker]# docker build -t busybox:v3 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM busybox---> 59788edf1f3e
Step 2/4 : RUN echo 'hello world'---> Using cache---> 2f50636190bd
Step 3/4 : RUN echo 'westos linux'---> Using cache---> 4b51d8f9a94b
Step 4/4 : RUN echo haha > hahafile---> Running in 3d4df4fde1c6
Removing intermediate container 3d4df4fde1c6---> 9e1099db5b57
Successfully built 9e1099db5b57
Successfully tagged busybox:v3
查看新生成的鏡像分層結構:
在Dockerfile文件中,每一個RUN語句都會生成一個新的鏡像層。
[root@docker docker]# docker history busybox:v3
IMAGE CREATED CREATED BY SIZE COMMENT
9e1099db5b57 49 seconds ago /bin/sh -c echo haha > hahafile 5B
4b51d8f9a94b 6 minutes ago /bin/sh -c echo 'westos linux' 0B
2f50636190bd 6 minutes ago /bin/sh -c echo 'hello world' 0B
59788edf1f3e 9 months ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:63eebd629a5f7558c… 1.15MB
docker鏡像優化:
1.優化鏡像應該主要有以下幾個方面:
1 選擇最精簡的基礎鏡像
2 減少鏡像的層數
3 清理鏡像構建的中間產物
4 注意優化網絡需求
5 盡量去用構建緩存
舉例(以nginx為例):
1、未優化
[root@docker docker]# ls
Dockerfile nginx-1.15.8.tar.gz westos.repo
[root@docker docker]# cat Dockerfile
FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
ADD nginx-1.15.9.tar.gz /mnt
COPY westos.repo /etc/yum.repos.d/westos.repo
RUN rpmdb --rebuilddb
RUN yum install -y gcc pcre-devel zlib-devel make
WORKDIR /mnt/nginx-1.15.9
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
創建鏡像并查看鏡像大小
docker build -t nginx:v1 .docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 c4712dcc2963 About a minute ago 295MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
2、 清理中間緩存并盡量減少鏡像層數
vim Dockerfile FROM rhel7
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
ADD nginx-1.15.9.tar.gz /mnt
COPY westos.repo /etc/yum.repos.d/westos.repo
WORKDIR /mnt/nginx-1.15.9
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && yum clean all && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
創建鏡像并查看鏡像大小
docker build -t nginx:v2 .docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 2b20e470e31c 25 seconds ago 252MB
nginx v1 c4712dcc2963 11 minutes ago 295MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
3、使用多階段構建方法
我們需要的只不過是編譯之后的軟件包,那么我們就可以在一容器編譯安裝以后,將編譯安裝之后的安裝包拷貝到另一個容器中,這樣就減小了不需要的開銷。并且將壓縮包刪除。
vim Dockerfile FROM rhel7 as build # 這一階段只需需要完成nginx的編譯
ADD nginx-1.15.9.tar.gz /mnt
COPY westos.repo /etc/yum.repos.d/westos.repo
WORKDIR /mnt/nginx-1.15.9
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && yum clean all && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.15.8FROM rhel7 # 創建鏡像,將編譯好的文件直接拿過來用
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
創建鏡像并查看鏡像大小
docker build -t nginx:v3 .docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 e5b903942033 19 seconds ago 141MB
nginx v2 2b20e470e31c 11 minutes ago 252MB
nginx v1 c4712dcc2963 22 minutes ago 295MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
4、減少底層base的大小
使用一個最基礎的系統環境鏡像。然后從nginx進行中將運行nginx所需要的依賴庫都導入到基礎的系統鏡像中,就可以滿足運行nginx的要求。做到最小化。
docker load -i distroless.tar ##一個基礎的系統環境鏡像
docker load -i nginx.tar ##nginx的進行,vim Dockerfile
FROM nginx:1.16 as base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
ARG Asia/Shanghai
RUN mkdir -p /opt/var/cache/nginx && \
cp -a --parents /usr/lib/nginx /opt && \
cp -a --parents /usr/share/nginx /opt && \
cp -a --parents /var/log/nginx /opt && \
cp -aL --parents /var/run /opt && \
cp -a --parents /etc/nginx /opt && \
cp -a --parents /etc/passwd /opt && \
cp -a --parents /etc/group /opt && \
cp -a --parents /usr/sbin/nginx /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libc.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libdl.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libpthread.so.* /opt && \
cp -a --parents /lib/x86_64-linux-gnu/libcrypt.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtimeFROM gcr.io/distroless/base
COPY --from=base /opt /
EXPOSE 80
VOLUME ["/usr/share/nginx/html"]
ENTRYPOINT ["nginx", "-g", "daemon off;"]
創建鏡像并查看鏡像大小
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v4 cb475e8f4412 7 seconds ago 23.7MB
nginx v3 e5b903942033 19 minutes ago 141MB
nginx 1.16 ac44715da54a 4 weeks ago 109MB
rhel7 latest 0a3eb3fde7fd 5 years ago 140MB
gcr.io/distroless/base latest 9a255d5fe262 49 years ago 16.8MB