当前位置: 首页 > article >正文

Docker基础以及单体实战

Docker

  • 一、Docker
      • 1.1 Docker组成
      • 1.2 Dcoker运行图
      • 1.3 名称空间Namepace
    • 1.4 docker、Docker compose、kubermetes
  • 二、Docker安装
    • 2.1 在线Docker安装
    • 2.2 使用官方通用安装脚本
    • 2.3 二进制安装Docker
    • 三、Docker基础命令
    • 3.1 启动类
    • 3.2 镜像类
    • 3.3 容器类
    • 3.4 网络类
    • 3.5 Docker compose
  • 四、Docker优化配置
  • 五、Docker镜像和下载
    • 5.1 镜像结构和原理
    • 5.2 搜索镜像和下载
    • 5.3 Docker导入与导出
  • 六、Docker管理容器
    • 6.1 容器的生命周期
  • 七、Podman容器引擎
    • 7.1 Podman介绍
    • 7.2 Podman 与 Docker 的区别
  • 八、Docker镜像制作实战
    • 8.1 制作镜像Dockerfile流程
    • 8.2 基于容器手动制作镜像步骤
    • 8.3 Docker实战-制作nginx镜像
    • 8.4 Dockerfile制作镜像
      • 8.4.1 Dockfile 介绍
      • 8.4.2 Dockerfile 镜像制作和使用流程
      • 8.4.3 Dockerfile文件的制作镜像的分层结构
      • 8.4.4 Dockerfile制作镜像
      • 8.4.5 Dockerfile指令详细介绍
    • 8.5 使用Dockerfile制作系统镜像
    • 8.6 直接制作nginx 镜像
    • 8.7 制作自定义tomcat业务镜像
    • 8.8 从JDK镜像构建tomcat 8 Base镜像
      • 8.8.1 构建业务镜像1
    • 8.9 构建haproxy镜像
  • 九、Docker 数据管理

一、Docker

1.1 Docker组成

Docker主机(Host):一个物理机或虚拟机,用于运行Docker服务进程和容器,也称为宿主机,node节点

Docker服务端(Server):Docker守护进程,运行docker容器

Docker客户端(Client):客户端使用docker命令或其他工具调用dockerAPI

Docker镜像(Images):镜像可以理解为创建实例使用的模板,本质上就是一些程序文件的集合

Docker仓库(Registry):保存镜像的仓库,可以搭建私有仓库harbor

Docker容器(Container):容器是从镜像生成对外提供服务的一个或一组服务,其本质就是将镜像中的程序启动后生成的进程

1.2 Dcoker运行图

1.3 名称空间Namepace

MNT Namespace(mount):提供磁盘挂载点和文件系统的隔离能力

IPC Namespace(Inter-Process Communication):提供进程间通信的隔离能力,包括信号量,消息队列和共享内存

UTS Namespace(UNIx Timesharing System):提供内核,主机名和域名隔离能力

PID Namespace(Process Identification):提供进程隔离能力

Net Namespace(network):提供网络隔离能力,包括网络设备,网络栈,端口等

User Namespace(user):提供用户隔离能力,包括用户和组

1.4 docker、Docker compose、kubermetes

Docker 像是一个“打包神器”,可以把你的应用程序和它需要的所有东西(比如代码、配置文件、运行环境等)都装进一个“小盒子”(容器)里。这样无论在哪里运行这个“盒子”,里面的东西都能正常工作。

Docker Compose 就像是一个“拼装工具”,当你有多个“小盒子”(容器)需要一起工作时,它能帮你把它们组合起来,方便你一起管理。比如你有个网站,一个容器是前端,一个容器是后端,用 Docker Compose 就能轻松把它们“拼”在一起。

Kubernetes 则像是一个“超级管理员”,它能管理一大堆“小盒子”(容器),帮你自动安排它们在服务器上怎么运行,比如自动扩容(忙的时候多开几个盒子)、自动修复(坏了就重启)等,特别适合大规模的项目。

镜像是“模板”,Docker 是“工具”,两者配合才能完成容器的创建和管理

镜像就像是软件安装包可以看作是软件的“镜像”。你可以将这个安装包复制到不同的电脑上,然后安装相同的软件

  • 应用程序:货物
  • Docker 容器:集装箱
  • Docker 镜像:集装箱的模板
  • Docker 守护进程:运输工具(货轮、火车、卡车)
  • Docker 宿主机:港口

二、Docker安装

2.1 在线Docker安装

进入清华大学镜像网站 https://mirrors.tuna.tsinghua.edu.cn/help/docker-ce/

# 检查系统内核是否大于3.10
[root@localhost ~]# uname -a
Linux localhost.localdomain 4.18.0-80.el8.x86_64 #1 SMP Wed Mar 13 12:02:46 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
# 更新系统软件包
yum update

# 如果之前有安装过docker,请使用下面命令
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

# 安装依赖,下载 repo 文件,并把软件仓库地址替换为镜像站
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 替换为清华的镜像
sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# 或者直接使用阿里云下载docker-ce镜像
wget -P /etc/yum.repos.d/ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 清理缓存
yum clean all

# 查找Docker-CE的版本
yum list docker-ce.x86_64 --showduplicates | sort -r

# 安装指定版本的Docker-CE
yum -y install docker-ce-[VERSION]

# 或者安装docker
yum install docker-ce -y

# 开启以及自启查看docker相关服务
systemctl start docker
systemctl enable docker
rpm -qa | grep docker

# 查看版本
docker version

# 查看docker信息
docker info
Client:
 Debug Mode: false     #client 端是否开启 debug

Server:
 Containers: 2   #当前 主机运行的容器总数
  Running: 0     #有几个容器是正在运行的
  Paused: 0      #有几个容器是暂停的
  Stopped: 2     #有几个容器是停止的
 Images: 4       #当前服务器的镜像数
 Server Version: 19.03.5   #服务端版本
 Storage Driver: overlay2  #正在使用的存储引擎
  Backing Filesystem: extfs   #后端文件系统,即服务器的磁盘文件系统
  Supports d_type: true  #是否支持 d_type
  Native Overlay Diff: true  #是否支持差异数据存储
 Logging Driver: json-file   #日志类型 
 Cgroup Driver: cgroupfs  #Cgr oups 类型
 Plugins:                  #插件
  Volume: local            #卷 
  Network: bridge host ipvlan macvlan null overlay # overlay 跨主机通信
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog  # 日志类型
 Swarm: inactive    #是否支持 swarm
 Runtimes: runc     #已安装的容器运行时
 Default Runtime: runc   #默认使用的容器运行时
 Init Binary: docker-init   #初始化容器的守护进程,即 pid 为 1的进程
 containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339 #版本
 runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657  #runc 版本
 init version: fec3683  #init 版本
 Security Options:   #安全选项
  apparmor     #安全模块,https://docs.docker.com/engine/security/apparmor/
  seccomp  #安全计算模块,即制容器操作,https://docs.docker.com/engine/security/seccomp/
   Profile: default  #默认的配置文件
 Kernel Version: 4.15.0-29-generic  #宿主机内核版本
 Operating System: Ubuntu 18.04.1 LTS  #宿主机操作系统
 OSType: linux    #宿主机操作系统类型
 Architecture: x86_64   #宿主机架构
 CPUs: 1    #宿主机 CPU 数量
 Total Memory: 962MiB   #宿主机总内存 
 Name: ubuntu1804.magedu.org #宿主机 hostname
 ID: IZHJ:WPIN:BRMC:XQUI:VVVR:UVGK:NZBM:YQXT:JDWB:33RS:45V7:SQWJ #宿主机 ID
 Docker Root Dir: /var/lib/docker  #宿主机关于docker数据的保存目录
 Debug Mode: false   #server 端是否开启 debug
 Registry: https://index.docker.io/v1/  #仓库路径
 Labels:
 Experimental: false  #是否测试版
 Insecure Registries:
  127.0.0.0/8  : #非安全的镜像仓库
 Registry Mirrors:
  https://si7y70hh.mirror.aliyuncs.com/   #镜像仓库
 Live Restore Enabled: false  #是否开启 活动重启 (重启dockerdocker-daemon 不关闭 容器 )

