Apache Dubbo 是一款高性能、轻量级的开源服务框架,提供了六大核心能力:面向接口代理的高性能 RPC 调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。
- Dobbo 官网:https://dubbo.apache.org/
- Dobbo 文档:https://dubbo.apache.org/zh/docs/
1 Jenkins 流水线准备工作
1.1 参数构建要点
Jenkins 流水线配置的 Java 项目的十个常用参数:
参数名 | 作用 | 举例或说明 |
---|---|---|
app_name | 项目名 | dubbo_demo_service |
image_name | Docker 镜像名 | app/dubbo-demo-service |
git_repo | 项目的 Git 地址 | https://x.com/x/x.git |
git_ver | 项目的 Git 分支或版本号 | master |
add_tag | 镜像标签,常用时间戳 | 191203_1830 |
mvn_dir | 执行 Maven 编译的目录 | ./ |
target_dir | 编译产生包的目录 | ./target |
mvn_cmd | 编译 Maven 项目的命令 | mvc clean package -Dmaven. |
base_image | 项目的 Docker 底包 | 不同的项目底包不一样,下拉选择 |
maven | Maven 软件版本 | 不同的项目可能 Maven 环境不一样 |
除了base_image和maven是choice parameter,其他都是string parameter
1.2 创建流水线
1.2.1 创建流水线
创建名为 dubbo-demo
的流水线( pipeline ),并设置 Discard old builds
为如下
Discard old builds选项 | 值 |
---|---|
Days to keep builds | 3 |
Max # of builds to keep | 30 |
1.2.2 添加 10 个构建参数
This project is parameterized
点击 Add Parameter
,分别添加如下 10 个参数
#第 1 个参数
参数类型 : String Parameter
Name : app_name
Description : 项目名 eg:dubbo-demo-service
#第 2 个参数
参数类型 : String Parameter
Name : image_name
Description : docker镜像名 eg: app/dubbo-demo-service
#第 3 个参数
参数类型 : String Parameter
Name : git_repo
Description : 仓库地址 eg: https://gitee.com/xxx/xxx.git
#第 4 个参数
参数类型 : String Parameter
Name : git_ver
Description : 项目的 Git 分支或版本号
#第 5 个参数
参数类型 : String Parameter
Name : add_tag
Description :
给docker镜像添加标签组合的一部分,如
$git_ver_$add_tag=master_191203_1830
#第 6 个参数
参数类型 : String Parameter
Name : mvn_dir
Default Value : ./
Description : 执行 Maven 编译的目录,默认是项目根目录, eg: ./
#第 7 个参数
参数类型 : String Parameter
Name : target_dir
Default Value : ./target
Description : 编译产生的 war/jar 包目录 eg: ./dubbo-server/target
#第 8 个参数
参数类型 : String Parameter
Name : mvn_cmd
Default Value : mvn clean package -Dmaven.test.skip=true
Description : 编译命令,常加上 -e -q 参数只输出错误
#第 9 个参数
参数类型 : Choice Parameter
Name : base_image
Choices :
base/jre7:7u80
base/jre8:8u112
Description : 项目的 Docker 底包
#第 10 个参数
参数类型 : Choice Parameter
Name : maven
Choices :
3.6.1
3.2.5
2.2.1
Description : 执行编译使用 Maven 软件版本
1.2.3 添加完成效果如下:
1.2.4 添加 Pipiline 代码
流水线构建所用的 Pipiline 代码语法比较有专门的生成工具
以下语句的作用大致是分为四步: 拉代码 -> 构建包 -> 移动包-> 打 Docker 镜像并推送
pipeline {
agent any
stages {
stage('pull') { //get project code from repo
steps {
sh "git clone ${params.git_repo} ${params.app_name}/${env.BUILD_NUMBER} && cd ${params.app_name}/${env.BUILD_NUMBER} && git checkout ${params.git_ver}"
}
}
stage('build') { //exec mvn cmd
steps {
sh "cd ${params.app_name}/${env.BUILD_NUMBER} && /var/jenkins_home/maven-${params.maven}/bin/${params.mvn_cmd}"
}
}
stage('package') { //move jar file into project_dir
steps {
sh "cd ${params.app_name}/${env.BUILD_NUMBER} && cd ${params.target_dir} && mkdir project_dir && mv *.jar ./project_dir"
}
}
stage('image') { //build image and push to registry
steps {
writeFile file: "${params.app_name}/${env.BUILD_NUMBER}/Dockerfile", text: """FROM harbor.zq.com/${params.base_image}
ADD ${params.target_dir}/project_dir /opt/project_dir"""
sh "cd ${params.app_name}/${env.BUILD_NUMBER} && docker build -t harbor.zq.com/${params.image_name}:${params.git_ver}_${params.add_tag} . && docker push harbor.zq.com/${params.image_name}:${params.git_ver}_${params.add_tag}"
}
}
}
}
1.3 用流水线完成 dubbo-service 的构建
记得先在 Harbor 中创建私有仓库 app
1.3.1 选择参数化构建
进入 dubbo-demo
后,选择的参数化构建 build with parameters
,填写 10 个构建的参数
参数名 | 参数值 |
---|---|
app_name | dubbo-demo-service |
image_name | app/dubbo-demo-service |
git_repo | https://gitee.com/outmanzzq/dubbo-demo-service.git |
git_ver | master |
add_tag | 200509_0800 |
mvn_dir | ./ |
target_dir | ./dubbo-server/target |
mvn_cmd | mvn clean package -Dmaven.test.skip=true |
base_image | base/jre8:8u112 |
maven | 3.6.1 |
1.3.2 填写完成效果如下
1.3.3 执行构建并检查
填写完以后执行 bulid 第一次构建需要下载很多依赖包,时间很长,抽根烟,喝杯茶 经过漫长的等待后,已经构建完成了
点击打开 Blue Ocean
查看构建历史及过程:
检查 Harbor 是否已经有这版镜像:
2 交付 dubbo-service 到 K8S
2.1 准备资源清单
创建清单操作都在 7.200
上操作
mkdir /data/k8s-yaml/dubbo-server/
cd /data/k8s-yaml/dubbo-server
2.1.1 创建 Deploy 清单
cat >dp.yaml <<EOF
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: dubbo-demo-service
namespace: app
labels:
name: dubbo-demo-service
spec:
replicas: 1
selector:
matchLabels:
name: dubbo-demo-service
template:
metadata:
labels:
app: dubbo-demo-service
name: dubbo-demo-service
spec:
containers:
- name: dubbo-demo-service
image: harbor.zq.com/app/dubbo-demo-service:master_200509_0800
ports:
- containerPort: 20880
protocol: TCP
env:
- name: JAR_BALL
value: dubbo-server.jar
imagePullPolicy: IfNotPresent
imagePullSecrets:
- name: harbor
restartPolicy: Always
terminationGracePeriodSeconds: 30
securityContext:
runAsUser: 0
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
revisionHistoryLimit: 7
progressDeadlineSeconds: 600
EOF
需要根据自己构建镜像的 tag 来修改 image (重要) Dubbo 的 Server 服务,只向 Zookeeper 注册并通过 Zookeeper 与 Dobbo 的 Web 交互,不需要对外提供服务 因此不需要 Service 资源和 Ingress 资源
2.2 创建 K8S 资源
创建 K8S 资源的操作,在任意 Node 节点上操作即可
2.2.1 创建 app 名称空间
业务资源和运维资源等应该通过名称空间来隔离,因此创建专有名称空间 app
kubectl create namespace app
2.2.2 创建 Secret 资源
我们的业务镜像是 Harbor 中的私有项目,所以需要创建 docker-registry
的 Secret 资源:
kubectl -n app \
create secret docker-registry harbor \
--docker-server=harbor.zq.com \
--docker-username=admin \
--docker-password=Harbor12345
2.2.3 应用资源清单
kubectl apply -f http://k8s-yaml.zq.com/dubbo-server/dp.yaml
3分钟后检查启动情况
# 检查 Pod 是否创建:
~]# kubectl -n app get pod
NAME READY STATUS RESTARTS AGE
dubbo-demo-service-79574b6879-cxkls 1/1 Running 0 24s
# 检查是否启动成功:
~]# kubectl -n app logs dubbo-demo-service-79574b6879-cxkls --tail=2
Dubbo server started
Dubbo 服务端已经启动
到 zk 服务器检查是否有服务注册
sh /opt/zookeeper/bin/zkCli.sh
[zk: localhost:2181(CONNECTED) 0] ls /
[dubbo, zookeeper]
[zk: localhost:2181(CONNECTED) 1] ls /dubbo
[com.od.dubbotest.api.HelloService]
3 交付 dubbo-monitor 监控服务到 K8S
dubbo-monitor是监控zookeeper状态的一个服务,另外还有dubbo-admin,效果一样
dobbo-monitor源码地址: https://github.com/Jeromefromcn/dubbo-monitor.git
3.1 制作 dobbo-monitor 镜像
制作镜像在管理机 7.200
上操作
3.1.1 下载源码
cd /opt/src
wget https://github.com/Jeromefromcn/dubbo-monitor/archive/master.zip
yum -y install unzip
unzip master.zip
mv dubbo-monitor-mster /data/dockerfile/dubbo-monitor
cd /data/dockerfile/dubbo-monitor
3.1.2 修改配置文件:
直接覆盖它原始的配置
其实它原本就没什么内容,只是修改了 addr ,端口,目录等
cat >dubbo-monitor-simple/conf/dubbo_origin.properties <<'EOF'
dubbo.container=log4j,spring,registry,jetty
dubbo.application.name=simple-monitor
dubbo.application.owner=
dubbo.registry.address=zookeeper://zk1.zq.com:2181?backup=zk2.zq.com:2181,zk3.zq.com:2181
dubbo.protocol.port=20880
dubbo.jetty.port=8080
dubbo.jetty.directory=/dubbo-monitor-simple/monitor
dubbo.statistics.directory=/dubbo-monitor-simple/statistics
dubbo.charts.directory=/dubbo-monitor-simple/charts
dubbo.log4j.file=logs/dubbo-monitor.log
dubbo.log4j.level=WARN
EOF
3.1.3 优化 Dockerfile 启动脚本
# 修改 JVM 资源限制(非必须)
sed -i '/Xmx2g/ s#128m#16m#g' ./dubbo-monitor-simple/bin/start.sh
sed -i '/Xmx2g/ s#256m#32m#g' ./dubbo-monitor-simple/bin/start.sh
sed -i '/Xmx2g/ s#2g#128m#g' ./dubbo-monitor-simple/bin/start.sh
# 修改 Nohup 为 exec 不能改去掉改行最后的 & 符号
sed -ri 's#^nohup(.*) &#exec\1#g' ./dubbo-monitor-simple/bin/start.sh
# 删除 exec 命令行后面所有行
sed -i '66,$d' ./dubbo-monitor-simple/bin/start.sh
3.1.4 构建并上传
docker build . -t harbor.zq.com/infra/dubbo-monitor:latest
docker push harbor.zq.com/infra/dubbo-monitor:latest
3.2 创建资源配置清单
3.2.1 准备目录
mkdir /data/k8s-yaml/dubbo-monitor
cd /data/k8s-yaml/dubbo-monitor
3.2.2 创建 Deploy 资源文件
cat >dp.yaml <<EOF
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: dubbo-monitor
namespace: infra
labels:
name: dubbo-monitor
spec:
replicas: 1
selector:
matchLabels:
name: dubbo-monitor
template:
metadata:
labels:
app: dubbo-monitor
name: dubbo-monitor
spec:
containers:
- name: dubbo-monitor
image: harbor.zq.com/infra/dubbo-monitor:latest
ports:
- containerPort: 8080
protocol: TCP
- containerPort: 20880
protocol: TCP
imagePullPolicy: IfNotPresent
imagePullSecrets:
- name: harbor
restartPolicy: Always
terminationGracePeriodSeconds: 30
securityContext:
runAsUser: 0
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
revisionHistoryLimit: 7
progressDeadlineSeconds: 600
EOF
3.2.3 创建 Service 资源文件
cat >svc.yaml <<EOF
kind: Service
apiVersion: v1
metadata:
name: dubbo-monitor
namespace: infra
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 8080
selector:
app: dubbo-monitor
EOF
3.2.4 创建 Ingress 资源文件
cat >ingress.yaml <<EOF
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: dubbo-monitor
namespace: infra
spec:
rules:
- host: dubbo-monitor.zq.com
http:
paths:
- path: /
backend:
serviceName: dubbo-monitor
servicePort: 8080
EOF
3.3 创建 dobbo-miniotr 服务
3.3.1 应用资源配置清单
在任意 Node 节点
kubectl apply -f http://k8s-yaml.zq.com/dubbo-monitor/dp.yaml
kubectl apply -f http://k8s-yaml.zq.com/dubbo-monitor/svc.yaml
kubectl apply -f http://k8s-yaml.zq.com/dubbo-monitor/ingress.yaml
验证:
~]# kubectl -n infra get pod
NAME READY STATUS RESTARTS AGE
dubbo-monitor-d9675688c-sctsx 1/1 Running 0 29s
jenkins-7cd8b95d79-6vrbn 1/1 Running 0 3d2h
3.3.2 添加 Dns 解析
这个服务是有 Web 页面的,创建了 Ingress 和 Service 资源的,所以需要添加 DNS 解析
vi /var/named/zq.com.zone
dobbo-monitor A 10.4.7.10
重启并验证
systemctl restart named
dig -t A dubbo-monitor.zq.com @10.4.7.11 +short
3.3.3 访问 Monitor 的 Web 页面
访问 http://dubbo-monitor.zq.com
这里已经可以看到我们之前部署的 dubbo-demo-service 服务了,启动了两个进程来提供服务。
至此,dubbo-monitor 监控服务已经部署完成。
4 构建 dubbo-consumer 服务
4.1 构建 Docker 镜像
4.1.1 获取私有仓库代码
之前创建的 dubbo-service 是微服务的提供者,现在创建一个微服务的消费者
使用 git@gitee.com:outmanzzq/dubbo-demo-web.git
这个私有仓库中的代码构建消费者
先从https://gitee.com/sunx66/dubbo-demo-service
这里fork到自己仓库,在设为私有
并修改 zk 的配置,配置文件路径:
dubbo-demo-web/dubbo-client/src/main/java/config.properties
4.1.2 配置流水线
之前已经在 Jenkins 配置好了流水线,只需要填写参数就行了。
参数名 | 参数值 |
---|---|
app_name | dubbo-demo-consumer |
image_name | app/dubbo-demo-consumer |
git_repo | git@gitee.com:outmanzzq/dubbo-demo-web.git |
git_ver | master |
add_tag | 200506_1430 |
mvn_dir | ./ |
target_dir | ./dubbo-client/target |
mvn_cmd | mvn clean package -Dmaven.test.skip=true |
base_image | base/jre8:8u112 |
maven | 3.6.1 |
4.1.3 查看构建结果
如果构建不报错,则应该已经推送到 Harbor 仓库中了,这时我们直接再给镜像一个新 Tag ,以便后续模拟更新
docker tag \
harbor.zq.com/app/dubbo-demo-consumer:master_200506_1430 \
harbor.zq.com/app/dubbo-demo-consumer:master_200510_1430
docker push harbor.zq.com/app/dubbo-demo-consumer:master_200510_1430
查看 Harbor 仓库
4.2 准备资源配置清单:
先准备目录
mkdir /data/k8s-yaml/dubbo-consumer
cd /data/k8s-yaml/dubbo-consumer
4.2.1 创建 Deploy 资源清单
cat >dp.yaml <<EOF
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: dubbo-demo-consumer
namespace: app
labels:
name: dubbo-demo-consumer
spec:
replicas: 1
selector:
matchLabels:
name: dubbo-demo-consumer
template:
metadata:
labels:
app: dubbo-demo-consumer
name: dubbo-demo-consumer
spec:
containers:
- name: dubbo-demo-consumer
image: harbor.zq.com/app/dubbo-demo-consumer:master_200506_1430
ports:
- containerPort: 8080
protocol: TCP
- containerPort: 20880
protocol: TCP
env:
- name: JAR_BALL
value: dubbo-client.jar
imagePullPolicy: IfNotPresent
imagePullSecrets:
- name: harbor
restartPolicy: Always
terminationGracePeriodSeconds: 30
securityContext:
runAsUser: 0
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
revisionHistoryLimit: 7
progressDeadlineSeconds: 600
EOF
注意修改镜像的 Tag
4.2.2 创建 Service 资源清单
cat >svc.yaml <<EOF
kind: Service
apiVersion: v1
metadata:
name: dubbo-demo-consumer
namespace: app
spec:
ports:
- protocol: TCP
port: 8080
targetPort: 8080
selector:
app: dubbo-demo-consumer
EOF
4.2.3 创建 Ingress 资源清单
cat >ingress.yaml <<EOF
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: dubbo-demo-consumer
namespace: app
spec:
rules:
- host: dubbo-demo.zq.com
http:
paths:
- path: /
backend:
serviceName: dubbo-demo-consumer
servicePort: 8080
EOF
4.3 创建 K8S 资源
4.3.1 应用资源配置清单:
kubectl apply -f http://k8s-yaml.zq.com/dubbo-consumer/dp.yaml
kubectl apply -f http://k8s-yaml.zq.com/dubbo-consumer/svc.yaml
kubectl apply -f http://k8s-yaml.zq.com/dubbo-consumer/ingress.yaml
# 查看容器启动成功没
~]# kubectl get pod -n app
NAME READY STATUS RESTARTS AGE
dubbo-demo-consumer-b8d86bd5b-wbqhs 1/1 Running 0 6s
dubbo-demo-service-79574b6879-cxkls 1/1 Running 0 4h39m
4.3.2 验证启动结果
查看 log,是否启动成功:
~]# kubectl -n app logs --tail=2 dubbo-demo-consumer-b8d86bd5b-wbqhs
Dubbo client started
Dubbo 消费者端启动
检查 dubbo-monitor 是否已经注册成功:
4.3.3 添加 DNS 解析
vi /var/named/zq.com.zone
dubbo-demo A 10.4.7.10
# 重启服务
systemctl restart named
# 验证
~]# dig -t A dubbo-demo.zq.com @10.4.7.11 +short
10.4.7.10
浏览器访问http://dubbo-demo.zq.com/hello?name=lg
4.4 模拟版本升级
接下来我们模拟升级发版,之前已经用同一个镜像打了不同的 tag 并推送到从库
当然正常发版的顺序是:
- 提交修改过的代码的代码块
- 使用 Jenkins 构建新镜像
- 上传到私有 Harbor 仓库中
- 更新 deploy.yaml 文件并 apply
4.4.1 修改 dp.yaml 资源配置清单
修改 Harbor 镜像仓库中对应的 Tag 版本:
sed -i 's#master_200506_1430#master_200510_1430#g' dp.yaml
4.4.2 应用修改后的资源配置清单
当然也可以在 Dashboard 中进行在线修改:
kubectl apply -f http://k8s-yaml.zq.com/dubbo-consumer/dp.yaml
~]# kubectl -n app get pod
NAME READY STATUS RESTARTS AGE
dubbo-demo-consumer-84f75b679c-kdwd7 1/1 Running 0 54s
dubbo-demo-service-79574b6879-cxkls 1/1 Running 0 4h58m
4.4.3 使用浏览器验证
使用浏览器验证:http://dubbo-demo.zq.com/hello?name=lg
在短暂的超时后,即可正常访问
至此,我们一套完成的 Dubbo 服务就已经交付到 K8S 集群当中了,并且也演示了如何发版。
附:常见问题
1. dubbo-monitor Web 页面 dubbo server/consumer 无法正常显示服务?
注意检查 dubbo server/consumer 源码 Zookeeper 配置
dubbo-demo-server 配置路径: dubbo-server/src/main/java/config.properties
dubbo.registry=zookeeper://zk1.zq.com:2181?backup=zk2.zq.com:2181,zk3.zq.com:2181 dubbo.port=20880
dubbo-demo-consumer 配置路径: dubbo-demo-web/dubbo-client/src/main/java/config.properties
dubbo.registry=zookeeper://zk1.zq.com:2181?backup=zk2.zq.com:2181,zk3.zq.com:2181