找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

355

积分

0

好友

47

主题
发表于 昨天 00:45 | 查看: 5| 回复: 0

先说结论:经过一整天的捣鼓(其他啥事没干),Apache Flink on Kubernetes 终于被我跑起来了。

坦诚讲,这个过程对k8s的熟悉度要求不低。整个调通过程可谓煞费苦心,中间数次心态濒临崩溃。所以,如果你对 k8s 的熟悉程度跟我差不多,甚至还不如我的话,在决定尝试之前,最好想想清楚,它值不值得你付出这么多。

(PS:本文基于 k8s 集群已被成功部署完成之后的场景进行描述)

官网的踩坑起点

出师不利,一开始就被 Flink 官网的文档给误导了。我根据文档顺序,先找到的是“Kubernetes 设置”部分。

Flink配置界面中Kubernetes设置选项

这部分内容描述的是以手动定义 Deployment 和 Service 的方式来部署 Flink session 集群。

手动部署Flink Session集群的官方指南

对于新手来说,按照这个步骤操作大概率会失败,感觉像进了“黑店”。正确的入口,其实应该在“Native Kubernetes”这里。

Flink配置界面中的Native Kubernetes选项

这里的操作指引更为直接,主要是通过 Flink 自带的脚本与 Kubernetes 集群交互。

在Kubernetes上启动Flink会话的官方命令

导航到这里,真正的挑战才刚刚开始。

网络插件的部署与配置

根据我目前与 Kubernetes 打交道的经验,网络插件是我们绕不开的一道“坎”。它负责集群节点间的网络通讯,一旦出问题,整个集群都可能瘫痪。

在部署 Flink 之前,集群各 Pod 运行正常。

查看集群所有命名空间Pod状态

但当你启动一个 Flink Pod 之后,情况可能就不对了。

Flink JobManager Pod启动失败

查看 Pod 事件,会发现类似这样的错误:

Warning  FailedCreatePodSandBox  4m2s (x4 over 4m6s)  kubelet (combined from similar events): Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "11fcf6f563466d75e69b390353cea4bba8b0918c587970843115841813bf1a65" network for pod "flink-jobmanager-6d6f7f8765-l4r7l": networkPlugin cni failed to set up pod "flink-jobmanager-6d6f7f8765-l4r7l_default" network: loadFlannelSubnetEnv failed: open /run/flannel/subnet.env: no such file or directory

这表明缺少一个叫 flannel 的网络插件。于是,我尝试安装它:

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

安装后,问题依旧,flannel 的 Pod 不断重启(CrashLoopBackOff)。

Flannel网络插件Pod启动失败

一番排查后,怀疑是配置文件中的 Pod IP 网段与集群初始化时设置的网段不一致。首先,需要确认集群的 Pod 网段:

# cat /etc/kubernetes/manifests/kube-controller-manager.yaml | grep cluster-cidr
    - --cluster-cidr=10.244.0.0/16

然后,在下载的 kube-flannel.yml 文件中,找到 net-conf.json 部分,将其中的 Network 字段修改为与集群一致的网段(例如 10.244.0.0/16)。

Flannel配置文件中修改Network网段

修改完毕后,重新应用配置文件,flannel 插件终于正常运行。

Flannel网络插件Pod运行正常

网络问题解决后,以为可以一帆风顺了?事情远没有这么简单。如果完全照搬官网的命令,成功几率渺茫。这其中主要遇到两个大坑。

镜像版本与拉取问题

我使用的 Flink 版本是 1.19,因此希望 Session 集群也使用对应的镜像。但官网的启动命令默认可能拉取 latest 标签,这并非明智之选。官网确实有关于镜像别名的说明,但实际操作中并不直观。

官方关于Docker镜像别名的说明

正确的做法是去 Docker Hub 上找到明确且匹配的镜像标签。例如,我找到的是 apache/flink:1.19-scala_2.12-java8

Docker Hub上Flink 1.19版本镜像

然而,由于网络原因,直接从官方仓库拉取镜像可能非常缓慢甚至失败。我的解决方案是:使用一台境外云服务器拉取镜像,然后再导入到本地 k8s 集群的所有节点上。

指定了正确的镜像后,启动 Session 集群:

