目录
[1. 阿里Docker Yum 源安装](#1. 阿里Docker Yum 源安装)
[2. 依赖包安装](#2. 依赖包安装)
[二、 镜像管理](#二、 镜像管理)
[1. 搜索镜像](#1. 搜索镜像)
[2. 拉取镜像](#2. 拉取镜像)
[3. 查看镜像](#3. 查看镜像)
[4. 查看镜像制作的过程](#4. 查看镜像制作的过程)
[5. 删除镜像](#5. 删除镜像)
[6. 给镜像打标签](#6. 给镜像打标签)
[1. 仅创建容器](#1. 仅创建容器)
[2. 创建并运行容器](#2. 创建并运行容器)
[2. 关闭、启动、重启、暂停、恢复和重命名容器](#2. 关闭、启动、重启、暂停、恢复和重命名容器)
[3. 查看容器IP地址](#3. 查看容器IP地址)
[4. 访问容器(进行端口映射)](#4. 访问容器(进行端口映射))
[5. 连接容器](#5. 连接容器)
[6.1 attach连接](#6.1 attach连接)
[5.2 exec连接](#5.2 exec连接)
[6. 监控容器](#6. 监控容器)
[6.1 显示所有正在运行的容器的实时性能信息](#6.1 显示所有正在运行的容器的实时性能信息)
[6.2 查看容器的运行日志](#6.2 查看容器的运行日志)
[6.3 查看运行的容器里进程的信息](#6.3 查看运行的容器里进程的信息)
[6.4 实时输出Docker服务器端的事件,包括容器的创建,启动,关闭等](#6.4 实时输出Docker服务器端的事件,包括容器的创建,启动,关闭等)
[6.5 捕捉容器停止时的退出码(了解)](#6.5 捕捉容器停止时的退出码(了解))
[6.6 查看容器内发生改变的文件](#6.6 查看容器内发生改变的文件)
[📘 各字母含义与全称](#📘 各字母含义与全称)
[7. 宿主机和容器之间相互Copy文件](#7. 宿主机和容器之间相互Copy文件)
[1. 容器文件系统打包](#1. 容器文件系统打包)
[2. 通过容器创建本地镜像](#2. 通过容器创建本地镜像)
[3. 镜像迁移](#3. 镜像迁移)
[4. 通过Dockerfile创建镜像](#4. 通过Dockerfile创建镜像)
[4.1 docker build语法](#4.1 docker build语法)
[4.2 Dockerfile 语法说明](#4.2 Dockerfile 语法说明)
[4.3 🧱 Dockerfile 优化要点汇总表](#4.3 🧱 Dockerfile 优化要点汇总表)
[4.4 示例一](#4.4 示例一)
[4.5 示例二](#4.5 示例二)
[4.6 Python应用](#4.6 Python应用)
[(1) 准备工作](#(1) 准备工作)
[4.7 容器化Python的Flask应用](#4.7 容器化Python的Flask应用)
[4.8 Dockerfile多阶段构建](#4.8 Dockerfile多阶段构建)
[(1) 编译 Go 项目,并打包成镜像](#(1) 编译 Go 项目,并打包成镜像)
[(2) 导出编译产物](#(2) 导出编译产物)
[(3) 完成构建镜像和导出二进制的任务](#(3) 完成构建镜像和导出二进制的任务)
[1. 拉取registry镜像并运行为容器](#1. 拉取registry镜像并运行为容器)
[2. 仓库功能测试](#2. 仓库功能测试)
[3. 其他节点拉取私有仓库的镜像](#3. 其他节点拉取私有仓库的镜像)
[1. 配置工作](#1. 配置工作)
[2. 浏览器测试](#2. 浏览器测试)
[七、部署第三方镜像仓库 --- Harbor镜像仓库](#七、部署第三方镜像仓库 --- Harbor镜像仓库)
[1. 下载安装](#1. 下载安装)
[2. 启动和关闭Harbor](#2. 启动和关闭Harbor)
[3. 浏览器测试Harbor](#3. 浏览器测试Harbor)
[4. Harbor仓库使用](#4. Harbor仓库使用)
[4.1 新建项目](#4.1 新建项目)
[4.2 创建用户](#4.2 创建用户)
[4.3 项目授权](#4.3 项目授权)
[4.4 登录Harbor仓库](#4.4 登录Harbor仓库)
[4.5 Harbor仓库上传和拉取镜像](#4.5 Harbor仓库上传和拉取镜像)
[(1) 上传busybox镜像](#(1) 上传busybox镜像)
[4.6 重置Harbor密码](#4.6 重置Harbor密码)
[1. MySQL](#1. MySQL)
[2. Redis](#2. Redis)
[1. 查看当前网络](#1. 查看当前网络)
[十一、Docker Compose](#十一、Docker Compose)
[1. 编写简单的compose文件](#1. 编写简单的compose文件)
[2. 测试](#2. 测试)
[3. 资源限制和优化的compose文件](#3. 资源限制和优化的compose文件)
[4. 部署 Flask + Redis 应用](#4. 部署 Flask + Redis 应用)
[5. 完整 Docker Compose 示例](#5. 完整 Docker Compose 示例)
一、Docker安装
服务器信息表
| 主机名 | IP地址 | 功能描述 | 运行服务/容器 | 端口开放 |
|---|---|---|---|---|
| docker | 192.168.159.133 | Docker主节点 | Docker引擎、应用容器 | 22(SSH)、2375(Docker API可选) |
| docker-registry | 192.168.159.134 | 私有Docker镜像仓库 | Registry容器、Docker引擎 | 22(SSH)、5000(Registry)、9000(Web UI) |
1. 阿里Docker Yum 源安装
cs
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
yum install -y yum-utils device-mapper-persistent-data lvm2 git
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install docker-ce -y
systemctl start docker && systemctl enable docker
# 查看版本号等相关信息
[root@docker ~]# docker -v
Docker version 29.0.0, build 3d4129b
[root@docker ~]# docker version
Client: Docker Engine - Community
Version: 29.0.0
API version: 1.52
Go version: go1.25.4
Git commit: 3d4129b
Built: Mon Nov 10 21:49:39 2025
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 29.0.0
API version: 1.52 (minimum version 1.44)
Go version: go1.25.4
Git commit: d105562
Built: Mon Nov 10 21:46:25 2025
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v2.1.5
GitCommit: fcd43222d6b07379a4be9786bda52438f0dd16a1
runc:
Version: 1.3.3
GitCommit: v1.3.3-0-gd842d771
docker-init:
Version: 0.19.0
GitCommit: de40ad
2. 依赖包安装
cs
[root@docker docer_software]# ls
containerd.io-1.7.28-2.el9.x86_64.rpm docker-ce-28.5.1-1.el9.x86_64.rpm docker-compose-plugin-2.6.0-3.el9.x86_64.rpm
docker-buildx-plugin-0.29.1-1.el9.x86_64.rpm docker-ce-cli-28.5.1-1.el9.x86_64.rpm
[root@docker docer_software]# yum localinstall -y *.rpm
# 启动并设置开机自启
[root@docker docer_software]# systemctl start docker
[root@docker docer_software]# systemctl enable docker
查看版本和运行状态
cs
# 查看版本
[root@docker docer_software]# docker -v
Docker version 28.5.1, build e180ab8
[root@docker docer_software]# docker version
Client: Docker Engine - Community
Version: 28.5.1
API version: 1.51
Go version: go1.24.8
Git commit: e180ab8
Built: Wed Oct 8 12:20:03 2025
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 28.5.1
API version: 1.51 (minimum version 1.24)
Go version: go1.24.8
Git commit: f8215cc
Built: Wed Oct 8 12:17:02 2025
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.7.28
GitCommit: b98a3aace656320842a23f4a392a33f46af97866
runc:
Version: 1.3.3
GitCommit: v1.3.3-0-gd842d771
docker-init:
Version: 0.19.0
GitCommit: de40ad0
# 查看docker运行状态
[root@docker ~]# docker info
Client: Docker Engine - Community
Version: 28.5.1
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.29.1
Path: /usr/libexec/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.6.0
Path: /usr/libexec/docker/cli-plugins/docker-compose
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 28.5.1
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: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
CDI spec directories:
/etc/cdi
/var/run/cdi
Swarm: inactive
Runtimes: runc io.containerd.runc.v2
Default Runtime: runc
Init Binary: docker-init
containerd version: b98a3aace656320842a23f4a392a33f46af97866
runc version: v1.3.3-0-gd842d771
init version: de40ad0
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 5.14.0-592.el9.x86_64
Operating System: CentOS Stream 9
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 4.442GiB
Name: docker
ID: a5bc5e9b-8b53-4604-a602-be9aca5e4aa1
Docker Root Dir: /var/lib/docker
Debug Mode: false
Experimental: false
Insecure Registries:
::1/128
127.0.0.0/8
Live Restore Enabled: false
二、 镜像管理
镜像名称组成: registry/library/repo:tag
(1) DaoCloud(道客) 公司提供的 Docker/Kubernetes 镜像加速服务 https://github.com/DaoCloud/public-image-mirror
(2)渡渡鸟镜像同步站 https://docker.aityp.com/
(3)阿里云镜像 https://cr.console.aliyun.com/cn-hangzhou/instances/artifact
(4)毫秒镜像 https://1ms.run/
1. 搜索镜像
cs
# 仅用于官方镜像库
[root@docker ~]# docker search mysql
# 只显示星标(Stars)数量大于或等于 100 的镜像
[root@docker ~]# docker search ubuntu -f stars=100
2. 拉取镜像
cs
# 从 DaoCloud 镜像仓库拉取nginx镜像。
[root@docker ~]# docker pull m.daocloud.io/k8s.gcr.io/nginx
Using default tag: latest
latest: Pulling from k8s.gcr.io/nginx
a3ed95caeb02: Pull complete
e30706b9b4ff: Pull complete
82286846aa71: Pull complete
d433c42f6001: Pull complete
74d2508996ef: Pull complete
4fceae443db7: Pull complete
577897efe0e1: Pull complete
69d79999108f: Pull complete
091f65bae2b8: Pull complete
Digest: sha256:f49a843c290594dcf4d193535d1f4ba8af7d56cea2cf79d1e9554f077f1e7aaa
Status: Downloaded newer image for m.daocloud.io/k8s.gcr.io/nginx:latest
m.daocloud.io/k8s.gcr.io/nginx:latest
# 从渡渡鸟镜像同步站 拉取busybox镜像
[root@docker ~]# docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/e2e-test-images/busybox:1.29-4
1.29-4: Pulling from ddn-k8s/registry.k8s.io/e2e-test-images/busybox
b4a6e23922dd: Pull complete
Digest: sha256:7ddd6b83e44b8f6e2f1fccace9562f5600b71e7717515ebd2131bdb94ad8634c
Status: Downloaded newer image for swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/e2e-test-images/busybox:1.29-4
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/e2e-test-images/busybox:1.29-4

3. 查看镜像
cs
# 查看本地镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/e2e-test-images/busybox 1.29-4 d59c675982d8 6 years ago 1.15MB
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
# 旧版命令查看本地镜像(效果一致)
[root@docker ~]# docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/e2e-test-images/busybox 1.29-4 d59c675982d8 6 years ago 1.15MB
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
# 查看所有镜像的ID
[root@docker ~]# docker images -q
d59c675982d8
bf15594d61ad
# 查看镜像详情
[root@docker ~]# docker inspect d59c675982d8
[
{
"Id": "sha256:d59c675982d8692814ec9e1486d4c645cd86ad825ef33975a5db196cf2801592",
"RepoTags": [
"swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/e2e-test-images/busybox:1.29-4"
],
"RepoDigests": [
"swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/e2e-test-images/busybox@sha256:7ddd6b83e44b8f6e2f1fccace9562f5600b71e7717515ebd2131bdb94ad8634c"
],
"Parent": "",
"Comment": "",
"Created": "2018-12-26T08:20:42.831353376Z",
"DockerVersion": "",
"Author": "",
"Architecture": "amd64",
"Os": "linux",
"Size": 1154361,
"GraphDriver": {
"Data": {
"MergedDir": "/var/lib/docker/overlay2/34bb207525f57f02c032cbb77a3f1adcf456e062700a4078b34a2dff7a7a9f75/merged",
"UpperDir": "/var/lib/docker/overlay2/34bb207525f57f02c032cbb77a3f1adcf456e062700a4078b34a2dff7a7a9f75/diff",
"WorkDir": "/var/lib/docker/overlay2/34bb207525f57f02c032cbb77a3f1adcf456e062700a4078b34a2dff7a7a9f75/work"
},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:23bc2b70b2014dec0ac22f27bb93e9babd08cdd6f1115d0c955b9ff22b382f5a"
]
},
"Metadata": {
"LastTagTime": "0001-01-01T00:00:00Z"
},
"Config": {
"ArgsEscaped": true,
"Cmd": [
"sh"
],
"Entrypoint": null,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Labels": {
"commit_id": "b60176972182bc2a459e019bc039dfcffa2ff868",
"git_url": "https://github.com/kubernetes/kubernetes/tree/b60176972182bc2a459e019bc039dfcffa2ff868/test/images/busybox",
"image_version": "1.29-4"
},
"OnBuild": null,
"User": "",
"Volumes": null,
"WorkingDir": ""
}
}
]
4. 查看镜像制作的过程
cs
[root@docker ~]# docker history d59c675982d8
IMAGE CREATED CREATED BY SIZE COMMENT
d59c675982d8 6 years ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 6 years ago /bin/sh -c #(nop) ADD file:ce026b62356eec3ad... 1.15MB
[root@docker ~]# docker history bf15594d61ad
IMAGE CREATED CREATED BY SIZE COMMENT
bf15594d61ad 10 years ago /bin/sh 0B
<missing> 10 years ago /bin/sh 0B
<missing> 10 years ago /bin/sh 0B
<missing> 10 years ago /bin/sh 0B
<missing> 10 years ago /bin/sh 0B
<missing> 10 years ago /bin/sh 15.5MB
<missing> 10 years ago /bin/sh 0B
<missing> 10 years ago /bin/sh 0B
<missing> 10 years ago /bin/sh 0B
<missing> 10 years ago /bin/sh 80.6kB
<missing> 10 years ago /bin/sh 532B
<missing> 10 years ago /bin/sh 1.12kB
<missing> 10 years ago /bin/sh 222MB
<missing> 10 years ago /bin/sh 0B
<missing> 10 years ago /bin/sh 1.9kB
<missing> 10 years ago /bin/sh 195kB
<missing> 10 years ago /bin/sh 188MB
<missing> 12 years ago 0B
5. 删除镜像
cs
# 通过 镜像的唯一哈希 ID 删除镜像
[root@docker ~]# docker rmi d59c675982d8
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
# 通过 镜像名称 + 标签 删除镜像
[root@docker ~]# docker rmi m.daocloud.io/k8s.gcr.io/nginx:latest
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
如果镜像正在被使用,可用--force强制删除
如:docker rmi docker.io/ubuntu:latest --force
6. 给镜像打标签
cs
# 从渡渡鸟镜像同步站拉取mysql镜像
[root@docker ~]# docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/debezium/example-mysql:3.2
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/debezium/example-mysql 3.2 52f56ce7f78b 3 months ago 596MB
[root@docker ~]# docker tag swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/debezium/example-mysql:3.2 ink/mysql:v1
# 相当于"硬链接",删除其中一个镜像另一个仍可使用,除非通过IMAGE ID删除
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/debezium/example-mysql 3.2 52f56ce7f78b 3 months ago 596MB
ink/mysql v1 52f56ce7f78b 3 months ago 596MB
三、容器管理
1. 仅创建容器
cs
[root@docker ~]# docker create -it --name="mysql02" ink/mysql:v1
4918c4ec087a924eea8084ee0c939f69ceed46bb54ebcb532e859a3e0396cf96
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4918c4ec087a ink/mysql:v1 "/entrypoint.sh mysq..." 7 seconds ago Created mysql02
1d609e2de8c0 m.daocloud.io/k8s.gcr.io/nginx:latest "/bin/bash" 12 hours ago Exited (0) 12 hours ago nginx
6d55947b9aee ink/mysql:v1 "/entrypoint.sh mysq..." 12 hours ago Up 45 minutes 3306/tcp, 33060-33061/tcp mysql
[root@docker ~]# docker start nginx
nginx
2. 创建并运行容器
-i 捕获标准输入输出
-t 分配一个终端或控制台
-d 后台运行
--restart=always 容器随docker engine自启动,因为重启docker时默认容器都会被关闭,也适用于create子命令
--rm 当你仅仅需要短暂的运行一个容器且数据不需保存,你可能就希望Docker能在容器结束时自动清理其所产生的数据。这时就需要--rm参数了。注意:--rm 和 -d不能共用
--name="容器名称" 为容器分配一个名字,如果没有指定,docker会自动分配一个随机名称
可以通过三种方式调用容器:
1)使用UUID长命名("f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778")
2)使用UUID短Id("f78375b1c487")
3)使用Name("evil_ptolemy")
UUID标识是由Docker deamon生成的。 如果执行docker run时没指定--name,那么deamon会自动生成一个随机字符串。 但是对于一个容器来说有个name会非常方便,当需要连接其它容器时或者需要区分其它容器时,使用容器名可以简化操作。无论容器运行在前台或者后台,这个名字都是有效的。
cs
[root@docker ~]# docker run -itd --name="mysql" --restart=always ink/mysql:v1
6d55947b9aee4b0cf924b73c990419a99ca01e2936a0b498077de92ec5390171
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d55947b9aee ink/mysql:v1 "/entrypoint.sh mysq..." 2 seconds ago Up 2 seconds 3306/tcp, 33060-33061/tcp mysql
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ink/mysql v1 52f56ce7f78b 3 months ago 596MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/debezium/example-mysql 3.2 52f56ce7f78b 3 months ago 596MB
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
# 以交互模式启动 Nginx 容器并进入 Bash Shell(忽略 Nginx 镜像原本的默认命令,转而执行 /bin/bash,因为一个容器只能有一个进程)
[root@docker ~]# docker run -it --name="nginx" m.daocloud.io/k8s.gcr.io/nginx:latest /bin/bash
# 在容器内查看 Nginx 配置文件
[ root@1d609e2de8c0:/etc/nginx ]$ ls
certs/ fastcgi.conf koi-utf mime.types proxy_params sites-available/ snippets/ win-utf
conf.d/ fastcgi_params koi-win nginx.conf scgi_params sites-enabled/ uwsgi_params
#切换到容器根目录
[ root@1d609e2de8c0:/etc/nginx ]$ cd /
# 查看容器内进程列表(唯一运行的进程是 /bin/bash(PID 1),说明没有启动 Nginx 服务)
[ root@1d609e2de8c0:/ ]$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.3 0.0 19348 4352 pts/0 Ss 14:00 0:00 /bin/bash
root 43 0.0 0.0 15576 2048 pts/0 R+ 14:01 0:00 ps aux
# Ctrl + p + q快捷键退出(容器保证仍在运行)
# 如果是Ctrl + D 或者命令"exit"退出则容器会关闭
[ root@1d609e2de8c0:/ ]$ [root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d609e2de8c0 m.daocloud.io/k8s.gcr.io/nginx:latest "/bin/bash" 4 minutes ago Up 4 minutes 80/tcp, 443/tcp nginx
6d55947b9aee ink/mysql:v1 "/entrypoint.sh mysq..." 22 minutes ago Up 22 minutes 3306/tcp, 33060-33061/tcp mysql
[root@docker ~]# docker exec -it nginx03 /bin/bash
[ root@ec7eab6a1610:/etc/nginx ]$ exit
exit
# 交互式进入已运行的容器,exit退出容器仍可运行
[root@docker ~]# docker exec -it nginx03 /bin/bash
[ root@ec7eab6a1610:/etc/nginx ]$ exit
exit
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f5f9e2e5896 bf15594d61ad "echo 'Save containe..." 10 minutes ago Exited (0) 10 minutes ago nginx05
ec7eab6a1610 bf15594d61ad "/bin/bash" 37 minutes ago Up 24 minutes 80/tcp, 443/tcp nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 38 minutes ago Up 24 minutes 80/tcp, 443/tcp nginx022
# 短暂运行容器而不保存数据
[root@docker ~]# docker run -it --rm --name nginx04 bf15594d61ad echo "Hello Nginx04"
Hello Nginx04
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 21 minutes ago Up 9 minutes 80/tcp, 443/tcp nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 22 minutes ago Up 9 minutes 80/tcp, 443/tcp nginx022
# 保存容器ID --cidfile
[root@docker ~]# docker run -it --cidfile="/tmp/nginx05_cid.txt" --name nginx05 bf15594d61ad echo "Save containerID of nginx05"
Save containerID of nginx05
[root@docker ~]# cat /tmp/nginx05_cid.txt
2f5f9e2e589656cc3e6285af3c5e0a1c8dcbb0e64c7758152ddf72af8192963a
2. 关闭、启动、重启、暂停、恢复和重命名容器
cs
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 3 minutes ago Exited (0) 3 minutes ago nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 4 minutes ago Up 28 seconds 80/tcp, 443/tcp nginx02
# 关闭容器
[root@docker ~]# docker stop nginx02
nginx02
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 4 minutes ago Exited (0) 4 minutes ago nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 5 minutes ago Exited (0) 2 seconds ago nginx02
# 强制关闭容器
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 6 minutes ago Exited (0) 6 minutes ago nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 7 minutes ago Up 2 minutes 80/tcp, 443/tcp nginx022
[root@docker ~]# docker kill nginx022
nginx022
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 10 minutes ago Exited (0) 10 minutes ago nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 11 minutes ago Exited (137) 2 seconds ago nginx022
# 启动容器
[root@docker ~]# docker start nginx02
nginx02
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 4 minutes ago Exited (0) 4 minutes ago nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 5 minutes ago Up 1 second 80/tcp, 443/tcp nginx02
# 批量启动容器
[root@docker ~]# docker start $(docker ps -aq)
ec7eab6a1610
77b41e6d9bc9
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 12 minutes ago Up 1 second 80/tcp, 443/tcp nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 13 minutes ago Up 1 second 80/tcp, 443/tcp nginx022
# 重启容器
[root@docker ~]# docker restart nginx02
nginx02
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 4 minutes ago Exited (0) 4 minutes ago nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 5 minutes ago Up 1 second 80/tcp, 443/tcp nginx02
# 暂停容器
[root@docker ~]# docker pause nginx02
nginx02
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 5 minutes ago Exited (0) 5 minutes ago nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 6 minutes ago Up 47 seconds (Paused) 80/tcp, 443/tcp nginx02
# 恢复容器
[root@docker ~]# docker unpause nginx02
nginx02
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 5 minutes ago Exited (0) 5 minutes ago nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 6 minutes ago Up About a minute 80/tcp, 443/tcp nginx02
# 修改容器名称
[root@docker ~]# docker rename nginx02 nginx022
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ec7eab6a1610 bf15594d61ad "/bin/bash" 6 minutes ago Exited (0) 6 minutes ago nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" 7 minutes ago Up 2 minutes 80/tcp, 443/tcp nginx022
3. 查看容器IP地址
cs
# 使用 Go 模板格式化输出,直接从容器元数据中提取其 IP 地址字段
[root@docker ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' ec7eab6a1610
172.17.0.2
# 使用
[root@docker ~]# docker inspect ec7eab6a1610 | grep "IPAddress"
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
# 使用正则表达式匹配出所有包含 "IPAddress" 的行
[root@docker ~]# docker inspect ec7eab6a1610 | grep "IPAddress" | awk -F '"' 'NR==3{print $4}'
172.17.0.2
4. 访问容器(进行端口映射)
cs
# 运行容器同时进行端口映射(宿主机8000端口映射为容器端口80)
[root@docker ~]# docker run -itd -p 8000:80 --name=nginx bf
8f9d3aeda5d0a9a3be0d282cd9a8c2eec7b1443f4c6a16a5386b71787220c0c1
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8f9d3aeda5d0 bf "nginx" 5 seconds ago Up 4 seconds 443/tcp, 0.0.0.0:8000->80/tcp, [::]:8000->80/tcp nginx
613b7af35bf1 m.daocloud.io/k8s.gcr.io/redis:latest "redis-server /etc/r..." 3 minutes ago Up 3 minutes 6379/tcp laughing_vaughan
634a677ff3bf m.daocloud.io/k8s.gcr.io/nginx:latest "nginx" 13 minutes ago Up 13 minutes 80/tcp, 443/tcp modest_gagarin
# 查看防火墙规则
[root@docker ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000 to:172.17.0.3:80
端口转换测试结果

5. 连接容器
6.1 attach连接
cs
[root@docker ~]# docker attach nginx03
[ root@ec7eab6a1610:/etc/nginx ]$ echo "Hello World"
Hello World
[ root@ec7eab6a1610:/etc/nginx ]$ exit
# exit退出,容器则关闭
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f5f9e2e5896 bf15594d61ad "echo 'Save containe..." 34 minutes ago Exited (0) 16 minutes ago nginx05
ec7eab6a1610 bf15594d61ad "/bin/bash" About an hour ago Exited (0) 5 seconds ago nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" About an hour ago Up 48 minutes 80/tcp, 443/tcp nginx022
# Ctrl + P + Q 退出,容器仍可运行
[ root@ec7eab6a1610:/ ]$ read escape sequence
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f5f9e2e5896 bf15594d61ad "echo 'Save containe..." 39 minutes ago Exited (0) 3 minutes ago nginx05
ec7eab6a1610 bf15594d61ad "/bin/bash" About an hour ago Up 3 minutes 80/tcp, 443/tcp nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" About an hour ago Up 53 minutes 80/tcp, 443/tcp nginx022
5.2 exec连接
cs
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f5f9e2e5896 bf15594d61ad "echo 'Save containe..." 35 minutes ago Exited (0) 4 seconds ago nginx05
ec7eab6a1610 bf15594d61ad "/bin/bash" About an hour ago Up 4 seconds 80/tcp, 443/tcp nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" About an hour ago Up 49 minutes 80/tcp, 443/tcp nginx022
[root@docker ~]# docker exec -it nginx03 /bin/bash
[ root@ec7eab6a1610:/etc/nginx ]$ exit
# exit退出,容器仍可运行
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f5f9e2e5896 bf15594d61ad "echo 'Save containe..." 37 minutes ago Exited (0) About a minute ago nginx05
ec7eab6a1610 bf15594d61ad "/bin/bash" About an hour ago Up About a minute 80/tcp, 443/tcp nginx03
77b41e6d9bc9 bf15594d61ad "/bin/bash" About an hour ago Up 51 minutes 80/tcp, 443/tcp nginx022
6. 监控容器
6.1 显示所有正在运行的容器的实时性能信息
cs
# 显示所有正在运行的容器的实时性能信息
[root@docker ~]# docker stats

6.2 查看容器的运行日志
cs
[root@docker ~]# docker run -itd --name nginx03 m.daocloud.io/k8s.gcr.io/nginx:latest /bin/bash -c "while true; do echo hello world; sleep 2; done"
[root@docker ~]# docker logs nginx03
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
# 查看最后三条日志
[root@docker ~]# docker logs --tail 3 nginx03
hello world
hello world
hello world
# 实时查看
[root@docker ~]# docker logs -f nginx03
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
6.3 查看运行的容器里进程的信息
cs
[root@docker ~]# docker top nginx03
UID PID PPID C STIME TTY TIME CMD
root 2579 2559 0 10:59 pts/0 00:00:00 /bin/bash -c while true; do echo hello world; sleep 2; done
root 3238 2579 0 11:03 pts/0 00:00:00 sleep 2
6.4 实时输出Docker服务器端的事件,包括容器的创建,启动,关闭等
cs
[root@docker ~]# docker stop nginx03
nginx03
[root@docker ~]# docker start nginx01
nginx01
[root@docker ~]# docker events
2025-11-10T11:05:19.201775212+08:00 container kill a2bf2bbfa9c42135008489157a2057153f100a8f6f67ca81b1a08e85aa3f42db (image=m.daocloud.io/k8s.gcr.io/nginx:latest, name=nginx03, signal=15)
2025-11-10T11:05:29.214305148+08:00 container kill a2bf2bbfa9c42135008489157a2057153f100a8f6f67ca81b1a08e85aa3f42db (image=m.daocloud.io/k8s.gcr.io/nginx:latest, name=nginx03, signal=9)
2025-11-10T11:05:29.318861498+08:00 network disconnect ebf48f63bbad7317b202420143b25f05c835a48f646df0b79290950ef2b98a55 (container=a2bf2bbfa9c42135008489157a2057153f100a8f6f67ca81b1a08e85aa3f42db, name=bridge, type=bridge)
2025-11-10T11:05:29.320333441+08:00 volume unmount e977c3fd6b7b6cf5c2b9b8c26ed8b67c4c9612c729588be522b30fa84450a5cd (container=a2bf2bbfa9c42135008489157a2057153f100a8f6f67ca81b1a08e85aa3f42db, driver=local)
2025-11-10T11:05:29.320369739+08:00 volume unmount a2817bc85ac9ccf63591fad235052cd1423045a81290a683953cf0280c3f9d6c (container=a2bf2bbfa9c42135008489157a2057153f100a8f6f67ca81b1a08e85aa3f42db, driver=local)
2025-11-10T11:05:29.320378115+08:00 volume unmount 165d6ba524d99bae0b94b920444afbc0f255331114e24cfd60e96e2c5fd83016 (container=a2bf2bbfa9c42135008489157a2057153f100a8f6f67ca81b1a08e85aa3f42db, driver=local)
2025-11-10T11:05:29.320386752+08:00 volume unmount b5cc9b98f7f4c7583ffe8a7df7ce7bd619b5460a714421ae6f5fc40240267c32 (container=a2bf2bbfa9c42135008489157a2057153f100a8f6f67ca81b1a08e85aa3f42db, driver=local)
2025-11-10T11:05:29.320399165+08:00 volume unmount eea4fd8ba469d6a7df8f467187f32d8fb63a8a6295b8094be612b36480105446 (container=a2bf2bbfa9c42135008489157a2057153f100a8f6f67ca81b1a08e85aa3f42db, driver=local)
2025-11-10T11:05:29.321135030+08:00 container stop a2bf2bbfa9c42135008489157a2057153f100a8f6f67ca81b1a08e85aa3f42db (image=m.daocloud.io/k8s.gcr.io/nginx:latest, name=nginx03)
2025-11-10T11:05:29.322747655+08:00 container die a2bf2bbfa9c42135008489157a2057153f100a8f6f67ca81b1a08e85aa3f42db (execDuration=345, exitCode=137, image=m.daocloud.io/k8s.gcr.io/nginx:latest, name=nginx03)
2025-11-10T11:05:45.838897947+08:00 volume mount 6fe25dff84a84593e2fee1ae88ac26d70cb90133b79ae6774ee34b44e560d447 (container=ab07f1dd1a4c38dbc143c5a3ee0fb278bdffa7716196d51972190c90f255b26e, destination=/etc/nginx/certs, driver=local, propagation=, read/write=true)
2025-11-10T11:05:45.838938434+08:00 volume mount 205e0f3fcfe75b29c698b553b8fdf7ca6938c34a985afa00cddfc214ff4a3068 (container=ab07f1dd1a4c38dbc143c5a3ee0fb278bdffa7716196d51972190c90f255b26e, destination=/etc/nginx/conf.d, driver=local, propagation=, read/write=true)
2025-11-10T11:05:45.838949615+08:00 volume mount f416657ac8d2ee3f8deb3831b54c6967d8029eee20ad8d63ea52ec3fa51177d9 (container=ab07f1dd1a4c38dbc143c5a3ee0fb278bdffa7716196d51972190c90f255b26e, destination=/etc/nginx/sites-enabled, driver=local, propagation=, read/write=true)
2025-11-10T11:05:45.838957269+08:00 volume mount 537a91eeec2bc61608c9e5f16333851131d4fbaf594b3c06ef80900458dd6358 (container=ab07f1dd1a4c38dbc143c5a3ee0fb278bdffa7716196d51972190c90f255b26e, destination=/var/log/nginx, driver=local, propagation=, read/write=true)
2025-11-10T11:05:45.838964553+08:00 volume mount a91f945c0d63f2db6ff90ed93ddf972370217e0e9db78bfae880de33dac4a14b (container=ab07f1dd1a4c38dbc143c5a3ee0fb278bdffa7716196d51972190c90f255b26e, destination=/var/www/html, driver=local, propagation=, read/write=true)
2025-11-10T11:05:45.951102265+08:00 network connect ebf48f63bbad7317b202420143b25f05c835a48f646df0b79290950ef2b98a55 (container=ab07f1dd1a4c38dbc143c5a3ee0fb278bdffa7716196d51972190c90f255b26e, name=bridge, type=bridge)
2025-11-10T11:05:45.971844298+08:00 container start ab07f1dd1a4c38dbc143c5a3ee0fb278bdffa7716196d51972190c90f255b26e (image=bf15594d61ad, name=nginx01)
6.5 捕捉容器停止时的退出码(了解)
cs
[root@docker ~]# docker stop nginx01
nginx01
[root@docker ~]# docker wait nginx01
0
6.6 查看容器内发生改变的文件
cs
# 创建文件之前
[root@docker ~]# docker diff nginx02
C /root
A /root/.z
A /root/.bash_history
C /etc
C /etc/nginx
A /etc/nginx/certs
# 容器内根下创建测试文件
[root@docker ~]# docker exec nginx02 touch /docker_nginx02.txt
# 创建文件之后
[root@docker ~]# docker diff nginx02
A /docker_nginx02.txt
C /root
A /root/.z
A /root/.bash_history
C /etc
C /etc/nginx
A /etc/nginx/certs
# 查看容器nginx02根下文件变化
[root@docker ~]# docker exec nginx02 ls /
bin
boot
dev
docker_nginx02.txt
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
📘 各字母含义与全称
| 符号 | 全称 | 含义说明 |
|---|---|---|
| A | Added | 表示这个文件或目录是新增的(容器运行后创建的)。 |
| C | Changed | 表示这个文件或目录被修改过(内容或元数据发生变化)。 |
| D | Deleted | 表示这个文件或目录被删除了。 |
7. 宿主机和容器之间相互Copy文件
cs
[root@docker ~]# ls
abc.txt docer_software hello.txt
# 宿主机文件拷贝至容器nginx02中
[root@docker ~]# docker cp abc.txt nginx02:/
Successfully copied 2.05kB to nginx02:/
# 查看容器内文件是否拷贝成功
[root@docker ~]# docker exec nginx02 ls /
abc.txt
bin
boot
dev
docker_nginx02.txt
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 容器nginx02内的文件拷贝至宿主机
[root@docker ~]# docker cp nginx02:/docker_nginx02.txt .
Successfully copied 1.54kB to /root/.
# 查看宿主机中文件是否拷贝成功
[root@docker ~]# ls
abc.txt docer_software docker_nginx02.txt hello.txt
[root@docker ~]#
四、Docker容器镜像制作
1. 容器文件系统打包
Crystal
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a2bf2bbfa9c4 m.daocloud.io/k8s.gcr.io/nginx:latest "/bin/bash -c 'while..." 22 minutes ago Exited (137) 16 minutes ago nginx03
298bac09d384 m.daocloud.io/k8s.gcr.io/nginx:latest "/bin/bash" 18 hours ago Up 29 minutes 80/tcp, 443/tcp nginx02
ab07f1dd1a4c bf15594d61ad "nginx" 21 hours ago Up 13 minutes 80/tcp, 443/tcp nginx01
# 打包方式一
[root@docker ~]# docker export -o nginx01.tar nginx01
[root@docker ~]# ls
docer_software nginx01.tar
# 打包方式二
[root@docker ~]# docker export nginx02 > nginx02.tar
[root@docker ~]# ls
docer_software nginx01.tar nginx02.tar
# 即使nginx03未运行也可打包
[root@docker ~]# docker export -o nginx03.tar nginx03
[root@docker ~]# ls
docer_software nginx01.tar nginx02.tar nginx03.tar
cs
# 导入镜像归档文件到其他宿舍机(为了便于测试,以本机为例)
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ink/mysql v1 52f56ce7f78b 3 months ago 596MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/debezium/example-mysql 3.2 52f56ce7f78b 3 months ago 596MB
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
# 导入nginx01.tar并起镜像名字
[root@docker ~]# docker import nginx01.tar nginx011:v1
sha256:b9c8723311117f236dc9136dcbe853b3574e4d344e886f3ba8c4dcd64007cc19
# 查看本地镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx011 v1 b9c872331111 6 seconds ago 399MB
ink/mysql v1 52f56ce7f78b 3 months ago 596MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/debezium/example-mysql 3.2 52f56ce7f78b 3 months ago 596MB
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
# 导入nginx02.tar但未起镜像名字
[root@docker ~]# docker import nginx02.tar
sha256:17ec3fba21c8bdf297eaa7b00fb4c9098284747d95f089c91efc0e803943754b
# 查看本地镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 17ec3fba21c8 3 seconds ago 399MB
nginx011 v1 b9c872331111 35 seconds ago 399MB
ink/mysql v1 52f56ce7f78b 3 months ago 596MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/debezium/example-mysql 3.2 52f56ce7f78b 3 months ago 596MB
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
# 为导入的镜像归档文件中未起名的镜像起名字
[root@docker ~]# docker tag 17ec3fba21c8 nginx022:v1
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx022 v1 17ec3fba21c8 47 seconds ago 399MB
nginx011 v1 b9c872331111 About a minute ago 399MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/debezium/example-mysql 3.2 52f56ce7f78b 3 months ago 596MB
ink/mysql v1 52f56ce7f78b 3 months ago 596MB
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
2. 通过容器创建本地镜像
容器运行起来后,又在里面做了一些操作,并且要把操作结果保存到镜像里
cs
[root@docker ~]# docker exec -it nginx02 /bin/bash
[ root@298bac09d384:/etc/nginx ]$ cd
[ root@298bac09d384:~ ]$ touch 666.jpg
[ root@298bac09d384:~ ]$ ls
666.jpg
[ root@298bac09d384:~ ]$ exit
[root@docker ~]# docker commit -m "Add 666.jpg" -a "ink" 298bac09d384 m.daocloud.io/k8s.gcr.io/nginx:version2
sha256:c58efcf5f5be3a34c303c4e74d3b373e047ecb0ff6ddcafe9edadcbb8c7b49b0
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
m.daocloud.io/k8s.gcr.io/nginx version2 c58efcf5f5be 4 seconds ago 426MB
nginx022 v1 17ec3fba21c8 9 minutes ago 399MB
nginx011 v1 b9c872331111 10 minutes ago 399MB
ink/mysql v1 52f56ce7f78b 3 months ago 596MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/debezium/example-mysql 3.2 52f56ce7f78b 3 months ago 596MB
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
-m 添加注释
-a 作者author
298bac09d384 容器环境id
daocloud.io/ubuntu:v2 镜像名称:hub的名称/镜像名称:tag
-p,--pause=true 提交时暂停容器运行
3. 镜像迁移
docker save [OPTIONS] IMAGE [IMAGE...]
参数 说明 -o, --output string指定输出文件路径(保存为 tar 包) IMAGE镜像名称或 ID,可以同时指定多个镜像
cs
# 方式一
[root@docker ~]# docker save -o nginx.tar m.daocloud.io/k8s.gcr.io/nginx:latest
[root@docker ~]# ls
docer_software nginx01.tar nginx02.tar nginx03.tar nginx.tar
# 方式二
[root@docker ~]# docker save bf15594d61ad > nginx_bak.tar
[root@docker ~]# ls
docer_software nginx01.tar nginx02.tar nginx03.tar nginx_bak.tar nginx.tar
# 导入镜像
[root@docker ~]# docker rmi $(docker images -q) -f
# 确保原镜像已删除,便于测试
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
# 导入镜像
[root@docker ~]# docker load < nginx.tar
Loaded image: m.daocloud.io/k8s.gcr.io/nginx:latest
# 检测本地镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
4. 通过Dockerfile创建镜像
docker build命令用于根据给定的Dockerfile和上下文以构建Docker镜像。
4.1 docker build语法
docker build [OPTIONS] <PATH | URL | ->
--build-arg,设置构建时的变量
--no-cache,默认false。设置该选项,将不使用Build Cache构建镜像
--pull,默认false。设置该选项,总是尝试pull镜像的最新版本
--compress,默认false。设置该选项,将使用gzip压缩构建的上下文
--disable-content-trust,默认true。设置该选项,将对镜像进行验证
--file, -f,Dockerfile的完整路径,默认值为'PATH/Dockerfile'
--isolation,默认--isolation="default",即Linux命名空间;其他还有process或hyperv
--label,为生成的镜像设置metadata
--squash,默认false。设置该选项,将新构建出的多个层压缩为一个新层,但是将无法在多个镜像之间共享新层;设置该选项,实际上是创建了新image,同时保留原有image。
--tag, -t,镜像的名字及tag,通常name:tag或者name格式;可以在一次构建中为一个镜像设置多个tag
--network,默认default。设置该选项,Set the networking mode for the RUN instructions during build
--quiet, -q ,默认false。设置该选项,Suppress the build output and print image ID on success
--force-rm,默认false。设置该选项,总是删除掉中间环节的容器
--rm,默认--rm=true,即整个构建过程成功后删除中间环节的容器
PATH | URL | -说明
给出命令执行的上下文。docker build需要的各种文件必须放到上下文目录中
上下文可以是构建执行所在的本地路径,也可以是远程URL,如Git库、tar包或文本文件等。
如果是Git库,如https://github.com/docker/rootfs.git#container:docker,则隐含先执行git clone --depth 1 --recursive,到本地临时目录;然后再将该临时目录发送给构建进程。
构建镜像的进程中,可以通过ADD命令将上下文中的任何文件加入到镜像中。
-表示通过STDIN给出Dockerfile或上下文。
4.2 Dockerfile 语法说明
格式说明
每行命令都是以 INSTRUCTION statement 形式,就是命令+ 清单的模式。命令要大写,"#"是注解。
FROM 命令是告诉docker 我们的镜像什么。
MAINTAINER 是描述 镜像的创建人。
RUN 命令是在镜像内部执行。就是说他后面的命令应该是针对镜像可以运行的命令
RUN尽可能的少,多个RUN可以写成一个RUN,用分号" ; "隔开
docker build -t centos:v2 .
build 是docker创建镜像的命令
-t 镜像名称
"." 上下文目录,如果不用-f指定Dockerfile文件的位置和名称,默认会从上下文目录也就是这里指定的当前目录查找
4.3 🧱 Dockerfile 优化要点汇总表
| 序号 | 优化方向 | 优化说明 | 示例 / 关键点 |
|---|---|---|---|
| 1 | 选择合适的基础镜像 | 选择轻量级、官方优化的基础镜像,如 Alpine 、Scratch。 | FROM alpine:latest,FROM scratch |
| 2 | 最小化安装软件包 | 只安装必要依赖,删除多余文件、文档和包,减少镜像体积。 | RUN yum install -y nginx && yum clean all |
| 3 | 使用多阶段构建 | 在一个镜像中编译,在另一个轻量镜像中运行,只保留最终产物。 | FROM golang:alpine AS builder → FROM alpine:latest |
| 4 | 使用 .dockerignore 文件 |
排除不需复制进镜像的文件/目录,减少构建上下文。 | .dockerignore 文件中添加:Dockerfile、README.md、tmp/ 等 |
示例: # cat .dockerignore Dockerfile # docker build -t 2406/busybox:v4 . |
构建时 .dockerignore 自动生效;测试运行发现 Dockerfile 未被拷贝入镜像。 |
||
| 5 | 减少镜像层数 | 每条 RUN 都会生成新层,合并命令可减少层数和体积。 |
RUN yum -y install nginx && yum clean all && rm -rf /var/cache/yum |
| 6 | 清理临时文件与缓存 | 构建结束前清除缓存、临时文件、日志等,防止镜像膨胀。 | RUN yum clean all && rm -rf /tmp/* /var/cache/* |
4.4 示例一
cs
# 创建镜像所在的文件夹和Dockerfile文件
[root@docker ~]# mkdir /dockerfile_test
[root@docker ~]# cd /dockerfile_test
[root@docker dockerfile_test]# vim Dockerfile
[root@docker dockerfile_test]# cat Dockerfile
FROM box:v1
MAINTAINER ink 17611028236@163.com
RUN mkdir /box01; echo $(date) > /tmp/date.txt
# 创建镜像
[root@docker dockerfile_test]# docker build -t box:v2 .
[+] Building 0.3s (6/6) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 131B 0.0s
=> WARN: MaintainerDeprecated: Maintainer instruction is deprecated in favor of using label (line 2) 0.0s
=> [internal] load metadata for docker.io/library/box:v1 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> CACHED [1/2] FROM docker.io/library/box:v1 0.0s
=> [2/2] RUN mkdir /box01; echo $(date) > /tmp/date.txt 0.2s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:5ffb34c5b85dec7278e5c2086b794e5ec16fa0bd36f0c9c10babfcddc0d88227 0.0s
=> => naming to docker.io/library/box:v2 0.0s
1 warning found (use docker --debug to expand):
- MaintainerDeprecated: Maintainer instruction is deprecated in favor of using label (line 2)
# 查看本地镜像
[root@docker dockerfile_test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
box v2 98fdc02ca732 3 seconds ago 1.15MB
box v1 d59c675982d8 6 years ago 1.15MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/e2e-test-images/busybox 1.29-4 d59c675982d8 6 years ago 1.15MB
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
# 运行容器并检查
[root@docker dockerfile_test]# docker run -it box:v2 sh -c "ls / ;cat /tmp/date.txt"
bin box01 dev etc home mkdir proc root sys tmp usr var
Mon Nov 10 11:34:31 UTC 2025
[root
4.5 示例二
--build-arg小测试
cs
[root@docker dockerfile_test]# cat Dockerfile
FROM box:v1
MAINTAINER ink 17611028236@163.com
ARG name
ARG age
RUN echo $name > /name.txt
RUN echo $age > /age.txt
# 创建镜像
[root@docker dockerfile_test]# docker build --build-arg name=ink --build-arg age=23 -t box:v3 .
[+] Building 0.5s (7/7) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 153B 0.0s
=> WARN: MaintainerDeprecated: Maintainer instruction is deprecated in favor of using label (line 2) 0.0s
=> [internal] load metadata for docker.io/library/box:v1 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> CACHED [1/3] FROM docker.io/library/box:v1 0.0s
=> [2/3] RUN echo ink > /name.txt 0.2s
=> [3/3] RUN echo 23 > /age.txt 0.2s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:102338bc2059bf66aae4607308b445200da4000c2ef46b0bc2e58ced0493907a 0.0s
=> => naming to docker.io/library/box:v3 0.0s
1 warning found (use docker --debug to expand):
- MaintainerDeprecated: Maintainer instruction is deprecated in favor of using label (line 2)
# 查看本地镜像
[root@docker dockerfile_test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
box v3 102338bc2059 25 seconds ago 1.15MB
box v2 5ffb34c5b85d 7 minutes ago 1.15MB
box v1 d59c675982d8 6 years ago 1.15MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/e2e-test-images/busybox 1.29-4 d59c675982d8 6 years ago 1.15MB
m.daocloud.io/k8s.gcr.io/nginx latest bf15594d61ad 10 years ago 426MB
# 运行容器并检查
[root@docker dockerfile_test]# docker run -it box:v3 sh -c "ls; cat name.txt; cat age.txt"
age.txt bin dev etc home name.txt proc root sys tmp usr var
ink
23
4.6 Python应用
(1) 准备工作
bash
yum -y install pip
pip install ipython flask
In [2]: import socket
In [3]: socket.gethostname()
Out[3]: 'docker'
In [5]: socket.gethostbyname('docker')
Out[5]: '192.168.159.133
(2)创建网站目录
cs
[root@docker ~]# mkdir /python_app
[root@docker python_app]# cd /python_app
[root@docker python_app]# vim app.py
[root@docker python_app]# cat app.py
from flask import Flask
import socket
import os
app = Flask(__name__)
@app.route('/')
def hello():
html = "<h3>Hello {name}!</h3><b>Hostname:</b> {hostname}<br/><p>这是我的网页,我的ip地址是:</p>{ip}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), ip=socket.gethostbyname('docker'))
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
[root@docker python_app]# python app.py
(3)浏览器测试

(4)改进版
cs
[root@docker python_app]# ls
app02.py app.py
[root@docker python_app]# vim app02.py
[root@docker python_app]# python app02.py
[root@docker python_app]# cat app02.py
from flask import Flask
import socket
import os
app = Flask(__name__)
@app.route('/')
def hello():
html = '''<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>主机信息表</title>
<style>
table {{
width: 50%;
border-collapse: collapse;
margin: 20px auto;
}}
th, td {{
border: 1px solid #333;
padding: 8px 12px;
text-align: center;
}}
th {{
background-color: #f2f2f2;
}}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>欢迎语</th>
<th>信息</th>
</tr>
</thead>
<tbody>
<tr>
<td>欢迎语</td>
<td>World Peace</td>
</tr>
<tr>
<td>主机名称</td>
<td id="hostname">{hostname}</td>
</tr>
<tr>
<td>IP地址</td>
<td id="ip">{ip}</td>
</tr>
</tbody>
</table>
</body>'''
return html.format(hostname=socket.gethostname(),ip=socket.gethostbyname('docker'))
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)

4.7 容器化Python的Flask应用
(1)创建应用目录
cs
[root@docker ~]# mkdir /flask-app
[root@docker ~]# cd /flask-app
[root@docker flask-app]# touch app.py Dockerfile
[root@docker flask-app]# ls
app.py Dockerfile
[root@docker flask-app]# cat Dockerfile
FROM docker.1ms.run/library/python:latest
WORKDIR /flask-app
ADD . /flask-app
RUN pip install -i https://mirrors.cloud.tencent.com/pypi/simple/ --trusted-host mirrors.cloud.tencent.com flask
EXPOSE 80
ENV NAME=World
CMD ["python", "app.py"]
[root@docker flask-app]# cat app.py
from flask import Flask
import socket
import os
app = Flask(__name__)
@app.route('/')
def hello():
html = '''<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>主机信息表</title>
<style>
table {{
width: 50%;
border-collapse: collapse;
margin: 20px auto;
}}
th, td {{
border: 1px solid #333;
padding: 8px 12px;
text-align: center;
}}
th {{
background-color: #f2f2f2;
}}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>欢迎语</th>
<th>信息</th>
</tr>
</thead>
<tbody>
<tr>
<td>欢迎语</td>
<td>World Peace</td>
</tr>
<tr>
<td>主机名称</td>
<td id="hostname">{hostname}</td>
</tr>
</tbody>
</table>
</body>'''
return html.format(hostname=socket.gethostname())
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
(2)构建并运行Flask应用的Docker容器
cs
[root@docker flask-app]# docker build -t my-flask-app .
[root@docker flask-app]# docker run -p 4000:80 my-flask-app
(3)浏览器访问测试

4.8 Dockerfile多阶段构建
多阶段构建的作用
减少镜像大小:最终镜像只包含运行应用所需的最小文件,而不包括构建时产生的中间文件和依赖
提高构建效率:通过分阶段构建,可以在前几个阶段中缓存构建结果,加快后续阶段的构建速度
提高安全性:减少不必要的文件和依赖,可以降低潜在的安全风险
减少镜像大小是Dockerfile多阶段构建最主要的作用!
(1) 编译 Go 项目,并打包成镜像
cs
# 创建应用目录
[root@docker ~]# mkdir /go-app
# 使用多阶段构建
[root@docker go-app]# cat Dockerfile
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/golang:alpine AS build-stage
WORKDIR /go-app
COPY <<EOF ./main.go
package main
import "fmt"
func main() {
fmt.Println("hello, world")
}
EOF
RUN go build -o /hello ./main.go
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/alpine:3.19
COPY --from=build-stage /hello /hello
ENTRYPOINT [ "/hello" ]
[root@docker go-app]# docker build -t hello:multi .
# 未使用多阶段构建
[root@docker go-app]# cat Dockerfile
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/golang:alpine AS build-stage
WORKDIR /go-app
COPY <<EOF ./main.go
package main
import "fmt"
func main() {
fmt.Println("hello, world")
}
EOF
RUN go build -o /hello ./main.go
#FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/alpine:3.19
#COPY --from=build-stage /hello /hello
ENTRYPOINT [ "/hello" ]
[root@docker go-app]# docker build -t hello:single .
# 查看镜像大小
[root@docker go-app]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello multi f5a20dc200da About a minute ago 9.29MB
hello single 92b87b3475b8 About a minute ago 260MB
my-flask-app latest 16cd998ca30f 3 days ago 1.13GB
docker.1ms.run/tomcat latest 5212b7f54ba8 7 days ago 412MB
docker.1ms.run/nginx latest d261fd19cb63 2 weeks ago 152MB
docker.1ms.run/redis latest 017b1c12abf9 2 weeks ago 137MB
docker.1ms.run/mysql latest f6b0ca07d79d 3 weeks ago 934MB
192.168.159.134:80/test/busybox v1 08ef35a1c3f0 13 months ago 4.43MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/alpine 3.19 494edff73605 16 months ago 7.4MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/golang alpine a60a31a97fdb 16 months ago 231MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/uifd/ui-for-docker latest 965940f98fa5 9 years ago 8.1MB
# 容器运行结果一致
[root@docker go-app]# docker run hello:multi
hello, world
[root@docker go-app]# docker run hello:single
hello, world

(2) 导出编译产物
cs
[root@docker go-app]# cat Dockerfile
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/golang:alpine AS build-stage
WORKDIR /go-app
COPY <<EOF ./main.go
package main
import "fmt"
func main() {
fmt.Println("hello, world")
}
EOF
RUN go build -o /hello ./main.go
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/alpine:3.19
COPY --from=build-stage /hello /hello
[root@docker go-app]# docker build --output "$PWD" "$PWD"
[root@docker go-app]# ls
bin dev Dockerfile etc hello home lib media mnt opt proc root run sbin srv sys tmp usr var
[root@docker go-app]# ./hello
hello, world
(3) 完成构建镜像和导出二进制的任务
(1)和(2)的结合
cs
[root@docker go-app]# cat Dockerfile
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/golang:alpine AS build-stage
WORKDIR /go-app
COPY <<EOF ./main.go
package main
import "fmt"
func main() {
fmt.Println("hello, world")
}
EOF
# 改1
RUN CGO_ENABLED=0 GOOS=linux go build -o /hello ./main.go
# 改2
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/alpine:3.19 AS export-stage
COPY --from=build-stage /hello /hello
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/alpine:3.19 AS deploy-stage
COPY --from=build-stage /hello /hello
ENTRYPOINT [ "/hello" ]
[root@docker go-app]# docker build -t hello:multi_ouput .
[+] Building 0.0s (12/12) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 604B 0.0s
=> [internal] load metadata for swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/alpine:3.19 0.0s
=> [internal] load metadata for swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/golang:alpine 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [build-stage 1/4] FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/golang:alpine 0.0s
=> [deploy-stage 1/2] FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/alpine:3.19 0.0s
=> [internal] preparing inline document 0.0s
=> CACHED [build-stage 2/4] WORKDIR /go-app 0.0s
=> CACHED [build-stage 3/4] COPY <<EOF ./main.go 0.0s
=> CACHED [build-stage 4/4] RUN CGO_ENABLED=0 GOOS=linux go build -o /hello ./main.go 0.0s
=> CACHED [deploy-stage 2/2] COPY --from=build-stage /hello /hello 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:f5a20dc200daef8cbd29640c1c46fd1da7c53296cf28db739941fee437239c3c 0.0s
=> => naming to docker.io/library/hello:multi_ouput 0.0s
[root@docker go-app]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello single 92b87b3475b8 2 hours ago 260MB
hello multi f5a20dc200da 2 hours ago 9.29MB
hello multi_ouput f5a20dc200da 2 hours ago 9.29MB
my-flask-app latest 16cd998ca30f 3 days ago 1.13GB
docker.1ms.run/tomcat latest 5212b7f54ba8 7 days ago 412MB
docker.1ms.run/nginx latest d261fd19cb63 2 weeks ago 152MB
docker.1ms.run/redis latest 017b1c12abf9 2 weeks ago 137MB
docker.1ms.run/mysql latest f6b0ca07d79d 3 weeks ago 934MB
192.168.159.134:80/test/busybox v1 08ef35a1c3f0 13 months ago 4.43MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/alpine 3.19 494edff73605 16 months ago 7.4MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/golang alpine a60a31a97fdb 16 months ago 231MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/uifd/ui-for-docker latest 965940f98fa5 9 years ago 8.1MB
[root@docker go-app]# ls
Dockerfile
而若我们只需要导出可执行文件(即 export-stage)而不需要构建镜像(即 deploy-stage)时,我们可以指定 --target 选项,这样就只会执行 target stage 及之前的 stage 的逻辑了(即完成 export-stage 后就结束 docker build
docker build \
--target export-stage \
--output "$PWD" \
"$PWD"
docker build --target deploy-stage -t a 的执行)
五、Docker私有仓库
1. 拉取registry镜像并运行为容器
cs
# 拉取镜像 registry, 用于搭建私有仓库
[root@docker-registry ~]# docker pull docker.1ms.run/registry
# 查看镜像
[root@docker-registry ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/registry latest e4e570676819 7 months ago 57.7MB
# 运行容器
[root@docker-registry ~]# docker run --name="pri_registry" --restart=always -d -p 5000:5000 docker.1ms.run/registry:latest
e60447518a72700912ed2df63f121ed4e531df9a8385002663a347373c9b72bf
# 查看容器
[root@docker-registry ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e60447518a72 docker.1ms.run/registry:latest "/entrypoint.sh /etc..." 3 seconds ago Up 3 seconds 0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp pri_registry
# 连接容器查看端口状态
[root@docker-registry ~]# docker exec -it e60447518a72 /bin/sh
/ # netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::5000 :::* LISTEN 1/registry
tcp 0 0 :::5001 :::* LISTEN 1/registry
/ #
# 测试访问本地5000端口
[root@docker-registry ~]# curl -I 127.1:5000
HTTP/1.1 200 OK
Cache-Control: no-cache
Date: Thu, 13 Nov 2025 11:23:17 GMT
2. 仓库功能测试
cs
# 拉取用于测试的镜像
[root@docker-registry ~]# docker pull docker.1ms.run/busybox
[root@docker-registry ~]# docker pull docker.1ms.run/mysql
[root@docker-registry ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/mysql latest f6b0ca07d79d 3 weeks ago 934MB
docker.1ms.run/registry latest e4e570676819 7 months ago 57.7MB
docker.1ms.run/busybox latest 08ef35a1c3f0 13 months ago 4.43MB
# 创建镜像别名(IP地址为私有仓库服务器的IP)
[root@docker-registry ~]# docker tag docker.1ms.run/busybox:latest 192.168.159.134:5000/busybox
[root@docker-registry ~]# docker tag docker.1ms.run/mysql:latest 192.168.159.134:5000/mysql
# 查看镜像
[root@docker-registry ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.159.134:5000/mysql latest f6b0ca07d79d 3 weeks ago 934MB
docker.1ms.run/mysql latest f6b0ca07d79d 3 weeks ago 934MB
docker.1ms.run/registry latest e4e570676819 7 months ago 57.7MB
192.168.159.134:5000/busybox latest 08ef35a1c3f0 13 months ago 4.43MB
docker.1ms.run/busybox latest 08ef35a1c3f0 13 months ago 4.43MB
# 修改请求方式为http
[root@docker-registry ~]# vim /etc/docker/daemon.json
[root@docker-registry ~]# cat /etc/docker/daemon.json
{ "insecure-registries":["192.168.159.134:5000"] }
# 重启docker使配置生效
[root@docker-registry ~]# systemctl restart docker.service
# 上传镜像到私有仓库(只会推送到当前Docker客户端配置的仓库)
[root@docker-registry ~]# docker push 192.168.159.134:5000/busybox
[root@docker-registry ~]# docker push 192.168.159.134:5000/mysql
# 查看私有仓库里的所有镜像(本地或者其他节点上查看)
[root@docker ~]# curl 192.168.159.134:5000/v2/_catalog
{"repositories":["busybox","mysql"]}
[root@docker ~]# curl http://192.168.159.134:5000/v2/busybox/tags/list
{"name":"busybox","tags":["latest"]}
[root@docker ~]# curl http://192.168.159.134:5000/v2/mysql/tags/list
{"name":"mysql","tags":["latest"]}
3. 其他节点拉取私有仓库的镜像
cs
# 拉取之前的镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/tomcat latest 5212b7f54ba8 2 days ago 412MB
docker.1ms.run/python latest 0134b02fcae7 8 days ago 1.12GB
docker.1ms.run/nginx latest d261fd19cb63 9 days ago 152MB
docker.1ms.run/redis latest 017b1c12abf9 9 days ago 137MB
docker.1ms.run/mysql latest f6b0ca07d79d 3 weeks ago 934MB
# 修改请求方式为http
[root@docker ~]# vim /etc/docker/daemon.json
[root@docker ~]# cat /etc/docker/daemon.json
{ "insecure-registries":["192.168.159.134:5000"] }
[root@docker ~]# systemctl restart docker.service
# 拉取私有仓库的镜像busybox
[root@docker ~]# docker pull 192.168.159.134:5000/busybox
Using default tag: latest
latest: Pulling from busybox
bb1275e1a759: Pull complete
Digest: sha256:be49435f6288f9c5cce0357c2006cc266cb5c450dbd6dc8e3a3baec10c46b065
Status: Downloaded newer image for 192.168.159.134:5000/busybox:latest
192.168.159.134:5000/busybox:latest
# 查看本地镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/tomcat latest 5212b7f54ba8 2 days ago 412MB
docker.1ms.run/python latest 0134b02fcae7 8 days ago 1.12GB
docker.1ms.run/nginx latest d261fd19cb63 9 days ago 152MB
docker.1ms.run/redis latest 017b1c12abf9 9 days ago 137MB
docker.1ms.run/mysql latest f6b0ca07d79d 3 weeks ago 934MB
192.168.159.134:5000/busybox latest 08ef35a1c3f0 13 months ago 4.43MB
注意:
必须修改/etc/docker/daemon.json文件
否则会出现以下报错
root@docker \~\]# docker pull 192.168.159.134:5000/busybox Using default tag: latest Error response from daemon: Get "https://192.168.159.134:5000/v2/": http: server gave HTTP response to HTTPS client
六、部署Docker-WebUI
1. 配置工作
cs
# 拉取webui的镜像
[root@docker ~]# docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/uifd/ui-for-docker:latest
# 查看镜像
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/tomcat latest 5212b7f54ba8 2 days ago 412MB
docker.1ms.run/python latest 0134b02fcae7 8 days ago 1.12GB
docker.1ms.run/nginx latest d261fd19cb63 9 days ago 152MB
docker.1ms.run/redis latest 017b1c12abf9 9 days ago 137MB
docker.1ms.run/mysql latest f6b0ca07d79d 3 weeks ago 934MB
192.168.159.134:5000/busybox latest 08ef35a1c3f0 13 months ago 4.43MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/uifd/ui-for-docker latest 965940f98fa5 9 years ago 8.1MB
# 运行容器
[root@docker ~]# docker run -itd --name docker-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/uifd/ui-for-docker:latest
# 查看容器ID
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
491517c0ffdf swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/uifd/ui-for-docker:latest "/ui-for-docker" 2 seconds ago Up 2 seconds 0.0.0.0:9000->9000/tcp, [::]:9000->9000/tcp docker-web
# 启动webui容器
[root@docker ~]# docker start 491517c0ffdf
2. 浏览器测试



七、部署第三方镜像仓库 --- Harbor镜像仓库
1. 下载安装
docker-compose下载地址: https://github.com/docker/compose/releases
cs
# 安装harbor软件包
[root@docker-registry ~]# ls
harbor-offline-installer-v2.12.0-rc1.tgz
[root@docker-registry ~]# tar -xf harbor-offline-installer-v2.12.0-rc1.tgz
[root@docker-registry ~]# mv harbor/ /usr/local/harbor
[root@docker-registry ~]# cd /usr/local/harbor
[root@docker-registry harbor]# ls
common.sh harbor.v2.12.0.tar.gz harbor.yml.tmpl install.sh LICENSE prepare
# 修改配置文件(hostname和注释掉HTTPS保留HTTP)
[root@docker-registry harbor]# mv harbor.yml.tmpl harbor.yml
[root@docker-registry harbor]# vim harbor.yml
[root@docker-registry harbor]# grep -vE "^.*#|^$" harbor.yml
hostname: 192.168.159.134
http:
port: 80
harbor_admin_password: Harbor12345
database:
password: root123
max_idle_conns: 100
max_open_conns: 900
conn_max_lifetime: 5m
conn_max_idle_time: 0
data_volume: /data
trivy:
ignore_unfixed: false
skip_update: false
skip_java_db_update: false
offline_scan: false
security_check: vuln
insecure: false
timeout: 5m0s
jobservice:
max_job_workers: 10
job_loggers:
- STD_OUTPUT
- FILE
notification:
webhook_job_max_retry: 3
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor
_version: 2.12.0
proxy:
http_proxy:
https_proxy:
no_proxy:
components:
- core
- jobservice
- trivy
upload_purging:
enabled: true
age: 168h
interval: 24h
dryrun: false
cache:
enabled: false
expire_hours: 24
[root@docker-registry harbor]# ./install.sh
注意:如果第一次安装报如下错误,则执行./prepare命令后,重新运行安装脚本即可
ERROR: for postgresql Cannot start service postgresql: failed to create endpoint harbor-db on network harbor_harbor: failed to add the host (veth841e806) <=> sandbox (veth1c76e7a) pair interfaces: operation not permitted
cd到harbor.yml文件所在位置:
docker-compose down
vim harbor.yml
./prepare
docker-compose up -d
2. 启动和关闭Harbor
cs
# 进入Harbor的安装目录(必要操作!)
[root@docker-registry ~]# cd /usr/local/harbor/
# 启动Harbor
[root@docker-registry harbor]# docker compose up -d
[root@docker-registry harbor]# ps aux | grep harbor
10000 2152 0.7 0.7 1442456 28656 ? Ssl 21:36 0:00 /home/harbor/harbor_registryctl -c /etc/registryctl/config.yml
10000 2369 3.2 2.4 1636044 92348 ? Ssl 21:36 0:00 /harbor/harbor_core
10000 2639 0.6 1.1 1605092 43620 ? Ssl 21:36 0:00 /harbor/harbor_jobservice -c /etc/jobservice/config.yml
root 2686 0.0 0.0 6408 2176 pts/0 S+ 21:36 0:00 grep --color=auto harbor
# 关闭Harbor
[root@docker-registry harbor]# docker compose down
[root@docker-registry harbor]# ps aux | grep harbor
root 3142 0.0 0.0 6408 2176 pts/0 S+ 21:37 0:00 grep --color=auto harbor
3. 浏览器测试Harbor

4. Harbor仓库使用
4.1 新建项目


4.2 创建用户


4.3 项目授权



4.4 登录Harbor仓库
cs
[root@docker ~]# vim /etc/docker/daemon.json
[root@docker ~]# cat /etc/docker/daemon.json
{ "insecure-registries":["192.168.159.134:80"] }
[root@docker ~]# systemctl restart docker.service
# 客户端/etc/hosts一定要加上harbor服务器的解析
[root@docker ~]# vim /etc/hosts
[root@docker ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.159.134 registry
# 检查连通性
[root@docker ~]# ping -c3 192.168.159.134
PING 192.168.159.134 (192.168.159.134) 56(84) bytes of data.
64 bytes from 192.168.159.134: icmp_seq=1 ttl=64 time=0.376 ms
64 bytes from 192.168.159.134: icmp_seq=2 ttl=64 time=0.480 ms
64 bytes from 192.168.159.134: icmp_seq=3 ttl=64 time=0.470 ms
--- 192.168.159.134 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2026ms
rtt min/avg/max/mdev = 0.376/0.442/0.480/0.046 ms
# 登录
[root@docker ~]# docker login 192.168.159.134:80
Username: ink
Password:
WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/
Login Succeeded
如果客户端/etc/hosts没有加上harbor服务器的解析,将报错如下:
root@docker \~\]# docker login 192.168.159.134:80 Username: ink Password: Error response from daemon: Get "http://192.168.159.134:80/v2/": unauthorized:
4.5 Harbor仓库上传和拉取镜像
(1) 上传busybox镜像
cs
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/tomcat latest 5212b7f54ba8 2 days ago 412MB
docker.1ms.run/python latest 0134b02fcae7 9 days ago 1.12GB
docker.1ms.run/nginx latest d261fd19cb63 9 days ago 152MB
docker.1ms.run/redis latest 017b1c12abf9 9 days ago 137MB
docker.1ms.run/mysql latest f6b0ca07d79d 3 weeks ago 934MB
192.168.159.134:5000/busybox latest 08ef35a1c3f0 13 months ago 4.43MB
docker.1ms.run/busybox latest 08ef35a1c3f0 13 months ago 4.43MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/uifd/ui-for-docker latest 965940f98fa5 9 years ago 8.1MB
[root@docker ~]# docker tag docker.1ms.run/busybox:latest 192.168.159.134:80/test/busybox:v1
[root@docker ~]# docker push 192.168.159.134:80/test/busybox:v1

(2)拉取镜像
cs
# 删除本地的busybox镜像便于测试
[root@docker ~]# docker rmi 08ef35a1c3f0 -f
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/tomcat latest 5212b7f54ba8 2 days ago 412MB
docker.1ms.run/python latest 0134b02fcae7 9 days ago 1.12GB
docker.1ms.run/nginx latest d261fd19cb63 9 days ago 152MB
docker.1ms.run/redis latest 017b1c12abf9 9 days ago 137MB
docker.1ms.run/mysql latest f6b0ca07d79d 3 weeks ago 934MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/uifd/ui-for-docker latest 965940f98fa5 9 years ago 8.1MB
# 拉取Harbor仓库镜像
[root@docker ~]# docker pull 192.168.159.134:80/test/busybox:v1
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/tomcat latest 5212b7f54ba8 2 days ago 412MB
docker.1ms.run/python latest 0134b02fcae7 9 days ago 1.12GB
docker.1ms.run/nginx latest d261fd19cb63 9 days ago 152MB
docker.1ms.run/redis latest 017b1c12abf9 9 days ago 137MB
docker.1ms.run/mysql latest f6b0ca07d79d 3 weeks ago 934MB
192.168.159.134:80/test/busybox v1 08ef35a1c3f0 13 months ago 4.43MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/uifd/ui-for-docker latest 965940f98fa5 9 years ago 8.1MB
4.6 重置Harbor密码
cs
[root@docker-registry ~]# docker exec -it harbor-db /bin/bash
postgres [ / ]$ psql -h postgresql -d postgres -U postgres
Password for user postgres: # 这里输入root123(harbor.yml文件中的)
psql (15.8)
Type "help" for help.
postgres=# \c registry
You are now connected to database "registry" as user "postgres".
registry=# select * from harbor_user;
user_id | username | email | password | realname | comment | deleted | reset_uuid | salt | s
ysadmin_flag | creation_time | update_time | password_version
---------+-----------+---------------------+----------------------------------+----------------+-----------------------------+---------+------------+----------------------------------+--
-------------+----------------------------+----------------------------+------------------
2 | anonymous | | | anonymous user | anonymous user | t | | | f
| 2025-11-13 13:23:38.914258 | 2025-11-13 13:23:39.079798 | sha1
1 | admin | | 89616bb9236eb94705341d5435f695d1 | system admin | admin user | f | | rjW2NzOb5hSJVSBTNCUpgHEsc5eoOqFh | t
| 2025-11-13 13:23:38.914258 | 2025-11-13 13:23:39.361156 | sha256
3 | ink | 17611028236@163.com | 305d08b94efd491078895456ee215c43 | ink | user_password : Harbor12345 | f | | pX4H0C3BijrSMaUfa1Wc5FyxkaXiObbw | f
| 2025-11-13 13:53:49.692137 | 2025-11-13 13:56:32.239718 | sha256
(3 rows)
registry=# update harbor_user set password='89616bb9236eb94705341d5435f695d1', salt='rjW2NzOb5hSJVSBTNCUpgHEsc5eoOqFh' where user='admin';
UPDATE 0
registry=# \q
postgres [ / ]$ exit
exit
八、端口转发
1. MySQL
cs
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/library/redis latest 6a528f7fe7d1 3 hours ago 137MB
docker.1ms.run/library/mysql latest f6b0ca07d79d 3 weeks ago 934MB
[root@docker ~]# docker run --name some-mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123 -d docker.1ms.run/library/mysql:latest
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d0ba5107241 docker.1ms.run/library/mysql:latest "docker-entrypoint.s..." 4 minutes ago Up 4 minutes 33060/tcp, 0.0.0.0:3307->3306/tcp, [::]:3307->3306/tcp some-mysql
[root@docker ~]# docker inspect --format='{{.NetworkSettings.Networks.bridge.IPAddress}}' 5d0ba5107241
172.17.0.2
[root@docker ~]# yum -y install mysql
[root@docker ~]# mysql -uroot -p'123' -h 192.168.159.134 -P 3307
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 9.5.0 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
# 通过--link的方式连接,这种方式可以直接使用mysql服务端容器的名称来当做ip地址使用
[root@docker ~]# docker run -it --rm --link some-mysql:mysql_link docker.1ms.run/library/mysql:latest mysql -uroot -p'123' -h some-mysql
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 9.5.0 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.002 sec)
2. Redis
cs
[root@docker ~]# docker run -d --name myredis -P docker.1ms.run/library/redis:latest
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27830326fd1e docker.1ms.run/library/redis:latest "docker-entrypoint.s..." 5 seconds ago Up 5 seconds 0.0.0.0:32768->6379/tcp, [::]:32768->6379/tcp myredis
5d0ba5107241 docker.1ms.run/library/mysql:latest "docker-entrypoint.s..." 14 minutes ago Up 14 minutes 33060/tcp, 0.0.0.0:3307->3306/tcp, [::]:3307->3306/tcp some-mysql
# 另运行一个redis容器并且使用--link连接到上面的myredis,使用内置redis-cli连接myredis容器写入数据
[root@docker ~]# docker run --rm -it --name myredis2 --link myredis:redisdb docker.1ms.run/library/redis:latest /bin/bash
root@e3f807bfebf8:/data# redis-cli -h redisdb
redisdb:6379> set name "ink"
OK
redisdb:6379> set age 23
OK
redisdb:6379> get name
"ink"
redisdb:6379> get age
"23"
# 在别的机器上通过上面映射的端口32768连接这个容器的redis(确保该机器已部署redis)
[root@redis redis]# /usr/local/redis/src/redis-cli -h 192.168.159.134 -p 32768
192.168.159.134:32768> get name
"ink"
192.168.159.134:32768> get age
"23"
九、容器卷
cs
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/library/redis latest 6a528f7fe7d1 4 hours ago 137MB
docker.1ms.run/library/mysql latest f6b0ca07d79d 3 weeks ago 934MB
centos 7.6 f1cb7c7d58b7 6 years ago 202MB
swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/centos/centos 7.6.1810 f1cb7c7d58b7 6 years ago 202MB
[root@docker ~]# docker run -it --name="volume_test" -v /tmp:/test centos:7.6 /bin/bash
[root@e9e8aa4f6dd4 /]# ls /
anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys test tmp usr var
[root@e9e8aa4f6dd4 /]# cd test/
[root@e9e8aa4f6dd4 test]# ls
systemd-private-807d1404a1ca466995061a37836baeca-chronyd.service-2Y7E4E vmware-root_859-3988752861
systemd-private-807d1404a1ca466995061a37836baeca-dbus-broker.service-vqPhEy vmware-root_860-2722763268
systemd-private-807d1404a1ca466995061a37836baeca-irqbalance.service-LfZRaO vmware-root_875-4022308853
systemd-private-807d1404a1ca466995061a37836baeca-kdump.service-KpwD5k vmware-root_879-4013723248
systemd-private-807d1404a1ca466995061a37836baeca-systemd-logind.service-EdFgxg vmware-root_918-2697532712
# 在宿主机/tmp下创建测试文件
[root@docker tmp]# ls
systemd-private-807d1404a1ca466995061a37836baeca-chronyd.service-2Y7E4E vmware-root_859-3988752861
systemd-private-807d1404a1ca466995061a37836baeca-dbus-broker.service-vqPhEy vmware-root_860-2722763268
systemd-private-807d1404a1ca466995061a37836baeca-irqbalance.service-LfZRaO vmware-root_875-4022308853
systemd-private-807d1404a1ca466995061a37836baeca-kdump.service-KpwD5k vmware-root_879-4013723248
systemd-private-807d1404a1ca466995061a37836baeca-systemd-logind.service-EdFgxg vmware-root_918-2697532712
[root@docker tmp]# echo hello > hello.txt
[root@docker tmp]# ls
hello.txt vmware-root_859-3988752861
systemd-private-807d1404a1ca466995061a37836baeca-chronyd.service-2Y7E4E vmware-root_860-2722763268
systemd-private-807d1404a1ca466995061a37836baeca-dbus-broker.service-vqPhEy vmware-root_875-4022308853
systemd-private-807d1404a1ca466995061a37836baeca-irqbalance.service-LfZRaO vmware-root_879-4013723248
systemd-private-807d1404a1ca466995061a37836baeca-kdump.service-KpwD5k vmware-root_918-2697532712
systemd-private-807d1404a1ca466995061a37836baeca-systemd-logind.service-EdFgxg
[root@docker tmp]# cat hello.txt
hello
# 查看容器/test目录下是否有变化
[root@e9e8aa4f6dd4 test]# ls
hello.txt vmware-root_859-3988752861
systemd-private-807d1404a1ca466995061a37836baeca-chronyd.service-2Y7E4E vmware-root_860-2722763268
systemd-private-807d1404a1ca466995061a37836baeca-dbus-broker.service-vqPhEy vmware-root_875-4022308853
systemd-private-807d1404a1ca466995061a37836baeca-irqbalance.service-LfZRaO vmware-root_879-4013723248
systemd-private-807d1404a1ca466995061a37836baeca-kdump.service-KpwD5k vmware-root_918-2697532712
systemd-private-807d1404a1ca466995061a37836baeca-systemd-logind.service-EdFgxg
[root@e9e8aa4f6dd4 test]# cat hello.txt
hello
# 新建第二个容器,宿主机/tmp同样挂载到该容器的/test目录
[root@docker ~]# docker run -it --name="volume_test02" -v /tmp:/test centos:7.6 /bin/bash
[root@fc79ca173f66 /]# ls /
anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys test tmp usr var
[root@fc79ca173f66 /]# ls /test/
hello.txt vmware-root_859-3988752861
systemd-private-807d1404a1ca466995061a37836baeca-chronyd.service-2Y7E4E vmware-root_860-2722763268
systemd-private-807d1404a1ca466995061a37836baeca-dbus-broker.service-vqPhEy vmware-root_875-4022308853
systemd-private-807d1404a1ca466995061a37836baeca-irqbalance.service-LfZRaO vmware-root_879-4013723248
systemd-private-807d1404a1ca466995061a37836baeca-kdump.service-KpwD5k vmware-root_918-2697532712
systemd-private-807d1404a1ca466995061a37836baeca-systemd-logind.service-EdFgxg
[root@fc79ca173f66 /]# cat /test/hello.txt
hello
十、Docker网络
1. 查看当前网络
1、bridge:网络桥接
默认情况下启动、创建容器都是用该模式,所以每次docker容器重启时会按照顺序获取对应ip地址,这就导致容器每次重启,ip都发生变化
2、none:无指定网络
启动容器时,可以通过--network=none,docker容器不会分配局域网ip
3、host:主机网络
docker容器的网络会附属在主机上,两者是互通的。
cs
[root@docker ~]# docker network list
NETWORK ID NAME DRIVER SCOPE
6c9f06310b2d bridge bridge local
7636cad7be36 host host local
397eca4a52c8 none null local
十一、Docker Compose
1. 编写简单的compose文件
cs
# 创建应用目录
[root@docker ~]# mkdir /compose-test
[root@docker ~]# cd /compose-test
[root@docker compose-test]# docker compose version
Docker Compose version v2.6.0
[root@docker compose-test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/nginx latest 60adc2e137e7 27 hours ago 152MB
[root@docker compose-test]# cat nginx.yml
services:
web:
image: docker.1ms.run/nginx:latest
ports:
- "80:80"
# 验证 YAML 文件语法是否正确
[root@docker compose-test]# docker compose -f nginx.yml config
name: composr-test
services:
web:
image: docker.1ms.run/nginx:latest
networks:
default: null
ports:
- mode: ingress
target: 80
published: "80"
protocol: tcp
networks:
default:
name: composr-test_default
# 启动nginx服务
[root@docker compose-test]# docker compose -f nginx.yml up -d
[+] Running 2/2
⠿ Network composr-test_default Created 0.0s
⠿ Container composr-test-web-1 Started 0.3s
# 查看nginx服务状态
[root@docker compose-test]# docker compose -f nginx.yml ps
NAME COMMAND SERVICE STATUS PORTS
composr-test-web-1 "/docker-entrypoint...." web running 0.0.0.0:80->80/tcp, :::80->80/tcp
# 关闭nginx服务
[root@docker compose-test]# docker compose -f nginx.yml down
[+] Running 2/2
⠿ Container composr-test-web-1 Removed 0.1s
⠿ Network composr-test_default Removed
默认将会使用 项目名称-服务名称-序号 这样的格式,项目名称即当前所在目录名。
不要手动指定容器名称,指定容器名称后,该服务将无法进行扩展(scale),因为 Docker 不允许多个容器具有相同的名称
2. 测试
cs
[root@docker compose-test]# rpm -q nginx
package nginx is not installed
[root@docker compose-test]# curl 127.1
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
3. 资源限制和优化的compose文件
cs
[root@docker composr-test]# cat nginx01.yml
services:
web:
image: docker.1ms.run/nginx:latest
ports:
- "80:80"
volumes:
- static_volume:/usr/share/nginx/html
networks:
- app_net
deploy:
resources:
limits:
cpus: '0.5'
memory: 200M
volumes:
static_volume:
networks:
app_net:
[root@docker composr-test]# docker compose -f nginx01.yml up -d
[+] Running 2/2
⠿ Network composr-test_app_net Created 0.0s
⠿ Container composr-test-web-1 Started 0.2s
[root@docker composr-test]# docker compose -f nginx01.yml ps
NAME COMMAND SERVICE STATUS PORTS
composr-test-web-1 "/docker-entrypoint...." web running 0.0.0.0:80->80/tcp, :::80->80/tcp
[root@docker composr-test]# docker stats composr-test-web-1

4. 部署 Flask + Redis 应用
cs
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.1ms.run/redis latest 1c390e3bb5cb 10 hours ago 139MB
docker.1ms.run/python latest 936d907e9a6c 20 hours ago 1.12GB
docker.1ms.run/nginx latest 60adc2e137e7 28 hours ago 152MB
# 应用目录
[root@docker ~]# cd /flask-redis/
[root@docker flask-redis]# ls
app.py docker-compose.yml Dockerfile requirements.txt
[root@docker flask-redis]# cat app.py
from flask import Flask
import redis
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
@app.route('/')
def count():
visits = cache.incr('hits')
return f'Total visits: {visits}'
[root@docker flask-redis]# cat requirements.txt
flask
redis
[root@docker flask-redis]# cat Dockerfile
FROM docker.1ms.run/python
WORKDIR /flask-redis
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run", "--host=0.0.0.0"]
[root@docker flask-redis]# cat docker-compose.yml
version: '2.6'
services:
web:
build: .
ports:
- "5000:5000"
environment:
FLASK_DEBUG: 1
depends_on:
- redis
redis:
image: docker.1ms.run/redis:latest
volumes:
- redis_data:/data
volumes:
redis_data: {}
# 运行服务
[root@docker flask-redis]# docker compose up -d
[root@docker flask-redis]# docker compose -f docker-compose.yml ps
NAME COMMAND SERVICE STATUS PORTS
flask-redis-redis-1 "docker-entrypoint.s..." redis running 6379/tcp
flask-redis-web-1 "flask run --host=0...." web running 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp
# 访问宿主机5000端口测试
[root@docker flask-redis]# curl 127.1:5000
Total visits: 2[root@docker flask-redis]# curl 127.1:5000
Total visits: 3
[root@docker flask-redis]# curl 127.1:5000
Total visits: 4
5. 完整 Docker Compose 示例
cs
[root@docker ~]# mkdir /compose-test02
[root@docker ~]# cd /compose-test02
