在 Kubernetes 上部署 Apache Flink:生产实战指南

在 Kubernetes 上部署 Apache Flink:生产实战指南

本文基于 Flink 1.15.2 + Kubernetes 的生产环境部署实践。


一、架构概览

Flink 在 Kubernetes 上采用经典的 JobManager + TaskManager 主从架构,JobManager 负责作业调度与协调,TaskManager 承载实际的计算任务。

架构概览

资源分配一览

组件 作用 副本数 Task Slots 内存配置
JobManager 作业调度、Checkpoint 管理、协调 1 8G
TaskManager 执行计算任务 3 80/Pod 48G
总计 4 240

二、Namespace 隔离

为 Flink 创建独立 Namespace,实现资源与权限的逻辑隔离:

apiVersion: v1
kind: Namespace
metadata:
  name: flink-ns

Namespace 隔离


三、Service 设计

我们定义了两个 Service,分别处理内部通信与外部访问:

Service 架构

3.1 内部通信 Service(ClusterIP)

apiVersion: v1
kind: Service
metadata:
  name: flink-jobmanager
  namespace: flink-ns
spec:
  type: ClusterIP
  ports:
    - name: rpc
      port: 6123          # JobManager RPC
    - name: blob
      port: 6124          # Blob Server
    - name: query
      port: 6125          # Queryable State
    - name: ui
      port: 8081          # Web UI
  selector:
    app: flink-jobmanager

3.2 外部访问 Service(NodePort)

apiVersion: v1
kind: Service
metadata:
  name: flink-cs
  namespace: flink-ns
spec:
  type: NodePort
  ports:
    - port: 8081
      targetPort: 8081
      nodePort: 30081     # 外部访问端口
  selector:
    app: flink-jobmanager

访问 Flink Web UI:http://<任意节点IP>:30081


四、关键运行参数

通过 FLINK_PROPERTIES 环境变量注入 Flink 配置,这是 K8s 部署的推荐方式:

配置注入链路

4.1 Checkpoint 配置

execution.checkpointing.interval: 10min
execution.checkpointing.tolerable-failed-checkpoints: 100
  • 10 分钟 执行一次 Checkpoint,平衡数据安全性与性能开销
  • 允许 100 次 Checkpoint 失败容忍,避免偶发故障导致作业中断

4.2 容错与重启策略

restart-strategy: fixed-delay
restart-strategy.fixed-delay.attempts: 2147483647

采用 固定延迟重启策略,重试次数设为 Integer.MAX_VALUE,确保作业在异常情况下持续自动恢复 —— 这在生产环境中至关重要。

容错与重启流程

4.3 心跳配置

heartbeat.interval: 10000
heartbeat.timeout: 120000

心跳间隔 10 秒,超时阈值 120 秒。较长的超时时间适应 Kubernetes 环境中可能的网络波动和容器调度延迟,防止误判 TaskManager 失联。

4.4 内存配置

# JobManager
jobmanager.memory.process.size: 8G

# TaskManager
taskmanager.memory.process.size: 48G

五、外部服务连通

Flink 作业依赖 MongoDBKafka 集群,通过 hostAliases 在 Pod 内配置静态域名映射,避免依赖集群 DNS 解析外部服务:

hostAliases:
  - ip: "xxx.xxx.xxx.xxx"
    hostnames:
      - "mongoserver1"
  - ip: "xxx.xxx.xxx.xxx"
    hostnames:
      - "mongoserver2"
  - ip: "xxx.xxx.xxx.xxx"
    hostnames:
      - "mongoserver3"
  - ip: "xxx.xxx.xxx.xxx"
    hostnames:
      - "kafka-server01"
  - ip: "xxx.xxx.xxx.xxx"
    hostnames:
      - "kafka-server02"
  - ip: "xxx.xxx.xxx.xxx"
    hostnames:
      - "kafka-server03"

DNS 解析链路

为什么选择 hostAliases?

方案 优点 缺点
hostAliases 配置简单、Pod 内即时生效、无需依赖外部 DNS IP 变化时需更新 YAML
集群 CoreDNS 集中管理、自动生效 需要配置外部 DNS 转发,复杂度高
外部 Service + Endpoint K8s 原生方案 配置繁琐,需维护 Endpoint 对象

生产环境中外部服务 IP 通常稳定不变,hostAliases 是最简单可靠的选择。


六、节点调度策略

使用 nodeSelector 将 Flink Pod 调度到专属计算节点,保障资源独占:

nodeSelector:
  flink-server: "true"

节点打标签

部署前需要为目标节点打标签:

kubectl label nodes stream-node-01 flink-server=true
kubectl label nodes stream-node-02 flink-server=true
kubectl label nodes stream-node-03 flink-server=true

节点调度流程

为什么需要 nodeSelector?

  1. 资源独占:TaskManager 单 Pod 配置 48G 内存,需要物理节点有充足资源
  2. 避免竞争:防止 Flink 与其他业务争抢 CPU/内存,保障实时计算稳定性
  3. 网络亲和:计算节点与外部服务(MongoDB/Kafka)网络拓扑更近,降低延迟

七、完整部署流程

部署流程

步骤 1:节点打标签

