精彩文章免费看

【k8s学习】在Kubernetes上部署Hazelcast集群(embedded模式)

【本文目标】
将Hazelcast部署到k8s上,并且两个Pod间能组成Hazelcast集群。

官网:Get Started with Embedded Hazelcast on Kubernetes: https://docs.hazelcast.com/tutorials/kubernetes-embedded

准备一个项目,Hazelcast与Spring Boot集成,部署到kubernetes上需要在hazelcast.yaml中开启flag。
可参考我之前的文章: 【Hazelcast学习】入门篇,以及和Spring Boot集成 通过DockerFile build image
可参考我之前的文章: 【Docker学习】布署Spring Boot项目到docker中 push到docker hub上
可参考我之前的文章: 【k8s学习】布署Spring Boot项目到minikube上
  • Kubernetes相关:配置RBAC
  • 将项目部署至minikube中
    关于minikube安装,可参考之前的文章: 【k8s学习】minikube、kubectl、yaml配置文件的介绍

    1. 创建本地项目

    首先准备一个Hazelcast项目:
  • spring-boot-starter-web(version用的是2.5.7,还需要加上spring-boot parent)
  • hazelcast(version用的是5.1.1)
  • hazelcast-spring(version用的是5.1.1)
  • 另外别忘了加上build plugin:spring-boot-maven-plugin,这个可以将Spring Boot打包成fat jar(即可以使用java -jar运行)

    在resources.xml中加上hazelcast.yaml文件:

    hazelcast:
      network:
        join:
          multicast:
            enabled: false
          kubernetes:
            enabled: true
    

    写了几个API:

    @RestController
    public class HazelcastController {
        @Autowired
        private HazelcastInstance hazelcastInstance;
        @GetMapping("version")
        public String version() {
            return "hazelcast k8s test v1";
        @GetMapping("put")
        public boolean put(@RequestParam String key, @RequestParam String value) {
            IMap<String, String> map = hazelcastInstance.getMap("testMap");
            map.put(key, value);
            return true;
        @GetMapping("get")
        public String getValue(@RequestParam String key) {
            IMap<String, String> map = hazelcastInstance.getMap("testMap");
            return map.get(key);
        @GetMapping("size")
        public int getSize() {
            IMap<String, String> map = hazelcastInstance.getMap("testMap");
            return map.size();
    

    使用mvn clean package命令,将项目打包下。

    2. 添加DockerFile文件

    我用的是8090端口,在application.yaml中定义好的,如果不定义,默认是8080端口:

    FROM openjdk:8-jdk-alpine
    COPY target/SpringBootHazelcastK8s.jar hazelcastK8s.jar
    expose 8090
    ENTRYPOINT ["java","-jar","hazelcastK8s.jar"]
    

    打开命令行工具,跳到DockerFile所在的目录(我直接在idea terminal中运行的),运行:

    docker build -f DockerFile -t hazelcast-k8s .

    4. Kubernetes相关:配置RBAC

    RBAC全称叫:Role-based access control,即权限相关的配置。

    Hazelcast官网已经为我们准备了一个在线yaml,ServiceAccount=defult,namespace同样为default,如果需要自定义,那么下载rbac.yaml文件自行改之:

    kubectl apply -f https://raw.githubusercontent.com/hazelcast/hazelcast-kubernetes/master/rbac.yaml

    6. 测试

    创建一个类型为ClusterIP的service,自身的端口为8080,targetPort为8090(targetPort的意思是指向的Pod中的containerPort为多少,我们项目定义的为8090):

    kubectl create service clusterip hazelcast-k8s --tcp=8080:8090

    可以看到创建好了:
  • 要么通过另外创建组件Ingress进行访问
  • 要么将上述的service改为type为LoadBalancer的service
  • 要么通过下面的命令进行转发,这样才可以从我们本机的localhost进行访问:
  • kubectl port-forward service/hazelcast-k8s 8080:8080

    测试API:
    a) /version:

    那么两个Pod间是怎么自动发现的呢?

    从官网上来看,主要是通过插件——Hazelcast Kubernetes discovery plugin

    这个插件会调用Kubernetes API来自动发现成员。所以才需要【第4章】中的Role-based access control的相关配置。

    查看2个Pod的IP:

    kubectl get pod -o wide

    8. 为Hazelcast之间的通信加上Service:

    【更好的做法是我们可以为Hazelcast的5701也定义Service,这样在项目中可以写上service name,在Pod间的通信,可以通过Service转发】

    在项目中配置:

    hazelcast:
      network:
        join:
          multicast:
            enabled: false
          kubernetes:
            enabled: true
            namespace: default
            service-name: hazelcast-service
    

    重新docker push后,再重新创建deployment。

    创建新的Service,可以看到port为5701,为hazelcast通信时使用:

    apiVersion: v1
    kind: Service
    metadata:
      name: hazelcast-service
    spec:
      type: LoadBalancer
      selector:
        app: hazelcast-k8s
      ports:
      - name: hazelcast
        port: 5701
    

    启动后,查看service:
    可以看到Endpoint指向的是两个Pod,端口为5701:

    kubectl describe service hazelcast-service