微服務容器化遷移——在K8s中部署Spring Cloud


作者:小樹扎根兒

郵箱:zjg_num01@163.com

一、從運維角度看微服務:

1.1 微服務的特點:

  1. 服務組件化:每個微服務獨立開發、部署,可以有效避免因單個微服務的變更引起整個系統重新部署的情況。
  2. 技術棧靈活:約定通信方式,使得服務本身功能實現對技術棧要求不再敏感。
  3. 獨立部署:每個微服務獨立部署,加速部署速度,方便擴展。
  4. 擴展性強:每個微服務可以部署多個,並且有負載均衡能力。
  5. 獨立數據:每個微服務有獨立的基本組件,例如:數據庫、緩存等。

1.2 微服務的不足:

  1. 溝通成本:微服務相比於傳統單體應用開發團隊溝通成本更大。
  2. 數據一致性:每個微服務都有自己獨立的數據存儲,可能會造成數據的不一致。
  3. 運維成本:微服務部署會涉及更多的組件,對運維的部署、監控、更新都帶來更大的挑戰。
  4. 內部架構復雜性:微服務本身就會帶來架構的復雜性,如:服務之間的耦合性設計、分布式事務等。

1.3 單體架構 vs 微服務:

  1. 單體架構:

    • 單體架構的優勢:

    易於部署;

    易於測試;

    • 單體架構的不足:

    代碼臃腫,難以維護;

    構建、部署時間成本大;

    新人上手難;

  2. 微服務架構:

1.4 Java微服務框架:

  • Spring Boot
  • Spring Cloud / Spring Cloud Alibaba
  • Dubbo

二、在K8S平台部署微服務需要考慮的問題:

  1. 微服務架構圖:

  2. 項目遷移到K8S平台的流程:

    • 制作鏡像:

      鏡像分為三層:

      基礎鏡像:centos、ubuntu ... 純凈系統;

      運行環境:基礎鏡像 + 運行環境(如:jdk、php ....);

      項目鏡像:基礎鏡像 + 運行環境 + 應用程序代碼;

    • 控制器管理Pod:

      K8S包括以下幾種控制器:

      Deployment:無狀態部署;

      StatefulSet:有狀態部署;

      DaemonSet:守護進程部署;

      Job & CronJob:批處理;

    • 通過Service暴露應用:

      Service定義了Pod的邏輯集合和訪問這個集合的策略;

      Service的引入是為了解決Pod的動態變化,提供服務發現和負載均衡。

    • 通過Ingress對外發布應用:

      Ingress:

      通過Service關聯Pod;

      基於域名訪問;

      通過Ingress Controller實現Pod的負載均衡;

    • 日志/監控:

      主流方案:

      FileBeat + ELK

      Prometheus + Grafana

  3. 傳統部署與K8S部署的區別:

    • 傳統方式部署項目:

    • K8S方式部署項目:

三、在K8S平台部署Spring Cloud微服務項目:

1、熟悉Spring Cloud微服務項目:

  1. K8S服務器部署清單:

    角色 IP 組件
    k8s-master 192.168.1.90 kube-apiserver、kube-controller、kube-scheduler、docker、etcd
    K8s-node1 192.168.1.91 kubelet、kube-proxy、docker、etcd
    K8s-node2 192.168.1.92 kubelet、kube-proxy、docker、etcd
  2. Spring Cloud微服務項目地址:https://github.com/xiaoshuzhagen/simple-microservice

  3. Spring Cloud微服務使用到的組件如下:

2、通過二進制包方式部署Consul:

  1. Consul服務器部署清單:

    角色 IP 組件
    Consul Node 192.168.1.90 consul server(master)、 consul client
    Consul Node 192.168.1.91 consul server(follower)、consul client
    Consul Node 192.168.1.92 consul server(follower)、consul client

3、構建項目鏡像並推送到鏡像倉庫:

  1. 編寫微服務Dockerfile

    # 基礎鏡像,如果本地沒有,會從遠程倉庫拉取
    FROM openjdk:11
    # 鏡像的制作人
    MAINTAINER zjg_num01@163.com
    # 定義環境變量
    ENV JAVA_OPTS="$JAVA_OPTS"
    # 聲明容器應該打開的端口並沒有實際將端口啟用
    EXPOSE 6010
    # 拷貝本地文件到鏡像中
    COPY ./target/gateway-service.jar ./
    # 指定容器啟動時要執行的命令,但如果存在CMD命令,CMD命令中的參數會被附加到ENTRYPOIN指令的后面
    ENTRYPOINT ["java","-jar","./gateway-service.jar","$JAVA_OPTS"]
    
  2. 通過maven命令構建微服務:

    mvn clean package -Dmaven.test.skip=true
    
  3. jar包構建成docker鏡像並推送到鏡像倉庫中:

    docker build -t gateway-service .
    # -f : 可以指定要使用的Dockerfile路徑.
    # -m : 可以設置內存最大值.
    # -t : 可以指定鏡像名稱及版本.
    # .  : 指定構建鏡像的上下文路徑,docker build 會將這個路徑下所有的文件都打包上傳給Docker引擎.
    
  4. 將微服務鏡像推送到鏡像倉庫中:

    docker login http://192.168.1.90:6666
    docker push http://192.168.1.90:6666/simple-microservice/gateway-service:v1.0
    # simple-microservice:表示鏡像倉庫中的項目名稱,把鏡像打到指定的項目下.
    # gateway-service: 表示鏡像名稱.
    # v1.0:表示鏡像版本.
    

4、K8S部署Spring Cloud項目:

1、服務編排:

  1. 編寫微服務需要k8s編排的yaml文件:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: product-service
      namespace: simple-microservice
    spec:
      replicas: 2
      selector:
        matchLabels:
          project: simple-microservice
          app: product-service
      template:
        metadata:
          labels:
            project: simple-microservice
            app: product-service
        spec:
          imagePullSecrets:
            - name: registry-pull-secert
          containers:
            - name: product-service
              image: 192.168.1.90:7777/simple-microservice/product-service:v1.0
              imagePullPolicy: Always
              ports:
                - protocol: tcp
                  containerPort: 8888
              resources:
                requests:
                  cpu: 0.5
                  memory: 256Mi
                readinessProbe:
                  tcpSocket:
                    port: 8888
                  initialDelaySeconds: 60
                  periodSeconds: 10
                livenessProbe:
                  tcpSocket:
                    port: 8888
                  initialDelaySeconds: 60
                  periodSeconds: 10
    
  2. 部署微服務:

    kubectl apply -f product-service.yaml
    
  3. 資源限制問題:

    雖然微服務運行的Pod已經進行了資源限制,如:最大使用1G內存,但Pod中的jvm並不會感知到資源限制問題,jvm

    運行時如果資源不夠會繼續申請物理資源,此時,Pod檢測到使用的物理資源已經超出自身限制的最大可用戶資源,

    會將Java進程kill掉,從而Java程序會拋出OOM。

    • jdk 1.8之前的版本:

      ​ 服務編排的yaml中指定環境變量:

      Dockfile中引用服務編排yaml中定義的環境變量:

    • jdk 1.9以上的版本不存在這個問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM