Docker 与 K8s 生产级实战:从镜像极致优化到集群自动化部署全流程

文章目录

  • [🎯🔥 Docker 与 K8s 生产级实战:从镜像极致优化到集群自动化部署全流程](#🎯🔥 Docker 与 K8s 生产级实战:从镜像极致优化到集群自动化部署全流程)
      • [📊📋 第一章:引言------为什么镜像优化决定了交付效率?](#📊📋 第一章:引言——为什么镜像优化决定了交付效率?)
        • [🧬🧩 1.1 镜像体积的"复利开销"](#🧬🧩 1.1 镜像体积的“复利开销”)
        • [🛡️⚖️ 1.2 云原生契约的物理实现](#🛡️⚖️ 1.2 云原生契约的物理实现)
      • [🌍📈 第二章:精密工业------Dockerfile 多阶段构建(Multi-stage Build)深度拆解](#🌍📈 第二章:精密工业——Dockerfile 多阶段构建(Multi-stage Build)深度拆解)
        • [🧬🧩 2.1 传统构建的"臃肿症结"](#🧬🧩 2.1 传统构建的“臃肿症结”)
        • [🛡️⚖️ 2.2 多阶段构建的逻辑映射](#🛡️⚖️ 2.2 多阶段构建的逻辑映射)
        • [💻🚀 代码实战:通用型 Java 项目多阶段构建模板](#💻🚀 代码实战:通用型 Java 项目多阶段构建模板)
      • [🔄🎯 第三章:镜像体积优化------从 1G 到 500M 的极致压榨](#🔄🎯 第三章:镜像体积优化——从 1G 到 500M 的极致压榨)
        • [🧬🧩 3.1 基础镜像的"降维打击"](#🧬🧩 3.1 基础镜像的“降维打击”)
        • [🛡️⚖️ 3.2 链式指令与清理"边角料"](#🛡️⚖️ 3.2 链式指令与清理“边角料”)
        • [📉⚠️ 3.3 忽略文件的物理屏蔽](#📉⚠️ 3.3 忽略文件的物理屏蔽)
        • [💻🚀 代码实战:优化后的基础组件层镜像](#💻🚀 代码实战:优化后的基础组件层镜像)
      • [📊📋 第四章:Spring Boot 专属优化------Layered JARs 实战](#📊📋 第四章:Spring Boot 专属优化——Layered JARs 实战)
        • [🧬🧩 4.1 "胖 JAR"的增量痛点](#🧬🧩 4.1 “胖 JAR”的增量痛点)
        • [🛡️⚖️ 4.2 物理拆分逻辑](#🛡️⚖️ 4.2 物理拆分逻辑)
        • [💻🚀 代码实战:利用 layertools 构建分层镜像](#💻🚀 代码实战:利用 layertools 构建分层镜像)
      • [🏗️💡 第五章:跨越集群------从本地镜像到 K8s 调度的物理映射](#🏗️💡 第五章:跨越集群——从本地镜像到 K8s 调度的物理映射)
        • [🧬🧩 5.1 资源限额(Resources)的物理内幕](#🧬🧩 5.1 资源限额(Resources)的物理内幕)
        • [🛡️⚖️ 5.2 健康检查的闭环设计](#🛡️⚖️ 5.2 健康检查的闭环设计)
      • [🏗️🌍 第六章:工业级编排------K8s 核心资源声明与物理路径](#🏗️🌍 第六章:工业级编排——K8s 核心资源声明与物理路径)
        • [🧬🧩 6.1 资源配额(Resource Quotas)的物理意义](#🧬🧩 6.1 资源配额(Resource Quotas)的物理意义)
        • [🛡️⚖️ 6.2 存活与就绪探针的"攻防逻辑"](#🛡️⚖️ 6.2 存活与就绪探针的“攻防逻辑”)
        • [💻🚀 代码实战:高可用 Spring Boot 部署 YAML 全量解析](#💻🚀 代码实战:高可用 Spring Boot 部署 YAML 全量解析)
      • [🔄🛑 第七章:优雅停机------容器信号量与业务连续性的深度闭环](#🔄🛑 第七章:优雅停机——容器信号量与业务连续性的深度闭环)
        • [🧬🧩 7.1 SIGTERM 信号的物理流转](#🧬🧩 7.1 SIGTERM 信号的物理流转)
        • [🛡️⚖️ 7.2 Spring Boot 的优雅响应](#🛡️⚖️ 7.2 Spring Boot 的优雅响应)
        • [💻🚀 代码实战:K8s preStop 钩子与配置闭环](#💻🚀 代码实战:K8s preStop 钩子与配置闭环)
      • [🔒🛡️ 第八章:安全加固------从只读文件系统到 Distroless 镜像](#🔒🛡️ 第八章:安全加固——从只读文件系统到 Distroless 镜像)
        • [🧬🧩 8.1 最小化攻击面](#🧬🧩 8.1 最小化攻击面)
        • [🛡️⚖️ 8.2 运行时安全上下文](#🛡️⚖️ 8.2 运行时安全上下文)
        • [💻🚀 代码实战:K8s 安全上下文加固配置](#💻🚀 代码实战:K8s 安全上下文加固配置)
      • [💣💀 第九章:避坑指南------排查容器化过程中的十大"死亡错误"](#💣💀 第九章:避坑指南——排查容器化过程中的十大“死亡错误”)
      • [🌟🏁 第十章:总结与展望------迈向高性能交付体系](#🌟🏁 第十章:总结与展望——迈向高性能交付体系)

🎯🔥 Docker 与 K8s 生产级实战:从镜像极致优化到集群自动化部署全流程

前言:标准化容器交付的物理进化

在云计算的浪潮中,如果说代码是业务的灵魂,那么容器就是承载灵魂的"标准集装箱"。从 Docker 诞生至今,容器化技术已经完成了从"新鲜玩意"到"基础设施"的身份转变。然而,很多开发者对 Docker 的理解仍停留在 docker builddocker push 的初级阶段。

当镜像体积动辄突破 1G、部署到 K8s 后频繁出现 OOM、或者是 CI/CD 流水线因为镜像层数过多而卡顿时,我们才意识到:编写一个"能跑"的 Dockerfile 很简单,但构建一个"高性能、高安全、工业级"的容器化体系却有着极高的门槛。今天,我们将开启一场深度的实战拆解,从多阶段构建的底层逻辑到 K8s 的资源调度机制,全方位压榨容器的每一分性能。


📊📋 第一章:引言------为什么镜像优化决定了交付效率?

在传统的运维模型中,环境不一致导致的"在我机器上是好的"问题占据了 40% 以上的故障原因。容器通过对运行环境的"像素级"封印,解决了这个问题。

🧬🧩 1.1 镜像体积的"复利开销"

想象一个拥有 50 个微服务的系统,如果每个服务的镜像体积都是 1.2GB:

  1. 存储压力:私有仓库需要承载 60GB 的存储。
  2. 网络瓶颈:在 K8s 扩容时,节点拉取镜像(Image Pull)会消耗巨大的内网带宽,导致扩容响应延迟从秒级变为分钟级。
  3. 攻击面扩大:镜像中残留的编译工具(如 gcc、mvn)、包管理器(apt、yum)甚至调试工具(vim、curl),都可能成为黑客进行提权的跳板。
🛡️⚖️ 1.2 云原生契约的物理实现

优秀的容器化方案不仅是让应用"跑起来",更要让它"轻盈地跑"。通过精简底座、分层优化,我们可以将交付链路的效率提升数倍。这不仅是运维的艺术,更是每一位中高级开发者必须掌握的底层内功。


🌍📈 第二章:精密工业------Dockerfile 多阶段构建(Multi-stage Build)深度拆解

多阶段构建是 Docker 17.05 以后引入的黑科技,它彻底改变了镜像构建的范式。

🧬🧩 2.1 传统构建的"臃肿症结"

在过去,为了在容器内编译代码,我们必须在镜像中安装所有的开发工具(JDK、Maven、Node.js)。编译完成后,这些工具依然残留在镜像中,虽然它们对运行代码毫无用处。

🛡️⚖️ 2.2 多阶段构建的逻辑映射

多阶段构建允许我们在一个 Dockerfile 中使用多个 FROM 指令。

  • 构建阶段(Build Stage):使用全量的开发环境,进行代码编译、测试。
  • 运行阶段(Run Stage):使用极简的运行环境(如 JRE、Alpine),仅从构建阶段拷贝生成的二进制文件或 JAR 包。
  • 物理本质:最终镜像只包含运行阶段的内容,构建阶段的中间层会被 Docker 自动丢弃。
💻🚀 代码实战:通用型 Java 项目多阶段构建模板
dockerfile 复制代码
# ---------------------------------------------------------
# 代码块 1:工业级 Java 多阶段构建 Dockerfile
# ---------------------------------------------------------

# 第一阶段:编译环境(命名为 builder)
FROM maven:3.8.4-openjdk-17-slim AS builder
LABEL stage=builder

# 设置工作目录
WORKDIR /app

# 1. 巧妙利用缓存:先拷贝 pom.xml 并下载依赖
# 只要 pom.xml 没变,这一步就不会重新下载依赖包
COPY pom.xml .
RUN mvn dependency:go-offline -B

# 2. 拷贝源代码并执行打包
COPY src ./src
RUN mvn clean package -DskipTests

# 第二阶段:极致运行环境
# 使用 eclipse-temurin 提供的极简 JRE 镜像,而非完整的 JDK
FROM eclipse-temurin:17-jre-alpine AS runner

# 设置元数据
LABEL maintainer="tech-support@csdn.net"
LABEL service="order-service"

# 设置环境变量
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XshowSettings:vm"
ENV APP_HOME=/opt/app

# 创建非 root 用户,遵循最小权限原则
RUN addgroup -S javauser && adduser -S javauser -G javauser
WORKDIR $APP_HOME

# 3. 核心步骤:仅从 builder 阶段拷贝生成的 JAR 包
# 这样最终镜像中不会包含 Maven 及其产生的几百 MB 临时文件
COPY --from=builder /app/target/*.jar app.jar

# 赋权
RUN chown -R javauser:javauser $APP_HOME

# 切换用户
USER javauser

# 暴露端口
EXPOSE 8080

# 优雅停机处理:使用 exec 模式启动进程
# 确保 java 进程为 PID 1,能够正确接收 K8s 发出的 SIGTERM 信号
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

🔄🎯 第三章:镜像体积优化------从 1G 到 500M 的极致压榨

体积优化是一场关于"断舍离"的博弈。通过以下三个维度的调优,我们可以实现体积的质变。

🧬🧩 3.1 基础镜像的"降维打击"
  • 选择 1:Ubuntu/CentOS (约 200MB+)。包含完整的包管理器和系统库,适合复杂环境。
  • 选择 2:Debian-slim (约 100MB+)。移除了大量非核心文档和库,是稳定性与体积的平衡点。
  • 选择 3:Alpine (约 5MB)。基于 musl libc 和 busybox,极其精简。
  • 物理考量 :虽然 Alpine 很轻,但由于它不使用 glibc,运行某些涉及 JNI 或原生二进制调用的 Java 程序时可能会崩溃。生产环境建议优先使用 distrolessslim 版本。
🛡️⚖️ 3.2 链式指令与清理"边角料"

每一个 RUN 指令都会产生一层镜像。

  • 错误写法RUN apt-get updateRUN apt-get install git
  • 正确写法 :利用 && 连接所有指令,并在最后执行 rm -rf /var/lib/apt/lists/*
📉⚠️ 3.3 忽略文件的物理屏蔽

.dockerignore 文件往往被开发者忽视。如果不配置它,Docker 会将项目下的 .gittarget.idea 以及本地庞大的 node_modules 全部发送给 Docker Daemon,导致构建上下文(Context)瞬间膨胀。

💻🚀 代码实战:优化后的基础组件层镜像
dockerfile 复制代码
# ---------------------------------------------------------
# 代码块 2:带优化技巧的底层工具镜像构建
# ---------------------------------------------------------
FROM debian:bullseye-slim

# 链式操作并及时清理缓存,减少镜像层残留
RUN set -ex \
    && apt-get update \
    && apt-get install -y --no-install-recommends \
        ca-certificates \
        curl \
        net-tools \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# 配置时区:这一步常被忽视,导致容器日志时间对不上
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone

📊📋 第四章:Spring Boot 专属优化------Layered JARs 实战

Spring Boot 2.3+ 引入的分层镜像(Layered JARs)是 Java 容器化的最高级形态。

🧬🧩 4.1 "胖 JAR"的增量痛点

传统的 Spring Boot JAR 包包含:业务代码(经常变动)和第三方依赖(几乎不变)。

由于 Docker 镜像是按层缓存的,只要业务代码改了一个字,整个 JAR 包层(可能 200MB)就会失效。

🛡️⚖️ 4.2 物理拆分逻辑

Layered JARs 允许我们将应用解压为四个部分:

  1. dependencies:稳定不变的第三方库。
  2. spring-boot-loader:Spring Boot 引导程序。
  3. snapshot-dependencies:快照依赖。
  4. application:你编写的业务逻辑代码。
💻🚀 代码实战:利用 layertools 构建分层镜像
dockerfile 复制代码
# ---------------------------------------------------------
# 代码块 3:基于 Spring Boot 分层特性的 Dockerfile
# ---------------------------------------------------------

# 构建阶段
FROM eclipse-temurin:17-jre-alpine AS builder
WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
# 利用 layertools 提取分层数据
RUN java -Djarmode=layertools -jar application.jar extract

# 生产阶段
FROM eclipse-temurin:17-jre-alpine
WORKDIR application
# 按照变动频率,从小到大依次拷贝
# 这种顺序确保了当业务逻辑变化时,前三层都能命中 Docker 缓存
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./

# JVM 参数优化,开启容器感知
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "org.springframework.boot.loader.JarLauncher"]

🏗️💡 第五章:跨越集群------从本地镜像到 K8s 调度的物理映射

构建完完美的镜像后,如何让它在 K8s 集群中稳定运行?

🧬🧩 5.1 资源限额(Resources)的物理内幕

在 K8s 中,requests 决定调度,limits 决定生死。

  • 物理本质:K8s 底层利用 Cgroups 限制 CPU 和内存。
  • Java 风险 :如果 limits.memory 设为 1G,但 JVM 的堆大小(-Xmx)没配,JVM 默认会尝试申请宿主机内存的 1/4,这可能直接导致容器被操作系统 OOM Killer 杀掉。
🛡️⚖️ 5.2 健康检查的闭环设计
  • Liveness Probe(存活探针):判断容器是否活着。失败则重启。
  • Readiness Probe(就绪探针):判断容器是否准备好接收流量。失败则从 Service 列表中摘除。

🏗️🌍 第六章:工业级编排------K8s 核心资源声明与物理路径

构建完极致优化的镜像后,真正的挑战在于如何在 Kubernetes(K8s)这个"分布式操作系统"中,精准地描述应用的运行需求。

🧬🧩 6.1 资源配额(Resource Quotas)的物理意义

在 K8s 中,resources 字段决定了 Pod 在物理节点上的位置。

  • Requests(请求值):调度器(Scheduler)根据该值决定节点是否有足够空间。它相当于"保底"资源。
  • Limits(上限值):容器运行时的物理硬限。
  • 物理考量 :对于 Java 应用,建议将内存的 requestslimits 设为一致。这是因为 JVM 在启动时会预申请堆内存,如果 limit 波动,会导致频繁的系统级内存置换,严重影响性能甚至触发节点驱逐。
🛡️⚖️ 6.2 存活与就绪探针的"攻防逻辑"
  1. Liveness Probe :解决"程序卡死"问题。如果 Java 线程死锁,健康检查端点(如 /actuator/health)无响应,K8s 会果断重启容器。
  2. Readiness Probe:解决"流量平滑"问题。应用启动初期的 JIT 编译和连接池建立非常耗时,就绪探针确保只有在应用完全准备好时,才允许外部流量接入。
💻🚀 代码实战:高可用 Spring Boot 部署 YAML 全量解析
yaml 复制代码
# ---------------------------------------------------------
# 代码块 4:生产环境 Deployment 声明全量模板
# ---------------------------------------------------------
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
  namespace: prod
  labels:
    app: order-service
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1       # 更新时最多多出一个副本
      maxUnavailable: 0 # 确保更新过程中永远没有服务中断
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      # 安全加固:使用非 root 用户运行
      securityContext:
        runAsUser: 1000
        fsGroup: 2000
      containers:
      - name: order-service
        image: csdn-registry.com/prod/order-service:v1.2.5
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
        # 资源限制调优
        resources:
          requests:
            cpu: "500m"
            memory: "1024Mi"
          limits:
            cpu: "1000m"
            memory: "1024Mi"
        # 存活探针
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 60 # 给 JVM 充分的启动预热时间
          periodSeconds: 10
        # 就绪探针
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 5
        # 环境变量注入:让 JVM 动态感知物理限制
        env:
        - name: JAVA_OPTS
          value: "-XX:MaxRAMPercentage=75.0 -XX:+UseG1GC"

🔄🛑 第七章:优雅停机------容器信号量与业务连续性的深度闭环

在微服务频繁发布的今天,"停机不报错"是衡量交付质量的核心指标。

🧬🧩 7.1 SIGTERM 信号的物理流转

当 K8s 决定停止一个 Pod 时(如删除、滚动更新),它会向容器内 PID 为 1 的进程发送 SIGTERM 信号。

  • 物理本质 :如果你的启动脚本使用了 sh -c "java -jar app.jar",那么 PID 1 将是 Shell 进程,它可能不会转发 SIGTERM 给 Java 进程。
  • 后果 :Java 进程感知不到退出指令,一直运行到 30 秒后的 SIGKILL 强制杀掉,导致正在执行的订单丢失、数据库事务中断。
🛡️⚖️ 7.2 Spring Boot 的优雅响应

在 Spring Boot 2.3+ 中,开启优雅停机只需配置:
server.shutdown: graceful

此时,应用收到信号后,会停止接收新请求,并等待存量请求处理完成(默认有 30 秒宽限期)。

💻🚀 代码实战:K8s preStop 钩子与配置闭环
yaml 复制代码
# 在 Deployment.spec.template.spec.containers 下增加
lifecycle:
  preStop:
    exec:
      command: ["sh", "-c", "sleep 10"] # 预留时间给负载均衡器摘除 IP,防止新请求继续打入旧 Pod

🔒🛡️ 第八章:安全加固------从只读文件系统到 Distroless 镜像

容器安全不应仅仅是防火墙,更应深入到镜像的基因中。

🧬🧩 8.1 最小化攻击面

传统的镜像里包含 curlaptsh,一旦黑客通过应用漏洞(如 Log4j 漏洞)进入容器,这些工具就会成为其内网渗透的利器。

  • 进阶技巧 :使用 Google Distroless 镜像。它只包含 Java 运行时所需的最小依赖库,甚至连 Shell 都没有。这意味着黑客即使进入容器也"寸步难行"。
🛡️⚖️ 8.2 运行时安全上下文
  • ReadOnlyRootFilesystem:强制容器的根文件系统为只读。所有的写操作(如日志)必须写在挂载的临时卷(emptyDir)中。这能有效防御 90% 的二进制文件篡改攻击。
💻🚀 代码实战:K8s 安全上下文加固配置
yaml 复制代码
securityContext:
  allowPrivilegeEscalation: false # 禁止特权提升
  readOnlyRootFilesystem: true    # 根文件系统只读
  runAsNonRoot: true              # 强制非 root 运行
  capabilities:
    drop: ["ALL"]                 # 移除所有不必要的系统能力

💣💀 第九章:避坑指南------排查容器化过程中的十大"死亡错误"

根据过去在数百个生产集群中的运维复盘,我们总结了最容易让系统崩溃的十大"深坑":

  1. PID 1 僵尸进程问题 :Java 进程不处理僵尸进程回收,导致容器运行数月后进程数占满。
    • 对策 :在 Dockerfile 中使用 tini 作为 init 进程。
  2. 时区不一致 :默认镜像是 UTC 时间,导致业务日志与数据库时间差了 8 小时。
    • 对策 :挂载 /etc/localtime 或在 Dockerfile 中设置环境变量 TZ=Asia/Shanghai
  3. 大内存页导致启动慢:某些内核版本开启透明大页(THP)会导致 JVM 启动耗时倍增。
  4. DNS 查找风暴 :K8s 内默认的 ndots:5 会导致每一次数据库连接都要经历 5 次无效的域名查询。
    • 对策 :配置 dnsConfig 优化 ndots。
  5. 忽略日志重定向 :日志文件直接写在容器磁盘里,撑爆 Overlay2 层导致宿主机宕机。
    • 对策:全部打到 stdout,利用 Filebeat/Fluentd 采集。
  6. 健康检查端口冲突 :业务端口与 Actuator 监控端口混用,导致内网攻击者可以随意执行 /shutdown
    • 对策 :在 application.yml 中将 management.server.port 设为独立端口。
  7. 忽略 OOM Score 调整 :重要的 API 网关被操作系统优先杀掉。
    • 对策:通过资源 requests 保证关键应用的优先级。
  8. 本地缓存文件丢失:将验证码、临时图片存在容器 /tmp 下,容器重启后全丢。
  9. 忽略 K8s 服务的 Session 亲和性:在负载均衡下,用户的 Session 频繁失效。
  10. 硬编码 IP 地址:试图在镜像里写死数据库 IP。务必使用 K8s 的 Service Name 域名。

🌟🏁 第十章:总结与展望------迈向高性能交付体系

通过这两场跨越两万字的技术拆解,我们从 Dockerfile 的一行行指令,聊到了 K8s 编排的物理内核。

核心思想沉淀:

  1. 分层是效率之魂:利用多阶段构建和 Spring Boot 的 Layertools,将构建速度从分钟级压榨到秒级。
  2. 契约是协作之基:Dockerfile 是一份环境说明书,YAML 是运行时的契约,标准化是云原生的第一前提。
  3. 安全与性能并重 :优秀的工程师在写下 docker build 的那一刻,已经在脑海中预演了流量在 K8s 节点间流转的物理路径。

在未来的技术演进中,GraalVM Native Image(原生镜像) 将会彻底消除 Java 应用的启动延迟和内存臃肿。虽然技术在变,但本文中提到的解耦、精简、防御式治理的底层逻辑,将始终是高性能容器化体系的真理。


🔥 觉得这篇文章对你有启发?别忘了点赞、收藏、关注支持一下!
💬 互动话题:你在生产环境部署 Docker 或 K8s 时,遇到过最离奇的"灵异事件"是什么?欢迎在评论区留下你的排坑笔记!

相关推荐
小韩加油呀2 小时前
jenkins声明式pipline和shell从环境变量配置到打包构建再到发布到k8s
运维·kubernetes·jenkins
会写代码的饭桶2 小时前
【DevOps实战】使用 GitHub Actions 自动构建镜像并双推至 Docker Hub 和 GHCR
docker·自动化·github·devops
梁萌2 小时前
docker部署gitlab和gitlab runner
docker·eureka·gitlab
赛博云推-Twitter热门霸屏工具2 小时前
Twitter 自动化与热门霸屏实战:以赛博云推为例的技术解析
运维·自动化·twitter
代码方舟2 小时前
Java后端实战:对接天远车辆过户查询API打造自动化车况评估系统
java·开发语言·自动化
手动阀行2 小时前
守护发布的最后一道防线:将自动化红队测试深度嵌入 CI/CD 流水线,筑牢 MCP 应用持续交付的安全底座
安全·ci/cd·自动化
kabcko2 小时前
Windows10安装Docker
运维·docker·容器
梦想的旅途23 小时前
基于 RPA 模拟驱动的企业微信外部群自动化架构解析
机器人·自动化·rpa
A-刘晨阳3 小时前
K8S 部署 CoreDNS 之 DNS 域名获取
运维·云原生·容器·kubernetes·dns·coredns