Linux-docker镜像与制作
Docker镜像
Docker 镜像有没有内核?
- 从镜像大小上面来说,一个比较小的镜像只有十几兆(MB),而内核文件需要一百多兆,因此镜像里面是没有内核的,镜像在被启动为容器后将直接使用宿主机的内核,而镜像本身则只是提供相应的rootfs,即系统正常运行所必须的用户空间的文件系统,比如/dev,/bin,/etc等目录,所以容器当中基本是没有/boot目录的,而/boot当中保存的就是与内核相关的文件和目录。
为什么没有内核?
由于容器启动和运行过程中是直接使用了宿主机的内核,所以没有直接调用过物理硬件,所以也不会涉及到硬盘驱动,因此也用不上内核和驱动,另外有内核的那是虚拟机。
DockerFile制作镜像
- DockerFile是一种可以被Docker程序解释的脚本,DockerFile是由一条条的命令组成的,每条命令对应Linux下面的一条命令,docker程序将这些DokcerFile指令在翻译成真正的Linux命令,其有自己的书写方式和支持的命令,docker程序读取DockerFile并根据指令生成docker镜像,相比手动制作镜像的方式
- DockeFile更能直观的展示镜像是怎么产生的,有了写好的各种各样的DockerFile,当后期某个镜像有额外的需求时,只要在之前的DockerFIle添加或修改相应的操作即可重新生成新的docker镜像,避免重复手动制作镜像的麻烦
常用构建镜像的指令如下:
FROM:ROM centos:7.6.1810 #在整个dockerfile文件中,除了注释之外的第一行,要是from,用于指定父镜像 ADD: #用于添加宿主机的本地文件、目录、压缩等资源到镜像里面去,会自动解压tar.gz格式的压缩包,不会自动解压zip MAINTAINER: #镜像的作者信息 LABEL: #设置镜像的属性标签 COPY: #用于添加宿主机本地的文件、目录、压缩等资源到镜像里面去,不会解压任何压缩包 ENV: #设置容器环境变量 USER: #指定运行操作的用户 RUN: RUN yum install vim unzip -y && cd /etc/nginx #执行shell命令,但是一定要非交互的方式执行 VOLUME:#定义volume WORKDIR: #用于定义工作目录 EXPOSE 80:#声明要把容器的某些端口映射到宿主机 CMD: #镜像启动为一个容器时候的默认命令或脚本, CMD["/bin/bash"] ENTRYPOINT:#也可以用于定义容器在启动时候默认执行的命令或者脚本,如果时和CMD命令混合使用的时候,会将CMD的命令当作参数传递给ENTRYPOINT后面的脚本,可以在脚本中对参数做判断并相应的容器初始化操作
ENTRYPOINT ["top", "-b"] == ENTRYPOINT ["top", "-b", "-c"] CMD ["-c"] ["docker-entrypoint.sh"] CMD ["mysqld"] ENTRYPOINT ["docker-entrypoint.sh","mysqld"] ENTRYPOINT(脚本) + CMD(当做参数传递给ENTRYPOINT)
dockerfile制作编译版nginx镜像
现在基础镜像,centos7.8.2003版本
[12:08:12 root@ubuntu-lyj]#docker search centos7.8.2003 NAME DESCRIPTION STARS OFFICIAL AUTOMATED martonyang/centos7.8.2003 基于 CentOS 7 配置了阿里云 yum 源,安装了 ep… 1 daduber/centos7.8.2003 0 jingansi/centos7.8.2003 0 jiansunncar/centos7.8.2003_pumas 0 huanke/centos7.8.2003 0 frankxiaozhibin/centos7.8.2003.ssh docker run -p 9501:22 --name XXX --privilege… 0 septzhjie/centos7.8.2003_ssh_bt Centos7.8.2003_ssh_bt 0 pi3sme/centos7-systemd-sshd sshd service on CentOS7.8.2003 0 dockerbyman/base centos7.8.2003+bt+npm(taobao)+yarn+yum updat… 0 okafujikdl/centos7.8.2003-php CentOS&PHPイメージ 0 dejin/php-fpm PHP-FPM 系统版本 centos7.8.2003 php版本有PHP… 0 thanhlong9x/centos7.8 centos7.8.2003, sysstat, python3, vim, net-t… 0 ezphp/centos Centos7.8.2003 0 [12:08:41 root@ubuntu-lyj ~]#docker pull martonyang/centos7.8.2003
目录结构按照业务类型或系统类型等方式划分,方便后期镜像比较多的时候进行分类
[10:22:13 root@ubuntu-lyj ~]#cd /data/ [10:22:17 root@ubuntu-lyj /data]#mkdir -pv dockerfile/{web/{nginx,tomcat,jdk,apache},system/{centos,ubuntu,redhat}} mkdir: created directory 'dockerfile' mkdir: created directory 'dockerfile/web' mkdir: created directory 'dockerfile/web/nginx' mkdir: created directory 'dockerfile/web/tomcat' mkdir: created directory 'dockerfile/web/jdk' mkdir: created directory 'dockerfile/web/apache' mkdir: created directory 'dockerfile/system' mkdir: created directory 'dockerfile/system/centos' mkdir: created directory 'dockerfile/system/ubuntu' mkdir: created directory 'dockerfile/system/redhat'
[10:23:52 root@ubuntu-lyj /data]#tree /data/
/data/
└── dockerfile
├── system
│ ├── centos
│ ├── redhat
│ └── ubuntu
└── web
├── apache
├── jdk
├── nginx
└── tomcat
进入到指定的Dockerfile目录:
[10:25:36 root@ubuntu-lyj /data]#cd dockerfile/web/nginx/ [10:28:30 root@ubuntu-lyj /data/dockerfile/web/nginx]#pwd /data/dockerfile/web/nginx
编写Dckerfile
[10:28:35 root@ubuntu-lyj /data/dockerfile/web/nginx]#vim ./Dockerfile #生成的镜像的时候会在执行命令的当前目录查找Dockerfile文件,所有名称不可写作,而且D必须大写
逐步构建镜像,已经执行过的命令,下次执行时,docker检查该命令没有修改,则不会再次执行
[12:12:29 root@ubuntu-lyj /data/dockerfile/web/nginx]#vim ./Dockerfile [12:13:05 root@ubuntu-lyj /data/dockerfile/web/nginx]#cat ./Dockerfile #My Dockerfile #'#'为注释,等于shell脚本的中‘#’ #除了注释行之外的第一行,必须是From xxx(xxx是基础镜像) From martonyang/centos7.8.2003 #第一行定义基础镜像,后面的本地有效的镜像名,如果本地没有会从远程仓库下载,第一行很重要 MAINTAINER "jing 12345@qq.com" #镜像维护者的信息 RUN yum install -y vim wget tree lrzsz gcc gcc-c++ atutomake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop #安装编译环境依赖程序 [12:13:11 root@ubuntu-lyj /data/dockerfile/web/nginx]#docker build -t nginx-web1:v1 .
下载nginx安装包,dockerfile编译安装
[12:36:11 root@ubuntu-lyj /data/dockerfile/web/nginx]#wget https://nginx.org/download/nginx-1.16.1.tar.gz --2022-08-07 12:36:21-- https://nginx.org/download/nginx-1.16.1.tar.gz Resolving nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05:d014:edb:5702::6, ... Connecting to nginx.org (nginx.org)|3.125.197.172|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 1032630 (1008K) [application/octet-stream] Saving to: ‘nginx-1.16.1.tar.gz’ nginx-1.16.1.tar.gz 100%[===========================================>] 1008K 356KB/s in 2.8s 2022-08-07 12:36:25 (356 KB/s) - ‘nginx-1.16.1.tar.gz’ saved [1032630/1032630] [12:36:25 root@ubuntu-lyj /data/dockerfile/web/nginx]#vim ./Dockerfile #My Dockerfile #'#'为注释,等于shell脚本的中‘#’ #除了注释行之外的第一行,必须是From xxx(xxx是基础镜像) From martonyang/centos7.8.2003 #第一行定义基础镜像,后面的本地有效的镜像名,如果本地没有会从远程仓库下载,第一行很重要 MAINTAINER "jing 12345@qq.com" #镜像维护者的信息 RUN yum install -y vim wget tree lrzsz gcc gcc-c++ atutomake 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=/usr/local/nginx --with-http_sub_module && make && make install
#编译安装
再次构建镜像
[12:42:19 root@ubuntu-lyj /data/dockerfile/web/nginx]#docker build -t nginx-web1:v1 . Sending build context to Docker daemon 1.036MB Step 1/5 : From martonyang/centos7.8.2003 ---> 0c0f2dcf7afd Step 2/5 : MAINTAINER "jing 12345@qq.com" ---> Using cache ---> 5ec4dc5e1f9a Step 3/5 : RUN yum install -y vim wget tree lrzsz gcc gcc-c++ atutomake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop ---> Using cache ---> 3c59fa5fc782 Step 4/5 : ADD nginx-1.16.1.tar.gz /usr/local/src/ ---> 6349af9a08b1 Step 5/5 : RUN cd /usr/local/src/nginx-1.16.1 && ./configure --prefix=/usr/local/nginx --with-http_sub_module && make && make install ---> Running in 3a452353134d ....................
进入容器测试访问
[12:54:41 root@ubuntu-lyj /data/dockerfile/web/nginx]#docker run -it --rm -p 8080:80 nginx-web1:v1 bash [root@408e293207b7 /]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port [root@408e293207b7 /]# /usr/local/nginx/sbin/nginx [root@408e293207b7 /]# ss -tnl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:80 *:* [root@408e293207b7 /]#
访问测试

