目录

Flink-Dockerfile走读

概述

关于 Flink 的 Docker 相关的配置,可以参考源码这个目录。

1
2
3
4
5
6
/path/to/flink/flink-container/docker
├── Dockerfile // Dockerfile
├── README.md // 具体的说明,如何创建 Flink 的镜像文件
├── build.sh // 
├── docker-compose.yml //
└── docker-entrypoint.sh // Dockerfile 中运行的脚本

Dockerfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 省略了 License,特此声明

FROM openjdk:8-jre-alpine

# 安装需要的软件
# snappy 是一个压缩库
# libc6-compat 是 ANSI C 的函数库
RUN apk add --no-cache bash snappy libc6-compat

# Flink 容器里的环境变量
# Flink 软件的安装目录在 /opt
ENV FLINK_INSTALL_PATH=/opt
# Flikn 的解压目录在 /opt/flink
ENV FLINK_HOME $FLINK_INSTALL_PATH/flink
# Flink 的依赖包目录在 /opt/flink/lib
ENV FLINK_LIB_DIR $FLINK_HOME/lib
# Flink 的插件目录在 /opt/flink/plugins
ENV FLINK_PLUGINS_DIR $FLINK_HOME/plugins
# 这个不知道是什么目录
ENV FLINK_OPT_DIR $FLINK_HOME/opt
# 这是用户代码的 Jar 包目录,/opt/flink/artifacts
ENV FLINK_JOB_ARTIFACTS_DIR $FLINK_INSTALL_PATH/artifacts
# 更新一下 PATH,把 Flink 的二进制文件的目录加上 /opt/flink/bin
ENV PATH $PATH:$FLINK_HOME/bin

# 这些 ARG 可以在构建镜像的时候输入参数,默认值都是 NOT_SET,如果设置了就会去找对应的目录,并且打入镜像里
# Flink 的发行版路径,可以在本地指定任何下载或者自行打包的 Flink 发行版包
ARG flink_dist=NOT_SET
# 用户写的业务代码路径
ARG job_artifacts=NOT_SET
# Python 的版本,填2或者3
ARG python_version=NOT_SET
# Hadoop Jar 包的依赖路径
ARG hadoop_jar=NOT_SET*

# 安装 Python,根据前面填的 python_version 这个环境变量,不填就不装
RUN \
  if [ "$python_version" = "2" ]; then \
    apk add --no-cache python; \
  elif [ "$python_version" = "3" ]; then \
    apk add --no-cache python3 && ln -s /usr/bin/python3 /usr/bin/python; \
  fi

# 把 Flink 发行版和 Hadoop jar(不一定有 Hadoop)放在 /opt/flink 目录
ADD $flink_dist $hadoop_jar $FLINK_INSTALL_PATH/
# 用户代码放在 /opt/artifacts
ADD $job_artifacts/* $FLINK_JOB_ARTIFACTS_DIR/

RUN set -x && \
  ln -s $FLINK_INSTALL_PATH/flink-[0-9]* $FLINK_HOME && \
  for jar in $FLINK_JOB_ARTIFACTS_DIR/*.jar; do [ -f "$jar" ] || continue; ln -s $jar $FLINK_LIB_DIR; done && \
  if [ -n "$python_version" ]; then ln -s $FLINK_OPT_DIR/flink-python-*-java-binding.jar $FLINK_LIB_DIR; fi && \
  if [ -f ${FLINK_INSTALL_PATH}/flink-shaded-hadoop* ]; then ln -s ${FLINK_INSTALL_PATH}/flink-shaded-hadoop* $FLINK_LIB_DIR; fi && \
  # 创建 flink 用户组和 flink 用户,并且更改下面目录的用户权限
  addgroup -S flink && adduser -D -S -H -G flink -h $FLINK_HOME flink && \
  chown -R flink:flink ${FLINK_INSTALL_PATH}/flink-* && \
  chown -R flink:flink ${FLINK_JOB_ARTIFACTS_DIR}/ && \
  chown -h flink:flink $FLINK_HOME

# 把这个脚本拷贝到镜像
COPY docker-entrypoint.sh /

# 切换用户 flink
USER flink
# 暴露 8081 和 6123 端口
EXPOSE 8081 6123
# 指定容器启动脚本
ENTRYPOINT ["/docker-entrypoint.sh"]
# docker run 可以传入 -help 参数
CMD ["--help"]

Entrypoint

既然分析了 Dockerfile,那么也顺带分析一波 docker-entrypoint.sh 脚本都干了什么事。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 同样省略了 License
# 指定 Flink 的目录
FLINK_HOME=${FLINK_HOME:-"/opt/flink/bin"}

# 这两个变量分别用于启动 jc 和 tm
JOB_CLUSTER="job-cluster"
TASK_MANAGER="task-manager"

CMD="$1"
shift;

if [ "${CMD}" == "--help" -o "${CMD}" == "-h" ]; then
    echo "Usage: $(basename $0) (${JOB_CLUSTER}|${TASK_MANAGER})"
    exit 0
elif [ "${CMD}" == "${JOB_CLUSTER}" -o "${CMD}" == "${TASK_MANAGER}" ]; then
    echo "Starting the ${CMD}"

    if [ "${CMD}" == "${TASK_MANAGER}" ]; then
        # 启动 taskmanager
        exec $FLINK_HOME/bin/taskmanager.sh start-foreground "$@"
    else
        # 启动 standalone-job
        exec $FLINK_HOME/bin/standalone-job.sh start-foreground "$@"
    fi
fi

exec "$@"
警告
本文最后更新于 2017年2月1日,文中内容可能已过时,请谨慎参考。