全面图解Docker架构设计:掌握Docker全链路思维/实战/优化(小白到大师篇[3])

举报
肖哥弹架构 发表于 2024/11/26 18:39:03 2024/11/26
【摘要】 Docker 是一个革命性的开放平台,用于开发、交付和运行应用程序。通过使用 Docker,开发者可以打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何支持 Docker 的环境中,在不同环境中实现一致的运行。无论是在虚拟机、物理服务器、数据中心还是云平台,Docker 都能确保应用的快速、可靠地部署和运行。 Docker 提供的不仅仅是容器,它还构建了一个庞大的生态系统,包括

image.png
Docker 是一个革命性的开放平台,用于开发、交付和运行应用程序。通过使用 Docker,开发者可以打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何支持 Docker 的环境中,在不同环境中实现一致的运行。无论是在虚拟机、物理服务器、数据中心还是云平台,Docker 都能确保应用的快速、可靠地部署和运行。

Docker 提供的不仅仅是容器,它还构建了一个庞大的生态系统,包括 Docker Hub、Docker Compose、Docker Swarm 等工具,这些工具涵盖了从开发到生产、从单一容器到容器编排的全方位需求。Docker 还支持多种编程语言、框架和中间件,使其成为现代应用开发和部署的首选工具。

本节内容

image.png

8、Docker网络配置

8.1 网络类型

Docker 网络配置是 Docker 容器化技术的重要组成部分,它允许容器与外部世界进行通信。Docker 提供了多种网络驱动来满足不同的网络需求
image.png

图解释:

  • Docker Daemon: Docker 守护进程,负责管理 Docker 容器和网络。
  • Containers: Docker 容器,运行用户的应用。
  • Networks: Docker 网络,管理容器的网络连接。

网络类型:

  • Bridge (Docker0) : Docker 默认的网络类型,创建一个虚拟网桥,使得容器之间以及容器与外部网络之间可以通信。
  • Overlay: 用于 Docker Swarm 模式的跨主机通信,使得不同物理主机上的容器可以互相发现和通信。
  • Host: 将容器的网络堆栈直接与宿主机相连,容器将使用宿主机的网络。
  • Macvlan: 使得容器拥有独立的 MAC 地址,可以像物理设备一样在网络中表现。

网络详细:

  • 虚拟网桥 (Docker0) : Docker 安装后自动创建的虚拟网桥,容器通过这个网桥与外部通信。
  • 隔离: 每个容器都有自己独立的网络接口和 IP 地址,实现网络隔离。
  • 跨主机通信: Overlay 网络允许 Swarm 模式下的不同主机上的容器进行通信。
  • 直接使用宿主机网络: 使用 Host 网络的容器将直接使用宿主机的网络接口和 IP 地址。
  • 虚拟接口: Macvlan 网络为容器创建虚拟接口,使其看起来像物理网络设备。
  • 分配子网: Macvlan 网络为容器分配独立的子网。

8.2 网络详解

1. 默认网络

image.png

  • bridge: Docker 默认的网络驱动,创建一个虚拟的以太网桥,每个容器都会连接到这个虚拟网络并分配一个 IP 地址。
  • docker0: Docker 安装后自动创建的虚拟网桥,容器会连接到这个网桥并从网桥分配 IP 地址。

容器数据流转

image.png

2. 网络命名空间
  • network namespace: Linux 网络命名空间,它提供了网络环境的隔离,每个容器都有自己的网络命名空间。
3. 容器网络接口
  • eth0: 容器内部的网络接口,通常会连接到虚拟网桥。
  • veth: 一对虚拟网络接口,用于容器与宿主机之间的通信。
4. 自定义网络
  • user-defined networks: 用户可以创建自定义网络,这些网络可以是 bridge、overlay 或 host 类型。
5. 网络配置命令
  • docker network create: 创建一个新的 Docker 网络。
  • docker network ls: 列出现有的 Docker 网络。
  • docker network connect: 将容器连接到一个网络。
  • docker network disconnect: 将容器从网络断开。
  • docker network inspect: 查看网络的详细信息。

8.3 网络创建方式

1. Bridge 网络

Bridge 网络是 Docker 默认的网络类型,适合大多数容器化应用。

创建 Bridge 网络:

docker network create --driver bridge my-bridge-network
  • my-bridge-network 是您要创建的网络名称。
  • 此命令创建了一个新的 Bridge 网络。

