Docker 入门指南:从 “容器小白” 到快速上手

Docker全阶段

1. Docker发展与简介

1.1 云服务与虚拟化基础

1.1.1 云服务模型介绍

云计算 是通过网络为用户提供可伸缩的计算资源。云服务通常分为以下几种类型:

  1. IaaS(基础设施即服务)
    • 提供虚拟化计算资源(如虚拟机、存储、网络等)。
    • 用户可以灵活配置自己的计算环境,负责安装操作系统、管理资源等。
    • 优点:灵活度高、可扩展性强。
    • 缺点:管理复杂,需要较多技术支持。
  2. PaaS(平台即服务)
    • 提供一个开发平台,用户可以在上面开发应用程序,而无需关注底层硬件或操作系统。
    • 优点:简化开发过程,适合开发者。
    • 缺点:灵活度较低,可能受到平台限制。
  3. SaaS(软件即服务)
    • 提供已经构建好的应用程序,用户可以直接使用,无需安装和维护。
    • 优点:快速部署,省时省力。
    • 缺点:定制化差,依赖于服务提供商。
  4. DaaS(数据即服务)
    • 提供数据处理和分析服务,用户可以访问、分析云端存储的大数据。
    • 优点:降低用户管理数据的难度。
    • 缺点:可能涉及数据隐私问题。
1.1.2 常见云服务提供商
  • 阿里云腾讯云AWSGoogle Cloud华为云等是市场上主要的云服务提供商。
  • 云服务提供商通常提供各种服务,如存储、计算、网络、CDN 等。

1.2 虚拟化技术概述

1.2.1 虚拟化基础
  1. 虚拟化类型

    • 全虚拟化 :虚拟化软件完全模拟硬件环境,允许多个操作系统共享硬件资源,彼此之间相互独立。
      • 适用场景:需要兼容多个操作系统(如 Linux 与 Windows 同时运行)的环境。
    • 半虚拟化 :虚拟机与宿主操作系统协作,通过修改操作系统内核来提高性能。
      • 适用场景:高性能需求的环境,尤其是优化了开源操作系统(如 Linux)的虚拟化。
  2. 虚拟化产品

    • 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 SwarmKubernetes 的集成进行区分,Kubernetes 成为 Docker 引擎推荐的容器编排工具。

    Docker 开始更加聚焦于开发者工具,而逐渐减少对企业级 Kubernetes 的直接支持,特别是在容器编排方面。

  • 2021年:Docker 进一步优化了其本地开发工具,使得开发者能够更容易在本地环境中使用容器和 Kubernetes 进行集成。

    Docker HubDocker Desktop 的改进,使得 Docker 的云端镜像存储和本地开发环境更加流畅。

  • 2022年 :Docker 继续加大对 开发者体验 的关注,推出了对 GitHub 等工具的深度集成,帮助开发者快速构建和部署容器。

    在企业领域,Docker 企业版继续被 Kubernetes 和其他工具组合使用,尤其是对于 CI/CDDevOps 环境中的大规模部署。

  • 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 容器化技术的生态系统

容器技术是一种轻量级、提供隔离的虚拟化技术。这里是一些知名的容器技术:

  1. Docker:市场上最为知名和流行的容器框架之一,拥有生态系统完善且社区活跃的优秀特点。它通过简单的工具和接口,使得应用程序的部署于测试过程更为简单。
  2. Kubernetes:Google 开发并开源的容器编排平台,可以管理、调度和扩展容器的应用。
  3. OpenShift:是 Red Hat 提供的开源的容器平台,基于 Kubernetes,但提供了更丰富的功能。
  4. LXC: Linux 容器技术,比 Docker 更接近传统的虚拟化技术,可以看作是轻量级的 VM(虚拟机)。
  5. Rkt:由 CoreOS 开发的一种容器技术,设计上有别于 Docker,它更注重于安全性和模块化。
  6. Apache Mesos:一种用于大规模数据中心的容器编排平台,特别地,它可以与其他调度系统如 Marathon、Chronos 或 Jenkins 集成。
  7. Containerd:是一个开源的容器运行时,是 Docker 的核心组件之一,可用于管理完整的容器生命周期。
  8. Crio:是一个轻量级的容器运行时,专门用于 Kubernetes。
  9. Singularity:一款专注于面向性能敏感和计算密集型应用程序的容器技术。
  10. Podman:与 Docker 相似,但无需守护进程,支持运行和管理 OCI 容器和镜像。
