K8S+Dinky+Flink管理你的计算资源

前置条件

  • 已安装 Dinky (版本 1.2.3

  • 准备 Flink 镜像地址(版本 1.17.2

  • 已安装 K8S (版本 1.20.0

  • 已安装 Docker (版本 19.03.12

  • 已安装 Harbor (版本 2.0

  • 已安装 MinioFlink SQL 任务不需要,Flink Jar 任务需要)

本文只做 Kubernetes Application 模式任务的提交,其他模式不在本文的探讨范围内。

K8S初始环境

创建K8S命名空间

csharp 复制代码
# 创建一个名为 flink 的命名空间
kubectl create namespace flink

创建服务账号和角色绑定

ini 复制代码
# 在名字为 flink 的命名空间中,创建一个名为 flink-service-account 的 serviceaccount
kubectl create serviceaccount flink-service-account -n flink

# 创建 RoleBinding,绑定 ClusterRole admin 到该 ServiceAccount
kubectl create rolebinding dinky-admin --clusterrole=admin --serviceaccount=flink:flink-service-account -n flink
  • rolebinding dinky-admin:创建一个名为 dinky-adminRoleBinding

  • ---clusterrole=admin:指定要绑定的角色是集群角色 admin。虽然 admin 是一个 ClusterRole(定义在集群级别),但通过 RoleBinding 可以将其限制在某个命名空间内生效;

  • ---serviceaccount=flink:flink-service-account:指定目标 ServiceAccount,格式为

    : <namespace>:<serviceaccount-name>

  • -n flink:表示创建的这个 RoleBinding 作用于 flink 命名空间;

创建Secret敏感信息

Secret 用于存储访问私有 Docker 镜像仓库 Harbor 所需的认证信息。

  • harbor-login-registry 是创建的 Secret 的名称;

  • --docker-username=admin 表示 Harbor 登录账号;

  • --docker-password 表示 Harbor 登录密码;

  • -n flink 表示这个 Secretflink 这个命名空间下创建;

css 复制代码
kubectl create secret docker-registry harbor-login-registry --docker-server=harbor-domain --docker-username=admin --docker-password=****** -n flink

制作Docker镜像

理论上可以直接用官方的Flink镜像,但是我们最好还是在官方镜像的基础上构建一个新的基于我们自身需求的镜像。 构建镜像所需依赖清单如下:

sql 复制代码
config
....flink-conf.yaml
usrlib
....flink-s3-fs-hadoop-1.17.2.jar
....dinky-app-1.17-1.2.3-jar-with-dependencies.jar
lib
....mysql-connector-java-8.0.19.jar
....flink-connector-jdbc-3.1.1-1.17.jar
....flink-sql-connector-mysql-cdc-2.4.1.jar
Dockerfile
  • config目录保存flink配置文件;

  • usrlib目录保存用户所需的jar包;

  • lib目录保存flink所需的jar包,可依自己情况放入合适的依赖,不做强制要求;

  • Dockerfile文件放在根目录下;

完整的 Dockerfile 代码如下:

bash 复制代码
# 使用官方 Flink 镜像作为基础镜像
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/flink:1.17.2-scala_2.12-java8

# 设置时区(可选)
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 设置工作目录
WORKDIR /opt/flink

# 在容器内创建以下目录
RUN mkdir -p /opt/flink/usrlib
RUN mkdir -p /opt/flink/plugins/s3-fs-hadoop

# 添加自定义配置文件(可选)
# dinky 提交作业时并未生效,将会被 dinky 集群中的 flink 配置替换
# 将宿主文件 config/flink-conf.yaml 覆盖到镜像的 ${WORKDIR}/conf/ 目录下
COPY config/flink-conf.yaml ./conf/

# 兼容dinky替换jar包
# 删除镜像内 ${WORKDIR}/lib/ 下的所有 loader 包
RUN rm -rf ./lib/flink-table-planner-loader-*.jar
# 将镜像内 ${WORKDIR}/opt/ 下的 table planner 包移动到 ${WORKDIR}/lib/ 下
RUN mv ./opt/flink-table-planner_2.12-*.jar ./lib/

# 添加自定义jar包(可选)
# 将宿主机上 lib 目录下的所有 Flink 依赖包复制到镜像的 ${WORKDIR}/lib 下
COPY lib/*.jar ./lib/
# 将宿主机上 usrlib 目录下的 dinky app 包复制到镜像的 ${WORKDIR}/usrlib 下,这个包在后文中 dinky 的集群配置中会使用到,它是容器启动的包
COPY usrlib/dinky-app-1.17-1.2.3-jar-with-dependencies.jar ./usrlib/
# 将镜像内 ${WORKDIR}/opt/ 下的 flink-s3 依赖包复制到镜像内 flink 的插件目录下
RUN cp ./opt/flink-s3-fs-hadoop-1.17.2.jar ./plugins/s3-fs-hadoop/

# 设置环境变量
ENV FLINK_HOME=/opt/flink
ENV PATH=$FLINK_HOME/bin:$PATH

# 暴露必要的端口
# 8081 - Web UI
# 6123 - TaskManager RPC
EXPOSE 8081 6123

# 设置容器启动命令(根据需要修改)
CMD ["bash"]

构建Docker镜像

perl 复制代码
# 构建名为 my-flink-dinky 的镜像,版本号 1.0
docker build -t my-flink-dinky:1.0 .

# 给 my-flink-dinky 镜像打标签
docker tag my-flink-dinky:1.0 harbor-domain/project-name/my-flink-dinky:1.0

# 将镜像推送到远程 Harbor 仓库
docker push harbor-domain/project-name/my-flink-dinky:1.0

如果docker拉取镜像失败,有可能是因为网络限制,编辑或创建 /etc/docker/daemon.json,将镜像修改成你的阿里云账号镜像地址。

json 复制代码
{
  "registry-mirrors": ["https://<your-id>.mirror.aliyuncs.com"]
	 "insecure-registries" : [
		    "registry.docker-cn.com",
		    "docker.mirrors.ustc.edu.cn"
	    ],
	"debug": true,
	"experimental": false
}

拉取成功后,查看构建好的镜像

python 复制代码
docker images --filter "reference=*flink*"

配置 K8S 集群信息

打开 Dinky 界面,按照如下图所示步骤新建一个 K8S 集群配置

在新建窗口填写集群配置信息:

  • 类型:Kubernetes Application

  • 集群配置名称(自定义):Flink_K8S

  • 是否启用:勾选启用

  • 暴露端口类型:NodePort

  • Kubernetes 命名空间:flink

  • K8S KubeConfig:从本地文件加载会自动带入

  • k8s 提交账号:flink-service-account

  • Flink 镜像地址:harbor-domain/project-name/my-flink-dinky:1.0

  • Flink 配置文件路径:/opt/flink/conf/

  • JM Pod TemplateTM Pod Template

yaml 复制代码
apiVersion: v1
kind: Pod
spec:
  containers:
    - name: flink-main-container
      imagePullPolicy: Always
  imagePullSecrets:
    - name: harbor-login-registry
  • Jar 文件路径:local:///opt/flink/usrlib/dinky-app-1.17-1.2.3-jar-with-dependencies.jar

  • 其他预设配置可以根据自身实际使用需要,设置内存大小、插槽数等;

参数解读

Dinky 资源配置

提交 Flink Jar 任务时,因为 Jar 包路径在 Dinky 中配置,只支持 file:// 协议和 rs:/ 协议,rs 协议默认是保存本地服务器路径,所以这两种协议实际上都是保存在 Dinky 本地,但是任务提交到 K8S 容器之后是没办法读取 Dinky 服务的文件的,所以需要在 Dinky 中将资源配置修改为 S3 协议或者 hdfs 协议,再通过与 rs 协议桥接的方式,实现在 K8S 容器内读取远程 Jar 文件的功能。本文使用的是 MinioS3 协议。 具体配置方式如下图,重点是首先要先关闭是否启用Resource开关,再进行配置修改,最后打开开关让配置生效

  • 存储模式选择 OSS

  • MinioEndpoint Url(默认9000端口)、Access KeySecret Key 写入到配置表单中;

  • 上传目录根路径(/dinky)和存储桶名称(dinky)使用默认就好;

Minio 创建桶

创建一个桶名为 dinky,并将访问权限设置为 public

Dinky 资源管理中上传的文件最终会保存到 Minio 里,根目录是 /dinky/dinky,我这里上传了一个 Flink 官方流任务 TopSpeedWindowing.jar

配置解读

提交 Application 任务

  • 在数据开发中创建一个 Flink Jar 类型的任务;

  • 工具栏上有个下拉框选择我们创建好的集群 Flink_K8S

  • 程序路径可以在资源配置中选择,可以自己手写 rs:/job/TopSpeedWindowing.jarrs 协议会桥接到 s3 协议,从而访问 Minio

  • 程序运行类:org.apache.flink.streaming.examples.windowing.TopSpeedWindowing

  • 点击绿色三角形的启动按钮

K8SFlink 命名空间访问容器组页面,可以看到两个容器已经启动,一个是 Flink Jobmanager,另一个是 Flink TaskManager

如果是提交 Flink SQL 任务则更简单,不需要配置 S3,也不需要 Minio,只需要在 Dinky 中提交任务即可,Dinky 会将 Flink SQL 代码写入到 K8SCnfigMap 配置供容器使用。

常用命令

Docker

Shell 复制代码
# 构建Dockerfile
docker build -t image-name:tag .

# 镜像打标签
docker tag image-name:tag harbor-domain/project-name/image-name:tag

# 推送镜像
docker push harbor-domain/project-name/image-name:tag

# 查看docker镜像中某个目录的文件列表:
docker run --rm harbor-domain/project-name/image-name:tag ls -l /opt/flink/usrlib

# 过滤条件查看docker镜像:
docker images --filter "reference=*flink*"

# 从docker容器拷贝出来文件到宿主机:
docker cp 容器名或容器ID:容器内文件路径 宿主机目标路径
# 示例:
docker cp dinky:/opt/dinky/jar/dinky-app-1.17-1.2.3-jar-with-dependencies.jar /opt/dinky/

# 查看容器日志
docker logs -f --tail=200 <container name or id>

K8S

Shell 复制代码
# 查看容器信息
kubectl get pods pods,svc,sa -n <namespace>
kubectl get clusterrolebinding <rolebinding-name> -o yaml

# 查看日志:
kubectl get pod -n <namespace> -l component=jobmanager
kubectl describe pod <pod name> -n flink
kubectl -n flink logs <pod name> -c flink-main-container --previous

# k8s查看secret:
kubectl get secret -n <namespace> --field-selector type=kubernetes.io/dockerconfigjson

# k8s查看pod文件列表:
kubectl exec <pod name> -- ls /opt/flink

# k8s进入pod的交互式shell:
kubectl -n <namespace> exec -it <pod name> -- /bin/sh

# 查看资源:
kubectl get pods -n <namespace> | grep <deployment-name>
# 示例:
kubectl get pods -n flink | grep my-first-application-cluster

# 删除k8s pod的所有容器资源:
kubectl delete all -l app=<flink-cluster-id> -n <namespace>
# 示例:
kubectl delete all -l app=my-first-application-cluster -n flink

# 删除k8s命名空间:
kubectl delete ns <namespace>
# 示例:
kubectl delete ns flink
Shell 复制代码
# Flink 命令方式提交 Jar 任务到 K8S Application
bin/flink run-application \
    --target kubernetes-application \
    -Dkubernetes.cluster-id=my-first-application-cluster  \
    -Dkubernetes.container.image=harbor-domain/project-name/my-flink-dinky:latest \
    -Dkubernetes.jobmanager.replicas=1 \
    -Dkubernetes.namespace=flink \
    -Dkubernetes.jobmanager.service-account=flink-service-account \
    -Dexternal-resource.limits.kubernetes.cpu=2000m \
    -Dexternal-resource.limits.kubernetes.memory=2Gi \
    -Dexternal-resource.requests.kubernetes.cpu=1000m \
    -Dexternal-resource.requests.kubernetes.memory=1Gi \
    -Dkubernetes.rest-service.exposed.type=NodePort \
    local:///opt/flink/examples/streaming/TopSpeedWindowing.jar

参考

www.dinky.org.cn/docs/next/u... jishuzhan.net/article/193... www.cnblogs.com/liugp/p/167... juejin.cn/post/738703...

相关推荐
Oneslide34 分钟前
ubuntu 手动安装claude
后端
GetcharZp9 小时前
玩转 Linux 机器视觉:手把手带你搞定 Ubuntu 下海康工业相机 C++ SDK
后端
星星在线12 小时前
MusicFree:一个「All in One」的个人音乐服务器,让听歌回归简单
前端·后端
IT_陈寒13 小时前
Redis的SETNX并发问题让我加了三天班
前端·人工智能·后端
demo007x13 小时前
Docling 文档转换以及技术架构分析
前端·后端·程序员
袋鱼不重14 小时前
我的神奇同事,AI 用多了居然写了个 Open In Codex
前端·后端·ai编程
大树8814 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
用户83562907805114 小时前
使用 Python 操作 Word 内容控件
后端·python
像我这样帅的人丶你还14 小时前
啥? 前端也要会干Java?🛵🛵🛵
后端
Hommy8815 小时前
【剪映小助手】添加贴纸接口(Add Sticker)
后端·github·剪映小助手·视频剪辑自动化·剪映api