傳統應用遷移到kubernetes(Hadoop YARN)


 

spark-on-yarn-with-kubernetes

該例子僅用來說明具體的步驟划分和復雜性,在生產環境應用還有待驗證,請謹慎使用。

過程中可能用到的概念和術語初步整理如下:

整個遷移過程分為如下幾個步驟:

1. 將原有應用拆解為服務

我們不是一上來就開始做鏡像,寫配置,而是應該先梳理下要遷移的應用中有哪些可以作為服務運行,哪些是變的,哪些是不變的部分。

服務划分的原則是最小可變原則,這個同樣適用於鏡像制作,將服務中不變的部分編譯到同一個鏡像中。

對於像 Spark on YARN 這樣復雜的應用,可以將其划分為三大類服務:

  • ResourceManager
  • NodeManager
  • Spark client

2. 制作鏡像

根據拆解出來的服務,我們需要制作兩個鏡像:

  • Hadoop
  • Spark (From hadoop docker image)

因為我們運行的是 Spark on YARN,因此 Spark 依賴與 Hadoop 鏡像,我們在 Spark 的基礎上包裝了一個 web service 作為服務啟動。

鏡像制作過程中不需要在 Dockerfile 中指定 Entrypoint 和 CMD,這些都是在 kubernetes 的 YAML 文件中指定的。

Hadoop YARN 的 Dockerfile 參考如下配置。

FROM my-docker-repo/jdk:7u80 # Add native libs ARG HADOOP_VERSION=2.6.0-cdh5.5.2 ## Prefer to download from server not use local storage ADD hadoop-${HADOOP_VERSION}.tar.gz /usr/local ADD ./lib/* /usr/local/hadoop-${HADOOP_VERSION}/lib/native/ ADD ./jars/* /usr/local/hadoop-${HADOOP_VERSION}/share/hadoop/yarn/ ENV HADOOP_PREFIX=/usr/local/hadoop \ HADOOP_COMMON_HOME=/usr/local/hadoop \ HADOOP_HDFS_HOME=/usr/local/hadoop \ HADOOP_MAPRED_HOME=/usr/local/hadoop \ HADOOP_YARN_HOME=/usr/local/hadoop \ HADOOP_CONF_DIR=/usr/local/hadoop/etc/hadoop \ YARN_CONF_DIR=/usr/local/hadoop/etc/hadoop \ PATH=${PATH}:/usr/local/hadoop/bin RUN \ cd /usr/local && ln -s ./hadoop-${HADOOP_VERSION} hadoop && \ rm -f ${HADOOP_PREFIX}/logs/* WORKDIR $HADOOP_PREFIX # Hdfs ports EXPOSE 50010 50020 50070 50075 50090 8020 9000 # Mapred ports EXPOSE 19888 #Yarn ports EXPOSE 8030 8031 8032 8033 8040 8042 8088 #Other ports EXPOSE 49707 2122

3. 准備應用的配置文件

因為我們只制作了一個 Hadoop 的鏡像,而需要啟動兩個服務,這就要求在服務啟動的時候必須加載不同的配置文件,現在我們只需要准備兩個服務中需要同時用的的配置的部分。

YARN 依賴的配置在 artifacts 目錄下,包含以下文件:

bootstrap.sh capacity-scheduler.xml container-executor.cfg core-site.xml hadoop-env.sh hdfs-site.xml log4j.properties mapred-site.xml nodemanager_exclude.txt slaves start-yarn-nm.sh start-yarn-rm.sh yarn-env.sh yarn-site.xml

其中作為 bootstrap 啟動腳本的 bootstrap.sh 也包含在該目錄下,該腳本如何編寫請見下文。

4. Kubernetes YAML 文件

根據業務的特性選擇最適合的 kubernetes 的資源對象來運行,因為在 YARN 中 NodeManager 需要使用主機名向 ResourceManger 注冊,因此需要沿用 YARN 原有的服務發現方式,使用 headless service 和 StatefulSet 資源。更多資料請參考 StatefulSet

所有的 Kubernetes YAML 配置文件存儲在 manifest 目錄下,包括如下配置:

  • yarn-cluster 的 namespace 配置
  • Spark、ResourceManager、NodeManager 的 headless service 和 StatefulSet 配置
  • 需要暴露到 kubernetes 集群外部的 ingress 配置(ResourceManager 的 Web)