1.3.6 Docker 容器的优势
  • 移植性:应用和其依赖打包在容器中,跨平台和跨环境运行无缝。
  • 隔离性:容器内的应用互相隔离,不会影响宿主机或其他容器。
  • 效率高:由于不需要完整的操作系统,容器消耗的资源少,启动速度快。
  • 简化部署:通过 Docker,可以轻松创建、复制、修改和删除容器,简化了应用部署和管理的复杂度。
1.3.7 容器技术的应用场景
  • CI/CD(持续集成与持续交付):利用 Docker 快速构建和部署应用,保证开发、测试、生产环境的一致性。
  • 微服务架构:容器技术与微服务架构相得益彰,可以独立部署和扩展每个微服务。
  • 多云与混合云环境:容器跨平台能力使得应用能在不同云环境和本地环境间无缝迁移。

1.4 Docker 基础概念

1.4.1 Docker 简介

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 核心概念 重点
  1. 镜像(Image)
    • 镜像是包含应用程序及其所有依赖环境的可执行包。它是一个只读模板,基于该模板可以创建容器实例。
  2. 容器(Container)
    • 容器是镜像的运行实例。容器提供了与外部环境隔离的运行时环境,可以在不同的系统上运行。
    • 容器通过 Docker 引擎启动,具有独立的文件系统、网络、进程空间。
  3. 仓库(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

hub.docker.com

标签镜像
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 上看到该镜像,并分享或部署它。

补充说明:
  1. 镜像层 :镜像是由多层文件系统组成的,每一层都有自己的修改。比如,基础镜像、安装包、环境变量等都会在不同层中表示。docker inspect 可以看到这些层的详细信息。
  2. Docker Hub 和私有仓库:除了默认的 Docker Hub,用户还可以设置并使用私有镜像仓库。如果你有很多私有镜像或者需要将镜像存储在某个私有云中,可以选择 Docker Registry。
  3. 镜像的标签(Tag) :镜像的标签用于标识同一镜像仓库中的不同版本。latest 是默认标签,但为了避免版本问题,建议给镜像明确的标签,如 v1.0v1.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.txt
    2.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网卡设备通信。

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=2025-docker-%E5%85%A8%E6%96%B0%E6%95%99%E6%A1%88.assets%2Fimage-20220524212015374.png&pos_id=img-Q6n7Qh1o-1766229469897)

##### 案列:

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(不限制)。

  • 另一种更直观的写法

    bash 复制代码
    docker 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 争用时生效(不是硬限制)。

    • 举例:两个容器 c1c2--cpu-shares 512--cpu-shares 1024,在争用情况下 CPU 分配比约为 1:2。
  • 示例

    bash 复制代码
    docker 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 个核:

    bash 复制代码
    docker run -itd --name test7 --cpuset-cpus "1,3" centos:7 /bin/bash
  • 验证 :在宿主机运行 tophtop(按 1)查看各核利用率,或进入容器运行 taskset -p <pid>


4.1.4 压力测试与验证示例(CPU)
  • 在容器内创建一个繁忙循环脚本:

    bash 复制代码
    # /cpu.sh
    #!/bin/bash
    i=0
    while true; do let i++; done
  • 在容器内运行 ./cpu.sh,在宿主机观察 topdocker stats

    bash 复制代码
    docker 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:

    bash 复制代码
    cd /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 跳过文件系统缓存:

    bash 复制代码
    dd 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 占用的磁盘空间(补充)

  • 清理未使用的数据(可释放磁盘空间):

    bash 复制代码
    docker 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 启动容器并做修改
  1. 首先,通过 docker create 启动一个容器并进入其 bash 环境:

    bash 复制代码
    docker create -it centos:7 /bin/bash

    -it 参数表示交互式运行,/bin/bash 表示启动 bash shell。

  2. 查看当前容器的状态:

    bash 复制代码
    docker ps -a
  3. 修改容器内部的环境(例如安装软件包、修改配置文件等),然后退出容器。

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 中常用的指令:

  1. FROM

    指定新镜像基于的基础镜像,Dockerfile 的第一条指令必须为 FROM

    dockerfile 复制代码
    FROM centos:7
  2. MAINTAINER

    指定镜像的维护者信息:

    dockerfile 复制代码
    MAINTAINER "John Doe <johndoe@example.com>"
  3. RUN

    执行命令并将结果提交到镜像中。常用来安装软件包、修改配置等。

    dockerfile 复制代码
    RUN yum install -y httpd

