1 环境说明

说明: 本文主要关注微服务在k8s平台的实现过程,有些步骤不会在本文中体现,需要自行搭建。

1.1 服务器环境

实验服务器配置: 40核/64GB/2TB

主机名 系统版本 IP地址 cpu/内存/磁盘 用途 软件版本 k8s_nfs CentOS7.5 172.16.1.60 4核/8GB/60GB nfs存储/SkyWalking服务器端/jdk nfs-utils-1.3.0-0.68/es7-8.3.0/openjdk-1.8 k8s_harbor CentOS7.5 172.16.1.61 4核/4GB/60GB harbor镜像仓库 v1.9.1 k8s_gitlab CentOS7.5 172.16.1.62 4核/4GB/60GB gitlab代码仓库 GitLab Community Edition 13.12.2 k8s-master1 CentOS7.5 172.16.1.81 4核/4GB/60GB jdk、maven用于编译代码 jdk-8u45 maven-3.5.0 k8s-master2 CentOS7.5 172.16.1.82 4核/4GB/60GB kubernetes master2节点 k8s v1.20.0 k8s-node1 CentOS7.5 172.16.1.83 8核/16GB/60GB kubernetes node1节点 k8s v1.20.0 k8s-node2 CentOS7.5 172.16.1.84 8核/16GB/60GB kubernetes node2节点 k8s v1.20.0

补充: kubernetes集群的控制节点我打了污点不能被pod调度使用。

1.2 微服务项目说明
3 项目服务说明

第26章: 微服务容器化迁移

服务 服务名 端口号 连接信息 portal-service 前端服务 8080 连接eureka gateway-service 网关服务 9999 连接eureka order-service 订单服务 8020 连接eureka、mysql product-service 产品服务 8010 连接eureka、mysql stock-service 库存服务 8030 连接eureka、mysql eureka-service 微服务注册中心服务 8888 eureka之间相互连接 mysql 数据库服务 3306 /
1.3 应用环境准备

第26章: 微服务容器化迁移

[root@k8s-master1 ms]# kubectl get deployment,pod,svc,sc -n default

第26章: 微服务容器化迁移

Login Succeeded

2 微服务架构

2.1 单体应用 vs 微服务

1 单体架构

3) 新人上手难

第26章: 微服务容器化迁移

2 微服务架构

5) 大量服务治理

第26章: 微服务容器化迁移

3 JAVA微服务框架

(3) Dubbo:       阿里巴巴开源的微服务治理框架
2.2 在K8S平台部署微服务考虑的问题

第26章: 微服务容器化迁移

2 对微服务项目架构理解

(7) 区分有状态应用与无状态应用

3 为什么用注册中心系统

Eureka,Nacos,Consul

第26章: 微服务容器化迁移

4 在k8s部署项目流程

dockerfile 》》》Deployment、StatefulSet、DaemonSet 》》》Service Ingress 》》》Prometheus+Grafana、ELK Stack

3 在K8S平台部署Spring Cloud微服务项目

ms                Active   23s
3.1 熟悉Spring Cloud微服务项目
注: 我这里根据 dev4 分支进行部署操作

第26章: 微服务容器化迁移

架构图2:

第26章: 微服务容器化迁移

3.2 源代码编译构建
# mvn clean package -Dmaven.test.skip=true

第26章: 微服务容器化迁移

# ls -l eureka-service/target/eureka-service.jar
3.3 增加dockerfile容器编排文件

这里以order-service为例,其它服务类似

[root@k8s-master1 simple-microservice]# pwd
/root/ms/simple-microservice

# cat order-service/order-service-biz/Dockerfile
FROM  java:8-jdk-alpine
LABEL maintainer lc
ENV JAVA_ARGS="-Dfile.encoding=UTF8 -Duser.timezone=GMT+08"
RUN  sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
     apk add -U tzdata && \
     ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/order-service-biz.jar ./