kube-yarn-ingress.yaml spark-statefulset.yaml yarn-cluster-namespace.yaml yarn-nm-statefulset.yaml yarn-rm-statefulset.yaml 

5. Bootstrap 腳本

Bootstrap 腳本的作用是在啟動時根據 Pod 的環境變量、主機名或其他可以區分不同 Pod 和將啟動角色的變量來修改配置文件和啟動服務應用。

該腳本同時將原來 YARN 的日志使用 stdout 輸出,便於使用 kubectl logs 查看日志或其他日志收集工具進行日志收集。

啟動腳本 bootstrap.sh 跟 Hadoop 的配置文件同時保存在 artifacts 目錄下。

該腳本根據 Pod 的主機名,決定如何修改 Hadoop 的配置文件和啟動何種服務。bootstrap.sh 文件的部分代碼如下:

if [[ "${HOSTNAME}" =~ "yarn-nm" ]]; then sed -i '/<\/configuration>/d' $HADOOP_PREFIX/etc/hadoop/yarn-site.xml cat >> $HADOOP_PREFIX/etc/hadoop/yarn-site.xml <<- EOM <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>${MY_MEM_LIMIT:-2048}</value> </property> <property> <name>yarn.nodemanager.resource.cpu-vcores</name> <value>${MY_CPU_LIMIT:-2}</value> </property> EOM echo '</configuration>' >> $HADOOP_PREFIX/etc/hadoop/yarn-site.xml cp ${CONFIG_DIR}/start-yarn-nm.sh $HADOOP_PREFIX/sbin/ cd $HADOOP_PREFIX/sbin chmod +x start-yarn-nm.sh ./start-yarn-nm.sh fi if [[ $1 == "-d" ]]; then until find ${HADOOP_PREFIX}/logs -mmin -1 | egrep -q '.*'; echo "`date`: Waiting for logs..." ; do sleep 2 ; done tail -F ${HADOOP_PREFIX}/logs/* & while true; do sleep 1000; done fi

從這部分中代碼中可以看到,如果 Pod 的主機名中包含 yarn-nm 字段則向 yarn-site.xml配置文件中增加如下內容:

  <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>${MY_MEM_LIMIT:-2048}</value> </property> <property> <name>yarn.nodemanager.resource.cpu-vcores</name> <value>${MY_CPU_LIMIT:-2}</value> </property>

其中 MY_MEM_LIMIT 和 MY_CPU_LIMIT 是 kubernetes YAML 中定義的環境變量,該環境變量又是引用的 Resource limit。

所有的配置准備完成后,執行 start-yarn-nm.sh 腳本啟動 NodeManager。

如果 kubernetes YAML 中的 container CMD args 中包含 -d 則在后台運行 NodeManger 並 tail 輸出 NodeManager 的日志到標准輸出。

6. ConfigMaps

將 Hadoop 的配置文件和 bootstrap 腳本作為 ConfigMap 資源保存,用作 Pod 啟動時掛載的 volume。

kubectl create configmap hadoop-config \ --from-file=artifacts/hadoop/bootstrap.sh \ --from-file=artifacts/hadoop/start-yarn-rm.sh \ --from-file=artifacts/hadoop/start-yarn-nm.sh \ --from-file=artifacts/hadoop/slaves \ --from-file=artifacts/hadoop/core-site.xml \ --from-file=artifacts/hadoop/hdfs-site.xml \ --from-file=artifacts/hadoop/mapred-site.xml \ --from-file=artifacts/hadoop/yarn-site.xml \ --from-file=artifacts/hadoop/capacity-scheduler.xml \ --from-file=artifacts/hadoop/container-executor.cfg \ --from-file=artifacts/hadoop/hadoop-env.sh \ --from-file=artifacts/hadoop/log4j.properties \ --from-file=artifacts/hadoop/nodemanager_exclude.txt \ --from-file=artifacts/hadoop/yarn-env.sh kubectl create configmap spark-config \ --from-file=artifacts/spark/spark-bootstrap.sh \ --from-file=artifacts/spark/spark-env.sh \ --from-file=artifacts/spark/spark-defaults.conf

所有的配置完成后,可以可以使用 kubectl 命令來啟動和管理集群了,我們編寫了 Makefile,您可以直接使用該 Makefile 封裝的命令實現部分的自動化。

 參考:

https://www.kubernetes.org.cn/2568.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM