Docker全阶段
1. Docker发展与简介
1.1 云服务与虚拟化基础
1.1.1 云服务模型介绍
云计算 是通过网络为用户提供可伸缩的计算资源。云服务通常分为以下几种类型:
- IaaS(基础设施即服务)
- 提供虚拟化计算资源(如虚拟机、存储、网络等)。
- 用户可以灵活配置自己的计算环境,负责安装操作系统、管理资源等。
- 优点:灵活度高、可扩展性强。
- 缺点:管理复杂,需要较多技术支持。
- PaaS(平台即服务)
- 提供一个开发平台,用户可以在上面开发应用程序,而无需关注底层硬件或操作系统。
- 优点:简化开发过程,适合开发者。
- 缺点:灵活度较低,可能受到平台限制。
- SaaS(软件即服务)
- 提供已经构建好的应用程序,用户可以直接使用,无需安装和维护。
- 优点:快速部署,省时省力。
- 缺点:定制化差,依赖于服务提供商。
- DaaS(数据即服务)
- 提供数据处理和分析服务,用户可以访问、分析云端存储的大数据。
- 优点:降低用户管理数据的难度。
- 缺点:可能涉及数据隐私问题。
1.1.2 常见云服务提供商
- 阿里云 、腾讯云 、AWS 、Google Cloud 、华为云等是市场上主要的云服务提供商。
- 云服务提供商通常提供各种服务,如存储、计算、网络、CDN 等。
1.2 虚拟化技术概述
1.2.1 虚拟化基础
-
虚拟化类型
- 全虚拟化 :虚拟化软件完全模拟硬件环境,允许多个操作系统共享硬件资源,彼此之间相互独立。
- 适用场景:需要兼容多个操作系统(如 Linux 与 Windows 同时运行)的环境。
- 半虚拟化 :虚拟机与宿主操作系统协作,通过修改操作系统内核来提高性能。
- 适用场景:高性能需求的环境,尤其是优化了开源操作系统(如 Linux)的虚拟化。
- 全虚拟化 :虚拟化软件完全模拟硬件环境,允许多个操作系统共享硬件资源,彼此之间相互独立。
-
虚拟化产品
-
VMware:广泛使用的企业级虚拟化平台,支持全虚拟化和半虚 拟化。 企业版 mac fusion
EXSI企业版 vsphere work
-
Hyper-V:由微软推出的虚拟化平台,集成于 Windows Server 中。
-
VirtualBox:适用于个人和开发者的虚拟化产品,跨平台支持(Linux、macOS、Windows)。
-
1.3 Docker简介及其重要性
1.3.1. 为什么使用 Docker
Docker 是一种容器化技术,它使得开发者可以将应用及其依赖打包到一个标准化的容器中,从而在任何环境下都能一致地运行。这个概念类似于将应用放入一个容器(集装箱),无论容器被移动到哪个环境,它都能保持原有的运行状态。
容器技术相比传统的虚拟化技术(如 VMware)具有显著优势。传统虚拟化需要在每个虚拟机中运行完整的操作系统,资源消耗大,而 Docker 仅在宿主操作系统上运行多个隔离的容器,不需要完整的操作系统,大大减少了系统开销和资源浪费。
通过 Docker,应用可以更轻松地实现跨平台部署和运行。举个例子,一辆兰博基尼应用程序被装进集装箱(容器),可以在不同的操作系统上(如 CentOS 到 Ubuntu)无缝迁移,确保应用始终以相同的方式运行。
1.3.2 Docker 发展历史
Docker 是由 Solomon Hykes 和他团队在 2013 年从 DotCloud 开始开发的。它的最初目标是利用容器技术提供一种新的应用部署方式。Docker 从一开始就有了强大的生态系统和社区支持,迅速发展并成为全球最流行的容器化平台。
主要的发展节点包括:
-
2013年:Docker 项目发布;
-
2014年:Docker 公司成立;
-
2015年:Docker 发布了重要的版本 1.8,引入了新的网络架构和卷管理;
-
2017年:发布了 Docker Enterprise Edition(企业版)和 Docker Community Edition(社区版),并开始了时间驱动的版本发布。
-
2018年 : Docker 18.09 发布,加入了新的构建功能和改进的性能,重点是多阶段构建(Multi-stage Builds)和新的容器日志功能。
Docker 的 Kubernetes 集成 开始,推出了 Docker Desktop 中的 Kubernetes 支持,使得开发者可以在本地轻松使用 Kubernetes 来部署和管理容器。
-
2019年 :Docker 19.03 发布,新增了对 GPU 加速 的支持,以及 Docker CLI 的改进。此外,Docker 为 Kubernetes 提供了更好的支持。
Docker Desktop 的更新增强了与 Kubernetes 的集成,支持在 Windows 和 macOS 上直接运行 Kubernetes 集群。
Docker 提出了 Docker Desktop for Windows 和 macOS,为开发者提供了一个跨平台、统一的开发环境,结合了 Docker 引擎和 Kubernetes。
-
2020年 :Docker 20.10 发布,新增了对 Docker Compose v2 的支持,并在性能、功能和稳定性方面进行了一系列增强。
Docker 宣布将 Docker Swarm 和 Kubernetes 的集成进行区分,Kubernetes 成为 Docker 引擎推荐的容器编排工具。
Docker 开始更加聚焦于开发者工具,而逐渐减少对企业级 Kubernetes 的直接支持,特别是在容器编排方面。
-
2021年:Docker 进一步优化了其本地开发工具,使得开发者能够更容易在本地环境中使用容器和 Kubernetes 进行集成。
Docker Hub 和 Docker Desktop 的改进,使得 Docker 的云端镜像存储和本地开发环境更加流畅。
-
2022年 :Docker 继续加大对 开发者体验 的关注,推出了对 GitHub 等工具的深度集成,帮助开发者快速构建和部署容器。
在企业领域,Docker 企业版继续被 Kubernetes 和其他工具组合使用,尤其是对于 CI/CD 和 DevOps 环境中的大规模部署。
-
2023年 :Docker 23.x 发布,进一步增强了对 云原生应用 的支持,特别是对 Kubernetes 生态系统的集成增强。
Docker 在容器优化、安全性和持续集成/持续交付(CI/CD)方面继续推出新功能,提升了企业级应用部署的效率和安全性。
Docker 提供了更多对 开源 和社区驱动的工具的支持,力求保持其在容器生态中的主导地位。
1.3.3 Docker 版本:CE vs EE
Docker 提供了两个主要版本:
- Docker Community Edition (CE):适用于个人开发者或小型团队,提供基本的容器功能,免费使用。
- Docker Enterprise Edition (EE):适用于大规模生产环境,强调企业级的安全性和支持,通常是付费版本。
每个版本的发布周期不同,CE 通常每个月发布新版本,而 EE 版本则会有更长的维护周期。
1.3.4 Docker 与传统虚拟化的区别
Docker 通过操作系统级虚拟化(LXC)提供轻量级的虚拟化,容器之间共享宿主机的操作系统内核,因此相比传统虚拟机,Docker 容器更加轻便、高效。
- 传统虚拟机:每个虚拟机都包含完整的操作系统,资源占用大。
- Docker 容器:共享宿主操作系统的内核,启动快,占用少,易于管理。
| 特性 | Docker 容器 | 虚拟机 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 计算能力损耗 | 几乎无 | 损耗 50%左右 |
| 性能 | 接近原生 | 弱于 |
| 系统支持量(单机) | 上千个 | 几十个 |
| 隔离性 | 资源隔离/限制 | 完全隔离 |
1.3.5 容器化技术的生态系统
容器技术是一种轻量级、提供隔离的虚拟化技术。这里是一些知名的容器技术:
- Docker:市场上最为知名和流行的容器框架之一,拥有生态系统完善且社区活跃的优秀特点。它通过简单的工具和接口,使得应用程序的部署于测试过程更为简单。
- Kubernetes:Google 开发并开源的容器编排平台,可以管理、调度和扩展容器的应用。
- OpenShift:是 Red Hat 提供的开源的容器平台,基于 Kubernetes,但提供了更丰富的功能。
- LXC: Linux 容器技术,比 Docker 更接近传统的虚拟化技术,可以看作是轻量级的 VM(虚拟机)。
- Rkt:由 CoreOS 开发的一种容器技术,设计上有别于 Docker,它更注重于安全性和模块化。
- Apache Mesos:一种用于大规模数据中心的容器编排平台,特别地,它可以与其他调度系统如 Marathon、Chronos 或 Jenkins 集成。
- Containerd:是一个开源的容器运行时,是 Docker 的核心组件之一,可用于管理完整的容器生命周期。
- Crio:是一个轻量级的容器运行时,专门用于 Kubernetes。
- Singularity:一款专注于面向性能敏感和计算密集型应用程序的容器技术。
- Podman:与 Docker 相似,但无需守护进程,支持运行和管理 OCI 容器和镜像。
1.3.6 Docker 容器的优势
- 移植性:应用和其依赖打包在容器中,跨平台和跨环境运行无缝。
- 隔离性:容器内的应用互相隔离,不会影响宿主机或其他容器。
- 效率高:由于不需要完整的操作系统,容器消耗的资源少,启动速度快。
- 简化部署:通过 Docker,可以轻松创建、复制、修改和删除容器,简化了应用部署和管理的复杂度。
1.3.7 容器技术的应用场景
- CI/CD(持续集成与持续交付):利用 Docker 快速构建和部署应用,保证开发、测试、生产环境的一致性。
- 微服务架构:容器技术与微服务架构相得益彰,可以独立部署和扩展每个微服务。
- 多云与混合云环境:容器跨平台能力使得应用能在不同云环境和本地环境间无缝迁移。
1.4 Docker 基础概念
1.4.1 Docker 简介
① Docker 的 Logo 设计:Docker 的 Logo 设计为一条蓝色鲸鱼,拖着许多集装箱。鲸鱼代表宿主机,集装箱代表相互隔离的容器,每个集装箱中都包含自己的应用程序。
Docker 的设计宗旨
Docker 的设计宗旨是 Build, Ship and Run Any App, Anywhere。通过对应用组件的封装、发布、部署、运行等生命周期的管理,达到应用组件级别的"一次封装,到处运行"的目的。这里的组件可以是一个应用、一套服务,甚至是一个完整的操作系统。

