教程云原生容器编排【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址https://gitcode.com/gh_mirrors/ku/kubernetes-handbook点击查看免费下载本文是 Kubernetes Handbook 中面向存量应用迁移的实战指南以 Spark on YARN with Kubernetes 这一典型复杂分布式应用为样本完整拆解将传统应用迁移到 Kubernetes 的六个核心步骤服务拆解、镜像制作、配置准备、StatefulSet 编排、Bootstrap 启动脚本与 ConfigMap 配置注入。读完本文你将掌握一套可复制的传统应用上 K8s方法论并理解为何 NodeManager 这类依赖主机名注册的服务必须选用 Headless Service 与 StatefulSet。注意本文讲解的是如何将已有应用迁移到 Kubernetes而不是如何在 Kubernetes 中从零开发和部署应用。若你需要直接开发新应用并在 Kubernetes 中运行请参考 适用于 Kubernetes 的应用开发部署流程。迁移过程并不是简单的打包镜像、写个 YAML就能完成的。下图展示了将单体应用迁移到云原生架构的整体演进路径从单体Monolith逐步拆分为可独立部署的服务再走向容器化与云原生架构。对于符合云原生应用规范如 12 因素法则的应用迁移会相对顺利而传统分布式应用如 Hadoop YARN则往往会遇到服务发现、配置管理、有状态编排等一系列阻碍需要按步骤谨慎处理。迁移概览Spark on YARN with Kubernetes 的整体架构本文选择Spark on YARN with Kubernetes作为迁移样本该例子足够复杂也很有典型性——它同时包含资源管理YARN、计算框架Spark、多角色进程ResourceManager / NodeManager / Client、有状态注册机制主机名发现等多重挑战。理解这个例子后可以帮助你将绝大多数应用迁移到 Kubernetes 集群上。上图为整个架构的示意图所有的进程管理和容器扩容直接使用 Makefile 完成即通过 Makefile 封装 kubectl 命令来实现集群的启停与扩缩容。所有操作均通过命令手动完成不使用自动化工具——当充分了解细节后可以通过自动化工具如 Helm、Kustomize、Operator优化该过程使其更自动、更高效同时减少因人为操作失误导致的迁移失败。注意该例子仅用来说明具体的步骤划分和复杂性在生产环境应用还有待验证请谨慎使用。迁移前必知关键术语与概念对于未曾接触过 Kubernetes 或对云平台技术细节不太了解的人来说将应用迁移到 Kubernetes 中可能是个棘手的问题。在行动之前有必要先了解整个过程中会用到哪些概念和术语这有助于团队在行动中达成共识。整个迁移过程中可能用到的核心概念包括PodKubernetes 调度的最小单元是容器一个或多个的载体Service为 Pod 提供稳定的访问入口和负载均衡其中clusterIP: None的 Headless Service 不提供 Cluster IP只用于 DNS 解析是有状态应用的基础StatefulSet为 Pod 提供唯一、稳定的网络标识PodName 与 HostName 保持不变和有序部署/缩容的控制器详见 StatefulSet 概念ConfigMap将配置从镜像中解耦以键值对或文件方式向 Pod 注入配置详见 ConfigMap 概念Namespace资源隔离与逻辑分组Ingress将集群内部服务暴露到集群外部访问VolumePod 中的数据持久化与配置挂载Liveness/Readiness Probe健康检查与就绪判断是 StatefulSet 有序部署的前置条件。迁移六步法从拆解到运行整个迁移过程分为如下六个步骤可以对照下面的分解步骤解析图逐步推进将原有应用拆解为服务制作镜像准备应用的配置文件编写 Kubernetes YAML 文件编写 Bootstrap 启动脚本使用 ConfigMap 管理配置第一步将原有应用拆解为服务我们不是一上来就开始做镜像、写配置而是应该先梳理要迁移的应用中有哪些可以作为服务运行哪些是变的部分、哪些是不变的部分。服务划分的原则是最小可变原则——这个原则同样适用于镜像制作将服务中不变的部分编译到同一个镜像中把易变的部分配置、启动参数放到镜像外部通过 ConfigMap/环境变量注入从而避免每改一次配置就重做一个镜像。对于 Spark on YARN 这样复杂的应用可以将其划分为三大类服务ResourceManagerYARN 的资源管理与调度主节点NodeManagerYARN 的节点代理负责容器执行与资源上报Spark client提交作业的客户端第二步制作镜像根据拆解出来的服务需要制作两个镜像Hadoop基础镜像包含 YARN 全部运行时SparkFROM hadoop docker image在 Hadoop 镜像之上叠加 Spark 发行版因为我们运行的是 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_VERSION2.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对 Dockerfile 的要点说明使用ARG HADOOP_VERSION2.6.0-cdh5.5.2将 Hadoop 版本参数化便于构建时通过--build-arg覆盖通过ENV统一设置HADOOP_PREFIX等 8 个环境变量并加入PATH确保容器内任意路径可直接执行hadoop、yarn命令RUN中通过软链接ln -s ./hadoop-${HADOOP_VERSION} hadoop将带版本号的目录固定为/usr/local/hadoop并清理日志目录保证镜像可复用EXPOSE声明的端口按功能分组HDFS50010/50020/50070/50075/50090/8020/9000、MapReduce JobHistory19888、YARN8030–8033 为 RM 相关端口8040/8042 为 NM 端口8088 为 RM Web UI以及 49707、2122 等其他端口。EXPOSE仅起文档声明作用真正暴露方式由 Kubernetes Service/Ingress 决定。第三步准备应用的配置文件因为只制作了一个 Hadoop 镜像却需要启动两个服务ResourceManager 与 NodeManager这就要求在服务启动时必须加载不同的配置文件。此时只需准备两个服务共用的配置部分角色差异的部分留给 Bootstrap 脚本在启动时动态修改。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也包含在该目录下下文第五步详述。目录中既有静态配置core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml、capacity-scheduler.xml等也有两个服务各自的启动脚本start-yarn-rm.sh、start-yarn-nm.sh与节点列表slaves、nodemanager_exclude.txt。第四步编写 Kubernetes YAML 文件根据业务的特性选择最适合的 Kubernetes 资源对象来运行。因为在 YARN 中 NodeManager 需要使用主机名向 ResourceManager 注册所以需要沿用 YARN 原有的服务发现方式使用 Headless Service 与 StatefulSet 资源。更多资料请参考 StatefulSet 详解。为什么必须用 StatefulSet从 concepts/statefulset.md 可知StatefulSet 为 Pod 提供唯一、稳定的网络标识Pod 的主机名格式为$(statefulset名称)-$(序数)如web-0、web-1且 StatefulSet 中每个 Pod 的 DNS 格式为statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local。YARN 的 NodeManager 依赖这种稳定、可预测的主机名向 ResourceManager 注册而普通 Deployment/ReplicaSet 生成的随机 Pod 名无法满足这一需求。StatefulSet 的适用场景正是稳定唯一的网络标识 有序部署/缩容与 YARN 的需求高度吻合如果应用不需要稳定标识则应使用 Deployment 或 ReplicaSet 这类无状态控制器。所有 Kubernetes YAML 配置文件存储在manifest目录下包括如下配置yarn-cluster的 namespace 配置Spark、ResourceManager、NodeManager 的 headless service 和 statefulset 配置需要暴露到 Kubernetes 集群外部的 ingress 配置ResourceManager 的 Webkube-yarn-ingress.yaml spark-statefulset.yaml yarn-cluster-namespace.yaml yarn-nm-statefulset.yaml yarn-rm-statefulset.yaml仓库的 manifests/spark-standalone 目录提供了一套同主题的可对照样例Spark standalone 模式而非 YARN 模式其中 spark-master-controller.yaml 与 spark-worker-controller.yaml 展示了如何使用 ReplicationController 以component: spark-master/component: spark-worker标签划分角色、通过command: [/start-master]/command: [/start-worker]指定容器启动命令、并声明resources.requests.cpu资源请求的写法。注意standalone 模式下 Master 通过 Service DNSspark-master被发现无需主机名注册因此可以用无状态控制器而 YARN 模式因 NodeManager 依赖主机名注册必须使用 StatefulSet Headless Service——这正是按业务特性选择资源对象的最好例证。第五步编写 Bootstrap 启动脚本Bootstrap 脚本的作用是在启动时根据 Pod 的环境变量、主机名或其他可以区分不同 Pod 和启动角色的变量来修改配置文件并启动对应服务。该脚本同时将原来 YARN 的日志使用 stdout 输出便于使用kubectl logs查看日志或接入其他日志收集工具如 EFK、Promtail 等进行日志采集。启动脚本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 nameyarn.nodemanager.resource.memory-mb/name value${MY_MEM_LIMIT:-2048}/value /property property nameyarn.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 nameyarn.nodemanager.resource.memory-mb/name value${MY_MEM_LIMIT:-2048}/value /property property nameyarn.nodemanager.resource.cpu-vcores/name value${MY_CPU_LIMIT:-2}/value /property这里的实现细节值得展开主机名驱动的角色判断由于 StatefulSet 的 Pod 主机名形如yarn-nm-0、yarn-nm-1、yarn-rm-0脚本用正则${HOSTNAME} ~ yarn-nm即可区分 NodeManager 与 ResourceManager 两类 Pod无需额外维护角色清单动态注入资源参数MY_MEM_LIMIT和MY_CPU_LIMIT是 Kubernetes YAML 中定义的环境变量该环境变量又引用容器 spec 中的 resource limit。脚本通过sed删除yarn-site.xml末尾的/configuration追加 property 后再补回闭合标签实现配置文件的安全追加参数默认值兜底${MY_MEM_LIMIT:-2048}与${MY_CPU_LIMIT:-2}使用 Bash 默认值语法即使环境变量未注入也能以 2048MB / 2 vcore 启动保证脚本可独立于 Kubernetes 运行调试启动与前台化追加配置后将start-yarn-nm.sh拷贝到$HADOOP_PREFIX/sbin/并赋执行权限后执行启动 NodeManager如果 Kubernetes YAML 中 container 的 CMD args 包含-d则脚本等待日志文件生成后用tail -F将 NodeManager 日志实时输出到标准输出并以while true; do sleep 1000; done保持前台进程存活——这样容器不会退出且kubectl logs可直接看到 YARN 日志。第六步使用 ConfigMap 管理配置将 Hadoop 的配置文件和 bootstrap 脚本作为 ConfigMap 资源保存用作 Pod 启动时挂载的 volume。kubectl create configmap hadoop-config \ --from-fileartifacts/hadoop/bootstrap.sh \ --from-fileartifacts/hadoop/start-yarn-rm.sh \ --from-fileartifacts/hadoop/start-yarn-nm.sh \ --from-fileartifacts/hadoop/slaves \ --from-fileartifacts/hadoop/core-site.xml \ --from-fileartifacts/hadoop/hdfs-site.xml \ --from-fileartifacts/hadoop/mapred-site.xml \ --from-fileartifacts/hadoop/yarn-site.xml \ --from-fileartifacts/hadoop/capacity-scheduler.xml \ --from-fileartifacts/hadoop/container-executor.cfg \ --from-fileartifacts/hadoop/hadoop-env.sh \ --from-fileartifacts/hadoop/log4j.properties \ --from-fileartifacts/hadoop/nodemanager_exclude.txt \ --from-fileartifacts/hadoop/yarn-env.sh kubectl create configmap spark-config \ --from-fileartifacts/spark/spark-bootstrap.sh \ --from-fileartifacts/spark/spark-env.sh \ --from-fileartifacts/spark/spark-defaults.conf关于 ConfigMap 的使用要点详见 ConfigMap 详解--from-file以文件名作为键、文件内容作为值创建键值对多个文件可以一次性注入同一个 ConfigMapConfigMap 的用途是把配置信息与 Docker 镜像解耦——总不能每修改一个配置就重做一个镜像吧这正是第二步镜像中不写 Entrypoint/CMD设计的前置条件ConfigMap 中的配置在 Pod 中以数据卷挂载成文件每个 data 项成为一个新文件Bootstrap 脚本便可以从挂载路径读取配置、按角色动态改写。启动与管理集群所有配置完成后就可以使用 kubectl 命令启动和管理集群了。仓库还编写了 Makefile可以直接使用该 Makefile 封装的命令实现部分自动化例如构建镜像、创建 ConfigMap、下发 StatefulSet、查看日志等。可对照参考 manifests/spark-standalone/README.md 中的完整操作流程创建 namespace → 启动 master → 创建 headless service → 启动 worker → 通过 UI 验证集群就绪。迁移要点总结先拆解、后动手按最小可变原则划分服务与镜像边界变的部分配置、参数、启动命令留在镜像外不变的部分编译进镜像选择匹配的资源对象依赖主机名/网络身份注册的应用如 YARN NodeManager、ZooKeeper、Kafka优先使用 Headless Service StatefulSet 获得稳定标识与有序编排无状态应用则使用 Deployment/ReplicaSet用启动脚本桥接镜像不变与角色不同Bootstrap 脚本依据主机名或环境变量动态改写配置文件并启动对应角色同时将应用日志重定向到 stdout与kubectl logs及日志采集链路无缝对接配置全量进 ConfigMap配置文件与启动脚本统一以 ConfigMap 管理既保证镜像可复用又使配置变更可审计、可回滚逐步自动化手工验证流程细节后再用 Makefile、Helm、Operator 等工具将上述步骤自动化降低人为失误。将传统分布式应用迁移到 Kubernetes本质上是把进程管理模式翻译为声明式资源编排模式的过程。以 Spark on YARN 为样本的六步法覆盖了服务拆解、镜像构建、配置外置、有状态编排、角色化启动与配置注入的全部关键环节可复用于绝大多数存量应用的容器化改造。赞分享教程云原生容器编排【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址https://gitcode.com/gh_mirrors/ku/kubernetes-handbook点击查看免费下载相关推荐Bazel 从 Maven 迁移指南以 Guava 项目为例的完整实战教程Bazel 从 Maven 迁移指南以 Guava 项目为例的完整实战教程 本指南基于 Bazel 官方文档 docs/migrate/maven.mdx构建工具Data Engineering Zoomcamp 实战在 Hadoop YARN 上以伪分布式模式运行 Spark 集群Data Engineering Zoomcamp 实战在 Hadoop YARN 上以伪分布式模式运行 Spark 集群 本篇指南是 Data Engine教程数据工程TensorFlow.js Op 模块化改造完整指南以 SquaredDifference 为例的 Kernel/Gradient 迁移实战TensorFlow.js Op 模块化改造完整指南以 SquaredDifference 为例的 Kernel/Gradient 迁移实战 本文基于 tfj人工智能机器学习深度学习前端后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
