一.准备基础镜像
下载centos基础镜像
[root@k8s-master base-image]# docker pull centos:centos7.9.2009
centos7.9.2009: Pulling from library/centos
Digest: sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
Status: Downloaded newer image for centos:centos7.9.2009
docker.io/library/centos:centos7.9.2009
利用公共基础镜像制作私有镜像
[root@k8s-master base-image]# cat Dockerfile
FROM centos:centos7.9.2009
LABEL maintainer="OPS_MX"
RUN yum -y install wget && rm -f /etc/yum.repos.d/* && wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/Centos-7.repo \
&& wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo \
&& yum -y install vim-enhanced tcpdump lrzsz tree telnet bash-completion net-tools wget bzip2 lsof zip unzip nfs-utils gcc make gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel zlib-devel \
&& yum clean all \
&& rm -f /etc/localtime \
&& ln -s ../usr/share/zoneinfo/Asia/Shanghai /etc/localtime
构建脚本
[root@k8s-master base-image]# cat build.sh
#!/bin/bash
#
docker build -t centos7-base:v1 .
当使用Dockerfile构建镜像时,所在的目录一定要使用一个干净的目录(最好新建一个),以免目录下有其他文件(构建会加载当前目录下所有文件,导致磁盘爆满)
docker build 参数 镜像名 .
-t
:tag 打标签-f
:指定dockerfile目录.
:指构建镜像时使用的环境(当前目录),构建镜像时使用的上下文环境
构建镜像
[root@k8s-master base-image]# ./build.sh
Sending build context to Docker daemon 3.584kB
Step 1/3 : FROM centos:centos7.9.2009
---> eeb6ee3f44bd
Step 2/3 : LABEL maintainer="OPS_MX"
---> Running in 8a2aebc3840f
Removing intermediate container 8a2aebc3840f
---> 0b93f05d2ef1
Step 3/3 : RUN yum -y install wget && rm -f /etc/yum.repos.d/* && wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/Centos-7.repo && wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo && yum -y install vim-enhanced tcpdump lrzsz tree telnet bash-completion net-tools wget bzip2 lsof zip unzip nfs-utils gcc make gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel zlib-devel && yum clean all && rm -f /etc/localtime && ln -s ../usr/share/zoneinfo/Asia/Shanghai /etc/localtime
---> Running in 43a5b6d83ab4
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
* base: mirrors.tuna.tsinghua.edu.cn
* extras: mirrors.tuna.tsinghua.edu.cn
* updates: mirrors.tuna.tsinghua.edu.cn
Resolving Dependencies
--> Running transaction check
---> Package wget.x86_64 0:1.14-18.el7_6.1 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
wget x86_64 1.14-18.el7_6.1 base 547 k
Transaction Summary
================================================================================
Install 1 Package
Total download size: 547 k
。。。。。。 ##此处省略一万字
Successfully built c31fb99ef249
Successfully tagged centos7-base:v1 ##看到这,就是代表已经构建完成了,可以用docker查看镜像信息了
查看镜像
[root@k8s-master base-image]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7-base v1 c31fb99ef249 2 hours ago 432MB
centos centos7.9.2009 eeb6ee3f44bd 15 months ago 204MB
[root@k8s-master base-image]# docker history c31fb99ef249
IMAGE CREATED CREATED BY SIZE COMMENT
c31fb99ef249 2 hours ago /bin/sh -c yum -y install wget && rm -f /etc… 228MB
0b93f05d2ef1 2 hours ago /bin/sh -c #(nop) LABEL maintainer=OPS_MX 0B
eeb6ee3f44bd 15 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 15 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 15 months ago /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB
这里能发现centos镜像204MB,我制作的私有镜像432MB,这是因为docker镜像机制原因:分层构建,联合挂载。(可以好几个层共用一个底层的centos镜像)
镜像构建机制概述
docker构建镜像是 分层构建、联合挂载:
比如centos是一个镜像,nginx是一个镜像,那么把这两者叠加在一起则可以实现nginx运行在centos上,这就叫联合挂载。
当需要运行nginx时,把centos镜像和nginx镜像联合挂载。每一层镜像都是只读的,所以底层镜像是不允许修改的。
如果想在容器A中修改文件怎么办呢?那么可以附加一个新层即E层,E层是专门属容器A的层,是能读能写的,所以容器A就可以在E层进行读写。
但是如果容器A想要删除一个属于底层镜像的文件,怎么办?由于底层镜像是只读,所以是无法删除的,那么即可在底层镜像中标记为不可见即可。如果要修改底层镜像的文件,即把底层镜像中的文件复制到E层,然后在E层中进行修改即可。
另外一个问题,因为E层有数据,那么如何把容器A迁移到其他宿主机?因此在使用容器时,是不会在容器本地保存有效数据的,所以在需要存储数据时,就会在文件系统上挂载一个外部的存储,以后即使把容器删除,也可以再启动同样的镜像,创建同样的容器,然后挂载此数据库即可。
二.制作nginx镜像
准备Dockerfile
[root@k8s-master nginx-image]# ls
Dockerfile nginx-1.16.1.tar.gz ##准备二进制未编译的nginx tar包
[root@k8s-master nginx-image]# vim Dockerfile
FROM centos7-base:v1 ##挂在基础镜像
MAINTAINER OPS_MX ## 镜像作者
ENV NGINX_VERSION 1.16.1 ##定义环境变量
ENV BUILD_TOOLS gcc pcre-devel openssl-devel make
ADD nginx-${NGINX_VERSION}.tar.gz /opt ##将当前目录下的nginx tar包拷入镜像的/opt目录
RUN mkdir -p /opt/web_app/nginx-${NGINX_VERSION} \
&& useradd nginx && yum -y install ${BUILD_TOOLS} && cd /opt/nginx-${NGINX_VERSION} \
&& ./configure --user=nginx --group=nginx --with-http_ssl_module \
--prefix=/opt/web_app/nginx-${NGINX_VERSION} \
--sbin-path=/opt/web_app/nginx-${NGINX_VERSION}/sbin/nginx \
--conf-path=/opt/web_app/nginx-${NGINX_VERSION}/conf/nginx.conf \
--http-log-path=/opt/web_app/nginx-${NGINX_VERSION}/logs/access.log \
--error-log-path=/opt/web_app/nginx-${NGINX_VERSION}/logs/error.log \
--pid-path=/opt/web_app/nginx-${NGINX_VERSION}/logs/nginx.pid \
--lock-path=/opt/web_app/nginx-${NGINX_VERSION}/lock/subsys/nginx \
--with-http_stub_status_module && make && make install \
&& rm -rf /opt/nginx-${NGINX_VERSION} \
&& yum clean all ##编译安装
VOLUME /opt/web_app/nginx-${NGINX_VERSION} ##匿名卷,如果容器启动不加-v 默认会将此目录映射到宿主机上
WORKDIR /opt/web_app/nginx-${NGINX_VERSION} ##工作目录,进入nginx镜像,默认到此目录下
EXPOSE 80 443 ## 暴露80和443端口
RUN echo "daemon off;" >> /opt/web_app/nginx-${NGINX_VERSION}/nginx.conf
CMD ["/opt/web_app/nginx-1.16.1/sbin/nginx","-g","daemon off;"] ##这一步最关键,cmd是镜像启动时要执行的命令,这里用nginx -g daemon off 后台运行
[root@k8s-master nginx-image]# docker build -t nginx-1.16.1:v1 . ##构建镜像
查看nginx镜像
[root@k8s-master nginx-image]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx-1.16.1 v1 507f86395522 29 minutes ago 471MB
centos7-base v1 c31fb99ef249 24 hours ago 432MB
centos centos7.9.2009 eeb6ee3f44bd 15 months ago 204MB
这里能看到,centos是公共基础镜像,只有204MB,centos7-base是基于公共基础镜像制作的私有基础镜像,安装了一些基础命令,有432MB,nginx-1.16.1是基于私有基础镜像制作的nginx镜像,有471MB,分层构建,联合挂载会在依赖的私有基础镜像层基础上增加nginx占用空间,在构建镜像时,尽量每个中间件或者服务都单独在私有镜像基础上构建,不要依赖太多层,不然会变得越来越大
后台启动容器测试
[root@k8s-master nginx-image]# docker run --name nginx-test -d -i nginx-1.16.1:v1
357ef9e7d707fdc787722e91852cf736a56507d49b7d73cc14bf2bad4be04b0f
[root@k8s-master nginx-image]#
[root@k8s-master nginx-image]#
[root@k8s-master nginx-image]# docker ps -a | grep nginx
357ef9e7d707 nginx-1.16.1:v1 "/opt/web_app/nginx-…" 11 seconds ago Up 10 seconds 80/tcp, 443/tcp nginx-test
[root@k8s-master nginx-image]# docker exec -it 357ef9e7d707 /bin/bash ##进入启动的容器
[root@357ef9e7d707 nginx-1.16.1]# ps -ef | grep nginx ##查看nginx进程
root 1 0 0 15:07 ? 00:00:00 nginx: master process /opt/web_app/nginx-1.16.1/sbin/nginx -g daemon off;
nginx 8 1 0 15:07 ? 00:00:00 nginx: worker process
root 30 9 0 15:09 pts/0 00:00:00 grep --color=auto nginx
[root@357ef9e7d707 nginx-1.16.1]# pwd ##默认进入工作目录
/opt/web_app/nginx-1.16.1
访问测试
[root@357ef9e7d707 nginx-1.16.1]# curl 127.0.0.1 ##curl命令模拟访问
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@357ef9e7d707 nginx-1.16.1]# curl 127.0.0.1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@357ef9e7d707 nginx-1.16.1]# cd logs/
[root@357ef9e7d707 logs]# ls
access.log error.log nginx.pid
[root@357ef9e7d707 logs]# tail access.log ##查看模拟访问的日志
127.0.0.1 - - [23/Dec/2022:15:10:50 +0800] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0"
127.0.0.1 - - [23/Dec/2022:15:10:51 +0800] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0"