帮助中心
  • 云主机
  • 数据盘
  • 弹性IP
  • 快照
  • 云防火墙
  • 比格云容器服务:微服务应用案例部署实践

    基于比格云容器服务产品-微服务应用案例部署实践

     

    1. K8s部署微服务案例

    1.1. 项目简介

    该案例是基于比格云k8s平台部署spring cloud框架微服务项目。包括如下服务:注册服务eureka、网关服务gateway、前端portal、商品服务product、库存服务stock、订单服务order、数据库服务mysql。需提前在控制台创建好k8s集群和mysql云数据库。

    1.2. 服务架构

    通过ingress将前端域名暴露在公网为用户提供统一的入口,内部服务都注册到注册中心eureka,然后通过api网关gateway进行路由调度。

    外部有状态服务mysqles通过Headless Serviceendpoint的方式引入到k8s内部。

    1634296527693189.png 

    1.3. 项目部署流程

    该项目部署大概分如下几步:

    Ø 资源配置规划,包括k8s集群规模、服务域名、k8s内部资源;

    Ø 基础环境搭建,包括通过控制台创建k8s集群和mysql云数据库;

    Ø 准备代码配置文件制作docker镜像;

    Ø 创建k8s内部资源。

     

    1.3.1. 资源配置规划

    1.3.1.1. K8s集群规模规划

    根据实际的业务规模需求提前规划好k8s集群资源规模,主要是规划好cpu和内存,避免后续pod因为cpu、内存资源不足无法正常启动。

    k8s单个集群支持:

    不超过5000个节点

    不超过150000pod

    不超过300000个容器

    每台Node上不超过100pod

    本案例Pod包括日志相关、监控相关、dns相关、业务服务相关,集群详情如下:

    K8s版本

    1.14.10

    Master节点

    3

    Node节点

    3

    操作系统

    Ubuntu 16.04

    Master节点总CPU

    12C

    Master节点总内存

    24G

    Node节点总CPU

    24C

    Node节点总内存

    24G

    Pod数量

    26

    1.3.1.2. namespace 规划

    kubernetes系统中namespace通常用于实现多租户的资源隔离,例如:同一个namespace下面不允许出现两个叫mysqlservice

    namespace可按环境划分:devtest,也可按团队项目划分。

    本案例中所有的资源都创建在ms”这个namespace下,可通过控制台一键创建namespace,如下截图:

    1634294988615043.png 

    1.3.1.3. 控制器管理Pod规划

    根据实际的业务场景采用不同的pod控制器,Pod管理控制器分如下几类:
    Deployment:无状态部署
    StatefulSet:有状态部署(如:MySQLMongodbRedis
    DaemonSet:守护进程部署
    Job & CronJob:批处理

    本案例中eurekaStatefulSet有状态部署,其他均为Deployment无状态部署。

    1.3.1.4. 服务域名规划

    通过控制台创建好k8s集群时会自动部署coreDNS服务,k8s集群内各服务之间可通过域名进行相互访问。K8s集群外部服务可通过Headless Serviceendpoint方式引入到k8s集群内部,再通过域名进行访问。

    K8s域名又分service域名和pod域名,格式分别如下:

    Service域名格式为:

    [svc_name].[namespace_name].svc.cluster.local

    Pod域名格式为:

    pod-ip-address.[namespace].pod.cluster.local

    在同一个namespace下访问时可以省略掉cluster.local部分。

    本案例中所用到的域名如下:

    服务

    域名

    说明

    Mysql

    mysql-service.ms.svc.cluster.local

    Service域名

    Gateway

    gateway-service.ms.svc.cluster.local

    Service域名

    Eureka

    eureka-0.eureka.ms.svc.cluster.local

    Pod域名

    Portal

    www.portal.com

    外部域名

    1.3.2. 基础环境搭建

    1.3.2.1. 创建k8s集群

    通过比格云控制台可快速完成k8s集群的搭建,点击容器服务-->集群管理-->新建,然后根据集群资源规划选择好对应的配置即可一键完成集群搭建。

    1634295000623597.png 

    1.3.2.2. 创建mysql云数据库

    通过比格云控制台可快速完成mysql数据库的搭建,点击云数据库-->选择mysql-->创建,即可完成mysql的安装。

    1634295009121671.png 

    1.3.3. 制作镜像

    根据上面的域名更新对应的配置文件,然后编译打包,再通过Dockerfile制作镜像。

    本案例中基础镜像为Alpine Linux ,运行环境镜像为JDK8。生产环境可根据实际需要自制基础镜像和运行环境镜像。

    下面以制作eureka服务镜像为例,其他服务操作类似。

    1.3.3.1. 编译打包

    首先将代码和配置文件打成一个jar包,并上传到一个目录。

    1.3.3.2. 准备Dockerfile文件

    FROM java:8-jdk-alpine

    RUN  sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && \

         apk add -U tzdata && \

         ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  #设置容器内时区

    COPY ./eureka-service.jar /   #拷贝代码包到指定路径

    EXPOSE 8888

    CMD java -jar /eureka-service.jar  #启动eureka服务,不同服务启动命令不同。

     

    1.3.3.3. 3制作镜像

    在代码目录下执行如下命令制作镜像,镜像名称格式为:

    $docker_registry/${service}:${version}

    docker build -t registry-wx.biggeryun.com/test/eureka:v1.0 .

    1.3.3.4. 创建镜像仓库

    上传镜像前可先通过控制台创建自己的镜像仓库,如下截图:

    1634295020533890.png 

    1.3.3.5. 上传镜像

    首先执行docker login登录,用户名为控制台账号,密码可通过控制:台镜像仓库-->重置新密码。再执行docker push将镜像上传到镜像仓库,方便后续pod拉取使用。具体命令如下:

    docker login registry-wx.biggeryun.com
    docker push registry-wx.biggeryun.com/test/eureka:v1.0

     

    1.3.4. 创建k8s资源

    1.3.4.1. 引入外部mysql服务

    通过Headless Serviceendpoint方式将外部的mysql引入到k8s集群内部,应用可通过k8s内部域名访问mysql服务。

    1. apiVersion: v1  

    2. kind: Service  

    3. metadata:  

    4.   name: mysql-service  

    5.   namespace: ms  

    6. spec:  

    7.   clusterIP: None  

    8.   ports:  

    9.   - name: mysql  

    10.     port: 3306  

    11.     protocol: TCP  

    12.     targetPort: 3306  

    13.   type: ClusterIP  

    14.   

    15. ---  

    16. apiVersion: v1  

    17. kind: Endpoints  

    18. metadata:  

    19.   name: mysql  

    20.   namespace: ms  

    21. subsets:  

    22. - addresses:  

    23.   - ip: 10.100.100.45   #外部mysql地址  

    24.   ports:  

    25.   - name: mysql  

    26.     port: 3306  

    27.     protocol: TCP  

    1.3.4.2. 创建secret

    pod在启动的时候会pull指定的镜像,当镜像设置为私有的时候需要进行用户认证,比较方便的做法是创建一个secret用来保存私有仓库的认证信息,后面pod在直接应用该secret

    通过控制台创建secret

    1634295031680023.png 

    1.3.4.3. 创建pod

    本案例中eurekaStatefulSet有状态部署,其他均为Deployment无状态部署。在实际生产环境中可能会为pod增加许多自定义参数,所以一般通过yaml文件来创建pod资源。

    通过yaml文件创建pod,命令如下:

    kuber apply -f ****.yaml

     

    以下为eurekagatewayportalorderproductstockyaml文件内容。

    eureka

    1. apiVersion: apps/v1  

    2. kind: StatefulSet  

    3. metadata:  

    4.   name: eureka  

    5.   namespace: ms   

    6. spec:  

    7.   replicas: 3  #三副本  

    8.   selector:  

    9.     matchLabels:  

    10.       project: ms  

    11.       app: eureka  

    12.   serviceName: "eureka"  

    13.   template:  

    14.     metadata:  

    15.       labels:  

    16.         project: ms   

    17.         app: eureka  

    18.     spec:  

    19.       imagePullSecrets:  

    20.       - name: registry-pull-secret  #引用仓库认证secret

    21.       containers:  

    22.       - name: eureka  

    23.         image: registry-wx.biggeryun.com/test/eureka:v1.0  

    24.         ports:  

    25.           - protocol: TCP  

    26.             containerPort: 8888  

    27.         env:  

    28.           - name: JAVA_OPTS  

    29.             value: "-Xmx1g"  

    30.           - name: MY_POD_NAME  

    31.             valueFrom:  

    32.               fieldRef:  

    33.                 fieldPath: metadata.name  

    34.         resources:  

    35.           requests:  

    36.             cpu: 0.5  

    37.             memory: 256Mi  

    38.           limits:  

    39.             cpu: 1   

    40.             memory: 1Gi  

    41.         readinessProbe:  

    42.           tcpSocket:  

    43.             port: 8888  

    44.           initialDelaySeconds: 60  

    45.           periodSeconds: 10  

    46.         livenessProbe:  

    47.           tcpSocket:  

    48.             port: 8888  

    49.           initialDelaySeconds: 60  

    50.           periodSeconds: 10  

     

    gateway

    1. apiVersion: apps/v1  

    2. kind: Deployment   

    3. metadata:  

    4.   name: gateway  

    5.   namespace: ms   

    6. spec:  

    7.   replicas: 2  

    8.   selector:  

    9.     matchLabels:  

    10.       project: ms  

    11.       app: gateway  

    12.   template:  

    13.     metadata:  

    14.       labels:  

    15.         project: ms   

    16.         app: gateway  

    17.     spec:  

    18.       imagePullSecrets:  

    19.       - name: registry-pull-secret  

    20.       containers:  

    21.       - name: gateway  

    22.         image: registry-wx.biggeryun.com/test/gateway:v1.0  

    23.         imagePullPolicy: Always  

    24.         ports:  

    25.           - protocol: TCP  

    26.             containerPort: 9999   

    27.         env:  

    28.           - name: JAVA_OPTS  

    29.             value: "-Xmx1g"  

    30.         resources:  

    31.           requests:  

    32.             cpu: 0.5  

    33.             memory: 256Mi  

    34.           limits:  

    35.             cpu: 1  

    36.             memory: 1Gi  

    37.         readinessProbe:  

    38.           tcpSocket:  

    39.             port: 9999  

    40.           initialDelaySeconds: 60  

    41.           periodSeconds: 10  

    42.         livenessProbe:  

    43.           tcpSocket:  

    44.             port: 9999  

    45.           initialDelaySeconds: 60  

    46.           periodSeconds: 10

     

    portal

    1. apiVersion: apps/v1  

    2. kind: Deployment   

    3. metadata:  

    4.   name: portal  

    5.   namespace: ms   

    6. spec:  

    7.   replicas: 2  

    8.   selector:  

    9.     matchLabels:  

    10.       project: ms  

    11.       app: portal  

    12.   template:  

    13.     metadata:  

    14.       labels:  

    15.         project: ms   

    16.         app: portal  

    17.     spec:  

    18.       imagePullSecrets:  

    19.       - name: registry-pull-secret  

    20.       containers:  

    21.       - name: portal  

    22.         image: registry-wx.biggeryun.com/test/portal:v1.0  

    23.         imagePullPolicy: Always  

    24.         ports:  

    25.           - protocol: TCP  

    26.             containerPort: 8080   

    27.         env:  

    28.           - name: JAVA_OPTS  

    29.             value: "-Xmx1g"  

    30.         resources:  

    31.           requests:  

    32.             cpu: 0.5  

    33.             memory: 256Mi  

    34.           limits:  

    35.             cpu: 1  

    36.             memory: 1Gi  

    37.         readinessProbe:  

    38.           tcpSocket:  

    39.             port: 8080  

    40.           initialDelaySeconds: 60  

    41.           periodSeconds: 10  

    42.         livenessProbe:  

    43.           tcpSocket:  

    44.             port: 8080  

    45.           initialDelaySeconds: 60  

    46.           periodSeconds: 10  

     

    order

    1. apiVersion: apps/v1  

    2. kind: Deployment   

    3. metadata:  

    4.   name: order  

    5.   namespace: ms   

    6. spec:  

    7.   replicas: 2  

    8.   selector:  

    9.     matchLabels:  

    10.       project: ms  

    11.       app: order  

    12.   template:  

    13.     metadata:  

    14.       labels:  

    15.         project: ms   

    16.         app: order  

    17.     spec:  

    18.       imagePullSecrets:  

    19.       - name: registry-pull-secret  

    20.       containers:  

    21.       - name: order  

    22.         image: registry-wx.biggeryun.com/test/order:v1.0  

    23.         imagePullPolicy: Always  

    24.         ports:  

    25.           - protocol: TCP  

    26.             containerPort: 8020   

    27.         env:  

    28.           - name: JAVA_OPTS  

    29.             value: "-Xmx1g"  

    30.         resources:  

    31.           requests:  

    32.             cpu: 0.5  

    33.             memory: 256Mi  

    34.           limits:  

    35.             cpu: 1  

    36.             memory: 1Gi  

    37.         readinessProbe:  

    38.           tcpSocket:  

    39.             port: 8020  

    40.           initialDelaySeconds: 60  

    41.           periodSeconds: 10  

    42.         livenessProbe:  

    43.           tcpSocket:  

    44.             port: 8020  

    45.           initialDelaySeconds: 60  

    46.           periodSeconds: 10  

     

    product

    1. apiVersion: apps/v1  

    2. kind: Deployment   

    3. metadata:  

    4.   name: product  

    5.   namespace: ms   

    6. spec:  

    7.   replicas: 2  

    8.   selector:  

    9.     matchLabels:  

    10.       project: ms  

    11.       app: product  

    12.   template:  

    13.     metadata:  

    14.       labels:  

    15.         project: ms   

    16.         app: product  

    17.     spec:  

    18.       imagePullSecrets:  

    19.       - name: registry-pull-secret  

    20.       containers:  

    21.       - name: product  

    22.         image: registry-wx.biggeryun.com/test/product:v1.0  

    23.         imagePullPolicy: Always  

    24.         ports:  

    25.           - protocol: TCP  

    26.             containerPort: 8010   

    27.         env:  

    28.           - name: JAVA_OPTS  

    29.             value: "-Xmx1g"  

    30.         resources:  

    31.           requests:  

    32.             cpu: 0.5  

    33.             memory: 256Mi  

    34.           limits:  

    35.             cpu: 1  

    36.             memory: 1Gi  

    37.         readinessProbe:  

    38.           tcpSocket:  

    39.             port: 8010  

    40.           initialDelaySeconds: 60  

    41.           periodSeconds: 10  

    42.         livenessProbe:  

    43.           tcpSocket:  

    44.             port: 8010  

    45.           initialDelaySeconds: 60  

    46.           periodSeconds: 10  

     

    stock

    1. apiVersion: apps/v1  

    2. kind: Deployment   

    3. metadata:  

    4.   name: stock  

    5.   namespace: ms   

    6. spec:  

    7.   replicas: 2  

    8.   selector:  

    9.     matchLabels:  

    10.       project: ms  

    11.       app: stock  

    12.   template:  

    13.     metadata:  

    14.       labels:  

    15.         project: ms   

    16.         app: stock  

    17.     spec:  

    18.       imagePullSecrets:  

    19.       - name: registry-pull-secret  

    20.       containers:  

    21.       - name: stock  

    22.         image: registry-wx.biggeryun.com/test/stock:v1.0  

    23.         imagePullPolicy: Always  

    24.         ports:  

    25.           - protocol: TCP  

    26.             containerPort: 8030  

    27.         env:  

    28.           - name: JAVA_OPTS  

    29.             value: "-Xmx1g"  

    30.         resources:  

    31.           requests:  

    32.             cpu: 0.5  

    33.             memory: 256Mi  

    34.           limits:  

    35.             cpu: 1  

    36.             memory: 1Gi  

    37.         readinessProbe:  

    38.           tcpSocket:  

    39.             port: 8030  

    40.           initialDelaySeconds: 60  

    41.           periodSeconds: 10  

    42.         livenessProbe:  

    43.           tcpSocket:  

    44.             port: 8030  

    45.           initialDelaySeconds: 60  

    46.           periodSeconds: 10  

     

    1.3.4.4. 创建service

    k8s中部署一个deployment都是多副本的去部署,有可能会分布在不同的节点之上,而且重启 pod后其ip也会变,所以没有办法通过podip去访问pod里的服务。

    K8s是通过在pod前面加一个service,提供一个访问入口,只有访问这个统一入口,才能转发到后端多个pod

    Service 定义了 Pod 的逻辑集合和访问这个集合的策略,然后使用 CoreDNS 解析 Service 名称

    一般为每个pod创建一个service,但在微服务场景下,由于每个服务都会注册到注册中心,然后通过api网关进行路由,所以在微服务场景下并不需要为每个pod去创建对应的service

    通过控制台创建gateway service如下:

    1634295061807321.png 

    通过yaml文件创建如下:

    kubectl apply -f ***.yaml

    ingressservicepod可以合并成一个yaml文件,本次为了方便理解将其分开创建。

    由于eureka serviceclusterIP设置为None,所以通过yaml创建。

    下面为eurekaportalgateway serviceyaml文件内容。

    eureka

    1. apiVersion: v1  

    2. kind: Service  

    3. metadata:  

    4.   name: eureka-service  

    5.   namespace: ms  

    6. spec:  

    7.   clusterIP: None #不生成service的clusterIP,使用pod域名。  

    8.   ports:  

    9.   - port: 8888  

    10.     name: eureka   

    11.   selector:  

    12.     project: ms  

    13.     app: eureka  

     

    gateway

    1. apiVersion: v1  

    2. kind: Service  

    3. metadata:  

    4.   name: gateway-service  

    5.   namespace: ms  

    6. spec:  

    7.   ports:  

    8.   - port: 9999   

    9.     name: gateway  

    10.   selector:  

    11.     project: ms  

    12.     app: gateway  

     

    portal

    1. apiVersion: v1  

    2. kind: Service  

    3. metadata:  

    4.   name: portal-service  

    5.   namespace: ms  

    6. spec:  

    7.   ports:  

    8.   - port: 8080  

    9.     name: portal   

    10.   selector:  

    11.     project: ms  

    12.     app: portal  

     

    1.3.4.5. 创建ingress

    创建ingress之前必须先创建好ingress controller,在创建ingress controller的时候绑定一个负载均衡,创建ingress时会自动将ingress指定的域名解析到负载均衡上提供外网访问功能。

    创建ingress时也可以配置为https,通过控制台创建如下:

    1634295074129787.png 

    注意:域名需提前备案。

    通过yaml文件创建如下:

    kubectl apply -f ***.yaml

    下面为eurekaportalgateway ingressyaml文件内容。

    eureka

    1. apiVersion: extensions/v1beta1  

    2. kind: Ingress  

    3. metadata:  

    4.   name: eureka   

    5.   namespace: ms   

    6. spec:  

    7.   rules:  

    8.     - host: www.eureka.com   

    9.       http:  

    10.         paths:  

    11.         - path: /  

    12.           backend:  

    13.             serviceName: eureka-service  

    14.             servicePort: 8888  

     

    gateway

    1. apiVersion: extensions/v1beta1  

    2. kind: Ingress  

    3. metadata:  

    4.   name: gateway   

    5.   namespace: ms   

    6. spec:  

    7.   rules:  

    8.     - host: www.gateway.com   

    9.       http:  

    10.         paths:  

    11.         - path: /  

    12.           backend:  

    13.             serviceName: gateway-service  

    14.             servicePort: 9999  

     

    portal

    1. apiVersion: extensions/v1beta1  

    2. kind: Ingress  

    3. metadata:  

    4.   name: portal   

    5.   namespace: ms   

    6. spec:  

    7.   rules:  

    8.     - host: www.portal.com   

    9.       http:  

    10.         paths:  

    11.         - path: /  

    12.           backend:  

    13.             serviceName: portal-service  

    14.             servicePort: 8080  

     

    1.3.5. 验证

    在浏览器上访问www.portal.com

    1634295087998307.png 

    1.4. 集群日志

    通过控制台集群管理-->创建日志创建elk日志服务后(创建成功后创建日志按钮变为查看日志),会将k8s集群内所以pod的日志收集到elk日志平台中,可通过集群管理-->查看日志进入到kibana中查看pod日志。

    日志入口

    1634295095954289.png 

    Kibana日志展示

    1634295102338201.png 

     

     

     

     

     

    2. 结束语

    本篇基于比格云容器化平台部署一套微服务应用,涉及容器平台镜像制作、工作负载、服务、日志等,做为熟悉比格容器平台的应用案例之一,后续会持续更新。

     

     

     

     

     

     

     

     

     

     

     


  • 容器操作指南:容器快速入门(构建nginx服务)

    快速构建nginx服务

    Step1:点击控制台左侧集群管理,点击新建集群。

    1632808141690904.png


    Step2:填写集群配置信息。

    2.1 填写集群基本信息

    1632808186516672.png


    2.2 选择合适的Master机型

    1632808197371630.png


    2.3 选择合适的Node机型

    1632808211612994.png


    2.4 配置云服务器管理并确认

    2-4.png


    Step3:创建工作负载(Workload)。

    3.png



    Step4:填写工作负载详情。

    1632808457543665.png


    Step5:选择官方nginx镜像。

    5-1.png

    5-2.png


    Step6:设置主机端口访问,本例将以端口30001进行设置演示。

    1632822650342423.png


    Step7:开放云防火墙策略,创建云防火墙。

    图片1.png


    Step8:创建云防火墙,点击访问策略进行自定义端口设置。

    8.png


    Step9:访问Node节点下的外网IP,实现访问。

    12.png


    Step10:快速访问页面

    13.png

  • 容器操作指南:新建容器集群

    Step1:点击控制台左侧集群管理,点击新建集群。

    1.png


    Step2:填写集群配置信息。

    2.1 填写集群基本信息

    2-1.png


    2.2 选择合适的Master机型

    2-2.png


    2.3 选择合适的Node机型

    2-3.png


    2.4 配置云服务器管理并确认

    2-4.png


    Step3:点击确认创建集群。

    3.png



  • 容器操作指南:删除容器集群

    Step1:进入集群管理-选择集群,点击右侧管理集群。

    1.png


    Step2:选择节点管理>下拉菜单中的Node机型。

    2.png


    Step3:移出所有Node机型。

    3.png


    Step4:选择集群并删除集群。

    4.png

  • 容器操作指南:添加Node节点

    Step1:点击集群管理,选择集群,点击集群管理。

    1.png


    Step2:选择节点管理,选择Node机型。

    2.png


    Step3:点击新增主机,选择配置后确定创建。

    3.png


    Step4:等待Node节点主机创建,列表中新加Node节点完成后,节点状态变为绿色。

    4.png

  • 容器操作指南:创建命名空间

    Step1:点击命名空间。

    1.png



    Step2:填写名称、描述后确认完成创建。

    2.png

  • 容器操作指南:创建工作负载

    Step1:点击工作负载。

    1.png


    Step2:填写工作负载详细信息。

    2.png


    Step3:查看监控。

    3.png


  • 容器操作指南:创建服务

    Step1:点击集群管理,选择集群,点击管理集群。

    1.png


    Step2:点击新建服务。

    2.png


    Step3:填写服务内容信息。

    3.png

  • 容器操作指南:创建配置管理

    Step1:点击集群管理,选择集群后,点击配置管理。

    1.png


    Step2:点击新建配置。

    2.png


    Step3:填写名称、选择命名空间、填写内容后确认。

    3.png

  • 容器操作指南:创建容器监控

    Step1:点击集群管理,选择集群后,点击创建监控。

    6.png


    Step2:创建容器监控访问权限、选择监控存储及负载均衡,确认完成创建。

    7.png


    Step3:查看容器监控Dashboard。

    8.png

  • 容器操作指南:创建容器日志

    Step1:点击集群管理,选择集群后,点击创建日志。

    6.png


    Step2:选择负载均衡、填写日志相关内容。

    7.png


    Step3:点击集群管理,选择集群后,点击查看日志。

    8.png


    Step4:填写Elastic 用户名和密码。

    9.png


    Step5:进入Elastic Dashboard。

    10.png


技术交流企业群

点击发起工单