美文网首页
【k8s学习】在Kubernetes上部署Hazelcast集群

【k8s学习】在Kubernetes上部署Hazelcast集群

作者: 伊丽莎白2015 | 来源:发表于2022-06-28 23:17 被阅读0次

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

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


    【步骤】


    1. 创建本地项目

    首先准备一个Hazelcast项目: image.png

    pom.xml非常简单:
    三个artifactId:

    • 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 .

    image.png

    检查下,运行docker images,有了:

    docker images

    image.png

    3. 将hazelcast-k8s镜像推送至docker hub上

    docker tag:给我们本地的镜像加一个tag别名:

    docker tag hazelcast-k8s <docker username>/hazelcast-k8s

    push镜像:

    docker push <docker username>/hazelcast-k8s

    登陆docker hub查看,发现镜像已经有了: image.png

    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

    image.png

    查看资源类型为hazelcast-cluster-role

    image.png

    查看资源类型为hazelcast-cluster-role-binding

    image.png

    我也把rbac.yaml文件copy下来贴出来了:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: hazelcast-cluster-role
    rules:
      - apiGroups:
          - ""
        resources:
          - endpoints
          - pods
          - nodes
          - services
        verbs:
          - get
          - list
    
    ---
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: hazelcast-cluster-role-binding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: hazelcast-cluster-role
    subjects:
      - kind: ServiceAccount
        name: default
        namespace: default
    

    5. 将项目部署至Kubernetes中

    我的Kubernetes环镜用的是minikube。

    5.1 创建Deployment组件:

    kubectl create deployment hazelcast-k8s --image=<docker username>/hazelcast-k8s

    image.png 查看Pod: image.png

    查看具体的Log:

    kubectl logs -f hazelcast-k8s-5779bdf674-zpkmt

    image.png

    5.2 扩大Deployment中的replicaSet,从1个变为2个:

    kubectl scale deployment hazelcast-k8s --replicas=2

    image.png 可以看到新增了一个Pod: image.png

    查看新的Pod的Log:

    kubectl logs -f hazelcast-k8s-5779bdf674-cmd8w

    【成功!!!】两个Pod组成了一个Hazelcast的集群:
    Hazelcast有两种模式,一种是C/S模式,一个是embedded模式(即没有Server,每个节点既是client又是server),本文用的是embedded模式: image.png

    6. 测试

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

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

    可以看到创建好了: image.png

    因为ClusterIP为内部service,想要被外部访问:

    • 要么通过另外创建组件Ingress进行访问
    • 要么将上述的service改为type为LoadBalancer的service
    • 要么通过下面的命令进行转发,这样才可以从我们本机的localhost进行访问:

    kubectl port-forward service/hazelcast-k8s 8080:8080

    测试API:
    a) /version:

    image.png

    b) 存放cache:/put:

    image.png

    c) 取出cache:/get:

    image.png

    d) cache大小:/size:

    image.png

    7. 总结

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

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

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

    查看2个Pod的IP:

    kubectl get pod -o wide

    image.png log中可以看到,Hazelcast的通信用的是Pod自己的IP: image.png

    【目前的架构】hazelcast通过Pod的IP,端口为5701,进行通信,而创建的Service,只是给String Boot项目本身的8090端口做暴露,跟Hazelcast本身的5701没有关系:

    未命名文件 (8).png

    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

    image.png

    相关文章

      网友评论

          本文标题:【k8s学习】在Kubernetes上部署Hazelcast集群

          本文链接:https://www.haomeiwen.com/subject/oouzvrtx.html