ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

在 Kubernetes 上部署云原生 Hazelcast 集群:基于 Service 发现与 Deployment 弹性伸缩的完整实践

在 Kubernetes 上部署云原生 Hazelcast 集群:基于 Service 发现与 Deployment 弹性伸缩的完整实践 示例工程【免费下载链接】examplesKubernetes application example tutorials项目地址https://gitcode.com/gh_mirrors/examp/examples点击查看免费下载本文以当前 Kubernetes Examples 仓库中 Hazelcast 云原生部署指南 为主体完整讲解如何通过一个自定义 Hazelcast bootstrapper 在 Kubernetes 上动态发现集群成员并利用 Service 与 Deployment 两大核心原语搭建可弹性伸缩的 Hazelcast 集群。读完本文你将掌握 Pod、Service、Deployment 三者之间的协作关系能够从零创建并扩容一个多节点 Hazelcast 集群并通过日志实证验证成员自动发现与拓扑收敛的全过程。什么是云原生 Hazelcast 部署云原生cloud native在这里指应用自身清楚自己运行在集群管理器Kubernetes之中并主动利用集群管理基础设施来辅助实现应用本身。具体到本示例Hazelcast 节点通过一个自定义的 bootstrapper 启动bootstrapper 借助 Kubernetes API 动态发现已经加入集群的其他 Hazelcast 节点而不是依赖静态配置的 IP 列表或手工组网。任何集群拓扑变化节点加入、退出、扩容、缩容都由 Hazelcast 节点之间自行通信与协调无需人工干预。这正是 Hazelcast 与 Kubernetes 结合后最核心的价值Hazelcast 集群成员与 Kubernetes Pod 生命周期解耦节点增减完全由编排层驱动成员关系由 Hazelcast 内部协议收敛。本示例还顺带承担了教学任务帮助读者理解 Kubernetes 的三个核心组件——Pod、Service、Deployment——它们在本例中如何协作。前置条件本示例假设你满足以下条件已安装并运行一个 Kubernetes 集群minikube、本地集群或云端集群均可kubectl命令行工具已安装并位于 PATH 中集群的 DNS 配置可正常使用因为发现机制依赖 Kubernetes API 与 DNS。三个核心概念Pod、Service 与 Deployment在深入配置之前先厘清本例涉及的三个 Kubernetes 核心概念概念在本例中的作用Pod应用的原子调度单元一个或多个容器必须调度到同一宿主机共享网络命名空间可选共享挂载卷Service描述执行同一任务的一组 Pod 的集合既可作为负载均衡器分发流量也可作为常驻查询通过 Kubernetes API 暴露动态变化的 Pod 集合Deployment负责复制一组完全相同的 Pod包含选择器查询与期望副本数会创建或删除 Pod 以逼近期望状态本示例刻意没有先跑一个单 Pod Hazelcast 节点因为发现机制本身依赖 Service 定义——Pod 必须首先通过 Service 暴露出来后续节点才能看到它。第一步定义 Hazelcast Service在 Kubernetes 中Service 描述一组执行相同任务的 Pod。例如Hazelcast 集群中的节点集合。Service 的一个重要用途是创建跨集合成员的负载均衡器但本例更关键的用法是Service 作为一个常驻查询通过 Kubernetes API 把动态变化的 Pod 集合暴露出来——这正是发现机制的工作基础。仓库中的 hazelcast-service.yaml 内容如下apiVersion: v1 kind: Service metadata: labels: name: hazelcast name: hazelcast spec: ports: - port: 5701 selector: name: hazelcast最值得注意的部分是spec.selector。它是一组对标签labels的查询用于识别被该 Service 收录的 Pod 集合。此处选择器是name: hazelcast对照下文 Deployment 的 Pod 模板可以看到Pod 携带了同名标签name: hazelcast因此会被选中成为该 Service 的成员。端口方面Service 暴露 5701 端口——这是 Hazelcast 节点间通信的默认端口无需指定targetPort时流量会被转发到 Pod 的 5701 端口。创建该 Servicekubectl create -f _archived/storage/hazelcast/hazelcast-service.yaml第二步创建 Deployment 承载 Hazelcast 节点Kubernetes 与 Hazelcast 结合的真正威力在于可以轻松构建一个可复制、可调整规模的 Hazelcast 集群。Deployment 负责复制一组完全相同的 Pod。与 Service 一样它也有一个选择器查询来识别集合成员与 Service 不同的是它还有期望副本数replicas并通过创建或删除 Pod 来确保当前 Pod 数量与期望状态一致。Deployment 还会收养adopt与其选择器匹配的既有 Pod所以下面我们创建一个单副本 Deployment让它收养我们即将创建的 Hazelcast Pod。仓库中的 hazelcast-deployment.yaml 内容如下apiVersion: apps/v1 # for k8s versions before 1.9.0 use apps/v1beta2 and before 1.8.0 use extensions/v1beta1 kind: Deployment metadata: name: hazelcast labels: name: hazelcast spec: selector: matchLabels: name: hazelcast template: metadata: labels: name: hazelcast spec: containers: - name: hazelcast image: quay.io/pires/hazelcast-kubernetes:3.8_1 imagePullPolicy: Always env: - name: DNS_DOMAIN value: cluster.local - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace ports: - name: hazelcast containerPort: 5701逐项解读这份清单apiVersionapps/v1适用于较新的 Kubernetes 版本注释明确说明1.9.0 之前的版本需改用apps/v1beta21.8.0 之前则需使用extensions/v1beta1。使用旧版本集群时请按此调整。selector / matchLabelsDeployment 的选择器查询与 Pod 模板中的标签name: hazelcast对应用于识别它所管理的 Pod。templatePod 模板即创建新 Pod 时使用的配方。Deployment 清单的大部分内容与 Pod 声明相同多出的部分是选择器与期望副本数。imagequay.io/pires/hazelcast-kubernetes:3.8_1该镜像内含 Hazelcast 3.8 与自定义 bootstrapper。注意教程正文示例中镜像标签为0.8.0仓库实际清单文件已更新为3.8_1以实际文件为准。imagePullPolicy: Always始终拉取镜像确保节点总是运行最新推送的镜像内容。env.DNS_DOMAIN设置为cluster.local需按你集群的实际 DNS 配置调整Kubernetes 集群默认 DNS 域。env.POD_NAMESPACE通过fieldRef引用metadata.namespace将 Pod 所在命名空间注入环境变量bootstrapper 据此在正确的命名空间内查询 Service。ports声明容器暴露hazelcast端口containerPort 5701与 Service 的端口定义呼应。创建该 Deploymentkubectl create -f _archived/storage/hazelcast/hazelcast-deployment.yaml验证 Service 发现到 PodDeployment 成功创建 Pod 后可以查询 Service 的 endpoints确认 Service 与 Pod 已经建立关联kubectl get endpoints hazelcast -o yaml得到的输出类似以下为教程中的真实输出apiVersion: v1 kind: Endpoints metadata: creationTimestamp: 2017-03-15T09:40:11Z labels: name: hazelcast name: hazelcast namespace: default resourceVersion: 65060 selfLink: /api/v1/namespaces/default/endpoints/hazelcast uid: 62645b71-0963-11e7-b39c-080027985ce6 subsets: - addresses: - ip: 172.17.0.2 nodeName: minikube targetRef: kind: Pod name: hazelcast-4195412960-mgqtk namespace: default resourceVersion: 65058 uid: 7043708f-0963-11e7-b39c-080027985ce6 ports: - port: 5701 protocol: TCP可以看到Service 已经找到了由 Deployment 创建的 Podhazelcast-4195412960-mgqtkendpoint 指向其 Pod IP172.17.0.2的 5701 端口。弹性伸缩实战从 1 个副本扩到 2 个接下来体验最有趣的部分——把集群从 1 个节点扩展到 2 个节点kubectl scale deployment hazelcast --replicas 2列出当前 Deployment 与 Pod应该能看到两个 hazelcast Podkubectl get deployment,pods输出类似NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deploy/hazelcast 2 2 2 2 2m NAME READY STATUS RESTARTS AGE po/hazelcast-4195412960-0tl3w 1/1 Running 0 7s po/hazelcast-4195412960-mgqtk 1/1 Running 0 2m两个 Pod 都处于 Running 状态Deployment 的期望副本数、当前副本数与可用副本数均为 2。用日志证明集群成员自动发现为了证明整套机制真正生效使用kubectl logs观察新 Pod 的启动日志kubectl logs -f hazelcast-4195412960-0tl3w教程中记录的真实日志如下2017-03-15 09:42:45.046 INFO 7 --- [ main] com.github.pires.hazelcast.Application : Starting Application on hazelcast-4195412960-0tl3w with PID 7 (/bootstrapper.jar started by root in /) 2017-03-15 09:42:45.060 INFO 7 --- [ main] com.github.pires.hazelcast.Application : No active profile set, falling back to default profiles: default 2017-03-15 09:42:45.128 INFO 7 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext14514713: startup date [Wed Mar 15 09:42:45 GMT 2017]; root of context hierarchy 2017-03-15 09:42:45.989 INFO 7 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup 2017-03-15 09:42:46.001 INFO 7 --- [ main] c.g.p.h.HazelcastDiscoveryController : Asking k8s registry at https://kubernetes.default.svc.cluster.local.. 2017-03-15 09:42:46.376 INFO 7 --- [ main] c.g.p.h.HazelcastDiscoveryController : Found 2 pods running Hazelcast. 2017-03-15 09:42:46.458 INFO 7 --- [ main] c.h.instance.DefaultAddressPicker : [LOCAL] [someGroup] [3.8] Interfaces is disabled, trying to pick one address from TCP-IP config addresses: [172.17.0.6, 172.17.0.2] 2017-03-15 09:42:46.458 INFO 7 --- [ main] c.h.instance.DefaultAddressPicker : [LOCAL] [someGroup] [3.8] Prefer IPv4 stack is true. 2017-03-15 09:42:46.464 INFO 7 --- [ main] c.h.instance.DefaultAddressPicker : [LOCAL] [someGroup] [3.8] Picked [172.17.0.6]:5701, using socket ServerSocket[addr/0:0:0:0:0:0:0:0,localport5701], bind any local is true 2017-03-15 09:42:46.484 INFO 7 --- [ main] com.hazelcast.system : [172.17.0.6]:5701 [someGroup] [3.8] Hazelcast 3.8 (20170217 - d7998b4) starting at [172.17.0.6]:5701 2017-03-15 09:42:46.484 INFO 7 --- [ main] com.hazelcast.system : [172.17.0.6]:5701 [someGroup] [3.8] Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved. 2017-03-15 09:42:46.485 INFO 7 --- [ main] com.hazelcast.system : [172.17.0.6]:5701 [someGroup] [3.8] Configured Hazelcast Serialization version : 1 2017-03-15 09:42:46.679 INFO 7 --- [ main] c.h.s.i.o.impl.BackpressureRegulator : [172.17.0.6]:5701 [someGroup] [3.8] Backpressure is disabled 2017-03-15 09:42:47.069 INFO 7 --- [ main] com.hazelcast.instance.Node : [172.17.0.6]:5701 [someGroup] [3.8] Creating TcpIpJoiner 2017-03-15 09:42:47.182 INFO 7 --- [ main] c.h.s.i.o.impl.OperationExecutorImpl : [172.17.0.6]:5701 [someGroup] [3.8] Starting 2 partition threads 2017-03-15 09:42:47.189 INFO 7 --- [ main] c.h.s.i.o.impl.OperationExecutorImpl : [172.17.0.6]:5701 [someGroup] [3.8] Starting 3 generic threads (1 dedicated for priority tasks) 2017-03-15 09:42:47.197 INFO 7 --- [ main] com.hazelcast.core.LifecycleService : [172.17.0.6]:5701 [someGroup] [3.8] [172.17.0.6]:5701 is STARTING 2017-03-15 09:42:47.253 INFO 7 --- [cached.thread-3] c.hazelcast.nio.tcp.InitConnectionTask : [172.17.0.6]:5701 [someGroup] [3.8] Connecting to /172.17.0.2:5701, timeout: 0, bind-any: true 2017-03-15 09:42:47.262 INFO 7 --- [cached.thread-3] c.h.nio.tcp.TcpIpConnectionManager : [172.17.0.6]:5701 [someGroup] [3.8] Established socket connection between /172.17.0.6:58073 and /172.17.0.2:5701 2017-03-15 09:42:54.260 INFO 7 --- [ration.thread-0] com.hazelcast.system : [172.17.0.6]:5701 [someGroup] [3.8] Cluster version set to 3.8 2017-03-15 09:42:54.262 INFO 7 --- [ration.thread-0] c.h.internal.cluster.ClusterService : [172.17.0.6]:5701 [someGroup] [3.8] Members [2] { Member [172.17.0.2]:5701 - 170f6924-7888-442a-9875-ad4d25659a8a Member [172.17.0.6]:5701 - b1b82bfa-86c2-4931-af57-325c10c03b3b this } 2017-03-15 09:42:56.285 INFO 7 --- [ main] com.hazelcast.core.LifecycleService : [172.17.0.6]:5701 [someGroup] [3.8] [172.17.0.6]:5701 is STARTED 2017-03-15 09:42:56.287 INFO 7 --- [ main] com.github.pires.hazelcast.Application : Started Application in 11.831 seconds (JVM running for 12.219)这段日志完整揭示了发现机制的调用链值得逐条解读HazelcastDiscoveryController: Asking k8s registry at https://kubernetes.default.svc.cluster.local——bootstrapper 通过 Kubernetes 内置的 Service DNS 地址访问 Kubernetes API ServerFound 2 pods running Hazelcast——通过 Service 的常驻查询能力在集群中发现 2 个正在运行 Hazelcast 的 PodPicked [172.17.0.6]:5701与Connecting to /172.17.0.2:5701——新节点选定自己的地址并主动与既有节点建立 TCP 连接Established socket connection——两个节点间的 Hazelcast 通信通道建立成功Members [2]——集群拓扑收敛Hazelcast 内部协议完成成员列表同步新节点成功加入集群。继续扩容从 2 个节点到 4 个节点继续验证弹性能力把集群扩到 4 个节点kubectl scale deployment hazelcast --replicas 4再次检查任一节点的日志应当看到 4 个成员已互联类似(...) Members [4] { Member [172.17.0.2]:5701 - 170f6924-7888-442a-9875-ad4d25659a8a Member [172.17.0.6]:5701 - b1b82bfa-86c2-4931-af57-325c10c03b3b this Member [172.17.0.9]:5701 - 0c7530d3-1b5a-4f40-bd59-7187e43c1110 Member [172.17.0.10]:5701 - ad5c3000-7fd0-4ce7-8194-e9b1c2ed6dda }扩容后新增的两个节点无需任何手工配置即自动加入成员列表验证了任何拓扑变化都由 Hazelcast 节点自身通信处理的设计目标。仓库对清单的自动化校验当前仓库通过 examples_test.go 中的TestExampleObjectSchemas对这两个清单做自动化 schema 校验hazelcast-deployment按 Deployment 对象解析并校验hazelcast-service按 Service 对象解析并校验。测试会遍历仓库中的 YAML 清单将其解码为 Kubernetes API 对象并通过ValidateDeployment、ValidateService等校验函数检查任何不合法的清单都会导致测试失败。这从源码层面印证了本文展示的两份清单是符合 Kubernetes 资源规范、可被 API Server 接受的合法配置。tl;dr 快速上手对急于动手的读者本文全部核心命令汇总如下kubectl create -f _archived/storage/hazelcast/hazelcast-service.yaml kubectl create -f _archived/storage/hazelcast/hazelcast-deployment.yaml kubectl scale deployment hazelcast --replicas 2 kubectl scale deployment hazelcast --replicas 4执行顺序说明先创建 Service建立发现机制依赖的常驻查询再创建 Deployment承载节点 Pod最后通过scale命令验证弹性伸缩。排查问题时kubectl get endpoints hazelcast -o yaml用于确认 Service 与 Pod 的关联kubectl logs用于观察 bootstrapper 的发现日志与 Hazelcast 的成员收敛结果。补充说明镜像与版本仓库实际清单 hazelcast-deployment.yaml 使用quay.io/pires/hazelcast-kubernetes:3.8_1内置 Hazelcast 3.8 与 bootstrapper教程正文示例为0.8.0标签以仓库清单文件为准不同镜像标签对应不同的 Hazelcast 版本使用前请确认与你业务的兼容性。apiVersion 兼容apps/v1仅适用于较新的集群1.9.0 之前使用apps/v1beta21.8.0 之前使用extensions/v1beta1。环境变量DNS_DOMAIN需与集群 DNS 配置一致默认cluster.localPOD_NAMESPACE由fieldRef自动注入bootstrapper 据此在正确命名空间内查询发现目标。清理如需拆除示例可对上述两个清单执行kubectl delete -fDeployment 删除后其管理的 Pod 会被一并回收Service 的 endpoints 随即清空。示例归属本示例位于仓库 storage/hazelcast 目录归档区完整教程见 README.mdDiscovery 控制器源码由社区项目hazelcast-kubernetes-bootstrapper提供核心类是HazelcastDiscoveryController其职责正是本文日志中反复出现的向 Kubernetes API 查询 Hazelcast Pod环节。赞分享示例工程【免费下载链接】examplesKubernetes application example tutorials项目地址https://gitcode.com/gh_mirrors/examp/examples点击查看免费下载相关推荐GraphiQL云原生Kubernetes部署与弹性伸缩GraphiQL云原生Kubernetes部署与弹性伸缩 概述 GraphiQL作为GraphQL生态系统的官方IDE工具在现代Web开发中扮演着至关重要的开发工具后端Mooncake 在 Kubernetes 上的部署指南基于 Deployment 与 Service 搭建共享 Store 集群Mooncake 在 Kubernetes 上的部署指南基于 Deployment 与 Service 搭建共享 Store 集群 Mooncake Stor人工智能大模型模型推理服务后端Flink Standalone 模式在 Kubernetes 上的部署实战Session / Application 集群、Kubernetes HA 与 Reactive 弹性伸缩Flink Standalone 模式在 Kubernetes 上的部署实战Session / Application 集群、Kubernetes HA 与后端大数据流处理批处理上一篇微信聊天记录永久保存终极指南5步掌握WeChatMsg完整数据留痕方案下一篇WindowResizer突破Windows窗口限制的专业级强制调整工具解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表