Docker技术笔记-从零开始的容器技术之旅

理论

一、容器技术简介

  • 容器是一种轻量级可移植隔离的软件环境,通过操作系统级虚拟化实现资源隔离,确保应用程序在不同环境中能够保持一致运行。 
  容器和虚拟机对比
对比维度 容器(Docker) 虚拟机(VM、KVM)
架构原理

共享宿主机内核,通过命名空间(Namespaces)和控制组(Cgroups)实现资源隔离。 

通过Hypervisor虚拟化硬件资源,每个VM运行独立完整的操作系统(Guest OS)。 

资源消耗

极低(仅占用应用所需资源,无独立操作系统开销)。 

较高(须为每个VM分配固定资源,包括独立操作系统和虚拟硬件)。 

启动速度

毫秒级(通常几秒内完成)。 

分钟级(需启动完整操作系统)。 

隔离性

进程级隔离(基于操作系统提供的隔离机制,如命名空间和控制组,隔离性较弱)。 

硬件级隔离(通过Hypervisor虚拟化硬件资源,为每个虚拟机提供完全独立的运行环境,隔离性强)。 

安全性

安全性相对较低(由于共享宿主机内核,存在逃逸风险,需要额外安全策略进行加固)。 

安全性相对较高(每个虚拟机拥有独立的Guest OS,漏洞逃逸难度大,但并非绝对安全)

镜像体积

镜像体积通常为MB级(仅包含应用及其依赖库,具体大小因应用而异)。 

镜像体积通常为GB级(包含完整的操作系统,具体大小取决于操作系统及配置)。 

性能损耗

性能消耗相对较低(通常在3%~5%左右,直接调用宿主机资源,性能接近原生进程)。 

性能消耗相对较高(通常在15%~20%左右,需通过Hypervisor虚拟化资源)。 

可移植性

高(镜像打包为标准格式,可在不同环境中迁移和部署)。 

一般(受限于底层硬件和操作系统兼容性)。 

运维成本

低(可自动化构建、发布和管理,适合CI/CD流水线)。 

高(需安装和维护多个操作系统及虚拟化层)。 

二、容器技术起源

  • 容器技术的起源可以追溯到20世纪70年代的chroot工具,之后经过FreeBSD Jails、Linux VServer等技术的发展,直到2008年LXC(Linux Container)技术的出现,为Docker的诞生奠定了基础。 
    • 1979 年:UNIX 的 chroot 技术可隔离计算机资源,降低软件开发、测试阶段的风险,还能充当蜜罐吸引黑客攻击,以便监视黑客的行为。
    • 2002 年:Linux 引入由内核直接提供的全局资源封装的全新隔离机制。2009年,Linux内核支持UTS(主机名和域名隔离)IPC(进程间通信隔离)PID(进程ID隔离)NETWORK(网络栈隔离)MOUNT(文件系统挂载点隔离)USER(用户和组ID隔离)
    • 2008 年:LXC 结合 cgroups 和 namespaces 提供完整 Linux 容器管理方案(封装系统的轻量级虚拟化),为后续容器工具(Docker)发展奠定基础。
    • 2013 年Docker 基于 LXC 提供更高级的容器化解决方案。
    • 2014 年:Docker 开源 Libcontainer(Golang开发)。
    •  2014 年Google 开源 Kubernetes(实现容器的自动化调度、扩缩容和管理)。
    • 2015 年:在 Docker 主导和倡议下,多家公司联合制定 “开放容器交互标准”(OCI,容器格式和运行时的规范文件,包括 运行时标准(RUNTIME-SPEC)、容器镜像标准(IMAGE-SPEC)、镜像分发标准(DISTRIBUTION-SPEC) )。
    • 2015 年CNCF 成立,容器技术标准化(OCI),主导Kubernetes的发展。

三、Docker简介

  • 一个开源的容器化平台,基于Linux内核命名空间(Namespaces)控制组(Cgroups)技术,通过操作系统级虚拟化实现轻量级,可移植的应用程序封装运行环境隔离

四、Docker 核心概念

  • 容器:运行在隔离环境中的程序(系统进程)。
  • 镜像:一个只读的模板,包含了创建容器所需的所有文件和配置信息。
  • 仓库:用来存储、分发和管理镜像的地方。
  • 守护进程:Docker引擎的核心服务,常驻后台,负责处理所有Docker操作;监听来自客户端的请求,(docker run等),并执行镜像构建、容器管理、网络配置等任务。
  • 客户端:用户与Docker交互的工具,通常是命令行工具(CLI)或API。
  • 网络:容器间通信的基础
  • :独立于容器生命周期的数据存储机制,用于持久化数据或共享数据

五、Docker 镜像和容器

(一)镜像概述

  •  镜像是创建容器的核心,使用CoW(Copy on Write)技术,采用分层技术,始终都只是只读的。 
  • 每个镜像都有对应的唯一的镜像 ID, 和由镜像名称 + 标签确定的唯一的标识,默认标签为 latest(如果在调用镜像时没有指定标签,默认是latest)。
  • CoW技术
    • 使用指针指向原始盘的所有块,当一个块要被改写时(写操作),首先将数据从原始盘拷贝到临时存储区域,然后在临时存储区域进行改写拷贝过来的数据,最后把数据指针指向改过的数据,原始盘始终是只读的。

(二)镜像仓库       

官方仓库
镜像加速网站
  • https://docker.m.daocloud.io
  • https://docker.1panel.live
自定义镜像仓库
  • Docker Registry
  • Harbor   
  • Quay.io
  • Gitlab

(三)创建容器

  • 使用CoW为镜像创建一个读写层,容器在读写层运行,基于该方式可以通过一个镜像创建无数容器。

(四)容器服务原理

启动进程
  • 上帝进程:系统创建时产生的第一个进程PID 为 1,没有父进程,是所有程序的跟进程,上帝进程死亡系统实例随之关闭(杀死上帝进程的方法,执行poweroff命令关机)。
  • 容器内没有systemd进程(上帝进程),需要指定一个进程(如bash)来作为容器的启动进程(上帝进程),容器才能正常启动。
  • 容器的启动进程必须放在前台运行(启动进程即上帝进程,无法像操作系统的上帝进程如systemd一样帮忙托管其它进程)。因此,在容器中的所有进程(服务)都必须手动配置和启动
复用数据
  • 上层数据复用下层数据(UnionFS和CoW技术)(UnionFS是一种分层、轻量级且高效的文件系统,核心原理包括分层结构、写时复制和联合挂载)。
  • 镜像复用,共享只读数据,写操作将数据从只下层只读层拷贝到上层可写层,下层只读层的原始数据保持不变

(五)端口映射与容器卷

端口映射
  • 问题:新创建的容器的IP地址随机且每次重启后都会发生变化,且容器服务只有宿主机才能访问,不方便通过容器对外发布服务
  • 方案:通过端口映射,将容器端口宿主机端口进行映射绑定,使宿主机成为服务提供方,不用关心容器的IP地址(宿主机的每个端口只能和一个容器进行绑定)。
