Akka 集群如何部署到 k8s 中,实现自动发现管理节点

前言

其实 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

 

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

Scroll to Top