COPY skywalking /skywalking
EXPOSE 8020
CMD java -javaagent:/skywalking/skywalking-agent.jar=agent.service_name=ms-order,agent.instance_name=$(echo $HOSTNAME | awk -F- '{print $1"-"$NF}'),collector.backend_service=172.16.1.60:11800 $JAVA_ARGS $JAVA_OPTS -jar /order-service-biz.jar

说明:
agent.service_name=ms-order: 在skywalking中表示服务的名字,通常一个服务下有多个实例。

$(echo $HOSTNAME | awk -F- '{print $1"-"$NF}'): 表示以"-"为分割,截取pod容器主机名第一位和最后一位,然后以"-"连接,在
skywalking中表示pod实例。
示例:
# echo $(echo calico-node-pmf4q | awk -F- '{print $1"-"$NF}')
calico-pmf4q

collector.backend_service=172.16.1.60:11800: 指定SkyWalking服务器所在的地址及端口。

$JAVA_OPTS: 该变量在k8s yaml文件中定义,在pod容器中被引用。
3.4 增加K8s服务编排文件

这里以order-service为例,其它服务类似

[root@k8s-master1 simple-microservice]# pwd
/root/ms/simple-microservice

# cat k8s/order.yaml
apiVersion: apps/v1
kind: Deployment 
metadata:
  name: order
  namespace: ms 
spec:
  replicas: 1
  selector:
    matchLabels:
      project: ms
      app: order
  template:
    metadata:
      labels:
        project: ms 
        app: order
    spec:
      imagePullSecrets:
      - name: registry-pull-secret
      containers:
      - name: order
        image: 172.16.1.61/microservice/order:2022-01-15-22-38-07
        imagePullPolicy: Always
        ports:
          - protocol: TCP
            containerPort: 8020 
        env:
          - name: JAVA_OPTS
            value: "-Xmx1g"
        resources:
          requests:
            cpu: 0.5
            memory: 256Mi
          limits:
            cpu: 1
            memory: 1Gi
        readinessProbe:
          tcpSocket:
            port: 8020
          initialDelaySeconds: 60
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: 8020
          initialDelaySeconds: 60
          periodSeconds: 10
3.5 在K8s中部署MySQL
# kubectl get pvc,pv -n ms

MySQL [tb_stock]> exit
3.6 微服务部署脚本
[root@k8s-master1 k8s]# pwd
/root/ms/simple-microservice/k8s

1 创建 secret 用于 pod 从 harbor 仓库拉取镜像时进行账号密码验证
# docker_registry="172.16.1.61"
# 存储登录Harbor认证信息
# kubectl create secret docker-registry registry-pull-secret \
--docker-server=$docker_registry --docker-username=admin \
--docker-password=Harbor12345 --docker-email=admin@lc.com \
-n ms

# kubectl get secret -n ms | grep registry-pull-secret
registry-pull-secret   kubernetes.io/dockerconfigjson        1      31s

2 登录habor仓库,方便脚本推送镜像到harbor仓库
# docker login 172.16.1.61
Username: admin
Password: Harbor12345
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

3 脚本
[root@k8s-master1 k8s]# cat docker_build.sh
#!/bin/bash

# 说明: 执行脚本时所在的目录必须为 ../simple-microservice/k8s/

# Harbor仓库IP地址
docker_registry="172.16.1.61"

# 微服务应用部署列表
service_list="eureka-service order-service product-service stock-service gateway-service portal-service"
# 命令行指定微服务应用名时按指定的应用名部署,否则按照上面的应用列表进行部署
service_list="${1:-${service_list}}"
# 获取执行脚本时所在目录的上层目录
work_dir="$(dirname $PWD)"
# 获取执行脚本时所在目录
current_dir="$PWD"

# 编译构建代码
cd  $work_dir
mvn clean package -Dmaven.test.skip=true