鲸鱼背上有集装箱
蓝色的大海里面--------宿主机系统window10/linux
鲸鱼 ---------- docker
集装箱 ---------容器实例 from 来自我们的镜像模板
Docker 是一个开源的容器化平台,能够让开发者将应用及其依赖环境打包成容器,从而简化跨平台的部署和管理。
② Linux 六大命名空间
| 命名空间 | 缩写 | 作用 | 效果 |
|---|---|---|---|
| MNT | 挂载 | 文件系统隔离 | 每个命名空间可以有自己的文件系统挂载点 |
| NET | 网络 | 网络资源隔离 | 每个命名空间可以有自己的网络栈,包括网络接口、路由表等 |
| PID | 进程 | 进程号隔离 | 每个命名空间有自己独立的 PID 编号空间 |
| IPC | 间通 | 进程间通信隔离 | 每个命名空间有自己独立的 System V IPC 和 POSIX 消息队列 |
| UTS | 主机 | 主机名、域名隔离 | 每个命名空间可以有自己的主机名和域名 |
| USER | 用户 | 用户名、组名隔离 | 每个命名空间可以有自己的用户和组 ID 映射 |
③ Docker架构以及组件
-
Docker daemon(Docker守护进程)
Docker daemon是一个运行在宿主机(DOCKER_HOST)的后台进程。可通过Docker客户端与之通信。
-
Client(Docker客户端)
Docker客户端是Docker的用户界面,它可以接受用户命令和配置标识,并与Docker daemon通信。图中,docker build等都是Docker的相关命令。
-
Images(Docker镜像)
Docker镜像是一个只读模版,它包含创建Docker容器的说明。它和系统安装光盘有点像---使用系统安装光盘可以安装系统,同理,使用Docker镜像可以运行Docker镜像中的程序。
-
Container(容器)
容器是镜像的可运行实例。镜像和容器的关系有点类似于面向对象中,类和对象的关系。可通过Docker API或者CLI命令来启停,移动,删除容器。
-
Registry
Docker Registry是一个集中存储与分发镜像的服务。构建完Docker镜像后,就可在当前宿主机上运行。但如果想要在其他机器上运行这个镜像,就需要手动复制。此时可借助Docker Registry来避免镜像的手动复制。一个Docker Registry可包含多个Docker仓库,每个仓库可包含多个镜像标签,每个标签对应一个Docker镜像。这跟Maven的仓库有点类似,如果把Docker Registry比作Maven仓库的话,那么Docker仓库就可理解为某jar包的路径,而镜像标签则可理解为jar包的版本号。
④ Docker 组成
⑤ Docker 的核心技术
Docker 容器本质上是宿主机的一个进程,通过以下技术实现资源隔离和限制:
- Namespace:实现资源隔离。
- Cgroup:实现资源限制。
- 写时复制技术(Copy-on-Write):实现高效的文件操作。
1.4.2 Docker 核心概念 重点
- 镜像(Image)
- 镜像是包含应用程序及其所有依赖环境的可执行包。它是一个只读模板,基于该模板可以创建容器实例。
- 容器(Container)
- 容器是镜像的运行实例。容器提供了与外部环境隔离的运行时环境,可以在不同的系统上运行。
- 容器通过 Docker 引擎启动,具有独立的文件系统、网络、进程空间。
- 仓库(Repository)
- 仓库是存放 Docker 镜像的地方。Docker Hub 是最常用的公共仓库,用户也可以创建私有仓库。
1.4.3 Docker 安装与配置
-
Docker 目前仅支持 64 位系统。
-
关闭防火墙和 SELinux
systemctl stop firewalld.service
setenforce 0 -
安装依赖包
yum install -y yum-utils device-mapper-persistent-data lvm2 - yum-utils:提供了 `yum-config-manager` 工具。 - device-mapper:Linux 内核中支持逻辑卷管理的通用设备映射机制。 - device-mapper-persistent-data** 和 **lvm2**:device-mapper 存储驱动程序所需的依赖包。 -
设置阿里云镜像源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -
安装 Docker-CE 并设置为开机自动启动
yum install -y docker-ce docker-ce-cli containerd.io 注意:如果是指定版本docker-ce-20.10.18 systemctl start docker.service systemctl enable docker.service - Docker 系统包含两个程序:Docker 服务端和 Docker 客户端。 - Docker 服务端是一个服务进程,负责管理所有容器。 - Docker 客户端是 Docker 服务端的远程控制器,用于控制 Docker 服务端进程。 -
基本命令:
-
docker --version:查看 Docker 版本。 -
docker info:查看 Docker 系统信息。docker info Client: Context: default Debug Mode: false Plugins: app: Docker App (Docker Inc., v0.9.1-beta3) buildx: Build with BuildKit (Docker Inc., v0.5.1-docker) Server: Containers: 0 # 容器数量 Running: 0 Paused: 0 Stopped: 0 Images: 1 # 镜像数量 Server Version: 20.10.3 # server 版本 Storage Driver: overlay2 # docker 使用的是 overlay2 文件驱动 Backing Filesystem: xfs # 宿主机上的底层文件系统 Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs # Cgroups 驱动 Cgroup Version: 1 Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive Runtimes: io.containerd.runtime.v1.linux runc io.containerd.runc.v2 Default Runtime: runc Init Binary: docker-init containerd version: 269548fa27e0089a8b8278fc4fc781d7f65a939b runc version: ff819c7e9184c13b7c2607fe6c30ae19403a7aff init version: de40ad0 Security Options: seccomp Profile: default Kernel Version: 3.10.0-693.el7.x86_64 # 宿主机的相关信息 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 CPUs: 1 Total Memory: 976.3MiB Name: localhost.localdomain ID: Y4ES:FTH2:ZJL7:MRVE:RJVB:WJIB:S7BV:C5IZ:LMBR:E4G5:QWSM:SNDT Docker Root Dir: /var/lib/docker # docker 数据存储目录 Debug Mode: false Registry: https://index.docker.io/v1/ # registry 地址 Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Registry Mirrors: # 加速站点 https://6ijb8ubo.mirror.aliyuncs.com/ Live Restore Enabled: false -
Docker 系统信息 扩展
### Docker 系统信息 - **Client 部分**: - **Context**:当前使用的 Docker 上下文(默认为 "default")。 - **Debug Mode**:客户端调试模式是否开启(此处为 false)。 - **Plugins**:列出已安装的 Docker 插件,如 Docker App 和 Buildx。 - **Server 部分**(关键信息): - **Containers**: - **Containers**: 0(总容器数,包括运行、暂停和停止的容器)。 - **Running**: 0(正在运行的容器数)。 - **Paused**: 0(暂停的容器数)。 - **Stopped**: 0(停止的容器数)。 - **Images**: 1(本地镜像数)。 - **Server Version**: 20.10.3(Docker 服务器版本)。 - **Storage Driver**: overlay2(Docker 使用的存储驱动)。 - **Backing Filesystem**: xfs(宿主机上的底层文件系统)。 - **Supports d_type**: true(表示文件系统支持 d_type,有助于性能优化)。 - **Native Overlay Diff**: true(表示使用原生的 overlay diff 技术,提高性能)。 - **Logging Driver**: json-file(日志驱动)。 - **Cgroup Driver**: cgroupfs(Cgroups 驱动,用于资源限制和管理)。 - **Plugins**:列出 Docker 支持的卷、网络和日志插件。 - **Swarm**: inactive(Swarm 集群模式未启用)。 - **Runtimes**:列出 Docker 支持的运行时,如 runc。 - **Default Runtime**: runc(默认运行时)。 - **Security Options**:列出安全选项,如 seccomp(安全计算模式)。 - **Kernel Version** 和 **Operating System**:提供宿主机的内核版本和操作系统信息。 - **Architecture**:宿主机的架构(如 x86_64)。 - **CPUs** 和 **Total Memory**:宿主机的 CPU 数和总内存。 - **Name** 和 **ID**:Docker 主机的名称和唯一 ID。 - **Docker Root Dir**:Docker 数据存储的根目录(如 /var/lib/docker)。 - **Debug Mode**:服务器调试模式是否开启(此处为 false)。 - **Registry**:默认的 Docker 镜像仓库地址。 - **Labels**:Docker 主机的标签。 - **Experimental**:是否启用实验性功能(此处为 false)。 - **Insecure Registries**:列出不安全的镜像仓库地址(如 127.0.0.0/8)。 - **Registry Mirrors**:列出镜像加速站点,用于加速 Docker 镜像的拉取和推送。 - **Live Restore Enabled**:是否启用实时恢复功能(此处为 false)。 - **存储驱动(Storage Driver)**:Docker 使用 overlay2 作为其默认的存储驱动,它提供了高效的镜像和容器管理。 - **Cgroup 驱动(Cgroup Driver)**:cgroupfs 是 Linux 上用于限制、记录和隔离进程组所使用的物理资源(如 CPU、内存、磁盘 I/O 等)的机制。 - **运行时(Runtimes)**:Docker 支持多种容器运行时,其中 runc 是默认的运行时,用于启动和管理容器。 - **安全选项(Security Options)**:seccomp 是一种内核功能,用于在 Linux 上提供沙箱环境,限制容器内进程能够执行的系统调用。 - **镜像加速站点(Registry Mirrors)**:通过配置镜像加速站点,可以加速 Docker 镜像的下载速度,提高开发效率。
-
2. Docker 容器管理 2c4G
2.1 Docker 镜像操作
2.1.1 搜索镜像
bash
docker search nginx
- 作用 :通过关键字(例如
nginx)在 Docker Hub 上搜索相关的镜像。搜索结果会显示镜像的名称、描述、星级评价等。
2.1.2 获取镜像
bash
docker pull nginx
- 作用 :从 Docker Hub 拉取
nginx镜像,默认下载最新(latest)版本。如果你不指定标签(tag),则会下载默认的latest标签的镜像。
2.1.3 镜像加速下载
镜像下载可能会因为网络原因而比较慢,尤其是国内用户。这里给出了几种加速镜像下载的方法。
阿里云加速器:
bash
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://ae3f5qei.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
- 作用:配置 Docker 使用阿里云镜像加速器来提高镜像下载速度。
华为加速器:
bash
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [ "https://0a40cefd360026b40f39c00627fa6f20.mirror.swr.myhuaweicloud.com" ]
}
EOF
- 作用:配置 Docker 使用华为云镜像加速器。
国外小网站加速器:
bash
{
"registry-mirrors": ["https://hub.littlediary.cn/"]
}
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["http://43.163.206.59:9211"]
}
EOF
- 作用:使用一个国外小网站作为加速器,适用于国内网络环境下下载速度较慢的情况。
2.1.4 查看镜像信息
bash
cat /var/lib/docker/image/overlay2/repositories.json
- 作用 :查看 Docker 本地镜像的详细信息。
/var/lib/docker是 Docker 存储所有数据的目录,镜像存储在image目录下的overlay2子目录中。
查看本地所有镜像:
bash
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 41f689c20910 6 weeks ago 192MB
-----------------------------------------------------------------------------------------
REPOSITORY:镜像属于的仓库;
TAG:镜像的标签信息,标记同一个仓库中的不同镜像;
IMAGE ID:镜像的唯一ID 号,唯一标识一个镜像;
CREATED:镜像创建时间;
VIRTUAL SIZE:镜像大小;
-----------------------------------------------------------------------------------------
- 作用:列出所有已经下载到本地的镜像,包括仓库名称、标签、镜像 ID、创建时间和大小等信息。
2.1.5 获取镜像详细信息
bash
docker inspect 41f689c20910
- 作用:获取指定镜像(通过镜像 ID)详细信息。此命令返回一个 JSON 格式的详细信息,包括镜像的层次、历史记录、配置、大小等。
2.1.6 为本地镜像添加标签
bash
#格式:docker tag 名称:[标签] 新名称:[新标签]
docker tag nginx:latest nginx:web
docker images | grep nginx
- 作用 :为本地的
nginx:latest镜像添加新的标签nginx:web,这并不会创建新的镜像,而是为同一个镜像附加了新的标签。
2.1.7 删除镜像
bash
格式:
docker rmi 仓库名称:标签 #当一个镜像有多个标签时,只是删除其中指定的标签
或者
docker rmi 镜像ID号 #会彻底删除该镜像
注意:如果该镜像已经被容器使用,正确的做法是先删除依赖该镜像的所有容器,再去删除镜像。
docker rmi nginx:web
- 作用:删除指定标签的镜像。注意:如果镜像有多个标签,删除指定标签不会删除镜像本身,只有在没有其他标签和容器依赖的情况下才会彻底删除镜像。如果镜像正在被容器使用,需要先删除容器。
2.1.8 存储镜像(导出)
bash
docker save -o nginx.tar nginx:latest
- 作用 :将本地镜像
nginx:latest保存为 tar 包(nginx.tar)。这可以用于镜像备份或迁移。
2.1.9 载入镜像(导入)
bash
docker load < nginx.tar
- 作用:从本地 tar 文件中加载镜像。你可以将导出的镜像文件通过此命令重新加载到 Docker 中。
或者:
bash
docker load -i nginx.tar
- 作用:同上,导入镜像文件。
2.1.10 上传镜像到 Docker Hub
标签镜像:
bash
docker tag nginx:latest soscscs/nginx:web
- 作用 :为镜像添加一个新的标签,并指定上传到 Docker Hub 的目标仓库。
soscscs/nginx:web表示在 Docker Hub 上的soscscs账户下的nginx仓库,并使用web标签。
登录 Docker Hub:
bash
sudo docker tag {镜像名称}:{版本名称} swr.cn-east-3.myhuaweicloud.com/{组织名称}/{镜像名称}:{版本名称}
docker tag nginx:latest swr.cn-east-3.myhuaweicloud.com/nginx:web01
sudo docker push swr.cn-east-3.myhuaweicloud.com/{组织名称}/{镜像名称}:{版本名称}
docker push swr.cn-east-3.myhuaweicloud.com/nginx:web01
- 作用:登录 华为云,输入用户名、密码进行身份验证。登录后才可以上传镜像。
上传镜像:
bash
docker push soscscs/nginx:web
- 作用 :将本地的
nginx:web镜像上传到 Docker Hub。上传后,你可以在 Docker Hub 上看到该镜像,并分享或部署它。
补充说明:
- 镜像层 :镜像是由多层文件系统组成的,每一层都有自己的修改。比如,基础镜像、安装包、环境变量等都会在不同层中表示。
docker inspect可以看到这些层的详细信息。 - Docker Hub 和私有仓库:除了默认的 Docker Hub,用户还可以设置并使用私有镜像仓库。如果你有很多私有镜像或者需要将镜像存储在某个私有云中,可以选择 Docker Registry。
- 镜像的标签(Tag) :镜像的标签用于标识同一镜像仓库中的不同版本。
latest是默认标签,但为了避免版本问题,建议给镜像明确的标签,如v1.0、v1.1等。
总结:
- 这些基本操作对于管理 Docker 镜像非常重要,无论是本地使用、存储备份,还是上传到公共或私有仓库,都可以通过这些命令来完成。
- 配置镜像加速器是针对网络速度较慢的用户,能有效提升镜像拉取速度。
2.2 Docker 容器操作
容器创建:就是将镜像加载到容器的过程。
新创建的容器默认处于停止状态,不运行任何程序,需要在其中发起一个进程来启动容器。
2.2.1创建容器
格式:docker create [选项] 镜像
常用选项:
-i:让容器开启标准输入
-t:让 Docker 分配一个伪终端 tty
-it :合起来实现和容器交互的作用,运行一个交互式会话 shell
-
docker create:创建一个新容器,但不启动它。 -
示例:
docker create -it nginx:latest
docker create -it nginx:latest /bin/bash
2.2.2 启动容器
-
docker start:启动已创建的容器。 -
示例:
docker start <container_id>。'格式:docker start 容器的ID/名称 docker start 8b0a7be0ff58 docker ps -a
2.2.3停止容器
docker stop:停止正在运行的容器。- 示例:
docker stop <container_id>。
2.2.4查看容器状态
-
docker ps:查看正在运行的容器。 -
docker ps -a:查看所有容器,包括已停止的容器。#查看容器的运行状态
docker ps -a #-a 选项可以显示所有的容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b0a7be0ff58 nginx:latest "/docker-entrypoint...." 57 seconds ago Created inspiring_swanson容器的ID号 加载的镜像 运行的程序 创建时间 当前的状态 端口映射 名称
2.2.5 创建并启动容器
可以直接执行 docker run 命令, 等同于先执行 docker create 命令,再执行 docker start 命令。
注意:容器是一个与其中运行的 shell 命令共存亡的终端,命令运行容器运行, 命令结束容器退出。
docker 容器默认会把容器内部第一个进程,也就是 pid=1 的程序作为docker容器是否正在运行的依据,如果docker容器中 pid = 1 的进程挂了,那么docker容器便会直接退出,也就是说Docker容器中必须有一个前台进程,否则认为容器已经挂掉。
容器的生命周期包括创建、启动、停止、重启、删除等操作。容器会根据其进程的状态自动结束,例如当容器中的 PID=1 的进程退出时,容器也会停止。
docker run centos:7 /usr/bin/bash -c ls /
docker ps -a #会发现创建了一个新容器并启动执行一条 shell 命令,之后就停止了
当利用 docker run 来创建容器时, Docker 在后台的标准运行过程是:
- Dockers引擎会在本地查找镜像
- 本地找到镜像 然后启动镜像
- 本地没有找到镜像,然后根据Docker引擎配置的仓库地址,远程去查找镜像。
- 远程查询到镜像,把镜像下载到本地,然后启动镜像
- 远程查询到镜像,Docker返回错误,提示镜像远程未找到。
- 运行中的镜像支持:停止、启动、重启、删除(先停止才可以删除)操作
2.2.6 在后台持续运行 docker run 创建的容器
需要在 docker run 命令之后添加 -d 选项让 Docker 容器以守护形式在后台运行。并且容器所运行的程序不能结束
docker run -d centos:7 /usr/bin/bash -c "while true;do echo hello;done"
docker ps -a #可以看出容器始终处于 UP,运行状态
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2592d3fad0fb centos:7 "/usr/bin/bash -c 'w..." 2 seconds ago Up 2 seconds peaceful_chatelet
docker run -itd --name test1 centos:7 /bin/bash #创建容器并持续运行容器
docker容器的生命周期
Docker容器主要有以下7个状态:
- created:已创建,还未运行的容器
- running:正在运行中的容器
- restarting:容器正在重启中
- removing:容器正在迁移中
- paused:已暂停状态的容器
- exited:停止状态的容器
dead:死亡,主要是操作系统出现异常或者断电关机等有可能引发dead状态,不是很常见。
暂停和停止状态的区别
docker pause 命令挂起指定容器中的所有进程
docker stop 容器内主进程会在指定时间内被杀死,默认为10s后。
2.2.7 容器交互
需要进入容器进行命令操作时,可以使用 docker exec 命令进入运行着的容器。
-
执行命令 :使用
docker exec命令在容器内运行命令。-
示例:
docker exec -it <container_id> bash,进入容器交互式 shell。格式:docker exec -it 容器ID/名称 /bin/bash -i 选项表示让容器的输入保持打开; -t 选项表示让 Docker 分配一个伪终端。 docker start 2592d3fad0fb #进入容器前,确保容器正在运行 docker exec -it 2592d3fad0fb /bin/bash ls exit #退出容器后,容器仍在运行 docker ps -a docker run -it centos:7 bash #不加 -d 选项会创建容器后直接进入容器,但是退出容器,容器也会停止
2.2.8 复制到容器中
#面试题
怎么把宿主机的文件传入到容器内部
1、linux 怎么复制
cp 原文件路径目标文件路径
docker cp l opt / abc容器id: /opt/abc#======复制到容器中 echo abc123 > ~/test.txt docker cp ~/test.txt 2592d3fad0fb:/opt/ #从容器复制文件到主机 docker cp 2592d3fad0fb:/opt/test.txt ~/abc123.txt2.2.9 容器的导出与导入
用户可以将任何一个 Docker 容器从一台机器迁移到另一台机器。在迁移过程中,可以使用docker export 命令将已经创建好的容器导出为文件,无论这个容器是处于运行状态还是停止状态均可导出。可将导出文件传输到其他机器,通过相应的导入命令实现容器的迁移。
#导出格式:docker export 容器ID/名称 > 文件名 docker export 2592d3fad0fb > centos7.tar #导入格式:cat 文件名 | docker import -- 镜像名称:标签 cat centos7.tar | docker import - centos7:test #导入后会生成镜像,但不会创建容器2.2.10 删除容器
格式:docker rm [-f] 容器ID/名称 docker stop 2592d3fad0fb docker rm 2592d3fad0fb #删除已经终止状态的容器 docker rm -f 2592d3fad0fb #强制删除正在运行的容器 docker ps -a | awk 'NR>=2{print "docker stop "$1}' | bash #批量停止容器 docker ps -a | awk 'NR>=2{print $1}'| xargs docker stop docker ps -a | awk 'NR>=2{print "docker rm "$1}' | bash #批量删除所有容器 docker ps -a | awk 'NR>=2{print $1}'| xargs docker rm docker images | awk 'NR>=2{print "docker rmi "$3}'| bash #批量删除镜像 docker images | grep none | awk '{print $3}' | xargs docker rmi #删除none镜像 docker rm $(docker ps -a -q) #批量清理后台停止的容器 -
3. Docker 网络管理
3.1 Docker 网络实现原理
Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。
Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法直接通过 Container-IP 访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。
docker run -d --name test1 -P nginx #随机映射端口(从32768开始)
docker run -d --name test2 -p 43000:80 nginx #指定映射端口
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d3c04f57a68 nginx "/docker-entrypoint...." 4 seconds ago Up 3 seconds 0.0.0.0:43000->80/tcp test2
b04895f870e5 nginx "/docker-entrypoint...." 17 seconds ago Up 15 seconds 0.0.0.0:49170->80/tcp test1
浏览器访问:http://192.168.10.23:43000 、http://192.168.10.23:49170
#查看容器的输出和日志信息
docker logs 容器的ID/名称
3.2 Docker 的网络模式
用docker run创建Docker容器时,可以用 --net 或 --network 选项指定容器的网络模式
3.2.1 host模式
相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址。
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。
一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、iptable规则等都与其他的Network Namespace隔离。 一个Docker容器一般会分配一个独立的Network Namespace。 但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。
docker run -d --name nginx-host --network host nginx
总结:host模式:容器与宿主机共享网络环境,不具备独立的IP和网卡 ,而是使用宿主机的IP和端口
##### 3.2.2 Container模式
在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

