关注并标星 3分钟秒懂大数据
每天1次,打卡阅读
获取流计算、大数据技术和面经
大家好,我是土哥。
前几天给大家分享了一篇 史上最全干货!Kubernetes 原理+实战总结(全文6万字,90张图,100个知识点)教程,详细讲解了 K8S 的架构设计、集群安装部署、资源管理、实战总结等知识点。
今天我们结合 Kubernetes 和 Flink 1.14 版本,通过 图解 + 实战 教程,为大家全面讲解 Flink on K8S 的安装部署、运行原理、提交流程,并通过案例在 K8S 上提交 Flink 应用。
全文干货满满,大纲如下:

此文已经制作成带目录的 PDF,获取本文PDF 版本,请扫下方二维码加我微信,备注:Flink on K8S

通过上篇文章我们了解到,Pod 是 K8S 集群进行管理的最小单元,程序要运行必须部署在容器中,而容器必须存在于 Pod 中。
一个 Pod 中可以存在一个或者多个容器,容器在创建时,会先新建 containerd-shim,containerd-shim 会建出来最终的 docker 容器。所以 Flink 要被部署到 K8S集群上,需要先被加载到 Docker 镜像中。
本篇文章,我们使用 standalone的方式,详细讲解 如何在 docker 和 K8S 中中部署 Flink 集群。
可以回顾下 Flink 的启动方式。在传统的物理机或者虚拟机中部署 Flink,如果配置了免密和 slave 节点信息,我们可以使用 Flink 的 start-cluster.sh,一条命令启动整个集群。
但是在 docker 中,我们无法这样操作。在镜像中通常不会安装 ssh 服务。此外,docker 镜像的主进程要求使用前台的方式运行,否则该 container 会运行完毕退出。
所以 在 Docker 中需要单独启动 Flink job manager 和 task manager。
在 mini1 master 主节点根目录新建 lyz 文件夹。
#1. 配置jobmanager rpc 地址
jobmanager.rpc.address: 192.168.244.131
#2. 修改taskmanager内存大小,可改可不改
taskmanager.memory.process.size: 2048 m
#3. 修改一个taskmanager中对于的taskslot个数,可改可不改
taskmanager.numberOfTaskSlots: 4
#修改并行度,可改可不改
parallelism.default: 4
#修改主节点ip地址
192.168.244.131:8081
#修改从节点ip,因为是 standalone,所以主从一样
192.168.244.131
tar -zcvf flink-1.14.0-bin-scala_2.11.tar.gz flink-1.14.0/
由于新打的镜像不包含 Linux 的基础命令,所有我们需要使用 centos7 作为基础镜像。
# Dockerfile
[root@mini1 lyz]# vi Dockerfile
FROM centos:7
MAINTAINER lyz
ADD flink-1.14.0-bin-scala_2.11.tar.gz /root
ADD jdk‐8u202‐linux‐x64.tar.gz /root
ARG FLINK_VERSION=1.14.0
ARG SCALA_VERSION=2.11
ENV FLINK_HOME=/root/flink-1.14.0
ENV PATH=$FLINK_HOME/bin:$PATH
ENV JAVA_HOME=/root/jdk1.8.0_202
ENV PATH=$JAVA_HOME/bin:$PATH
RUN cd $FLINK_HOME \
&& echo "env.java.home: /root/jdk1.8.0_202" >> $FLINK_HOME/conf/flink-conf.yaml \
&& echo "FLINK_HOME=/root/flink-1.14.0" >> /etc/profile \
&& echo "PATH=$FLINK_HOME/bin:$PATH" >> /etc/profile \
&& echo "JAVA_HOME=/root/jdk1.8.0_202" >> /etc/profile \
&& echo "PATH=$JAVA_HOME/bin:$PATH" >> /etc/profile \
&& source /etc/profile
EXPOSE 8081
上述文件将 JDK 和 Flink1.14.0的安装包加载到 Docker的根目录下,同时会在 Profile 中添加 JDK 和 Flink 的环境变量。
docker build -t flink:1.14.0 . -f Dockerfile
如下图所示,已经打包成功
[root@mini1 lyz]# docker images
通过 docker run 命令,使用外部端口 9999 映射容器中 flink 集群的 8081 端口,将端口暴露在外边。
docker run -it -p 9999:8081 flink:1.14.0 /bin/bash
进入容器后,可以看到 jdk 和 flink 包全部存放在/root 根目录下。
[root@6437e358ba1d ~]# source /etc/profile
[root@6437e358ba1d ~]# cd flink-1.14.0/bin
[root@6437e358ba1d bin]# ./jobmanager.sh start
Starting standalonesession daemon on host 6437e358ba1d.
[root@6437e358ba1d bin]# ./taskmanager.sh start
Starting taskexecutor daemon on host 6437e358ba1d.
[root@6437e358ba1d bin]# jps
672 TaskManagerRunner
712 Jps
334 StandaloneSessionClusterEntrypoint
启动结果如下图所示:
使用 Flink 自带 WordCount.jar 提交应用任务,并输入外部映射的IP 和 端口。
[root@e7732776891e bin]# flink run -m 192.168.244.131:9999 \
../examples/batch/WordCount.jar --input aaa.txt --output bbb.txt/
上述 Flink on Docker 跑通后,下面我们重点研究一下 Flink on K8S Session 的提交流程、安装部署、应用提交案例。
Flink On K8s Session 模式执行原理图如下:
在 K8S 集群上使用 Session 模式提交 Flink 作业的过程会分为 3 个阶段,首先在 K8S 上启动 Flink Session 集群;其次通过 Flink Client 提交作业;最后进行作业调度执行。具体步骤如下:
1 启动集群
flink-configuration-configmap.yaml
jobmanager-service.yaml
jobmanager-rest-service.yaml #可选
jobmanager-deployment.yaml
taskmanager-deployment.yaml
通过这些文件请求 K8s Master。
以上两个步骤执行完后,Session模式集群创建成功。但此时还没有 JobMaster和 TaskManager,当提交作业需要执行时,才会按需创建。
2 作业提交
Client 用户使用 Flink run 命令,通过指定 Flink Master 的地址,将相应任务提交上来,用户的 Jar 和 JobGrapth 会在 Flink Client 生成,通过 SVC 传给 Dispatcher。
Dispatcher 收到 JobGraph后,会为每个作业启动一个JobMaster,将JobGraph 交给JobMaster进行调度。
3 作业调度
JobMaster 会向 KubernetesResourceManager 申请资源,请求Slot。
KubernetesResourceManager 从 K8S 集群分配 TaskManager。每个 TaskManager 都是具有唯一标识的 Pod。KubernetesResourceManager 会为 TaskManager 生成一份新的配置文件,里面有 Flink Master 的 service name 作为地址,保障在 Flink Master failover 后,TaskManager 仍然可以重新连接上。
K8S 集群分配一个新的 Pod 后,在上面启动 TaskManager。
TaskManager 启动后注册到 SlotManager。
SlotManager 向 TaskManager 请求 Slot。
TaskManager 提供 Slot 给 JobManager,然后任务被分配到 Slot 上运行。
通过上述流程图,我们已经详细了解了 Flink on K8S Session 模式的提交流程,接下来根据提交流程完成集群部署。
本文采用三节点进行部署,mini1 代表 Master 节点,mini2、mini3 代表 node 节点。
总共需要在 mini1 节点创建 5 个文件,其中一个为可选项
截图如下:
ConfigMap 是一个 K-V 数据结构。通常的用法是将 ConfigMap 挂载到 Pod ,作为配置文件提供 Pod 里新的进程使用。在 Flink 中可以将 Log4j 文件或者是 flink-conf 文件写到 ConfigMap 里面,在 JobManager 或者 TaskManger 起来之前将它挂载到 Pod 里,然后 JobManager 去读取相应的 conf 文件,加载其配置,进而再正确地拉起 JobManager 一些相应的组件。
# 新建根目录 k8s_flink
[root@mini1 ~]# mkdir k8s_flink
# 进入根目录
[root@mini1 ~]# cd k8s_flink/
# 新建 flink-configuration-configmap.yaml
[root@mini1 k8s_flink]# vim flink-configuration-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: flink-config
namespace: lyz
labels:
app: flink
data:
flink-conf.yaml: |+
jobmanager.rpc.address: 192.168.244.131
taskmanager.numberOfTaskSlots: 4
blob.server.port: 6124
jobmanager.rpc.port: 6123
taskmanager.rpc.port: 6122
queryable-state.proxy.ports: 6125
jobmanager.memory.process.size: 1600m
taskmanager.memory.process.size: 2048m
taskmanager.numberOfTaskSlots: 4
parallelism.default: 4
通过Serveice 对外暴露服务。Service 可以看作是一组同类 Pod 对外的访问接口。借助 Service,应用可以方便地实现服务发现和负载均衡。
# 创建 jobmanager-service.yaml
[root@mini1 k8s_flink]# vim jobmanager-service.yaml
apiVersion: v1
kind: Service
metadata:
name: flink-jobmanager
namespace: lyz
spec:
type: ClusterIP
ports:
- name: rpc
port: 6123
- name: blob-server
port: 6124
- name: webui
port: 8081
selector:
app: flink
component: jobmanager
可选的 service,该 service 将 jobmanager 的 rest 端口暴露为公共 Kubernetes node 的节点端口
# 创建 jobmanager-rest-service.yaml
[root@mini1 k8s_flink]# vim jobmanager-rest-service.yaml
apiVersion: v1
kind: Service
metadata:
name: flink-jobmanager-rest
namespace: lyz
spec:
type: NodePort
ports:
- name: rest
port: 8081
targetPort: 8081
nodePort: 30081
selector:
app: flink
component: jobmanager
创建 jobmanager 运行的 pod 控制器
# 创建 jobmanager-session-deployment.yaml
[root@mini1 k8s_flink]# vim jobmanager-session-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flink-jobmanager
namespace: lyz
spec:
replicas: 1
selector:
matchLabels:
app: flink
component: jobmanager
template:
metadata:
labels:
app: flink
component: jobmanager
spec:
containers:
- name: jobmanager
image: flink:1.14.0
args: ["jobmanager"]
ports:
- containerPort: 6123
name: rpc
- containerPort: 6124
name: blob-server
- containerPort: 8081
name: webui
livenessProbe:
tcpSocket:
port: 6123
initialDelaySeconds: 30
periodSeconds: 60
volumeMounts:
- name: flink-config-volume
mountPath: /opt/flink/conf
securityContext:
runAsUser: 9999
volumes:
- name: flink-config-volume
configMap:
name: flink-config
items:
- key: flink-conf.yaml
path: flink-conf.yaml
创建 taskmanager 运行的 pod 控制器
# 创建 taskmanager-session-deployment.yaml
[root@mini1 k8s_flink]# vim taskmanager-session-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flink-taskmanager
namespace: lyz
spec:
replicas: 2
selector:
matchLabels:
app: flink
component: taskmanager
template:
metadata:
labels:
app: flink
component: taskmanager
spec:
containers:
- name: taskmanager
image: flink:1.14.0
args: ["taskmanager"]
ports:
- containerPort: 6122
name: rpc
- containerPort: 6125
name: query-state
livenessProbe:
tcpSocket:
port: 6122
initialDelaySeconds: 30
periodSeconds: 60
volumeMounts:
- name: flink-config-volume
mountPath: /opt/flink/conf/
securityContext:
runAsUser: 9999
volumes:
- name: flink-config-volume
configMap:
name: flink-config
items:
- key: flink-conf.yaml
path: flink-conf.yaml
# Configuration 和 service 的定义
[root@mini1 k8s_flink]# kubectl create -f flink-configuration-configmap.yaml
[root@mini1 k8s_flink]# kubectl create -f jobmanager-service.yaml
[root@mini1 k8s_flink]# kubectl create -f jobmanager-rest-service.yaml
# 为集群创建 deployment
[root@mini1 k8s_flink]# kubectl create -f jobmanager-session-deployment.yaml
[root@mini1 k8s_flink]# kubectl create -f taskmanager-session-deployment.yaml
[root@mini1 k8s_flink]# kubectl get svc,pods -n lyz -o wide
通过截图可以看到Flink on K8S Session 集群已经全部启动成功,启动 2个 taskmanager 启动在 mini2,mini3 服务器上。jobmanager 启动在mini3 服务器上。对外暴露的端口号是30081。
通过 DashBoard Web 可以看到服务都正常启动,登录 Flink WEB 页面查看详情 192.168.244.131:30081
通过Flink 官方提供的命令进行应用提交
./bin/flink run -m 192.168.244.131:8081 ./examples/batch/WordCount.jar --input aaa.txt --output bbb.txt/
本文原创作者:土哥、一名大数据算法工程师。
文章首发平台:微信公众号【3分钟秒懂大数据】
需要 PDF 版本的小伙伴们,可以加我微信:threeknowbigdata,备注:Flink on K8S,进行领取。
原创不易,各位觉得文章不错的话,不妨点赞(在看)、留言、转发三连走起!谢谢大家!
原文作者:3分钟秒懂大数据;如有侵权,请联系管理员删除。