# 循环部署微服务应用列表中的应用
for service in ${service_list}; do
   # 进入应用中Dockerfile所在的目录
   cd ${work_dir}/$service
   # 业务程序需进入biz目录里构建
   if ls |grep biz &>/dev/null; then
      cd ${service}-biz
   fi
   # 拿掉最后一个 "-" 及其右边的字符串,比如"eureka-service"变为"eureka"
   service="${service%-*}"
   # 镜像名称=Harbor仓库IP/Harbor仓库项目名/微服务应用名作为镜像仓库名:以镜像构建时间作为镜像版本
   image_name="${docker_registry}/microservice/${service}:$(date +%F-%H-%M-%S)"
   # 构建微服务应用镜像
   docker build -t ${image_name} .
   # 将微服务镜像上传到Harbor镜像仓库
   docker push ${image_name}
   # 修改微服务应用k8s编排yaml文件中镜像地址为新推送的镜像地址并apply
   sed -i -r "s#(image: )(.*)#\1${image_name}#" ${current_dir}/${service}.yaml
   kubectl apply -f ${current_dir}/${service}.yaml
done
[root@k8s-master1 k8s]# 

4 微服务应用部署顺序
(1) 注册中心
eureka-service

(2) 业务应用
1) order-service
2) product-service
3) stock-service

(3) 网关服务
gateway-service

(4) 前端服务
portal-service
3.7 在K8s中部署Eureka集群

第26章: 微服务容器化迁移

http://eureka.lc.cn/

第26章: 微服务容器化迁移

3.8 部署微服务业务程序
# bash docker_build.sh portal-service
3.9 访问微服务
http://eureka.lc.cn/

第26章: 微服务容器化迁移

http://172.16.1.61/

第26章: 微服务容器化迁移

[root@k8s-master1 k8s]# kubectl get pod,svc,ep,ingress,pvc,pv -o wide -n ms

第26章: 微服务容器化迁移

(2) http://portal.ctnrs.com/ 

主页面:

添加商品:

查询订单

3.10 微服务升级与扩容
(3) 访问portal应用页面

第26章: 微服务容器化迁移

第26章: 微服务容器化迁移

(2) 查看eureka注册的order应用

4 微服务生产环境踩坑案例

4.1 限制了容器资源,还经常被杀死
(1) 手动指定JVM堆内存大小

第26章: 微服务容器化迁移

- XX:+UseCGroupMemoryLimitForHeap
4.2 滚动更新之健康检查重要性
2 解决办法

第26章: 微服务容器化迁移

4.3 滚动更新期间造成流量丢失
配置preStop回调,在容器终止前优雅暂停5秒,给kube-proxy多预留一点时间。

第26章: 微服务容器化迁移

5 APM监控微服务项目

5.1 APM监控系统说明
一个优秀的调用跟踪系统必须支持分布式部署,具备良好的可扩展性,能够支持的组件越多当然越好。

第26章: 微服务容器化迁移

5.2 Skywalking说明
2 Skywalking架构

第26章: 微服务容器化迁移

5.3 Skywalking部署

第26章: 微服务容器化迁移

java -javaagent:/skywalking/skywalking-agent.jar=agent.service_name=<项目名称>,agent.instance_name=<实例名称>,collector.backend_service=<Skywalking服务器>:11800 -jar xxx.jar
5.4 Skywalking UI使用

1 导航栏

第三栏: 不同纬度展示,服务/实例/端点

2 全局

7 底部栏:                   展示数据的时间区间,点击可以调整

3 Service

11 Service Instance Successful Rate:  服务实例成功率

4 Instance

9 CLR XX:                             .NET服务的指标,类似JVM虚拟机

5 Endpoint

7 Endpoint Successful Rate:             端点请求成功率

6 拓扑图


相关文章:

  • 2021-08-26
  • 2021-09-25
  • 2022-01-18
  • 2022-12-23
  • 2022-12-23
  • 2021-11-20
  • 2021-12-14
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-08-22
  • 2022-12-23
  • 2021-09-29
  • 2022-02-26
  • 2021-08-26
相关资源
相似解决方案