容器卷
  • 问题:Docker 容器不适合保存任何数据,重要数据在容器内不方便管理且易丢失。同时,修改多个容器中的数据非常困难,而多容器之间又存在数据共享,数据文件与配置文件频繁更改的需求。
  • 方案:通过容器卷,可以映射宿主机文件或目录到容器中。目标对象不存在自动创建,目标对象存在直接覆盖,多个容器可以映射同一个目标对象来达到数据共享的目的。

(六)容器间通信                                                      

模式 说明
 bridge 

    默认模式,多个容器之间相互隔离通过网桥来进行通信。

     host     

   容器与宿主机共享网络命名空间,容器的网络配置与宿主机一致,容器的IP地址即宿主机的IP地址。

 none

 无网络模式,完全隔离。

    container 

   共享其他容器的网络命名空间,新容器将使用指定容器的网络配置,包括IP地址、端口等。

   自定义网络 

用户可创建自定义的桥接网络 Overlay 网络,以实现对容器间通信的精细控制,增强网络隔离性安全性,适用于复杂的应用场景。

五、微服务架构

(一)微服务简介

  • 起源:2013年,Docker项目开源,容器技术开始兴起,以容器为载体,使用多个小型服务组合构建复杂应用的微服务架构逐渐清晰,围绕具体的应用进行构建。
  • 优势:各服务之间可以采用不同编程语言和存储技术,运行在各自的进程之中,互不干扰,协同工作

(二)微服务架构简介

  • 微服务架构是一种架构思想而非具体的技术;它是以容器技术为载体,演进出的一种以软件运行环境、产品、研发、运营为一体的全新模式。
  • 以Docker的视角来看,容器是服务的良好载体,软件可以通过多个容器组合来实现复杂的应用架构。

(三)微服务与云原生

  • 容器编排工具(如DockerSwarmApacheMesosKubernetes)的出现和发展,推动了微服务架构在云原生时代的广泛应用,可用于解决微服务架构中的编排调度问题。
  • 优势:松耦合高内聚,高度可扩展性,出色的弹性,易于部署和访问。

六、容器服务编排

Compose

  • 问题:微服务架构中每个微服务一般都会包含多个容器实例,而每个微服务如果手动管理的话,效率低维护量大
  • 解决:使用Compose,它是一个用于定义和运行多容器的应用的工具,可以在一个文件中通过配置多个容器服务,然后使用一个简单的命令就可以轻松高效地管理配置中引用的所有容器服务。
  • 介绍:Compose项目是Docker官方的开源项目,负责实现容器集群的快速编排。它通过一个YAML文件定义多个容器服务、网络和数据卷等,用户可以通过简单的命令启动、停止和管理整个应用stack。
   核心概念
服务(service)  

一个应用的容器,实际上可以包括若干个运行相同镜像的容器实例。

项目(project)

由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yaml文件中定义(文件名自定义)。

七、Harbor仓库

(一)Harbor简介 

  • 介绍:Harbor是VMware公司在Registry上进行了相应的企业级扩展,从而获得了更加广泛的应用。
  • 优点:提供Web界面,优化用户体验,支持登录 、搜索功能,区分公有、私有镜像,基于角色的访问控制,集成日志审计,支持水平扩展。
  • 不足:部署环境繁琐,涉及到web服务器 、数据库服务器 、程序代码 、docker私有镜像仓库等9个应用。
  • 方式:所有应用官方都以docker镜像方式发布,采用compose方式管理,使用微服务项目方式来部署Harbor仓库。

(二)仓库类型

  • 公共仓库:任何人都可以访问或下载镜像(通常不需要登录和认证),但上传镜像通常需要用户认证。
  • 私有仓库:不论是上传还是下载都必须登录且必须是项目对应的认证用户才可以访问。

(三)私有仓库管理

  • 用户:用来登录Harbor仓库,认证权限。
  • 项目:用来存储镜像的逻辑单元(地址路径),管理员可分配项目权限给用户,用户也可以自己创建项目。
  • 项目赋权:使用管理员登录Harbor的web页面,选择项目来添加指定成员为项目管理员。

(四)镜像推向仓库命名标准

  • 仓库主机:端口号/项目名称/镜像名称:标签

(五)仓库使用规则

  • Docker在下载镜像时按顺序查找镜像仓库,最后查找官方仓库docker.io
  • Docker默认使用的是https协议,需要添加主机信任
  • 放到library路径下的镜像,下载时不需要指定下载路径(该路径是默认路径)。

实践

一、Docker部署

(一)基本环境准备

主机准备
主机名 IP地址 最低配置
Docker        192.168.88.1        2CPU,4G内存
  • Linux系统版本 RockyLinux 8.6
  • 卸载Podman Podman和Docker之间存在依赖冲突等问题
    • yum -y remove podman buildah
  • 开启路由转发  容器对外提供服务依赖于路由转发功能
sysctl net.ipv4.ip_forward 
//查看指定内核参数,确保值为1(开启),如果为0,通过以下方法开启
//临时开启
sysctl -w net.ipv4.ip_forward=1

//永久开启
echo "net.ipv4.ip_forward = 1" /etc/sysctl.conf >> /etc/sysctl.conf && sysctl -p /etc/sysctl.conf

(二)下载和安装软件

安装包下载

Index of linux/centos/8/x86_64/stable/Packages/

  • 虚拟机需要具备联网功能。如果在虚拟机中下载失败或连接超时,可先在真机上通过浏览器访问相应的下载链接,完成下载后,将文件传输至虚拟机进行安装。
  • 或者检查虚拟机的网络设置,确保其能正常访问互联网,然后在虚拟机上多次尝试下载。            
软件名 作用 功能
docker-ce Docker Engine的核心组件

提供Docker守护进程,负责管理容器的创建、运行和镜像存储;实现容器的启动、停止、日志管理、网络和存储等功能。

docker-ce-cli Docker命令行工具(CLI)

提供docker命令;用户通过CLI与Docker守护进程交互,管理容器和镜像。

docker-ce-rootless-extras 支持Rootless模式的额外工具

允许非root用户运行Docker容器(提升安全性);

提供dockerd-rootlesss.sh脚本,用于配置非root用户的Docker环境。

docker-buildx-plugin Docker Buildx插件

支持多平台构建;

提供docker buildx命令,扩展了docker build的功能。

docker-compose-plugin Docker Compose命令

提供docker compose命令;

通过YAML文件定义和管理多容器应用(服务、网络、卷等)。

containerd.io Containerd容器运行时

Docker的底层容器运行时;

负责容器的生命周期管理(创建、启动、停止、删除等);

提供镜像的拉取、存储和分发功能。

下载命令
curl -O -k https://download.docker.com/linux/centos/8/x86_64/stable/Packages/docker-ce-25.0.2-1.el8.x86_64.rpm  
curl -O -k https://download.docker.com/linux/centos/8/x86_64/stable/Packages/docker-ce-cli-25.0.2-1.el8.x86_64.rpm
curl -O -k https://download.docker.com/linux/centos/8/x86_64/stable/Packages/docker-ce-rootless-extras-25.0.2-1.el8.x86_64.rpm
curl -O -k https://download.docker.com/linux/centos/8/x86_64/stable/Packages/docker-buildx-plugin-0.14.0-1.el8.x86_64.rpm
curl -O -k https://download.docker.com/linux/centos/8/x86_64/stable/Packages/docker-compose-plugin-2.20.2-1.el8.x86_64.rpm
curl -O -k https://download.docker.com/linux/centos/8/x86_64/stable/Packages/containerd.io-1.6.28-3.1.el8.x86_64.rpm
配置软件仓库
  • 作用:方便多次安装或在多台机器上统一管理Docker软件包,以及提高安装效率。