WARNING: No swap limit support  #系统警告 信息 (没有开启 swapswap资源限制 )

2.2 使用官方通用安装脚本

# 当前不支持RockyLinux
curl -fsSL get.docker.com -o get-docHer.sh
sh get-docker.sh --mirror Aliyun

2.3 二进制安装Docker

三、Docker基础命令

3.1 启动类

# 1. 启动 docker
systemctl start docker

# 2. 关闭 docker
systemctl stop docker

# 3. 重新启动 docker
systemctl restart docker

# 4. docker 设置自启动
systemctl enable docker

# 5. 查看 docker 运行状态
systemctl status docker

# 6. 查看 docker 版本号等信息,还可以查看到有多少 容器及其状态 和 镜像 的信息
docker version  /  docker info

# 7. docker 帮助
docker --help // 查看总体文档
docker run --help // 查看docker run 的帮助文档

3.2 镜像类

# 1. 查看镜像
docker images

# 查看指定的镜像信息
docker image inspect 镜像名称

# 2. 搜索镜像,docker search默认是从官方搜索
docker search [OPTIONS] 镜像名字
docker search mysql

# 3. 拉取镜像
docker pull
docker pull mysql #没有制定版本则默认最新版 
docker 官方镜像地址

# 4. 运行镜像
docker run
docker run tomcat # 运行镜像后可以按 ctrl+c 退出

# 使用 alpine 镜像创建并启动一个名为 alpine1 的容器
docker run --name alpine1 alpine

# 5. 删除镜像
docker rmi  镜像名/镜像ID #若镜像在运行则会报错
docker rmi -f 镜像名/镜像ID #强制删除一个
docker rmi -f mysql

docker rmi -f 镜像名/镜像ID 镜像名/镜像ID 镜像名/镜像ID #删除多个 其镜像ID或镜像用用空格隔开即可 
docker rmi -f mysql redis

docker rmi -f $(docker images -aq)   #删除全部镜像  -a 意思为显示全部, -q 意思为只显示ID

# 6. 加载镜像
docker load -i 镜像保存文件位置
docker load myimage.tar

# 7. 保存镜像
docker save 镜像名/镜像ID -o 镜像保存位置和名字
docker save tomcat -o /myimage.tar

# 镜像导出
docker save IMAGE > /path/file.tar.gz
# 一次导出多个镜像
docker save busybox alpine > /all.tar.gz

# 镜像导入
docker load < /data/mysql5.7.29.tar.gz 

# 8. 格式化查看镜像
docker image ls --format "{{.Repository}}:{{.Tag}}"

# 镜像打标签
docker tag  alpine alpine:3.11

3.3 容器类

# 1. 查看正在运行的容器
docker ps
docker ps -a # 查看所有容器
#加格式化方式访问,格式会更加清爽
docker ps --format "table {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Names}}"

# 2. 创建容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
常用参数:
--name=NAME   #为容器指定名字为NAME,不使用的话系统自动为容器命名
-d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);
 
-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
也即启动交互式容器(前台有伪终端,等待交互,一般连用,即-it);
 
-P: 随机端口映射,大写P
-p: 指定端口映射,小写p

# 创建并允许 Nginx 容器
docker run -d --name nginx -p 80:80 nginx

# 3. 启动守护式容器(后台运行)
docker run -d 容器名
docker run -d redis:6.0.8
docker run -d --name alpine4 alpine 
docker run -d --name nginx  -p 80:80  nginx 
# sleep infinity 会一直运行,从而让容器保持在后台
docker run -d --name centos7 centos:7 sleep infinity

# 运行一个容器
docker run -it --name nginx03 nginx bash
docker exec  -it 2478(容器ID)  bash

# 容器已经启动,进入容器
docker exec -it centos7 /bin/bash

# 4. 停止容器
docker stop 容器名
docker stop nginx

# 5. 启动容器
docker start 容器名
docker start nginx
docker restart 容器名
docker restart nginx

# 6. 进入正在运行的容器
docker exec -it 容器名 bashshell
docker exec -it nginx /bin/bash

# 7、停止容器
docker stop 容器名
docker stop nginx

# 8. 强制停止容器
docker kill 容器名
docker kill nginx

# 9. 删除容器
#删除一个
docker rm 容器ID  
docker rm nginx
docker rm -f 容器ID  #强制删除
docker rm -f nginx
 
#删除多个
docker rm -f $(docker ps -a -q)docker ps -a -q | xargs docker rm

# 10. 查看容器日志
docker logs 容器名
docker logs nginx

# 11. 查看容器内运行的进程
docker top 容器名
docker top nginx

# 12. 查看容器内部细节
docker inspect 容器名
docker inspect nginx

# 13. 创建容器数据卷挂载
# 创建容器并指定数据卷,注意通过 -v 参数来指定数据卷
docker run -d --name nginx -p 80:80 -v html:/usr/share/nginx/html nginx

# 容器启动|停止|重启|暂停|恢复
docker start|stop|restart|pause|unpause 容器ID

# 强制终止一个或多个正在运行的容器
# 强制终止所有正在运行的容器
docker kill
# 强制终止一个正在运行的容器
docker kill 容器id

# 14. 查看数据卷
docker volume ls

# 15. 查看数据卷详情
docker volume inspect 数据卷名
docker volume inspect html

# 16. 删除数据卷
docker volume rm 数据卷名
docker volume rm html

# 指定容器端口映射
docker run -p 可以将容器的预定义的指定端口映射到宿主机的相应端口

#  注意:多个容器映射到宿主机的端口不能冲突,但容器内使用的端口可以相同
#  方式1:本地端口81映射到容器80端口:
docker run  -p 81:80 --name nginx-test-port1 nginx

#  方式2:本地IP:本地端口:容器端口
docker run  -p 192.168.0.100:82:80 --name nginx-test-port2 docker.io/nginx

#  方式3:本地IP:本地随机端口:容器端口,默认从32768开始
docker run -p 192.168.0.100::80 --name nginx-test-port3 docker.io/nginx

#  方式4:本机ip:本地端口:容器端口/协议,默认为tcp协议
docker run  -p 192.168.0.100:83:80/udp --name nginx-test-port4 docker.io/nginx

#  方式5:一次性映射多个端口+协议:
docker run  -p 8080:80/tcp -p 8443:443/tcp -p 53:53/udp --name nginx-test-port5  nginx

# 查看容器已经映射的端口
docker port nginx(容器名称)

3.4 网络类

# 1. 查看网络
docker network ls

# 2. 创建网络
docker network create 网络名
docker network create hmall

# 3. 查看网络数据源
docker network inspect 网络名
docker network inspect hmall

# 4. 删除网络
docker network rm 网络名
docker nerwork rm hmall

3.5 Docker compose

docker run -d \
  --name mysql \
  -p 3306:3306 \
  -e TZ=Asia/Shanghai \
  -e MYSQL_ROOT_PASSWORD=123 \
  -v ./mysql/data:/var/lib/mysql \
  -v ./mysql/conf:/etc/mysql/conf.d \
  -v ./mysql/init:/docker-entrypoint-initdb.d \
  --network hmall
  mysql

那么用docker-compose.yml 文件定义就是:
version: "3.8"
services:
  mysql:
    image: mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
    networks:
      - new
networks:
  new:
    name: hmall


# 1. 查看帮助
docker-compose -h

# 2. 启动所有服务
docker-compose up
docker-compose up -d # 后台运行

# 3. 停止并删除容器、网络、卷、镜像。
docker-compose down

# 4. 进入容器实例内部
docker-compose exec  yml里面的服务id

# 5. 展示容器
ocker-compose ps

# 6. 展示进程
docker-compose top

# 7. 查看容器输出日志
docker-compose logs  yml里面的服务id

# 8. 检查配置
docker-compose config
docker-compose config -q # 检查配置,有问题才有输出

# 9. 启动服务
docker-compose start

# 10. 重启服务
docker-compose restart

# 11. 停止服务
docker-compose stop

安装runlike可以查看已经运行的容器命令以及配置

# 安装python3-pip
yum/apt -y install python3-pip

# 使用python包管理工具安装runlike
pip3 install runlike

# runlike 容器名
runlike -p nginx

