8 K8S 运行 dubbo + zookeeper 微服务案例
微服务的话最需要的地方就是注册中心,也就是 K8S 中跑的服务会有很多个,然后对应的服务起来之后就会注册到 zookeeper 这种注册中心,然后服务之间内部调用
这个就够就是在 K8S 中先启注册中心,这里我使用的是 zookeeper ,然后服务采用的是生产者消费者模型由开发定义。
生产者用于提供服务能够被客户端访问,客户端也就是所谓的消费者
如果客户端想要调用生产者这里拿 tomcat 和 nginx 来说,tomcat 就是生产者 nginx 就是消费者。nginx 想要调用 tomcat 要么写 tomcat 地址,要么写 tomcat pod 的 svc,但是现在这种结构就不行了
因为在这种场合下,尤其是在 K8S 中每个服务的地址都不是固定的,所以没有办法通过固定的地址来访问生产者,那这种情况该怎么办呢?就是当生产者起来之后将自己注册进去,生产者注册的时候至少会包含他的一些基本信息(ip 和 port)
如图中的 10.100.2.1:20080。
注册之后如果说有消费者想要对他进行调用从注册中心去拿这个地址,消费者并不是通过配置文件读的,而且生产者 pod 的地址是不固定的(因为我们都知道每当 pod 重启之后会就重新分配地址),不过这个没有关系,因为生产者起来之后会第一时间将自己注册进去
而消费者起来之后也会第一时间链接注册中心,再从注册中心里面将生产者的地址拿到,当消费者拿到生产者的地址后就相当于客户端知道了服务端地址了,然后在通过拿到的地址进行调用
当我们的生产者和消费者注册到 zookeeper 之后,相对他们进行管理的话就需要 dubbo admin 连接到注册中心,通过注册中心查到他的生产者地址和消费者地址,然后再进行统计或管理,但这个 dubbo admin 组件并不是必须的
这种情况就没有通过 svc ,从而性能会更好
8.1 单体服务和微服务的区别
8.1.1 什么是单体服务、单体应用
缺点:随着业务增长及开发团队的不断扩大、遇到的问题如下:
- 部署效率问题
- 一套代码几十兆或上百兆,需要较长的编译时间和部署时间
- 团队协作问题
- 一个单体应用中包含多个功能,但是每个功能可能是不同的开发小组单独开发,那么代码怎么一起打包与构建
- 影响业务稳定
- 一个 tomcat 运行的代码过于臃肿、会导致内存溢出问题
8.1.2 什么是微服务
微服务就是将单个应用拆分为多个应用(由开发进行拆分),每个应用运行在单独的运行环境(这个运行环境其实就是通过 pod 来提供的,如果是 java 的业务就提供 jdk 环境, go 的就提供 go 的环境),应用之间通过指定接口与方式调用,应用之间的代码版本升级互不影响。
实现微服务的方式:
- 横向拆分(按照功能拆分,如将 100M 的服务拆分为 10M 这样的话进行编译就会快很多):
- 按照不同的业务进行拆分,如支付、订单、登录、物流等
- 纵向拆分(将一个业务中的功能组件在进行细拆):
- 把一个业务中的组件在细致拆分,比如支付系统拆分为,微信支付、银联支付、支付宝支付等
这个怎么拆分就取决于公司的开发,这就是微服务和单体服务之间的区别
8.2 什么是微服务
微服务,又叫微服务架构,是一种软件架构方式。它将应用构建成一系列按业务领域划分模块的、小的自治服务。
在微服务架构中,每个服务都是自我包含的,并且实现了单一的业务功能。
简单来说,就是将一个系统按业务划分成多个子系统,每个子系统都是完整的,可独立运行的,子系统间的交互可通过HTTP协议进行通信(也可以采用消息队列来通信,如RoocketMQ,Kafaka等)。
所以,不同子系统可以使用不同的编程语言实现,使用不同的存储技术。但是,因为子系统服务数量越多,管理起来越复杂,因此需要采用集中化管理,例如Eureka,Zookeeper等都是比较常见的服务集中化管理框架;同时,使用自动化部署(如Jenkins)减少人为控制,降低出错概率,提高效率。
微服务的特点
● 解耦:同一系统内的服务大部分可以被解耦。因此应用,作为一个整体,可以轻易地被构建、修改和扩展。
● 组件化:微服务可以被看成相互独立的组件,这些组件可以被轻易地替换和升级。
● 业务能力:微服务很小,它们可以专注于某种单一的能力
● 自治:开发者和团队可以独立地工作,提高开发速度。
● 持续交付:允许持续发布软件新版本,通过系统化的自动手段来创建、测试和批准新版本。
● 职责明确:微服务不把应用看成一个又一个的项目。相反,它们把应用当成了自己需要负责的项目。
● 去中心化管理:关注于使用正确的工具来完成正确的工作。这也就是说,没有标准化的方式或者技术模式。开发者们有权选择最好的工具来解决问题。
● 敏捷性:微服务支持敏捷开发。任何新功能都可以被快速开发或丢弃。
微服务的优势
● 独立开发:基于各个微服务所独有的功能,它们可以被轻易开发出来。
● 独立部署:基于它们所提供的服务,它们可以被独立地部署到应用中。
● 错误隔离:即便其中某个服务发生了故障,整个系统还可以继续工作。
● 混合技术栈:可以使用不同的语言和技术来为同一个应用构建不同的服务。
● 按粒度扩展:可以根据需求扩展某一个组件,不需要将所有组件全部扩展。
8.2.1 微服务实现的几个要素
- 微服务如何落地(容器+K8S)
- 这样成本会降低很多,只有一个服务器的时候也能跑几百个微服务,而且如果在物理机上
- 微服务之间如何发现对方(注册中心、服务发现)
- 微服务之间如何访问对方(服务访问 -> resetful API)
- 微服务如何快速扩容(服务治理)
- 通过 deployment 快速扩容副本数。扩容之后还得需要通过注册中心将扩容好的那些新的容器在加入到我们的可用服务列表中,让用户访问,那么新启的一个 pod 怎么才能让别的服务访问到呢?那就是通过服务注册了,通过注册中心发现新启动的 pod 然后再对它进行调用
- 微服务如何监控(服务监控)
- 容器我们主要是使用 Prometheus 或者 zabbix
- 微服务如何升级与回滚(CI/CD)
- 主要是通过 Jenkins+gitlab
- 微服务访问日志如何查看(ELK)
这些东西都是必须要做的,不然不好落地
8.2.2 微服务开发环境
- sprint boot:是一个快速开发框架,内置 java 运行环境 ,但是 spring boot 倾向于开发单个服务
- sprint cloud:基于Spring Boot,为微服务体系开发中的架构问题,提供了一整套的解决方案的服务注册与发现, 服务消费,服务保护与熔断,网关,分布式调用追踪,分布式配置管理等。
-
Dubbo:是阿里巴巴开源的分布式服务治理框架,也具备服务注册与发现,服务消费等功能,出现比Spring Cloud早,功能没有Spring Cloud多,但是国内目前依然有很多互联网企业实现dubbo实现微服务。
8.2.2.1 Spring boot 与 Spring Cloud 区别
SpringBoot 只是一个快速开发框架, 使用注解简化了 xml 配置,内置了 Servlet 容器,以 Java 应用程序进行执行。
- SpringCloud 是系列框架的集合,可以包含 SpringBoot
- 1.SpringBoot 专注于方便的开发单个个体微服务
- 2 SpringCloud 是关注于全局的微服务协调治理框架,它将 SpringBoot 开发的一个个单体微服务整合并管理起来。为各个微服务之间提供配置管理,服务发现,断路器,路由,微代理,事件总线,决策竞选,分布式会话等集成服务
- spring boot 使用了默认大于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置,Spring Cloud 很大的-部分是基于 Spring boot 来实现。
- SpringBoot 可以离开 SpringCloud 单独使用,而 SpringCloud 离不开 SpringBoot
8.3 架构解析
那么消费者怎么知道生产者的 ip 呢?
就是因为在配置文件中写了注册中心的地址,并且通过将自己注册到注册中心中获取到生产者的地址
所以当我们的消费者和生产者在事先不知道对方的地址的时候,就基于注册中心来做发现,整个流程如上图
- 先启动生产者(provider),以容器为例会将自己的地址和端口注册到注册中心
- 当生产者注册好了之后在启动消者(consumer),消费者启动之后会从注册中心获取地址
- 这个地址可能不止一个,因为生产者可能有多个 pod,有多个 pod 的话就是多个地址列表。
- 这时候消费者就会轮询一遍该列表,如果只有一个生产者那只能调用该生产者,如果有多个就挨着每个生产者轮询调用一遍
- 并且当消费者起来之后会发起订阅(subscribe)
- 就是一旦生产者的地址发生变化或者服务器状态发生变化(比如这时候生产者的 pod 副本数在多一个呢?这时候就会有 3 个 server 端,并且都会注册到注册中心中),这时注册中心就会主动通知(notify)消费者说生产者的地址发生变化,这样我们的消费者就能拿到最新的生产者
- 如果是我们的生产者 pod 挂了,这时注册中心也会及时发现并通知消费者,消费者得到消息之后也不会再去调用挂掉的 pod ,而是调用剩下可用的 pod
角色说明:
- provider:服务提供方
- consumer:服务消费方
- registry:服务注册与发现的注册中心
- monitor:统计服务的调用次数和调用时间的监控中心
- container:服务运行容器
调用关系说明:
0.服务器负责启动、加载、运行服务提供者
1.服务提供者在启动时,向注册中心注册自己提供的服务
2.服务消费者在启动时,向注册中心订阅自己所需的服务
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
4.服务消费者,从提供者列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,更换另一台调用
5.服务消费者和服务提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
8.4 部署流程
注意:
zookeeper 起来之后我们就将微服务跑进来,在整个部署流程中的启动顺序:
- 部署生产者(server)
- 如果是先部署消费者的话,消费者对应的 pod 被拉起来就会立马向生产者进行访问就会报错
- 部署消费者
- 并且在部署期间使用的镜像也需要我们自己构建,因为在构建的时候要告诉镜像我们的注册中心在什么地方,有的时候还要连接数据库、还要链接存储 redis 等,都需要在配置文件中指定
注册中心这里使用在 K8S 实战系列:zookeeper 集群 部署的 zookeeper 即可
[21:22:56 root@k8s-master ~]#kubectl get pod -n zookeeper
NAME READY STATUS RESTARTS AGE
zookeeper1-77548f5584-rfwgk 1/1 Running 2 34h
zookeeper2-db4d698d7-2hktl 1/1 Running 2 34h
zookeeper3-867cc94cc6-bpl6w 1/1 Running 3 34h
8.4.1 部署生产者
8.4.1.1 构建生产者镜像
1.该镜像目录文件解释
[21:41:51 root@k8s-master provider]#pwd
/root/k8sMicroservices/dubbo/dockerfile/provider
[21:46:43 root@k8s-master provider]#tree
.
├── build-command.sh # 构建脚本
├── Dockerfile # docker 镜像文件
├── dubbo-demo-provider-2.1.5 # dubbo 对应的启动文件和配置文件
│ ├── bin # dubbo 启动文件
│ │ ├── dump.sh
│ │ ├── restart.sh
│ │ ├── server.sh
│ │ ├── start.bat
│ │ ├── start.sh
│ │ └── stop.sh
│ ├── conf # dubbo 配置文件
│ │ └── dubbo.properties
│ └── lib # dubbo 库文件
│ ├── cache-api-0.4.jar
│ ├── commons-codec-1.4.jar
│ ├── commons-logging-1.1.1.jar
│ ├── commons-pool-1.5.5.jar
│ ├── dubbo-2.1.5.jar
│ ├── dubbo-demo-2.1.5.jar
│ ├── dubbo-demo-provider-2.1.5.jar
│ ├── fastjson-1.1.8.jar
│ ├── gmbal-api-only-3.0.0-b023.jar
│ ├── grizzly-core-2.1.4.jar
│ ├── grizzly-framework-2.1.4.jar
│ ├── grizzly-portunif-2.1.4.jar
│ ├── grizzly-rcm-2.1.4.jar
│ ├── hessian-4.0.7.jar
│ ├── hibernate-validator-4.2.0.Final.jar
│ ├── httpclient-4.1.2.jar
│ ├── httpcore-4.1.2.jar
│ ├── javassist-3.15.0-GA.jar
│ ├── jedis-2.0.0.jar
│ ├── jetty-6.1.26.jar
│ ├── jetty-util-6.1.26.jar
│ ├── jline-0.9.94.jar
│ ├── log4j-1.2.16.jar
│ ├── management-api-3.0.0-b012.jar
│ ├── mina-core-1.1.7.jar
│ ├── netty-3.2.5.Final.jar
│ ├── servlet-api-2.5-20081211.jar
│ ├── slf4j-api-1.6.2.jar
│ ├── spring-2.5.6.SEC03.jar
│ ├── validation-api-1.0.0.GA.jar
│ └── zookeeper-3.3.3.jar
├── dubbo-demo-provider-2.1.5-assembly.tar.gz # dubbo 安装包
└── run_java.sh # 启动容器后台运行脚本
2.先编写配置文件,需要在配置文件中指定注册中心地址
[21:41:36 root@k8s-master provider]#vim dubbo-demo-provider-2.1.5/conf/dubbo.properties
##
# Copyright 1999-2011 Alibaba Group.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
dubbo.container=log4j,spring
dubbo.application.name=demo-provider
dubbo.application.owner=
#dubbo.registry.address=multicast://224.5.6.7:1234
dubbo.registry.address=zookeeper://zookeeper1.zookeeper.svc.linux.local:2181 | zookeeper://zookeeper2.zookeeper.svc.linux.local:2181 | zookeeper://zookeeper3.zookeeper.svc.linux.local:2181
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090
dubbo.monitor.protocol=registry
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.log4j.file=logs/dubbo-demo-provider.log
dubbo.log4j.level=WARN
# dubbo.registry.address 注册地址后面写的都是对应的 zookeeper pod 的 DNS 解析进行注册,因为我这个 K8S 中有 3 个 zookeeper 所以我这里分别写了 3 个不同的 zookeeper pod
2.编写 Dockerfile
这里采用的是我们在前面几个实验中就做好的 jdk 基础镜像
[21:45:06 root@k8s-master provider]#cat Dockerfile
#Dubbo provider
FROM hub.zhangguiyuan.com/baseimage/jdk-base:v8.212
MAINTAINER zhangguiyuan
RUN yum install file nc -y
RUN mkdir -p /apps/dubbo/provider
# 添加 dubbo 程序和配置文件
ADD dubbo-demo-provider-2.1.5/ /apps/dubbo/provider
ADD run_java.sh /apps/dubbo/provider/bin
# jdk-base:v8.212 基础镜像是通过 nginx 来启动,所以为了避免权限问题,最好也通过 nginx 来启动
RUN chown nginx.nginx /apps -R
RUN chmod a+x /apps/dubbo/provider/bin/*.sh
CMD ["/apps/dubbo/provider/bin/run_java.sh"]
3.编写后台脚本
[21:48:17 root@k8s-master provider]#cat run_java.sh
#!/bin/bash
su - nginx -c "/apps/dubbo/provider/bin/start.sh"
tail -f /etc/hosts
4.编写构建脚本
[21:50:20 root@k8s-master provider]#vim build-command.sh
#!/bin/bash
docker build -t hub.zhangguiyuan.com/baseimage/dubbo-demo-provider:v1 .
sleep 3
docker push hub.zhangguiyuan.com/baseimage/dubbo-demo-provider:v1
5.加上执行权限
[21:50:21 root@k8s-master provider]#chmod +x *.sh
6.执行构建脚本
[21:54:22 root@k8s-master provider]#. build-command.sh
构建完脚本之后,我们在来启动该脚本他就会自动的注册到注册中心,也就是我们的 3 个 zookeeper pod
[21:56:31 root@k8s-master provider]#kubectl get pod -n zookeeper -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
zookeeper1-77548f5584-rfwgk 1/1 Running 2 34h 10.10.113.146 k8s-node <none> <none>
zookeeper2-db4d698d7-2hktl 1/1 Running 2 34h 10.10.113.142 k8s-node <none> <none>
zookeeper3-867cc94cc6-bpl6w 1/1 Running 3 34h 10.10.169.145 k8s-node2 <none> <none>
8.4.1.2 编写 yaml 文件并创建 pod
1.编写 yaml
[22:03:07 root@k8s-master provider]#pwd
/root/k8sMicroservices/dubbo/yaml/provider
# 这里我将他放到了 zookeeper namespace 下
[22:07:00 root@k8s-master provider]#cat provider.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: dubbo-provider
name: dubbo-provider-deployment
namespace: zookeeper
spec:
replicas: 1
selector:
matchLabels:
app: dubbo-provider
template:
metadata:
labels:
app: dubbo-provider
spec:
containers:
- name: dubbo-provider-container
image: hub.zhangguiyuan.com/baseimage/dubbo-demo-provider:v1
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 20880 # 容器端口开启 20880 主要是给不同程序之间调用使用
protocol: TCP
name: http
---
kind: Service
apiVersion: v1
metadata:
labels:
app: dubbo-provider
name: dubbo-provider-spec
namespace: zookeeper
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 20880
#nodePort: 30001 一般情况下是不需要固定 nodeport
selector:
app: dubbo-provider
2.创建
[22:09:59 root@k8s-master provider]#kubectl apply -f provider.yaml
# 启动
[22:36:55 root@k8s-master provider]#kubectl get pod -n zookeeper -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
dubbo-provider-deployment-54f6fdfb98-ksmph 1/1 Running 0 30m 10.10.235.204 k8s-master <none> <none>
zookeeper1-77548f5584-rfwgk 1/1 Running 2 35h 10.10.113.146 k8s-node <none> <none>
zookeeper2-db4d698d7-2hktl 1/1 Running 2 35h 10.10.113.142 k8s-node <none> <none>
zookeeper3-867cc94cc6-bpl6w 1/1 Running 3 35h 10.10.169.145 k8s-node2 <none> <none>
8.4.1.3 验证
构建好镜像之后尽量都将其启动为容器验证一下,以避免工作中的其他问题
启动之后到底是否注册到了注册中心呢?我们可以链接 zookeeper 看一下
这里我通过 zk 客户端进行查看
登录至 zookeeper 暴露的 nodeport
并且已经注册成功,而且这个地址就是 dubbo 的 pod 地址
接下来就开始创建我们的消费者
8.4.2 部署消费者
消费者也需要和生产者链接同一个注册中心
8.4.2.1 构建消费者镜像
1.目录结构
[22:43:26 root@k8s-master consumer]#pwd
/root/k8sMicroservices/dubbo/dockerfile/consumer
[22:43:31 root@k8s-master consumer]#tree
.
├── build-command.sh
├── Dockerfile
├── dubbo-demo-consumer-2.1.5
│ ├── bin
│ │ ├── dump.sh
│ │ ├── restart.sh
│ │ ├── server.sh
│ │ ├── start.bat
│ │ ├── start.sh
│ │ └── stop.sh
│ ├── conf
│ │ └── dubbo.properties
│ └── lib
│ ├── cache-api-0.4.jar
│ ├── commons-codec-1.4.jar
│ ├── commons-logging-1.1.1.jar
│ ├── commons-pool-1.5.5.jar
│ ├── dubbo-2.1.5.jar
│ ├── dubbo-demo-2.1.5.jar
│ ├── dubbo-demo-consumer-2.1.5.jar
│ ├── fastjson-1.1.8.jar
│ ├── gmbal-api-only-3.0.0-b023.jar
│ ├── grizzly-core-2.1.4.jar
│ ├── grizzly-framework-2.1.4.jar
│ ├── grizzly-portunif-2.1.4.jar
│ ├── grizzly-rcm-2.1.4.jar
│ ├── hessian-4.0.7.jar
│ ├── hibernate-validator-4.2.0.Final.jar
│ ├── httpclient-4.1.2.jar
│ ├── httpcore-4.1.2.jar
│ ├── javassist-3.15.0-GA.jar
│ ├── jedis-2.0.0.jar
│ ├── jetty-6.1.26.jar
│ ├── jetty-util-6.1.26.jar
│ ├── jline-0.9.94.jar
│ ├── log4j-1.2.16.jar
│ ├── management-api-3.0.0-b012.jar
│ ├── mina-core-1.1.7.jar
│ ├── netty-3.2.5.Final.jar
│ ├── servlet-api-2.5-20081211.jar
│ ├── slf4j-api-1.6.2.jar
│ ├── spring-2.5.6.SEC03.jar
│ ├── validation-api-1.0.0.GA.jar
│ └── zookeeper-3.3.3.jar
├── dubbo-demo-consumer-2.1.5-assembly.tar.gz
└── run_java.sh
2.修改消费者配置文件,指定和生产者的同一个注册中心
[22:45:25 root@k8s-master consumer]#vim dubbo-demo-consumer-2.1.5/conf/dubbo.properties
##
# Copyright 1999-2011 Alibaba Group.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
dubbo.container=log4j,spring
dubbo.application.name=demo-consumer
dubbo.application.owner=
#dubbo.registry.address=multicast://224.5.6.7:1234
dubbo.registry.address=zookeeper://zookeeper1.zookeeper.svc.linux.local:2181 | zookeeper://zookeeper2.zookeeper.svc.linux.local:2181 | zookeeper://zookeeper3.zookeeper.svc.linux.local:2181
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090
dubbo.monitor.protocol=registry
dubbo.log4j.file=logs/dubbo-demo-consumer.log
dubbo.log4j.level=WARN
3.编写 Dockerfile
[22:46:03 root@k8s-master consumer]#vim Dockerfile
#Dubbo consumer
FROM hub.zhangguiyuan.com/baseimage/jdk-base:v8.212
MAINTAINER zhangguiyuan
RUN yum install file -y
RUN mkdir -p /apps/dubbo/consumer
ADD dubbo-demo-consumer-2.1.5 /apps/dubbo/consumer
ADD run_java.sh /apps/dubbo/consumer/bin
RUN chown nginx.nginx /apps -R
RUN chmod a+x /apps/dubbo/consumer/bin/*.sh
CMD ["/apps/dubbo/consumer/bin/run_java.sh"]
3.编写后台运行脚本
[22:46:35 root@k8s-master consumer]#cat run_java.sh
#!/bin/bash
su - nginx -c "/apps/dubbo/consumer/bin/start.sh"
tail -f /etc/hosts
4.编写构建脚本
[22:47:37 root@k8s-master consumer]#vim build-command.sh
#!/bin/bash
docker build -t hub.zhangguiyuan.com/baseimage/dubbo-demo-consumer:v1 .
sleep 3
docker push hub.zhangguiyuan.com/baseimage/dubbo-demo-consumer:v1
5.添加执行权限
[22:48:18 root@k8s-master consumer]#chmod +x *.sh
6.执行构建脚本
[22:48:26 root@k8s-master consumer]#. build-command.sh
8.4.2.2 编写 yaml 文件并创建 pod
1.编写 yaml
[22:49:30 root@k8s-master consumer]#pwd
/root/k8sMicroservices/dubbo/yaml/consumer
[22:52:21 root@k8s-master consumer]#cat consumer.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: dubbo-consumer
name: dubbo-consumer-deployment
namespace: zookeeper # 尽量指定和生产者在同一个命名空间
spec:
replicas: 1
selector:
matchLabels:
app: dubbo-consumer
template:
metadata:
labels:
app: dubbo-consumer
spec:
containers:
- name: dubbo-consumer-container
image: hub.zhangguiyuan.com/baseimage/dubbo-demo-consumer:v1
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
name: http
---
kind: Service
apiVersion: v1
metadata:
labels:
app: dubbo-consumer
name: dubbo-consumer-server
namespace: zookeeper
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
#nodePort: 30001
selector:
app: dubbo-consumer
2.创建
[22:52:22 root@k8s-master consumer]#kubectl apply -f consumer.yaml
3.查看已经运行,并且消费者起来之后也会将自己注册到 zookeeper 中,而且起来之后会立即去调用生产者,所以生产者应该很快就有调用日志
[22:54:04 root@k8s-master consumer]#kubectl get pod -n zookeeper -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
dubbo-consumer-deployment-5c5f545d87-4nh5t 1/1 Running 0 42s 10.10.235.205 k8s-master <none> <none>
dubbo-provider-deployment-54f6fdfb98-ksmph 1/1 Running 0 44m 10.10.235.204 k8s-master <none> <none>
zookeeper1-77548f5584-rfwgk 1/1 Running 2 35h 10.10.113.146 k8s-node <none> <none>
zookeeper2-db4d698d7-2hktl 1/1 Running 2 35h 10.10.113.142 k8s-node <none> <none>
zookeeper3-867cc94cc6-bpl6w 1/1 Running 3 35h 10.10.169.145 k8s-node2 <none> <none>
# 消费者 pod ip 10.10.235.205
8.4.2.3 验证
1.查看生产者日志
# 进入生产者 pod
[22:57:19 root@k8s-master consumer]#kubectl exec -it -n zookeeper dubbo-provider-deployment-54f6fdfb98-ksmph /bin/bash
# 进入日志目录
[root@dubbo-provider-deployment-54f6fdfb98-ksmph /]# cd apps/dubbo/provider/logs/
# 查看输出日志已经调用 10.10.235.205 消费者 pod
[root@dubbo-provider-deployment-54f6fdfb98-ksmph logs]# cat stdout.log
..............................
[22:56:58] Hello world104, request from consumer: /10.10.235.205:57620
[22:57:00] Hello world105, request from consumer: /10.10.235.205:57620
[22:57:02] Hello world106, request from consumer: /10.10.235.205:57620
[22:57:04] Hello world107, request from consumer: /10.10.235.205:57620
[22:57:06] Hello world108, request from consumer: /10.10.235.205:57620
[22:57:08] Hello world109, request from consumer: /10.10.235.205:57620
[22:57:10] Hello world110, request from consumer: /10.10.235.205:57620
........................
8.4.3 部署 dubbo admin
基于 zookeeper 发现并管理 生产者(provider) 和 消费者(consumer)
部署 dubbo admin 需要通过 tomcat 渲染前端页面
这里的 tomcat 基于 K8S 实战系列:自定义镜像实现 nginx 与 tomcat 动静分离 来做基础镜像
8.4.3.1 构建 dubbo amdin 镜像
1.编写配置文件
[23:20:49 root@k8s-master dubboadmin]#pwd
/root/k8sMicroservices/dubbo/dockerfile/dubboadmin
# 在配置文件将 admin 指定链接到 zookeeper 注册中心,因为需要链接至 zookeeper 发现生产者和消费者并进行管理
[23:21:15 root@k8s-master dubboadmin]#vim dubbo.properties
dubbo.registry.address=zookeeper://zookeeper1.zookeeper.svc.linux.local:2181
dubbo.admin.root.password=root # 登录账户
dubbo.admin.guest.password=guest # 登录密码
2.编写 dockerfile
[23:26:52 root@k8s-master dubboadmin]#vim Dockerfile
#Dubbo dubboadmin
FROM hub.zhangguiyuan.com/baseimage/tomcat-base:v8.5.43
MAINTAINER zhangguiyaun
RUN yum install unzip -y
ADD server.xml /apps/tomcat/conf/server.xml
ADD logging.properties /apps/tomcat/conf/logging.properties
ADD catalina.sh /apps/tomcat/bin/catalina.sh
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
# 要求 tomcat 能够在加载的时候加载 /data/tomcat/webapps/ 这个目录下的 war 包
ADD dubboadmin.war /data/tomcat/webapps/dubboadmin.war
RUN cd /data/tomcat/webapps && unzip dubboadmin.war && rm -rf dubboadmin.war && chown -R nginx.nginx /data /apps
# 将我们修改好的配置文件添加到镜像中
COPY dubbo.properties /data/tomcat/webapps/dubboadmin/WEB-INF/dubbo.properties
EXPOSE 8080 8443
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
3.编写 server.xml 文件,指定 /data/tomcat/webapps/
目录,这个作为 tomcat 的 web / 目录
[23:35:14 root@k8s-master dubboadmin]#cat server.xml | grep 'data/tomcat/webapps'
<Host appBase="/data/tomcat/webapps" autoDeploy="true" name="localhost" unpackWARs="true">
4.编写构建脚本
[23:37:06 root@k8s-master dubboadmin]#vim build-command.sh
#!/bin/bash
TAG=$1
docker build -t hub.zhangguiyuan.com/baseimage/dubboadmin:${TAG} .
sleep 3
docker push hub.zhangguiyuan.com/baseimage/dubboadmin:${TAG}
5.编写启动 tomcat 后台程序脚本
[23:38:50 root@k8s-master dubboadmin]#cat run_tomcat.sh
#!/bin/bash
su - nginx -c "/apps/tomcat/bin/catalina.sh start"
su - nginx -c "tail -f /etc/hosts"
6.添加执行权限
[23:35:24 root@k8s-master dubboadmin]#chmod +x *.sh
7.构建镜像
[23:38:51 root@k8s-master dubboadmin]#. build-command.sh v1
8.4.3.2 编写 yaml
1.编写 yaml
[00:12:32 root@k8s-master dubboadmin]#pwd
/root/k8sMicroservices/dubbo/yaml/dubboadmin
[23:42:19 root@k8s-master dubboadmin]#cat dubboadmin.yaml
kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: dubboadmin
name: dubboadmin-deployment
namespace: zookeeper
spec:
replicas: 1
selector:
matchLabels:
app: dubboadmin
template:
metadata:
labels:
app: dubboadmin
spec:
containers:
- name: dubboadmin-container
image: hub.zhangguiyuan.com/baseimage/dubboadmin:v1
#command: ["/apps/tomcat/bin/run_tomcat.sh"]
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
name: http
---
kind: Service
apiVersion: v1
metadata:
labels:
app: dubboadmin
name: dubboadmin-service
namespace: zookeeper
spec:
type: NodePort
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
nodePort: 30080
selector:
app: dubboadmin
2.启动
[23:42:48 root@k8s-master dubboadmin]#kubectl apply -f dubboadmin.yaml
3.pod 已经创建
[23:43:25 root@k8s-master dubboadmin]#kubectl get pod -n zookeeper
NAME READY STATUS RESTARTS AGE
dubbo-consumer-deployment-5c5f545d87-4nh5t 1/1 Running 0 50m
dubbo-provider-deployment-54f6fdfb98-ksmph 1/1 Running 0 93m
dubboadmin-deployment-65c49fddd9-tt8v7 1/1 Running 0 5s
zookeeper1-77548f5584-rfwgk 1/1 Running 2 36h
zookeeper2-db4d698d7-2hktl 1/1 Running 2 36h
zookeeper3-867cc94cc6-bpl6w 1/1 Running 3 36h
8.4.3.3 浏览器验证
访问暴露的 svc 30080 端口
账户:root
密码:root
可以按照机器或者角色来进行查询,提供者就是生产者,我们可以看到对应的生产者 ip 就是生产者 pod 的 ip
一般保持默认就可以,不用配置
查看是否能够链接注册中心,链接不上的注册中心状态就不会是正常