k8s部署spring cloud eureka集群

本文档介绍了如何在Kubernetes(k8s)环境中使用StatefulSet部署Spring Cloud Eureka集群。内容涵盖系统环境、Eureka配置、Dockerfile制作以及通过Headless Service在k8s中的应用,确保Eureka实例具有稳定的网络标识和存储。此外,还讨论了使用Ingress访问Eureka UI的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 系统环境

java JDK 11
docker 19.03.9
k8s 1.18

2. eureka架构图

在这里插入图片描述

3. eureka配置

application.yml

eureka:
  instance:
    prefer-ip-address: false  # 我们使用的是hostname注册,要设置为false,否则注册不成功
  client:
    register-with-eureka: true #相互注册
    fetch-registry: true
    service-url:
      defaultZone: http://eureka-0.eureka:8761/eureka,http://eureka-1.eureka:8761/eureka,http://eureka-2.eureka:8761/eureka

主机名使用的是k8s的pod名称+服务名

Pod的Name怎么组成的:

statefulSet控制器的Name + 序号

defaultZone也可以在k8s的部署文件中配置

这里把eureka的 hostname配置放到了部署文件中

4 dockerfile

FROM openjdk:11-jre
ARG JAR_FILE
ENV PROFILE default
ENV JAVA_OPTS -server
ENTRYPOINT java -Dspring.profiles.active=${PROFILE} -Duser.timezone=Asia/Shanghai ${JAVA_OPTS} -jar /usr/share/app.jar
EXPOSE 8761
ADD target/${JAR_FILE} /usr/share/app.jar

生成docker镜像

docker build -t  registry.com/kubernetes/eureka:latest

5. 部署到k8s

创建 Eureka 部署文件,用于在 Kubernetes 中部署 Eureka,这里选择用 StatefulSet (有状态集)方式来部署,这样能保证它 Eureka Pod 名是有序的,如果部署为 Deployment,那么得部署三个 Deployment 对象,比较繁琐。并且 StatefulSet 支持 Service Headless 方式创建 Service 来对内部服务访问,如果是 CluserIP 方式创建 Service 会分一个虚拟 IP 给该 Service,那么服务通过 Service 访问 Pod 每次都需要经过 Kube-proxy 代理流量,这样会增加与注册中心的通信造成一定性能损耗。Headless 方式部署的 Service 不会分配虚拟 IP,而是用轮询的访问,每次都直接与 Pod 的 IP 进行通信。

它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。

为什么使用headless:

因为给Pod分配一个域,让其他Pod可以通过dnsName访问到这组Eureka的Pod

5.1 创建eureka.yml

---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: eureka
  namespace: dev
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - host: eureka.com
      http:
        paths:
          - path: /
            backend:
              serviceName: eureka
              servicePort: 8761
---
apiVersion: v1
kind: Service
metadata:
  name: eureka
  namespace: dev
spec:
  clusterIP: None
  ports:
    - name: eureka
      port: 8761
  selector:
    app: eureka
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: eureka
  namespace: dev
spec:
  serviceName: eureka
  replicas: 3
  selector:
    matchLabels:
      app: eureka
  template:
    metadata:
      labels:
        app: eureka
    spec:
      terminationGracePeriodSeconds: 1    #当删除Pod时,等待时间
      containers:
        - name: eureka
          image: registry.com/eureka:1.0.0
          imagePullPolicy: Always
          ports:
            - protocol: TCP
              containerPort: 8761
          env:
            - name: APP_NAME
              value: "eureka"
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: EUREKA_SERVER
              value: "http://eureka-0.eureka:8761/eureka/,http://eureka-1.eureka:8761/eureka/,http://eureka-2.eureka:8761/eureka/"
            - name: EUREKA_INSTANCE_HOSTNAME
              value: ${POD_NAME}.eureka
#            - name: PORT
#              value: "8761"
            - name: PROFILE
              value: "test"
          readinessProbe:              #就绪探针
            tcpSocket:
              port: 8761
            initialDelaySeconds: 20    #延迟加载时间
            periodSeconds: 5           #重试时间间隔
            timeoutSeconds: 10         #超时时间设置
            failureThreshold: 5        #探测失败的重试次数
          livenessProbe:               #存活探针
            tcpSocket:
              port: 8761
            initialDelaySeconds: 60    #延迟加载时间
            periodSeconds: 5           #重试时间间隔
            timeoutSeconds: 5          #超时时间设置
            failureThreshold: 3        #探测失败的重试次数
  podManagementPolicy: "Parallel"  #并行部署
  1. 匹配Pod name(网络标识)的模式为:(statefulset名称)−(序号),比如上面的示例:eureka-0,eureka-1,eureka-2。
  2. StatefulSet为每个Pod副本创建了一个DNS域名,这个域名的格式为: $(podname).(headless Service name),也就意味着服务间是通过Pod域名来通信而非Pod IP,因为当Pod所在Node发生故障时,Pod会被飘移到其它Node上,Pod IP会发生变化,但是Pod域名不会有变化。
  3. StatefulSet使用Headless服务来控制Pod的域名,这个域名的FQDN为:(servicename).(namespace).svc.cluster.local,其中,“cluster.local”指的是集群的域名。

StatefulSet使用场景:

1.稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现。
2.稳定的网络标识符,即Pod重新调度后其PodName和HostName不变。
3.有序部署,有序扩展,基于init containers来实现。
4.有序收缩。

5.2 部署Eureka Server到kubernetes

kubectl apply -f eureka.yaml
#如果发现部署错了,可以执行kubectl delete -f erueka.yaml,删除这个yaml部署的所有资源

5.3. 访问Eurek UI

这里需要先安装ingress,具体看这篇文章 安装ingress

通过命令查看域名配置:
在这里插入图片描述

由于ingress配置了域名,先修改本地hosts,把域名解析到ingress-controller的Pod所在的NodeIP。
然后输入域名即可:
在这里插入图片描述

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiegwei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值