四、Docker优化配置

vi /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://docker.m.daocloud.io",
        "https://docker.1ms.run"
    ]
}
# 重新加载配置并重启
systemctl daemon-reload
systemctl restart docker

# 详细版本
vim/etc/docker/daemon.json
{
    "registry-mirrors":[
        "https://registry.docker-cn.com",
        "http://hub-mirror.c.163.com",
        "https://docker.mirrors.ustc.edu.cn",
        "https://si7y70hh.mirror.aliyuncs.com/"
    ],I
    "hosts":["unix:///var/run/docker.sock","tcp://0.0.0.0:2375"],  # 可远程连接
    "insecure-registries":["harbor.wang.org"],        # 可连接私有仓库
    "exec-opts":["native.cgroupdriver=systemd"],
    "graph":"/data/docker",									#指定docker数据目录
    "max-concurrent-downloads":10,     # 最多同时启动下载多个容器
    "max-concurrent-uploads":5,        # 最多同时启动上传多个容器
    "log-opts":{
        “max-size":"300m",				#指定容器日志文件的最大值
        # 指定容器日志文件的个数,循环写入日志文件,即一个日志满,会写入第二个文件
        "max-file":"2"			
    },
    # 就像给运行中的 Docker 容器加了个“保护罩”,
    # 即使 Docker 服务重启,容器也不会被关掉,能继续运行,保证服务不中断
    "live-restore": true
}

五、Docker镜像和下载

5.1 镜像结构和原理

可写的:可写容器(container)

可读的:镜像(tomcat)、镜像(jdk)、rootfs基础镜像(centos/ubuntu)、bootfs

bootfs:(用于系统引导。它包含引导加载程序(bootloader)和 Linux 内核。当容器启动时,<font style="color:rgb(6, 6, 7);">bootfs</font> 会被加载到内存中,用于引导操作系统启动。一旦内核加载完成,<font style="color:rgb(6, 6, 7);">bootfs</font> 会被卸载,以节省内存资源)

Docker的镜像是分层的,镜像底层为库文件且只读层即不能写入也不能删除数据,从镜像加载启动为一个容器后会生成一个可写层,其写入的数据会复制到宿主机上对应容器的目录,但是容器内的数据在删除容器后也会被随之删除。

镜像是创建容器的模板。类似于在使用Vware时,创建虚拟机

5.2 搜索镜像和下载

常见的docker系统镜像以及大小

  • alpine 4.799 MB
  • debian 84.98 MB
  • ubuntu 188.3 MB
  • centos 210 MB

pine官网:https://www.alpinelinux.org/

Alpine官方仓库:https://github.com/alpinelinux

Alpine官方镜像:https://hub.docker.com//alpine/

Alpine官方镜像仓库:https://github.com/gliderlabs/docker-alpine

Alpine阿里云的镜像仓库:https://mirrors.aliyun.com/alpine/

5.3 Docker导入与导出

# 查看现有的镜像
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
centos        latest    5d0da3dc9764   3 years ago   231MB
hello-world   latest    48b5124b2768   8 years ago   1.84kB
# 将centos镜像打包压缩
[root@localhost ~]# docker save centos:latest | gzip > centos.tar.gz
[root@localhost ~]# ll
total 131220
-rw-------. 1 root root     1306 Feb  1 17:04 anaconda-ks.cfg
-rw-r--r--. 1 root root 80904571 Feb  2 00:24 centos.tar.gz
-rw-r--r--. 1 root root   211884 Feb  1 17:16 ChangeMirrors.sh
# 远程传给另一台服务器
[root@localhost ~]# scp centos.tar.gz 10.0.0.20:
The authenticity of host '10.0.0.20 (10.0.0.20)' can't be established.
ECDSA key fingerprint is SHA256:7hSHdnpDfIY5BX7mKisvLJrLYHPatr4gekKUaBq2Y2E.
ECDSA key fingerprint is MD5:91:57:d2:6b:72:fd:c2:95:76:74:48:59:e3:41:e4:5e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.0.20' (ECDSA) to the list of known hosts.
root@10.0.0.20's password: 
centos.tar.gz                                                                            100%   77MB  50.4MB/s   00:01    
# 新的Ubuntu服务器
# 查看镜像,这个时候还没有安装docker
# 安装
root@moban:~# apt  install docker.io
# 再次查看镜像
root@moban:~# docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
# 把从10.0.0.10发送的centos镜像加载
root@moban:~# docker load < centos.tar.gz 
74ddd0ec08fa: Loading layer [==================================================>]  238.6MB/238.6MB
Loaded image: centos:latest
# 查看镜像
root@moban:~# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
centos       latest    5d0da3dc9764   3 years ago   231MB

六、Docker管理容器

6.1 容器的生命周期

容器启动流程

七、Podman容器引擎

7.1 Podman介绍

Podman 是一个开源的容器引擎,用于在 Linux 系统上开发、管理和运行 Open Container Initiative (OCI) 容器和容器镜像。它由 Red Hat 在 2018 年推出。

Podman 的优势

  • 安全性:无需守护进程和 root 权限,降低了安全风险。
  • 灵活性:支持 root 和非 root 用户模式。
  • 兼容性:提供与 Docker 兼容的命令行前端,用户可以使用 alias docker=podman 来无缝切换。
  • 功能丰富:支持容器、镜像、卷和网络的管理

7.2 Podman 与 Docker 的区别

  • 守护进程:Podman 是无守护进程的,而 Docker 需要依赖后台的 Docker daemon。
  • 用户权限:Podman 可以以非 root 用户运行,提高了安全性。
  • Pod 支持:Podman 支持 Pod 概念,与 Kubernetes 中的 Pod 类似。
  • 存储方式:Podman 将镜像和容器存储在不同位置,而 Docker 必须存储在 Docker Engine 所在的本地。
  • 架构:Podman 使用传统的 fork-exec 模式,而 Docker 是 client-server 架构

八、Docker镜像制作实战

8.1 制作镜像Dockerfile流程

  1. 需求分析
    确定应用类型(如 Web 服务、数据库、微服务等)。
    确定依赖环境(如 Python、Node.js、Java 等)。
    确定运行环境(如开发、测试、生产环境)。
  2. 选择基础镜像
    优先使用官方镜像,确保安全性和稳定性。
    选择轻量级镜像(如 alpine)以减少镜像大小。
    考虑多阶段构建,分离构建环境和运行环境。
  3. 编写 Dockerfile
    使用 RUN 安装依赖包。
    使用 ENV 配置环境变量。
    使用 COPY 或 ADD 复制应用代码。
    使用 EXPOSE 暴露端口。
    使用 CMD 或 ENTRYPOINT 设置启动命令。
    使用 HEALTHCHECK 添加健康检查。
  4. 优化 Dockerfile
    合并多个 RUN 命令,减少镜像层数。
    清理缓存和临时文件(如 apt-get clean)。
    使用多阶段构建,只保留运行时所需的文件。
    添加 .dockerignore 文件,忽略不必要的文件。
  5. 构建 Docker 镜像
    使用 CI/CD 工具(如 Jenkins、GitLab CI)自动化构建。
    为镜像打标签(如版本号、环境标识)。
  6. 测试镜像
    运行容器并验证功能是否正常。
    检查容器日志和性能指标。
    运行健康检查,确保容器状态正常。
  7. 安全扫描
    使用工具(如 Trivy、Clair)扫描镜像漏洞。
    修复发现的安全问题,重新构建镜像。
  8. 推送镜像到仓库
    推送到私有镜像仓库(如 Harbor、Nexus)。
    为镜像打标签并分类(如 dev、prod)。
  9. 部署到生产环境
    使用 Kubernetes 或 Docker Swarm 部署容器。
    配置监控和日志管理(如 Prometheus、ELK)。

8.2 基于容器手动制作镜像步骤

# 安装依赖,下载 repo 文件,并把软件仓库地址替换为镜像站
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 替换为清华的镜像
sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# 安装docker
yum install docker-ce -y

# 开启以及自启查看docker相关服务
systemctl start docker
systemctl enable docker
rpm -qa | grep docker

# 加速配置
vi /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://docker.m.daocloud.io",
        "https://docker.1ms.run"
    ]
}