nginx访问正常,编辑nginx修改配置文件
- 1、拷贝镜像中的nginx.conf,修改
- 2、dockerfile编辑命令替换调配置文件
1、拷贝出配置文件 [13:15:04 root@ubuntu-lyj /]#docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 408e293207b7 nginx-web1:v1 "bash" 20 minutes ago Up 20 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp pedantic_kowalevski [13:15:17 root@ubuntu-lyj /]#docker cp 408e293207b7:/usr/local/nginx/conf/nginx.conf /data/dockerfile/web/nginx
[13:15:40 root@ubuntu-lyj /data/dockerfile/web/nginx]#ls Dockerfile nginx-1.16.1.tar.gz nginx.conf
修改配置文件优化nginx
- 修改了登录用户和html文件访问路径
user nginx; location / { root /data/nginx/html; index index.html index.htm; }
修改完成后,编辑dockerfile
[13:21:59 root@ubuntu-lyj /data/dockerfile/web/nginx]#vim ./Dockerfile #My Dockerfile #'#'为注释,等于shell脚本的中‘#’ #除了注释行之外的第一行,必须是From xxx(xxx是基础镜像) From martonyang/centos7.8.2003 #第一行定义基础镜像,后面的本地有效的镜像名,如果本地没有会从远程仓库下载,第一行很重要 MAINTAINER "jing 12345@qq.com" #镜像维护者的信息 RUN yum install -y vim wget tree lrzsz gcc gcc-c++ atutomake 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=/usr/local/nginx --with-http_sub_module && make && make install RUN useradd nginx -s /bin/nologin #创建登录用户
ADD nginx.conf /usr/local/nginx/conf/nginx.conf #拷贝修改优化好的配置文件,到镜像目录下 ADD code.tar.gz /data/nginx/html #拷贝html文件夹,到镜像/data/nginx/html
cade.tar.gz中时开发提供的html文件
nginx.conf 文件和code.tar.gz文件都在 /data/dockerfile/web/nginx中,和Dockerfile在同一个目录
环境演示自己创建html文件打包
[13:24:04 root@ubuntu-lyj /]#cd /data/dockerfile/web/nginx [13:24:15 root@ubuntu-lyj /data/dockerfile/web/nginx]#ls Dockerfile nginx-1.16.1.tar.gz nginx.conf [13:24:16 root@ubuntu-lyj /data/dockerfile/web/nginx]#mkdir code [13:24:50 root@ubuntu-lyj /data/dockerfile/web/nginx]#vim code/index.html [13:28:38 root@ubuntu-lyj /data/dockerfile/web/nginx]#cat code/index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JING</title> <body> <h1>测试页面</h1> </body> </html>
[13:59:13 root@ubuntu-lyj /data/dockerfile/web/nginx]#cd code/
[13:59:16 root@ubuntu-lyj /data/dockerfile/web/nginx/code]#tar czvf code.tar.gz ./
./
./index.html
tar: .: file changed as we read it
[13:59:24 root@ubuntu-lyj /data/dockerfile/web/nginx/code]#ls
code.tar.gz index.html
[13:59:27 root@ubuntu-lyj /data/dockerfile/web/nginx/code]#mv code.tar.gz /data/dockerfile/web/nginx/
[13:59:47 root@ubuntu-lyj /data/dockerfile/web/nginx/code]#cd ..
[13:59:49 root@ubuntu-lyj /data/dockerfile/web/nginx]#ls
code code.tar.gz Dockerfile nginx-1.16.1.tar.gz nginx.conf
再次构建镜像
[13:38:59 root@ubuntu-lyj /data/dockerfile/web/nginx]#docker build -t nginx-web1:v1 .
进入镜像访问测试
[14:02:37 root@ubuntu-lyj /data/dockerfile/web/nginx]#docker run -it --rm -p 8080:80 nginx-web1:v1 bash [root@0c28fe81f3b1 /]# /usr/local/nginx/sbin/nginx
访问测试