##### 案列:
docker run -itd --name test1 centos:7 /bin/bash #--name 选项可以给容器创建一个自定义名称
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ed82355f811 centos:7 "/bin/bash" 5 days ago Up 6 hours test1
docker inspect -f '{{.State.Pid}}' 3ed82355f811 #查看容器进程号
25945
ls -l /proc/25495/ns #查看容器的进程、网络、文件系统等命名空间编号
lrwxrwxrwx 1 root root 0 1月 7 11:29 ipc -> ipc:[4026532572]
lrwxrwxrwx 1 root root 0 1月 7 11:29 mnt -> mnt:[4026532569]
lrwxrwxrwx 1 root root 0 1月 7 11:27 net -> net:[4026532575]
lrwxrwxrwx 1 root root 0 1月 7 11:29 pid -> pid:[4026532573]
lrwxrwxrwx 1 root root 0 1月 7 12:22 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 1月 7 11:29 uts -> uts:[4026532570]
docker run -itd --name test2 --net=container:3ed82355f811 centos:7 /bin/bash
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff96bc43dd27 centos:7 "/bin/bash" 48 seconds ago Up 46 seconds test2
3ed82355f811 centos:7 "/bin/bash" 58 minutes ago Up 58 minutes test1
docker inspect -f '{{.State.Pid}}' ff96bc43dd27
27123
ls -l /proc/27123/ns #查看可以发现两个容器的 net namespace 编号相同
lrwxrwxrwx 1 root root 0 1月 7 12:27 ipc -> ipc:[4026532692]
lrwxrwxrwx 1 root root 0 1月 7 12:27 mnt -> mnt:[4026532690]
lrwxrwxrwx 1 root root 0 1月 7 12:27 net -> net:[4026532575]
lrwxrwxrwx 1 root root 0 1月 7 12:27 pid -> pid:[4026532693]
lrwxrwxrwx 1 root root 0 1月 7 12:27 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 1月 7 12:27 uts -> uts:[4026532691]
总结:与指定的容器共享network命令空间
##### **3.2.3 无网络模式(none)**
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息。这种网络模式下容器只有lo回环网络,没有其他网卡。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
总结 :none 模式 是指禁用网络功能 只有lo接口 在容器创建时使用 --network=none指定
##### 3.2.4**桥接模式(bridge)**
bridge模式是docker的默认网络模式,不用--net参数,就是bridge模式。
相当于Vmware中的 nat 模式,容器使用独立network Namespace,并连接到docker0虚拟网卡。通过docker0网桥以及iptables nat表配置与宿主机通信,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。
(1)当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
(2)从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
(3)Docker将 veth pair 设备的一端放在新创建的容器中,并命名为 eth0(容器的网卡),另一端放在主机中, 以 * 这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。可以通过 brctl show 命令查看。veth
(4)使用 docker run -p 时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL 查看。
!
`virbr0`是 Linux 系统中的一种网络接口,它是支持虚拟机网络通信的一种默认的虚拟桥接网络。当你安装虚拟化技术(比如 KVM、VirtualBox 等)的时候,就会创建这样的虚拟网络桥接。
用"大白话"来理解它,`virbr0`就像是一个虚拟的交换机或路由器,它把你的计算机和虚拟机连接起来,让虚拟机可以通过它与外界进行网络通信。简单来说,您的电脑和虚拟机可以被看作是在同一个局域网内。
这就像一栋大楼中的各个房间可以通过交换机(这里是虚拟的 `virbr0`)和大楼外的世界(互联网)进行通讯一样。每个房间(虚拟机)都有自己的门牌号(IP地址),通过这个"虚拟的交换机",门牌号可以被识别并且数据可以正确地在各个房间(虚拟机)和外部的世界之间传递
总结:bridge网络模式 容器运行在同一宿主机内的虚拟网桥上,可以通过容器互相通信,与宿主机网络隔离。
##### 3.2.5 自定义模式
自定义网络模式,docker提供了三种自定义网络驱动: bridge overlay macvlan
bridge驱动类似默认的bridge网络模式,但增加了一些新的功能, overlay和macvlan是用于创建跨主机网络
建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址
Docker提供了创建这些网络的默认网络驱动程序,你可以创建一个新的Bridge网络,Overlay或Macvlan网络
bridge 单机网络模式适合在一台宿主机 内容器互联
overlay 跨主机容器互联 docker swarm
macvlan 容器像一台物理机一样 直接获取宿主机的所在的网络的IP (容器像物理机一样直接连接局域网)
#直接使用bridge模式,是无法支持指定IP运行docker的,例如执行以下命令就会报错
docker run -itd --name test3 --network bridge --ip 172.17.0.10 centos:7 /bin/bash
//创建自定义网络
#可以先自定义网络,再使用指定IP运行docker
docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
#docker1 为执行 ifconfig -a 命令时,显示的网卡名,如果不使用 --opt 参数指定此名称,那你在使用 ifconfig -a 命令查看网络信息时,看到的是类似 br-110eb56a0b22 这样的名字,这显然不怎么好记。
#mynetwork 为执行 docker network list 命令时,显示的bridge网络模式名称。
docker run -itd --name test4 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash
##### 3.2.6 总结:
1. **桥接模式(bridge)**
- 默认的网络模式,容器通过虚拟网桥与宿主机和其他容器通信。
2. **主机模式(host)**
- 容器共享宿主机的网络栈,直接使用宿主机的 IP 地址。
3. **容器模式(container)**
- 容器共享另一个容器的网络栈,两个容器可以使用相同的 IP 地址进行通信。
4. **无网络模式(none)**
- 容器没有网络配置,只有回环接口(lo)。
5. **自定义网路**:定义网络允许用户自定义容器的网络范围、子网和路由,从而提供更高的网络控制和隔离性。
额外附加:
1. **Overlay**:这是Docker Swarm模式的网络,主要用于在多个主机上创建一个分布式网络。容器间即便在不同的主机也能完成通信,相当于在跨主机的容器之间创建了一个覆盖网络。
2. **Macvlan**:Macvlan模式可以让容器直接连接到主机的物理网络,每个Macvlan接口都有一个唯一的MAC地址,此模式使得容器看起来就像是网络上的物理设备。
------
## 4. 资源限制
### 4.1 CPU 资源控制
**概述(cgroups)**
- `cgroups`(Control Groups)是 Linux 内核提供的资源控制机制。对容器非常重要,可控制:资源限制、优先级分配、资源统计、任务控制(挂起/恢复/终止)。
- Docker 通过 cgroups 来实现 CPU、内存、IO 等限制与度量。
**cgroups 的 4 大功能(简要)**
- 资源限制:限制任务使用的总资源量。
- 优先级分配:如通过 cpu 时间片和 IO 带宽分配优先级。
- 资源统计:统计 cpu 时长、内存用量等。
- 任务控制:对 cgroup 中的进程执行挂起/恢复等操作。
------
#### 4.1.1 设置 CPU 使用率上限(`--cpu-period` / `--cpu-quota`)
- **原理**:Linux 使用 CFS(Completely Fair Scheduler)。通过两个参数控制:`cpu.cfs_period_us`(周期,微秒)和 `cpu.cfs_quota_us`(配额,微秒)。
- `quota / period` = 可用 CPU 核心数的 **小数** 表示(相对于 1 个 CPU)。
- 默认 `period = 100000`(100 ms)。`quota = -1` 表示不限制。
- **示例**:限制容器为 **50% 的一个 CPU**:
```bash
docker run -itd --name test6 --cpu-quota 50000 centos:7 /bin/bash 0.5
解释:50000 / 100000 = 0.5 → 相当于 0.5 个 CPU(即 50% 的单核)。
-
注意 :如果宿主机有 4 个逻辑核,那么
0.5个 CPU ≈0.5 / 4 = 0.125(即 12.5% 的整机 CPU 能力)。 -
(计算示例:50000/100000 = 0.5;0.5/4 = 0.125 → 12.5%)
-
最小值/范围 :
--cpu-period有效范围通常 1000 ~ 1000000(单位 us)。--cpu-quota必须 >= 1000(1 ms)或者 -1(不限制)。 -
另一种更直观的写法:
bashdocker run -itd --name cputest --cpus="0.5" centos:7 /bin/bash--cpus=0.5是--cpu-quota/--cpu-period的友好封装(要求较新版本 Docker)。
4.1.2 设置 CPU 占用比(权重 --- --cpu-shares)
-
原理 :
--cpu-shares指定相对权重(默认 1024),仅在 CPU 争用时生效(不是硬限制)。- 举例:两个容器
c1、c2,--cpu-shares 512与--cpu-shares 1024,在争用情况下 CPU 分配比约为 1:2。
- 举例:两个容器
-
示例:
bashdocker run -itd --name c1 --cpu-shares 512 centos:7 docker run -itd --name c2 --cpu-shares 1024 centos:7 -
验证 :运行压力程序(
stress -c N)后用docker stats观察 CPU % 倾向于 1:2(随系统负载和核心数而变化)。
4.1.3 绑定指定 CPU(--cpuset-cpus)
-
用途:把容器进程绑定到宿主机的指定 CPU 核上(硬亲和性)。
-
示例:将容器绑定到第 1 和第 3 个核:
bashdocker run -itd --name test7 --cpuset-cpus "1,3" centos:7 /bin/bash -
验证 :在宿主机运行
top或htop(按1)查看各核利用率,或进入容器运行taskset -p <pid>。
4.1.4 压力测试与验证示例(CPU)
-
在容器内创建一个繁忙循环脚本:
bash# /cpu.sh #!/bin/bash i=0 while true; do let i++; done -
在容器内运行
./cpu.sh,在宿主机观察top与docker stats:bashdocker exec -it <container> bash ./cpu.sh -
分别进入容器,进行压力测试
yum install -y epel-release yum install -y stress stress -c 4 #产生四个进程,每个进程都反复不停的计算随机数的平方根 -
修改
cgroups手工测试(示例):bash# 找到容器对应的 cgroup 路径(容器ID替换) cd /sys/fs/cgroup/cpu/docker/<container-id>/ cat cpu.cfs_period_us cat cpu.cfs_quota_us echo 50000 > cpu.cfs_quota_us # 设置配额(临时生效)
4.1.5 注意事项(CPU)
--cpu-shares是权重,不是限额。--cpu-quota/--cpu-period是硬限制(quota = -1 表示无限制)。- 使用
--cpuset-cpus能提高性能稳定性(避免与其他进程抢核)。 - 在多核宿主机上理解
quota/period的含义(单位是 "相对于 1 个 CPU 的份额")。
4.2 内存使用限制
基础选项
-m, --memory:限制容器可用的物理内存(例如-m 512m)。--memory-swap:限制容器可用的物理内存 + swap 总量(必须与-m一起使用以明确 swap 上限)。
4.2.1 --memory 与 --memory-swap 规则
- 示例:
-m 300m --memory-swap=1g- 含义:容器可用物理内存 = 300 MB;物理 + swap 总共 = 1 GB → swap 可用 = 700 MB(1G - 300M)。
- 默认行为:若不设置
--memory-swap,通常容器可使用的 swap 为-m值的两倍(行为可能随 Docker 版本/配置变化)。 - 若
--memory-swap=-1:swap 不受限制(宿主机可用多少 swap 就用多少)。 - 若
--memory-swap=-m:容器不能使用 swap(物理内存用尽会触发 OOM)。
4.2.2 示例命令
bash
docker run -itd --name test8 -m 512m centos:7 /bin/bash
# 或者设置 swap 总额
docker run -itd --name test8b -m 300m --memory-swap=1g centos:7
4.2.3 验证与观察
-
使用
docker stats观察MEM USAGE / LIMIT。 -
在宿主机查看 cgroup:
bashcd /sys/fs/cgroup/memory/docker/<container-id>/ cat memory.limit_in_bytes cat memory.usage_in_bytes -
OOM 行为 :如果容器超过允许内存且没有 swap 或无更多内存可用,会被内核 OOM killer 杀掉。可查看容器日志与
dmesg来确认 OOM 事件。
4.2.4 建议与注意
- 为生产服务设置合理内存限制,避免单容器把宿主机内存耗尽。
- 对于内存敏感的应用,建议同时设置
-m与--memory-swap,并配合健康检查/重启策略。 - 在 cgroup v2 环境下内存控制文件名/行为可能与 v1 略有不同(检查
/sys/fs/cgroup结构)。
4.3 磁盘 IO(blkio / io)控制
说明
- Docker 提供对块设备读写带宽与 IOPS 的限制选项(基于 cgroups 的 blkio 控制器)。
- 注意:在 cgroup v2 中,blkio 功能被
io控制器取代,语义与文件名有所不同(如果你运行的是较新内核/系统,请参考对应 cgroup 版本文档)。
4.3.1 常用 Docker 参数(blkio)
--device-read-bps /dev/sda:1M:限制设备上读速率为 1 MB/s。--device-write-bps /dev/sda:1M:限制写速率为 1 MB/s。--device-read-iops /dev/sda:100:限制读 IOPS(次数)。--device-write-iops /dev/sda:100:限制写 IOPS(次数)。
示例:
bash
docker run -it --name test10 --device-write-bps /dev/sda:1MB centos:7 /bin/bash
4.3.2 验证(用 dd 测试写速)
-
在容器内执行写入测试,使用
oflag=direct跳过文件系统缓存:bashdd if=/dev/zero of=test.out bs=1M count=10 oflag=direct输出示例说明:
10485760 bytes (10 MB) copied, 10.0025 s, 1.0 MB/s→ 写速被限为约 1 MB/s。
4.3.3 注意事项(blkio)
- 限制需要指定具体块设备路径 (如
/dev/sda)。错误的设备路径不会生效。 - 在虚拟化环境或云盘(如 EBS、云盘快照)上,底层 IO 性能由云提供商或 hypervisor 决定,容器层设置可能受限。
- 在 cgroup v2 上,对 IO 的控制接口为
io.max等,需要使用不同的工具/路径来配置验证。
4.4 清理 Docker 占用的磁盘空间(补充)
-
清理未使用的数据(可释放磁盘空间):
bashdocker system prune -a- 该命令会删除停止的容器、未使用的镜像、未使用的网络和构建缓存(要谨慎使用,会删除很多资源)。
4.5 常见命令速查(快速摘录)
bash
总结命令 资源限制
# CPU
docker run -itd --name c1 --cpu-shares 512 centos:7
docker run -itd --name c2 --cpu-quota 50000 centos:7
docker run -itd --name c3 --cpuset-cpus "1,3" centos:7
docker run -itd --name c4 --cpus="0.5" centos:7
# 内存
docker run -itd --name memtest -m 512m centos:7
docker run -itd --name memtest2 -m 300m --memory-swap=1g centos:7
# blkio
docker run -it --name iotest --device-write-bps /dev/sda:1MB centos:7
# 监控/验证
docker stats
docker exec -it <container> bash
cat /sys/fs/cgroup/cpu/docker/<container-id>/cpu.cfs_quota_us
cat /sys/fs/cgroup/memory/docker/<container-id>/memory.limit_in_bytes
# 清理
docker system prune -a
4.6 常见陷阱与建议
- 理解权重 vs 限额 :
--cpu-shares= 权重(争用时生效);--cpu-quota/--cpus= 硬限制。 - cgroup v1 vs v2:不同内核/发行版可能使用不同 cgroup 版本,相关文件/控制器名会不同(例如 blkio ↔ io)。CentOS7 默认通常是 cgroup v1。
- IO 限制依赖底层设备:在云/虚拟机上测试时,注意底层虚拟磁盘的行为。
- 生产环境:建议配合监控(Prometheus + cAdvisor / node-exporter)来持续观察容器资源使用情况并调优。
- 权限 :修改
/sys/fs/cgroup/*需要 root 权限;Docker run 的限制设置通常更简单、安全。
5. 数据卷容器 (Data Volumes Containers)
5.1 数据卷
数据卷是 Docker 中一种专门为容器提供持久化存储的机制。它是容器内部的特殊目录,可以与宿主机或其他容器共享数据。通过使用数据卷,容器可以在其生命周期内访问和修改数据,而不会影响镜像本身。这样一来,数据卷能够保持数据持久性,即使容器被删除或重建,数据依然能够保留。
5.1.1 创建与挂载数据卷
使用 docker run 命令启动一个容器时,可以通过 -v 或 --mount 选项将宿主机的目录挂载到容器中的数据卷。下面是一个简单的例子:
bash
docker run -v /var/www:/data1 --name web1 -it centos:7 /bin/bash
-v /var/www:/data1: 将宿主机上的/var/www目录挂载到容器中的/data1目录。这样容器内/data1的修改会同步到宿主机上的/var/www。--name web1: 给容器指定一个名称web1。-it centos:7 /bin/bash: 使用centos:7镜像启动容器并进入交互式 shell。
5.1.2 在数据卷中写入数据
进入容器后,可以在 /data1 目录下创建文件:
bash
echo "this is web1" > /data1/abc.txt
此时,容器中的 /data1/abc.txt 文件与宿主机中的 /var/www/abc.txt 文件是同步的。即使容器退出,宿主机上的数据依然存在。
5.1.3 查看宿主机的数据
退出容器后,返回宿主机查看数据是否已成功同步:
bash
cat /var/www/abc.txt
你应该能看到容器中写入的数据内容:this is web1。
5.2 数据卷容器
数据卷容器是一种专门用于共享数据的容器,它不是用于运行应用程序的容器,而是仅仅提供一个数据卷,供其他容器挂载并使用。这种方式常用于多个容器共享数据,避免数据丢失或重复管理。
5.2.1 创建数据卷容器
首先,创建一个数据卷容器 web2,并挂载多个数据卷:
bash
docker run --name web2 -v /data1 -v /data2 -it centos:7 /bin/bash
--name web2: 给容器命名为web2。-v /data1 -v /data2: 在容器内部挂载了两个数据卷/data1和/data2。这些数据卷不依赖于宿主机,而是仅仅存在于容器内。
5.2.2 在数据卷容器中写入数据
进入 web2 容器后,可以在 /data1 和 /data2 目录下写入数据:
bash
echo "this is web2" > /data1/abc.txt
echo "THIS IS WEB2" > /data2/ABC.txt
现在,web2 容器内的 /data1/abc.txt 和 /data2/ABC.txt 文件已经被创建。
5.2.3 使用 --volumes-from 共享数据卷
接下来,创建一个新的容器 web3,并通过 --volumes-from 选项将 web2 容器中的数据卷挂载到 web3 容器中:
bash
docker run -it --volumes-from web2 --name web3 centos:7 /bin/bash
--volumes-from web2: 这表示将容器web2中的所有数据卷挂载到新容器web3中。
5.2.4 在新容器中查看数据
进入 web3 容器后,查看 web2 容器中的数据:
bash
cat /data1/abc.txt
cat /data2/ABC.txt
你应该能看到如下输出:
bash
this is web2
THIS IS WEB2
这表明 web3 容器成功挂载了 web2 容器中的数据卷,并能够访问其中的文件。
5.3 总结
- 数据卷 (Data Volumes) 是容器中的特殊目录,用于持久化存储数据。它可以通过宿主机的目录进行挂载,实现容器与宿主机之间的数据共享。
- 数据卷容器 (Data Volumes Containers) 允许容器之间共享数据卷,避免每个容器都需要挂载宿主机目录。使用
--volumes-from可以让多个容器共享同一数据卷。
6. 端口映射
在 Docker 中,容器内部运行的服务默认是不能被外部网络访问的。如果需要让外部网络能够访问容器中的服务,就需要使用端口映射机制。端口映射将宿主机的端口映射到容器内的端口,从而使得外部网络能够通过访问宿主机的端口,进而访问容器内的服务。
6.1 随机端口映射
如果不指定端口,Docker 会自动为容器的服务分配一个随机端口(通常从 32768 开始)。这种方式适用于无需指定端口号的场景。
命令示例:
bash
docker run -d --name test1 -P nginx
-P: 自动将容器内部暴露的端口映射到宿主机上的随机端口。nginx: 使用nginx镜像启动容器。
运行后,可以通过 docker ps -a 查看容器的状态,特别是端口映射信息:
bash
docker ps -a
输出示例:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d3c04f57a68 nginx "/docker-entrypoint...." 4 seconds ago Up 3 seconds 0.0.0.0:49170->80/tcp test1
此时,test1 容器内部的端口 80 被映射到宿主机的端口 49170。你可以通过浏览器访问:
http://192.168.80.10:49170
6.2 指定端口映射
如果你希望容器内的服务映射到宿主机上的指定端口,可以使用 -p 选项手动指定端口映射。
命令示例:
bash
docker run -d --name test2 -p 43000:80 nginx
-p 43000:80: 将宿主机的端口43000映射到容器内的端口80。这意味着你可以通过访问宿主机的43000端口来访问容器中的 Nginx 服务。
运行后,通过 docker ps -a 查看容器的状态,特别是端口映射信息:
bash
docker ps -a
输出示例:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b04895f870e5 nginx "/docker-entrypoint...." 17 seconds ago Up 15 seconds 0.0.0.0:43000->80/tcp test2
此时,test2 容器内部的端口 80 被映射到宿主机的端口 43000。你可以通过浏览器访问:
http://192.168.80.10:43000
6.3 总结
- 随机端口映射 :使用
-P选项,Docker 会自动为容器暴露的端口分配一个随机的宿主机端口,适用于无需手动指定端口的情况。 - 指定端口映射 :使用
-p <宿主机端口>:<容器端口>的格式,手动指定宿主机和容器之间的端口映射关系,适用于需要明确指定端口的场景。
通过端口映射,容器内的服务可以轻松暴露给外部网络,供外界访问。
7. 容器互联(使用 CentOS 镜像)
容器互联是一种让容器之间能够通过网络相互通信的机制。通过在容器间建立网络通信隧道,源容器和接收容器可以互相看到对方的指定信息。Docker 提供了 --link 选项来实现容器互联,在一个容器中可以通过另一个容器的名称来访问它。
7.1 创建并运行源容器 web1
首先,创建并运行源容器 web1,它将作为通信的源容器。使用 CentOS 镜像启动容器,并让容器在后台运行:
bash
docker run -itd -P --name web1 centos:7 /bin/bash
-itd: 启动容器并使其在后台运行。-P: 随机映射容器的端口到宿主机。--name web1: 给容器指定一个名称web1。centos:7: 使用 CentOS 7 镜像启动容器。/bin/bash: 启动后进入容器的 bash shell。
7.2 创建并运行接收容器 web2
接下来,创建并运行接收容器 web2,并使用 --link 选项来连接容器 web1,从而实现容器间的通信。
bash
docker run -itd -P --name web2 --link web1:web1 centos:7 /bin/bash
--link web1:web1: 通过--link选项连接web1容器,将web1容器暴露给web2容器,并在web2中将web1显示为别名web1。这样web2容器就可以通过web1访问源容器的信息。
7.3 在接收容器 web2 中测试连接
进入容器 web2,然后尝试 ping web1 容器,验证是否可以与 web1 容器通信:
bash
docker exec -it web2 bash
ping web1
docker exec -it web2 bash: 进入web2容器的 bash 环境。ping web1: 测试web2是否能与web1通信。
如果连接成功,说明容器互联配置正确。
7.4 总结
- 源容器 :通过
docker run启动,并通过--name指定一个唯一名称,例如web1。 - 接收容器 :通过
docker run启动,并通过--link选项将其与源容器web1连接。--link会将源容器暴露为别名,接收容器可以通过该别名与源容器进行通信。 - 容器间通信 :接收容器可以通过源容器的名称进行通信,如在
web2中通过ping web1测试与web1的连通性。
这种容器互联的方式适用于简单的容器间网络通信,但在较复杂的场景中,建议使用 Docker 网络(如桥接网络或自定义网络)来管理容器间的通信。
8. Docker 镜像的创建
Docker 提供了多种方式来创建镜像,常见的有三种方法:基于已有镜像创建、基于本地模板创建和基于 Dockerfile 创建。以下是这三种方法的详细介绍。
8.1 基于现有镜像创建
8.1.1 启动容器并做修改
-
首先,通过
docker create启动一个容器并进入其 bash 环境:bashdocker create -it centos:7 /bin/bash-it参数表示交互式运行,/bin/bash表示启动 bash shell。 -
查看当前容器的状态:
bashdocker ps -a -
修改容器内部的环境(例如安装软件包、修改配置文件等),然后退出容器。
8.1.2 提交容器为新的镜像
完成容器内的修改后,可以通过 docker commit 命令将容器提交为新的镜像:
bash
docker commit -m "new" -a "centos" 000550eb36da centos:test
-m: 提交说明。-a: 作者信息。000550eb36da: 容器 ID。centos:test: 创建的新镜像名称。
查看创建的新镜像:
bash
docker images
8.2 基于本地模板创建
通过导入模板文件,可以创建一个新的镜像。模板通常可以从开源项目(如 OPENVZ)中获取。
8.2.1 下载操作系统模板
例如,下载 Debian 模板:
bash
下载地址为http://openvz.org/Download/template/precreated
wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz
也可以使用 curl 下载:
bash
curl -L 下载路径 -o 保存路径
wget
8.2.2 导入为 Docker 镜像
将模板文件导入为 Docker 镜像:
bash
cat debian-7.0-x86-minimal.tar.gz | docker import - debian:test
这里 debian:test 是新创建的镜像名称。
8.3 基于 Dockerfile 创建 重点
Dockerfile 是一个文本文件,其中包含了一系列的指令,每个指令创建一个新的镜像层。通过 Dockerfile,我们可以实现镜像的自动化构建。
8.3.1 Docker 镜像的分层结构
-
镜像分层:Docker 镜像不是单一文件,而是由多层文件系统组成。每执行一条 Dockerfile 指令,都会生成新的镜像层。容器启动时会在镜像的只读层上添加一层可读写层。
-
镜像缓存:Docker 会缓存每一层的镜像,如果某一层的内容没有变化,则会复用缓存层,以提高构建效率。
//联合文件系统(UnionFS)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。AUFS、OverlayFS 及 Devicemapper 都是一种 UnionFS。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
我们下载的时候看到的一层层的就是联合文件系统。
//镜像加载原理
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。
在Docker镜像的最底层是bootfs,这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs,在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
我们可以理解成一开始内核里什么都没有,操作一个命令下载debian,这时就会在内核上面加了一层基础镜像;再安装一个emacs,会在基础镜像上叠加一层image;接着再安装一个apache,又会在images上面再叠加一层image。最后它们看起来就像一个文件系统即容器的rootfs。在Docker的体系里把这些rootfs叫做Docker的镜像。但是,此时的每一层rootfs都是read-only的,我们此时还不能对其进行操作。当我们创建一个容器,也就是将Docker镜像进行实例化,系统会在一层或是多层read-only的rootfs之上分配一层空的read-write的rootfs。
//为什么Docker里的centos的大小才200M?
因为对于精简的OS,rootfs可以很小,只需要包含最基本的命令、工具和程序库就可以了,因为底层直接用宿主机的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。 -
Dockerfile基本细说
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
Dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了Dockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成 image 即可, 省去了敲命令的麻烦。
除了手动生成Docker镜像之外,可以使用Dockerfile自动生成镜像。Dockerfile是由多条的指令组成的文件,其中每条指令对应 Linux 中的一条命令,Docker 程序将读取Dockerfile 中的指令生成指定镜像。
Dockerfile结构大致分为四个部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以"#"号开头的注释。
#Docker 镜像结构的分层
镜像不是一个单一的文件,而是有多层构成。容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。如果删除了容器,也就删除了其最上面的读写层,文件改动也就丢失了。Docker使用存储驱动管理镜像每层内容及可读写层的容器层。(1)Dockerfile 中的每个指令都会创建一个新的镜像层;
(2)镜像层将被缓存和复用;
(3)当Dockerfile 的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效;
(4)某一层的镜像缓存失效,它之后的镜像层缓存都会失效;
(5)镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件,只是这个文件在 Docker 容器中不可见了。
基于图更好理解




8.3.2 Dockerfile 操作常用指令 重点
以下是 Dockerfile 中常用的指令:
-
FROM
指定新镜像基于的基础镜像,Dockerfile 的第一条指令必须为
FROM。dockerfileFROM centos:7 -
MAINTAINER
指定镜像的维护者信息:
dockerfileMAINTAINER "John Doe <johndoe@example.com>" -
RUN
执行命令并将结果提交到镜像中。常用来安装软件包、修改配置等。
dockerfileRUN yum install -y httpd
ls
rm
cd
```
-
ENTRYPOINT
设置容器启动时默认执行的命令:
dockerfileENTRYPOINT ["httpd"] -
CMD
容器启动时执行的默认命令。
CMD指令会被docker run命令后指定的命令覆盖。dockerfileCMD ["httpd", "-D", "FOREGROUND"] -
EXPOSE
声明容器内的端口:
dockerfileEXPOSE 80 -
ENV
设置环境变量:
dockerfileENV MY_VAR=my_value -
ADD
将文件或目录从宿主机复制到镜像中,支持从 URL 下载文件,并能自动解压归档文件:
dockerfileADD myfile.tar.gz /app -
COPY
将本地文件或目录复制到镜像中:
dockerfileCOPY . /app -
VOLUME
在容器中创建挂载点:
dockerfileVOLUME ["/data"] -
USER
设置容器内运行命令时的用户:
dockerfileUSER root -
WORKDIR
设置后续指令的工作目录:
dockerfileWORKDIR /app -
ONBUILD
设置当该镜像作为基础镜像时,后续 Dockerfile 执行的命令:
dockerfileONBUILD RUN echo "Building from base image" -
HEALTHCHECK
设置容器的健康检查:
dockerfileHEALTHCHECK CMD curl --fail http://localhost:8080 || exit 1
面试时候说法
在编写 Dockerfile 时,有严格的格式需要遵循: 还是你面试中说出 dockerfile 环境编写
●第一行必须使用 FROM 指令指明所基于的镜像名称;
●之后使用 MAINTAINER 指令说明维护该镜像的用户信息;
●然后是镜像操作相关指令,如 RUN 指令。每运行一条指令,都会给基础镜像添加新的一层。
●最后使用 CMD 指令指定启动容器时要运行的命令操作。
8.3.3 Dockerfile 示例
以下是一个简单的 Dockerfile 示例:
dockerfile
# 使用 CentOS 7 作为基础镜像
#建立工作目录
mkdir /opt/apache
cd /opt/apache
vim Dockerfile
#基于的基础镜像
FROM centos:7
#维护镜像的用户信息
MAINTAINER this is apache image <hmj>
#镜像操作指令安装apache软件
ADD CentOS-Base.repo /etc/yum.repos.d/
RUN yum clean all
RUN yum -y update
RUN yum -y install httpd
#开启 80 端口
EXPOSE 80
#复制网站首页文件
ADD index.html /var/www/html/index.html
//方法一:
#将执行脚本复制到镜像中
ADD run.sh /run.sh
RUN chmod 755 /run.sh
#启动容器时执行脚本
CMD ["/run.sh"]
//方法二:
ENTRYPOINT [ "/usr/sbin/apachectl" ]
CMD ["-D", "FOREGROUND"]
//方法三
# 启动 httpd 服务
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
准备执行脚本(方式一)
vim run.sh
#!/bin/bash
rm -rf /run/httpd/* #清理httpd的缓存
/usr/sbin/apachectl -D FOREGROUND #指定为前台运行
#因为Docker容器仅在它的1号进程(PID为1)运行时,会保持运行。如果1号进程退出了,Docker容器也就退出了。
//准备网站页面
//
echo "this is test web" > index.html
//生成镜像
docker build -t httpd:centos . #注意别忘了末尾有"."
//新镜像运行容器
docker run -d -p 1216:80 httpd:centos
//测试
http://192.168.10.23:1216/
8.3.4 构建镜像
使用以下命令构建镜像:
bash
docker build -t my-web-server .
这将根据当前目录下的 Dockerfile 构建一个名为 my-web-server 的镜像。
8.3.5 镜像的分层和缓存
- 每一条 Dockerfile 指令都会创建一个新的镜像层。
- Docker 会缓存每一层的镜像,只有在指令或文件发生变化时,才会重新构建该层及其之后的层。
- 镜像层是不可变的,删除容器时只会删除其上面的读写层,底层的镜像层不会丢失。
8.4 总结
Docker 镜像的创建方式多种多样,常用的有:
- 基于现有镜像创建:通过修改容器并提交为新的镜像。
- 基于本地模板创建:从模板文件导入创建镜像。
- 基于 Dockerfile 创建:通过编写 Dockerfile 来定制镜像,支持自动化构建。
好的,继续接下来的内容。下面是关于 Nginx + Tomcat 的 Docker Compose 编排 部分的梳理,已经按 Markdown 大纲格式进行整理:
好的,下面是完整的 Nginx + Tomcat Docker Compose 编排 的详细步骤,其中包括了 YAML 文件格式及编写注意事项,以及对各个部分的解释和使用:
9. Docker Compose 编排
9.1 简介
通过 Docker Compose,我们可以在一个 YAML 配置文件中定义多个服务,并实现容器之间的联动,简化了应用的部署和管理。
Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。
Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(container)。Docker-Compose运行目录下的所有文件(docker-compose.yml,extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。一个服务当中可包括多个容器实例,Docker-Compose并没有解决负载均衡的问题,因此需要借助其它工具实现服务发现及负载均衡,比如 Consul。
Docker-Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。
使用一个Dockerfile模板文件,可以让用户很方便的定义一个单独的应用容器。在工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个Web项目,除了Web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
LNMP
Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
Docker-Compose项目由Python编写,调用Docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持Docker API, 就可以在其上利用Compose来进行编排管理
在 Web 应用中,常常需要将前端的请求通过反向代理转发到后端应用服务器。在这里,我们将使用 Docker Compose 来编排 Nginx 和 Tomcat 两个服务。Nginx 将作为前端的反向代理服务器,接收客户端请求并将其转发到后端的 Tomcat 容器。Tomcat 则负责处理 Web 应用的请求。
9.2 项目结构
9.2.1 Docker Compose 环境安装
#下载
curl -L https://github.com/docker/compose/releases/download/1.21.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
#安装
chmod +x /usr/local/bin/docker-compose
#查看版本
docker-compose --version
新的版本下载地址
sudo curl -L "https://github.com/docker/compose/releases/download/2.26.0/docker-compose-linux-aarch64" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
9.3 YAML 文件格式及编写注意事项
YAML(YAML Ain't Markup Language)是一种简洁的数据序列化格式,常用于配置文件。它比 JSON 更加简洁易读,并且支持更复杂的数据结构。使用 YAML 编写 Docker Compose 配置文件时,有几个注意事项:
9.3.1 YAML 基本语法
- 大小写敏感:YAML 是大小写敏感的,所以一定要注意区分大小写。
- 缩进 :YAML 使用空格进行缩进,不支持 TAB 缩进。通常推荐使用两个空格作为一个层级的缩进。
- 列表 :列表项使用
-(短横线)表示。 - 字典 :字典使用
:(冒号)连接键值对,冒号后面需要加一个空格。 - 注释 :使用
#来添加注释。 - 字符串 :如果字符串包含特殊字符,可以使用单引号
'或双引号"来包裹。
数据结构:
●对象映射: 键值对的字典
animal: pets
●序列数组: 一组按次序排列的列表
- Cat
- Dog
- Goldfish
["Cat", "Dog", "Goldfish"]
●布尔值
debug: true
debug: false
示例:
# yaml 格式
languages: #序列的映射
- Java
- Golang
- Python
websites: #映射的映射
cpu: 2
memory: 1024M
swap: 2048M
disk: 60G
键:{值}
# Json 格式
{
languages: [
'Java',
'Golang',
'Python'
],
resources: {
cpu: '2',
memory: '1024M',
swap: '2048M',
disk: '60G'
}
}
Baidu:
www.baidu.com
ftp.baidu.com
wangyi: www.163.com
tengxun: www.qq.com
键 值
school: bei da
kgc: (两个空格)
yunjisuan:
- dingding
- benet
- wanglei
- zhoubo
- dalao
dashuju:
- lijia
- chenming
9.3.2 Docker Compose配置常用字段
字段 描述
build 指定 Dockerfile 文件名,
要指定Dockerfile文件需要在build标签的子级标签中使用dockerfile标签指定
dockerfile 构建镜像上下文路径
context 可以是 dockerfile 的路径,或者是指向 git 仓库的 url 地址
image 指定镜像
command: 执行命令,覆盖容器启动后默认执行的命令
container_name 指定容器名称,由于容器名称是唯一的,如果指定自定义名称,则无法scale指定容器数量
deploy 指定部署和运行服务相关配置,只能在 Swarm 模式使用
environment 添加环境变量
networks 加入网络,引用顶级networks下条目
network_mode 设置容器的网络模式,如 host,bridge,...
ports 暴露容器端口,与 -p 相同,但端口不能低于 60
volumes 挂载一个宿主机目录或命令卷到容器,命名卷要在顶级 volumes 定义卷名称
volumes_from 从另一个服务或容器挂载卷,可选参数 :ro 和 :rw,仅版本 '2' 支持
hostname 容器主机名
sysctls 在容器内设置内核参数
links 连接到另外一个容器,- 服务名称[:服务别名]
privileged 用来给容器root权限,注意是不安全的,true | false
restart 设置重启策略,no,always,nounless-st-failure,oped
no,默认策略,在容器退出时不重启容器。
on-failure,在容器非正常退出时(退出状态非0),才会重启容器。
on-failure:3,在容器非正常退出时重启容器,最多重启3次。
always,在容器退出时总是重启容器。
unless-stopped,在容器退出的容器时总是重启容器,但是不考虑在 Docker 守护进程启动时就已经停止了。
depends_on 在使用Compose时,最大的好处就是少打启动命令,但一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,可能会因为容器依赖问题而启动失败。例如在没启动数据库容器的时候启动应用容器,应用容器会因为找不到数据库而退出。depends_on标签用于解决容器的依赖、启动先后的问题。
php:
depends_on:
- apache
- mysql
9.3.3 Docker Compose 常用命令
字段 描述
build 重新构建服务
ps 列出容器
up 创建和启动容器
exec 在容器里面执行命令
scale 指定一个服务容器启动数量
top 显示容器进程
logs 查看容器输出
down 删除容器、网络、数据卷和镜像
stop/start/restart 停止/启动/重启服务
9.3.4 Docker Compose 文件结构
/opt/compose_nginx_tomcat/
├── docker-compose.yml # Docker Compose 配置文件
├── nginx
│ ├── Dockerfile # Nginx 镜像的 Dockerfile
│ └── nginx.conf # Nginx 配置文件
├── tomcat
│ ├── Dockerfile # Tomcat 镜像的 Dockerfile
│ └── webapps
│ └── ROOT.war # Tomcat 应用的 WAR 包
└── wwwroot
└── index.html # 静态文件,Nginx 显示的页面
9.3.2 YAML 示例
① 准备依赖文件
mkdir -p /opt/compose_nginx/nginx /opt/compose_nginx/wwwroot
cd /opt/compose_nginx/nginx
cp nginx-1.20.2.tar.gz ./
vim run.sh
#!/bin/bash
/usr/local/nginx/sbin/nginx
vim Dockerfile
#基于基础镜像
FROM centos:7
#用户信息
MAINTAINER this is nginx image <hmj>
#添加环境包
RUN rm -rf /etc/yum.repos.d/*
ADD CentOS-Base.repo /etc/yum.repos.d/
RUN yum clean all && \
yum makecache && \
yum -y install pcre-devel zlib-devel gcc gcc-c++ make && \
useradd -M -s /sbin/nologin nginx
#上传nginx软件压缩包,并解压
ADD nginx-1.20.2.tar.gz /usr/local/src/
#指定工作目录
WORKDIR /usr/local/src/nginx-1.20.2
RUN ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
ENV PATH /usr/local/nginx/sbin:$PATH
#指定http和https端口
EXPOSE 80
EXPOSE 443
//方法一:
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf #关闭 nginx 在后台运行
#添加宿主机中run.sh到容器中
ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]
//方法二:
ENTRYPOINT [ "/usr/local/nginx/sbin/nginx", "-g", "daemon off;" ]
echo "<h1>this is test web</h1>" > /opt/compose_nginx/wwwroot/index.html
② 编写配置文件docker-compose.yml
yaml
vim /opt/compose_nginx/docker-compose.yml
version: '3'
services:
nginx:
container_name: web1
hostname: nginx
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- 1216:80
- 1217:443
networks:
lnmp:
ipv4_address: 172.18.0.10
volumes:
- ./wwwroot:/usr/local/nginx/html
networks:
lnmp:
driver: bridge
ipam:
config:
- subnet: 172.18.0.0/16
cd /opt/compose_nginx/
docker-compose -f docker-compose.yml up -d
----------------------------------------------------------------------------------------------------------
-f, --file FILE :使用特定的 compose 模板文件,默认为 docker-compose.yml
-p, --project-name NAME :指定项目名称,默认使用目录名称
-d :在后台运行
----------------------------------------------------------------------------------------------------------
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b48dceee248f compose_nginx_nginx "/run.sh" About a minute ago Up About a minute 0.0.0.0:1216->80/tcp, 0.0.0.0:1217->443/tcp compose_nginx_nginx_1
cd /opt/compose_nginx/
docker-compose ps #必须在docker-compose.yml所在目录执行此命令
浏览器访问:http://192.168.10.23:1216
9.3.3 编写注意事项
- 文件路径 :在
docker-compose.yml文件中,context和volumes路径都是相对路径,相对于docker-compose.yml文件所在的目录。 - 字段区分 :YAML 格式中,
services下定义的每个服务都会有自己的配置项,例如image、build、ports等。确保每个字段的位置和缩进正确。 - 服务间的依赖关系 :例如,
depends_on可以控制服务启动的顺序,确保依赖的服务先启动。
9.4 准备 Nginx 配置
在 nginx/nginx.conf 中,配置 Nginx 作为反向代理,转发请求到 Tomcat 服务:
nginx
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://tomcat:8080; # 将请求转发给 Tomcat 服务
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
proxy_pass http://tomcat:8080表示将请求转发到名为tomcat的服务(在 Compose 中,这个名称会自动解析为 Tomcat 容器的名称)。- 配置
proxy_set_header是为了确保转发请求时,Nginx 会把客户端的 IP 和请求头传递给后端服务器。
9.5 编写 docker-compose.yml
接下来,我们编写 docker-compose.yml 配置文件,定义 Nginx 和 Tomcat 两个服务。以下是一个完整的示例:
yaml
version: '3'
services:
nginx:
container_name: nginx
image: nginx:latest
build:
context: ./nginx
ports:
- "8081:80" # 将宿主机的8081端口映射到Nginx的80端口
volumes:
- ./wwwroot:/usr/share/nginx/html # 映射静态文件目录
networks:
- app_network
depends_on:
- tomcat # 确保Tomcat容器先启动
tomcat:
container_name: tomcat
build:
context: ./tomcat
ports:
- "8080:8080" # 将宿主机的8080端口映射到Tomcat的8080端口
networks:
- app_network
environment:
- JAVA_OPTS=-Djava.security.egd=file:/dev/./urandom
networks:
app_network:
driver: bridge
depends_on确保 Nginx 服务启动时,Tomcat 服务已启动并运行。networks部分将两个服务连接到同一个 Docker 网络app_network,保证它们之间可以相互通信。
9.6 启动服务
完成以上配置后,可以通过 docker-compose 启动项目:
bash
cd /opt/compose_nginx_tomcat
docker-compose up -d
-d参数表示在后台运行容器。
10. Docker--Harbor 私有仓库部署与管理
10.1 搭建本地私有仓库
10.1.1 下载 registry 镜像
私有镜像仓库的核心是 Docker Registry,我们通过以下命令下载官方的 registry 镜像:
bash
docker pull registry
10.1.2 配置 Docker 守护进程
为了能够与我们搭建的私有仓库进行交互,我们需要配置 Docker 的守护进程,让其支持连接不安全的私有镜像仓库。
编辑 Docker 配置文件 /etc/docker/daemon.json,并添加私有仓库地址:
bash
vim /etc/docker/daemon.json
在该文件中加入如下内容:
json
{
"insecure-registries": ["192.168.10.23:5000"], # 允许访问的私有仓库地址,注意用逗号结尾
"registry-mirrors": ["https://ae3f5qei.mirror.aliyuncs.com"] # 阿里云 Docker 镜像加速器地址
}
修改完后重启 Docker 服务:
bash
systemctl restart docker.service
10.1.3 运行 Registry 容器
通过 Docker 运行一个 registry 容器,指定本地存储路径和端口映射:
bash
docker run -itd -v /data/registry:/var/lib/registry -p 5000:5000 --restart=always --name registry registry:latest
-itd:在容器中启动一个伪终端,进行交互,并让容器在后台运行。-v /data/registry:/var/lib/registry:将宿主机的/data/registry目录挂载到容器内的/var/lib/registry目录,用于存储镜像数据,保证数据的持久化。-p 5000:5000:将宿主机的 5000 端口映射到容器内的 5000 端口,提供访问入口。--restart=always:配置容器在停止后自动重启。--name registry:容器命名为registry。registry:latest:使用官方镜像registry来创建容器。
10.1.4 Docker 容器的重启策略
Docker 支持几种容器重启策略:
no:容器退出时不自动重启。on-failure:仅当容器非正常退出时(即返回错误代码)才重启。on-failure:3:最多重启 3 次,如果容器失败 3 次,则不再重启。always:容器退出时总是自动重启。unless-stopped:容器退出时总是自动重启,除非 Docker 服务停止时容器已经停止。
10.1.5 为镜像打标签
上传镜像到私有仓库前,我们需要给本地镜像打上标签,标签格式为 <私有仓库地址>/<镜像名>:<标签>。
bash
docker tag centos:7 192.168.10.23:5000/centos:v1
其中 centos:7 是本地镜像,192.168.10.23:5000/centos:v1 是我们要推送到私有仓库的镜像标签。
10.1.6 上传镜像到私有仓库
上传镜像到私有仓库的命令是:
bash
docker push 192.168.10.23:5000/centos:v1
如果这是第一次上传该镜像,Docker 会先从本地计算差异,然后推送镜像层到私有仓库。
10.1.7 列出私有仓库的所有镜像
可以通过 curl 请求获取仓库中的所有镜像:
bash
curl http://192.168.10.23:5000/v2/_catalog
这将返回一个 JSON 格式的镜像列表。
10.1.8 获取镜像的所有 Tag
要列出某个镜像的所有版本标签(Tag),可以使用以下命令:
bash
curl http://192.168.10.23:5000/v2/centos/tags/list
返回的结果是该镜像在仓库中的所有标签,如 v1、v2 等。
10.1.9 测试私有仓库下载镜像
如果我们之前已经删除了本地的 CentOS 镜像,可以通过以下命令从私有仓库拉取镜像:
bash
docker rmi -f 8652b9f0cb4c # 删除本地镜像
docker pull 192.168.10.23:5000/centos:v1 # 从私有仓库拉取镜像
10.2 Harbor 简介
10.2.1 什么是 Harbor
Harbor 是一个企业级的 Docker 镜像仓库管理平台,它在 Docker Registry 的基础上进行了扩展,增加了更多功能,使得管理镜像更加方便和安全。Harbor 提供了图形化管理界面、角色访问控制、镜像复制、LDAP 集成等功能。
Harbor 的每个组件都是以 Docker 容器的形式构建的,使用 docker-compose 来对它进行部署。用于部署 Harbor 的 docker-compose 模板位于 harbor/docker-compose.yml。
10.2.2 Harbor 特性
- 图形化管理界面:通过浏览器访问,方便用户管理镜像和权限。
- 基于角色的访问控制:用户可在 Harbor 中创建不同角色并为每个角色分配不同的权限。
- LDAP/AD 集成:支持与 LDAP 或 Active Directory 集成,进行用户认证和权限管理。
- 镜像复制:支持将镜像从一个 Harbor 实例复制到另一个实例,实现跨数据中心的镜像管理。
- 审计日志:记录所有操作的日志,便于审计和排查问题。
- 安全扫描:集成 Clair 进行镜像的安全扫描,自动检测镜像中的漏洞。
10.2.3 Harbor 架构
Harbor 在架构上主要有 Proxy、Registry、Core services、Database(Harbor-db)、Log collector(Harbor-log)、Job services 六个组件
Harbor 的核心组件包括:
-
Proxy:反向代理,用于处理客户端请求。
是一个 nginx 的前端代理,Harbor 的 Registry、UI、Token 服务等组件,都处在 nginx 反向代理后边。 该代理将来自浏览器、docker clients 的请求转发到后端不同的服务上。 -
Registry :存储 Docker 镜像的核心组件,支持 Docker 的
push和pull操作。负责储存 Docker 镜像,并处理 Docker push/pull 命令。由于要对用户进行访问控制,即不同用户对 Docker 镜像 有不同的读写权限,Registry 会指向一个 Token 服务,强制用户的每次 Docker pull/push 请求都要携带一个合法的 Token, Registry 会通过公钥对 Token 进行解密验证。 认证方式有三种 扩展 令牌 用户密码 ssl -
Core Services:包含 Web 界面、API 和 Webhook 等服务。
1)UI(harbor-ui): 提供图形化界面,帮助用户管理 Registry 上的镜像(image), 并对用户进行授权。 2)WebHook:为了及时获取Registry上image 状态变化的情况,在Registry 上配置 Webhook,把状态变化传递给 UI 模块。 3)Token 服务:负责根据用户权限给每个 Docker push/pull 命令签发 Token。Docker 客户端向 Registry 服务发起的请求, 如果不包含 Token,会被重定向到 Token 服务,获得 Token 后再重新向 Registry 进行请求。 -
Database:保存 Harbor 的配置和镜像的元数据。
为core services提供数据库服务,负责储存用户权限、审计日志、Docker 镜像分组信息等数据。 -
Job Services:处理镜像复制等异步任务。
主要用于镜像复制,本地镜像可以被同步到远程 Harbor 实例上。 -
Log Collector:收集 Harbor 各组件的日志。
Harbor 的每个组件都是以 Docker 容器的形式构建的,因此,使用 Docker Compose 来对它进行部署。
总共分为7个容器运行,通过在docker-compose.yml所在目录中执行 docker-compose ps 命令来查看, 名称分别为:nginx、harbor-jobservice、harbor-ui、harbor-db、harbor-adminserver、registry、harbor-log。
其中 harbor-adminserver 主要是作为一个后端的配置数据管理,并没有太多的其他功能。harbor-ui 所要操作的所有数据都通过 harbor-adminserver 这样一个数据配置管理中心来完成。

数据流向分析:
- Docker客户端 / 浏览器 :
- 用户通过 Docker 客户端或者浏览器进行交互。
- Proxy(代理) :
- 客户端的请求会通过代理转发,可能是为了负载均衡或处理一些中间层逻辑。
- Core services(核心服务) :
- 包含 UI 、token 和 webhook。这些服务处理用户请求的业务逻辑,比如 UI 提供用户界面,token 服务管理认证,webhook 可能用于触发外部通知或事件。
- Registry(注册表) :
- 这是容器镜像的存储地方,核心服务会与 Registry 交互来存储或获取镜像。
- Database(数据库) :
- Core services 还与数据库交互,用来存储与 Harbor 相关的元数据、配置、用户信息等。
- Job services(作业服务) :
- 处理后台任务和作业,可能包括镜像同步、清理任务等。
- Log Collector(日志收集器) :
- 系统会收集日志以便后期分析和排查。
- Replication to remote Harbor instances(同步到远程 Harbor 实例) :
- 可能用于在多个 Harbor 实例之间同步镜像,保证镜像的高可用和分布式存储。
10.3 部署 Harbor 服务
10.3.1 安装 Docker Compose
Harbor 使用 Docker Compose 来启动各个组件,所以需要安装 Docker Compose 工具:
bash
curl -L https://github.com/docker/compose/releases/download/1.21.1/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose --version
10.3.2 下载 Harbor 安装包
从 Harbor 官网下载离线安装包:
bash
wget https://github.com/goharbor/harbor/releases/download/v2.4.0/harbor-offline-installer-v2.4.0.tgz
tar zxvf harbor-offline-installer-v2.4.0.tgz -C /usr/local/
10.3.3 修改 Harbor 配置文件
在 /usr/local/harbor/ 目录中修改 harbor.cfg 配置文件,设置 Harbor 服务器的地址、管理员密码等:
bash
vim /usr/local/harbor/harbor.cfg
修改以下字段:
-
hostname: 配置为 Harbor 的 IP 地址或域名,例如192.168.10.23。--5行--修改,设置为Harbor服务器的IP地址或者域名 hostname = 192.168.10.23 -
harbor_admin_password: 设置管理员密码。--59行--指定管理员的初始密码,默认的用户名/密码是admin/Harbor12345 harbor_admin_password = Harbor12345
关于 Harbor.cfg 配置文件中有两类参数:所需参数和可选参数
1、所需参数:这些参数需要在配置文件 Harbor.cfg 中设置。如果用户更新它们并运行 install.sh 脚本重新安装 Harbor, 参数将生效。具体参数如下:
-
hostname:用于访问用户界面和 register 服务。它应该是目标机器的 IP 地址或完全限定的域名(FQDN),例如 192.168.10.23 或 hub.kgc.cn。不要使用 localhost 或 127.0.0.1 为主机名。
-
ui_url_protocol:(http 或 https,默认为 http)用于访问 UI 和令牌/通知服务的协议。如果公证处于启用状态,则此参数必须为 https。
-
max_job_workers:镜像复制作业线程。
-
db_password:用于db_auth 的MySQL数据库root 用户的密码。
-
customize_crt:该属性可设置为打开或关闭,默认打开。打开此属性时,准备脚本创建私钥和根证书,用于生成/验证注册表令牌。当由外部来源提供密钥和根证书时,将此属性设置为 off。
-
ssl_cert:SSL 证书的路径,仅当协议设置为 https 时才应用。
-
secretkey_path:用于在复制策略中加密或解密远程 register 密码的密钥路径。
2、可选参数:这些参数对于更新是可选的,即用户可以将其保留为默认值,并在启动 Harbor 后在 Web UI 上进行更新。如果进入 Harbor.cfg,只会在第一次启动 Harbor 时生效,随后对这些参数的更新,Harbor.cfg 将被忽略。
注意:如果选择通过 UI 设置这些参数,请确保在启动 Harbor 后立即执行此操作。具体来说,必须在注册或在 Harbor 中创建任何新用户之前设置所需的 auth_mode。当系统中有用户时(除了默认的 admin 用户), auth_mode 不能被修改。 具体参数如下:
-
Email:Harbor 需要该参数才能向用户发送"密码重置"电子邮件,并且只有在需要该功能时才启用。请注意,在默认情况下 SSL 连接时没有启用。如果 SMTP 服务器需要 SSL,但不支持 STARTTLS,那么应该通过设置启用 SSL email_ssl = TRUE。
-
harbor_admin_password:管理员的初始密码,只在 Harbor 第一次启动时生效。之后, 此设置将被忽略,并且应在 UI 中设置管理员的密码。请注意,默认的用户名/密码是admin/Harbor12345。
-
auth_mode:使用的认证类型,默认情况下,它是 db_auth,即凭据存储在数据库中。对于LDAP身份验证,请将其设置为 ldap_auth。
-
self_registration:启用/禁用用户注册功能。禁用时,新用户只能由 Admin 用户创建,只有管理员用户可以在 Harbor 中创建新用户。注意:当 auth_mode 设置为 ldap_auth 时,自注册功能将始终处于禁用状态,并且该标志被忽略。
-
Token_expiration:由令牌服务创建的令牌的到期时间(分钟),默认为 30 分钟。
-
project_creation_restriction:用于控制哪些用户有权创建项目的标志。默认情况下,每个人都可以创建一个项目。 如果将其值设置为"adminonly",那么只有 admin 可以创建项目。
-
verify_remote_cert:打开或关闭,默认打开。此标志决定了当Harbor与远程 register 实例通信时是否验证 SSL/TLS 证书。 将此属性设置为 off 将绕过 SSL/TLS 验证,这在远程实例具有自签名或不可信证书时经常使用。
另外,默认情况下,Harbor 将镜像存储在本地文件系统上。在生产环境中,可以考虑 使用其他存储后端而不是本地文件系统,如 S3、Openstack Swif、Ceph 等对象存储。但需要更新 common/templates/registry/config.yml 文件。
Harbor的默认镜像存储路径在 /data/registry 目录下,映射到docker容器里面的 /storage 目录下。
这个参数是在 docker-compose.yml 中指定的,在 docker-compose up -d 运行之前修改。
如果希望将 Docker 镜像存储到其他的磁盘路径,可以修改这个参数。
10.3.4 启动 Harbor
配置好文件后,运行以下命令启动 Harbor 服务:
bash
#在配置好了 harbor.cfg 之后,执行 ./prepare 命令,为 harbor 启动的容器生成一些必要的文件(环境)
再执行命令 ./install.sh 以 pull 镜像并启动容器
cd /usr/local/harbor/
./prepare
./install.sh
10.3.5 查看 Harbor 启动状态
通过 docker-compose 查看各个 Harbor 服务的状态:
bash
cd /usr/local/harbor/
docker-compose ps
如果 Harbor 启动成功,应该能看到各个容器的状态为 "Up"。
10.3.6 创建一个新项目
(1)浏览器访问:http://192.168.10.23 登录 Harbor WEB UI 界面,默认的管理员用户名和密码是 admin/Harbor12345
(2)输入用户名和密码登录界面后可以创建一个新项目。点击"+项目"按钮
(3)填写项目名称为"myproject-yjs",点击"确定"按钮,创建新项目
(4)此时可使用 Docker 命令在本地通过 127.0.0.1 来登录和推送镜像。默认情况下,Registry 服务器在端口 80 上侦听。
//登录 Harbor
docker login [-u admin -p Harbor12345] http://127.0.0.1
//下载镜像进行测试
docker pull nginx
//将镜像打标签
格式:docker tag 镜像:标签 仓库IP/项目名称/镜像名:标签
docker tag nginx:latest 127.0.0.1/myproject-yjs/nginx:v1
//上传镜像到 Harbor
docker push 127.0.0.1/myproject-yjs/nginx:v1
(5)在 Harbor 界面 myproject-kgc 目录下可看见此镜像及相关信息
10.4 客户端上传镜像
10.4.1 配置 Docker 客户端
以上操作都是在 Harbor 服务器本地操作。如果其他客户端登录到 Harbor,就会报如下错误。出现这问题的原因为Docker Registry 交互默认使用的是 HTTPS,但是搭建私有镜像默认使用的是 HTTP 服务,所以与私有镜像交互时出现以下错误。
docker login -u admin -p Harbor12345 http://192.168.10.23
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Error response from daemon: Get https://192.168.10.23/v2/: dial tcp 192.168.10.23:443: connect: connection refused
(1)在 Docker 客户端配置操作
为了让 Docker 客户端能够访问私有仓库,配置文件需要添加 --insecure-registry 参数:
bash
//解决办法是:在 Docker server 启动的时候,增加启动参数,默认使用 HTTP 访问。
vim /usr/lib/systemd/system/docker.service
--13行--修改
ExecStart=/usr/bin/dockerd -H fd:// --insecure-registry 192.168.10.23 --containerd=/run/containerd/containerd.sock
或
ExecStart=/usr/bin/dockerd --insecure-registry 192.168.10.23
//重启 Docker,再次登录
systemctl daemon-reload
systemctl restart docker
//再次登录 Harbor
docker login -u admin -p Harbor12345 http://192.168.10.23
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Login Succeeded
//将自动保存凭据到/root/.docker/config.json,下次登录时可直接使用凭据登录 Harbor
//下载镜像进行测试
docker pull 192.168.10.23/myproject-yjs/nginx:v1
//上传镜像进行测试
docker pull cirros
docker tag cirros:latest 192.168.10.23/myproject-yjs/cirros:v2
docker push 192.168.10.23/myproject-yjs/cirros:v2
(2)刷新 Harbor 的 Web 管理界面进行查看,会发现 myproject-yjs 项目里面有两个镜像
10.5 维护管理Harbor
10.5.1 通过 Harbor Web 创建项目
在 Harbor 仓库中,任何镜像在被 push 到 regsitry 之前都必须有一个自己所属的项目。
单击"+项目",填写项目名称,项目级别若设置为"私有",则不勾选。如果设置为公共仓库,则所有人对此项目下的镜像拥有读权限,命令行中不需要执行"Docker login"即可下载镜像,镜像操作与 Docker Hub 一致。
10.5.2 创建 Harbor 用户
(1)创建用户并分配权限
在 Web 管理界面中单击系统管理 -> 用户管理 -> +用户,
填写用户名为"yjs-zhangsan",邮箱为"yjs-zhangsan@kgc.com",全名为"zhangsan",密码为"Abc123456",注释为"管理员"(可省略)。
附:用户创建成功后,单击左侧"..."按钮可将上述创建的用户设置为管理员角色或进行删除操作,本例不作任何设置。
(2)添加项目成员
单击项目 -> myproject-yjs-> 成员 -> + 成员,填写上述创建的用户 yjs-zhangsan 并分配角色为"开发人员"。
附:此时单击左侧"..."按钮仍然可对成员角色进行变更或者删除操作
(3)在客户端上使用普通账户操作镜像
//删除上述打标签的本地镜像
docker rmi 192.168.10.23/myproject-yjs/cirros:v2
//先退出当前用户,然后使用上述创建的账户 yjs-zhangsan 登录
docker logout 192.168.10.23
docker login 192.168.10.23
或
docker login -u yjs-zhangsan -p Abc123456 http://192.168.10.23
//下载和上传镜像进行测试
docker pull 192.168.10.23/myproject-yjs/cirros:v2
docker tag cirros:latest 192.168.10.23/myproject-yjs/cirros:v3
docker push 192.168.10.23/myproject-yjs/cirros:v3
10.5.3 查看日志
Web 界面日志,操作日志按时间顺序记录用户相关操作
10.5.4 修改 Harbor.cfg 配置文件
要更改 Harbor的配置文件中的可选参数时,请先停止现有的 Harbor实例并更新 Harbor.cfg;然后运行 prepare 脚本来填充配置; 最后重新创建并启动 Harbor 的实例。
使用 docker-compose 管理 Harbor 时,必须在与 docker-compose.yml 相同的目录中运行。
cd /usr/local/harbor
docker-compose down -v
vim harbor.cfg #只能修改可选参数
./prepare
docker-compose up -d
//如果有以下报错,需要开启防火墙 firewalld 服务解决
Creating network "harbor_harbor" with the default driver
ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule: (iptables failed: iptables --wait -t nat -I DOCKER -i br-b53c314f45e8 -j RETURN: iptables: No chain/target/match by that name.
(exit status 1))
systemctl restart firewalld.service
docker-compose up -d
10.5.5 移除 Harbor 服务容器同时保留镜像数据/数据库,并进行迁移
在Harbor服务器上操作
(1)移除 Harbor 服务容器
cd /usr/local/harbor
docker-compose down -v
2)把项目中的镜像数据进行打包
//持久数据,如镜像,数据库等在宿主机的/data/目录下,日志在宿主机的/var/log/Harbor/目录下
ls /data/registry/docker/registry/v2/repositories/myproject-yjs
cd /data/registry/docker/registry/v2/repositories/myproject-yjs
tar zcvf kgc-registry.tar.gz ./*
10.5.6 如需重新部署,需要移除 Harbor 服务容器全部数据
cd /usr/local/harbor
docker-compose down -v
rm -r /data/database
rm -r /data/registry
ARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Login Succeeded
//将自动保存凭据到/root/.docker/config.json,下次登录时可直接使用凭据登录 Harbor
//下载镜像进行测试
docker pull 192.168.10.23/myproject-yjs/nginx:v1
//上传镜像进行测试
docker pull cirros
docker tag cirros:latest 192.168.10.23/myproject-yjs/cirros:v2
docker push 192.168.10.23/myproject-yjs/cirros:v2
(2)刷新 Harbor 的 Web 管理界面进行查看,会发现 myproject-yjs 项目里面有两个镜像
### 10.5 维护管理Harbor
#### 10.5.1 通过 Harbor Web 创建项目
在 Harbor 仓库中,任何镜像在被 push 到 regsitry 之前都必须有一个自己所属的项目。
单击"+项目",填写项目名称,项目级别若设置为"私有",则不勾选。如果设置为公共仓库,则所有人对此项目下的镜像拥有读权限,命令行中不需要执行"Docker login"即可下载镜像,镜像操作与 Docker Hub 一致。
#### 10.5.2 创建 Harbor 用户
(1)创建用户并分配权限
在 Web 管理界面中单击系统管理 -> 用户管理 -> +用户,
填写用户名为"yjs-zhangsan",邮箱为"yjs-zhangsan@kgc.com",全名为"zhangsan",密码为"Abc123456",注释为"管理员"(可省略)。
附:用户创建成功后,单击左侧"..."按钮可将上述创建的用户设置为管理员角色或进行删除操作,本例不作任何设置。
(2)添加项目成员
单击项目 -> myproject-yjs-> 成员 -> + 成员,填写上述创建的用户 yjs-zhangsan 并分配角色为"开发人员"。
附:此时单击左侧"..."按钮仍然可对成员角色进行变更或者删除操作
(3)在客户端上使用普通账户操作镜像
//删除上述打标签的本地镜像
docker rmi 192.168.10.23/myproject-yjs/cirros:v2
//先退出当前用户,然后使用上述创建的账户 yjs-zhangsan 登录
docker logout 192.168.10.23
docker login 192.168.10.23
或
docker login -u yjs-zhangsan -p Abc123456 http://192.168.10.23
//下载和上传镜像进行测试
docker pull 192.168.10.23/myproject-yjs/cirros:v2
docker tag cirros:latest 192.168.10.23/myproject-yjs/cirros:v3
docker push 192.168.10.23/myproject-yjs/cirros:v3
#### 10.5.3 查看日志
Web 界面日志,操作日志按时间顺序记录用户相关操作
#### 10.5.4 修改 Harbor.cfg 配置文件
要更改 Harbor的配置文件中的可选参数时,请先停止现有的 Harbor实例并更新 Harbor.cfg;然后运行 prepare 脚本来填充配置; 最后重新创建并启动 Harbor 的实例。
使用 docker-compose 管理 Harbor 时,必须在与 docker-compose.yml 相同的目录中运行。
cd /usr/local/harbor
docker-compose down -v
vim harbor.cfg #只能修改可选参数
./prepare
docker-compose up -d
//如果有以下报错,需要开启防火墙 firewalld 服务解决
Creating network "harbor_harbor" with the default driver
ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule: (iptables failed: iptables --wait -t nat -I DOCKER -i br-b53c314f45e8 -j RETURN: iptables: No chain/target/match by that name.
(exit status 1))
systemctl restart firewalld.service
docker-compose up -d
#### 10.5.5 移除 Harbor 服务容器同时保留镜像数据/数据库,并进行迁移
**在Harbor服务器上操作**
(1)移除 Harbor 服务容器
cd /usr/local/harbor
docker-compose down -v
2)把项目中的镜像数据进行打包
//持久数据,如镜像,数据库等在宿主机的/data/目录下,日志在宿主机的/var/log/Harbor/目录下
ls /data/registry/docker/registry/v2/repositories/myproject-yjs
cd /data/registry/docker/registry/v2/repositories/myproject-yjs
tar zcvf kgc-registry.tar.gz ./*
#### 10.5.6 如需重新部署,需要移除 Harbor 服务容器全部数据
cd /usr/local/harbor
docker-compose down -v
rm -r /data/database
rm -r /data/registry