应用到容器:

docker run -d --name container1 --network my-bridge-network nginx
  • 运行一个 Nginx 容器,并将其连接到 my-bridge-network 网络。
2. Overlay 网络

Overlay 网络用于多宿主机之间的容器通信,常见于 Docker Swarm 模式。

创建 Overlay 网络 (在 Docker Swarm 模式下):

docker swarm init
docker network create --driver overlay my-overlay-network
  • 首先初始化 Docker Swarm 模式。
  • my-overlay-network 是您要创建的网络名称。
  • Overlay 网络允许不同物理主机上的容器进行通信。

应用到容器 (在 Docker Swarm 模式下):

docker service create --replicas 3 --name my-service --network my-overlay-network nginx
  • 创建一个包含 3 个副本的 Nginx 服务,并将其连接到 my-overlay-network 网络。
3. Host 网络

Host 网络将容器的网络堆栈直接连接到宿主机,使得容器共享宿主机的网络命名空间。

应用到容器 (不需要创建,使用时指定):

docker run -d --name container1 --network host nginx
  • 运行一个 Nginx 容器,并将其网络堆栈直接绑定到宿主机。
4. Macvlan 网络

Macvlan 网络允许容器拥有独立的 MAC 地址,看起来就像物理主机一样。

创建 Macvlan 网络:

docker network create --driver macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 my-macvlan-network
  • --driver macvlan 指定网络驱动为 Macvlan。
  • --subnet 指定子网。
  • --gateway 指定网关。
  • my-macvlan-network 是您要创建的网络名称。

应用到容器:

docker run -d --name container1 --network my-macvlan-network nginx
  • 运行一个 Nginx 容器,并将其连接到 my-macvlan-network 网络。
使用场景:
  • Bridge: 适用于大多数单主机容器通信。
  • Overlay: 适用于多主机容器通信,如 Docker Swarm。
  • Host: 适用于需要访问宿主机网络接口的容器。
  • Macvlan: 适用于需要独立网络接口的容器,如网络服务或测试。

9、DockerFile

Dockerfile 是一个文本文件,它包含了用于构建 Docker 镜像的一系列指令和参数。以下是 Dockerfile 的常见结构和组成部分:

指令 说明
FROM 指定基础镜像,开始构建新镜像
RUN 执行命令并创建新的镜像层
CMD 提供容器启动时执行的默认命令
ENTRYPOINT 设置容器启动时的入口点
COPY 从构建上下文复制新文件或目录到镜像中
ADD 类似于 COPY,但可以解压缩归档文件并添加执行权限
ENV 设置环境变量
ARG 定义构建时使用的变量
VOLUME 定义一个挂载点,用于数据持久化或共享
EXPOSE 声明容器运行时监听的端口
WORKDIR 设置工作目录
USER 指定运行命令的用户
HEALTHCHECK 定义容器的健康检查命令
ONBUILD 指定当所创建的镜像作为其他镜像的基础镜像时执行的命令
STOPSIGNAL 配置停止容器的信号
LABEL 为镜像添加元数据
SHELL 指定用于执行 RUN、CMD、ENTRYPOINT 和 SCRIPT 指令的 shell
MAINTAINER 指定维护者的姓名和一个可选的电子邮件地址(已废弃)

完整案例

# 使用基础镜像,这是构建新镜像的起点
FROM ubuntu:20.04 AS base

# 维护者信息(使用 LABEL 替代 MAINTAINERLABEL maintainer="Name <email>"

# 设置环境变量,这会影响后续的RUN指令以及容器运行时的环境
ENV MY_ENV_VAR="my_value"
ENV PATH="/usr/local/bin:${PATH}"

# RUN 指令执行命令并创建一个新的镜像层,用于安装软件包
RUN apt-get update && apt-get install -y \
    curl \
    git \
    vim

# 工作目录 :WORKDIR 设置工作目录,后续的RUNCMDENTRYPOINT指令都会基于这个工作目录
WORKDIR /app

# 复制当前目录内容到容器内的 /app 目录下,COPY 从构建上下文(通常为Dockerfile所在的目录)复制新文件或目录到镜像中
COPY . /app

