Docker环境搭建与容器管理实战:从部署到编排的完整指南

目录

一、Docker安装

[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文件)

四、Docker容器镜像制作

[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) 准备工作)

(2)创建网站目录

(3)浏览器测试

(4)改进版

[4.7 容器化Python的Flask应用](#4.7 容器化Python的Flask应用)

(1)创建应用目录

(2)构建并运行Flask应用的Docker容器

(3)浏览器访问测试

[4.8 Dockerfile多阶段构建](#4.8 Dockerfile多阶段构建)

[(1) 编译 Go 项目,并打包成镜像](#(1) 编译 Go 项目,并打包成镜像)

[(2) 导出编译产物](#(2) 导出编译产物)

[(3) 完成构建镜像和导出二进制的任务](#(3) 完成构建镜像和导出二进制的任务)

五、Docker私有仓库

[1. 拉取registry镜像并运行为容器](#1. 拉取registry镜像并运行为容器)

[2. 仓库功能测试](#2. 仓库功能测试)

[3. 其他节点拉取私有仓库的镜像](#3. 其他节点拉取私有仓库的镜像)

六、部署Docker-WebUI

[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镜像)

(2)拉取镜像

[4.6 重置Harbor密码](#4.6 重置Harbor密码)

八、端口转发

[1. MySQL](#1. MySQL)

[2. Redis](#2. Redis)

九、容器卷

十、Docker网络

[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)

Index of linux/centos/9/x86_64/stable/Packages/https://download.docker.com/linux/centos/9/x86_64/stable/Packages/

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 选择合适的基础镜像 选择轻量级、官方优化的基础镜像,如 AlpineScratch FROM alpine:latestFROM scratch
2 最小化安装软件包 只安装必要依赖,删除多余文件、文档和包,减少镜像体积。 RUN yum install -y nginx && yum clean all
3 使用多阶段构建 在一个镜像中编译,在另一个轻量镜像中运行,只保留最终产物。 FROM golang:alpine AS builderFROM alpine:latest
4 使用 .dockerignore 文件 排除不需复制进镜像的文件/目录,减少构建上下文。 .dockerignore 文件中添加:DockerfileREADME.mdtmp/
示例: # 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
相关推荐
qq_2153978972 小时前
docker 安装 redis
redis·docker·容器
RPA机器人就选八爪鱼3 小时前
RPA财务机器人:驱动财务数字化转型的核心引擎
大数据·运维·人工智能·机器人·rpa
-大头.4 小时前
Redis内存碎片深度解析:从动态整理到核心运维实践
运维·数据库·redis
huisheng_qaq4 小时前
【RocketMq源码篇-02】rocketmq集群搭建详细过程(docker版-2主2从)
docker·rocketmq·rocketmq集群·rocketmq源码·2主2从
qq_2153978974 小时前
docker 管理工具 Portainer安装
运维·服务器·docker
凤凰战士芭比Q4 小时前
Docker安装与常用命令
linux·运维·docker·容器
华哥啊.5 小时前
服务器安装node_exporter监测cpu以及内存相关情况
运维·服务器
SongYuLong的博客6 小时前
Ubuntu24.04搭建GitLab服务器
运维·服务器·gitlab
guygg886 小时前
Linux服务器上安装配置GitLab
linux·运维·gitlab