Docker镜像的制作

由于内核过大,Docker的镜像中不包含内核,直接使用宿主机的内核,在此之上层层打包镜像, 就像盖房子一般,镜像的制作通常有两种方式,一种是手动制作镜像,另一种是通过dockerfile文件,编写镜像的制作步骤,与ansible的playbook十分相似,配合docker build制作镜像。
制作镜像的步骤通常有三步:
1)初始化镜像,也就是拉取基础镜像,通常是某个操作系统的镜像
2)根据业务需求配置环境,如下载常用的命令等
3)配置好镜像后使用相关命令构建

手动制作镜像

制作yum源安装的nginx镜像

1. 拉取基础镜像--centos7.7
docker pull centos:7.7.1908
2. 进到镜像中安装nginx
2.1 获取阿里yum源
rm -rf /etc/yum.repos.d/*
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum repolist
2.2 安装系统常用命令
yum install -y vim wget pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
2.3 安装nginx并配置配置参数与主页
yum -y install nginx
[root@9396b5bc79c9 /]# cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
daemon off;   #将程序放在前台执行
rm -f /usr/share/nginx/html/index.html  #拉去centos镜像时index.html为一个不存在连接文件的软连接,需要手动创建
[root@9396b5bc79c9 /]# cat /usr/share/nginx/html/index.html 
docker image yum nginx

为什么单独拉去nginx时要执行nginx -g daemon off 这是因为Docker必须有一个持久运行的PID,也就是PID为1的进程,如果该进程不存在,表示容器无效,docker就会将容器关闭,如果不使nginx持久运行,则nginx容器就会以bash运行一次nginx程序,之后进程马上结束,此时进程中就没有PID为1的进程,该容器就会被关闭。

3. 提交镜像

命令及用法:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

OPTIONS说明:
-a :提交的镜像作者;
-c :使用Dockerfile指令来创建镜像;
-m :提交时的说明文字;
-p :在commit时,将容器暂停。

提交镜像,并设置tag为v1-1161

root@ubuntu1804-server:~# docker commit -a "thomas chen <thomas.chen@qq.com>" -m "this is a nginx image" 9396b5bc79c9 nginx:v1-1161
sha256:510dbb44b2c8cdd321b93125525592f054f2d3de0900d3cbc48c765bcb892a80
root@ubuntu1804-server:~# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               v1-1161             510dbb44b2c8        7 seconds ago       453MB

拉取手动制作的镜像并运行,容器内没有启动nginx,需要手动执行

root@ubuntu1804-server:~# docker run -it -d -p 80:80 nginx:v1-1161 nginx
dd7d27b964e9818a052bc753bb432c46355afb6ed0125412aaac754e7d775877
root@ubuntu1804-server:~# ss -tnl
State               Recv-Q               Send-Q                              Local Address:Port                               Peer Address:Port               
LISTEN              0                    128                                 127.0.0.53%lo:53                                      0.0.0.0:*                  
LISTEN              0                    128                                       0.0.0.0:22                                      0.0.0.0:*                  
LISTEN              0                    128                                     127.0.0.1:6010                                    0.0.0.0:*                  
LISTEN              0                    128                                     127.0.0.1:6011                                    0.0.0.0:*                  
LISTEN              0                    128                                             *:80                                            *:*                  
LISTEN              0                    128                                          [::]:22                                         [::]:*                  
LISTEN              0                    128                                         [::1]:6010                                       [::]:*                  
LISTEN              0                    128                                         [::1]:6011                                       [::]:*        

root@ubuntu1804-server:~# curl 127.0.0.1
docker image yum nginx

制作编译安装的nginx镜像

1. 拉取基础镜像--centos7.7
docker pull centos:7.7.1908
2. 进到镜像中安装nginx
2.1 获取阿里yum源
yum -y install wget
rm -rf /etc/yum.repos.d/*
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum repolist
2.2 安装系统常用命令以及编译安装需要的命令
yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
2.3	拉取nginx包编译安装并配置nginx参数
wget http://nginx.org/download/nginx-1.16.1.tar.gz
tar xvzf /usr/local/src/nginx-1.16.1.tar.gz
[root@cf9bc5db1968 ]# cd /usr/local/src/nginx-1.16.1
[root@cf9bc5db1968 nginx-1.16.1]# ls
CHANGES  CHANGES.ru  LICENSE  README  auto  conf  configure  contrib  html  man  src
[root@cf9bc5db1968 nginx-1.16.1]# ./configure --prefix=/apps/nginx --with-http_sub_module
[root@cf9bc5db1968 nginx-1.16.1]# make && make install 
[root@cf9bc5db1968 nginx-1.16.1]# ll /apps/nginx/
total 16
drwxr-xr-x 2 root root 4096 Feb 18 07:34 conf
drwxr-xr-x 2 root root 4096 Feb 18 07:34 html
drwxr-xr-x 2 root root 4096 Feb 18 07:34 logs
drwxr-xr-x 2 root root 4096 Feb 18 07:34 sbin

关闭后台运行

[root@cf9bc5db1968 nginx-1.16.1]# cat /apps/nginx/conf/nginx.conf

#user  nobody;
worker_processes  auto;
daemon off;

创建nginx命令软连接,否则启动容器时需要使用nginx绝对路径启动

[root@cf9bc5db1968 nginx-1.16.1]# ln -sv /apps/nginx/sbin/nginx  /usr/sbin/
'/usr/sbin/nginx' -> '/apps/nginx/sbin/nginx'

创建web页面并测试

[root@cf9bc5db1968 nginx-1.16.1]# echo "docker image gcc nginx" >  /apps/nginx/html/index.html

创建nginx用户,并将ngixn目录授权给nginx用户

[root@cf9bc5db1968 nginx-1.16.1]# useradd  -r -s /sbin/nologin nginx
[root@cf9bc5db1968 nginx-1.16.1]# chown -R nginx.nginx /apps/nginx/
3	提交镜像,并运行测试
root@ubuntu1804-server:~# docker commit -a "thomas.com@qq.com" -m "this is a gcc nginx image" cf9bc5db1968 nginx:vg-1161
sha256:804be1a5dffadf696694f62a8891cdd618184e98dfcd4228dfaf9d2bce77093f
root@ubuntu1804-server:~# docker run -it -d -p 88:80 nginx:vg-1161 nginx
ffc93e7e3fe74b295248008812a586a60996f5b8fbad20175f2a493d2b0a9283
root@ubuntu1804-server:~# ss -tnl
State                Recv-Q                Send-Q                                Local Address:Port                               Peer Address:Port               
LISTEN               0                     128                                   127.0.0.53%lo:53                                      0.0.0.0:*                  
LISTEN               0                     128                                         0.0.0.0:22                                      0.0.0.0:*                  
LISTEN               0                     128                                       127.0.0.1:6010                                    0.0.0.0:*                  
LISTEN               0                     128                                       127.0.0.1:6011                                    0.0.0.0:*                  
LISTEN               0                     128                                               *:80                                            *:*                  
LISTEN               0                     128                                               *:81                                            *:*                  
LISTEN               0                     128                                            [::]:22                                         [::]:*                  
LISTEN               0                     128                                               *:88                                            *:*                  
LISTEN               0                     128                                           [::1]:6010                                       [::]:*                  
LISTEN               0                     128                                           [::1]:6011                                       [::]:*                  
root@ubuntu1804-server:~# curl 127.0.0.1:88
docker image gcc nginx

使用dockerfile制作镜像

dockerfile 文件

想比手动制作镜像,更加直观显示镜像的制作过程,防止日久后忘了手动的操作,有了dockerfile可以唤起当时缺失的记忆,而且使用dockerfile制作镜像,可以避免重复多余的手动制作镜像的麻烦。
dockerfiel命令:

ADD 	:相当于`copy+tar`解压,zip压缩文件需要安装zip命令解压,Dockerfile中不支持
COPY	:仅copy功能
ENV		:环境变量,将参数传递给镜像中,容器启动后就可以根据变量引用,常用于java运行环境的容器中
EXPOSE	:定义宿主机端口映射给容器中,向外暴露,创建容器使用`docker run `命令时需以 `-p` 参数指定暴露的端口
FROM	:获取镜像,
LABEL	:标签,用于添加注释,需以`<key>=<value>`方式写入,否则报错
STOPSIGNAL:用于设置容器的停止信号
USER	:指定该容器运行时的用户名和 UID,后续的命令也会以此用户身份运行
VOLUME	:数据存储卷,设置挂在的主机目录
WORKDIR	:工作目录,相当于`cd`命令
RUN		:相当于bash,后面可以跟上任意想要执行的命令,用于制作镜像时编写过程
CMD		:容器启动时执行的命令
ENTRYPOINT: 功能与CMD类似,两者单独使用时功能相似,两者一起使用时,CMD的内容将成为ENTRYPOINT的参数。

使用Dockerfile制作编译安装的nginx镜像

1. 编写Dockerfile:名称严格规范,D为大写,

1.1#根据需求创建目录树,方便对各个服务制作dockerfile文件,执行docker build 命令时会寻找当前路径下的Dockerfile文件,执行dockerfile时如果需要copy文件,也会自动定位到于dockerfile相同目录
root@ubuntu1804-server:/data/dockerfile/web/nginx# tree /data/dockerfile/
/data/dockerfile/
└── web
    ├── mysql
    ├── nginx
    │   ├── Dockerfile
    │   ├── nginx-1.16.1.tar.gz
    │   └── nginx.conf
    └── tomcat

4 directories, 3 files
root@ubuntu1804-server:/data/dockerfile/web/nginx# vim Dockerfile
#  #:注释
From centos:7.7.1908
Label description="thomas chen <thomas.chen@qq.com>"

RUN yum repolist  \
        && yum -y install wget && rm -rf /etc/yum.repos.d/*  \
        && wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo  \
        && wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo  \
        && yum repolist

RUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop

ADD nginx-1.16.1.tar.gz /usr/local/src

RUN cd /usr/local/src/nginx-1.16.1  \
        && ./configure --prefix=/apps/nginx --with-http_sub_module  \
        && make && make install
ADD nginx.conf /apps/nginx/conf/nginx.conf

RUN ln -sv /apps/nginx/sbin/nginx /usr/sbin/

RUN useradd -r -s /sbin/nologin nginx  \
        && chown -R nginx.nginx /apps/nginx

RUN echo "Dockerfile nginx" > /apps/nginx/html/index.html

EXPOSE 80 443

#如果此CMD要指定,则在nginx的配置文件中就不需要指定  
CMD ["nginx","-g","daemon off;"]
3. 使用`docker build `制作为本地镜像

docker build 命令常见用法
docker build [OPTIONS] PATH | URL | -
常用选项:
-t 为镜像指定tag,name:tag
-f 默认为当前路径,可以指定dockerfile文件的路径

root@ubuntu1804-server:/data/dockerfile/web/nginx# docker build -t nginx:vd3-1161 .
Sending build context to Docker daemon  1.039MB
Step 1/12 : From centos:7.7.1908
 ---> 08d05d1d5859
Step 2/12 : Label description="thomas chen <thomas.chen@qq.com>"
 ---> Using cache
 ---> 7888990fed95
Step 3/12 : RUN yum repolist  	&& yum -y install wget && rm -rf /etc/yum.repos.d/*  	&& wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo  	&& wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo  	&& yum repolist
 ---> Using cache
 ---> 32c03dff92b0
Step 4/12 : RUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
 ---> Using cache
 ---> e1a43bc44356
Step 5/12 : ADD nginx-1.16.1.tar.gz /usr/local/src
 ---> Using cache
 ---> 7fc9585c859d
Step 6/12 : RUN cd /usr/local/src/nginx-1.16.1  	&& ./configure --prefix=/apps/nginx --with-http_sub_module  	&& make && make install
 ---> Using cache
 ---> dc8fb2b23501
Step 7/12 : ADD nginx.conf /apps/nginx/conf/nginx.conf
 ---> deb4d95d40e1
Step 8/12 : RUN ln -sv /apps/nginx/sbin/nginx /usr/sbin/
 ---> Running in 86e221f4316a
'/usr/sbin/nginx' -> '/apps/nginx/sbin/nginx'
Removing intermediate container 86e221f4316a
 ---> 0d6b3a092a01
Step 9/12 : RUN useradd -r -s /sbin/nologin nginx  	&& chown -R nginx.nginx /apps/nginx
 ---> Running in 2131f7b7befd
Removing intermediate container 2131f7b7befd
 ---> 752d48b764d0
Step 10/12 : RUN echo "Dockerfile nginx" > /apps/nginx/html/index.html
 ---> Running in 99e7099d0a0e
Removing intermediate container 99e7099d0a0e
 ---> 33d2f2b2a3b6
Step 11/12 : EXPOSE 80 443
 ---> Running in 4ac4e0b56196
Removing intermediate container 4ac4e0b56196
 ---> 918276e962c2
Step 12/12 : CMD ["nginx","-g","daemon off;"]
 ---> Running in aef299dfe705
Removing intermediate container aef299dfe705
 ---> a2e4d1941ef5
Successfully built a2e4d1941ef5
Successfully tagged nginx:vd3-1161
root@ubuntu1804-server:/data/dockerfile/web/nginx# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               vd3-1161            a2e4d1941ef5        29 minutes ago      662MB
nginx               vd2-1161            01a192c873f4        39 minutes ago      662MB
nginx               vd-1161             f66de32f8f50        About an hour ago   662MB
nginx               vg-1161             804be1a5dffa        3 hours ago         521MB
nginx               v1-1161             510dbb44b2c8        3 hours ago         453MB
nginx               1.16.1              55c440ba1ecb        2 weeks ago         127MB
centos              7.7.1908            08d05d1d5859        3 months ago        204MB