欢迎光临散文网 会员登陆 & 注册

学习日志 21-12-17 部署Java微服务 微服务互调

2021-12-17 16:33 作者:mayoiwill  | 我要投稿

# 1217


# 部署java应用的镜像


## 检查昨天创建的私有docker registry

- 出了好多问题, 见下Q&A


### Q&A

- Q: deployment 启不来, ready一直是0

- A: 原因是node minikube 重启后 /opt/certs /opt/registry目录都没了

  - 每次minikube stop 再 start后, /opt/certs 和 /opt/registry 目录都会消失

  - 而且minikube的 ip也会变

  - 后续不做minikube stop start了, 改为在hyper-v中对minikube做保存/重启

  - ssh登录minikube vm, 重新做certs 和 registry目录

  - 重新生成证书, 下载证书, 重新在windows中安装该证书

  - 删除旧证书 在控制面版中搜索证书 用户证书 -> 中间证书颁发机构 按日期找到旧证书 删除

  - docker客户端重启一下

  - 修改 etc/hosts 采用新IP

  - 重新push docker image


## 将Java应用镜像部署到k8s

- 直接在开发机 做 docker Apply

  - 解决ImagePullBackOff 问题, 见Q&A部分

  - 检查kubectl get deployments 发现新的Java应用已经成功启动

  - 如未启动 可以尝试 kubectl rollout restart

- 校验java应用能否正常使用

  - 尝试 `exec -- bash` 的方式

    - 发现linux-slim镜像没有curl工具

  - 创建service

    - copy一个service的yaml部分, 添加到原yaml的下面

    - yaml是不变的部分不执行, 新增/修改的部分才会被k8s执行

    - 可以重复Apply没问题

  - Apply后, 走外部端口访问

    - 网络不通, 见Q&A第二个问题

  - 检查日志 `kubectl logs <pod名>`

    - 发现是spring-boot的启动日志 一切正常

  - 结果 外部端口访问成功

    - 在开发机访问类似 http://172.26.85.189:31000/

- 总结

  - k8s的pre-pulled image实际上就是minikube node(control plan) 上做docker pull

  - k8s Apply 能否成功, 也依赖于minikube node能否直接靠自己的docker客户端 pull到image

  - 如果pull不到, 从docker客户端的角度解决问题即可

  - k8s需要经常自己pull image, 就是怕有latest的情况, 它每次启动都需要重pull image

  - 参考 上述 imagePullPolicy


### Q&A

- Q: 新建的pod 处理 ImagePullBackOff 状态

- A: 从minikube集群无法使用新建的私有docker registry仓库

  - 网络不通 minikube 不认识k8s-master这个域名

    - 登录minikube节点 编辑/etc/hosts 把k8s-master域名直接指向minikube的ip

  - 没有证书

    - 根据 https://docs.docker.com/engine/security/certificates/

    - 登录minikube节点 创建 /etc/docker/certs.d/k8s-master:31320 目录

    - 注意:31320是目录名的一部分, linux目录名可以支持:

    - 在该目录下创建ca.crt文件, 把之前私有registry的证书, crt的那份, 内容复制进去

  - 重新docker pull 可以发现从minikube节点可以pull到image了

- Q: 新建的service, 外部访问网络不通

- A: 检查service的yaml配置, 发现 selector App这部分写错了

  - 修改为正确的App 即 springbootdemo

  - 重新Apply


# 微服务内部调用


## 目标

- 实现在K8s上部署两个微服务, A和B, 实现A调用B


## 实现

- 基于之前的springbootdemo 该微服务已经提供了restful的/路径

  - 还提供了一个service 类型是nodeport, 内部端口8080 外部端口31000

  - service的名字是 springbootdemo-service

  - 该服务作为我们的被调用者

  - 测试 从开发机访问 minikube_ip:31000/

  - 类似 http://172.26.85.189:31000/

- 调用者 搞个新的Java工程

  - 从start.spring.io上搞一个springboot + web的标准工程

  - 创建一个RequestMApping

  - 采用Java 11的httpclient 调用 上述 提供者的微服务

  - 重点参数

    - host : springbootdemo-service

      - 即k8s service的名字

      - k8s会负责让所有pod运行环境都知道这个service名对应的ip地址

      - 类似DNS解析

    - port : 使用该service的内部端口 8080

      - 注意这里不是外部端口31000

    - 只需注意以上两个参数即可调通

  - 重点代码

    ```

    @RequestMApping("/")

    public DeferredResult<String> home() {

        DeferredResult<String> result = new DeferredResult<>();

        HttpClient client = HttpClient.newHttpClient();

        HttpRequest request = HttpRequest.newBuilder()

                .uri(URI.create("http://springbootdemo-service:8080" ))

                .build();

        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())

                .thenApply(HttpResponse::body)

                .thenAccept(it -> {

                    result.setResult("get resp from springbootdemo-service:8080 : \n" +

                            it);

                })

                .join();

        return result;

    }

    ```

  - 其它说明

    - 该controller使用了DeferredResult<String>异步方式

    - 配合httpclient异步调用方式

- 制作Docker image

  - 参考上文

  - 因为使用了变量${project.artifactId} 所以什么都不用改

    ```

            <plugin>

                <groupId>com.spotify</groupId>

                <artifactId>dockerfile-maven-plugin</artifactId>

                <version>1.4.13</version>

                <configuration>

                    <dockerfile>Dockerfile</dockerfile>

                    <repository>${project.artifactId}</repository>

                </configuration>

            </plugin>

    ```

  - 编写Dockerfile

    - 参考之前springbootdemo的Dockerfile

    - 修改点 把COPY 和 CMD 指令 jar包的名字改一下即可

  - 执行 mvn package 和 mvn dockerfile:build

  - 我们这里没写tag, 也没指定使用私有docker仓库k8s-master

  - 这些我们手动操作 见下

- 上传Docker镜像

  - 使用docker tag 命令对本地的springbootdemocaller:latest 重新命名

  - 为 k8s-master:31320/springbootdemocaller:1.0.0

  - 之后把该本地镜像 push 给私有仓库

- 编写 k8s.yaml 部署k8s调用者的微服务

  - 参考 提供者 springbootdemo的k8s.yaml

  - 把所有springbootdemo单词都替换成springbootdemocaller

  - 修改外部端口号 为 32000 (31000已被占用, 也不能用私有仓库占用的31320)

  - kubectl Apply 即可

- 验证结果

  - 从开发机访问 http://172.26.85.189:32000/


学习日志 21-12-17 部署Java微服务 微服务互调的评论 (共 条)

分享到微博请遵守国家法律