zoukankan      html  css  js  c++  java
  • 微服务容器化迁移——在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以上的版本不存在这个问题。

  • 相关阅读:
    mac md5/base64 终端处理 及文件处理js
    ag(Silver Searcher)查找文件
    js压缩之uglify-js
    iReport Designer在mac下打不开
    mac新建批处理文件,双击启动.sh文件
    将本地文件夹添加到Git仓库
    vue2.X + HTML5 plus 拍照和调用设备相册 另附 图片转base64和压缩图片方法
    Vue3-js 学习笔记
    Vue2.x 常用功能和方法
    typescript 编译报错 不能用于索引类型
  • 原文地址:https://www.cnblogs.com/xiaoshuzhagen/p/14704912.html
Copyright © 2011-2022 走看看