kubectl label nodes stream-node-01 flink-server=true
kubectl label nodes stream-node-02 flink-server=true
kubectl label nodes stream-node-03 flink-server=true

步骤 2:执行部署

kubectl apply -f flink.yaml

步骤 3:检查 Pod 状态

kubectl get pod -n flink-ns -o wide

预期输出:

NAME                                  READY   STATUS    RESTARTS   AGE   IP            NODE
flink-jobmanager-xxxxxxxxxx-xxxxx     1/1     Running   0          60s   10.x.x.x     stream-node-01
flink-taskmanager-xxxxxxxxxx-xxxx1    1/1     Running   0          60s   10.x.x.x     stream-node-01
flink-taskmanager-xxxxxxxxxx-xxxx2    1/1     Running   0          60s   10.x.x.x     stream-node-02
flink-taskmanager-xxxxxxxxxx-xxxx3    1/1     Running   0          60s   10.x.x.x     stream-node-03

步骤 4:排查日志(如需)

kubectl -n flink-ns logs <pod-name> --all-containers=true

八、核心配置速查表

核心配置速查

配置项 JobManager TaskManager 说明
Checkpoint 间隔 10min 10min 保障数据安全
Checkpoint 容忍 100 100 防止偶发故障中断
重启策略 fixed-delay fixed-delay 自动恢复
重试次数 MAX MAX 最大限度可用性
心跳间隔 10s 10s 健康检测
心跳超时 120s 120s 适应 K8s 环境
进程内存 8G 48G 资源保障
Task Slots 80/Pod 单 Pod 高并行度

九、实践总结

六大核心实践

要点 说明 核心收益
Namespace 隔离 独立命名空间 flink-ns 资源冲突避免,权限管控清晰
双 Service 设计 ClusterIP 内部 + NodePort 外部 通信安全 + 运维便捷
极限容错配置 fixed-delay + MAX 重试 作业永不停歇
hostAliases 连通 Pod 内静态域名映射 外部服务稳定可达
nodeSelector 独占 调度到专属计算节点 资源充足,避免竞争
80 Slots / Pod 单 Pod 高并行度 减少 Pod 数量,降低调度开销

阅读更多

Skills系统:可扩展AI能力设计

Skills系统:可扩展AI能力设计

概述 Skills系统是AI-Native架构中的重要组件,它允许通过声明式配置扩展AI的能力。本文将介绍Skills系统的设计与实现,让大模型能够像人类专家一样具备特定领域的能力。 什么是Skills系统 概念 Skills(技能)是一种声明式的AI能力扩展机制,类似于人类的"专业技能": 与Function Calling的区别 特性 Skills Function Calling 目的 改变AI的"思维"方式 扩展AI的"工具"能力 实现 系统提示词注入 API调用 持久性 会话级别 单次调用 复杂度 简单(配置) 复杂(开发) 灵活性 高(声明式) 低(编程式) 系统设计 架构 SKILL.

By 菱角
插件化架构设计模式

插件化架构设计模式

概述 插件化架构是一种将核心功能与扩展功能分离的设计模式,允许系统在运行时动态加载和卸载功能模块。本文将介绍如何在微服务平台中设计和实现插件化架构。 为什么需要插件化 插件化优势 1. 模块化:功能独立,边界清晰 2. 可扩展:按需加载,动态增删 3. 隔离性:插件间互不干扰 4. 可维护:独立开发、测试、部署 5. 可定制:用户按需选择功能 核心设计 架构概览 核心组件实现 1. 插件接口定义 // core/plugin.interface.ts // 插件接口 export interface IPlugin { // 插件名称 readonly name: string // 插件版本 readonly version: string // 插件配置 getConfig(): PluginConfig // 插件清单

By 菱角
gRPC服务通信设计与实践

gRPC服务通信设计与实践

概述 在微服务架构中,服务间通信是关键环节。相比REST API,gRPC提供了更高的性能和更强的类型安全。本文将介绍如何在微服务平台中设计和实现gRPC服务通信。 为什么选择gRPC gRPC vs REST对比 特性 gRPC REST 协议 HTTP/2 HTTP/1.1 序列化 Protocol Buffers (二进制) JSON (文本) 性能 高(二进制+压缩) 中(文本开销) 类型安全 强(代码生成) 弱(运行时检查) 流式通信 原生支持(双向流) 需额外实现(SSE/WebSocket) 代码生成 自动生成 手动编写 浏览器支持 需gRPC-Web 原生支持 调试难度

By 菱角
多语言微服务架构:Node.js与Python协作

多语言微服务架构:Node.js与Python协作

概述 在微服务架构中,根据场景选择最适合的编程语言是最佳实践。本文将介绍如何在微服务平台中实现Node.js与Python的协作,发挥各自技术优势。 技术选型策略 为什么混合使用 服务划分 Node.js服务(7个) 服务 功能 选择Node.js的原因 llm.api 大模型服务 高并发SSE流式响应 ucenter.api 用户中心 RESTful API标准实践 doc.api 文件服务 流式上传下载处理 resource.api 资源管理 gRPC高性能通信 rag.api 知识库服务 MongoDB集成便利 statistic.api 统计分析 事件驱动架构 pptonline.api PPT服务 与前端技术栈统一 Python服务(1个) 服务 功能 选择Python的原因

By 菱角