# 添加额外的文件到镜像中:ADDCOPY类似,但可以处理tar压缩文件,并且可以执行一些特殊操作
ADD ./files/* /app/files/

# 定义一个挂载点:VOLUME 定义一个挂载点,用于数据持久化或容器间数据共享
VOLUME /var/log/myapp

# EXPOSE 声明容器运行时监听的端口
EXPOSE 8000

# 指定容器启动时执行的命令:CMD 指令提供容器启动时执行的默认命令,可以被docker run的参数覆盖
CMD ["python", "/app/main.py"]

# 构建阶段:编译应用,使用多阶段构建来减小最终镜像的大小
FROM base AS builder
RUN apt-get update && apt-get install -y build-essential
COPY --from=base /app /app
RUN make /app

# 生产阶段:运行应用,使用基础镜像作为构建产物的运行环境
FROM base AS production
COPY --from=builder /app/bin /app/bin
CMD ["/app/bin/myapp"]

# 健康检查: HEALTHCHECK 定义容器的健康检查命令,提高容器的可靠性
HEALTHCHECK --interval=30s --timeout=30s --retries=3 \
  CMD curl -f http://localhost:8000 || exit 1

# 用户:USER 指定运行命令的用户和用户组,提高安全性
USER 1000:1000

# 构建缓存:ARG 定义构建缓存的变量,可以用于构建过程中的参数传递
ARG BUILD_DATE
LABEL org.label-schema.build-date=$BUILD_DATE

# 停止信号:STOPSIGNAL 配置停止容器的信号,可以是任何POSIX停止信号或数字
STOPSIGNAL SIGTERM

# 使用 SHELL 指令 :SHELL 指定用于执行指令的shell,可以是bash、sh等
SHELL ["/bin/bash", "-c"]
解释
  1. 基础镜像: 使用 ubuntu:20.04 作为基础镜像。
  2. 维护者信息: 使用 LABEL 替代已废弃的 MAINTAINER
  3. 环境变量: 设置环境变量 MY_ENV_VAR 和更新 PATH
  4. 更新和安装软件: 使用 RUN 安装软件包。
  5. 工作目录: 设置工作目录为 /app
  6. 复制文件: 使用 COPY 和 ADD 将文件添加到镜像中。
  7. 挂载点: 定义一个挂载点。
  8. 暴露端口: 声明容器运行时监听的端口。
  9. 默认命令: 设置容器启动时执行的默认命令。
  10. 构建阶段: 使用 builder 阶段编译应用。
  11. 生产阶段: 使用 production 阶段运行应用。
  12. 健康检查: 定义容器的健康检查命令。
  13. 用户: 指定运行命令的用户。
  14. 构建缓存: 使用 ARG 定义构建时的变量。
  15. 停止信号: 配置停止容器的信号。
  16. SHELL: 指定用于执行指令的 shell。
命令详细说明

1. 基础镜像指令 (FROM)

FROM ubuntu:20.04
  • FROM 指令指定了基础镜像,这是构建新镜像的基础。

2. 维护者指令 (MAINTAINER) (可选,已废弃,建议使用 LABEL)

LABEL maintainer="name <email>"
  • LABEL 用于添加元数据,替代了以前的 MAINTAINER 指令。

3. 环境变量指令 (ENV)

ENV PATH /usr/local/bin:$PATH
  • ENV 用于设置环境变量。

4. 工作目录指令 (WORKDIR)

WORKDIR /app
  • WORKDIR 设置容器内的当前工作目录。

5. 复制指令 (COPY 和 ADD)

COPY . /app
  • COPY 从构建上下文复制新文件或目录到容器的文件系统。
  • ADD 与 COPY 类似,但处理归档文件时有额外的功能。

6. 运行指令 (RUN)

RUN apt-get update && apt-get install -y nginx
  • RUN 指令用于执行命令,并将其结果(如安装的软件)作为新的镜像层保存。

7. 暴露指令 (EXPOSE)

EXPOSE 80
  • EXPOSE 指令通知 Docker 守护进程容器运行时监听的端口。

8. 启动命令指令 (CMD)

CMD ["nginx", "-g", "daemon off;"]
  • CMD 指令指定了容器启动时执行的默认命令。

9. 健康检查指令 (HEALTHCHECK)

HEALTHCHECK --interval=30s --timeout=30s --retries=3 CMD curl -f http://localhost || exit 1
  • HEALTHCHECK 指令用于指定如何检查容器健康状况。

10. 构建缓存指令 (ARG)

ARG VERSION=latest
  • ARG 指令用于定义构建过程中的变量。

11. 多阶段构建 (FROM 在 Dockerfile 中多次使用)

# 第一阶段: 构建阶段
FROM golang:1.16 AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN go build -o /my-go-app

# 第二阶段: 生产环境
FROM alpine:latest
RUN apk add --no-cache ca-certificates
WORKDIR /root
COPY --from=builder /my-go-app .
CMD ["./my-go-app"]
  • 使用多阶段构建可以减小最终镜像的大小,将构建产物从构建阶段复制到生产环境镜像。

10、DockerFile实战案例

第一个案例是Spring Boot应用,第二个案例是一个使用Spring Boot和MyBatis的多模块项目。

10.1 案例1:Spring Boot应用

项目结构

假设我们的Spring Boot应用结构如下:

springbootapp/
├── src/
│   ├── main/
│   │   ├── java/com/
│   │   │   └── example/
│   │   │       ├── controller/
│   │   │       │   └── HelloController.java
│   │   │       └── Application.java
│   │   └── resources/
│   │       └── application.properties
├── pom.xml
└── Dockerfile
  • HelloController.java 是Spring Boot控制器。
  • Application.java 是Spring Boot应用的主程序。
  • application.properties 包含应用配置。
  • pom.xml 是Maven构建配置文件。
Dockerfile
# 使用官方Java基础镜像,带有Maven环境,用于构建项目
FROM maven:3.8.1-jdk-11 AS build
# 设置工作目录
WORKDIR /app
# 复制项目文件到容器中
COPY src ./src
COPY pom.xml .
# 使用Maven构建项目
RUN mvn -f pom.xml clean package

# 使用官方Java基础镜像,用于运行应用
FROM openjdk:11-jre-slim
# 设置工作目录
WORKDIR /app
# 从构建阶段复制已构建的jar文件到运行阶段
COPY --from=build /app/target/*.jar ./app.jar
# 暴露端口
EXPOSE 8080
# 运行Spring Boot应用
CMD ["java", "-jar", "app.jar"]
构建和运行Docker镜像
  1. 构建镜像
docker build -t springbootapp .
  1. 运行容器
docker run -p 8080:8080 springbootapp

10.2 案例2:Spring Boot和MyBatis多模块项目

项目结构

多模块Spring Boot和MyBatis应用结构如下:

multimoduleapp/
├── pom.xml
├── Dockerfile
└── app/
    ├── common/
    │   ├── pom.xml
    │   └── src/
    │       ├── main/
    │       └── java/
    │           └── com/
    │               └── example/
    │                   └── common/
    │                       └── CommonService.java
    ├── api/
    │   ├── pom.xml
    │   └── src/
    │       ├── main/
    │       │   ├── java/
    │       │   │   └── com/
    │       │   │       └── example/
    │       │   │           └── api/
    │       │   │               └── ApiController.java
    │       │   └── resources/
    │       └── application.properties
    └── service/
        ├── pom.xml
        ├── src/
        │   ├── main/
        │   │   ├── java/
        │   │   │   └── com/
        │   │   │       └── example/
        │   │   │           └── service/
        │   │   │               └── BusinessService.java
        │   │   └── resources/
        └── src/
            └── main/
                └── resources/
                    └── mapper/
                        └── UserMapper.xml
  • CommonService.java 是一个通用服务。
  • ApiController.java 是Spring Boot控制器。
  • BusinessService.java 是业务逻辑服务。
  • UserMapper.xml 是MyBatis映射文件。
  • pom.xml 是Maven构建配置文件。
Dockerfile
# 使用官方Java基础镜像,带有Maven环境,用于构建项目
FROM maven:3.8.1-jdk-11 AS build
# 设置工作目录
WORKDIR /app
# 复制项目文件到容器中
COPY . .
# 使用Maven构建项目
RUN mvn -f pom.xml clean package

# 使用官方Java基础镜像,用于运行应用
FROM openjdk:11-jre-slim
# 设置工作目录
WORKDIR /app
# 从构建阶段复制已构建的jar文件到运行阶段
COPY --from=build /app/api/target/*.jar ./app.jar
# 暴露端口
EXPOSE 8080
# 运行Spring Boot应用
CMD ["java", "-jar", "app.jar"]
构建和运行Docker镜像
  1. 构建镜像
docker build -t multimoduleapp .
  1. 运行容器
docker run -p 8080:8080 multimoduleapp
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。