docker启动后,nginx自动运行
编辑Dockerfile
#My Dockerfile #'#'为注释,等于shell脚本的中‘#’ #除了注释行之外的第一行,必须是From xxx(xxx是基础镜像) From martonyang/centos7.8.2003 #第一行定义基础镜像,后面的本地有效的镜像名,如果本地没有会从远程仓库下载,第一行很重要 MAINTAINER "jing 12345@qq.com" #镜像维护者的信息 RUN yum install -y vim wget tree lrzsz gcc gcc-c++ atutomake 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=/usr/local/nginx --with-http_sub_module && make && make install RUN useradd nginx -s /bin/nologin ADD nginx.conf /usr/local/nginx/conf/nginx.conf ADD code.tar.gz /data/nginx/html ADD run_nginx.sh /usr/local/nginx/sbin/run_nginx.sh #拷贝脚本到镜像 RUN chmod a+x /usr/local/nginx/sbin/run_nginx.sh #添加执行权限 EXPOSE 80 443 CMD ["/usr/local/nginx/sbin/run_nginx.sh"] #执行脚本
脚本内容
#!/bin/bash /usr/local/nginx/sbin/nginx -g 'daemon off;'
#在容器中,如果pid=1的进程退出了,那么容器就会退出。所以要保证容器持久运行,就要保证pid=1的进程能够持久运行接下来。nginx -g 'daemon off;'命令是一个持久任务,不会运行一下该程序就结束了;如果在shell下执行该命令,该命令不会退出,会一直占据终端。
把nginx的启动命令放到一个shell脚本里,容器的CMD设置为该脚本
在容器环境,one container == one process,容器要能持续运行,必须有且仅有一个前台进程,所以对nginx进程容器化,需要将nginx转为前后进程( daemon off)。
构建镜像
[15:34:30 root@ubuntu-lyj /data/dockerfile/web/nginx]#docker build -t nginx-web1:v1 .
启动镜像
前台运行 [15:51:30 root@ubuntu-lyj /data/dockerfile/web/nginx]#docker run -it --rm -p 8085
:80 nginx-web1:v1
页面访问测试
dockerfile构建nginx镜像的文件内容
#My Dockerfile #'#'为注释,等于shell脚本的中‘#’ #除了注释行之外的第一行,必须是From xxx(xxx是基础镜像) From martonyang/centos7.8.2003 #第一行定义基础镜像,后面的本地有效的镜像名,如果本地没有会从远程仓库下载,第一行很重要 MAINTAINER "jing 12345@qq.com" #镜像维护者的信息 RUN yum install -y vim wget tree lrzsz gcc gcc-c++ atutomake 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=/usr/local/nginx --with-http_sub_module && make && make install RUN useradd nginx -s /bin/nologin ADD nginx.conf /usr/local/nginx/conf/nginx.conf ADD code.tar.gz /data/nginx/html ADD run_nginx.sh /usr/local/nginx/sbin/run_nginx.sh RUN chmod a+x /usr/local/nginx/sbin/run_nginx.sh EXPOSE 80 443 CMD ["/usr/local/nginx/sbin/run_nginx.sh"]
注意:
编写dockerfile文件时,编写一条或两条可执行的命令时,保存退出构建镜像,进入容器查看是否存在,防止出现错误不好排查。已执行过的命令未被修改,下次再构建镜像时,不会重复执行。
docker build -t nginx-web1:v1 . #构建镜像命令 docker build -t 自定义镜像名称:TAG(一般为版本号) .(本地目录文件构建镜像/data/dockerfile/web/nginx)
docker前台运行参考文献
https://pshizhsysu.gitbook.io/docker/dockerfile/qian-tai-yun-xing
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)