帮助中心
  • 云主机
  • 数据盘
  • 弹性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. 结束语

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

 

 

 

 

 

 

 

 

 

 

 


下一篇

技术交流企业群

点击发起工单