Kubernetes(K8s)部署 SpringCloud 服務實戰

追風人聊Java發表於2021-12-02

1. 概述

老話說的好:有可能性就不要放棄,要敢於嘗試。

 

言歸正傳,之前我們聊了一下如何在 Kubernetes(K8s)中部署容器,今天我們來聊一下如何將 SpringCloud 的服務部署到 Kubernetes(K8s)中。

 

2. 有狀態應用和無狀態應用 

我們先來了解兩個概念,有狀態應用 和 無狀態應用。

 

有狀態應用:簡單說就是不能簡單的實現負載均衡的服務,例如:有資料產生的服務,Redis、MySql、RabbitMQ、ES等,這些服務必須通過一些較複雜的配置才能做到負載均衡。

無狀態應用:就是沒有資料的應用,可以簡單的實現負載均衡,複製一個節點即可,例如:SpringCloud中的業務服務。

 

無狀態的應用適合部署在 Kubernetes(K8s)中或者容器中。

有狀態的應用,建議直接在物理機部署,方便管理、維護。

 

Eureka 服務,也屬於有狀態應用,因為 Eureka 服務叢集需要每個節點去註冊除自己之外的其他Eureka服務,配置檔案有差異,因此每個節點是不一樣的。

 

這裡我們只部署一個Eureka節點,就也使用容器部署。

 

3. 場景說明

