docker镜像创建与优化

1 . 创建镜像

有两种方法构建镜像:

  1. docker commit :将运行的容器保存成镜像
  2. Dockerfile:自动构建

使用docker commit 创建镜像分为三步:

  1. 运行容器
  2. 修改容器
  3. 将容器保存为镜像

举例:

[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 dockerfile

FROM 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.8


FROM 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/localtime


FROM 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值