Flink-1.10.0 Native Kubernetes 部署方式實踐

最新發布的 Flink 中支持了 native Kubernetes 的部署方式,可以根據需要動態的增加、減少pod,非常值得測試,目前還處於beta階段,且目前支持 Flink-Session 的部署方式


前提

1、1.9版本或者以上的K8s集羣,且啓用了DNS
2、能夠操作pod、service的 KubeConfig
3、有RBAC權限的service Account,用於創建,刪除pod


部署

解壓flink tar包後,執行如下命令:

./bin/kubernetes-session.sh

啓動成功後可根據日誌輸出打印的 URL 訪問 flink 的頁面,也可以根據 flink 啓動的ClsuterIP/LoadBalancer service 裏的 CLUSTER-IP:8081 來訪問。

默認flink native k8s 啓動的 job master pod 日誌是打印到 pod 裏 /opt/flink/log 目錄下的,如果想通過 kubectl log 查看日誌,可以在 conf/log4j.properties 添加相關配置:

log4j.rootLogger=INFO, file, console

# Log all infos to the console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p %-60c %x - %m%n

然後啓動時添加 -Dkubernetes.container-start-command-template 的參數就可以通過kubectl logs 查看日誌了:

./bin/kubernetes-session.sh -Dkubernetes.container-start-command-template="%java% %classpath% %jvmmem% %jvmopts% %logging% %class% %args%"

然後就可以提交相關job了:

./bin/flink run -d -e kubernetes-session -Dkubernetes.cluster-id=<ClusterId> examples/streaming/WindowJoin.jar

通過不斷提交 job,然後 cancel 掉 job,發現 native k8s 的部署方式可以根據需要動態增加/刪除 pod,相比於之前要事先設定好taskmanager的數量來得方便,也可以更有效的利用資源


採坑

在測試過程中,原先配置的jobmanager.heap.size: 600m,發現pod一直沒啓動成功,describe pod 和查看 pod 日誌後發現 jvm 的啓動內存設置的都是0

Start command : /bin/bash -c $JAVA_HOME/bin/java -classpath $FLINK_CLASSPATH -Xms0m -Xmx0m -Dlog.file=/opt/flink/log/jobmanager.log -Dlogback.configurationFile=file:/opt/flink/conf/logback.xml -Dlog4j.cint.KubernetesSessionClusterEntrypoint
Invalid maximum heap size: -Xmx0m
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

查看相關源碼後發現對於 Yarn、Mesos、K8s 模式啓動的 container 中除了 Flink 的相關進程外還會預留其他 jvm內存,默認最小預留600m,所以上面配置的jobmanager.heap.size: 600m時,經過下面的計算邏輯後剩餘的 jobmanager 的 jvm 的值就爲0了,所以啓動失敗。

	/**
	 * Calculate heap size after cut-off. The heap size after cut-off will be used to set -Xms and -Xmx for jobmanager
	 * start command.
	 * 
	 * 代碼在:org.apache.flink.runtime.clusterframework.BootstrapTools#calculateHeapSize
	 */
	public static int calculateHeapSize(int memory, Configuration conf) {

		final float memoryCutoffRatio = conf.getFloat(ResourceManagerOptions.CONTAINERIZED_HEAP_CUTOFF_RATIO);
		final int minCutoff = conf.getInteger(ResourceManagerOptions.CONTAINERIZED_HEAP_CUTOFF_MIN);

		if (memoryCutoffRatio > 1 || memoryCutoffRatio < 0) {
			throw new IllegalArgumentException("The configuration value '"
				+ ResourceManagerOptions.CONTAINERIZED_HEAP_CUTOFF_RATIO.key()
				+ "' must be between 0 and 1. Value given=" + memoryCutoffRatio);
		}
		if (minCutoff > memory) {
			throw new IllegalArgumentException("The configuration value '"
				+ ResourceManagerOptions.CONTAINERIZED_HEAP_CUTOFF_MIN.key()
				+ "' is higher (" + minCutoff + ") than the requested amount of memory " + memory);
		}

		int heapLimit = (int) ((float) memory * memoryCutoffRatio);
		if (heapLimit < minCutoff) {
			heapLimit = minCutoff;
		}
		return memory - heapLimit;
	}

上面的計算邏輯代碼中涉及到兩個配置參數:

  • containerized.heap-cutoff-ratio:爲安全起見,Job Master容器中要刪減的內存
  • containerized.heap-cutoff-min:要從Job Master容器(YARN / Mesos / Kubernetes)中刪除用於其他JVM內存使用的堆空間百分比。

過程參考:
官網-Flink native k8s 部署模式
官網-Flink相關參數配置
《Flink 1.10 Native Kubernetes 原理與實踐》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章