使用之前搭建的 Kubernetes(K8s)叢集,搭建的過程可參見我之前的文章《使用國內的映象源搭建 kubernetes(k8s)叢集》(https://www.cnblogs.com/w84422/p/15596883.html)。

在 Kubernetes(K8s)叢集中,搭建1個 Eureka 節點,搭建2個 Gateway 負載均衡節點,搭建2個 Eureka Client  負載均衡節點,提供一個簡單的介面。

搭建成功後,我們通過呼叫 Gateway 來訪問 Eureka Client 的這個簡單介面。

 

4. 部署 SpringCloud 服務

4.1 部署 Eureka 服務

4.1.1 Eureka 服務 application.yml 配置

spring:
  application:
    name: my-eureka
server:
  port: 35000
eureka:
  instance:
    hostname: my-eureka  
  client:
    register-with-eureka: false       # 是否發起服務註冊
    fetch-registry: false             # 是否拉取服務登錄檔
  server:
    enable-self-preservation: false         # 是否開啟自我保護,建議關閉,開啟自我保護機制後,例項當機也被不會剔除
    eviction-interval-timer-in-ms: 10000    # 每隔多久觸發一次服務剔除,預設是60秒

 

4.1.2 生成 Eureka 服務的 Docker 映象

簡單起見,這裡這裡直接在 Kubernetes(K8s)的資料節點建立映象,然後本地拉取,不上傳到遠端 Docker 倉庫了。

# vi Dockerfile

FROM java:8
ADD my-eureka-0.0.1-SNAPSHOT.jar my-eureka-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","my-eureka-0.0.1-SNAPSHOT.jar"]

# docker build -t myeureka:1.0 .

 

4.1.3 Eureka 服務 Deployment 部署

在 Kubernetes(K8s)Master 節點執行

# vi eureka-deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-eureka
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-eureka
  template:
    metadata:
      labels:
        app: my-eureka
    spec:
      containers:
      - name: my-eureka
        image: myeureka:1.0

 

# kubectl apply -f eureka-deployment.yml

 

4.1.4 Eureka 服務 Service 部署

由於需要在瀏覽器開啟 Eureka 控制檯,並且其他服務需要向 Eureka 註冊,因此需要部署 Service 。

在 Kubernetes(K8s)Master 節點執行

# vi eureka_service.yml

apiVersion: v1
kind: Service
metadata:
  name: my-eureka-svc
spec:
  type: NodePort
  selector:
    app: my-eureka
  ports:
  - protocol: TCP
    nodePort: 35000
    port: 35000
    targetPort: 35000

 

# kubectl apply -f eureka_service.yml

 

4.2 部署 Eureka Client 服務

4.2.1 Eureka Client 服務的簡單介面

@RestController
@RequestMapping("/eurekaClient")
public class EurekaClientController {

    @GetMapping("/hello")
    public String hello() {
        return "eurekaClient hello";
    }

 

4.2.2 Eureka Client 服務 application.yml 配置

spring:
  application:
    name: my-eureka-client
server:
  port: 36000
eureka:
  client:
    service-url:     
      defaultZone: http://my-eureka-svc:35000/eureka/
    healthcheck:
      enabled: true    # 開啟健康檢查, 依賴於 spring-boot-starter-actuator
  instance:
    lease-renewal-interval-in-seconds: 5      # 發出續約指令的間隔,預設30秒
    lease-expiration-duration-in-seconds: 30  # 租期到期時間,預設90秒
    instance-id: ${spring.cloud.client.ip-address}.${server.port}
    prefer-ip-address: true

注:在 Kubernetes(K8s)中,容器間可以使用 Service 中的 metadata.name + “:” + spec.ports.port 訪問服務,因此 Eureka Client 服務可以使用 my-eureka-svc:35000 訪問 Eureka 服務

 

4.2.3 生成 Eureka Client 服務的 Docker 映象

# vi Dockerfile

FROM java:8
ADD my-eureka-client-0.0.1-SNAPSHOT.jar my-eureka-client-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","my-eureka-client-0.0.1-SNAPSHOT.jar"]

 

# docker build -t myeurekaclient:1.0 .

 

4.2.4 Eureka Client 服務 Deployment 部署

# vi eurekaclient-deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-eureka-client
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-eureka-client
  template:
    metadata:
      labels:
        app: my-eureka-client
    spec:
      containers:
      - name: my-eureka-client
        image: myeurekaclient:1.0

 

# kubectl apply -f eurekaclient-deployment.yml

 

4.3 部署 Gateway 服務

4.3.1 Gateway 服務 application.yml 配置

這裡用簡單的路由規則,按照服務的 string.application.name 小寫的形式路由

server:
  port: 44000

spring:
  application:
    name: my-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true   # service-id 是否用小寫
eureka:
  client:
    service-url:
      defaultZone: http://my-eureka-svc:35000/eureka/
      healthcheck:
        enabled: true    # 開啟健康檢查, 依賴於 spring-boot-starter-actuator
  instance:
    lease-renewal-interval-in-seconds: 5      # 發出續約指令的間隔,預設30秒
    lease-expiration-duration-in-seconds: 30  # 租期到期時間,預設90秒
    instance-id: ${spring.cloud.client.ip-address}.${server.port}
    prefer-ip-address: true

 

4.3.2 生成 Gateway 服務的 Docker 映象

# vi Dockerfile

FROM java:8
ADD my-gateway-0.0.1-SNAPSHOT.jar my-gateway-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","my-gateway-0.0.1-SNAPSHOT.jar"]

 

# docker build -t mygateway:1.0 .

 

4.3.3 Gateway 服務 Deployment 部署

# vi gateway-deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-gateway
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-gateway
  template:
    metadata:
      labels:
        app: my-gateway
    spec:
      containers:
      - name: my-gateway
        image: mygateway:1.0

 

# kubectl apply -f gateway-deployment.yml

 

4.3.4 Gateway 服務 Service 部署

# vi gateway_service.yml

apiVersion: v1
kind: Service
metadata:
  name: my-gateway-svc
spec:
  type: NodePort
  selector:
    app: my-gateway
  ports:
  - protocol: TCP
    nodePort: 44000
    port: 44000
    targetPort: 44000

 

# kubectl apply -f gateway_service.yml

  

4.4 驗證

4.4.1 瀏覽器訪問 Eureka

http://192.168.1.12:35000/

可以看到有2個 my-eureka-client 服務 和 2個 my-gateway 服務 註冊到了 Eureka。

192.168.1.12 是 kubernetes(k8s)Master 節點的IP地址。

 

4.4.2 瀏覽器訪問介面

http://192.168.1.12:44000/my-eureka-client/eurekaClient/hello

介面可以正常訪問,代表驗證成功。

 

5. 綜述

今天聊了一下 kubernetes(k8s)叢集上是如何部署SpringCloud服務的,希望可以對大家的工作有所幫助。

歡迎幫忙點贊、評論、轉發、加關注 :)

關注追風人聊Java,每天更新Java乾貨。

 

6. 個人公眾號

追風人聊Java,歡迎大家關注

相關文章