前言
其实 akka 官网文档有很详细的介绍和说明,如何把 akka 集群一步一步,部署到 k8s 上,然后自动实现节点的管理。 但是全网并没有中文版的完整翻译,本篇博客算是一个比较全的介绍了。
第一步,添加依赖
akka 的官网有针对scala + sbt + gradle编译的,也有 java + maven 编译的,我们这里介绍的是 java 和 maven的,其实官网有一一对照的写法。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>akkademo</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <scala.version>2.6.17</scala.version> <scala.binary.version>2.13</scala.binary.version> <akka.management.version>1.1.3</akka.management.version> <version.number>v1</version.number> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-bom_${scala.binary.version}</artifactId> <version>${scala.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- 这里是 akka 集群的基本依赖--> <dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-cluster-typed_${scala.binary.version}</artifactId> </dependency> <dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-actor_${scala.binary.version}</artifactId> </dependency> <!-- 这里是添加k8s节点自动发现管理的依赖 --> <dependency> <groupId>com.lightbend.akka.management</groupId> <artifactId>akka-management-cluster-http_${scala.binary.version}</artifactId> <version>${akka.management.version}</version> </dependency> <dependency> <groupId>com.lightbend.akka.management</groupId> <artifactId>akka-management-cluster-bootstrap_${scala.binary.version}</artifactId> <version>${akka.management.version}</version> </dependency> <dependency> <groupId>com.lightbend.akka.discovery</groupId> <artifactId>akka-discovery-kubernetes-api_${scala.binary.version}</artifactId> <version>${akka.management.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.0-alpha1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>2.0.0-alpha1</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.conf</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> <include>**/*.conf</include> </includes> <filtering>false</filtering> </resource> </resources> <plugins> <!-- 这个插件是自动将项目打包成docker镜像的, 执行 mvn package 后就能编译打包了 --> <plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.34.1</version> <configuration> <images> <image> <name>%a</name> <build> <from>adoptopenjdk:11-jre-hotspot</from> <tags> <tag>latest</tag> <tag>${version.number}</tag> </tags> <entryPoint> java -cp '/maven/*' singleton.Main </entryPoint> <assembly> <descriptorRef>artifact-with-dependencies</descriptorRef> </assembly> </build> </image> </images> </configuration> <executions> <execution> <id>build-docker-image</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
第二步,配置application.conf,这是akka的配置文件
akka { loglevel = "DEBUG" actor.provider = cluster coordinated-shutdown.exit-jvm = on cluster { shutdown-after-unsuccessful-join-seed-nodes = 60s } } #management-config akka.management { cluster.bootstrap { contact-point-discovery { # 这是你service akka system名称 service-name = "akkademo" discovery-method = kubernetes-api required-contact-point-nr = 2 } } }
第三步,启动management和bootstrap自动发现
//在你的root actor,或者main方法启动的时候调用 ActorSystem<Void> system = context.getSystem(); final akka.actor.ActorSystem classicSystem = Adapter.toClassic(context.getSystem()); AkkaManagement.get(classicSystem).start(); ClusterBootstrap.get(classicSystem).start();
第四步,配置你的k8s yaml文件
#你需要改你自己的app名称,我的是akkademo,命名空间是pge apiVersion: apps/v1 kind: Deployment metadata: labels: app: akkademo name: akkademo namespace: pge spec: replicas: 3 selector: matchLabels: app: akkademo template: metadata: labels: app: akkademo actorSystemName: akkademo spec: containers: - name: akkademo image: akkademo:latest # minikube的话,本地镜像可以用下面这个配置 imagePullPolicy: Never readinessProbe: httpGet: path: /ready port: management periodSeconds: 10 failureThreshold: 3 initialDelaySeconds: 10 livenessProbe: httpGet: path: "/alive" port: management periodSeconds: 10 failureThreshold: 5 initialDelaySeconds: 20 ports: - name: management containerPort: 8558 protocol: TCP - name: http containerPort: 8080 protocol: TCP env: - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: REQUIRED_CONTACT_POINT_NR value: "3" --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: pod-reader namespace: pge rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: read-pods namespace: pge subjects: - kind: User name: system:serviceaccount:pge:default roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io
部署
mvn clean mvn package kubectl apply -f yourYaml.xml