Docker概述_Docker使用场景和优势
前言:
Docker 是一种开源的容器化平台,它通过轻量级的容器技术,实现了应用程序的快速打包、分发和运行。与传统虚拟化技术不同,Docker 利用操作系统级别的虚拟化,使应用能够在隔离的环境中高效运行,同时保持极低的资源开销。Docker 的核心优势在于其可移植性、一致性和高效的 DevOps 支持,使得开发、测试和部署流程更加流畅。无论是微服务架构、持续集成(CI/CD),还是云原生应用开发,Docker 都已成为现代软件开发和运维的重要工具。
目录
一、 Docker概述
Docker简介
Docker版本演化与技术特征更新
1、Docker发展历程概述
1. 初创期(2013-2014)
2. 成长期(2015-2016)
3. 成熟期(2017-2019)
4. 现代期(2020至今)
2、重大版本技术特征更新
Docker 1.0 (2014年6月)
Docker 1.12 (2016年7月)
Docker 17.03 (2017年3月)
Docker 18.09 (2018年11月)
Docker 19.03 (2019年7月)
Docker 20.10 (2020年12月)
Docker 23.0 (2023年1月)
3、关键技术演进路线
1. 容器运行时演进
2. 构建系统革新
3. 网络模型发展
4. 存储驱动优化
5. 安全增强路径
4、当前技术趋势
Docker容器技术与虚拟机的区别
Docker相较于VM的优点
Docker局限性
Docker通常用于如下场景
二、 Docker 架构
三、 Docker安装
1、使用官方安装脚本自动安装
2、手动安装
3、启动 Docker
4、卸载 Docker
四、 Docker 镜像加速
五、/etc/docker/daemon.json 配置文件
1. 通用配置
2. 存储驱动
3. 网络配置
4. 镜像和 Registry 配置
5. 安全配置
6. 日志配置
7. 其他配置
示例 daemon.json
六、 Docker命令
docker命令帮助
docker常用子命令
docker管理子命令
swarm集群管理子命令
docker容器管理子命令
docker全局选项
七、 docker镜像管理
概述
核心概念
镜像的分层
镜像分层后的优势
镜像的特点
镜像的表示
镜像的表示分为四部分
镜像制作方式
镜像管理命令
docker images 显示解析
docker history命令
DockerHub
八、容器管理
概述
容器操作命令
docker run 命令
docker exec命令
docker logs命令
docker rename命令
docker top命令
docker ps 命令
docker ps -a显示信息解析
docker rm 命令
docker kill 命令
docker start命令
docker restart命令
docker stop 命令
docker inspect命令
docker tag命令
docker pause命令
docker unpause命令
docker port命令
docker info命令
docker create命令
docker rmi命令
docker save命令
docker load命令
docker cp命令
docker stats命令
docker version命令
docker容器创建后的状态
九、Dockerfile文件
1、概述
2、常见命令
2.1 FROM
2.2 MAINTAINER(新版即将废弃)
2.3 RUN
2.4 ADD
2.5 COPY
2.6 CMD
2.7 ENTRYPOINT
2.8 LABEL
2.9 ENV
2.10 EXPOSE
2.11 VOLUME
2.12 WORKDIR
2.13 USER
2.14 ARG
2.15 ONBUILD
3、制作镜像
编写dockerfile文件
构建镜像
4、实战
使用Dockerfile搭建LNMP平台部署Discuz论坛
1. 准备工作
先拉取三个基础镜像
文件结构确认
2. 创建MySQL容器
Dockerfile (mysql/Dockerfile)
3. 创建PHP容器
Dockerfile (php/Dockerfile)
4. 创建Nginx容器
Dockerfile (nginx/Dockerfile)
5. 创建docker-compose.yml
6. 配置Discuz
7. 验证服务
注意事项
十、Docker私有仓库
1、 概述
Harbor介绍
Harbor仓库结构
harbor依赖组件
harbor组件数据流向
2、 Harbor架构部署
安装方式
离线安装步骤
推荐系统配置
离线部署流程
软件要求
系统环境要求
验证compose
安装harbor
harbor的启停
harbor访问
浏览器登录 : admin/密码
命令行登录
3、Harbor的使用
总结
一、 Docker概述
Docker简介
Docker,翻译过来就是码头工人
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可抑制的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器完全使用沙盒机制,相互之间不会存在任何接口。几乎没有性能开销,可以很容易的在机器和数据中心运行。最重要的是,他们不依赖于任何语言、框架或者包装系统。
Docker是dotCloud公司开源的一个基于LXC的高级容器引擎,源码托管在Github上,基于go语言并且遵从Apache2.0协议开源。
LXC主要通过Kernel的namespace实现每个用户实例之间的项目隔离,通过cgroup实现对资源的配额和调度。
docker官网: https://www.docker.com
Docker版本演化与技术特征更新
1、Docker发展历程概述
Docker自2013年诞生以来,经历了从简单的容器工具到完整的容器生态系统的演变过程。其版本演化可以分为四个主要阶段:
1. 初创期(2013-2014)
-
2013年3月:Docker 0.1.0发布,基于LXC技术
-
2014年6月:Docker 1.0发布,标志着生产就绪
2. 成长期(2015-2016)
-
引入Swarm集群管理
-
建立开放容器倡议(OCI)标准
3. 成熟期(2017-2019)
-
采用新的版本命名方案(YY.MM)
-
分化为CE(社区版)和EE(企业版)
4. 现代期(2020至今)
-
深度集成Kubernetes
-
专注于开发者体验和安全增强
2、重大版本技术特征更新
Docker 1.0 (2014年6月)
-
核心技术:从LXC转向libcontainer
-
镜像格式:建立分层存储体系
-
网络模型:基础桥接网络支持
Docker 1.12 (2016年7月)
-
Swarm模式:内置容器编排功能
-
服务发现:内置DNS服务
-
安全增强:TLS加密通信
Docker 17.03 (2017年3月)
-
版本改革:采用YY.MM版本号
-
多架构支持:ARM平台正式支持
-
插件系统:卷和网络插件标准化
Docker 18.09 (2018年11月)
-
BuildKit:实验性下一代构建引擎
-
Rootless模式:非root用户运行容器
-
cgroups v2:初步支持新控制组系统
Docker 19.03 (2019年7月)
-
GPU支持:NVIDIA GPU容器化
-
性能优化:containerd集成改进
-
Windows容器:完善WSL2支持
Docker 20.10 (2020年12月)
-
BuildKit默认:取代经典构建引擎
-
Compose V2:重写为Go版本
-
检查点/恢复:实验性容器状态保存
Docker 23.0 (2023年1月)
-
构建革新:完全移除经典构建引擎
-
镜像管理:改进垃圾回收机制
-
安全扫描:内置漏洞扫描工具
3、关键技术演进路线
1. 容器运行时演进
-
libcontainer → runc → containerd
-
符合OCI运行时规范
-
gVisor、Kata Containers等安全容器支持
2. 构建系统革新
-
传统构建 → BuildKit
-
多阶段构建支持
-
构建缓存优化和并行构建
3. 网络模型发展
-
基础桥接网络 → overlay网络
-
Macvlan/IPvlan支持
-
服务网格集成能力
4. 存储驱动优化
-
AUFS → overlay2
-
快照和存储配额管理
-
卷插件生态系统
5. 安全增强路径
-
用户命名空间隔离
-
Rootless容器模式
-
内容信任和镜像签名
4、当前技术趋势
-
云原生集成:与Kubernetes深度整合
-
开发者体验:简化本地开发工作流
-
安全强化:默认安全配置和策略
-
性能优化:资源利用率和启动速度
-
多平台支持:ARM、RISC-V等架构
Docker容器技术与虚拟机的区别
相同点:docker容器技术和虚拟机技术,都是虚拟化技术。
不同点:
-
虚拟机技术:
-
docker容器技术:
通过图片,我们很明显的看到docker有着比虚拟机更少的抽象层。 由于docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。所以docker效率比虚拟机效率高。达到了秒级启动的地步。
Docker相较于VM的优点
-
比VM小、快,Docker容器的尺寸减小相比于整个虚拟机大大简化了分布到云和分发时间的开销。Docker启动一个容器实例时间仅仅需要几秒钟。
-
Docker是一个开放的平台,构建、发布和运行分布式应用程序。
-
开发人员不需要关注具体是哪个Linux操作系统。
-
Google、微软(azure)、亚马逊(AWS)、IBM等都支持docker。
-
Docker支持Unix/Linux操作系统,也支持Windows和Mac。
-
一次封装,到处运行
Docker局限性
Docker用于应用程序时是最有用的,但并不包含数据。日志、数据库等通常放在Docker容器外。一个容器的镜像通常都很小,不用存储大量数据,存储可以通过外部挂载等方式使用,比如:NFS、ipsan、MFS、ceph等 ,或者docker -v 命令进行映射磁盘。 总之,docker只用于计算,存储交给别人。
Docker通常用于如下场景
-
web应用的自动化打包和发布;
-
自动化测试和持续集成、发布;
-
在服务型环境中部署和调整数据库或其他的后台应用;
-
从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境。
二、 Docker 架构
Docker 包括三个基本概念
-
镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。
-
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
-
仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
Docker 容器通过 Docker 镜像来创建。
三、 Docker安装
1、使用官方安装脚本自动安装
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
2、手动安装
#rocky8 安装 yum remove runc -y yum install -y yum-utils yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install -y docker-ce
3、启动 Docker
[root@docker ~]# systemctl start docker ##通过运行 hello-world 镜像来验证是否正确安装了 Docker Engine-Community 。 [root@docker ~]# docker run hello-world
4、卸载 Docker
##删除安装包 [root@docker ~]# yum remove docker-ce ##删除镜像、容器、配置文件等内容 [root@docker ~]# rm -rf /var/lib/docker
四、 Docker 镜像加速
国内从 DockerHub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。Docker 官方和国内很多云服务商都提供了国内加速器服务,
##编辑配置文件 [root@docker ~]# cat /etc/docker/daemon.json { \"registry-mirrors\": [ \"https://0vmzj3q6.mirror.aliyuncs.com\", \"https://docker.m.daocloud.io\", \"https://mirror.baidubce.com\", \"https://dockerproxy.com\", \"https://mirror.iscas.ac.cn\", \"https://huecker.io\", \"https://dockerhub.timeweb.cloud\", \"https://noohub.ru\", \"https://vlgh0kqj.mirror.aliyuncs.com\" ] } ##重新启动服务 [root@docker ~]# systemctl daemon-reload [root@docker ~]# systemctl restart docker
五、/etc/docker/daemon.json 配置文件
1. 通用配置
**debug**: 启用调试模式(true/false)。**log-level**: 设置日志级别(debug、info、warn、error、fatal)。**hosts**: 指定 Docker 监听的地址(如 unix:///var/run/docker.sock、tcp://0.0.0.0:2375)。**data-root**: 设置 Docker 存储镜像和容器的根目录(如 /var/lib/docker)。**exec-root**: 设置 Docker 运行时状态文件的根目录(如 /var/run/docker)。**pidfile**: 指定 Docker 守护进程的 PID 文件路径(如 /var/run/docker.pid)。
2. 存储驱动
**storage-driver**: 设置存储驱动(如 overlay2、aufs、btrfs、zfs)。**storage-opts**: 存储驱动的额外选项(如 overlay2 的 size 限制)。
3. 网络配置
**bip**: 设置 Docker 网桥的 IP 地址(如 172.17.0.1/16)。**default-gateway**: 设置容器的默认网关。**default-gateway-v6**: 设置 IPv6 默认网关。**dns**: 设置容器的默认 DNS 服务器(如 [\"8.8.8.8\", \"8.8.4.4\"])。**dns-opts**: 设置 DNS 选项(如 [\"ndots:2\"])。**dns-search**: 设置 DNS 搜索域(如 [\"example.com\"])。**fixed-cidr**: 设置 Docker 网桥的子网(如 172.17.0.0/24)。**fixed-cidr-v6**: 设置 IPv6 子网。**ipv6**: 启用 IPv6 支持(true/false)。**mtu**: 设置 Docker 网络的 MTU(如 1500)。**bridge**: 绑定 Docker 到自定义网桥(如 docker0)。
4. 镜像和 Registry 配置
**insecure-registries**: 允许访问非 HTTPS 的私有 Registry(如 [\"myregistry:5000\"])。**registry-mirrors**: 设置镜像加速器(如 [\"https://mirror.example.com\"])。**allow-nondistributable-artifacts**: 允许推送非分发镜像到特定 Registry。
5. 安全配置
**tlsverify**: 强制 TLS 验证(true/false)。**tlscacert**: 指定 CA 证书路径(如 /etc/docker/ca.pem)。**tlscert**: 指定 Docker 服务端证书路径(如 /etc/docker/server-cert.pem)。**tlskey**: 指定 Docker 服务端私钥路径(如 /etc/docker/server-key.pem)。**userns-remap**: 启用用户命名空间隔离(如 default 或 uid:gid)。**default-ulimits**: 设置容器的默认资源限制(如 nofile=65535)。
6. 日志配置
**log-driver**: 设置容器日志驱动(如 json-file、syslog、journald)。**log-opts**: 日志驱动的额外选项(如 max-size=10m、max-file=3)。
7. 其他配置
**features**: 启用实验性功能(如 {\"buildkit\": true})。**max-concurrent-downloads**: 设置镜像下载并发数(如 3)。**max-concurrent-uploads**: 设置镜像上传并发数(如 5)。**shutdown-timeout**: 设置 Docker 守护进程关闭超时(如 15,单位:秒)。**live-restore**: 允许容器在 dockerd 重启时保持运行(true/false)。**icc**: 启用容器间通信(true/false,默认 true)。**iptables**: 启用 iptables 规则管理(true/false,默认 true)。**ip-forward**: 启用 IP 转发(true/false,默认 true)。
示例 daemon.json
{ // 通用配置 \"debug\": false, // 启用调试模式(默认 false) \"log-level\": \"info\", // 日志级别(debug, info, warn, error, fatal) \"hosts\": [\"unix:///var/run/docker.sock\", \"tcp://0.0.0.0:2376\"], // 监听地址 \"data-root\": \"/var/lib/docker\", // Docker 数据存储目录 \"exec-root\": \"/var/run/docker\", // 运行时状态文件目录 \"pidfile\": \"/var/run/docker.pid\", // PID 文件路径 // 存储配置 \"storage-driver\": \"overlay2\", // 存储驱动(推荐 overlay2) \"storage-opts\": [ // 存储驱动选项 \"overlay2.override_kernel_check=true\" ], // 网络配置 \"bip\": \"172.17.0.1/16\", // Docker 网桥 IP \"default-gateway\": \"172.17.0.1\", // 容器默认网关 \"default-gateway-v6\": \"2001:db8::1\",// IPv6 默认网关 \"dns\": [\"8.8.8.8\", \"8.8.4.4\"], // 容器 DNS 服务器 \"dns-opts\": [\"ndots:2\"], // DNS 选项 \"dns-search\": [\"example.com\"], // DNS 搜索域 \"fixed-cidr\": \"172.17.0.0/24\", // 固定子网 \"fixed-cidr-v6\": \"2001:db8::/64\", // IPv6 固定子网 \"ipv6\": false,// 是否启用 IPv6 \"mtu\": 1500, // 网络 MTU \"bridge\": \"docker0\", // 自定义网桥 // Registry 和镜像配置 \"insecure-registries\": [\"myregistry:5000\"], // 非 HTTPS Registry \"registry-mirrors\": [\"https://mirror.example.com\"], // 镜像加速器 \"allow-nondistributable-artifacts\": [\"myregistry:5000\"], // 允许非分发镜像 // 安全配置 \"tlsverify\": true, // 强制 TLS 验证 \"tlscacert\": \"/etc/docker/ca.pem\", // CA 证书路径 \"tlscert\": \"/etc/docker/server-cert.pem\", // 服务端证书 \"tlskey\": \"/etc/docker/server-key.pem\", // 服务端私钥 \"userns-remap\": \"default\", // 用户命名空间隔离 \"default-ulimits\": { // 默认资源限制 \"nofile\": { \"Name\": \"nofile\", \"Hard\": 65535, \"Soft\": 65535 } }, // 日志配置 \"log-driver\": \"json-file\", // 容器日志驱动 \"log-opts\": { // 日志选项 \"max-size\": \"10m\", \"max-file\": \"3\" }, // 实验性功能 \"features\": { \"buildkit\": true // 启用 BuildKit(默认 true) }, // 性能优化 \"max-concurrent-downloads\": 3, // 镜像下载并发数 \"max-concurrent-uploads\": 5, // 镜像上传并发数 \"shutdown-timeout\": 15, // 关闭超时(秒) // 容器运行时选项 \"live-restore\": true, // 守护进程重启时保持容器运行 \"icc\": true, // 容器间通信(默认 true) \"iptables\": true, // 启用 iptables(默认 true) \"ip-forward\": true, // 启用 IP 转发(默认 true) \"userland-proxy\": true // 使用用户态代理(默认 true)}
六、 Docker命令
docker命令帮助
[root@docker ~]# docker --help Usage: docker [OPTIONS] COMMAND A self-sufficient runtime for containers Common Commands: run Create and run a new container from an image exec Execute a command in a running container ps List containers build Build an image from a Dockerfile pull Download an image from a registry push Upload an image to a registry images List images login Log in to a registry logout Log out from a registry search Search Docker Hub for images version Show the Docker version information info Display system-wide information Management Commands: builder Manage builds buildx* Docker Buildx (Docker Inc., v0.11.2) checkpoint Manage checkpoints compose* Docker Compose (Docker Inc., v2.21.0) container Manage containers context Manage contexts image Manage images manifest Manage Docker image manifests and manifest lists network Manage networks plugin Manage plugins system Manage Docker trust Manage trust on Docker images volume Manage volumes Swarm Commands: config Manage Swarm configs node Manage Swarm nodes secret Manage Swarm secrets service Manage Swarm services stack Manage Swarm stacks swarm Manage Swarm Commands: attach Attach local standard input, output, and error streams to a running container commit Create a new image from a container\'s changes cp Copy files/folders between a container and the local filesystem create Create a new container diff Inspect changes to files or directories on a container\'s filesystem events Get real time events from the server export Export a container\'s filesystem as a tar archive history Show the history of an image import Import the contents from a tarball to create a filesystem image inspect Return low-level information on Docker objects kill Kill one or more running containers load Load an image from a tar archive or STDIN logs Fetch the logs of a container pause Pause all processes within one or more containers port List port mappings or a specific mapping for the container rename Rename a container restart Restart one or more containers rm Remove one or more containers rmi Remove one or more images save Save one or more images to a tar archive (streamed to STDOUT by default) start Start one or more stopped containers stats Display a live stream of container(s) resource usage statistics stop Stop one or more running containers tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE top Display the running processes of a container unpause Unpause all processes within one or more containers update Update configuration of one or more containers wait Block until one or more containers stop, then print their exit codes Global Options: --config string Location of client config files (default \"/root/.docker\") -c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with \"docker context use\") -D, --debug Enable debug mode -H, --host list Daemon socket to connect to -l, --log-level string Set the logging level (\"debug\", \"info\", \"warn\", \"error\", \"fatal\") (default \"info\") --tls Use TLS; implied by --tlsverify --tlscacert string Trust certs signed only by this CA (default \"/root/.docker/ca.pem\") --tlscert string Path to TLS certificate file (default \"/root/.docker/cert.pem\") --tlskey string Path to TLS key file (default \"/root/.docker/key.pem\") --tlsverify Use TLS and verify the remote -v, --version Print version information and quit Run \'docker COMMAND --help\' for more information on a command. For more help on how to use Docker, head to https://docs.docker.com/go/guides/
docker常用子命令
docker管理子命令
swarm集群管理子命令
docker容器管理子命令
docker全局选项
七、 docker镜像管理
概述
docker镜像是docker
的核心概念之一,它是用来构建和运行docker容器的模板。
类似于虚拟机镜像,可以理解为一个面向Docker引擎的只读模板,包含了文件系统。 例如:一个镜像可以包含一个完整的Ubuntu操作系统环境,可以把它称为一个Ubuntu镜像。镜像也可以安装了Apache应用程序,可以把它称为一个Apache镜像。 镜像是创建Docker容器的基础。通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来创建和更新现有的镜像,用户甚至可以从网上下载一个已经做好的应用镜像,并通过简单的命令就可以直接使用。
镜像自身是只读的。容器从镜像启动的时候,Docker会在镜像的最上层创建一个可写层,镜像本身将保持不变。
核心概念
镜像的分层
docker镜像分为四层,如下图所示:
镜像分层后的优势
-
共享宿主机的kernel
-
base镜像提供的是最小的Linux发行版(base镜像:不同发行版的/文件系统)
-
同一docker主机支持运行多种Linux发行版
-
采用分层结构的最大好处是:共享资源
-
镜像通过分层,如果本地已经有了,不管这一层属于哪个镜像,因为每一层都有独立的标识(都是唯一的),只要docker判断有这一层,那它就不会进行重复的拉取。包括在上传仓库的时候也是一样的,仓库内存储时也是按照层来存储的,如果远程仓库有这一层了,就不需要重复上传了,节省了带宽。
镜像的特点
docker使用 Copy-on-Write 的机制(可写容器层,cow),当我们想保存一个数据的时候,由于镜像是只读的,当我们创建容器时,是在镜像层的上面创建一个可写容器层,所有对容器的修改都会放置在可写容器层上,只要这个容器不被释放,这个数据一直存在,除非把这个容器删掉。如果想保存,把可写容器层进行打包,即把它创建成一个镜像层,一旦成为镜像层它就变成只读模式了(最多127层)。
镜像层数量可能会很多,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /a,上层的 /a会覆盖下层的 /a,也就是说用户只能访问到上层中的文件 /a。在容器层中,用户看到的是一个叠加之后的文件系统。
添加文件:在容器中创建文件时,新文件被添加到容器层中;
读取文件:在容器中读取某个文件时,Docker会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后打开并读入内存;
修改文件:在容器中修改已存在的文件时,Docker 会从上往下依次在各镜像层中查找此文件。一旦找到,立即将其复制到容器层,然后修改之;
删除文件:在容器中删除文件时,Docker 也是从上往下依次在镜像层中查找此文件。找到后,会在容器层中记录下此删除操作;
只有当需要修改时才复制一份数据,这种特性被称作Copy-on-Write。可见,容器层保存的是镜像变化的部分,不会对镜像本身进行任何修改。这样就解释了我们前面提出的问题:容器层记录对镜像的修改,所有镜像层都是只读的,不会被容器修改,所以镜像可以被多个容器共享。
镜像的表示
镜像的表示分为四部分
-
红色的部分是镜像中心域名
-
黄色的部分是镜像命名空间,我们可以根据命名空间进行权限控制等操作
-
绿色是镜像的名称,每个镜像有一个版本(即标签)。
-
蓝色表示版本,laest是最新版
Docker官方的镜像不需要镜像中心的域名,有一些镜像可以省略命名空间。
镜像制作方式
镜像管理命令
docker images 显示解析
[root@docker ~]# docker images 仓库名 标签 镜像ID 创建时间 镜像大小 REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest feb5d9fea6a5 2 years ago 13.3kB
docker history命令
命令语法:
docker history [OPTIONS] IMAGE
实战:
[root@docker ~]# docker history nginx:latest IMAGE CREATED CREATED BY SIZE COMMENT2cd1d97f893f 3 weeks ago CMD [\"nginx\" \"-g\" \"daemon off;\"] 0B buildkit.dockerfile.v0 3 weeks ago STOPSIGNAL SIGQUIT 0B buildkit.dockerfile.v0 3 weeks ago EXPOSE map[80/tcp:{}] 0B buildkit.dockerfile.v0 3 weeks ago ENTRYPOINT [\"/docker-entrypoint.sh\"] 0B buildkit.dockerfile.v0 3 weeks ago COPY 30-tune-worker-processes.sh /docker-ent… 4.62kB buildkit.dockerfile.v0 3 weeks ago COPY 20-envsubst-on-templates.sh /docker-ent… 3.02kB buildkit.dockerfile.v0 3 weeks ago COPY 15-local-resolvers.envsh /docker-entryp… 389B buildkit.dockerfile.v0 3 weeks ago COPY 10-listen-on-ipv6-by-default.sh /docker… 2.12kB buildkit.dockerfile.v0 3 weeks ago COPY docker-entrypoint.sh / # buildkit 1.62kB buildkit.dockerfile.v0 3 weeks ago RUN /bin/sh -c set -x && groupadd --syst… 117MB buildkit.dockerfile.v0 3 weeks ago ENV DYNPKG_RELEASE=1~bookworm 0B buildkit.dockerfile.v0 3 weeks ago ENV PKG_RELEASE=1~bookworm 0B buildkit.dockerfile.v0 3 weeks ago ENV NJS_RELEASE=1~bookworm 0B buildkit.dockerfile.v0 3 weeks ago ENV NJS_VERSION=0.9.0 0B buildkit.dockerfile.v0 3 weeks ago ENV NGINX_VERSION=1.29.0 0B buildkit.dockerfile.v0 3 weeks ago LABEL maintainer=NGINX Docker Maintainers <d… 0B buildkit.dockerfile.v0 3 weeks ago # debian.sh --arch \'amd64\' out/ \'bookworm\' \'… 74.8MB debuerreotype 0.15
DockerHub
开源应用程序非常多,打包这些应用往往是重复的劳动。为了避免这些重复劳动,人们就会将自己打包的应用镜像,例如Redis、MySQL镜像放到网络上,共享使用,就像GitHub的代码共享一样。
DockerHub:DockerHub是一个官方的Docker镜像的托管平台。这样的平台称为Docker Registry。
国内也有类似于DockerHub 的公开服务,比如 网易云镜像服务、阿里云镜像库等。
八、容器管理
概述
Docker容器(Container)类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。 容器是从镜像创建的应用运行实例,可以将其启动、开始、停止、删除,而这些容器都是相互隔离、互不可见的。 可以把容器看做一个简易版的Linux系统环境(包括root用户权限、进程空间、用户空间和网络空间等),以及运行在其中的应用程序打包而成的应用盒子。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。
因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户 ID 空间。
容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。
容器操作命令
docker run 命令
命令语法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
--add-host 列表 添加自定义主机到 IP 的映射(主机:IP) --annotation 映射 向容器添加注释(传递给 OCI 运行时) (默认映射列表为空 []) -a, --attach 列表 附加到标准输入(STDIN)、标准输出(STDOUT)或标准错误(STDERR) --blkio-weight 无符号 16 位整数 块 I/O(相对权重),取值范围在 10 到 1000 之间,或设为 0 禁用 (默认值为 0) --blkio-weight-device 列表 块 I/O 权重(相对设备权重)(默认列表为空 []) --cap-add 列表 添加 Linux 功能 --cap-drop 列表 移除 Linux 功能 --cgroup-parent 字符串 容器可选的父 cgroup --cgroupns 字符串 要使用的 cgroup 命名空间(主机 | 私有) \' 主机 \':在 Docker 主机的 cgroup 命名空间中运行容器 \' 私有 \':在容器自身的私有 cgroup 命名空间中运行容器 \'\':使用守护进程上默认的 cgroupns-mode 选项所配置的 cgroup 命名空间(默认情况) --cidfile 字符串 将容器 ID 写入文件 --cpu-period 整数 限制 CPU 的 CFS(完全公平调度器)周期 --cpu-quota 整数 限制 CPU 的 CFS(完全公平调度器)配额 --cpu-rt-period 整数 以微秒为单位限制 CPU 实时周期 --cpu-rt-runtime 整数 以微秒为单位限制 CPU 实时运行时间 -c, --cpu-shares 整数 CPU 份额(相对权重) --cpus 十进制数 CPU 数量 --cpuset-cpus 字符串 允许执行的 CPU(格式如 0-3、0,1) --cpuset-mems 字符串 允许执行的内存(格式如 0-3、0,1) -d, --detach 在后台运行容器并打印容器 ID --detach-keys 字符串 覆盖用于分离容器的按键序列 --device 列表 向容器添加主机设备 --device-cgroup-rule 列表 向 cgroup 允许的设备列表中添加规则 --device-read-bps 列表 限制从设备读取的速率(每秒字节数)(默认列表为空 []) --device-read-iops 列表 限制从设备读取的速率(每秒 I/O 次数)(默认列表为空 []) --device-write-bps 列表 限制向设备写入的速率(每秒字节数)(默认列表为空 []) --device-write-iops 列表 限制向设备写入的速率(每秒 I/O 次数)(默认列表为空 []) --disable-content-trust 跳过镜像验证(默认值为真) --dns 列表 设置自定义 DNS 服务器 --dns-option 列表 设置 DNS 选项 --dns-search 列表 设置自定义 DNS 搜索域 --domainname 字符串 容器的 NIS 域名 --entrypoint 字符串 覆盖镜像的默认入口点(ENTRYPOINT) -e, --env 列表 设置环境变量 --env-file 列表 读取包含环境变量的文件 --expose 列表 暴露一个端口或端口范围 --gpus GPU 请求 要添加到容器的 GPU 设备(\'all\' 表示传递所有 GPU) --group-add 列表 添加要加入的其他组 --health-cmd 字符串 用于检查健康状况的命令 --health-interval 持续时间 运行检查的时间间隔(毫秒 | 秒 | 分 | 时)(默认值为 0 秒) --health-retries 整数 判定为不健康所需的连续失败次数 --health-start-interval 持续时间 在启动期间运行检查的时间间隔(毫秒 | 秒 | 分 | 时) (默认值为 0 秒) --health-start-period 持续时间 容器初始化的启动周期,在开始健康检查失败次数倒计时之前(毫秒 | 秒 | 分 | 时) (默认值为 0 秒) --health-timeout 持续时间 允许一次健康检查运行的最长时间(毫秒 | 秒 | 分 | 时)(默认值为 0 秒) --help 打印使用说明 -h, --hostname 字符串 容器主机名 --init 在容器内运行一个初始化程序,用于转发信号并回收进程 -i, --interactive 即使未附加,也保持标准输入(STDIN)打开 --ip 字符串 IPv4 地址(例如,172.30.100.104) --ip6 字符串 IPv6 地址(例如,2001:db8::33) --ipc 字符串 要使用的进程间通信(IPC)模式 --isolation 字符串 容器隔离技术 --kernel-memory 字节数 内核内存限制 -l, --label 列表 在容器上设置元数据 --label-file 列表 读取包含标签的以行分隔的文件 --link 列表 添加到另一个容器的链接 --link-local-ip 列表 容器的 IPv4/IPv6 链路本地地址 --log-driver 字符串 容器的日志驱动程序 --log-opt 列表 日志驱动程序选项 --mac-address 字符串 容器的 MAC 地址(例如,92:d0:c6:0a:29:33) -m, --memory 字节数 内存限制 --memory-reservation 字节数 内存软限制 --memory-swap 字节数 交换空间限制,等于内存加上交换空间:\'-1\' 表示启用无限制交换 --memory-swappiness 整数 调整容器内存交换倾向(取值范围 0 到 100)(默认值为 - 1) --mount 挂载 将文件系统挂载附加到容器 --name 字符串 为容器指定一个名称 --network 网络 将容器连接到网络 --network-alias 列表 为容器添加网络作用域的别名 --no-healthcheck 禁用任何容器指定的健康检查 --oom-kill-disable 禁用内存溢出(OOM)杀手 --oom-score-adj 整数 调整主机的内存溢出(OOM)偏好(取值范围 - 1000 到 1000) --pid 字符串 要使用的进程 ID(PID)命名空间 --pids-limit 整数 调整容器的进程数量限制(设为 - 1 表示无限制) --platform 字符串 如果服务器支持多平台,则设置平台 --privileged 赋予此容器扩展权限 -p, --publish 列表 将容器的端口发布到主机 -P, --publish-all 将所有暴露的端口发布到随机端口 --pull 字符串 在运行前拉取镜像(“总是”“缺失时”“从不”)(默认值为 “缺失时”) -q, --quiet 抑制拉取输出 --read-only 将容器的根文件系统挂载为只读 --restart 字符串 当容器退出时应用的重启策略(默认值为 “不重启”) --rm 容器退出时自动删除容器 --runtime 字符串 此容器要使用的运行时 --security-opt 列表 安全选项 --shm-size 字节数 /dev/shm 的大小 --sig-proxy 将接收到的信号代理到进程(默认值为真) --stop-signal 字符串 用于停止容器的信号 --stop-timeout 整数 停止容器的超时时间(以秒为单位) --storage-opt 列表 容器的存储驱动程序选项 --sysctl 映射 Sysctl 选项(默认映射为空 []) --tmpfs 列表 挂载临时文件系统(tmpfs)目录 -t, --tty 分配一个伪终端(TTY) --ulimit 资源限制 资源限制选项(默认列表为空 []) -u, --user 字符串 用户名或用户 ID(格式:[:]) --userns 字符串 要使用的用户命名空间 --uts 字符串 要使用的主机名与域名系统(UTS)命名空间 -v, --volume 列表 绑定挂载一个卷 --volume-driver 字符串 容器可选的卷驱动程序 --volumes-from 列表 从指定的容器挂载卷 -w, --workdir 字符串 容器内的工作目录
实战:
###[root@docker ~]# docker run -it nginx:latest bashroot@5875b8b4f275:/# exit###[root@docker ~]# docker run -it --rm nginx:latest bashroot@1dfbed9b59c2:/# exit###[root@docker ~]# docker run -d alpine:latest b30dcd128cc673def04fa5b662adf1b58df4f440b06d0a2b23c7ecaec2c5ad4a###[root@docker ~]# docker run -itd alpine:latest shfb8bb23ed89fbf0ed6ddb36eb7646c2f59a4b17db2c45a4c35bacc77ae017caf###[root@docker ~]# docker run -itd nginx:latest bash280ee47f4a853029b54e3d98a6f49511d9bcfb315366e03d4d6c9dcae35ea711###[root@docker ~]# docker run -itd --hostname=web1 nginx:latest bash00698a21f0c38149deec5d3b33494d2870ee0840c2a15b12f47b4878320c4e36###[root@docker ~]# docker run -itd --hostname=web2 nginx:latest088a44296a06aa9ef125732a9ceceb8e48bb3e5d24f1152275899fab57553074###[root@docker ~]# docker run -itd --hostname=web3 -p 80:80 nginx:latest302506c25894659087323a88ab96e5734cca0021224ebc469fac0fa2f6dc1c61
docker exec命令
命令语法:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
实战:
###[root@docker ~]# docker run -itd alpine:latest shfb8bb23ed89fbf0ed6ddb36eb7646c2f59a4b17db2c45a4c35bacc77ae017caf[root@docker ~]# docker exec -it exciting_cohen sh/ # whoamiroot/ # lsbin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var/ # cd~ # ls~ # exit或者[root@docker ~]# docker exec -it fb sh###[root@docker ~]# docker run -itd nginx:latest bash280ee47f4a853029b54e3d98a6f49511d9bcfb315366e03d4d6c9dcae35ea711[root@docker ~]# docker exec -it 28 bashroot@280ee47f4a85:/# exitexit###[root@docker ~]# docker run -itd --hostname=web1 nginx:latest bash00698a21f0c38149deec5d3b33494d2870ee0840c2a15b12f47b4878320c4e36[root@docker ~]# docker exec -it 00 bashroot@web1:/# lsroot@web1:/# exit
docker logs命令
命令语法:
docker logs [OPTIONS] cantinerName
实战:
[root@docker ~]# docker logs 47/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d//docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh/docker-entrypoint.sh: Configuration complete; ready for start up2025/08/05 16:50:22 [notice] 1#1: using the \"epoll\" event method2025/08/05 16:50:22 [notice] 1#1: nginx/1.29.02025/08/05 16:50:22 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14+deb12u1) 2025/08/05 16:50:22 [notice] 1#1: OS: Linux 4.18.0-553.el8_10.x86_642025/08/05 16:50:22 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:10485762025/08/05 16:50:22 [notice] 1#1: start worker processes2025/08/05 16:50:22 [notice] 1#1: start worker process 292025/08/05 16:50:22 [notice] 1#1: start worker process 302025/08/05 16:50:22 [notice] 1#1: start worker process 312025/08/05 16:50:22 [notice] 1#1: start worker process 322025/08/05 16:50:22 [notice] 1#1: start worker process 332025/08/05 16:50:22 [notice] 1#1: start worker process 342025/08/05 16:50:22 [notice] 1#1: start worker process 352025/08/05 16:50:22 [notice] 1#1: start worker process 36
docker rename命令
命令语法:
docker rename CONTAINER NEW_NAME
实战:
[root@docker ~]# docker rename 3f web1[root@docker ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES3f3a2215b1d0 nginx:latest \"/docker-entrypoint.…\" 2 minutes ago Created web1d388e2b0c2f3 alpine:latest \"sh\" 4 minutes ago Up 4 minutes pedantic_jemison
docker top命令
命令语法:
docker top CONTAINER [ps OPTIONS]
实战:
[root@docker ~]# docker top 30UID PID PPID C STIME TTY TIME CMDroot 97016 96957 0 01:09 pts/0 00:00:00 nginx: master process nginx -g daemon off;101 97060 97016 0 01:09 pts/0 00:00:00 nginx: worker process101 97061 97016 0 01:09 pts/0 00:00:00 nginx: worker process101 97062 97016 0 01:09 pts/0 00:00:00 nginx: worker process101 97063 97016 0 01:09 pts/0 00:00:00 nginx: worker process101 97064 97016 0 01:09 pts/0 00:00:00 nginx: worker process101 97065 97016 0 01:09 pts/0 00:00:00 nginx: worker process101 97066 97016 0 01:09 pts/0 00:00:00 nginx: worker process101 97067 97016 0 01:09 pts/0 00:00:00 nginx: worker process
docker ps 命令
命令语法:
docker ps [OPTIONS]
docker ps -a显示信息解析
容器ID 镜像名称 容器启动时的运行命令 创建时间 容器当前的状态 容器运行时暴漏的端口 容器名称 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7df4661fb5d1 hello-world \"/hello\" 7 minutes ago Exited (0) 7 minutes ago happy_hermann
docker rm 命令
命令语法:
docker rm [OPTIONS] CONTAINER [CONTAINER...]
实战:
[root@docker ~]# docker rm -f `docker ps -qa`476fe1dbeccc121b95ca3dfc088a44296a0600698a21f0c3280ee47f4a85fb8bb23ed89f###[root@docker ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUSPORTS NAMESb30dcd128cc6 alpine:latest \"/bin/sh\" 50 seconds ago Exited (0) 49 seconds ago adoring_driscoll[root@docker ~]# docker rm -f b30b30
docker kill 命令
命令语法:
docker kill [OPTIONS] CONTAINER [CONTAINER...]
SIGTERM
:发送终止信号,通常用于请求容器停止运行。SIGKILL
:发送终止信号,强制终止容器,通常用于紧急情况下快速停止容器。SIGINT
:发送中断信号,通常与Ctrl+C
类似,用于触发默认行为。实战:
[root@docker ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESd388e2b0c2f3 alpine:latest \"sh\" 6 seconds ago Up 5 seconds pedantic_jemison[root@docker ~]# docker kill d3d3###[root@docker ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESd388e2b0c2f3 alpine:latest \"sh\" 15 seconds ago Exited (137) 2 seconds ago pedantic_jemison
docker start命令
命令语法:
docker start [OPTIONS] CONTAINER [CONTAINER...]
实战:
[root@docker ~]# docker start d3d3[root@docker ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESd388e2b0c2f3 alpine:latest \"sh\" 29 seconds ago Up Less than a second pedantic_jemison
docker restart命令
命令语法:
docker restart [OPTIONS] CONTAINER [CONTAINER...]
docker stop 命令
命令语法:
docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker inspect命令
docker inspect
命令用于查看 Docker 对象(如容器、镜像、网络等)的详细信息。可以使用 Go 模板语法来筛选和格式化输出内容。以下是一些常用的命令示例:
完整输出:
[root@docker ~]# docker inspect 08[ { \"Id\": \"088a44296a06aa9ef125732a9ceceb8e48bb3e5d24f1152275899fab57553074\", \"Created\": \"2025-08-05T16:29:01.483588762Z\", \"Path\": \"/docker-entrypoint.sh\", \"Args\": [ \"nginx\", \"-g\", \"daemon off;\" ], \"State\": { \"Status\": \"running\", \"Running\": true, \"Paused\": false, \"Restarting\": false, \"OOMKilled\": false, \"Dead\": false, \"Pid\": 71138, \"ExitCode\": 0, \"Error\": \"\", \"StartedAt\": \"2025-08-05T16:29:01.78195585Z\", \"FinishedAt\": \"0001-01-01T00:00:00Z\" }, \"Image\": \"sha256:2cd1d97f893f70cee86a38b7160c30e5750f3ed6ad86c598884ca9c6a563a501\", \"ResolvConfPath\": \"/var/lib/docker/containers/088a44296a06aa9ef125732a9ceceb8e48bb3e5d24f1152275899fab57553074/resolv.conf\", \"HostnamePath\": \"/var/lib/docker/containers/088a44296a06aa9ef125732a9ceceb8e48bb3e5d24f1152275899fab57553074/hostname\", \"HostsPath\": \"/var/lib/docker/containers/088a44296a06aa9ef125732a9ceceb8e48bb3e5d24f1152275899fab57553074/hosts\", \"LogPath\": \"/var/lib/docker/containers/088a44296a06aa9ef125732a9ceceb8e48bb3e5d24f1152275899fab57553074/088a44296a06aa9ef125732a9ceceb8e48bb3e5d24f1152275899fab57553074-json.log\", \"Name\": \"/admiring_saha\", \"RestartCount\": 0, \"Driver\": \"overlay2\", \"Platform\": \"linux\", \"MountLabel\": \"\", \"ProcessLabel\": \"\", \"AppArmorProfile\": \"\", \"ExecIDs\": null, \"HostConfig\": { \"Binds\": null, \"ContainerIDFile\": \"\", \"LogConfig\": { \"Type\": \"json-file\", \"Config\": {} }, \"NetworkMode\": \"bridge\", \"PortBindings\": {}, \"RestartPolicy\": { \"Name\": \"no\", \"MaximumRetryCount\": 0 }, \"AutoRemove\": false, \"VolumeDriver\": \"\", \"VolumesFrom\": null, \"ConsoleSize\": [ 14, 104 ], \"CapAdd\": null, \"CapDrop\": null, \"CgroupnsMode\": \"host\", \"Dns\": [], \"DnsOptions\": [], \"DnsSearch\": [], \"ExtraHosts\": null, \"GroupAdd\": null, \"IpcMode\": \"private\", \"Cgroup\": \"\", \"Links\": null, \"OomScoreAdj\": 0, \"PidMode\": \"\", \"Privileged\": false, \"PublishAllPorts\": false, \"ReadonlyRootfs\": false, \"SecurityOpt\": null, \"UTSMode\": \"\", \"UsernsMode\": \"\", \"ShmSize\": 67108864, \"Runtime\": \"runc\", \"Isolation\": \"\", \"CpuShares\": 0, \"Memory\": 0, \"NanoCpus\": 0, \"CgroupParent\": \"\", \"BlkioWeight\": 0, \"BlkioWeightDevice\": [], \"BlkioDeviceReadBps\": [], \"BlkioDeviceWriteBps\": [], \"BlkioDeviceReadIOps\": [], \"BlkioDeviceWriteIOps\": [], \"CpuPeriod\": 0, \"CpuQuota\": 0, \"CpuRealtimePeriod\": 0, \"CpuRealtimeRuntime\": 0, \"CpusetCpus\": \"\", \"CpusetMems\": \"\", \"Devices\": [], \"DeviceCgroupRules\": null, \"DeviceRequests\": null, \"MemoryReservation\": 0, \"MemorySwap\": 0, \"MemorySwappiness\": null, \"OomKillDisable\": false, \"PidsLimit\": null, \"Ulimits\": [], \"CpuCount\": 0, \"CpuPercent\": 0, \"IOMaximumIOps\": 0, \"IOMaximumBandwidth\": 0, \"MaskedPaths\": [ \"/proc/asound\", \"/proc/acpi\", \"/proc/kcore\", \"/proc/keys\", \"/proc/latency_stats\", \"/proc/timer_list\", \"/proc/timer_stats\", \"/proc/sched_debug\", \"/proc/scsi\", \"/sys/firmware\", \"/sys/devices/virtual/powercap\" ], \"ReadonlyPaths\": [ \"/proc/bus\", \"/proc/fs\", \"/proc/irq\", \"/proc/sys\", \"/proc/sysrq-trigger\" ] }, \"GraphDriver\": { \"Data\": { \"LowerDir\": \"/var/lib/docker/overlay2/1486d2eaaebca310344616c75f7429d3961ec0fc6e5b8451aa87221d51c77130-init/diff:/var/lib/docker/overlay2/11a4b16b84d7b2887226105f843964ee0f39c9a5715b981fd5cd017fe6ddfac8/diff:/var/lib/docker/overlay2/1fbda7bc26ba717e3d91ba1d4a3276630722196d80094bf79b6584527904f98d/diff:/var/lib/docker/overlay2/274a317f37edeac704a33a1941f8c3c90c5931a77e78f70c0997d7f95cb36379/diff:/var/lib/docker/overlay2/1471d408102785b22fc83b20f216920071ad49895a4c2f62250e603cf913071f/diff:/var/lib/docker/overlay2/9e94819c612f8664196a30cac8097d64e7f3e06c5599d10801b1193f3365a7d7/diff:/var/lib/docker/overlay2/e8170f4a18234500e3cb0a9e201e9fe4f8f3b0b89ee939186e14baed0ce387ca/diff:/var/lib/docker/overlay2/52e401d009a0e8d8de96512afcf2a7e5d93f897b7d6e590582477773765c908d/diff\", \"MergedDir\": \"/var/lib/docker/overlay2/1486d2eaaebca310344616c75f7429d3961ec0fc6e5b8451aa87221d51c77130/merged\", \"UpperDir\": \"/var/lib/docker/overlay2/1486d2eaaebca310344616c75f7429d3961ec0fc6e5b8451aa87221d51c77130/diff\", \"WorkDir\": \"/var/lib/docker/overlay2/1486d2eaaebca310344616c75f7429d3961ec0fc6e5b8451aa87221d51c77130/work\" }, \"Name\": \"overlay2\" }, \"Mounts\": [], \"Config\": { \"Hostname\": \"web2\", \"Domainname\": \"\", \"User\": \"\", \"AttachStdin\": false, \"AttachStdout\": false, \"AttachStderr\": false, \"ExposedPorts\": { \"80/tcp\": {} }, \"Tty\": true, \"OpenStdin\": true, \"StdinOnce\": false, \"Env\": [ \"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\", \"NGINX_VERSION=1.29.0\", \"NJS_VERSION=0.9.0\", \"NJS_RELEASE=1~bookworm\", \"PKG_RELEASE=1~bookworm\", \"DYNPKG_RELEASE=1~bookworm\" ], \"Cmd\": [ \"nginx\", \"-g\", \"daemon off;\" ], \"Image\": \"nginx:latest\", \"Volumes\": null, \"WorkingDir\": \"\", \"Entrypoint\": [ \"/docker-entrypoint.sh\" ], \"OnBuild\": null, \"Labels\": { \"maintainer\": \"NGINX Docker Maintainers \" }, \"StopSignal\": \"SIGQUIT\" }, \"NetworkSettings\": { \"Bridge\": \"\", \"SandboxID\": \"87ba7f9e5e6ab6f9e247787d8556972e406ca5288773d029e5e909ba4d6f3f35\", \"SandboxKey\": \"/var/run/docker/netns/87ba7f9e5e6a\", \"Ports\": { \"80/tcp\": null }, \"HairpinMode\": false, \"LinkLocalIPv6Address\": \"\", \"LinkLocalIPv6PrefixLen\": 0, \"SecondaryIPAddresses\": null, \"SecondaryIPv6Addresses\": null, \"EndpointID\": \"ee02ab255c6230eac1eae2ce130392ff4a62cce9254eaac281da9c871822756f\", \"Gateway\": \"172.17.0.1\", \"GlobalIPv6Address\": \"\", \"GlobalIPv6PrefixLen\": 0, \"IPAddress\": \"172.17.0.5\", \"IPPrefixLen\": 16, \"IPv6Gateway\": \"\", \"MacAddress\": \"02:42:ac:11:00:05\", \"Networks\": { \"bridge\": { \"IPAMConfig\": null, \"Links\": null, \"Aliases\": null, \"MacAddress\": \"02:42:ac:11:00:05\", \"NetworkID\": \"73896bca066d5dd8671d271e04dd0173d9a53dad95f8658bcddd7bc3827686f6\", \"EndpointID\": \"ee02ab255c6230eac1eae2ce130392ff4a62cce9254eaac281da9c871822756f\", \"Gateway\": \"172.17.0.1\", \"IPAddress\": \"172.17.0.5\", \"IPPrefixLen\": 16, \"IPv6Gateway\": \"\", \"GlobalIPv6Address\": \"\", \"GlobalIPv6PrefixLen\": 0, \"DriverOpts\": null, \"DNSNames\": null } } } }]
-
查看容器的 IP 地址:
docker inspect -f \'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}\' container_name_or_id
-
查看容器的 MAC 地址:
docker inspect -f \'{{range .NetworkSettings.Networks}}{{.MacAddress}}{{end}}\' container_name_or_id
-
查看容器的挂载点:
docker inspect -f \'{{range .Mounts}}{{.Source}} -> {{.Destination}}{{end}}\' container_name_or_id
-
查看容器的日志路径:
docker inspect -f \'{{.LogPath}}\' container_name_or_id
-
查看容器的镜像名称:
docker inspect -f \'{{.Config.Image}}\' container_name_or_id
-
查看容器的启动命令:
docker inspect -f \'{{.Config.Cmd}}\' container_name_or_id
-
查看容器的端口映射:
docker inspect -f \'{{range $p, $conf := .NetworkSettings.Ports}}{{$p}} -> {{(index $conf 0).HostPort}}{{end}}\' container_name_or_id
-
查看容器的状态:
docker inspect -f \'{{.State.Status}}\' container_name_or_id
-
查看容器的重启策略:
docker inspect -f \'{{.HostConfig.RestartPolicy.Name}}\' container_name_or_id
-
查看容器的标签:
docker inspect -f \'{{range $k, $v := .Config.Labels}}{{$k}}={{$v}} {{end}}\' container_name_or_id
docker tag命令
实战:
[root@docker ~]# docker tag nginx:latest nginxnginx nginx:latest [root@docker ~]# docker tag nginx:latest nginx:v1.29[root@docker ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEalpine latest 9234e8fb04c4 3 weeks ago 8.31MBnginx latest 2cd1d97f893f 3 weeks ago 192MBnginx v1.29 2cd1d97f893f 3 weeks ago 192MBbusybox latest 6d3e4188a38a 10 months ago 4.28MB
docker pause命令
实战:
[root@docker ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESd388e2b0c2f3 alpine:latest \"sh\" 29 seconds ago Up Less than a second pedantic_jemison[root@docker ~]# docker pause d3d3[root@docker ~]# [root@docker ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESd388e2b0c2f3 alpine:latest \"sh\" About a minute ago Up About a minute (Paused) pedantic_jemison
docker unpause命令
实战:
[root@docker ~]# docker unpause d3d3[root@docker ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESd388e2b0c2f3 alpine:latest \"sh\" 2 minutes ago Up About a minute pedantic_jemison
docker port命令
实战:
[root@docker ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES302506c25894 nginx:latest \"/docker-entrypoint.…\" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp, :::80->80/tcp fervent_chandrasekhar3f3a2215b1d0 nginx:latest \"/docker-entrypoint.…\" 3 hours ago Created web1d388e2b0c2f3 alpine:latest \"sh\"3 hours ago Exited (137) 3 hours ago pedantic_jemison[root@docker ~]# docker port 3080/tcp -> 0.0.0.0:8080/tcp -> [::]:80
docker info命令
实战:
[root@docker ~]# docker infoClient: Docker Engine - Community Version: 26.1.3 Context: default Debug Mode: false Plugins: buildx: Docker Buildx (Docker Inc.) Version: v0.14.0 Path: /usr/libexec/docker/cli-plugins/docker-buildx compose: Docker Compose (Docker Inc.) Version: v2.27.0 Path: /usr/libexec/docker/cli-plugins/docker-composeServer: Containers: 5 Running: 4 Paused: 0 Stopped: 1 Images: 3 Server Version: 26.1.3 Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: true Using metacopy: false Native Overlay Diff: true userxattr: false Logging Driver: json-file Cgroup Driver: cgroupfs Cgroup Version: 1 Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog Swarm: inactive Runtimes: io.containerd.runc.v2 runc Default Runtime: runc Init Binary: docker-init containerd version: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89 runc version: v1.1.12-0-g51d5e94 init version: de40ad0 Security Options: seccomp Profile: builtin Kernel Version: 4.18.0-553.el8_10.x86_64 Operating System: Rocky Linux 8.10 (Green Obsidian) OSType: linux Architecture: x86_64 CPUs: 8 Total Memory: 7.486GiB Name: docker ID: 8f1148e7-1782-4c0f-9c2b-7fecf94fb040 Docker Root Dir: /var/lib/docker Debug Mode: false Experimental: false Insecure Registries: 127.0.0.0/8 Registry Mirrors: https://0vmzj3q6.mirror.aliyuncs.com/ https://docker.m.daocloud.io/ https://mirror.baidubce.com/ https://dockerproxy.com/ https://mirror.iscas.ac.cn/ https://huecker.io/ https://dockerhub.timeweb.cloud/ https://noohub.ru/ https://vlgh0kqj.mirror.aliyuncs.com/ Live Restore Enabled: false
利用awk命令切出对docker容器的server监控指标
[root@docker ~]# docker info | awk \'NR>=13{print}\'Server: Containers: 5 Running: 4 Paused: 0 Stopped: 1 Images: 3 Server Version: 26.1.3 Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: true Using metacopy: false Native Overlay Diff: true userxattr: false Logging Driver: json-file Cgroup Driver: cgroupfs Cgroup Version: 1 Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog Swarm: inactive Runtimes: io.containerd.runc.v2 runc Default Runtime: runc Init Binary: docker-init containerd version: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89 runc version: v1.1.12-0-g51d5e94 init version: de40ad0 Security Options: seccomp Profile: builtin Kernel Version: 4.18.0-553.el8_10.x86_64 Operating System: Rocky Linux 8.10 (Green Obsidian) OSType: linux Architecture: x86_64 CPUs: 8 Total Memory: 7.486GiB Name: docker ID: 8f1148e7-1782-4c0f-9c2b-7fecf94fb040 Docker Root Dir: /var/lib/docker Debug Mode: false Experimental: false Insecure Registries: 127.0.0.0/8 Registry Mirrors: https://0vmzj3q6.mirror.aliyuncs.com/ https://docker.m.daocloud.io/ https://mirror.baidubce.com/ https://dockerproxy.com/ https://mirror.iscas.ac.cn/ https://huecker.io/ https://dockerhub.timeweb.cloud/ https://noohub.ru/ https://vlgh0kqj.mirror.aliyuncs.com/ Live Restore Enabled: false
docker create命令
实战:
[root@docker ~]# docker create nginx:latest 476fe1dbeccc2fe0e4d096c9fe4028b7c7022022bfc6dba9c2cc4565c1077b4f[root@docker ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES476fe1dbeccc nginx:latest \"/docker-entrypoint.…\" 5 seconds ago Created vigilant_wilson
docker rmi命令
实战:
[root@docker ~]# docker rmi alpine:latest Untagged: alpine:latestUntagged: alpine@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1Deleted: sha256:9234e8fb04c47cfe0f49931e4ac7eb76fa904e33b7f8576aec0501c085f02516Deleted: sha256:418dccb7d85a63a6aa574439840f7a6fa6fd2321b3e2394568a317735e867d35[root@docker ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZEnginx latest 2cd1d97f893f 3 weeks ago 192MBbusybox latest 6d3e4188a38a 10 months ago 4.28MB
docker save命令
实战:
[root@docker ~]# docker save alpine:latest -o alpine.tar
docker load命令
实战:
[root@docker ~]# docker load -i alpine.tar 418dccb7d85a: Loading layer 8.596MB/8.596MBLoaded image: alpine:latest[root@docker ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZEalpine latest 9234e8fb04c4 3 weeks ago 8.31MBnginx latest 2cd1d97f893f 3 weeks ago 192MBbusybox latest 6d3e4188a38a 10 months ago 4.28MB
docker cp命令
实战:
[root@docker ~]# echo 1111 > index.html[root@docker ~]# docker run -itd --hostname=web3 -p 80:80 nginx:latest302506c25894659087323a88ab96e5734cca0021224ebc469fac0fa2f6dc1c61###[root@docker ~]# docker cp index.html 30:/usr/share/nginx/html/Successfully copied 2.05kB to 30:/usr/share/nginx/html/
浏览器访问192.168.72.122web页面
docker stats命令
实战:
[root@docker ~]# docker stats[root@docker ~]# docker statsCONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS302506c25894 fervent_chandrasekhar 0.00% 8.059MiB / 7.486GiB 0.11% 29.5kB / 12.9kB 8.19kB / 30.7kB 9###[root@docker ~]# docker stats web1CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS3f3a2215b1d0 web1 0.00% 0B / 0B 0.00% 0B / 0B 0B / 0B 0
各列含义解释
docker version命令
实战:
[root@docker ~]# docker version Client: Docker Engine - Community Version: 26.1.3 API version: 1.45 Go version: go1.21.10 Git commit: b72abbb Built: Thu May 16 08:34:39 2024 OS/Arch: linux/amd64 Context: defaultServer: Docker Engine - Community Engine: Version: 26.1.3 API version: 1.45 (minimum version 1.24) Go version: go1.21.10 Git commit: 8e96db1 Built: Thu May 16 08:33:34 2024 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.6.32 GitCommit: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89 runc: Version: 1.1.12 GitCommit: v1.1.12-0-g51d5e94 docker-init: Version: 0.19.0 GitCommit: de40ad0
docker容器创建后的状态
-
0(正常退出)
-
含义:这是最理想的退出状态码,表示容器中的应用程序或进程正常结束。通常是因为应用完成了它的任务,例如一个脚本成功执行完毕,或者一个服务器应用在收到正常的关闭信号后,干净利落地退出。
-
示例:
-
假设你有一个简单的容器,里面运行一个打印 “Hello, World!” 然后退出的脚本。当脚本执行完打印操作后,它会正常退出,此时容器的退出状态码就是 0。
-
对于一个 Web 服务器容器,如果它正确地处理了关闭信号(比如
SIGTERM
),完成了所有正在处理的请求,释放了资源,然后退出,也会返回 0。
-
-
-
1(通用错误)
-
含义:这是一个比较笼统的错误状态码。它可能表示容器内部的应用程序发生了错误,比如应用程序自身的代码出现了问题,如语法错误、运行时错误(例如除以零错误、空指针引用等),或者应用程序无法正确启动。
-
示例:
-
如果容器内运行的是一个 Python 脚本,脚本中有一个语法错误(如缺少冒号、缩进错误等),当尝试运行这个脚本时,容器就会因为脚本无法正确执行而以状态码 1 退出。
-
若一个 Java 应用程序在启动过程中,由于无法加载某个必需的类而抛出异常,导致启动失败,容器也可能以 1 退出。
-
-
-
137(被强制终止)
-
含义:这个状态码通常表示容器被外部信号强制终止。最常见的情况是容器收到了
SIGKILL
信号。这种信号通常是在容器占用过多资源(如内存或 CPU),超出了系统设置的限制,或者系统需要紧急回收资源时发出的。 -
示例:
-
当容器的内存使用量不断增长,超过了 Docker 为其设置的内存限制时,Docker 守护进程可能会发送
SIGKILL
信号来终止容器,此时容器就会以 137 状态码退出。 -
如果在主机系统上使用
docker kill
命令(不带-s
选项,默认发送SIGKILL
)来强制终止容器,容器也会以 137 状态码退出。
-
-
-
139(段错误)
-
含义:当容器内的应用程序发生段错误(segmentation fault)时,容器会以 139 状态码退出。段错误通常是由于程序试图访问它不应该访问的内存区域,比如访问一个已经释放的指针所指向的内存,或者数组越界访问等。
-
示例:
-
在 C 或 C++ 程序中,如果有一个指针没有正确初始化就被用来访问内存,或者一个数组访问超出了其定义的范围,就很可能会导致段错误。当这样的程序在容器中运行时,容器会以 139 状态码退出。
-
-
这些是比较常见的 Docker 容器退出状态码,但实际上还有其他状态码,它们都可以帮助你诊断容器退出的原因。在处理容器退出问题时,结合容器的日志和应用程序本身的特性来分析这些状态码是很重要的
九、Dockerfile文件
1、概述
Dockfile文件是镜像生成的一种方式。Dockerfile 是一个文本格式的配置文件,用户可以使用 Dockerfile 快速创建自定义的镜像。Dockerfile文件中的每一个命令都会创建镜像的一层。
2、常见命令
FROM
:
FROM
:
=
=
=
...
写成一个url,那么ADD就类似于wget命令; 尽量不要把
写成一个文件夹,如果
是一个文件夹了,复制整个目录的内容,包括文件系统元数据 能够将压缩文件自动解压
只能是本地文件,其他用法一致
=
来指定参数;如果用户在build镜像时指定了一个参数没有定义在Dockerfile种,那么将有一个Warning 提示如下: [Warning] One or more build-args [foo] were not consumed. 如果我们给了ARG定义的参数默认值,那么当build镜像时没有指定参数值,将会使用这个默认值
[=
]2.1 FROM
指定基础镜像,必须为第一个命令
格式: FROM FROM : FROM @ 示例: FROM mysql:5.6 注: tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
2.2 MAINTAINER(新版即将废弃)
维护者信息
格式: MAINTAINER 示例: MAINTAINER bertwu MAINTAINER xxx@162.com MAINTAINER bertwu
2.3 RUN
构建镜像时执行的命令
RUN用于在构建镜像时执行命令,其有以下两种命令执行方式: shell执行 格式: RUN exec执行 格式: RUN [\"executable\", \"param1\", \"param2\"] 示例: RUN [\"executable\", \"param1\", \"param2\"] RUN apk update RUN [\"/etc/execfile\", \"arg1\", \"arg1\"] 注:RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像, 可以在构建时指定--no-cache参数,如:docker build --no-cache
2.4 ADD
将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
格式: ADD ... ADD [\"\",... \"\"] 用于支持包含空格的路径 示例: ADD hom* /mydir/ # 添加所有以\"hom\"开头的文件 ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:\"home.txt\" ADD test relativeDir/ # 添加 \"test\" 到 `WORKDIR`/relativeDir/ ADD test /absoluteDir/ # 添加 \"test\" 到 /absoluteDir/
2.5 COPY
功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
2.6 CMD
构建镜像后调用,也就是在容器启动时才进行调用。
格式: CMD [\"executable\",\"param1\",\"param2\"] (执行可执行文件,优先) CMD [\"param1\",\"param2\"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数) CMD command param1 param2 (执行shell内部命令) 示例: CMD echo \"This is a test.\" | wc -l CMD [\"/usr/bin/wc\",\"--help\"] 注:CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
2.7 ENTRYPOINT
配置容器,使其可执行化。配合CMD可省去\"application\",只使用参数。
格式: ENTRYPOINT [\"executable\", \"param1\", \"param2\"] (可执行文件, 优先) ENTRYPOINT command param1 param2 (shell内部命令) 示例: FROM ubuntu ENTRYPOINT [\"ls\", \"/usr/local\"] CMD [\"/usr/local/tomcat\"] 之后,docker run 传递的参数,都会先覆盖cmd,然后由cmd 传递给entrypoint ,做到灵活应用 注:ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT, 而docker run命令中指定的任何参数,都会被当做参数再次传递给CMD。 Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置, 而只执行最后的ENTRYPOINT指令。 通常情况下, ENTRYPOINT 与CMD一起使用,ENTRYPOINT 写默认命令,当需要参数时候 使用CMD传参
2.8 LABEL
用于为镜像添加元数据
格式: LABEL = = = ... 示例: LABEL version=\"1.0\" description=\"这是一个Web服务器\" by=\"IT笔录\" 注: 使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据 之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。
2.9 ENV
设置环境变量
格式: ENV #之后的所有内容均会被视为其的组成部分,因此,一次只能设置一个变量 ENV = ... #可以设置多个变量,每个变量为一个\"=\"的键值对,如果中包含空格,可以使用\\来进行转义,也可以通过\"\"来进行标示;另外,反斜线也可以用于续行 示例: ENV myName John Doe ENV myDog Rex The Dog ENV myCat=fluffy
2.10 EXPOSE
指定于外界交互的端口
格式: EXPOSE [...] 示例: EXPOSE 80 443 EXPOSE 8080 EXPOSE 11211/tcp 11211/udp 注: EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口 如果没有暴露端口,后期也可以通过-p 8080:80方式映射端口,但是不能通过-P形式映射
2.11 VOLUME
用于指定持久化目录(指定此目录可以被挂载出去)
格式: VOLUME [\"/path/to/dir\"] 示例: VOLUME [\"/data\"] VOLUME [\"/var/www\", \"/var/log/apache2\", \"/etc/apache2\" 注:一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能: 1 卷可以容器间共享和重用 2 容器并不一定要和其它容器共享卷 3 修改卷后会立即生效 4 对卷的修改不会对镜像产生影响 5 卷会一直存在,直到没有任何容器在使用它
2.12 WORKDIR
工作目录,类似于cd命令
格式: WORKDIR /path/to/workdir 示例: WORKDIR /a (这时工作目录为/a) WORKDIR b (这时工作目录为/a/b) WORKDIR c (这时工作目录为/a/b/c) 注: 通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。
2.13 USER
指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户
格式: USER user USER user:group USER uid USER uid:gid USER user:gid USER uid:group 示例: USER www 注: 使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。 镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。
2.14 ARG
用于指定传递给构建运行时的变量(给dockerfile传参),相当于构建镜像时可以在外部为里面传参
格式: ARG [=] 示例: ARG site ARG build_user=www From centos:7 ARG parameter VOLUME /usr/share/nginx RUN yum -y install $parameter EXPOSE 80 443 CMD nginx -g \"daemon off;\" # 可以这如下这样灵活传参 docker build --build-arg=parameter=net-tools -t nginx:01 .
2.15 ONBUILD
用于设置镜像触发器
格式: ONBUILD [INSTRUCTION] 示例: ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src 注: ONBUID后面跟指令,当当前的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发
3、制作镜像
编写dockerfile文件
FROM ubuntu RUN apt update && apt install -y gcc make wget && apt install -y libpcre3 libpcre3-dev zlib1g-dev openssl libssl-dev RUN wget http://nginx.org/download/nginx-1.24.0.tar.gz && tar xf nginx-1.24.0.tar.gz && cd nginx-1.24.0 && ./configure --prefix=/usr/local/nginx && make && make install EXPOSE 80 CMD [\"/usr/local/nginx/sbin/nginx\", \"-g\", \"daemon off;\"] # This my first nginx Dockerfile # Version 1.0 # Base images 基础镜像 FROM centos:7 #MAINTAINER 维护者信息 MAINTAINER bertwu #ENV 设置环境变量 ENV PATH /usr/local/nginx/sbin:$PATH #ADD 文件放在当前目录下,拷过去会自动解压 ADD nginx-1.8.0.tar.gz /usr/local/ ADD epel-release-latest-7.noarch.rpm /usr/local/ #RUN 执行以下命令 RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all RUN useradd -s /sbin/nologin -M www #WORKDIR 相当于cd WORKDIR /usr/local/nginx-1.8.0 RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install RUN echo \"daemon off;\" >> /etc/nginx.conf #EXPOSE 映射端口 EXPOSE 80 #CMD 运行以下命令 CMD [\"nginx\"]
构建镜像
docker build命令解析
-
-t, --tag: 给镜像打标签,格式为
name:tag
。docker build -t myimage:latest .
-
-f, --file: 指定 Dockerfile 的路径。
docker build -f /path/to/Dockerfile .
-
--build-arg: 设置构建参数,可以在 Dockerfile 中使用
ARG
指令引用。docker build --build-arg MY_VAR=value .
-
--no-cache: 不使用缓存,强制重新构建所有层。
docker build --no-cache .
-
--pull: 总是尝试拉取最新的基础镜像。
docker build --pull .
-
--compress: 使用 gzip 压缩构建上下文。
docker build --compress .
-
--quiet, -q: 静默模式,只输出镜像 ID。
docker build -q .
-
--target: 指定构建阶段,适用于多阶段构建。
docker build --target mystage .
-
--network: 指定构建过程中使用的网络模式。
docker build --network mynetwork .
-
--label: 给镜像添加元数据标签。
docker build --label version=1.0 .
例如,如果你想构建一个带有特定标签和构建参数的镜像,可以使用以下命令:
docker build -t myimage:1.0 --build-arg MY_VAR=value .
这样,你就可以在 Dockerfile 中使用 ARG MY_VAR
来引用 MY_VAR
的值。
4、实战
使用Dockerfile搭建LNMP平台部署Discuz论坛
1. 准备工作
确保Rocky8系统已安装Docker并启动服务:
sudo systemctl start dockersudo systemctl enable docker
先拉取三个基础镜像
在构建各自的Dockerfile之前,先拉取官方基础镜像
# 拉取MySQL 8.0官方镜像docker pull mysql:8.0# 拉取PHP-FPM 8.1镜像(包含FPM服务)docker pull php:8.1-fpm# 拉取Nginx最新稳定版镜像docker pull nginx:1.25
创建项目目录结构:
mkdir -p ~/lnmp-discuz/{nginx,php,mysql,www}
文件结构确认
~/lnmp-discuz/├── docker-compose.yml├── mysql/│ ├── Dockerfile│ ├── init.sql│ └── data/├── nginx/│ ├── Dockerfile│ └── discuz.conf├── php/│ └── Dockerfile└── www/ └── upload/ (Discuz程序文件)
将Discuz_X3.5_SC_UTF8_20250205.zip解压到www目录:
下载地址:
Discuz!官方网站 - 开放、连接、共赢
unzip Discuz_X3.5_SC_UTF8_20250205.zip -d ~/lnmp-discuz/www/
2. 创建MySQL容器
Dockerfile (mysql/Dockerfile)
FROM mysql:8.0ENV MYSQL_ROOT_PASSWORD=discuz@123ENV MYSQL_DATABASE=discuzENV MYSQL_USER=discuzENV MYSQL_PASSWORD=discuz@123COPY ./init.sql /docker-entrypoint-initdb.d/
创建初始化SQL文件 (mysql/init.sql):
CREATE DATABASE IF NOT EXISTS discuz DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;GRANT ALL PRIVILEGES ON discuz.* TO \'discuz\'@\'%\';FLUSH PRIVILEGES;
构建并运行MySQL容器:
cd ~/lnmp-discuz/mysqldocker build -t discuz-mysql .docker run -d --name discuz-mysql \\ -v ~/lnmp-discuz/mysql/data:/var/lib/mysql \\ -p 3306:3306 \\ discuz-mysql
3. 创建PHP容器
Dockerfile (php/Dockerfile)
FROM php:8.1-fpmRUN apt-get update && apt-get install -y \\ libfreetype6-dev \\ libjpeg62-turbo-dev \\ libpng-dev \\ libzip-dev \\ && docker-php-ext-configure gd --with-freetype --with-jpeg \\ && docker-php-ext-install -j$(nproc) gd pdo pdo_mysql mysqli zip opcache \\ && docker-php-ext-enable mysqliRUN pecl install redis && docker-php-ext-enable redisWORKDIR /var/www/html
构建并运行PHP容器:
cd ~/lnmp-discuz/phpdocker build -t discuz-php .docker run -d --name discuz-php \\ -v ~/lnmp-discuz/www:/var/www/html \\ --link discuz-mysql:mysql \\ discuz-php
4. 创建Nginx容器
Dockerfile (nginx/Dockerfile)
FROM nginx:1.25COPY ./discuz.conf /etc/nginx/conf.d/default.conf
创建Nginx配置文件 (nginx/discuz.conf):
server { listen 80; server_name localhost; root /var/www/html; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \\.php$ { fastcgi_pass php:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~ /\\.ht { deny all; }}
构建并运行Nginx容器:
cd ~/lnmp-discuz/nginxdocker build -t discuz-nginx .docker run -d --name discuz-nginx \\ -v ~/lnmp-discuz/www:/var/www/html \\ -p 80:80 \\ --link discuz-php:php \\ discuz-nginx
5. 创建docker-compose.yml
为了更方便管理,可以创建一个docker-compose.yml文件:
version: \'3.8\'services: mysql: build: ./mysql container_name: discuz-mysql volumes: - ./mysql/data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: discuz@123 MYSQL_DATABASE: discuz MYSQL_USER: discuz MYSQL_PASSWORD: discuz@123 ports: - \"3306:3306\" restart: always php: build: ./php container_name: discuz-php volumes: - ./www:/var/www/html depends_on: - mysql restart: always nginx: build: ./nginx container_name: discuz-nginx volumes: - ./www:/var/www/html ports: - \"80:80\" depends_on: - php restart: always
docker compose命令下载
sudo wget \"https://github.com/docker/compose/releases/download/v2.27.1/docker-compose-linux-x86_64\" -O /usr/local/bin/docker-compose
验证下载
[root@lnmp harbor]# ls -lh /usr/local/bin/docker-compose-rwxr-xr-x. 1 root root 0 8月 7 09:25 /usr/local/bin/docker-compose
使用docker-compose启动所有服务:
docker-compose up -d
6. 配置Discuz
-
确保~/lnmp-discuz/www目录有以下子目录:
- upload/ (Discuz程序文件)
- config/ (配置文件)
- data/ (数据目录)
- uc_client/ (UC客户端)
- uc_server/ (UC服务端)
-
设置目录权限:
chmod -R 777 ~/lnmp-discuz/www/upload/configchmod -R 777 ~/lnmp-discuz/www/upload/datachmod -R 777 ~/lnmp-discuz/www/upload/uc_client/datachmod -R 777 ~/lnmp-discuz/www/upload/uc_server/data
通过浏览器访问 http://本机ip/install/ 完成Discuz安装
7. 验证服务
检查容器运行状态:
docker ps
应该能看到三个容器正常运行:
- discuz-nginx
- discuz-php
- discuz-mysql
注意事项
数据库连接配置:
主机:discuz-mysql或mysql(在PHP容器中使用) 或 服务器IP (在安装界面使用)
用户名:discuz或root
密码:discuz@123
数据表前缀:pre_(默认)
数据库名:discuz
生产环境应考虑:使用更安全的密码配置SSL/TLS加密设置定期备份配置防火墙规则
成功访问Discuz论坛
这样就成功使用Dockerfile搭建了LNMP平台并部署了Discuz论坛。
注意:
mysql8的官方容器镜像,远程登录认证模块有异常需要更改远程用户登录认证方式:
alter user \'admin\'@\'%\' identified with mysql_native_password by \'123.com\';
mysql8的用户赋权需要先创建用户再进行赋权:
create user \'admin\'@\'%\' identified by \'123.com\'; grant all on *.* to \'admin\'@\'%\';
十、Docker私有仓库
1、 概述
Harbor介绍
Harbor是由VMware公司开源的企业级的Docker Registry管理项目,Harbor主要提供Dcoker Registry管理UI,提供的功能包括:基于角色访问的控制权限管理(RBAC)、AD/LDAP集成、日志审核、管理界面、自我注册、镜像复制和中文支持等。Harbor的目标是帮助用户迅速搭建一个企业级的Docker registry服务。它以Docker公司开源的registry为基础,额外提供了如下功能:
-
基于角色的访问控制(Role Based Access Control)
-
基于策略的镜像复制(Policy based image replication)
-
镜像的漏洞扫描(Vulnerability Scanning)
-
AD/LDAP集成(LDAP/AD support)
-
镜像的删除和空间清理(Image deletion & garbage collection)
-
友好的管理UI(Graphical user portal)
-
审计日志(Audit logging)
-
RESTful API
-
部署简单(Easy deployment)
Harbor的所有组件都在Docker中部署,所以Harbor可使用Docker Compose快速部署。需要特别注意:由于Harbor是基于Docker Registry V2版本,所以docker必须大于等于1.10.0版本,docker-compose必须要大于1.6.0版本!
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,流程图如下:
Harbor仓库结构
Harbor的每个组件都是以Docker容器的形式构建的,可以使用Docker Compose来进行部署。如果环境中使用了kubernetes,Harbor也提供了kubernetes的配置文件。Harbor大概需要以下几个容器组成:
-
ui(Harbor的核心服务)
-
log(运行着rsyslog的容器,进行日志收集)
-
mysql(由官方mysql镜像构成的数据库容器)
-
Nginx(使用Nginx做反向代理)
-
registry(官方的Docker registry)
-
adminserver(Harbor的配置数据管理器)
-
jobservice(Harbor的任务管理服务)
-
redis(用于存储session)
harbor依赖组件
-
Nginx(Proxy代理层):Nginx前端代理,主要用于分发前端页面ui访问和镜像上传和下载流量; Harbor的registry,UI,token等服务,通过一个前置的反向代理统一接收浏览器、Docker客户端的请求,并将请求转发给后端不同的服务
-
Registry v2:镜像仓库,负责存储镜像文件; Docker官方镜像仓库, 负责储存Docker镜像,并处理docker push/pull命令。由于我们要对用户进行访问控制,即不同用户对Docker image有不同的读写权限,Registry会指向一个token服务,强制用户的每次docker pull/push请求都要携带一个合法的token, Registry会通过公钥对token进行解密验证
-
Database(MySQL或Postgresql):为core services提供数据库服务,负责储存用户权限、审计日志、Docker image分组信息等数据
-
Core services(Admin Server):这是Harbor的核心功能,主要提供以下服务:
UI:提供图形化界面,帮助用户管理registry上的镜像(image), 并对用户进行授权 webhook:为了及时获取registry 上image状态变化的情况, 在Registry上配置webhook,把状态变化传递给UI模块 Auth服务:负责根据用户权限给每个docker push/pull命令签发token. Docker 客户端向Regiøstry服务发起的请求,如果不包含token,会被重定向到这里,获得token后再重新向Registry进行请求 API: 提供Harbor,RESTful API
-
Replication Job Service:提供多个 Harbor 实例之间的镜像同步功能
-
Log collector:为了帮助监控Harbor运行,负责收集其他组件的log,供日后进行分析
harbor组件数据流向
-
proxy,它是一个nginx前端代理,主要是分发前端页面ui访问和镜像上传和下载流量,上图中通过深蓝色先标识;
-
ui提供了一个web管理页面,当然还包括了一个前端页面和后端API,底层使用mysql数据库;
-
registry是镜像仓库,负责存储镜像文件,当镜像上传完毕后通过hook通知ui创建repository,上图通过红色线标识,当然registry的token认证也是通过ui组件完成;
-
adminserver是系统的配置管理中心附带检查存储用量,ui和jobserver启动时候回需要加载adminserver的配置,通过灰色线标识;
-
jobsevice是负责镜像复制工作的,他和registry通信,从一个registry pull镜像然后push到另一个registry,并记录job_log,上图通过紫色线标识;
-
log是日志汇总组件,通过docker的log-driver把日志汇总到一起,通过浅蓝色线条标识。
2、 Harbor架构部署
安装方式
官方提供2种部署Harbor的方式:
-
在线安装: 从Docker Hub下载Harbor的镜像来安装, 由于Docker Hub比较慢, 建议Docker配置好加速器。(非常慢)
-
离线安装: 这种方式应对与部署主机没联网的情况使用。需要提前下载离线安装包: harbor-offline-installer-.tgz 到本地
离线安装步骤
-
下载Harbor最新的在线安装包
-
配置Harbor (harbor.yml)
-
运行install.sh来安装和启动Harbor
-
Harbor的日志路径:/var/log/harbor
推荐系统配置
离线部署流程
软件要求
系统环境要求
验证compose
###下载compose [root@docker ~]# curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose ##更改命令权限 [root@docker ~]# chmod +x /usr/local/bin/docker-compose #查看版本 [root@docker ~]# docker-compose version docker-compose version 1.18.0, build 8dd22a9 docker-py version: 2.6.1 CPython version: 2.7.13 OpenSSL version: OpenSSL 1.0.1t 3 May 2016
安装harbor
###导入harbor软件包### [root@docker ~]# ls harbor-offline-installer-v2.7.3.tgz ###解压### [root@docker~]# tar xf harbor-offline-installer-v2.7.3.tgz ###修改安装配置### [root@docker ~]# cd harbor/ [root@docker harbor]# cp harbor.yml.tmpl harbor.yml ##修改配置文件## [root@docker harbor]# vim harbor.yml
###修改docker配置文件#### \"data-root\": \"/opt/module/docker_data\", [root@docker ~]# cat /etc/docker/daemon.json { \"log-driver\": \"json-file\", \"log-opts\": { \"max-size\": \"100m\" }, \"insecure-registries\": [ \"192.168.72.126:8080\" ], \"registry-mirrors\": [ \"https://0vmzj3q6.mirror.aliyuncs.com\", \"https://docker.m.daocloud.io\", \"https://mirror.baidubce.com\", \"https://dockerproxy.com\", \"https://mirror.iscas.ac.cn\", \"https://huecker.io\", \"https://dockerhub.timeweb.cloud\", \"https://noohub.ru\", \"https://vlgh0kqj.mirror.aliyuncs.com\" ] } [root@docker harbor]# systemctl daemon-reload [root@docker harbor]# systemctl restart docker ######################## ###配置文件解析###### 1. data-root: 指定Docker存储数据的根目录,这里设置为/opt/module/docker_data。 2. log-driver: 指定Docker的日志驱动程序,这里设置为json-file,表示将日志以JSON格式存储。 3. log-opts: 指定日志驱动程序的参数选项。 max-size: 指定日志文件的最大大小,这里设置为100m,表示最大为100MB。 4. insecure-registries: 指定不安全的镜像仓库,在这里设置为192.168.115.129:80,表示允许与该镜像仓库通信,即使没有启用TLS。 ####安装harbor#### [root@docker harbor]# ./install.sh
harbor的启停
##切换到harbor安装包目录 ##停止Harbor [root@localhost harbor]# docker-compose stop ##启动Harbor [root@localhost harbor]# docker-compose start
harbor访问
浏览器登录 : admin/密码
http://192.168.72.126
命令行登录
[root@localhost ~]# docker login -u admin http://192.168.72.126:8080 Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
到此Harbor部署完毕!!
3、Harbor的使用
将nginx:latest镜像文件上传到创建好的harbor仓库中。
通过web浏览器界面在Harbor创建项目
上传镜像流程
###修改nginx:1.25官方镜像的tag标签 [root@localhost ~]# docker tag nginx:1.25 192.168.72.126:8080/nginx/nginx:v1 #登录harbor [root@localhost ~]# docker login -u admin -p Harbor12345 192.168.72.126:8080 #推送镜像到harbor[root@lnmp harbor]# docker push 192.168.72.126:8080/nginx/nginx:v1The push refers to repository [192.168.72.126:8080/nginx/nginx]14773070094d: Pushed 7d2fd59c368c: Pushed 56f8fe6aedcd: Pushed 9f4d73e635f1: Pushed 747b290aeba8: Pushed fc1cf9ca5139: Pushed 5d4427064ecc: Pushed v1: digest: sha256:0e1ac7f12d904a5ce077d1b5c763b5750c7985e524f6083e5eaa7e7313833440 size: 1778
浏览器查看Harbor项目信息
总结:
Docker 通过容器化技术彻底改变了软件的交付和运行方式,使开发者和运维团队能够更高效地构建、部署和管理应用。它的轻量级、可移植性和标准化特性,极大地提升了开发效率,降低了环境差异带来的问题。随着云原生和微服务架构的普及,Docker 已成为现代 IT 基础设施的核心组件之一。无论是个人开发者还是企业级应用,掌握 Docker 都能为软件生命周期管理带来显著的优化。未来,随着容器生态的持续发展,Docker 仍将在云计算和 DevOps 领域发挥关键作用。