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