ls

复制代码
rm 

cd 
```
  1. ENTRYPOINT

    设置容器启动时默认执行的命令:

    dockerfile 复制代码
    ENTRYPOINT ["httpd"]
  2. CMD

    容器启动时执行的默认命令。CMD 指令会被 docker run 命令后指定的命令覆盖。

    dockerfile 复制代码
    CMD ["httpd", "-D", "FOREGROUND"]
  3. EXPOSE

    声明容器内的端口:

    dockerfile 复制代码
    EXPOSE 80
  4. ENV

    设置环境变量:

    dockerfile 复制代码
    ENV MY_VAR=my_value
  5. ADD

    将文件或目录从宿主机复制到镜像中,支持从 URL 下载文件,并能自动解压归档文件:

    dockerfile 复制代码
    ADD myfile.tar.gz /app
  6. COPY

    将本地文件或目录复制到镜像中:

    dockerfile 复制代码
    COPY . /app
  7. VOLUME

    在容器中创建挂载点:

    dockerfile 复制代码
    VOLUME ["/data"]
  8. USER

    设置容器内运行命令时的用户:

    dockerfile 复制代码
    USER root
  9. WORKDIR

    设置后续指令的工作目录:

    dockerfile 复制代码
    WORKDIR /app
  10. ONBUILD

    设置当该镜像作为基础镜像时,后续 Dockerfile 执行的命令:

    dockerfile 复制代码
    ONBUILD RUN echo "Building from base image"
  11. HEALTHCHECK

    设置容器的健康检查:

    dockerfile 复制代码
    HEALTHCHECK 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 来编排 NginxTomcat 两个服务。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 文件中,contextvolumes 路径都是相对路径,相对于 docker-compose.yml 文件所在的目录。
  • 字段区分 :YAML 格式中,services 下定义的每个服务都会有自己的配置项,例如 imagebuildports 等。确保每个字段的位置和缩进正确。
  • 服务间的依赖关系 :例如,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

返回的结果是该镜像在仓库中的所有标签,如 v1v2 等。

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 的 pushpull 操作。

    复制代码
    负责储存 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 这样一个数据配置管理中心来完成。

数据流向分析:

  1. Docker客户端 / 浏览器
    • 用户通过 Docker 客户端或者浏览器进行交互。
  2. Proxy(代理)
    • 客户端的请求会通过代理转发,可能是为了负载均衡或处理一些中间层逻辑。
  3. Core services(核心服务)
    • 包含 UItokenwebhook。这些服务处理用户请求的业务逻辑,比如 UI 提供用户界面,token 服务管理认证,webhook 可能用于触发外部通知或事件。
  4. Registry(注册表)
    • 这是容器镜像的存储地方,核心服务会与 Registry 交互来存储或获取镜像。
  5. Database(数据库)
    • Core services 还与数据库交互,用来存储与 Harbor 相关的元数据、配置、用户信息等。
  6. Job services(作业服务)
    • 处理后台任务和作业,可能包括镜像同步、清理任务等。
  7. Log Collector(日志收集器)
    • 系统会收集日志以便后期分析和排查。
  8. 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

复制代码
相关推荐
HIT_Weston2 小时前
68、【Ubuntu】【Hugo】搭建私人博客:方案分析(二)
linux·运维·ubuntu
cws2004013 小时前
HeidiSQL 使用操作说明书
运维·数据库·windows·mysql·heidisql
prettyxian3 小时前
【linux】进程概念(1)PCB、系统调用与 proc 目录全解析
linux·运维·服务器
乾元3 小时前
用 AI 做联动:当应用层出现问题,网络如何被“自动拉入决策回路”
运维·开发语言·网络·人工智能·ci/cd·自动化
youxiao_904 小时前
Docker 容器(一)
运维·docker·容器
悲喜自渡7214 小时前
Docker指令自存
java·docker·eureka
小尧嵌入式4 小时前
Linux进程线程与进程间通信
linux·运维·服务器·c语言·开发语言·数据结构·microsoft
Arvin6274 小时前
docker /var/lib/docker/overlay2磁盘满的处理方法
运维·docker·容器
Bruce_Liuxiaowei4 小时前
网站敏感文件_目录大全(分类记忆+风险标注)
运维·网络·网络协议·http·网络安全·https