# 重新加载配置并重启
systemctl daemon-reload
systemctl restart docker

# 拉取镜像
docker pull centos:centos7.9.2009

# 查看镜像下载是否成功
docker images 

# 后台运行并进入容器
docker run -it centos:centos7.9.2009 bash

# 删除本地时间
rm -f /etc/localtime

# 创建本地时间软链接
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 删除默认的所有源
rm -rf /etc/yum.repos.d/*

# 创建新的源文件CentOS-Base.repo
vi /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-$releasever - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/os/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
 
#released updates 
[updates]
name=CentOS-$releasever - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/updates/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
 
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/extras/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
 
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/centosplus/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/centosplus/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
 
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/contrib/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/contrib/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7

# 清理缓存并重新缓存
yum clean all
yum makecache

# 安装wget
yum -y install wget

# 增加EPEL源
wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo

# 安装常用工具
yum install -y vim curl iproute net-tools 

# 安装nginx
yum -y install nginx 

# 新建nginx配置文件
vim /etc/nginx/nginx.conf 
user nginx;
daemon off; # Close background operation

# 自定义web界面
rm -f /usr/share/nginx/html/index.html
echo "test page in docker" > /usr/share/nginx/html/index.html

# 不关闭容器的情况(再新开一个会话),将容器提交为镜像
# 基于容器生成镜像,EXPOSE在镜像中暴露 80 和 443 端口
docker commit -a "root@xiaoan.com" -m "nginx yum v1" -c "EXPOSE 80 443" a3be60af16fc xiaoan/centos7.9-nginx:1.20.1.v1

# 检查制作的镜像是否成功
 docker images

# 启动制作新的镜像
docker run -d -p 8080:80 --name my-centos7.9-nginx xiaoan/centos7.9-nginx:1.20.1.v1 /usr/sbin/nginx 

# 访问
curl 127.0.0.1:8080
[root@localhost ~]# curl 127.0.0.1:8080
test page in docker

8.3 Docker实战-制作nginx镜像

# 安装依赖,下载 repo 文件,并把软件仓库地址替换为镜像站
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 替换为清华的镜像
sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# 安装docker
yum install docker-ce -y

# 开启以及自启查看docker相关服务
systemctl start docker
systemctl enable docker
rpm -qa | grep docker

# 加速配置
vi /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://docker.m.daocloud.io",
        "https://docker.1ms.run"
    ]
}

# 重新加载配置并重启
systemctl daemon-reload
systemctl restart docker

# 拉取镜像
docker pull centos:centos7.9.2009

# 查看镜像下载是否成功
docker images 

# 后台运行并进入容器
docker run -it centos:centos7.9.2009 bash

# 删除本地时间
rm -f /etc/localtime

# 创建本地时间软链接
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 删除默认的所有源
rm -rf /etc/yum.repos.d/*

# 创建新的源文件CentOS-Base.repo
vi /etc/yum.repos.d/CentOS-Base.repo
[base]
name=CentOS-$releasever - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/os/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
 
#released updates 
[updates]
name=CentOS-$releasever - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/updates/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
 
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/extras/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
 
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/centosplus/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/centosplus/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
 
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/contrib/$basearch/
        http://mirrors.aliyuncs.com/centos/$releasever/contrib/$basearch/
        http://mirrors.cloud.aliyuncs.com/centos/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7

# 清理缓存并重新缓存
yum clean all
yum makecache

# 安装wget
yum -y install wget

# 增加EPEL源
wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo

# 安装常用工具
yum install -y vim curl iproute net-tools 

# 添加系统nginx用户
useradd -r -s /sbin/nologin nginx

# 安装基础包
yum -y install gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel

# 下载nginx
cd /usr/local/src
wget http://nginx.org/download/nginx-1.26.0.tar.gz

# 解压
tar xf nginx-1.26.0.tar.gz

# 创建目录
mkdir -p /apps/nginx

# 编译安装
cd nginx-1.26.0
./configure --prefix=/apps/nginx
make && make install

# 关闭nginx后台运行
cd /apps/nginx/
ll
vi conf/nginx.conf
user nginx;
daemon off;

# 创建软连接
ln -s /apps/nginx/sbin/nginx /usr/sbin/
ll /usr/sbin/nginx

# 准备相关数据自定义web界面
echo "Nginx Test Page in Docker" > /apps/nginx/html/index.html

# 提交镜像
# 不要退出容器,在另一个终端窗口执行以下命令
docker images 
docker ps 
docker commit -m "nginx1.26.0" 9f0115bef789  centos7.9-nginx:1.26.0

# 查看镜像
docker images

# 从自己的镜像启动容器,注意,提交的镜像名称与运行的镜像需要一致
docker run -d -p 80:80 centos7.9-nginx:1.26.0 nginx
docker ps 

# 测试
curl 127.0.0.1

# 查看Nginx访问日志和进程
docker exec -it bbc5c945303d(容器ID) bash
cat /apps/nginx/logs/access.log 

# 查看进程
ps aux

8.4 Dockerfile制作镜像

8.4.1 Dockfile 介绍

DockerFile 是一种被Docker程序解释的脚本,DockerFile是由一条条的命令组成的,每条命令对应linux下面的一条命令,Docker程序将这些DockerFile指令再翻译成真正的linux命令,其有自己的书写方式和支持的命令,Docker程序读取DockerFile并根据指令生成Docker镜像,相比手动制作镜像的方式,DockerFile更能直观的展示镜像是怎么产生的,有了DockerFile,当后期有额外的需求时,只要在之前的DockerFile添加或者修改响应的命令即可重新生成新的Docke镜像,避免了重复手动制作镜像的麻烦,类似与shell脚本一样,可以方便高效的制作镜像

通俗理解:

Dockerfile就像一个“菜谱”,记录了制作Docker镜像的每一步操作。Docker按照这个“菜谱”把命令翻译成Linux能理解的指令,一步步生成镜像。有了它,就像有了标准的制作流程,方便修改和复现,避免了手动制作镜像的繁琐,让镜像制作更高效、直观。

8.4.2 Dockerfile 镜像制作和使用流程

8.4.3 Dockerfile文件的制作镜像的分层结构

8.4.4 Dockerfile制作镜像

# 按照业务类型或系统类型等方式划分创建目录环境,方便后期镜像比较多的时候进行分类
mkdir /data/dockerfile/{web/{nginx,apache,tomcat,jdk},system/{centos,ubuntu,alpine,debian}} -p
tree /data/dockerfile/
[root@localhost ~]# tree /data/dockerfile/
/data/dockerfile/
├── system
│   ├── alpine
│   ├── centos
│   ├── debian
│   └── ubuntu
└── web
    ├── apache
    ├── jdk
    ├── nginx
    └── tomcat
    
# Dockerfile 文件说明

每一行以Dockerfile的指令开头,指令不区分大小写,但是惯例使用大写
使用 # 开始作为注释
每一行只支持一条指令,每条指令可以携带多个参数
指令按文件的顺序从上+
至下进行执行
每个指令的执行会生成一个新的镜像层,为了减少分层和镜像大小,尽可能将多条指令合并成一条指令
制作镜像一般可能需要反复多次,每次执行dockfile都按顺序执行,从头开始,已经执行过的指令已经缓存,
# 不需要再执行,后续有一行指令没执行过,再往后的指令将会重新执行,所以为加速镜像制作,
# 将最常变化的内容放下dockerfile的文件的后面

cd /data/dockerfile/system/alpine
touch Dockerfile

8.4.5 Dockerfile指令详细介绍

  1. FROM:指定基础镜像
FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

说明:
--platform 指定镜像的平台,比如:linux/amd64, linux/arm64, or windows/amd64
tag 和 digest是可选项,如果不指定,默认为latest


FROM scratch #所有镜像的起源镜像,相当于Object类
FROM ubuntu
FROM ubuntu:bionic
FROM debian:buster-slim    # 只能放系统镜像
  1. LABEL:指定镜像元数据

可以指定镜像元数据,如:镜像作者等

# 多种写法
# 一
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."

# 二
"Labels": {
    "maintainer='an<root@an.com>'"
    "com.example.vendor": "ACME Incorporated"
    "com.example.label-with-value": "foo",
    "version": "1.0",
    "description": "This text illustrates that label-values can span multiple lines.",
    "multi.label1": "value1",
    "multi.label2": "value2",
    "other": "value3"
},
  1. RUN:执行shell命令
#shell 格式: 
RUN <命令> 

#exec 格式: 
RUN ["可执行文件", "参数1", "参数2"]

# 范例:
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
RUN ["/bin/bash", "-c", "echo hello world"]
RUN yum -y install epel-release \
      && yum -y install nginx \
      && rm -rf /usr/share/nginx/html/*
      && echo "<h1> docker test nginx </h1>" > /usr/share/nginx/html/index.html
  1. COPY:复制文本

复制本地主机的 (为 Dockerfile 所在目录的相对路径)到容器中的 。

COPY <src>... <dest>
COPY ["<src1>",... "<目标路径>"]
# 说明:
# 可以是多个、以及使用通配符,通配符规则满足Go的filepath.Match 规则
# 使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等
# 如果是目录,只复制目录内容,而非目录本身

范例:
COPY hom* /mydir/    COPY hom?.txt /mydir/
  1. ADD:复制和解包文件

命令可认为是增强版的COPY,不仅支持COPY,还支持解压缩,可以将复制指定的文件或目录到容器中的目标路径,其中源文件可以是Dockerfile所在目录的一个相对路径、一个URL或一个tar文件(自动解压)。

ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"] 

# 说明:
# 如果src是目录,只复制目录中的内容,而非目录本身
# 如果src是本地打包或压缩文件,如gzip, bzip2 ,xz ,将解包
# 如果src是一个 URL ,下载后的文件权限自动设置为 600

# 范例:
ADD test relativeDir/          # adds "test" to 
WORKDIR
/relativeDir/
ADD test /absoluteDir/         # adds "test" to /absoluteDir/
ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
  1. CMD:容器启动命令

CMD用于指定容器启动时默认执行的命令。如果Dockerfile中有多条CMD命令,仅最后一条有效;若用户在运行容器时通过<font style="color:rgb(6, 6, 7);">docker run</font>指定了命令(如<font style="color:rgb(6, 6, 7);">docker run xxx /bin/bash</font>),则该命令会覆盖CMD指定的默认命令。

# 使用 exec 执行,推荐方式,第一个参数必须是命令的全路径
CMD ["executable","param1","param2"] 

# 在 /bin/sh 中执行,提供给需要交互的应用;
CMD command param1 param2 

# 提供给 ENTRYPOINT 的默认参数;
CMD ["param1","param2"] 
范例:

CMD ["nginx", "-g", "daemon off;"]
范例:

FROM ubuntu:18.04
RUN apt update \
&& apt -y install  curl \
&& rm -rf /var/lib/apt/lists/*
CMD [ "curl", "-s","https://ip.cn"]

[root@centos8 ubuntu]#podman  run  9b cat /etc/issue
Ubuntu 18.04.4 LTS \n \l

[root@centos8 ubuntu]#podman  run  9b
{"ip": "111.199.187.36", "country": "北京市", "city": "联通"}

#cat /etc/etc/issue覆盖了curl命令
[root@centos8 ubuntu]#podman  run  9b cat /etc/issue
Ubuntu 18.04.4 LTS \n \l
  1. ENTRYPOINT:入口点

ENTRYPOINT用于配置容器启动后执行的命令及参数,且不可被docker run提供的命令覆盖,而是将docker run的参数追加到ENTRYPOINT指定的命令中。如果docker run没有提供参数,但Dockerfile中存在CMD命令(第三种用法),则CMD的内容将作为ENTRYPOINT的参数。用户可以通过docker run --entrypoint在运行时替换ENTRYPOINT指定的命令。与CMD不同,ENTRYPOINT允许在运行时接受新参数,而CMD需要重新指定命令才能追加参数。每个Dockerfile中只能有一个ENTRYPOINT,多条时仅最后一条生效。

# 使用 exec 执行
ENTRYPOINT ["executable", "param1", "param2"]

# shell中执行
ENTRYPOINT command param1 param2
范例:

FROM ubuntu:18.04
RUN apt update \
&& apt -y install  curl \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT [ "curl", "-s","https://ip.cn"]

[root@centos8 ubuntu]#podman run -it --rm f68e006 
{"ip": "111.199.187.36", "country": "北京市", "city": "联通"}

#追加-i参数
[root@centos8 ubuntu]#podman run -it --rm f68e006  -i
HTTP/2 200 
date: Sun, 23 Feb 2020 08:05:19 GMT
content-type: application/json; charset=UTF-8
set-cookie: __cfduid=d4a22496ea6f3b2861763354f8ca600711582445119; expires=Tue, 24-Mar-20 08:05:19 GMT; path=/; domain=.ip.cn; HttpOnly; SameSite=Lax
cf-cache-status: DYNAMIC
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
alt-svc: h3-25=":443"; ma=86400, h3-24=":443"; ma=86400, h3-23=":443"; ma=86400
server: cloudflare
cf-ray: 5697b1ac1862eb41-LAX

{"ip": "111.199.187.36", "country": "北京市", "city": "联通"}
  1. ENV:设置环境变量
# 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

# 范例:
ENV VERSION=1.0 DEBUG=on NAME="Happy Feet"
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
  1. ARG:构建参数
# 指定变量
ARG <name>[=<default value>]

# 如果和ENV同名,ENV覆盖ARG变量
# 和ENV不同的是,容器运行时不会存在这些环境变量
# 可以用 docker build –build-arg <参数名>=<值> 来覆盖

# 范例:
FROM busybox
ARG user1=someuser
ARG buildno=1

FROM busybox
ARG SETTINGS
RUN ./run/setup $SETTINGS
  1. VOLUME:挂载点

在容器中创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等,一般会将宿主机上的目录<font style="color:rgb(61, 70, 77);background-color:rgb(244, 244, 244);">/var/lib/containers/storage/volumes/<id>/_data</font>挂载至VOLUME 指令指定的容器目录。即使容器后期删除,此宿主机的目录仍会保留,从而实现容器数据的持久保存。

VOLUME ["<容器内路径1>", "<容器内路径2>"...]
VOLUME <路径>

# 范例:在容器创建一个/data/ 的挂载点
VOLUME [ "/data""/data2" ] 

# 范例:
[root@centos8 ~]#cat /data/dockerfile/system/alpine/Dockerfile 
FROM alpine:3.11 
LABEL maintainer="wangxiaochun <root@wangxiaochun.com>"
COPY repositories /etc/apk/repositories 
VOLUME [ "/testdata" , "/testdata2" ]

[root@centos8 alpine]#podman run -it --rm 8ef61dd3959da3f sh
/ # df 
Filesystem           1K-blocks      Used Available Use% Mounted on
overlay              104806400   3656380 101150020   3% /
tmpfs                    65536         0     65536   0% /dev
/dev/sda2            104806400   3656380 101150020   3% /testdata2
/dev/sda2            104806400   3656380 101150020   3% /testdata
/ # cp /etc/issue  /testdata/f1.txt
/ # cp /etc/issue  /testdata2/f2.txt

[root@centos8 ~]#tree /var/lib/containers/storage/volumes/
/var/lib/containers/storage/volumes/
├── 725f0f67921bdbffbe0aaf9b015d663a6e3ddd24674990d492025dfcf878529b
│   └── _data
│       └── f1.txt
└── fbd13e5253deb375e0dea917df832d2322e96b04ab43bae061584dcdbe7e89f2
    └── _data
        └── f2.txt

4 directories, 2 files
  1. EXPOSE:暴露端口

告诉 Docker 服务端容器暴露的端口号,供互联系统使用。

EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射

因此,在启动容器时需要通过 -P 或-p ,Docker 主机会分配一个端口转发到指定暴露的端口,才可以使用

EXPOSE <端口1> [<端口2>...]
  1. WORKDIR:指定工作目录

为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录,当容器运行后,进入容器内的默认目录

WORKDIR /path/to/workdir

# 两次run不在一个环境内,可以使用WORKDIR
RUN cd /app
RUN echo "hello" > world.txt

# 可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
# 则最终路径为
/a/b/c
  1. ONBUILD:子镜像引用父镜像的指令

可以用来配置当创建当前镜像的子镜像时,会自动触发执行的指令。

ONBUILD [INSTRUCTION]

# 例如,Dockerfile 使用如下的内容创建了镜像 image-A。
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src...

# 如果基于 image-A 创建新的镜像时,新的Dockerfile中使用 FROM image-A指定基础镜像时,
# 会自动执行ONBUILD 指令内容,等价于在后面添加了两条指令。
FROM image-A

#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src

# 使用ONBUILD指令的镜像,推荐在标签中注明,例如ruby:1.9-onbuild
  1. USER:指定当前用户
# 指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户
# 当服务不需要管理员权限时,可以通过该命令指定运行用户
# 这个用户必须是事先建立好的,否则无法切换
# 要临时获取管理员权限可以使用 gosu,而不推荐 sudo
USER <user>[:<group>] 
USER <UID>[:<GID>]

# 范例:
RUN groupadd -r mysql && useradd -r -g mysql mysql
USER mysql
  1. HEALTHCHECK:健康检查
# 检查容器的健康性
HEALTHCHECK [选项] CMD <命令> #设置检查容器健康状况的命令
HEALTHCHECK NONE #如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

HEALTHCHECK 支持下列选项:
--interval=<间隔> :两次健康检查的间隔,默认为 30 秒;
--timeout=<时长> :健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
--retries=<次数> :当连续失败指定次数后,则将容器状态视为 unhealthy ,默认 3次。


# 范例
FROM nginx
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s \
CMD curl -fs http://localhost/ || exit 1
  1. STOPSIGNAL:退出容器的信号

STOPSIGNAL指令用于设置容器退出时接收的系统调用信号。该信号可以是一个与内核syscall表中位置匹配的有效无符号数字(如9),也可以是符合SIGNAME格式的信号名称(如SIGKILL)。

STOPSIGNAL signal
  1. .dockerignore文件

官方文档:https://docs.docker.com/engine/reference/builder/#dockerignore-file
与.gitignore文件类似,生成构建上下文时Docker客户端应忽略的文件和文件夹指定模式。

以下是完整的语法:
'*'      匹配任何非分隔符字符序列
'?'     匹配任何单个非分隔符
'['['^'] {character-range}']'
字符类(必须是非空的)
c匹配字符c  (c!='*''?''\\''[''\\'    表示  \

'**'    匹配任意数量的目录(包括零)例如,**/*.go将排除.go 在所有目录中找到的以该结尾的所有文件,包括构建上下文的根。
'!'    表示取反,可用于排除例外情况
以此字符开头的'#'行将被忽略:将其用于注释

