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 端是否开启 debugServer: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_typeNative 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 #是否支持 swarmRuntimes: 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 #宿主机 hostnameID: IZHJ:WPIN:BRMC:XQUI:VVVR:UVGK:NZBM:YQXT:JDWB:33RS:45V7:SQWJ #宿主机 IDDocker Root Dir: /var/lib/docker #宿主机关于docker数据的保存目录Debug Mode: false #server 端是否开启 debugRegistry: 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 mysqldocker rmi -f 镜像名/镜像ID 镜像名/镜像ID 镜像名/镜像ID #删除多个 其镜像ID或镜像用用空格隔开即可
docker rmi -f mysql redisdocker 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 hmallmysql那么用docker-compose.yml 文件定义就是:
version: "3.8"
services:mysql:image: mysqlcontainer_name: mysqlports:- "3306:3306"environment:TZ: Asia/ShanghaiMYSQL_ROOT_PASSWORD: 123volumes:- "./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流程
- 需求分析
确定应用类型(如 Web 服务、数据库、微服务等)。
确定依赖环境(如 Python、Node.js、Java 等)。
确定运行环境(如开发、测试、生产环境)。 - 选择基础镜像
优先使用官方镜像,确保安全性和稳定性。
选择轻量级镜像(如 alpine)以减少镜像大小。
考虑多阶段构建,分离构建环境和运行环境。 - 编写 Dockerfile
使用 RUN 安装依赖包。
使用 ENV 配置环境变量。
使用 COPY 或 ADD 复制应用代码。
使用 EXPOSE 暴露端口。
使用 CMD 或 ENTRYPOINT 设置启动命令。
使用 HEALTHCHECK 添加健康检查。 - 优化 Dockerfile
合并多个 RUN 命令,减少镜像层数。
清理缓存和临时文件(如 apt-get clean)。
使用多阶段构建,只保留运行时所需的文件。
添加 .dockerignore 文件,忽略不必要的文件。 - 构建 Docker 镜像
使用 CI/CD 工具(如 Jenkins、GitLab CI)自动化构建。
为镜像打标签(如版本号、环境标识)。 - 测试镜像
运行容器并验证功能是否正常。
检查容器日志和性能指标。
运行健康检查,确保容器状态正常。 - 安全扫描
使用工具(如 Trivy、Clair)扫描镜像漏洞。
修复发现的安全问题,重新构建镜像。 - 推送镜像到仓库
推送到私有镜像仓库(如 Harbor、Nexus)。
为镜像打标签并分类(如 dev、prod)。 - 部署到生产环境
使用 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指令详细介绍
- 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是可选项,如果不指定,默认为latestFROM scratch #所有镜像的起源镜像,相当于Object类
FROM ubuntu
FROM ubuntu:bionic
FROM debian:buster-slim # 只能放系统镜像
- 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"
},
- 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
- COPY:复制文本
复制本地主机的 (为 Dockerfile 所在目录的相对路径)到容器中的 。
COPY <src>... <dest>
COPY ["<src1>",... "<目标路径>"]
# 说明:
# 可以是多个、以及使用通配符,通配符规则满足Go的filepath.Match 规则
# 使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等
# 如果是目录,只复制目录内容,而非目录本身范例:
COPY hom* /mydir/ COPY hom?.txt /mydir/
- 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 /
- 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
- 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": "联通"}
- 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
- ARG:构建参数
# 指定变量
ARG <name>[=<default value>]# 如果和ENV同名,ENV覆盖ARG变量
# 和ENV不同的是,容器运行时不会存在这些环境变量
# 可以用 docker build –build-arg <参数名>=<值> 来覆盖# 范例:
FROM busybox
ARG user1=someuser
ARG buildno=1FROM busybox
ARG SETTINGS
RUN ./run/setup $SETTINGS
- 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.txt4 directories, 2 files
- EXPOSE:暴露端口
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。
EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射
因此,在启动容器时需要通过 -P 或-p ,Docker 主机会分配一个端口转发到指定暴露的端口,才可以使用
EXPOSE <端口1> [<端口2>...]
- 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
- 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
- USER:指定当前用户
# 指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户
# 当服务不需要管理员权限时,可以通过该命令指定运行用户
# 这个用户必须是事先建立好的,否则无法切换
# 要临时获取管理员权限可以使用 gosu,而不推荐 sudo
USER <user>[:<group>]
USER <UID>[:<GID>]# 范例:
RUN groupadd -r mysql && useradd -r -g mysql mysql
USER mysql
- 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
- STOPSIGNAL:退出容器的信号
STOPSIGNAL指令用于设置容器退出时接收的系统调用信号。该信号可以是一个与内核syscall表中位置匹配的有效无符号数字(如9),也可以是符合SIGNAME格式的信号名称(如SIGKILL)。
STOPSIGNAL signal
- .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.26vim 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 allADD 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/nginxEXPOSE 80 443CMD ["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
└── Dockerfilebash /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.shvim haproxy.cfg
# 全局配置
globalchroot /apps/haproxy # 将 HAProxy 的根目录设置为 /apps/haproxy,增强安全性#stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin # 启用统计套接字(注释掉表示不启用)uid 99 # 以 UID 99(通常为 nobody 用户)运行 HAProxygid 99 # 以 GID 99(通常为 nobody 组)运行 HAProxydaemon # 以守护进程模式运行 HAProxynbproc 1 # 使用 1 个进程运行 HAProxypidfile /apps/haproxy/run/haproxy.pid # 指定 PID 文件路径log 127.0.0.1 local3 info # 将日志发送到本地 syslog 的 local3 设备,日志级别为 info# 默认配置
defaultsoption http-keep-alive # 启用 HTTP 长连接option forwardfor # 在请求头中添加 X-Forwarded-For,记录客户端真实 IPmode http # 默认模式为 HTTPtimeout connect 300000ms # 连接后端服务器的超时时间为 300 秒timeout client 300000ms # 客户端超时时间为 300 秒timeout server 300000ms # 服务器超时时间为 300 秒# 统计页面配置
listen statsmode http # 统计页面使用 HTTP 模式bind 0.0.0.0:9999 # 绑定所有 IP 的 9999 端口stats enable # 启用统计页面log global # 使用全局日志配置stats uri /haproxy-status # 统计页面的访问路径为 /haproxy-statusstats auth haadmin:123456 # 统计页面的登录认证,用户名为 haadmin,密码为 123456# Web 服务配置
listen web_portbind 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/binEXPOSE 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 -ntlcat /etc/haproxy/haproxy.cfg
ps aux
九、Docker 数据管理
待更新