多重保护,提升读写,提高利用率
云物理机性能卓越、满足核心高性能应用场景
服务器托管性能可控、资源独享、物理资源隔离
镜像标准镜像、服务集成镜像,自定义镜像
本地快照定期对数据备份,以防数据丢失
基于比格云容器服务产品-微服务应用案例部署实践
该案例是基于比格云k8s平台部署spring cloud框架微服务项目。包括如下服务:注册服务eureka、网关服务gateway、前端portal、商品服务product、库存服务stock、订单服务order、数据库服务mysql。需提前在控制台创建好k8s集群和mysql云数据库。
通过ingress将前端域名暴露在公网为用户提供统一的入口,内部服务都注册到注册中心eureka,然后通过api网关gateway进行路由调度。
外部有状态服务mysql、es通过Headless Service和endpoint的方式引入到k8s内部。
该项目部署大概分如下几步:
Ø 资源配置规划,包括k8s集群规模、服务域名、k8s内部资源;
Ø 基础环境搭建,包括通过控制台创建k8s集群和mysql云数据库;
Ø 准备代码配置文件制作docker镜像;
Ø 创建k8s内部资源。
根据实际的业务规模需求提前规划好k8s集群资源规模,主要是规划好cpu和内存,避免后续pod因为cpu、内存资源不足无法正常启动。
k8s单个集群支持:
不超过5000个节点
不超过150000个pod
不超过300000个容器
每台Node上不超过100个pod
本案例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个 |
在kubernetes系统中namespace通常用于实现多租户的资源隔离,例如:同一个namespace下面不允许出现两个叫mysql的service。
namespace可按环境划分:dev、test,也可按团队项目划分。
本案例中所有的资源都创建在“ms”这个namespace下,可通过控制台一键创建namespace,如下截图:
根据实际的业务场景采用不同的pod控制器,Pod管理控制器分如下几类:
Deployment:无状态部署
StatefulSet:有状态部署(如:MySQL、Mongodb、Redis)
DaemonSet:守护进程部署
Job & CronJob:批处理
本案例中eureka为StatefulSet有状态部署,其他均为Deployment无状态部署。
通过控制台创建好k8s集群时会自动部署coreDNS服务,k8s集群内各服务之间可通过域名进行相互访问。K8s集群外部服务可通过Headless Service和endpoint方式引入到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 | 外部域名 |
通过比格云控制台可快速完成k8s集群的搭建,点击容器服务-->集群管理-->新建,然后根据集群资源规划选择好对应的配置即可一键完成集群搭建。
通过比格云控制台可快速完成mysql数据库的搭建,点击云数据库-->选择mysql-->创建,即可完成mysql的安装。
根据上面的域名更新对应的配置文件,然后编译打包,再通过Dockerfile制作镜像。
本案例中基础镜像为Alpine Linux ,运行环境镜像为JDK8。生产环境可根据实际需要自制基础镜像和运行环境镜像。
下面以制作eureka服务镜像为例,其他服务操作类似。
首先将代码和配置文件打成一个jar包,并上传到一个目录。
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服务,不同服务启动命令不同。 |
在代码目录下执行如下命令制作镜像,镜像名称格式为:
$docker_registry/${service}:${version}
docker build -t registry-wx.biggeryun.com/test/eureka:v1.0 . |
上传镜像前可先通过控制台创建自己的镜像仓库,如下截图:
首先执行docker login登录,用户名为控制台账号,密码可通过控制:台镜像仓库-->重置新密码。再执行docker push将镜像上传到镜像仓库,方便后续pod拉取使用。具体命令如下:
docker login registry-wx.biggeryun.com |
通过Headless Service和endpoint方式将外部的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
pod在启动的时候会pull指定的镜像,当镜像设置为私有的时候需要进行用户认证,比较方便的做法是创建一个secret用来保存私有仓库的认证信息,后面pod在直接应用该secret。
通过控制台创建secret
本案例中eureka为StatefulSet有状态部署,其他均为Deployment无状态部署。在实际生产环境中可能会为pod增加许多自定义参数,所以一般通过yaml文件来创建pod资源。
通过yaml文件创建pod,命令如下:
kuber apply -f ****.yaml |
以下为eureka、gateway、portal、order、product、stock的yaml文件内容。
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
在 k8s中部署一个deployment大都是多副本的去部署,有可能会分布在不同的节点之上,而且重启 pod后其ip也会变,所以没有办法通过pod的ip去访问pod里的服务。
K8s是通过在pod前面加一个service,提供一个访问入口,只有访问这个统一入口,才能转发到后端多个pod上。
Service 定义了 Pod 的逻辑集合和访问这个集合的策略,然后使用 CoreDNS 解析 Service 名称。
一般为每个pod创建一个service,但在微服务场景下,由于每个服务都会注册到注册中心,然后通过api网关进行路由,所以在微服务场景下并不需要为每个pod去创建对应的service。
通过控制台创建gateway service如下:
通过yaml文件创建如下:
kubectl apply -f ***.yaml |
像ingress、service、pod可以合并成一个yaml文件,本次为了方便理解将其分开创建。
由于eureka service的clusterIP设置为None,所以通过yaml创建。
下面为eureka、portal、gateway service的yaml文件内容。
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
创建ingress之前必须先创建好ingress controller,在创建ingress controller的时候绑定一个负载均衡,创建ingress时会自动将ingress指定的域名解析到负载均衡上提供外网访问功能。
创建ingress时也可以配置为https,通过控制台创建如下:
注意:域名需提前备案。
通过yaml文件创建如下:
kubectl apply -f ***.yaml |
下面为eureka、portal、gateway ingress的yaml文件内容。
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
在浏览器上访问www.portal.com。
通过控制台集群管理-->创建日志创建elk日志服务后(创建成功后创建日志按钮变为查看日志),会将k8s集群内所以pod的日志收集到elk日志平台中,可通过集群管理-->查看日志进入到kibana中查看pod日志。
日志入口
Kibana日志展示
本篇基于比格云容器化平台部署一套微服务应用,涉及容器平台镜像制作、工作负载、服务、日志等,做为熟悉比格容器平台的应用案例之一,后续会持续更新。
快速构建nginx服务
Step1:点击控制台左侧集群管理,点击新建集群。
Step2:填写集群配置信息。
2.1 填写集群基本信息
2.2 选择合适的Master机型
2.3 选择合适的Node机型
2.4 配置云服务器管理并确认
Step3:创建工作负载(Workload)。
Step4:填写工作负载详情。
Step5:选择官方nginx镜像。
Step6:设置主机端口访问,本例将以端口30001进行设置演示。
Step7:开放云防火墙策略,创建云防火墙。
Step8:创建云防火墙,点击访问策略进行自定义端口设置。
Step9:访问Node节点下的外网IP,实现访问。
Step10:快速访问页面
Step1:点击控制台左侧集群管理,点击新建集群。
Step2:填写集群配置信息。
2.1 填写集群基本信息
2.2 选择合适的Master机型
2.3 选择合适的Node机型
2.4 配置云服务器管理并确认
Step3:点击确认创建集群。
Step1:进入集群管理-选择集群,点击右侧管理集群。
Step2:选择节点管理>下拉菜单中的Node机型。
Step3:移出所有Node机型。
Step4:选择集群并删除集群。
Step1:点击集群管理,选择集群,点击集群管理。
Step2:选择节点管理,选择Node机型。
Step3:点击新增主机,选择配置后确定创建。
Step4:等待Node节点主机创建,列表中新加Node节点完成后,节点状态变为绿色。
Step1:点击命名空间。
Step2:填写名称、描述后确认完成创建。
Step1:点击工作负载。
Step2:填写工作负载详细信息。
Step3:查看监控。
Step1:点击集群管理,选择集群,点击管理集群。
Step2:点击新建服务。
Step3:填写服务内容信息。
Step1:点击集群管理,选择集群后,点击配置管理。
Step2:点击新建配置。
Step3:填写名称、选择命名空间、填写内容后确认。
Step1:点击集群管理,选择集群后,点击创建监控。
Step2:创建容器监控访问权限、选择监控存储及负载均衡,确认完成创建。
Step3:查看容器监控Dashboard。
Step1:点击集群管理,选择集群后,点击创建日志。
Step2:选择负载均衡、填写日志相关内容。
Step3:点击集群管理,选择集群后,点击查看日志。
Step4:填写Elastic 用户名和密码。
Step5:进入Elastic Dashboard。
Copyright © 2011-2024 Biggeryun.com. All Rights Reserved. 比格云 版权所有
工信部可信云云主机服务认证 | 国家信息安全等级保护三级认证 | 《中华人民共和国增值电信业务经营许可证》B1-20172466 | 沪ICP备12023723号-6 | 沪公网安备 31011502006948号 拒绝网络谣言 清朗网络环境