#  范例1:
#排除 test 目录下的所有文件
test/*
#排除 md 目录下的 xttblog.md 文件
md/xttblog.md
#排除 xttblog 目录下的所有 .md 的文件
xttblog/*.md
#排除以 xttblog 为前缀的文件和文件夹
xttblog?
#排除所有目录下的 .sql 文件夹
**/*.sql

# 范例2:
#除了README的md不排外,排除所有md文件,但不排除README-secret.md
*.md
!README*.md
README-secret.md

#除了所有README的md文件以外的md都排除
*.md
README-secret.md
!README*.md

Dockerfile文件指令总结

8.5 使用Dockerfile制作系统镜像

# 安装依赖,下载 repo 文件,并把软件仓库地址替换为镜像站
yum install -y yum-utils vim wget
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 替换为清华的镜像
sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# 安装docker
yum install docker-ce -y

# 开启以及自启查看docker相关服务
systemctl start docker
systemctl enable docker
rpm -qa | grep docker

# 加速配置
vi /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://docker.m.daocloud.io",
        "https://docker.1ms.run"
    ]
}

# 重新加载配置并重启
systemctl daemon-reload
systemctl restart docker

# 按照业务类型或系统类型等方式划分创建目录环境,方便后期镜像比较多的时候进行分类
mkdir /data/dockerfile/{web/{nginx,apache,tomcat,jdk},system/{centos,ubuntu,alpine,debian}} -p
tree /data/dockerfile/

