Docker概述 Docker 是一个开源的容器化平台, 旨在简化应用程序的开发、 部署和运行过程。 它通过将应用程序及其所有依赖项打包进一个可移植的容器中, 实现了应用程序与基础架构的解耦, 从而加快了软件交付的速度并增强了其可移植性。 百度百科 Docker 详细介绍。
🏷️关键特性包括:
轻量级: Docker容器相比于传统的虚拟机更加轻量, 因为它们不需要额外的操作系统层, 而是直接在主机的内核上运行。 这使得容器启动迅速, 资源利用率高。
隔离性: 尽管轻量, Docker容器仍然提供了良好的隔离性。 每个容器都在自己的进程中运行, 拥有独立的文件系统、 CPU、 内存、 网络等资源, 确保应用之间互不干扰。
可移植性: Docker容器能够在任何支持Docker的环境中一致地运行, 不论是在开发者的笔记本电脑、 测试服务器还是生产环境, 消除了“ 在我机器上能跑” 的问题。
快速交付: Docker通过镜像( Images) 来定义和封装应用及环境配置, 使得从开发到测试再到生产的整个流程变得高效且一致。
DevOps友好: Docker整合了开发和运维的工作流, 使得持续集成、 持续部署( CI/CD) 更加顺畅。 Dockerfile的使用让构建过程可脚本化、 可重复。
生态系统丰富: Docker拥有庞大的社区支持和丰富的工具链, 如Docker Compose用于定义和运行多容器应用, Docker Swarm和Kubernetes用于容器编排, 以及Docker Hub作为官方的镜像仓库, 便于镜像的分享和管理。
💗💗综上所述, Docker通过提供标准化的打包和运行环境, 极大地提高了软件开发和运维的效率, 是现代云原生应用架构中的关键技术之一。 Docker安装 安装 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum makecache fast yum install docker-ce docker-ce-cli containerd.io systemctl start docker docker -version docker run hello-world
⭐⭐组件介绍 docker-ce, docker-ce-cli, 和 containerd.io 是构成 Docker 容器运行环境的关键组件, 它们在 Docker 的安装和运行中扮演不同的角色:
docker-ce (Docker Community Edition): 这是 Docker 的社区版, 包含了完整的容器化平台。 它提供了 Docker 守护进程 (dockerd), 该进程负责管理容器的创建、 运行、 暂停、 恢复和删除等操作。 此外, Docker CE 也包括了 Docker 命令行界面 (CLI), 使得用户能够通过命令行与 Docker 守护进程交互, 执行诸如构建镜像、 运行容器、 管理网络和数据卷等任务。 Docker CE 是面向开发者、 系统管理员和希望使用最新 Docker 功能的用户的首选版本。
docker-ce-cli: 功能: 这是 Docker 的命令行客户端工具。 尽管它通常随 Docker CE 一起安装, 但也可以单独安装或升级。 它允许用户通过命令行执行 Docker 相关操作, 比如构建镜像 (docker build)、 运行容器 (docker run)、 查看容器状态 (docker ps) 等。 当你只需要命令行工具与远程 Docker 守护进程交互, 而不需要在本地主机上运行容器时, 单独安装此 CLI 就非常有用。
containerd.io: Containerd 是一个低级别的容器运行时( 启动容器通常需要运行一个专门的工具来配置内核来运行容器,这些工具也被称为“ 容器运行时” 。 ) , 它负责容器和镜像的生命周期管理, 包括镜像的传输、 存储、 容器的执行和监控等底层操作。 它是 Docker 守护进程 (dockerd) 之下的一个组件, 为 Docker 提供了与操作系统进行交互的能力。 Containerd 设计为高度模块化和可嵌入式的, 不仅服务于 Docker, 还可以被其他容器管理系统使用, 比如 Kubernetes。 它是 Docker 实例化和管理容器的核心依赖。
💗💗综上所述, docker-ce 提供了用户与 Docker 交互的主要界面和后台服务, docker-ce-cli 是与这些服务进行命令行交互的工具, 而 containerd.io 则是负责底层容器运行时的管理和协调。 这三个组件共同构成了 Docker 在 Linux 系统上的运行环境。 配置 ⭐⭐配置阿里云镜像加速 1 2 3 4 5 6 7 8 9 10 11 12 13 14 vi /etc/docker/daemon.json { "registry-mirrors" : ["https://xxxxxxxx.mirror.aliyuncs.com" ] } sudo systemctl daemon-reload sudo systemctl restart docker docker info
卸载 1 2 3 4 5 sudo yum remove docker-ce docker-ce-cli containerd.io sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd
Docker镜像 镜像的概念 Docker镜像( Image) 是Docker技术中的核心组件, 它是创建和运行Docker容器的前提。 镜像可以被理解为轻量级、 可执行的独立软件包。 它包含运行某个应用所需的所有内容, 包括代码、 运行时、 库、 环境变量和配置文件。 形象地说, Docker镜像相当于是一个面向应用的、 预配置的操作系统环境模板。
⭐⭐镜像的特性:
只读性: Docker镜像是只读的, 这意味着一旦创建, 就不能被修改。 当你运行一个容器时, Docker会在镜像的顶部添加一个可写层, 这个可写层用来保存容器运行时产生的变化, 而底下的镜像层保持不变。
分层存储: Docker镜像是由多层组成的, 每一层代表了文件系统的一系列变更。 这种分层结构使得镜像的构建高效且灵活, 因为它可以重用已有的层, 避免重复下载相同的内容。 当从Docker Hub或其他仓库下载镜像时, 实际上是在下载构成该镜像的所有层。
可移植性: 因为镜像包含了运行应用所需的一切, 所以它可以在任何支持Docker的环境中一致地运行, 无论是开发者的笔记本、 测试服务器还是生产环境。
版本控制: 镜像可以通过标签( tag) 来标记不同的版本, 便于管理和识别。 例如, 你可以有ubuntu:latest、 nginx:1.18这样的标签来分别指代最新版的Ubuntu镜像或特定版本的Nginx镜像。
⭐⭐构建和管理镜像:
构建: 镜像通常是通过DockerFile来构建的, DockerFile是一个文本文件, 其中包含了逐条指令来定义如何从基础镜像开始, 一步步添加文件、 安装软件、 设置环境变量等, 最终形成新的镜像。
拉取: 使用docker pull命令可以从Docker Hub或其他注册中心下载镜像到本地。
查看: 使用docker images命令可以列出本地的所有镜像及其相关信息, 如镜像ID、 创建时间、 大小和标签。
运行: 通过docker run命令可以基于镜像创建并启动一个新的容器, 此时Docker会在镜像的顶部添加一个可写层作为容器的运行环境。
推送: 使用docker push命令可以将自己的镜像推送到Docker Hub或其他私有仓库, 以便他人或自己在其他地方使用。
⭐⭐Docker镜像的设计理念极大地简化了应用的打包、 分发和部署过程, 使得应用程序能够在几乎任何基础设施上以一致的方式运行, 这是容器化技术的一大优势。 联合文件系统 Docker的联合文件系统( Union File System, 简称UnionFS) 是一种特殊的文件系统技术, 它允许将多个文件系统层叠加在一起, 形成一个单一的可读写的文件系统视图。
这种分层的文件系统设计是Docker的核心技术之一, 它极大地促进了Docker镜像的高效创建、 管理和容器的快速启动。
在Docker中, 每个镜像由一系列只读层组成, 最顶层通常是一个可写层( 当容器运行时生成) 。 这些层是相互依赖的, 下层的更改不会影响上层, 而上层可以添加、 修改或删除文件, 看起来就像是一个统一的文件系统。
⭐⭐关键优势:
镜像复用: 因为层是可以共享的, 所以多个容器可以共用相同的底层镜像, 节省了存储空间。
快速部署: 新容器可以从现有镜像的层快速启动, 只需添加一个可写层用于保存状态和差异。
高效的镜像传输: 当推送或拉取镜像时, 只需要传输层间差异, 而非整个文件系统。
易于理解的分层结构: 每个操作( 如安装软件包) 都可以视为一个新的层, 便于追踪和回滚。
⭐⭐Docker支持多种联合文件系统的实现, 包括但不限于:
AUFS( Advanced Multi-Layered Unification Filesystem) : 早期Docker默认使用的实现, 支持精细的权限控制和高效的层管理。
OverlayFS: Linux内核原生支持的轻量级联合文件系统, 逐渐成为许多现代Docker部署的首选。
Btrfs: 一种具有高级特性的文件系统, 支持快照和子卷, 也可用于Docker存储。
VFS( Virtual File System) : Docker的一个基本实现, 兼容性好但性能较低。
ZFS: 一个功能丰富的文件系统, 支持高级存储功能, 如数据校验和自动修复。
Device Mapper: Linux内核中用于创建逻辑设备的框架, 也用于Docker存储驱动。
分层存储 Docker镜像的分层存储是基于联合文件系统( Union File System) 实现, 每一个镜像由多个只读层( read-only layers) 组成, 这些层叠加在一起形成了一个完整的文件系统。
Docker镜像的最底层是 bootfs( boot file system) , 它主要包含操作系统的 bootloader( 引导加载器) 和 kernel( 内核) 。 bootloader主要是引导加载kernel。 它提供了系统启动时所需的最基本的文件和程序, 包括能够加载和初始化 Linux 内核的组件。
Docker镜像的最底层 bootfs 之上就是 rootfs (root file system), 包含了系统运行所需的最基本目录结构和文件。
Docker镜像的最上面的一层通常是可写层( writable layer) 这一层就是我们通常说的容器层, 容器之下的都叫镜像层, 运行 docker run 命令时创建该层, 主要用于保存容器运行时产生的数据和改动。
这种分层的设计使得镜像的构建、 存储和传输都极为高效。
⭐⭐层的特性:
不可变性: 一旦创建, 层的内容就不能被修改。 这种设计保证了镜像的可重现性和一致性。
复用性: 多个镜像可以共享相同的底层层, 减少了存储空间的需求。
轻量级: 当提交一个新的层时, 实际上只是记录了相对于前一层所做的更改, 而不是整个文件系统的拷贝。
写时复制( COW, Copy-On-Write) : 当需要修改文件时, 该文件首先会被复制到一个新的层中, 然后在新层上进行修改。 这样的话, 原始层保持不变, 确保了高效性和资源利用率。
Docker命令 镜像命令 镜像列表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 docker images docker image ls docker image list -a, --all -f, --filter filter --format string --no-trunc -q, --quiet docker images -aq docker images --digests docker images -f "dangling=true" docker images -f "reference=latest" docker images --format "{{json .}}" docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
搜索镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 docker search image_name -f, --filter filter --format string --limit int --no-trunc docker search mysql --filter=STARS=3000 docker search -f is-official=true zookeeper docker search --limit =5 zookeeper
下载镜像 1 2 3 4 5 6 7 8 9 10 11 12 docker pull image_name[:tag] -a, --all-tags --disable-content-trust --platform string -q, --quiet docker pull mysql docker pull docker.io/library/mysql:latest
删除镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 docker rmi image_id docker rmi image_name -f, --force --no-prune docker rmi -f e73346bdf465 docker rmi -f mysql docker rmi -f $(docker images -aq) docker image prune docker system prune
镜像提交 1 2 3 4 5 6 7 8 9 10 11 12 docker commit CONTAINER_ID image_name:[tag] -a, --author string -c, --change list -m, --message string -p, --pause docker commit -a="作者名称" -m="提交的描述信息" d1e5e331a66a test-image-name:1.0.0
镜像推送 1 2 3 4 5 6 7 8 9 10 docker login --username=阿里云登录用户名 registry.cn-beijing.aliyuncs.com docker tag [ImageId] registry.cn-beijing.aliyuncs.com/命名空间/仓库名称:[镜像版本号] docker push registry.cn-beijing.aliyuncs.com/命名空间/仓库名称:[镜像版本号]
镜像打包 ⭐⭐可以把镜像打成一个压缩包, 自己保存或者发送给别人。 1 2 3 4 5 6 7 8 9 docker save image_id ... -o, --output string docker save -o /home/docker/test.jar a3e63372bd98 605c77e624dd docker save a3e63372bd98 605c77e624dd > /home/docker/test.jar
镜像加载 ⭐⭐可以把镜像打成一个压缩包, 自己保存或者发送给别人。 1 2 3 4 5 6 7 8 9 10 docker save image_id ... -i, --input string -q, --quiet docker load -i /home/docker/test.jar docker load < /home/docker/test.jar
容器命令 运行容器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 docker run [可选项] image_id docker run [可选项] image_name docker run --help --name="container_name" -d -it -P -p -p 容器端口 -p 主机端口:容器端口 -p ip:主机端口:容器端口 docker run -it centos /bin/bash docker run -d --name nginx01 -p 3344:80 nginx curl localhost:3344 docker run -d centos
创建容器 ⭐⭐ 创建容器命令与运行容器命令基本一致。 创建容器命令: 只创建不运行。 运行容器命令: 创建并运行。 1 docker create [可选项] image_id
查看列表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 docker ps -a, --all -f, --filter filter --format string -n, --last int -l, --latest --no-trunc -q, --quiet -s, --size docker ps -a
删除容器 1 2 3 4 5 6 7 8 9 10 11 12 docker rm CONTAINER_ID docker rm NAMES -f, --force -l, --link -v, --volumes docker rm -f c3180317543b docker rm -f $(docker ps -aq) docker ps -aq | xargs docker rm -f
查看日志 1 2 3 4 5 6 7 8 9 10 11 12 docker logs CONTAINER_ID --details -f, --follow --since string -n, --tail string -t, --timestamps --until string docker logs -tf --tail 10 d1e5e331a66a
拷贝文件 1 2 3 4 docker cp d1e5e331a66a:/home/test.java /home docker cp my.tar d1e5e331a66a:/root
容器启动与停止 1 2 3 4 docker start CONTAINER_ID docker restart CONTAINER_ID docker stop CONTAINER_ID docker kill CONTAINER_ID
进入正在运行的容器 1 2 3 4 5 6 7 8 docker exec -it CONTAINER_ID 命令行 docker attach CONTAINER_ID docker exec -it d1e5e331a66a /bin/bash docker exec -it -w /root d1e5e331a66a /bin/bash
退出正在运行的容器
查看容器内部的进程
查看容器的元数据 1 docker inspect CONTAINER_ID
导出/导入容器 1 2 3 4 docker export /home/tomcat-export.tar d1e5e331a66a docker import /home/tomcat-export.tar tomcat-export:1.0
暂停容器服务 ⭐⭐ 暂停容器对外提供服务, 并不是暂停容器 1 2 3 4 docker pause d1e5e331a66a docker unpause d1e5e331a66a
容器数据卷 数据卷的概念 Docker容器数据卷是一种由Docker管理的、 用于存储容器数据的独立于容器的持久化存储机制。 它是宿主机上的一个特定目录, 可以被挂载到一个或多个Docker容器中。 在宿主机中的这个文件/目录就称为数据卷, 而容器中的这个关联文件/目录则称为该数据卷在该容器中的挂载点。
数据卷的设计旨在解决容器数据的持久化问题, 确保数据不因容器的创建、 启动、 停止或删除等操作而丢失。 使用数据卷是实现 Docker 应用数据持久化和容器间数据共享的有效方式, 它增强了容器化应用的数据管理灵活性和可靠性。
⭐⭐数据卷的关键特性:
持久性: 数据卷中的数据会在容器被删除后继续存在, 因为数据卷拥有自己的生命周期, 独立于任何单个容器。
可共享性: 多个容器可以同时挂载同一个数据卷, 实现数据的实时共享。
宿主机集成: 数据卷直接在宿主机的文件系统中存在, 可以轻松地从宿主机备份、 恢复或直接访问数据卷内容。
绕过UnionFS: 数据卷不使用Docker的联合文件系统(UnionFS), 这意味着对数据卷内数据的修改是直接的, 不会受到容器读写层的影响, 提高了I/O性能。
命名卷与匿名卷:
命名卷: 由用户显式创建并命名, 便于在多个容器间共享和管理。
匿名卷: 在容器创建时自动创建且未命名, 主要用于临时存储或一次性使用的场景。
数据卷容器: 一种特殊的容器, 其主要作用是提供数据卷供其他容器挂载, 这样可以更容易地管理和迁移数据。
指定宿主机路径挂载卷 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 docker run -it -v /home/ceshi:/home centos /bin/bash docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
不指定宿主机路径挂载卷 ⭐⭐不指定路径挂载卷默认保存到 –> /var/lib/docker/volumes 目录下 匿名卷 1 2 3 4 5 6 docker run -d -P -v /etc/nginx --name nginx01 nginx:latest
命名卷 1 2 3 4 5 6 7 8 docker run -d -P -v zdy-name-nginx:/etc/nginx --name nginx02 nginx:latest
卷的操作 1 2 3 4 5 6 7 8 9 10 11 docker volume [指令] create inspect ls prune rm docker volume ls
数据卷共享 当一个容器与另一个容器使用相同的数据卷时, 就称这两个容器实现了“ 数据卷共享” 。
当一个 容器C 启动运行时创建并挂载了数据卷, 若其它容器也需要共享 容器C 挂载的数据卷, 这些容器只需在 docker run 启动时通过 –volumes-from[容器C] 选项即可实现数据卷共享。 此时 容器C 就称为数据卷容器。
1 docker run --name myubuntu --volumes-from 容器C -it ubuntu /bin/bash
数据卷的权限 1 2 3 4 docker run -d -P -v zdy-name-nginx:/etc/nginx:ro nginx docker run -d -P -v zdy-name-nginx:/etc/nginx:rw nginx
💗💗一旦设置了容器的权限则不可修改, 默认是可读写权限。 DockerFile DockerFile的概念 Dockerfile 是一个用于自动化构建 Docker 镜像的文本文件, 其中包含了一系列命令和说明。 这些命令用于定制基础镜像、 安装软件、 设置环境变量、 暴露端口、 指定运行时的工作目录和启动命令等, 创建一个全新的 Docker 镜像。 Dockerfile 的命令类似于 Linux 的 shell 命令, 使得开发人员能够以简洁的方式表述镜像的构建过程。
⭐⭐Dockerfile 的基本结构通常包括以下几个部分:
基础镜像信息
维护者信息
镜像操作指令
容器启动时执行指令
💗💗Docker 引擎会读取 Dockerfile 中的指令, 依次执行它们, 最终生成一个新的 Docker 镜像。 这种方式标准化了应用的打包和部署流程, 提高了可移植性和重复性。 基本结构与指令 基础镜像信息 基础镜像信息在 Dockerfile 中通过 FROM 指令指定, 这是 Dockerfile 中的第一条也是必备的指令。
基础镜像实际上是构建新镜像的起始点, 它可以是一个预定义的操作系统镜像, 如 Ubuntu、 Alpine Linux、 CentOS, 或者是一个包含了特定运行环境的镜像, 比如带有 Java 运行时的 OpenJDK 镜像、 Python 的官方镜像等。
也可以用一个特殊的 Docker 镜像: scratch 镜像。 scratch 镜像表示一个完全空白的基础镜像。 它不包含任何操作系统层或文件系统, 实质上是一个空的、 无父镜像的状态。 当你使用 FROM scratch 开始一个 Dockerfile 时, 意味着你正在从零开始创建一个镜像, 你需要手动添加所有需要的文件和二进制执行文件。
⭐⭐ FROM 指令: 添加基础镜像。 1 2 3 4 5 FROM scratch FROM centos:7.9.0
维护者信息 ⭐⭐ MAINTAINER 指令: 添加维护者信息。 1 2 3 4 5 6 MAINTAINER name MAINTAINER name@example.com MAINTAINER 名字<name@example.com>
⭐⭐ LABEL 指令: 为生成的镜像添加元数据标签。 随着 Docker 的发展, 推荐的做法是使用 LABEL 指令来添加。 1 2 3 4 5 LABEL author.name="your-name" \ author.email="your-name@example.com" \ description="A custom Docker image maintained by your-name."
镜像操作指令 ⭐⭐ WORKDIR 指令: 设置镜像的工作目录, 后续的RUN、 CMD、 ENTRYPOINT指令将在这个目录下执行。
⭐⭐ VOLUME 指令: 创建一个挂载点, 用于持久化数据。 1 2 3 4 5 VOLUME ["/var/log/nginx" , "/etc/nginx/conf.d" ] docker run -d -v /host/path/to/data:/data my_image
⭐⭐ RUN 指令: 在构建镜像的过程中执行命令, 可以是shell命令或执行器命令。 1 2 RUN apt-get update && apt-get install -y nginx
⭐⭐ COPY 指令: 在构建镜像的过程中执行命令, 可以是shell命令或执行器命令。 1 2 COPY package.json /app/
⭐⭐ ADD 指令: 类似COPY, 但能处理URL和自动解压tar文件。 1 2 3 ADD file.tar.gz /app/ ADD https://example.com/archive.tar.gz /app/
⭐⭐ ENV 指令: 设置环境变量, 在构建过程及容器运行时生效。 1 2 ENV MYSQL_ROOT_PASSWORD=123456
⭐⭐ EXPOSE 指令: 声明容器运行时监听的端口, 供宿主机或其他服务访问。 1 2 3 4 5 EXPOSE 8080 80 443 docker run -p 10000:8080 -p 80:80 -p 443:443 nginx
⭐⭐ ARG 指令: 定义构建时变量, 可以在构建过程中使用这些变量。 1 2 3 4 5 6 7 8 9 ARG VERSION=1.0 LABEL version=$VERSION RUN ["echo" , "Building version" , "${VERSION} " ] docker build --build-arg VERSION=2.0 -t my-image-name .
⭐⭐ SHELL 指令: 设置默认的shell。 1 2 SHELL ["/bin/bash" , "-c" ]
⭐⭐ ONBUILD 指令: 触发指令, 当基于当前镜像构建新镜像时, 这些指令会被执行。 1 2 ONBUILD RUN npm install
⭐⭐ USER 指令: 指定运行容器时的用户和用户组。
⭐⭐ STOPSIGNAL 指令: 设置容器停止时发送的系统信号, 默认是 SIGTERM。
⭐⭐ HEALTHCHECK 指令: 配置健康检查命令, 用于判断容器服务是否健康运行。 1 2 HEALTHCHECK --interval=5s --timeout =3s CMD curl -f http://localhost/ || exit 1
容器启动时执行指令 ⭐⭐ CMD 指令: 容器启动时默认执行的命令, 可以被docker run命令行参数覆盖。
⭐⭐ ENTRYPOINT 指令: 容器启动时默认执行的命令, 不会被docker run的命令行参数覆盖, 命令行参数会追加到 ENTRYPOINT 指令后边。
构建Docker镜像 编写文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 cd /homemkdir -p docker/tomcat/bulidtouch Dockerfilevi Dockerfile FROM centos LABEL author.name="szxck" author.url="szxck.top" ARG MYPATH=/usr/local WORKDIR ${MYPATH} RUN rm -f /etc/yum.repos.d/*.repo RUN echo "[AppStream]" >> CentOS-Linux-AppStream.repo RUN echo "name=AppStream" >> CentOS-Linux-AppStream.repo RUN echo "baseurl=https://mirrors.aliyun.com/centos/\$releasever/AppStream/\$basearch/os/" >> CentOS-Linux-AppStream.repo RUN echo "gpgcheck=1" >> CentOS-Linux-AppStream.repo RUN echo "enabled=1" >> CentOS-Linux-AppStream.repo RUN echo "gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial" >> CentOS-Linux-AppStream.repo RUN echo "[BaseOS]" >> CentOS-Linux-BaseOS.repo RUN echo "name=CentOS-\$releasever - BaseOS" >> CentOS-Linux-BaseOS.repo RUN echo "baseurl=https://mirrors.aliyun.com/centos/\$releasever/BaseOS/\$basearch/os/" >> CentOS-Linux-BaseOS.repo RUN echo "gpgcheck=1" >> CentOS-Linux-BaseOS.repo RUN echo "enabled=1" >> CentOS-Linux-BaseOS.repo RUN echo "gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial" >> CentOS-Linux-BaseOS.repo RUN mv CentOS-Linux-AppStream.repo /etc/yum.repos.d/ RUN mv CentOS-Linux-BaseOS.repo /etc/yum.repos.d/ RUN yum clean all RUN yum makecache RUN yum install -y vim ADD jdk-8u11-linux-x64.tar.gz ${MYPATH} /java ADD apache-tomcat-8.5.100.tar.gz ${MYPATH} /tomcat ENV JAVA_HOME=${MYPATH} /java/jdk1.8.0_11 ENV CLASSPATH=$JAVA_HOME /lib/dt.jar:$JAVA_HOME /lib/tools.jar ENV TMOCAT_HOME=${MYPATH} /tomcat/apache-tomcat-8.5.100 ENV TMOCAT_BASH=${MYPATH} /tomcat/apache-tomcat-8.5.100 ENV PATH=$PATH :$JAVA_HOME /bin:${TMOCAT_HOME} /lib:${TMOCAT_HOME} /bin EXPOSE 8080 CMD /usr/local/tomcat/apache-tomcat-8.5.100/bin/startup.sh && tail -F /usr/local/tomcat/apache-tomcat-8.5.100/logs/catalina.out
构建镜像 1 2 3 4 5 docker build -f Dockerfile -t tomcat-centos:1.0 . docker history image_id
运行镜像 1 2 3 4 5 docker run -d -p 10000:8080 -v /home/docker/tomcat/test:/usr/local/tomcat/apache-tomcat-8.5.100/webapps/test -v /home/docker/tomcat/logs:/usr/local/tomcat/apache-tomcat-8.5.100/logs --name tomcat-centos tomcat-centos:1.0 curl localhost:10000
构建运行Jar包 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 vi Dockerfile FROM openjdk:8u102 LABEL auth=szxck email=suzengxin@foxmail.com WORKDIR /home COPY app.jar /home/app.jar EXPOSE 8080 ENTRYPOINT ["java" , "-jar" , "app.jar" ] docker build -t hello-docker . docker run -d -p 8080:8080 --name hello-docker hello-docker curl localhost:8080
Docker缓存机制 Docker Build 缓存机制是为了加速镜像构建过程而设计的。 当你使用 docker build 命令来创建一个新的镜像时, Docker 会根据 Dockerfile 中的指令逐步执行并构建每个镜像层。 为了提高效率, Docker 使用缓存机制避免重新构建那些在之前的构建中没有发生变化的部分。
⭐⭐以下是一些关于 Docker Build 缓存机制的关键点:
缓存键( Cache Key) : Docker 计算一个缓存键, 它基于 Dockerfile 中每条指令的内容及其所依赖的文件。 如果这些内容或文件没有变化, 缓存键保持不变, Docker 就可以重用缓存。 缓存键考虑到了文件的元数据( 如修改时间、 权限、 inode 等) 和文件的实际内容。
ADD 和 COPY 指令: ADD 和 COPY 指令会触发缓存键的重新计算。 如果在这两个指令中引用的文件发生变化, 缓存就会失效, 即使 Dockerfile 没有变化。 如果文件的修改时间或内容发生变化, 即使文件名相同, 缓存也会失效。
缓存失效: 当 Dockerfile 或其引用的文件发生变化时, 从那个点开始的缓存都会失效, 后续的指令需要重新执行。 例如, 如果 Dockerfile 的第一条 RUN 指令之后是一个 COPY 指令, 并且 COPY 的源文件被修改, 那么所有在 COPY 之后的指令都需要重新执行, 即使它们自身没有变化。
禁用缓存: 可以通过向 docker build 命令添加 –no-cache 参数来完全禁用缓存, 这通常用于确保镜像是根据最新的代码和依赖项构建的。
缓存清理: Docker 会自动管理缓存, 但有时可能需要手动清理以释放磁盘空间。 可以使用 docker builder prune 命令来清除不再使用的构建缓存。
BuildKit: Docker 18.09 引入了 BuildKit, 这是一个用于构建镜像的新引擎, 它提供了更高级别的缓存管理和其他功能, 比如并行化构建步骤。
💗💗Docker Build 缓存机制对于优化构建流程和减少构建时间非常重要。 正确地组织 Dockerfile 和使用缓存可以帮助你更快地迭代和部署应用。 Docker网络原理 Docker网络架构基础 📶📶 Docker0网桥: 当你在宿主机上安装Docker时, 会自动创建一个名为docker0的虚拟网桥。 这个网桥本质上是一个软件定义的网络交换机, 允许连接到它的网络设备( 即容器) 相互通信, 并可配置与外部网络的连接。 📶📶 网络命名空间: 每个Docker容器都运行在自己的网络命名空间中, 这意味着每个容器都有独立的网络设备、 IP地址、 路由表等, 实现了容器间的网络隔离。 📶📶 Veth Pair: veth( virtual Ethernet) 对是一种虚拟网络设备对, 通常用于连接两个网络命名空间。 当创建一个新的Docker容器时, 会创建一对veth接口, 一端位于容器内部( 如eth0) , 另一端则连接到宿主机上的网络栈, 通常绑定到docker0网桥上。 这样, 容器内的网络流量可以通过这对veth接口流向宿主机网络, 并通过docker0网桥与其他容器通信。 1 2 3 4 5 6 7 8 ip addr docker network ls docker exec -it CONTAINER_ID ip addr
容器间通信原理 📤📤 同一宿主机上的容器通信: 同一宿主机上的Docker容器通过共享docker0网桥实现通信。 每个容器获得一个与docker0网桥同网段的IP地址, 由于它们处于同一子网, 可以直接通过IP通信, 无需额外配置。 📤📤 跨宿主机容器通信: 当容器分布在不同的宿主机上时, 需要更复杂的网络配置, 如使用Docker的overlay网络或第三方网络插件, 实现跨宿主机容器的通信。 1 2 3 4 5 6 7 8 9 docker exec -it CONTAINER_ID ping Docker0网桥为容器分配的IP地址 docker run -d -P --link tomcat01 --name tomcat02 tomcat docker exec -it tomcat02 ping tomcat01
ARP协议与容器发现 🔎🔎 ARP协议: 当容器需要与另一个容器通信但只知道目标容器的IP地址时, 会使用ARP( Address Resolution Protocol) 协议来解析目标容器的MAC地址。 容器会发送ARP广播请求, 询问具有特定IP地址的MAC地址。 目标容器接收到请求后, 会回应其MAC地址, 发起请求的容器即可构建完整的以太网帧进行通信。 网络配置与管理 ⏩⏪ 端口映射: Docker支持端口映射, 允许将容器内部的服务端口映射到宿主机的某个端口, 使得外部网络可以通过宿主机的IP和端口访问容器内的服务。 💿💿 Docker网络驱动: Docker提供了多种网络驱动, 包括bridge( 默认) 、 host、 none、 overlay等, 每种模式提供了不同的网络隔离和连接策略, 满足不同场景下的网络需求。 1 2 docker run -d -P --net bridge --name tomcat01 tomcat
自定义网络 创建自定义网络 💗💗 使用自定义网络的容器, 启动时不需要配置 –link 就可以使用容器名字进行互联, –link 配置已经不推荐使用, 推荐使用自定义网络。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet docker network ls docker network inspect mynet docker run -d -P --net mynet --name tomcat-net-01 tomcat docker run -d -P --net mynet --name tomcat-net-02 tomcat docker exec -it tomcat-net-01 ping tomcat-net-02
容器互通 💗💗 在不同的自定义网络中, 容器的相互通信 1 2 3 4 docker network connect mynet tomcat01
网络共享 1 2 docker run -d -P --network container:tomcat01 --name tomcat02 tomcat
搭建 Redis 集群 💗💗 创建Docker自定义网络 1 docker network create --subnet 192.169.0.0/16 --gateway 192.169.0.1 redis
💗💗 创建Redis容器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 mkdir -p /home/docker/rediscd /home/docker/redisvi createRedis.sh for port in $(seq 1 6);do mkdir -p /home/docker/redis/node-${port} /conftouch /home/docker/redis/node-${port} /conf/redis.confcat << EOF > /home/docker/redis/node-${port}/conf/redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 192.169.0.1${port} cluster-announce-port 6379 cluster-announce-bus-port 16379 appendonly yes EOF docker run -p 637${port} :6379 -p 1637${port} :16379 \ -v /home/docker/redis/node-${port} /data:/data \ -v /home/docker/redis/node-${port} /conf/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 192.169.0.1${port} \ --name redis-${port} \ redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf done chmod +x createRedis.sh./createRedis.sh
💗💗 配置Redis集群 1 2 3 4 5 6 7 8 9 10 11 docker exec -it redis-1 /bin/sh redis-cli --cluster create \ 192.169.0.11:6379 \ 192.169.0.12:6379 \ 192.169.0.13:6379 \ 192.169.0.14:6379 \ 192.169.0.15:6379 \ 192.169.0.16:6379 \ --cluster-replicas 1
💗💗 测试Redis集群 1 2 3 4 5 6 7 8 redis-cli -c cluster info cluster nodes
Docker Compose Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。 使用 YAML 文件描述整个应用程序的组件, 包括每个服务的容器、 网络、 卷和其他资源。 通过这种方式, 可以将复杂的应用程序环境封装成可移植且可重复的单元。
💗💗 Docker Compose 的核心概念:
项目( Project) : 一个项目是指由一组相关服务组成的集合, 它们一起构成一个完整的应用程序。 所有服务都定义在一个 docker-compose.yml 文件中, 并且属于同一个项目。
服务( Service) : 每个服务定义了运行该服务的一个或多个容器的配置, 包括使用的镜像、 端口映射、 环境变量、 卷绑定等。
容器( Container) : 服务下运行的实际实例。 每个服务可以运行一个或多个容器实例。
网络( Network) : Docker Compose 支持自定义网络, 允许服务之间的容器相互通信。
卷( Volume) : 用于数据持久化, 可以在容器重启或重建后保留数据。
💗💗 Docker Compose 的优势:
简化配置: 使用 YAML 文件集中管理所有服务的配置, 便于维护和版本控制。
自动化部署: 可以通过一个命令启动或停止所有服务, 减少手动配置的错误。
环境一致性: 确保本地开发环境与生产环境保持一致。
可扩展性: 易于添加或删除服务, 适应应用程序的变化。
常用命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 docker compose attach docker compose build docker compose config docker compose cp docker compose create docker compose down docker compose events docker compose exec docker compose images docker compose kill docker compose logs docker compose ls docker compose pause docker compose port docker compose ps docker compose pull docker compose push docker compose restart docker compose rm docker compose run docker compose scale docker compose start docker compose stats docker compose stop docker compose top docker compose unpasse docker compose up docker compose version docker compose wait docker compose watch
项目部署 创建构建文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 cd /home/docker/szxckvi Dockerfile FROM openjdk:8u102 LABEL auth=szxck email=suzengxin@foxmail.com WORKDIR /home COPY app.jar /home/app.jar EXPOSE 8080 ENTRYPOINT ["java" , "-jar" , "app.jar" ] vi compose.yml networks: szxck-net: driver: bridge services: szxck-server: build: ./ image: szxck-server:1.0 container_name: szxck-server ports: - 10000:8080 networks: - szxck-net volumes: - ./logs:/home/logs depends_on: - szxck-mysql - szxck-redis szxck-mysql: image: mysql:5.7 container_name: szxck-mysql environment: MYSQL_ROOT_PASSWORD: 123456 ports: - 3306:3306 networks: - szxck-net volumes: - /home/docker/mysql/log:/var/log/mysql - /home/docker/mysql/data:/var/lib/mysql - /home/docker/mysql/conf:/etc/mysql/conf.d szxck-redis: image: redis:latest container_name: szxck-redis ports: - 6379:6379 networks: - szxck-net volumes: - /home/docker/redis/redis.conf:/etc/redis/redis.conf - /home/docker/redis/data:/data command : redis-server /etc/redis/redis.conf
验证文件 1 docker compose config -q
启动服务 1 docker compose -f compose.yml up -d
Docker Swarm Docker Swarm 是 Docker 公司提供的一个用于构建和管理容器集群的工具。 它允许用户将多个 Docker 主机组织成一个集群, 并且能够统一管理和调度集群内的容器。
Docker Swarm 提供了集群级别的特性, 如服务发现、 负载均衡、 以及跨主机的网络连接, 使得在集群环境中部署和管理容器化应用变得更为简单。
💗💗Docker Swarm 的组件
管理节点 (Manager nodes): 管理节点负责维护集群状态、 执行编排决策和协调任务。 它们存储集群的状态和配置信息, 并处理加入和离开集群的请求。 至少需要一个管理节点来启动 Swarm 集群。
工作节点 (Worker nodes): 工作节点是执行容器和任务的实际机器。 它们接收来自管理节点的任务, 并在其上运行容器实例。
服务 (Services): 服务定义了容器运行的策略, 包括容器的数量、 网络设置、 更新策略等。 Docker Swarm 使用服务的概念来实现容器的编排。
任务 (Tasks): 任务是服务的具体实例, 代表了运行中的容器。 每个服务可以有多个任务, 这些任务可以在集群中的不同工作节点上运行。
网络 (Networks): Docker Swarm 支持多种网络模式, 包括覆盖网络 (overlay networks), 允许容器在不同的主机之间相互通信。
堆栈 (Stacks): 堆栈是一个或多个服务的集合, 通常由 Docker Compose 文件定义, 可以在 Swarm 模式下部署。
💗💗Docker Swarm 的优势
易于使用: Swarm 与 Docker 引擎紧密集成, 使用 Docker CLI 或者 API 即可管理集群。
轻量级: 相比于 Kubernetes, Swarm 更轻量, 适合小型或中型部署。
内置网络: Swarm 提供了内置的覆盖网络, 简化了跨主机容器间的通信。
安全性: Swarm 支持加密通信和认证机制, 确保集群的安全性。
常用命令 初始化集群
加入节点 1 2 3 docker swarm join docker swarm join-token manager docker swarm join-token worker
部署服务 1 2 docker service create docker stack deploy
管理节点 1 2 3 4 5 docker info docker node ls docker node inspect docker node update docker node rm
管理服务 1 2 3 4 docker service ls docker service inspect docker service scale docker service rm
集群搭建 集群初始化 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 docker swarm init --advertise-addr 服务器IP地址 docker swarm join-token manager docker swarm join-token worker docker swarm join --token SWMTKN-1-24xzkhefjywjnn078e10w5c6z4c33jbp2hft0dfcmdb4l73jri-4p0mjvzk7xxvsyh08fyj6lbtq 172.14.195.136:2377 docker swarm join --token SWMTKN-1-24xzkhefjywjnn078e10w5c6z4c33jbp2hft0dfcmdb4l73jri-1sr5j29kqudsoreh3ssp0huou 172.14.195.136:2377 docker node ls
添加备注信息 💗💗给节点添加描述信息, 便于浏览、 记忆。 1 2 3 4 5 6 7 docker node update --label-add auth=李四 --label-add email=lisi@163.com 5w16y47qf225m8ac2ggyh6mt9 docker node update --label-rm email 5w16y47qf225m8ac2ggyh6mt9
节点升级/降级 💗💗升级节点为 manager 节点 1 2 3 4 5 docker node promote 5w16y47qf225m8ac2ggyh6mt9 docker node update --role manager 5w16y47qf225m8ac2ggyh6mt9
💗💗降级节点为 worker 节点 1 2 3 4 5 docker node demote 5w16y47qf225m8ac2ggyh6mt9 docker node update --role worker 5w16y47qf225m8ac2ggyh6mt9
节点退出集群 1 2 3 4 5 6 7 8 9 10 11 12 docker swarm leave docker swarm leave --force docker node rm -f 5w16y47qf225m8ac2ggyh6mt9
集群退出自动锁定 💗💗开启集群退出自动锁定后, 节点中需要至少有一个manager节点运行, 不然manager节点全部宕机, 则启动秘钥丢失( 秘钥保存在内存中) , 集群就不可使用, 只能离开原有集群, 重新搭建。 1 2 3 4 5 6 7 8 9 10 11 docker swarm update --autolock=true docker swarm update --autolock=false docker swarm unlock-key docker swarm unlock
集群通信安全 Docker Swarm 的通信安全主要围绕着确保集群内部通信以及客户端与集群之间通信的完整性、 机密性和不可否认性。 Swarm 通过使用 Transport Layer Security (TLS) 加密来实现这一目标, 以防止中间人攻击、 数据窃听和其他安全威胁。
Docker Swarm 使用 TLS 加密来保护管理节点和工作节点之间的通信, 同时也用于保护 Docker 客户端与 Swarm 集群之间的通信。 TLS 证书可以由任何证书颁发机构( CA) 生成, 包括自签名证书或第三方 CA。
💗💗在 Swarm 集群中, TLS 证书通常包括以下几部分
CA 证书: 这是集群的根证书, 用于签发所有其他证书。
Manager 证书: 为每个管理节点生成的证书, 用于与其他节点通信。
Worker 证书: 为每个工作节点生成的证书, 用于与管理节点通信。
客户端证书: 为每个需要与 Swarm 集群交互的 Docker 客户端生成的证书。
💗💗安全通信端口
2377/tcp: 用于客户端与 Swarm 进行安全通信, 以及管理节点之间的通信。
7946/tcp 和 7946/udp: 用于节点之间的心跳检测和集群状态的同步。
4789/udp: 用于 overlay 网络的 VXLAN 通信。
💗💗Swarm 集群的安全性
定期轮换证书: 定期更换 TLS 证书, 尤其是当有节点离开集群或怀疑证书已泄露时。
限制对管理节点的访问: 只允许经过身份验证和授权的客户端访问管理节点。
使用强密码策略: 为 Docker 客户端和节点使用复杂的密码或 SSH 密钥进行身份验证。
监控和审计: 实施日志记录和审计措施, 监控集群活动, 以便及时发现异常行为。
集群服务 创建服务( 容器) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 docker service create -p 9000:8080 --replicas 3 --name tomcat tomcat:8.5.49 docker service create -p 9000:8080 --mode global --name tomcat tomcat:8.5.49 docker service create \ -p 9000:8080 \ --replicas 5 \ --name tomcat \ --update-parallelism 2 \ --update-delay 3s \ --update-max-failure-ratio 0.2 \ --update-failure-action rollback \ --rollback-parallelism 2 \ --rollback-delay 3s \ --rollback-max-failure-ratio 0.2 \ --rollback-failure-action contiue \ tomcat:8.5.39
服务列表查询 1 2 3 docker service ls docker service ps tomcat docker node ps
更新服务 1 docker service update --image tomcat:8.5.39 tomcat
服务回滚 1 docker service update --rollback tomcat
服务扩容\缩容 1 2 3 4 5 docker service update --replicas 5 --name tomcat docker service scale tomcat=5
节点暂停扩容 1 2 docker node update --availability pause 5w16y47qf225m8ac2ggyh6mt9
节点清空任务 1 2 docker node update --availability drain 5w16y47qf225m8ac2ggyh6mt9
删除服务( 任务) 1 docker service rm tomcat
负载均衡验证 1 2 3 docker service create -p 8080:80 --replicas 5 --name whoami containous/whoami curl http://localhost:8080
集群网络 Swarm 使用一种称为 Overlay 网络的技术来实现跨主机的服务通信, 这使得容器可以在集群中的任何节点上运行, 同时保持与其他容器的网络连通性。
💗💗Swarm 集群网络主要分为以下几个部分
Swarm Overlay 网络: Swarm 提供了一种特殊的网络类型, 即 Overlay 网络, 它允许容器跨越不同的物理或虚拟主机进行通信。 当在一个 Swarm 集群中创建服务时, Docker 会自动为服务创建一个 Overlay 网络。 这个网络类型是基于 VXLAN 的, 这意味着它使用封装技术在底层网络上创建了一个逻辑上的二层网络, 这样容器就像在同一台主机上一样进行通信, 而实际上它们可能分布在集群的不同节点上。
Ingress 网络: 当服务被创建时, Swarm 也会创建一个 Ingress 网络。 这个网络用于将外部流量路由到服务的容器实例上。 Ingress 网络利用了负载均衡器( 通常是 Traefik 或 Nginx) 来转发流量到正确的容器。 Ingress 网络使用一个虚拟 IP (VIP) 来接收外部请求, 并将请求路由到集群内服务的实例上。
Node 网络: 每个 Swarm 节点都有一个 Node 网络, 它负责将容器与本地网络接口连接起来, 同时也提供了与 Overlay 网络的连接。 Node 网络是每个节点上的默认桥接网络。
端口映射和服务发现: 服务在 Swarm 集群中可以定义端口映射, 将容器的端口暴露给外部世界。 此外, Swarm 支持服务发现, 允许容器自动找到同一服务的其他实例, 而无需显式配置。
网络策略和安全: Swarm 允许管理员设置网络策略, 例如限制容器之间的通信或访问外部网络的权限。 这可以通过网络的标签和容器的网络连接规则来实现。
DNS 解析: Swarm 集群中的容器可以自动解析服务名称到其 IP 地址, 这得益于内置的 DNS 服务, 使得容器间的通信更加便捷。
CI/CD | DevOps 概述 CI/CD 是现代软件开发和运维( DevOps) 中非常关键的概念。 CI/CD 不仅是一种技术实践, 也是一种文化和工作流程的变革, 它鼓励团队采用敏捷开发方法, 快速迭代, 同时保持高度的质量标准。 通过自动化和标准化, CI/CD 帮助组织实现了更快的软件交付周期, 提高了软件质量和客户满意度。
💗💗 CI 持续集成( Continuous Integration) , 持续集成是一种软件开发实践, 要求开发人员经常( 比如每天) 将他们的工作集成到共享的主干分支中。 每次集成后, 会通过自动化构建( 包括编译和测试) 来验证, 以便尽早发现集成错误。
💗💗 CD
持续交付( Continuous Delivery) , 持续交付扩展了持续集成的概念, 它不仅包括自动化构建和测试, 还包含了自动化部署至测试和预生产环境。 这意味着, 软件产品在任何时刻都可以被部署到生产环境, 但实际是否部署则由人工决策。
持续部署( Continuous Deployment) , 持续部署是持续交付的进一步延伸, 它指的是每当代码通过了所有预定的测试之后, 就自动部署到生产环境中, 无需人工干预。
💗💗DevOps DevOps 是一个结合了软件开发( Development) 和 IT 运维( Operations) 的术语, 旨在促进软件开发、 技术运营和质量保证( QA) 部门之间的沟通、 协作与整合。 DevOps 文化和实践的目标是缩短系统开发周期, 提供持续的交付和部署能力, 同时仍然保持高质量的软件产品。 DevOps 是一种综合的方法论, 它改变了传统软件开发和运维的分离模式, 推动了软件开发的现代化和高效化。
💗💗工具链
源代码管理系统: 如 Git 和 SVN。
构建和自动化工具: 如 Jenkins、 Travis CI、 GitLab CI/CD 和 GitHub Actions。
自动化测试框架: 如 JUnit、 Selenium、 Postman 等。
容器化和虚拟化平台: 如 Docker 和 Kubernetes。
配置管理工具: 如 Ansible、 Chef 和 Puppet。
监控和日志工具: 如 Prometheus、 Grafana 和 ELK Stack。
系统架构 CI/CD简化流程图 graph LR;
A[代码提交] --> B{构建};
B -->|通过| C[测试];
B -->|失败| F[构建失败];
C --> D{代码审查};
D -->|通过| E[制品];
D -->|失败| G[代码审查失败];
E --> H[打包];
H --> I{部署};
I -->|成功| J[生产环境];
I -->|失败| K[部署失败];
J --> L[监控];
L --> M{问题? };
M -->|是| N[警报];
M -->|否| J;
classDef success fill:#0f0,stroke:#333,stroke-width:4px;
classDef fail fill:#f00,stroke:#333,stroke-width:4px;
classDef monitoring fill:#ccc,stroke:#333,stroke-width:4px;
class J success;
class F,G,K,N fail;
class L monitoring;
系统整体架构图 C4Container
Person(User, 用户, "Eclipse | IDEA")
Container(GitLab, "源代码仓库", "Git | GitLab | SVN")
Container_Boundary(Jenkins, "Jenkins") {
Container(Maven, "mvn package", "源代码打包")
Container(SonarScanner, "SonarScanner", "SonarQube客户端")
Container(Docker, "cocker build", "构建镜像")
Container(JT, "监听")
}
Container_Boundary(SonarQube, "SonarQube") {
Container(SonarQube, "SonarQube")
}
Container_Boundary(Harbor, "Harbor") {
Container(Harbor, "Harbor", "镜像仓库")
}
Container_Boundary(TargetServer, "TargetServer") {
Container(DockerServer, Docker, "docker run")
}
Container(DD, "钉钉")
Rel(User, GitLab, "Uses", "git push")
Rel(GitLab, Maven, "git push")
Rel(Maven, SonarScanner, "")
Rel(SonarScanner, Docker, "")
Rel(SonarScanner, SonarQube, "代码质量检测")
Rel(Docker, Harbor, "docker push")
Rel(Docker, DockerServer, "SSH:cmd")
Rel(Harbor, DockerServer, "docker pull")
Rel(JT, DD, "消息推送")
UpdateRelStyle(User, GitLab, $offsetY="10")
UpdateRelStyle(JT, DD, $offsetY="-100", $offsetX="-30")
UpdateRelStyle(SonarScanner, SonarQube, $offsetY="10", $offsetX="-50")
UpdateRelStyle(Harbor, DockerServer, $offsetY="10", $offsetX="-45")
Docker项目配置运行 安装可视化面板 1 2 3 4 5 6 7 8 9 10 11 12 docker run -d \ -p 9000:9000 \ -p 9443:9443 \ -v /data -v /var/run/docker.sock:/var/run/docker.sock \ --restart=always \ --privileged=true \ --name portainer \ portainer/portainer-ce
安装 Nginx 容器 1 2 3 4 5 6 7 8 docker run --rm --entrypoint=cat nginx /etc/nginx/conf.d/default.conf > /home/docker/nginx/conf.d/default.conf docker run --rm --entrypoint=cat nginx /etc/nginx/nginx.conf > /home/docker/nginx/nginx.conf docker run -d -p 10000:80 \ -v /home/docker/nginx/conf.d:/etc/nginx/conf.d\ -v /home/docker/nginx/nginx.conf:/etc/nginx/nginx.conf \ -v /home/docker/nginx/html:/usr/share/nginx/html \ --name nginx \ nginx
安装 MySql 容器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 docker run -d -p 10000:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ -v /home/docker/mysql/conf:/etc/mysql/conf.d \ -v /home/docker/mysql/data:/var/lib/mysql \ -v /home/docker/mysql/log:/var/log/mysql \ --name mysql \ mysql:5.7 vim /home/docker/mysql/conf/my.cnf [client] default_character_set=utf8 [mysql] default_character_set=utf8 [mysqld] character_set_server=utf8 docker restart mysql
搭建私有镜像中心: registry 1 2 yum install -y httpd-tools
创建镜像中心登录用户 1 2 3 4 5 6 7 8 9 mkdir -p /home/docker/authcd /home/docker/authhtpasswd -Bbc htpasswd.user zhangsan 123 htpasswd -Bb htpasswd.user lisi 123 htpasswd -D htpasswd.user lisi
运行容器 1 2 3 4 5 6 7 8 9 10 11 docker run \ -d -p 5000:5000 \ --restart always \ -v /var/lib/registry:/var/lib/registry \ -v /home/docker/auth:/auth \ -e "REGISTRY_AUTH=htpasswd" \ -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \ -e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd.user \ --name registry \ registry
把请求改为http 1 2 3 4 5 6 7 8 9 10 vi /etc/docker/daemon.json { "registry-mirrors" : ["https://xxxxxxxx.mirror.aliyuncs.com" ], "insecure-registries" : ["192.168.192.111:5000" ] }
推送镜像 1 2 3 4 5 6 docker login -u zhangsan 192.168.192.111:5000 docker tag hello-world 192.168.192.111:5000/zhangsan/hw:1.0 docker push 192.168.192.111:5000/zhangsan/hw:1.0
查看镜像 1 2 3 4 5 curl -u zhangsan:123 -XGET http://192.168.192.111:5000/v2/_catalog curl -u zhangsan:123 -XGET http://192.168.192.111:5000/v2/zhangsan/hw/tags/list tree /var/lib/registry
修改配置 1 2 3 4 5 6 7 8 9 10 docker exec -it registry /bin/sh vi /etc/docker/registry/config.yml storage: delete: enabled: true docker restart registry
删除镜像 1 2 3 4 5 curl -u zhangsan:123 -I -XDELETE http://192,168.192.111:5000/v2/zhangsan/hw/manifests/sha256:7071451ad41asdada1531as3415 docker exec -it registry registry garbage-collect /etc/docker/registry/config.yml
搭建源代码仓库: GitLab 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 docker pull gitlab/gitlab-ce mkdir -p /home/docker/gitlabvi compose.yml services: gitlab: image: gitlab/gitlab-ce container_name: gitlab restart: always environment: GITLAB_OMNIBUS_CONFIG: external_url 'http://192.168.153.128:9999' gitlab_rails['initial_root_password' ]=123456789 gitlab_rails['gitlab_shell_ssh_port' ]=2222 ports: - 9999:9999 - 2222:2222 volumes: - ./config:/etc/gitlab - ./logs:/var/log/gitlab - ./data:/var/opt/gitlab docker compose config -q docker compose up -d docker logs gitlab docker exec -it gitlab bash cat /etc/gitlab/initial_root_passwordhttp://192.168.153.128:9999
学习资源