制作flink镜像
创建一个目录,用来存放Dockerfile文件及需要的tar包
mkdir /home/lonton/docker/dockerfile/flink
#将flink-1.10.0.tar.gz放在目录下
mv flink-1.10.0.tar.gz /home/lonton/docker/dockerfile/flink
Flink的job manager和task manager使用的是同一套配置文件和代码,他们可以使用同一个镜像。启动不同的进程只需要传递不同的启动命令。接下来我们需要为Flink镜像编写一个入口文件。
run.sh:
#!/bin/bash
FLINK_JOB_MANAGER_SH=$FLINK_HOME/bin/jobmanager.sh
FLINK_TASK_MANAGER_SH=$FLINK_HOME/bin/taskmanager.sh
case "$1" in
"jobmanager")
$FLINK_JOB_MANAGER_SH start-foreground
;;
"taskmanager")
$FLINK_TASK_MANAGER_SH start-foreground
;;
*)
echo "COMMAND ERROR"
;;
esac
编写Dockerfile
FROM jdk:alpine
MAINTAINER lbz
RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g" /etc/apk/repositories
RUN apk update && apk upgrade
RUN apk add openssh vim openrc bash bash-doc bash-completion --no-cache
RUN sed -i "s/#PermitRootLogin.*/PermitRootLogin yes/g" /etc/ssh/sshd_config
ADD flink-1.10.0.tar.gz /opt
ENV FLINK_HOME /opt/flink-1.10.0
COPY run.sh /root/
RUN chmod +x /root/run.sh
EXPOSE 8088
VOLUME $FLINK_HOME/conf
ENTRYPOINT ["/root/run.sh"]
基础镜像用的是我自己写的jdk
构造镜像
将run.sh、Dockerfile都放到flink目录下
docker build -t flink:alpine --squash .
#给镜像打标签
docker tag flink:alpine 192.168.0.16:5000/flink:dev
#把镜像push到私仓
docker push 192.168.0.16:5000/flink:dev
部署flink
Flink conf文件
下载Flink的二进制软件包,解压其中的conf目录到任意目录即可。
配置k8s资源对象
创建configmap
首先修改conf/flink-conf.yaml,修改jobmanager.rpc.address
$ vi flink-conf.yaml
jobmanager.rpc.address: flink-jm-rpc-service
其中flink-jm-rpc-service为后续需要创建的service名称。这个service创建之后,k8s会为我们创建一个同名的DNS条目。我们使用这条DNS可以访问到Flink的job manager。
接下来执行这条命令,将conf目录下所有文件内容创建为一个config map,名字为flink-config:
$ kubectl create configmap flink-config --from-file=./conf
创建Job Manager RPC service
我们需要创建一个service,指向job manager这个pod。Kubenetes会自动创建一个DNS入口。这样一来,无论job manager调度到哪个节点上,它的IP如何变化,k8s自动帮我们更新,并通过DNS关联起来。我们的程序不用做任何修改。
flink-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: flink-jm-rpc-service
spec:
clusterIP: None
selector:
role: jobmanager
ports:
- protocol: TCP
port: 6123
targetPort: 6123
创建Job manager和Task manager的deployment
flink-jm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flink-jobmanager
labels:
app: flink
spec:
replicas: 1
selector:
matchLabels:
app: flink
role: jobmanager
template:
metadata:
labels:
app: flink
role: jobmanager
spec:
containers:
- name: flink
image: 192.168.0.16:5000/flink:dev
args: ["jobmanager"]
ports:
- name: web-port
containerPort: 8081
volumeMounts:
- name: flink-config-volume
mountPath: /opt/flink-1.10.0/conf
volumes:
- name: flink-config-volume
configMap:
name: flink-config
同理,下面是Task manager的Deployment。这里我们设定replica为3,即启动3个task manager。
flink-tm.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: flink-taskmanager
labels:
app: flink
role: taskmanager
spec:
replicas: 3
selector:
matchLabels:
app: flink
template:
metadata:
labels:
app: flink
spec:
containers:
- name: flink
image: 192.168.0.16:5000/flink:dev
args: ["taskmanager"]
ports:
- name: web-port
containerPort: 8081
volumeMounts:
- name: flink-config-volume
mountPath: /opt/flink-1.10.0/conf
volumes:
- name: flink-config-volume
configMap:
name: flink-config
暴露Flink web端口到集群外
到目前为止,Flink集群实际上已经部署完毕,但是Flink的web界面只能在集群的容器内部访问,我们需要将这个端口暴露到集群外部。
uisvc.yaml
apiVersion: v1
kind: Service
metadata:
name: flink-web-service
spec:
selector:
app: flink
type: NodePort
ports:
- protocol: TCP
port: 8081
targetPort: 8081
nodePort: 30123
启动服务
$ kubectl create -f flink-svc.yaml
$ kubectl create -f flink-jm.yaml
$ kubectl create -f flink-tm.yaml
$ kubectl create -f uisvc.yaml
查看pod状态
$ kubectl get pods
flink-jobmanager-6b789dc567-7lm46 1/1 Running 0 57m
flink-taskmanager-65d457c5c-bjmtz 1/1 Running 0 57m
flink-taskmanager-65d457c5c-hrf9f 1/1 Running 0 57m
flink-taskmanager-65d457c5c-q9l88 1/1 Running 0 57m
登录web界面查看