bin/kubernetes-session.sh \
-Dkubernetes.cluster-id=my-first-flink-cluster \
-Dkubernetes.container.image=apache/flink:1.19-scala_2.12-java8

启动成功后会输出一个 Web UI 地址,例如 http://192.168.1.173:30793。但直接访问这个地址(IP 是 Master 节点)可能会失败,因为服务实际可能运行在某个 Worker 节点(如 192.168.1.175)上。

通过Worker节点IP访问Flink Web UI

这引出了一个更严重的问题:后续提交任务时,Flink 客户端默认会尝试连接启动日志中给出的那个地址(Master 节点 IP),如果无法连通,任务提交就会卡住或失败。

我的调试过程一度陷入僵局,甚至因为一些激进的操作(如修改节点网络配置)导致整个 k8s 集群崩溃了两次,不得不推倒重来。这段经历虽然痛苦,但也让我对 Kubernetes 的底层机制有了更深刻的理解。

权限配置:最后的临门一脚

在集群“重生”后,我再次启动 Flink Session,并增加了一个关键参数,将服务端口类型设置为 NodePort,以便外部访问:

2026-01-16 14:29:10,803 INFO  org.apache.flink.kubernetes.KubernetesClusterDescriptor      [] - Create flink session cluster my-first-flink-cluster successfully, JobManager Web Interface: http://192.xxx.xxx.173:31430

这次,无论是 Master 节点 IP 还是 Worker 节点 IP,都能成功访问 Web UI 了。

所有节点IP均可访问Flink Dashboard

但是,当我兴冲冲地提交一个示例任务时,任务状态却一直卡在 RUNNING,实际上没有真正的 TaskManager 被创建,几分钟后便超时失败。

任务提交后卡在RUNNING状态

问题出在哪里?又是一轮排查后,我将目光投向了 Kubernetes 的 RBAC 权限。可能是默认的 serviceaccount 权限不足,无法在集群中创建 TaskManager 的 Pod。

于是,我进行了以下权限配置操作:

# 创建独立的namespace
kubectl create ns flink
# 创建serviceaccount
kubectl create serviceaccount flink-account -n flink
# 为serviceaccount绑定clusterrole
kubectl create clusterrolebinding flink-role-binding-flink --clusterrole=edit --serviceaccount=flink:flink-account

现在,完整的、能够成功运行的 Flink Session 启动命令如下:

bin/kubernetes-session.sh \
 -Dkubernetes.cluster-id=my-first-flink-cluster  \
 -Dkubernetes.container.image=apache/flink:1.19-scala_2.12-java8 \
 -Dkubernetes.namespace=flink \
 -Dkubernetes.jobmanager.service-account=flink-account \
 -Dkubernetes.rest-service.exposed.type=NodePort

使用此命令启动集群后,再次提交任务。这一次,一切都顺畅了:

  • TaskManager 的 Pod 被成功创建并运行。
    TaskManager Pod成功创建
  • 任务在 Web UI 中清晰可见,并从 RUNNING 状态最终变为 FINISHED
    任务成功运行并完成

至此,我的 Flink on Kubernetes 运行环境才算是真正调试完成。

总结与思考

回顾整个过程,上面记录的只是所遇困难的冰山一角。我想说的是,在 Kubernetes 上运行 Flink 在技术上是完全可行的,但其中的复杂性和可能遇到的“坑”需要你有充分的心理和技术准备。

你需要面对网络插件配置、镜像拉取、服务暴露、权限控制等一系列在传统部署中较少触及的 运维 层面问题。任何一个环节出错,都可能导致整个流程失败,且排查难度较大。

在我看来,Flink on k8s 更适合两类人:

  1. 对 Kubernetes 有较深理解,能驾驭其各种复杂问题的高手。
  2. 拥有极强耐心和折腾精神,不惧推倒重来的探索者。

你属于哪一种呢?如果你也在探索云原生技术栈,欢迎来 云栈社区 分享你的故事或寻找解决方案。




上一篇:3个优雅的Java函数式编程工具方法,帮你简化项目中的if-else逻辑
下一篇:Go bytes.Reader源码解析:实现高效流式读取与随机定位
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-18 19:46 , Processed in 0.213725 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表