akka-Cluster:k8s部署
背景:在 Spring Boot
中整合akka集群。现在需要将其部署在k8s中。
以下仅是一个节点的配置过程。若存在多个节点,则需要配置多次。
假设当前项目为3个akka节点。则在kubernetes中结构为:
代码层面:
- 嵌入 启动
management
和bootstrap
自动发现代码- 可在配置类中(
@configuration
)ActorSystem.create
创建actorSystem
- 再使用
@Resource
注入;
- 可在配置类中(
public void init(){AkkaManagement.get(actorSystem).start();ClusterBootstrap.get(actorSystem).start();}
- 健康检查类:
- 注意: 在后续的 conf配置时,需要配置该全限定类名。
public class MyhealthCheck implements Supplier<CompletionStage<Boolean>> {private final Cluster cluster;public ClusterCheck(ActorSystem system) {cluster = Cluster.get(system);}@Overridepublic CompletionStage<Boolean> get() {return CompletableFuture.completedFuture(cluster.selfMember().status() == MemberStatus.up());}
}
kubernetes.yaml 配置
apiVersion: apps/v1 #必选,版本号,例如v1
kind: Deployment #必选,Pod
metadata: #必选,元数据labels: #自定义标签app: appka-testname: appka-testnamespace: appka-1
spec: #必选,Pod中容器的详细定义replicas: 1selector:matchLabels:app: appka-testtemplate:metadata: # 资源的元数据/属性labels: # 设定资源的标签app: appka-testactorSystemName: appka-testspec:containers: #必选,Pod中容器列表- name: appka-test # 容器的名字image: appka-test-k8s:latest # 容器使用的镜像地址readinessProbe: # Pod 准备服务健康检查设置httpGet: # 通过httpget检查健康,返回200-399之间,则认为容器正常path: "/ready"port: managementperiodSeconds: 10 # 检查间隔时间failureThreshold: 3 # 失败门槛,连接失败5次,pod杀掉,重启一个新的podinitialDelaySeconds: 10 # 表明第一次检测在容器启动后多长时间后开始livenessProbe: # pod 内部健康检查的设置httpGet:path: "/alive"port: managementperiodSeconds: 10failureThreshold: 5initialDelaySeconds: 20ports: #需要暴露的端口库号列表# akka remoting- name: remotingcontainerPort: 2552 #容器需要监听的端口号protocol: TCP #端口协议,支持TCP和UDP,默认TCP# akka-management and bootstrap- name: managementcontainerPort: 8558protocol: TCP- name: httpcontainerPort: 8080protocol: TCPenv: #容器运行前需设置的环境变量列表- name: NAMESPACE #环境变量名称valueFrom:fieldRef:fieldPath: metadata.namespace- name: REQUIRED_CONTACT_POINT_NRvalue: "2"---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: pod-readernamespace: appka-1
rules:- apiGroups: [""] # "" indicates the core API groupresources: ["pods"]verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: read-podsnamespace: appka-1
subjects:# serviceAccount是用于控制对Kubernetes API的访问的一种身份验证机制。# 每个命名空间默认有一个名为default的服务账号,当你不指定服务账号时,Kubernetes会默认使用这个账号。# 这种指定方式有助于明确哪些资源可以访问,从而提高系统的安全性。# 在某些情况下,可能需要创建和使用自定义的服务账号,以便更好地控制资源的访问。- kind: Username: system:serviceaccount:appka-1:default
roleRef:kind: Rolename: pod-readerapiGroup: rbac.authorization.k8s.io
tips:
appka-test
需要适配自己的项目名appka-1
命名空间 namespace 需要自己适配containers.image
容器镜像:需要项目自定义部署subjects.name
: 服务账号;其中 appka-1 是命名空间。若需自定义,需要注意!kind: Role
角色配置次数选择官网默认。
- kubernetes 快速入门:K8S系列一:概念入门 - 知乎
- K8S系列二:实战入门 - 知乎
- K8S系列三:单服务部署 - 知乎
- K8S系列四:服务管理 - 知乎
akka conf
文件配置
coordinated-shutdown.exit-jvm = on
- 当集群节点看到自己处于 Exit 状态时,
CoordinatedShutdown
自动运行,将所有组件和资源关闭,包括终止JVM进程。
- 当集群节点看到自己处于 Exit 状态时,
allow-java-serialization
: 设置 允许使用Java序列化来序列化和反序列化Akka的消息- cluster集群配置:
akka.actor.provider = "cluster"
设置akka集群模式shutdown-after-unsuccessful-join-seed-nodes
- 种子节点无法成功加入的最大 时间
- 脑裂配置
contact-point-discovery
节点 发现配置- k8s服务发现的名称:需要自定义
- k8s发现方式:本项目采用
kubernetes-api
- Akka组成集群最少节点数
- health-checks 健康就绪检查
akka {loglevel = "DEBUG"coordinated-shutdown.exit-jvm = onactor {allow-java-serialization = onprovider = "cluster"}cluster {shutdown-after-unsuccessful-join-seed-nodes = 60sdowning-provider-class = "akka.cluster.sbr.SplitBrainResolverProvider"}}akka.management {cluster.bootstrap {contact-point-discovery {// ; k8s 服务发现的名称, 自定义service-name = "%s"discovery-method = kubernetes-apirequired-contact-point-nr = 2// ; akka组成集群最少节点数required-contact-point-nr = ${?REQUIRED_CONTACT_POINT_NR}}}}akka.management {health-checks {readiness-checks {// ; 健康探测的类example-ready = "com.src.akka.check.MyhealthCheck"}}}
Akka Management HTTP
Akka Management HTTP 的默认配置适合在 Kubernetes 中使用,它将绑定到 Pod 外部 IP 地址上的默认端口 8558。
配置完成后,需要对不同的节点打jar包,创建对应的docker镜像,进而部署至不同的pod中。
下面是后续需要考虑的问题。(皆来自官网)
其他存在的问题
配置后 akka-cluster在k8s还可能存在其他问题:
-
集群节点发现方式若两者其中有一个挂掉(如:a挂掉),a重新加入集群后,是否产生新的集群?
-
Akka Cluster Bootstrap
-
-
-
【脑裂】akka cluster split-brain-resolver(SBR)_lease-majority-CSDN博客
-
k8s 不同的pod ip不一样。若其中一个节点挂掉,重启pod会改变ip,但akka 集群会继续连接该ip
-
解决方式:配置相关策略
- Akka集群脑裂_akka脑裂-CSDN博客
-
主要参考官网的部署步骤:
Deploying Akka Cluster to Kubernetes
学习文章:
Akka 集群如何部署到 k8s 中,实现自动发现管理节点 – 墨烟客 – 不只是代码,更是文学