安装软件
yum -y install vsftpd createrepo //vsftpd用于搭建FTP服务器的软件,createrepo用于创建YUM软件仓库清单的工具
修改配置
vim /etc/vsftpd/vsftpd.conf
anonymous_enable=YES  //允许匿名访问,生产环境慎用
    立即启动并设置为开启自启
    systemctl enable --now vsftpd
    创建目录
    mkdir /var/ftp/Docker //移动下载的软件包到/var/ftp/Docker
    制作仓库清单
    createrepo /var/ftp/Docker //仓库清单是YUM软件仓库的元数据文件 ,用于帮助YUM客户端快速查找和安装软件包
    修改YUM仓库配置文件
    vim /etc/yum.repos.d/Docker.repo
    [Docker]
    name=Docker Packages
    baseurl=ftp://192.168.88.1/Docker  //确保Docker主机的防火墙设置允许FTP服务的访问
    enabled=1
    gpgcheck=0
    更新YUM仓库清单
    yum makecache //用于生成或更新本地YUM软件包缓存
    安装软件包
    yum -y install docker-ce
    启动服务并设置为开机自启
    systemctl enable --now docker //如果服务能正常起来说明可以使用docker了,最后就是部署镜像仓库,因为官方的仓库无法直接使用,所以使用镜像加速网站来作为替代。
    配置镜像加速器
    vim /etc/docker/daemon.json //该文件初始是不存在的
    {
           "registry-mirrors": ["https://docker.m.daocloud.io"] //由于国内网络环境的限制,直接访问Docker Hub可能会比较慢。配置镜像加速器可以提高镜像下载速度,加速器通过缓存镜像数据等方式来减少重复下载时间
    }
    重启服务
    systemctl restart docker
    测试
    docker info //显示如下
        ...
         Registry Mirrors:
        https://docker.m.daocloud.io/ //表示配置镜像加速器已生效
        ...
    docker pull busybox:latest //测试能否拉取该镜像,拉取成功,则表示配置成功

    二、Docker命令和语法

    (一)基本命令

    命令 作用
    docker version

    查看服务器与客户端的版本号、编译时间等信息,用于检查Docker环境是否兼容。

    docker info

    查看Docker服务的系统信息,包括内核版本、镜像数量、容器数量等。

    docker images

    查看本机镜像的名称和标签

    docker pull 镜像名称:标签

    从镜像仓库下载一个镜像到本地,如果配置了其他镜像仓库加速器或私有仓库,可以通过在镜像名称前添加仓库地址来指定来源。

    docker save 镜像名称:标签 -o 文件名

    镜像导出为一个tar文件

    docker load -i 备份文件:名称

    导入备份的镜像文件

    docker history 镜像名称:标签

    查看镜像的制作历史(镜像的分层信息)。

    (二)容器管理命令

    命令 作用 子选项解释
    docker run -itd  [ --name 容器名称] [ --rm ] 镜像名称:标签

    根据指定镜像创建容器

    • -i 交互式模式,保持标准输入处于打开状态;
    • -t 分配一个伪终端;-
    • d 表示后台运行容器;
    • --rm 创建临时容器,退出后容器消失(不能放在最后会被当成传递的参数);
    • --name 给创建的容器定义一个名字(要在指定镜像前使用)。
    docker ps [-a | -q ]

    查看容器的信息(默认只显示启动中的容器)。

    • -a 显示所有的容器(不论是否启动);
    • -q 只显示容器的ID。
    docker inspect 镜像名称 | 容器名称

    查询容器/镜像的详细信息,包括网络配置、挂载卷信息、环境变量。

    ...

    docker exec -it 容器ID 要执行的命令

    在容器内执行指定命令(如bash,和ls等)。

    ...

    docker logs [ -f ] 容器ID

    查看容器日志

    -f 实时跟踪日志输出。

    docker cp src dst

    将文件从源文件或目录(src)拷贝到目标文件或目录(dst)(路径形式包括本机路径和容器ID/路径)。

    ...

    docker rm [ -f ] 容器ID

    删除容器(未在运行)

    -f 强制删除容器(无论是否运行)。

    docker rmi 镜像ID或镜像名称:标签

    删除镜像(必须先停止并删除基于该镜像的所有容器才能够成功删除镜像)。

    ...

    docker tag 镜像ID或镜像名称:标签 新镜像名称:新标签 

    创建新的镜像名称和标签,为同一个镜像添加多个标签,用于区分不同的版本或用途等(若未指定标签,默认为latest)。

    ...

    docker commit 容器ID或容器名称 自定义镜像名称:自定义镜像标签

    根据指定容器创建自定义的镜像。

    ...

    docker push 仓库名:端口号/项目名称/镜像:标签

    上传镜像到指定仓库的指定位置(仓库名 是镜像仓库的地址;端口号 是镜像仓库监听的端口;项目名称 是镜像所属的项目;镜像 是镜像的名称;标签 是镜像的版本或标识)。

    ...

    docker run -itd -p 宿主机端口:容器端口 镜像:标签

    将宿主机的指定端口与容器的指定端口绑定(未指定容器端口时,使用随机端口映射)。

    ...

    docker run -itd -v 宿主机对象:容器内对象:ro 镜像:标签

    将宿主机的对象映射到容器内的对象中,可以实现数据共享(可同时映射多个)(ro表示只读挂载)。

    ...

    docker run -itd --network=container 指定容器  镜像:标签

    将指定容器的网卡和其它新建的容器共享

    ...

    docker build -t 自定义镜像名:自定义标签 Dockerfile文件所在目录路径

    基于Dockerfile文件制作镜像

    ...

    docker compose [ -p 指定项目名称 ] 项目管理命令

    对项目进行管理操作

    -p 针对指定的某一个项目,不指定默认所有。

    (三)项目管理命令

    命令 作用
    up

    创建项目并启动容器(-d 将容器放在后台运行)。

    ls

    列出可以管理的项目

    images

    列出项目使用的镜像

    ps 

    显示项目中容器的状态

    logs

    查看项目中容器的日志

    start

    启动项目

    stop

    停止项目

    restart

    重启项目

    down

    删除项目容器及网络

    (四)Dockerfile文件

    指令 解释
    FROM 指定基础镜像(scratch代表空镜像,基于空制作,初始镜像的起源)(尽量选择精简版镜像以减小镜像体积)。
    RUN 容器内执行的命令(镜像)(可以写多条,但不能是交互式命令;用于执行一次性命令,创建、修改、删除数据,但不适用于执行进程,执行的进程仅在制作镜像时启动了,但在创建容器时没有相关的行为)。
    ADD 文件拷贝到容器内,如果文件是tar..xx包格式,会自动解压
    COPY 把文件拷贝到容器内,不会自动解压,不支持远程文件。
    ENV 设置启动容器的环境变量,即定义持久化的环境变量,作用于整个镜像和容器运行时(可用于在镜像构建过程中传递变量,也可以在容器运行时用于配置应用程序)。
    WORKDIR 设置启动容器的默认工作目录(唯一),进入容器时所在的目录(如果指定一个不存在的目录,会自动创建)(相当于cd,但是远程cd无效,中途会断开)(方便别人使用时知道服务在哪个目录,了解该容器的大概用途)(可基于前一个WORKDIR使用相对路径)。
    CMD 容器的默认执行命令,可以被命令行参数覆盖(唯一)(最开始执行的参数命令,如果有传递参数则使用传递的参数)(非持久化命令,执行完后容器立马退出,无法再进入容器中)。
    ENTRYPOINT 容器默认的入口命令,通常用于设置容器的执行环境或脚本(唯一)(如果为空,则CMD作为命令执行,具体执行的内容看是否有。传递参数;如果不为空,则CMD作为ENTRYPOINT的参数,具体执行的内容看是否有传递参数)。
    USER 启动容器使用的用户(唯一)(运行容器时使用非root用户,以降低容器被入侵后的安全风险)。
    EXPOSE 使用镜像创建的容器,默认监听使用的端口号/协议(仅声明,在docker ps中显示,无真正影响)。

    (五)项目文件语法

    指令 解释
    container_name 指定容器名称(必须唯一)。
    image 指定为镜像名称或镜像ID
    ports 暴露端口信息(宿主机端口:容器端口)(-p 80-88:80-88 映射连续的端口范围,-p 8080-8088:80 将多个宿主机端口映射到容器的同一个端口)。
    volumes 数据卷,支持(volume,bindtmpfs,npipe)[type选定类型,source指定宿主机端口,target指定容器端口]。
    network_mode 设置网络模式
    environment 设置环境变量(可通过多次使用或以数组形式指定多个环境变量,通过命令行传递的环境变量会覆盖Dockerfile或compose文件中设置的同名环境变量)。
    restart 容器保护策略[always 容器关闭直接重启,适用于需要长期运行的服务,但可能会导致失败的服务无限重启,消耗资源;no 容器关闭什么都不做,on-falure 如果状态码为0无操作,如果为1重启容器,适用于偶尔出现故障的服务,可在服务异常时自动恢复)。
    command 覆盖容器启动后默认执行的命令,可以覆盖Dockerfile中定义的默认命令,使容器在启动时执行自定义的命令或脚本)。
    healthcheck 配置服务健康检测(test 健康检查指令[ interval 健康检查的间隔时间;timeout 健康检查的超时时间;retries 健康检查的重试次数;start_period 容器启动后延时检查时间],CMD 简单命令, CMD-SHELL 嵌入脚本)。
    depends_on 服务依赖关系[services_started服务已启动,处于运行状态;services_healthy服务已启动且通过健康检查,功能正常;services_completed服务完成其预定人任务或启动进程;services_successfully服务操作或任务成功完成])。

    (六)Harbor仓库管理命令

    命令 解释
    docker login harbor:443 登录Harbor仓库(443端口),在/root/.docker/config.json保存认证信息记录文件。
    docker logout harbor:443 登出Harbor仓库(443端口),清除/root/.docker/config.json中记录的认证信息。

    三、Docker基本使用

    (一)镜像基本管理

    下载镜像
    docker pull rockylinux:8.5
    查看镜像
    docker images
    字段名 解释
    REPOSITORY  镜像仓库名。
    TAG  镜像标签。
    IMAGE ID 镜像唯一标识符。
    CREATED  创建时间。
    SIZE 镜像大小。
    查看镜像制作历史
    docker history rockylinux:8.5 
    字段名 解释
    IMAGE 镜像层的唯一标识符。
    CREATED 该层的创建时间。
    CREATED BY 创建该层的具体命令或操作。
    SIZE 该层对镜像总大小的贡献值。
    COMMIT 附加注释信息。
    备份镜像
    docker save rockylinux:8.5 -o myrockylinux.tar
    删除镜像
    docker rmi rockylinux:8.5
    导入镜像
    docker load -i myrockylinux.tar

    (二)容器基本管理

    运行容器
    docker run -it --name test  rockylinux:8.5 //不加-d选项,直接进入容器中
    docker run -itd --name test rockylinux:8.5 //容器放在后台运行
    docker run -it --name test rockylinux:8.5 ls //用指定命令(ls)代替容器的默认启动命令
    • 容器名必须唯一,同名容器会报错
    退出容器
    • 容器中执行exit或ctrl d,退出后容器停止运行
    • Ctrl p + Ctrl q,退出后容器保持运行
    查看容器
    docker ps -a 
    字段名 解释
    CONTAINER ID 容器唯一标识符(容器的唯一ID)
    IMAGE 容器使用的镜像
    COMMAND 容器启动时执行的命令。
    CREATED  容器创建时间)。
    STATUS  容器当前状态(Up 正在运行,Exited 已停止,Created 已创建但未启动,Paused 被暂停)。
    PORTS 端口映射关系。
    NAMES 容器名称。
    删除容器
    docker rm $(docker ps -aq)  //通过$(docker ps -aq)得到所有容器的ID,基于容器ID来删除容器

    (三)容器服务部署

    Apache服务
    基本部署
    docker run -it --name web rockylinux:8.5
    yum -y install httpd && echo "apache test" >> /var/www/html/index.html  
    //安装软件并编写测试网页文件
    
    cat /usr/lib/systemd/system/httpd.service 
    //根据配置文件中Service下的Environment和ExecStart等要求,进行相应的环境设置和命令执行
    
    export LANG=C 
    //设置系统语言环境为POSIX C环境,避免因语言环境导致的字符编码问题
    
    /usr/sbin/httpd $OPTIONS -DFOREGROUND 
    //容器没有systemd进程帮助托管,将Apache HTTP服务器启动并放在前台运行,$OPTIONS是httpd服务的启动参数,用于指定服务的运行选项,DFOREGROUND将httpd服务放在前台运行
    • 测试
      curl 172.17.0.2 
      //新开终端访问容器的IP地址进行测试(可通过" docker inspect | grep -i ipaddress "命令获取)

    php解析支持
    • Ctrl c结束之前的httpd服务
    yum -y install php  //安装php软件,识别php语言
    vi /var/www/html/test.php
    
    
    
    vi /etc/httpd/conf.modules.d/00-mpm.conf
    
        11行  LoadModules mpm_prefork_module  
    //去掉注释,启用prefork模块,prefork模块是多进程单线程的工作模式,适合处理阻塞型操作(如PHP解析)
    
        23行 #LoadModules mpm_event_module 
    //注释配置,禁用event模块,event模块是多进程多线程的工作模式,适合处理高并发的非阻塞型操作
    
    注:同一时间只能启用prefork、event、worker 其中一个模块,此时只用启动httpd进程而不需要启动httpd和php-fpm两个进程
    
    /usr/sbin/httpd $OPTIONS -DROREGROUND
    • 测试
      curl 172.17.0.2/test.php 
      //新开终端访问测试,能看到返回的test php字符串,如果无法访问可能是权限问题,检查文件权限(chmod设置)和SELINUX状态(通过getenforce命令查看,通过setenforce 0设置为宽松模式后再进行测试)

    (四)镜像制作

    commit命令
    • 切换到处于容器内的终端
    • Ctrl c结束httpd进程
    yum -y install net-tools vim-enhanced bash-completion iproute procps-ng psmisc 
    //在容器内安装工具软件包,依次提供ifconfig命令,vim命令,tap补全功能,ip命令,ps命令,pstree命令
    
    yum clean all //删除YUM缓存,减小制作的镜像的大小
    
    exit 
    //退出容器,使容器停止运行,通过docker ps -a查看容器状态,如果不是停止状态,通过docker stop web命令来停止容器
    
    docker commit web test:v1 //停止容器后再制作镜像,确保数据的一致性和镜像的稳定性
    Dockerfile文件
    • 优势:commit制作镜像时无法处理复杂情况,想要制作复杂情况的镜像需要用类似脚本的Dockerfile文件来制作。
    • 思路:将制作镜像时需要手动执行的步骤转换为Dockerfile文件的指令。
    • 步骤
      • 创建存放Dockerfile文件的目录 -> 编写Dockerfile文件 -> 基于Dockerfile文件
      • docker build -t 自定义镜像名称:自定义标签 Dockerfile文件所在目录 命令来制作镜像
    Apache镜像
    基本准备
    mkdir /root/Apache //创建目录
    docker cp web:/var/www/html/index.html ./ 
    //将web容器中的index.html,test.php,00-mpm.conf文件拷贝到当前路径(/root目录)
    
    dokcer cp web:/var/www/html/test.php ./ 
    docker cp web:/etc/httpd/conf.modules.d/00-mpm.conf /root/Apache 
    tar -zcvf Apache/web.tar index.html test.php 
    //将index.html和test.php打成tar包放在Dockerfile文件的目录中,文件必须在Dockerfile的目录中
    Dockerfile文件执行时才能找到对应的文件
    
    docker rm -f web && \
        docker run -itd --name web rockylinux:8.5 \
        && docker exec -it web yum -y install net-tools vim-enhanced bash-completion iproute procps-ng psmisc    
        && docker exec -it yum clean all
        && dokcer stop web
        && docker commit web mylinux:v1 
    //制作基础镜像mylinux:v1(该基础镜像的大小比较大,可以根据自己的需求去下载或自己制作更小的基础镜像)
    编写文件
    vim Apache/Dockerfile
        FROM mylinux:v1
        RUN yum install -y httpd php && yum clean all
        COPY 00-mpm.conf /etc/httpd/conf.modules.d/00-mpm.conf
        ADD web.tar /var/www/html   //将web.tar包解压到/var/www/html
        ENV LANG=C
        EXPOSE 80/tcp
        WORKDIR /var/www/html
        CMD ["/usr/sbin/httpd","-DFOREGROUND"]    //这里不加$OPTIONS,该变量并未定义,如果要使用,还需要额外设置
    制作镜像
    docker build -t apache:v1 Apache
    验证测试
    docker images
    docker run -itd --name web apache:v1
    docker inspect web | grep -i ipaddress 
    curl http://172.17.0.2/test.php
    Nginx镜像
    基本准备
    mkdir /root/Nginx
    wget https://nginx.org/download/nginx-1.24.0.tar.gz
    mv nginx-1.24.0.tar.gz Nginx
    单阶段镜像

    编写文件

    vim Nginx/Dockerfile
    FROM mylinux:v1
    ADD nginx-1.24.0.tar.gz /
    WORKDIR /nginx-1.24.0
    RUN yum -y install gcc make openssl pcre openssl-devel pcre-devel \
        && yum -y clean all \
        && ./configure --prefix=/usr/local/nginx --with-pcre --with-http_ssl_module \
        && make \
        && make install \
        && echo 'Nginx' > /usr/local/nginx/html/index.html
    //解释
    //使用\表示命令换行,在下一行继续执行命令;
        gcc 开发工具,用来编译C/C++源代码,生成可执行文件;
        make 开发工具,自动化构建项目,管理依赖关系;
        openssl-devel 库文件,提供SSL/TLS加密功能,用于安全通信;
        pcre-devel 库文件,提供正则表达式支持,用于文本匹配和URL重写等;
        --prefix 指定Nginx的安装路径;
        --with-pcre 表示启用PCRE支持,用于处理正则表达式;
        -with-http_ssl_module- 表示启用SSL模块,支持HTTPS协议
    
    ENV PATH=${PATH}:/usr/local/nginx/sbin 
    //将Nginx的可执行文件目录添加到环境变量PATH中
    
    WORKDIR /usr/local/nginx 
    //设置容器的工作目录为/usr/local/nginx
    
    EXPOSE 80/tcp 
    //声明容器运行时监听的端口为80,协议为tcp
    
    CMD ["nginx","-g","daemon off;"]

    制作镜像

    docker build -t nginx:v1 Nginx

    验证测试

    dokcer images
    docker run -itd --name nginx nginx:v1
    docker inspect nginx | grep -i ipaddress
    curl http://172.17.0.2
    多阶段镜像
    • 优势:多阶段构建可以有效减小最终镜像的体积,提高镜像的安全性,适用于需要编译源代码的场景。 

    基本准备

    docker rm -f $(docker ps -aq) && docker rmi nginx:v1

    路径编写文件

    vim Nginx/Dockerfile
    
    //第一阶段,编译程序,为第二阶段提供程序,减少不必要的步骤和空间占用
    FROM mylinux:v1 as basement
    ADD nginx-1.24.0.tar.gz /
    WORKDIR /nginx-1.24.0
    RUN yum -y install openssl-devel pcre-devel gcc make 
    RUN ./configure --prefix=/usr/local/nginx --with-pcre --with-http_ssl_module && make && make install
    RUN echo "Nginx" > /usr/local/nginx/html/index.html
    
    //第二阶段基于第一阶段编译的程序得到最终镜像
    FROM mylinux:v1
    RUN yum -y install pcre openssl && yum clean all
    COPY --from=basement /usr/local/nginx /usr/local/nginx 
    //从构建阶段(basement)复制指定路径的文件到当前镜像的指定路径
    
    ENV PATH=${PATH}:/usr/local/nginx/sbin
    WORKDIR  /usr/local/nginx
    EXPOSE 80/tcp
    CMD ["nginx","-g","daemon off;"]

    制作镜像

    docker build -t nginx:v1 Nginx

    验证测试

    dokcer images //镜像大小明显减小
    docker run -itd --name nginx nginx:v1
    docker inspect nginx | grep -i ipaddress
    curl http://172.17.0.2
    php-fpm镜像
    基本准备
    mkdir PHP-FPM
    wget https://www.php.net/distributions/php-8.2.0.tar.gz
    mv php-8.2.0.tar.gz PHP-FPM
    编写文件
    vim PHP-FPM/Dockerfile
    FROM mylinux:v1
    RUN yum -y install php-fpm && yum clean all  \
        && mkdir -p /run/php-fpm \
        && chown -R nobody:nobody /run/php-fpm /var/log/php-fpm \
        && sed -ri 's,^listen = .*,listen = 127.0.0.1:9000,' /etc/php-fpm.d/www.conf
    
    //解释
    //php-fpm是PHP的FastCGI进程管理器,主要用于处理PHP请求,与Nginx等Web服务器配合使用,实现PHP的解析和执行;
        /run/php-fpm目录用于存放php-fpm的套接字文件或PID文件;
        /var/log/php-fpm目录用于存放php-fpm的日志文件;
        将这些目录的所有者设置为nobody用户,是为了使php-fpm以较低的权限运行,提高安全性;
        将listen参数修改为127.0.0.1:9000是为了使php-fpm监听容器内部的特定地址和端口,便于与Web服务器(Nginx等)进行通信
    
    USER nobody
    EXPOSE 9000/tcp
    CMD ["/usr/sbin/php-fpm","--nodaemonize"]
    制作镜像
    docker build -t php-fpm:v1 PHP-FPM      
    验证测试
    docker images 
    docker run -itd --name php-fpm php-fpm:v1
    docker exec -it php-fpm /bin/bash
    id && ps -ef && exit //在容器中检查用户和进程

    (五)容器对外发布服务

    端口绑定
    docker rm -f $(docker ps -aq)
    docker run -itd  --name web --rm -p 80:80 nginx:v1 
    //基于之前制作的nginx:v1镜像创建容器,将宿主机的80端口和容器的80端口绑定,并设置容器退出时自动移除(--rm)
    • ​​​​测试:curl http://192.168.88.1 //访问宿主机地址测试
    docker run -itd --name test --rm -p 80:80 nginx:v1 
    //报错,一个宿主机端口只能绑定一个容器端口,通过lsof -i :端口号 或 ss -anltpu | grep 端口号 来检查占用端口的进程,通过kill等命令停止或杀死相应的进程
    • ​​​​:如果通过其它虚拟机访问显示路由不可达,在保证前面的步骤准确的前提下,通过ip route add 目标地址 via 可以访问的地址(相应的主机需要开启路由转发功能) 命令来添加对应的路由。 
    容器存储卷
    基本使用
    mkdir /webroot && echo 'test' >> /webroot/index.html 
    //创建共享目录/webroot,并在其中创建index..html文件,用于存储测试网页内容
    
    docker rm -f web && docker run -itd --name web -p 80:80 -v /webroot:/usr/local/nginx/html nginx:v1
    • 测试:curl http://192.168.88.1
    echo "TEST" > /webroot/index.html && curl http://192.168.88.1 
    //直接修改数据卷内容会在容器上同步体现
    
    mv test.php /webroot
    修改配置文件
    • 步骤获取 -> 编辑 -> 映射 -> 验证
    • docker cp web:/usr/local/nginx/conf ./     
      //容器卷映射目录而不是单个文件,因此需要将整个配置目录拷贝出来,修改后目录下的配置文件再进行映射
      
      vim conf/nginx.conf    //修改配置文件,使其支持php解析
          location ~ \.php$ {
          root    html;
          fastcgi_pass   127.0.0.1:9000;
          fastcgi_index   index.php;
          include    fastcgi.conf;
      }
      
      docker rm -f web \ 
          && docker run -itd --rm --name web -p 80:80 -v /root/conf:/usr/local/nginx/conf -v /webroot:/usr/local/nginx/html nginx:v1
      //如果之前nginx已启动,则先执行docker exec -it web nginx -s load来重启nginx服务重新加载配置
      • ​​​​测试:curl http://192.168.88.1/test.php //显示404,正常,虽然配置文件修改了,但是容器中没有php-fpm服务来解析php文件
      容器网络通信
      共享名称空间
      docker run -itd --name php --rm --network=container:web -v /webroot/:/usr/local/nginx/html php-fpm:v1
      • 解释
        • 创建php-fpm容器,命名为php,设置容器退出时自动移除,共享web容器的网络命名空间,并将宿主机的/webroot目录挂载到容器的/usr/local/nginx/html目录。 
        • 将web容器的网络名称空间(容器共享网卡,可以不用知道对方的ip地址,即将请求发给自己即可) (网卡监听端口都能看见,因为使用的同一张网卡)和用php-fpm:v1创建的容器进行共享。 
        • 为php增加数据卷 (nginx给php的请求的是文件的绝对路径,php根据该路径到指定目录下查找该文件,再将处理好的请求原路返回,需要和nginx的网页文件目录路径一致)。 
      • ​​​​测试curl http://192.168.88.1/test.php 

      (六)服务编排与治理

      编写项目文件
      • ​​​​步骤项目添加服务 -> 定义服务名称 -> 指定容器名称 -> 指定使用的镜像
        vim docker-compose.yaml   
        //注意YAML格式文件要求严格对齐,必须使用空格(不能用Tab键),以确保文件结构的正确性
        
        name: web  //指定项目名称
        version: "1" //指定Docker Compose文件的版本
        services:   //定义服务(容器)的集合
          websvc: //自定义一个服务(容器),服务名称为websvc
            container_name: nginx //为容器指定一个自定义名称
            image: nginx:v1 //指定容器使用的镜像
              ports: //指定绑定的端口
              - 80:80
              environment: //设置环境变量,设置时区为上海
              - "TZ=Asia/Shanghai"
            volumes: //设置容器存储卷,可同时设置多个
            - type: bind
              source: /root/conf/nginx.conf
              target: /usr/local/nginx/conf/nginx.conf
            - type: bind
              source: /webroot
              target: /usr/local/nginx/html
          phpsvc:
            container_name: php
            image: php-fpm:v1
            restart: always //容器关闭就重启
            network_mode: "service:websrc" //共享websvc服务(容器)的网卡
            volumes: 
            - type: bind 
            source: /webroot
            target: /usr/local/nginx/html
      创建并启动项目
      docker rm -f $(docker ps -aq) && docker compose -f docker-compose.yaml up -d 
      //删除之前的容器,根据项目文件重新创建新的容器
      
      docker compose -f docker-compose.yaml logs 
      //查看项目的日志输出
      ​​​​查看项目
      docker compose ls -a 
      //-a参数表示列出所有项目,包括正在运行、已停止和已创建但未启动的项目
      字段名 含义
      NAME 项目名称。
      STATUS 项目的当前运行状态(running 项目正在运行,exited 项目已停止(容器已退出),created 项目已创建但未启动,restarting 项目正在重启)。
      CONFIG FILES 与项目关联的docker-compose.yaml文件的路径。
      检验服务
      • docker compose -p web ps 
        //查看项目中各容器的ID、名称、状态、端口映射等信息

      • ​​​​测试:curl http://192.168.88.88/test.php

      (七)Docker私有仓库

      registry仓库
      基本环境准备
      主机名 IP地址 最低配置
      registry 192.168.88.1 1CPU,1G内存
      • 修改主机名
      • 在Docker主机操作
      • hostnamectl set-hostname registry //修改原有的Docker主机的主机名为registry,docker-distribution软件包找了很久没找到,就换一种方式搭建
      • ​​​​:如果有找到的,新建一台如上配置的虚拟机,IP地址修改为192.168.88.2,将包放到Docker主机的/var/ftp/Docker目录中,执行createrepo --update /var/ftp/Docker,之后再配置YUM仓库,第一种方式
      第一种方式
      配置YUM仓库
      • registry主机进行操作
      • 将Docker的YUM仓库配置文件传给registry主机
      rsync -av 192.168.88.1:/etc/yum.repos.d/Docker.repo /etc/yum.repos.d/Docker.repo
      yum makecache && yum -y install docker-distribution && systemctl enable --now docker-distribution 
      //更新YUM缓存,安装docker-distribution软件立即启动并设置为开机自启
      客户端配置
      • Docker主机操作
      • echo "192.168.88.2 registry"  >> /etc/hosts //配置主机解析文件
      vim /etc/docker/daemon.json //修改配置文件
      {
              "registry-mirrors": ["http://registry:5000","其它镜像仓库"],
              "insecure-registries": ["registry:5000"]
      }
      
      systemctl restart docker && docker info  //重启服务,能看到相应的仓库地址信息
      • //之后是另一种方式,不论哪种方式上传镜像都是在Docker主机操作
      第二种方式
      拉取镜像
      • 在Docker主机(另一种方式中叫做registry主机)操作
      docker pull registry:2  
      //必须是2版本的,latest版本的不行,其它版本未作了解
      
      echo "192.168.88.1 registry" >>  /etc/hosts 
      //配置主机解析文件
      
      vim /etc/docker/daemon.json //修改配置文件
      {
          "registry-mirrors": ["http://registry:5000","其它镜像仓库"],
          "insecure-registries": ["registry:5000"]
      }
      
      systemctl restart docker && docker info  
      //重启服务,能看到相应的仓库地址信息
      
      docker run -d -p 5000:5000 --name registry registry:2 
      //根据下载的镜像创建registry容器,将宿主机的5000端口和容器的5000端口进行绑定
      • //另一种方式如上,之后是相同的步骤
      上传镜像
      • Docker主机操作
      dokcer tag mylinux:v1 registry:5000/img/mylinux:v1 
      //给镜像设置目标仓库地址和路径的标签,如果不包含仓库地址,会默认将镜像推送到Docker Hub
      
      docker tag apache:v1 registry:5000/library/apache:v1 
      docker push registry;5000/img/mylinux:v1 //上传镜像
      docker push registry:5000/library/apache:v1
      查看镜像
      • curl -s http://registry:5000/v2/_catalog | python3 -m json.tool
        //使用Python的json.tool模块对JSON数据进行格式化输出,使结果更易读。
        //易读格式显示镜像名称,-s为静默模式,如果返回结果为空,可能因为仓库中没有镜像,或者网络连接问题等
        
        curl -s http://registry:5000/v2/img/mylinux/tags/list | pythons -m json.tool 
        //易读格式查看镜像标签
        //http://仓库IP:5000/v2/_catalog 访问能查看镜像名称,http://仓库IP:5000/v2/镜像名称(要带项目路径)/tags/list 访问能查看镜像标签
      拉取镜像
      docker rmi mylinux:v1 && docker pull registry:5000/img/mylinux:v1 
      //删除原有镜像,从regisgtry仓库中重新拉取镜像
      • ​​​​测试:docker run -itd --rm apache:v1 //library是默认路径,可以省略路径地址
      harbor仓库
      基本环境准备
      主机名 IP地址 最低配置
      harbor 192.168.88.3 2CPU,4G
      下载harbor安装包
      • 配置代理或VPN等网络工具

      https://github.com/goharbor/harbor/releases/download/v2.9.2/harbor-offline-installer-v2.9.2.tgz

      修改主机名
      hostnamectl set-hostname harbor
      配置主机解析
      echo "192.168.88.3 harbor" >> /etc/hosts 
      //通过ping harbor 命令来验证
      卸载软件
      yum -y remove podman docker-distribution 
      //卸载podman和docker-distribution软件之后重启系统(reboot)
      配置YUM仓库
      • 将Docker的YUM仓库配置文件传给harbor主机
      rsync -av 192.168.88.1:/etc/yum.repos.d/Docker.repo /etc/yum.repos.d/Docker.repo
      部署Docker
      yum -y install docker-ce && systemctl enable --now docker-distribution 
      //更新YUM缓存,安装docker-ce软件立即启动并设置为开机自启
      导入项目镜像
      tar -zxf harbor-offline-installer-v2.9.2.tgz -C /usr/local
      cd /usr/local/harbor
      docker load  -i harbor.v2.9.2.tar.gz
      创建证书
      mkdir tls 
      openssl genrsa -out tls/cert.key 2048 
      //生成一个2048位(推荐长度)的RSA私钥
      
      openssl req -new -x509 -days 3650 -key tls/cert.key -out tls/cert.crt -subj "/C=CN/ST=HN/L=CS/O=HAR/OU=BOR/CN=harbor " -addext "subjectAltName = IP:192.168.88.3"
      • ​​​​解释
        • -new 生成一个新的证书请求或自签名证书;
        • -x509 生成一个自签名的X509证书而非证书请求;
        • -days 3650 设置证书的有效期为3650天;
        • -key tls/cert 指定使用tls/cert.key作为私钥文件来签名证书;
        • -out tls/cert.crt 指定生成证书文件保存路径为tls/cert.crt;
        • -subj 证书主体信息,包括国家代码/省份/城市/组织名称/组织单位名称/通用名称(harbor表示适用于harbor主机);
        • --addext 添加扩展字段,subjectAltName 指定证书的替代名称,设置IP地址,表示该证书可用于通过此IP地址访问的服务
      修改配置文件
      cp harbor.yml.tmpl harbor.yml //复制模板
      vim harbor.yml
          5行 hostname: 192.168.88.3 //指定harbor主机的IP地址为域名
          8行 #http    //使用https,注释http
          10行 #port: 80
          17行 certifficat: /usr/local/habor/tls/cert.crt
          18行 private_key: /usr/local/harbor/tls/cert.key
          36行 harbor_admin_password: harbor //设置登录harbor页面的密码
      
      /usr/local/harbor/prepare  
      //执行prepare文件,预安装环境检查,生成项目文件docker-compose.yml
      启动项目
      docker compose -f docker-compose.yml up -d 
      //创建并启动项目
      
      docker compose -f docker-compose.yml ps && docker compose-f docker-compose.ym logs //判断项目是否成功启动
      
      chmod 0755 /etc/rc.d/rc.local && echo "/usr/bin/docker compose -p harbor start" >> /etc/rc.d/rc.local 
      //修改权限并设置项目开启自启动
      harbor管理
      • Docker主机操作
      配置主机解析文件
      vim /etc/hosts
          192.168.88.3 harbor
      修改docker配置文件
      vim /etc/docker/daemon.json
      {
          "registry-mirrors": ["https://harbor:443","其它镜像仓库"],
          "insecure-registries": ["harbor:443","其他镜像仓库"] 
          //为了保证安全,建议仅在私有网络环境中使用
      }
      重启服务
      systemctl restart docker && docker info 
      //检查是否有对应仓库的地址
      登录harbor仓库
      • 浏览器访问https://192.168.88.3,输入用户名和密码后点击新建项目,创建private项目,访问级别为私有(输入private项目名称后,直接点击创建)(如果不创建,之后推送镜像到private项目时会报错)。
      docker login harbor:443 
      //输入登录用户(admin),登录密码(自己设置的)(有警告信息,但并不影响)
      //或
      
      docker login harbor:443 -u admin --password 自己设置的登录密码(如harbor) 
      //明文输入密码
      
      docker tag mylinux:v1 harbor:443/private/mylinux:v1
      //设置(private项目)标签,harbor:443表示Harbor仓库的地址和端口;
          private是项目名称;
          mylinux:v1是镜像名称和标签,用于指定镜像在Harbor仓库中的存储位置
      
      docker tag apache:v1 harbor:443/library/apache:v1  
      //设置(library项目)标签
      
      docker push harbor:443/private/apache:v1 
      //上传镜像到harbor仓库,必须登录
      
      docker push harbor:443/private/mylinux:v1 
      //上传镜像到private仓库,需要先在,登录的用户必须具有相应的权限
      查看结果
      • 浏览器访问https://192.168.88.3,输入用户名和密码,登录成功之后可以在对应的项目中看到上传的镜像。 

      总结

      一、优化

      (一)镜像优化

      Docker镜像的分层结构
      • 基础层基础镜像
      • 中间层:通过RUNCOPYADD等指令生成的修改层
      • 最终层:容器运行时的可写层(Container Layer)。    
      • 原因:每执行一个RUN、COPY或ADD指令,Docker会创建一个新层,并将记录该层的元数据(如文件路径、权限、哈希值等),层数越多,元数据总开销越大。
      多阶段构建
      • 目的分离构建环境和运行环境,丢弃中间层,仅保留运行时所需的文件,减少最终镜像地址。
      • 流程
        • 第一阶段:使用完整基础镜像编译应用
        • 第二阶段复制编译产物到轻量级基础镜像。
      合并RUN指令
      • 目的减少镜像层数
      • 方式:用&&串联多个命令。
      清理缓存
      • 目的清理无用文件
      • 方式:在同一层中删除临时文件(如编译缓存、下载包),防止它们被后续层继承。
      基础镜像
      • 目的:从选择基础镜像开始减小整的镜像大小。
      • 方式:选择rockylinux:8-slim(~150MB)和apline:3.16(~5.6MB)。
      复用构建缓存       
      • 目的:通过缓存复用减少重复构建时间。
      • 方式:将变化率低的操作(如安装依赖)放在Dockerfile前部,复制依赖声明文件早于源代码。

      (二)构建过程优化

      使用.dockerignore
      • 目的:避免无关文件(如node_modules,.git)进入构建上下文。
      • 方式:创建.dockerignore文件(放到与对应的Dockerfile文件同一目录下),排除无关文件,在文件中添加不想让其进入构建上下文阶段对应的文件,如.git和*.log等。
      BuildKit加速构建
      • 目的:利用并行构建和智能缓存管理加速构建。
      • 方式:启用DOCKER_BUILDKIT=1环境变量,通过export来声明环境变量。

      (三)容器运行时优化

      资源限制
      • 目的:防止容器耗尽宿主机资源。
      • 方式:通过--memory,--cpus,--pids-limit等参数限制资源(在使用dockre run创建容器时使用)。
      健康检查
      • 目的确保应用就绪
      • 方式:在Dockerfile中添加HEALTHCHECK指令。
      使用非root用户
      • 目的增强安全性
      • 方式:在Dockerfile中创建并切换到非root用户。

      (四)存储优化

      避免写操作到容器层
      • 目的减少容器大小,提高性能。
      • 方式:敏感数据使用--mount挂在配置文件,日志输出到stdout/stderr,临时文件挂在tmpfs(在docker run创建容器时使用)。
      卷管理
      • 目的持久化重要数据
      • 方式:通过docker volume create 卷名 创建卷并挂载到容器(docker run 创建容器时使用)。

      (五)网络优化

      选择合适网络模式
      • 目的:平衡隔离性与性能。
      • 方式
        • 默认bridge 隔离容器网络;
        • host 高性能(牺牲隔离性);
        • 自定义网络 增强容器间通信安全(通过docker network create 网络模式名 创建自定义网络模式,通过docker run --network 指定使用的网络模式)。
      端口复用
      • 目的:复用宿主机端口,避免端口冲突。
      • 方式:通过-p参数映射不同容器到同一宿主机端口。

      二、排错

      基本问题

      • 思路检查容器状态 -> 查看容器日志 -> 进入容器内部排查 -> 查看容器详细信息 -> 监控资源使用情况 -> 监控Docker事件
      • 命令docker ps -a、docker logs 、docker exec、dokcer inspect、docker stats、dokcer inspect
      命令 作用 典型问题
      docker ps -a

      列出所有容器(包括已停止的),查看容器状态、退出代码、创建时间等。

      确认容器是否创建、是否异常退出。

      docker logs

      获取容器日志,定位启动失败或运行时错误。

      分析容器日志中的异常信息。

      docker exec

      进入容器内部执行命令,检查服务、文件、网络等。

      验证容器内服务运行状态或配置问题。

      dokcer inspect

      查看容器的详细配置(网络、挂载点、IP地址等)。

      排查网络配置、挂载路径或端口映射问题。

      docker stats

      实时监控容器(仅显示运行中的容器的资源使用情况,--all显示所有)的资源使用情况(CPU、内存、网络等)

      分析性能瓶颈或资源限制问题。

      docker events

      监控Docker守护进程的时间流(如容器生命周期、网络变化等)。

      跟踪容器状态变化或调试Docker行为。

      • 网络问题检查容器内的DNS服务是否能正常解析,通过修改Docker配置文件或使用命令直接指定来配置DNS;
      • 存储问题检查空间是否足够,删除不需要的镜像和不需要的文件或直接扩展宿主机的磁盘空间。
      • harbor仓库问题
      • 密码输入正确但无法登录或存在启动失败的容器。
      • 重建harbor相关的容器
      • 在harbor主机执行以下命令。
        • 修改了配置文件
      cd /usr/local/harbor \
          && docker rm -f $(docker ps -aq) \
          && rm -rf docker-compose.yml \
          && ./prepare \
          && docker compose -f docker-compose.yml up -d
      
      //解释
      //进入Harbor安装目录;
          删除所有容器;
          删除旧的docker-compose.yml文件;
          重新执行预安装脚本生成新的配置文件;
          最后根据新配置文件启动Harbor服务
      • 未修改配置文件(仅有某些容器启动失败)
        cd /usr/local/harbor  \
            && docke compose -f docker-compose.yml \
            && docker compose -f docker-compose.yml up -d 
        //根据项目文件先删除项目再重建项目

      你可能感兴趣的:(docker,学习,容器)