# 下载基础镜像
docker pull centos:centos7.7.1908
docker images

# 先制作系统镜像
cd /data/dockerfile/system/centos/

vim Dockerfile
FROM centos:centos7.9.2009
LABEL maintainer="an <root@an.com>"
RUN rm -f /etc/localtime \
  && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
  && rm -rf /etc/yum.repos.d/* \
  && curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo \
  && curl -o /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo \
  && yum clean all && yum makecache \
  && 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

# 新建构建脚本
vim /data/dockerfile/system/centos/build.sh
#!/bin/bash
docker build -t centos7.9-system:v1  .

# 执行脚本
bash /data/dockerfile/system/centos/build.sh

# 查看镜像
docker images 

# 查看系统构建信息
docker image history centos7.9-system:v1

[root@localhost centos]# docker images                                                                                               
REPOSITORY         TAG              IMAGE ID       CREATED          SIZE
centos7.9-system   v1               294c8dd4efc2   17 seconds ago   1.12GB
centos7.9-nginx    1.26.0           0be2f7817518   4 hours ago      976MB
alpine             3.19             37668a5f6667   3 weeks ago      7.4MB
centos             centos7.9.2009   eeb6ee3f44bd   3 years ago      204MB
[root@localhost centos]# docker image history centos7.9-system:v1
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
294c8dd4efc2   50 seconds ago   RUN /bin/sh -c rm -f /etc/localtime   && ln …   914MB     buildkit.dockerfile.v0
<missing>      50 seconds ago   LABEL maintainer=an <root@an.com>               0B        buildkit.dockerfile.v0
<missing>      3 years ago      /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
<missing>      3 years ago      /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
<missing>      3 years ago      /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4…   204MB

8.6 直接制作nginx 镜像

# 安装依赖,下载 repo 文件,并把软件仓库地址替换为镜像站
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 替换为清华的镜像
sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# 安装docker
yum install docker-ce -y

# 开启以及自启查看docker相关服务
systemctl start docker
systemctl enable docker
rpm -qa | grep docker

# 加速配置
vi /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://docker.m.daocloud.io",
        "https://docker.1ms.run"
    ]
}

# 重新加载配置并重启
systemctl daemon-reload
systemctl restart docker

# 拉取镜像
docker pull centos:centos7.9.2009

# 查看镜像下载是否成功
docker images 

# 在Dockerfile目录下准备编译安装的相关文件
mkdir -p /data/dockerfile/web/nginx/1.26

# 修改nginx
cd /data/dockerfile/web/nginx/1.26

# 修改nginx配置文件
vim nginx.conf
events {
    worker_connections 1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   /apps/nginx/html;
            index  index.html index.htm;
        }
    }
}
  

wget -P /data/dockerfile/web/nginx/1.26 http://nginx.org/download/nginx-1.26.0.tar.gz

## 编写Nginx的Dockerfile文件
cd /data/dockerfile/web/nginx/1.26

vim  Dockerfile 

FROM centos:centos7.9.2009
LABEL maintainer="root@an.com"

RUN rm -f /etc/localtime \
    && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && rm -rf /etc/yum.repos.d/* \
    && curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo \
    && curl -o /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo \
    && yum install -y gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel \
    && useradd -r -s /sbin/nologin nginx \
    && yum clean all

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

RUN cd /usr/local/src/nginx-1.26.0 \
    && ./configure --prefix=/apps/nginx \
    && make \
    && make install

# 将 nginx.conf 和 index.html 文件放在 Dockerfile 所在的目录中,然后复制
COPY nginx.conf /apps/nginx/conf/nginx.conf
COPY index.html /apps/nginx/html/

RUN rm -rf /usr/local/src/nginx* \
    && ln -s /apps/nginx/sbin/nginx /usr/sbin/nginx

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]



## 生成nginx镜像
# 编写脚本
vim /data/dockerfile/web/nginx/1.26/build.sh
#!/bin/bash
docker build -t nginx-centos7:1.26.0 . 

# 执行脚本
bash /data/dockerfile/web/nginx/1.26/build.sh
docker images 

# 测试容器镜像
docker run  -d -p 80:80  nginx-centos7.9:1.26.0-v1
[root@localhost 1.26]# curl 127.0.0.1
test
# 查看容器进程
docker ps

# 进入容器
docker exec -it e8e733c6dc96(容器ID) bash

# 查看进程
ps aux

8.7 制作自定义tomcat业务镜像

# 安装依赖,下载 repo 文件,并把软件仓库地址替换为镜像站
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 替换为清华的镜像
sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# 安装docker
yum install docker-ce -y

# 开启以及自启查看docker相关服务
systemctl start docker
systemctl enable docker
rpm -qa | grep docker

# 加速配置
vi /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://docker.m.daocloud.io",
        "https://docker.1ms.run"
    ]
}

# 重新加载配置并重启
systemctl daemon-reload
systemctl restart docker

# 拉取镜像
docker pull centos:centos7.9.2009

# 查看镜像下载是否成功
docker images 


# 创建目录
mkdir -p /data/dockerfile/{web/{nginx,tomcat,jdk},system/{centos,ubuntu,alpine,debian}} 
cd /data/dockerfile/system/centos/ 

# 编写文件
vim Dockerfile

# Centos Base Image 
FROM centos:centos7.9.2009
LABEL maintainer="root@an.com"

RUN rm -f /etc/localtime \
    && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && rm -rf /etc/yum.repos.d/* \
    && curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo \
    && curl -o /etc/yum.repos.d/epel-7.repo 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 \
#添加系统账户
    && groupadd www -g 2019 && useradd www -u 2019 -g www 

# 脚本
vim build.sh
#!/bin/bash 
docker build -t centos7.9-system:v1 . 

# 执行
bash /data/dockerfile/system/centos/build.sh 
docker images

# 构建JDK 镜像
# http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
# 下载移动jdk到Dockerfile 所在目录下
# 复制本机的/etc/profile目录到
cp /etc/profile /data/dockerfile/web/jdk

# 修改profile文件,加下面四行相关变量
vim /data/dockerfile/web/jdk/profile
# 添加
export JAVA_HOME=/usr/local/jdk
export TOMCAT_HOME=/apps/tomcat
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$TOMCAT_HOME/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar

# 生效
source /data/dockerfile/web/jdk/profile

# 下载jdk包上传到Dockerfile 所在目录下
cd /data/dockerfile/web/jdk
tree /data/dockerfile/web/jdk

# 准备Dockerfile文件
vim  /data/dockerfile/web/jdk/Dockerfile 
#JDK Base Image
FROM centos7.9-system:v1
LABEL maintainer="an <root@an.com>"
ADD jdk-8u441-linux-x64.tar.gz /usr/local/jdk_version
RUN ln -s /usr/local/jdk_version/jdk1.8.0_441 /usr/local/jdk
ADD profile /etc/profile
ENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin

# 构建脚本
vim /data/dockerfile/web/jdk/build.sh
#!/bin/bash
docker build -t centos7.9-jdk:1.8 .

tree /data/dockerfile/web/jdk/

# 执行
bash /data/dockerfile/web/jdk/build.sh
docker images 

# 运行
# --rm 表示容器在退出后自动删除自身,避免残留无用的容器文件,常用于临时测试或单次任务场景
docker run -it --rm centos7.9-jdk:1.8 bash java -version
[root@8134ecb5da43 /]# java -version
java version "1.8.0_441"
Java(TM) SE Runtime Environment (build 1.8.0_441-b07)
Java HotSpot(TM) 64-Bit Server VM (build 25.441-b07, mixed mode)


# 测试
java -version

8.8 从JDK镜像构建tomcat 8 Base镜像

# 基于自定义的 JDK 基础镜像,构建出通用的自定义 Tomcat 基础镜像,
# 此镜像后期会被多个业务的多个服务共同引用(相同的JDK 版本和Tomcat 版本)

# 上传tomcat 压缩包
mkdir -p /data/dockerfile/web/tomcat/tomcat-base-8.5.50
cd /data/dockerfile/web/tomcat/tomcat-base-8.5.50

# 下载tomcat,如果这下载不了,在浏览器下载好上传
wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.98/bin/apache-tomcat-9.0.98.tar.gz

# 编辑Dockerfile
vim /data/dockerfile/web/tomcat/tomcat-base-8.5.50/Dockerfile 
#Tomcat Base Image 
FROM centos7.9-jdk:1.8 
LABEL maintainer="an <root@an.com>"
#env 
ENV TZ "Asia/Shanghai" 
ENV LANG en_US.UTF-8 
ENV TERM xterm 
ENV TOMCAT_MAJOR_VERSION 9 
ENV TOMCAT_MINOR_VERSION 9.0.98 
ENV CATALINA_HOME /apps/tomcat 
ENV APP_DIR ${CATALINA_HOME}/webapps 
RUN mkdir /apps  
ADD apache-tomcat-9.0.98.tar.gz /apps   
RUN ln -s /apps/apache-tomcat-9.0.98 /apps/tomcat



# 通过脚本构建tomcat 基础镜像
vim  build.sh 
#!/bin/bash
docker build -t tomcat-base:v9.0.98 .
tree
.
├── apache-tomcat-9.0.98.tar.gz
├── build.sh
└── Dockerfile

bash /data/dockerfile/web/tomcat/tomcat-base-9.0.98/build.sh
docker images

# 验证镜像构建完成
docker run -it --rm -p 8080:8080  tomcat-base:v9.0.98 bash   

# 运行
/apps/tomcat/bin/catalina.sh start

# 查看端口
netstat -ntl

8.8.1 构建业务镜像1

# 准备tomcat的配置文件
mkdir -p /data/dockerfile/web/tomcat/tomcat-app{1,2}
tree /data/dockerfile/web/tomcat/

# 解压tomcat-base-9.0.98
cd /data/dockerfile/web/tomcat/tomcat-base-9.0.98
tar xf apache-tomcat-9.0.98.tar.gz

# 将官方的tomcat配置文件 复制到tomcat-app1
cp apache-tomcat-9.0.98/conf/server.xml /data/dockerfile/web/tomcat/tomcat-app1/
cd /data/dockerfile/web/tomcat/tomcat-app1/

# 修改配置,appBase修改路径
vim server.xml
<Host name="localhost" appBase="/data/tomcat/webapps" unpackWARs="true" 
      autoDeploy="true">

# 准备自定义页面
mkdir -p /data/dockerfile/web/tomcat/tomcat-app1/app
echo "Tomcat Page in app1" > app/index.jsp

# 打包app
tar zcf app.tar.gz app

# 准备容器启动执行脚本
vim run_tomcat.sh
#!/bin/bash
echo "nameserver 114.114.114.114" > /etc/resolv.conf 
su - www -c "/apps/tomcat/bin/catalina.sh start" 
su - www -c "tail -f /etc/hosts"

# 授权
chmod a+x run_tomcat.sh 

# 准备Dockerfile
vim Dockerfile 
#Tomcat Web Image 
FROM tomcat-base:v9.0.98
LABEL maintainer="an <root@an.com>"
ADD server.xml /apps/tomcat/conf/server.xml
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh 
ADD app.tar.gz /data/tomcat/webapps/ 
RUN chown -R www.www /apps/   /data/tomcat/   
EXPOSE 8080  8009
CMD ["/apps/tomcat/bin/run_tomcat.sh"] 

# 执行构建脚本制作镜像
vim /data/dockerfile/web/tomcat/tomcat-app1/build.sh
#!/bin/bash
docker build -t tomcat-web:app1 .
tree

# 执行
bash /data/dockerfile/web/tomcat/tomcat-app1/build.sh 
docker images

# 测试
docker run -d  -p 8080:8080  tomcat-web:app1

# 访问测试
curl 127.0.0.1:8080/app/
Tomcat Page in app1
# 进入容器
docker exec -it 82e6690e36c3  bash
[root@9776b56ebf84 /]# ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          1  0.0  0.0  13292  1480 ?        Ss   19:28   0:00 /bin/bash /apps/tomcat/bin/run_tomcat.sh
www          26  9.7  9.4 2915880 191756 ?      Sl   19:28   0:06 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/
root         27  0.0  0.1  83584  2196 ?        S    19:28   0:00 su - www -c tail -f /etc/hosts
www          28  0.0  0.0   4404   356 ?        Ss   19:28   0:00 tail -f /etc/hosts
root         69  0.4  0.1  13956  2616 pts/0    Ss   19:30   0:00 bash
root         89  0.0  0.0  53332  1868 pts/0    R+   19:30   0:00 ps aux

# 修改首页
vim /data/tomcat/webapps/app/index.jsp 
Tomcat Page in app1 v2

# 重启
/apps/tomcat/bin/catalina.sh stop
/apps/tomcat/bin/catalina.sh start

# 重新测试
exit
curl 127.0.0.1:8080/app/
Tomcat Page in app1 v2

8.9 构建haproxy镜像

#准备haproxy源码文件
mkdir -p  /data/dockerfile/web/haproxy/2.5.13-centos7.9
cd /data/dockerfile/web/haproxy/2.5.13-centos7.9
# 在本地下载上传到服务器
wget https://mirrors.huaweicloud.com/haproxy/2.5/src/haproxy-2.5.13.tar.gz
file haproxy-2.5.13.tar.gz
haproxy-2.5.13.tar.gz: gzip compressed data, from Unix, max compression

#准备haproxy启动脚本
vim run_haproxy.sh
#!/bin/bash
# 启动 HAProxy 服务,使用指定的配置文件
# -f /etc/haproxy/haproxy.cfg:指定 HAProxy 的配置文件路径
haproxy -f /etc/haproxy/haproxy.cfg

# 持续监控 /etc/hosts 文件的变化
# tail -f:实时显示文件的新增内容
# /etc/hosts:系统的主机名解析文件,用于将主机名映射到 IP 地址
tail -f /etc/hosts

# 给予执行权限
chmod +x run_haproxy.sh

vim haproxy.cfg
# 全局配置
global
    chroot /apps/haproxy                     # 将 HAProxy 的根目录设置为 /apps/haproxy,增强安全性
    #stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin  # 启用统计套接字(注释掉表示不启用)
    uid 99                                   # 以 UID 99(通常为 nobody 用户)运行 HAProxy
    gid 99                                   # 以 GID 99(通常为 nobody 组)运行 HAProxy
    daemon                                   # 以守护进程模式运行 HAProxy
    nbproc 1                                 # 使用 1 个进程运行 HAProxy
    pidfile /apps/haproxy/run/haproxy.pid    # 指定 PID 文件路径
    log 127.0.0.1 local3 info                # 将日志发送到本地 syslog 的 local3 设备,日志级别为 info

# 默认配置
defaults
    option http-keep-alive                   # 启用 HTTP 长连接
    option forwardfor                        # 在请求头中添加 X-Forwarded-For,记录客户端真实 IP
    mode http                                # 默认模式为 HTTP
    timeout connect 300000ms                 # 连接后端服务器的超时时间为 300 秒
    timeout client 300000ms                  # 客户端超时时间为 300 秒
    timeout server 300000ms                  # 服务器超时时间为 300 秒

# 统计页面配置
listen stats
    mode http                                # 统计页面使用 HTTP 模式
    bind 0.0.0.0:9999                        # 绑定所有 IP 的 9999 端口
    stats enable                             # 启用统计页面
    log global                               # 使用全局日志配置
    stats uri /haproxy-status                # 统计页面的访问路径为 /haproxy-status
    stats auth haadmin:123456                # 统计页面的登录认证,用户名为 haadmin,密码为 123456

# Web 服务配置
listen web_port
    bind 0.0.0.0:80                          # 绑定所有 IP 的 80 端口
    mode http                                # 使用 HTTP 模式
    log global                               # 使用全局日志配置
    balance roundrobin                       # 使用轮询(roundrobin)负载均衡算法
    server web1 10.0.0.101:8080 check inter 3000 fall 2 rise 5  # 后端服务器 web1,IP 为 10.0.0.101,端口为 8080,健康检查间隔 3 秒,失败 2 次标记为宕机,成功 5 次标记为正常
    

# 准备Dockerfile
vim /data/dockerfile/web/haproxy/2.5.13-centos7.9/Dockerfile 
#Haproxy Base Image
FROM centos7.9-system:v1
LABEL maintainer="an <root@an.com>"

ADD haproxy-2.5.13.tar.gz /usr/local/src/ 

RUN cd /usr/local/src/haproxy-2.5.13 \
    && make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 PREFIX=/apps/haproxy \
    && make install PREFIX=/apps/haproxy \
    && ln -s /apps/haproxy/sbin/haproxy  /usr/sbin/ \
    && mkdir /apps/haproxy/run \
    && rm -rf /usr/local/src/haproxy*  

ADD haproxy.cfg /etc/haproxy/
ADD run_haproxy.sh /usr/bin

EXPOSE 80 9999
CMD ["run_haproxy.sh"]


# 准备构建脚本构建haproxy镜像
vim build.sh  
#!/bin/bash
docker build -t haproxy-centos7.9:2.5.13 .
tree

# 执行脚本
bash build.sh 
docker images 

# 从镜像启动容器
docker run -d -p 80:80 -p 9999:9999 haproxy-centos7.9:2.5.13 

# 在另外一台主机启动容器
#导出本地相关镜像,这块需要改进,按你自己的命名来写
docker save centos7.9-system:v1 > /data/centos7.9-system.tar.gz
docker save centos7.9-jdk:1.8 > /data/centos7.9-jdk.tar.gz
docker save tomcat-base:v9.0.98 > /data/tomcat-base.tar.gz
docker save tomcat-web:app1 > /data/tomcat-web-app1.tar.gz
docker save haproxy-centos7.9:2.5.13 > /data/haproxy-centos7.9.tar.gz

[root@localhost 2.5.13-centos7.9]# ls /data
centos7.9-jdk.tar.gz     dockerfile                tomcat-base.tar.gz
centos7.9-system.tar.gz  haproxy-centos7.9.tar.gz  tomcat-web-app1.tar.gzata

#将镜像复制到另外一台主机
scp /data/*.gz 10.0.0.30:/data/  

#在另外一台主机上执行下面操作导入镜像
ls /data
for i in /data/*.gz;do docker load -i $i;done

#在另外一台主机上创建相关容器
docker run -d -p 8080:8080 tomcat-web:app1 

# web访问验证
curl http://10.0.0.30/app/


# 进入容器
docker exec -it e0a7c827cb5 bash
netstat -ntl

cat /etc/haproxy/haproxy.cfg 
ps aux

九、Docker 数据管理

待更新


http://www.kler.cn/a/534291.html

相关文章:

  • Docker使用教程
  • 大语言模型的个性化综述 ——《Personalization of Large Language Models: A Survey》
  • 4种架构的定义和关联
  • 今日AI和商界事件(2025-02-05)
  • Java 面试之结束问答
  • 在 Spring Boot 项目中,bootstrap.yml 和 application.yml文件区别
  • Node.js 与 PostgreSQL 集成:深入 pg 模块的应用与实践
  • 基于Ceph14对接openstack的Nova、Glance、Cinder服务为后端存储
  • [权限提升] Linux 提权 — 系统内核溢出漏洞提权
  • linux常用基础命令 最新
  • Java 微服务实用指南(一)
  • Node.js学习指南
  • 18爬虫:关于playwright相关内容的学习
  • ES6 对象扩展:对象简写,对象属性 表达式,扩展运算符 ...,Object.assign,Object.is,用法和应用场景
  • 教育邮箱免费使用Notion专业版,还能免费使用Azure和OpenAI!
  • [Leetcode]求最长公共前缀
  • Linux 安装 RabbitMQ
  • 高级java每日一道面试题-2025年01月28日-框架篇[SpringBoot篇]-如何使用Spring Boot实现异常处理?
  • 按月拆分工作表,报表清晰没烦恼-Excel易用宝
  • ubuntu22.40安装及配置静态ip解决重启后配置失效
  • Linux环境部署DeepSeek大模型
  • 深入解析:如何获取商品 SKU 详细信息
  • 双亲委派(jvm)
  • Anaconda中指定python版本安装langchain
  • Django框架丨从零开始的Django入门学习
  • Excel中Address函数的用法