image.png

把服务做到镜像里

下载基础镜像

  1. docker pull hub.hexiaodai.com/kubernetes/openjdk:8-jre-alpine

打包项目(MVN 构建项目)

[root@m1 mooc-k8s-demo-docker]# ll
drwxr-xr-x. 4 root root   86 12月 13 13:07 dubbo-demo
drwxr-xr-x. 4 root root   72 12月 13 13:07 dubbo-demo-api

# mvn install
[root@m1 mooc-k8s-demo-docker]# cd dubbo-demo-api
[root@m1 dubbo-demo-api]# mvn install

# mvn package
[root@m1 dubbo-demo-api]# cd ../dubbo-demo
[root@m1 dubbo-demo]# mvn package

本地启动项目

[root@m1 target]# ll
-rw-r--r--. 1 root root 12068084 12月 13 22:23 dubbo-demo-1.0-SNAPSHOT-assembly.tar.gz
-rw-r--r--. 1 root root     3491 12月 13 22:23 dubbo-demo-1.0-SNAPSHOT.jar

# 解压
[root@m1 target]# tar zxvf dubbo-demo-1.0-SNAPSHOT-assembly.tar.gz

[root@m1 target]# cd bin/
[root@m1 bin]# ls
start.sh  stop.sh

# 启动项目
[root@m1 bin]# sh ./start.sh
Starting the demo ...PID: 65660
STDOUT: /root/mooc-k8s-demo-docker/dubbo-demo/target/logs/stdout.log

# 停止项目
[root@m1 bin]# ./start.sh
Starting the demo ...PID: 65660
STDOUT: /root/mooc-k8s-demo-docker/dubbo-demo/target/logs/stdout.log

# telnet 查看项目
[root@m1 bin]# telnet 127.0.0.1 20880
Trying 127.0. 0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
dubbo>ls
com.mooc.demo.api.DemoService
dubbo>ls com.mooc.demo.api.DemoService
sayHello
dubbo>invoke com.mooc.demo.api.DemoService.sayHello("hexiaodai")
"Hello hexiaodai"
elapsed: 2 ms.
dubbo>exit
Connection closed by foreign host.

构建镜像 - Dockerfile

将服务运行的相关文件 mv 到 ./ROOT 文件加下

[root@m1 target]# mkdir ROOT
[root@m1 target]# mv dubbo-demo-1.0-SNAPSHOT-assembly.tar.gz ROOT/
[root@m1 target]# cd ROOT
[root@m1 ROOT]# tar zxvf dubbo-demo-1.0-SNAPSHOT-assembly.tar.gz
# 这些文件是需要放入 docker 中的文件
[root@m1 ROOT]# ll
drwxrwxrwx. 2 root root       37 12月 13 13:07 bin
drwxrwxrwx. 3 root root       61 12月 13 13:07 conf
drwxr-xr-x. 2 root root     4096 12月 13 22:50 lib
FROM hub.hexiaodai.com/kubernetes/openjdk:8-jre-alpine

COPY target/ROOT /ROOT

ENTRYPOINT ["sh", "/ROOT/bin/start.sh"]

build

docker build -t dubbo:v1 .

测试镜像

docker run -it dubbo:v1

发布镜像

docker tag dubbo:v1 hub.hexiaodai.com/kubernetes/dubbo:v1

docker push hub.hexiaodai.com/kubernetes/dubbo:v1

制作 k8s 服务,并调度

确定服务发现策略

ingress-nginx

host 模式

host 模式,相当于是在主机上直接运行了一个 provider,跟在主机上运行的效果是一样的,可以将 provider 的真实 ip 写入 zookeeper。
image.png

小问题(端口冲突问题)

如果一台宿主机上有多个 dubb 服务,一个 dubb 服务占用了 20880 端口,那么其它 dubb 服务就不能在使用 20880 这个端口了,如果使用 host 模式,就必须保证每个 dubb 服务的端口不一样。

如何保证呢?

我们不可能限制应用方只能使用某个端口(不能把端口写死),万一新同事修改了该端口号,那就 GG 了

解决法案

通过 k8s 的配置,给 dubb 服务指定端口,在启动的时候 dubb 服务就可以用到这个端口,相当于是把修改 dubb 服务端口的权利集中在一起了,管理 k8s 配置的人可以统一的去配置 dubb 服务的端口,保证 端口不会冲突。
image.png

桥接模式

由于使用了 zookeeper,会产生一些问题;provider 注册到 zookeeper,consumer 会使用 172.22.0.1 访问 provider,如果 3 者都是在 k8s 集群内部的服务,是没有问题的,可以访问到服务的 ip。如果 consumer 是 k8s 集群外部的 ip,那么它是无法访问 127.22.0.1 ip 的。

解决方案

在容器启动的时候,给 provider 指定一个环境变量,设置为宿主机的真实 ip;由于 pod 启动的时候,pod 无法拿到宿主机的 ip,所以只能通过文件挂载的方式,在宿主机上写一个文件,将宿主机的 ip 写入文件中,在把这个文件挂载到容器里,之后 provider 就可以读取到宿主机的真实 ip

# start.sh
# 支持自定义写入 port
if [ -z "${DUBBO_PORT}" ]; then
    sed -i "s/dubbo.protocol.port=${SERVER_PORT}/dubbo.protocol.port=${DUBBO_PORT}/g" conf/dubbo.properties
    SERVER_PORT=${DUBBO_PORT}
fi

缺点

性能差,非常麻烦
image.png

发布镜像

docker build -t dubbo:v1 .

docker tag dubbo :v1 hub.hexiaodai.com/kubernetes/dubbo:v1

docker push hub.hexiaodai.com/kubernetes/dubbo:v1

编写 k8s 配置文件

#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dubb-demo
spec:
  selector:
    matchLabels:
      app: dubb-demo
  replicas: 1
  template:
    metadata:
      labels:
        app: dubb-demo
    spec:
      # 定义 host 网络模式
      hostNetwork: true
      # 亲和性调度,多个 dubbo 实例不会调度在同一个节点上,从而产生端口冲突
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - dubb-demo
            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: dubb-demo
        image: hub.hexiaodai.com/kubernetes/dubbo:v1
        ports:
        - containerPort: 20881
        env:
        # 定义 dubbo 服务端口
        - name: DUBBO_PORT
          value: "20881"
kubectl apply -f dubbo-demo.yaml

查看 dubbo-demo 运行情况

[root@m1 nginx]# k get pod -o wide
NAME                                  READY   STATUS             RESTARTS   AGE     IP               NODE   NOMINATED NODE   READINESS GATES
dubb-demo-7d5cbc8597-8mwqg            1/1     Running            0          53s     192.168.109.13   s1     <none>           <none>

dubbo-demo 运行在 s1 节点上,我们可以访问它

# telnet 查看项目
[root@m1 bin]# telnet 127.0.0.1 20881
Trying 127.0. 0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
dubbo>ls
com.mooc.demo.api.DemoService
dubbo>ls com.mooc.demo.api.DemoService
sayHello
dubbo>invoke com.mooc.demo.api.DemoService.sayHello("hexiaodai")
"Hello hexiaodai"
elapsed: 2 ms.
dubbo>exit
Connection closed by foreign host.