學(xué)習(xí)日志 21-12-17 部署Java微服務(wù) 微服務(wù)互調(diào)
# 1217
# 部署java應(yīng)用的鏡像
## 檢查昨天創(chuàng)建的私有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也會變
? - 后續(xù)不做minikube stop start了, 改為在hyper-v中對minikube做保存/重啟
? - ssh登錄minikube vm, 重新做certs 和 registry目錄
? - 重新生成證書, 下載證書, 重新在windows中安裝該證書
? - 刪除舊證書 在控制面版中搜索證書 用戶證書 -> 中間證書頒發(fā)機構(gòu) 按日期找到舊證書 刪除
? - docker客戶端重啟一下
? - 修改 etc/hosts 采用新IP
? - 重新push docker image
## 將Java應(yīng)用鏡像部署到k8s
- 直接在開發(fā)機 做 docker Apply
? - 解決ImagePullBackOff 問題, 見Q&A部分
? - 檢查kubectl get deployments 發(fā)現(xiàn)新的Java應(yīng)用已經(jīng)成功啟動
? - 如未啟動 可以嘗試 kubectl rollout restart
- 校驗java應(yīng)用能否正常使用
? - 嘗試 `exec -- bash` 的方式
? ? - 發(fā)現(xiàn)linux-slim鏡像沒有curl工具
? - 創(chuàng)建service
? ? - copy一個service的yaml部分, 添加到原yaml的下面
? ? - yaml是不變的部分不執(zhí)行, 新增/修改的部分才會被k8s執(zhí)行
? ? - 可以重復(fù)Apply沒問題
? - Apply后, 走外部端口訪問
? ? - 網(wǎng)絡(luò)不通, 見Q&A第二個問題
? - 檢查日志 `kubectl logs <pod名>`
? ? - 發(fā)現(xiàn)是spring-boot的啟動日志 一切正常
? - 結(jié)果 外部端口訪問成功
? ? - 在開發(fā)機訪問類似 http://172.26.85.189:31000/
- 總結(jié)
? - k8s的pre-pulled image實際上就是minikube node(control plan) 上做docker pull
? - k8s Apply 能否成功, 也依賴于minikube node能否直接靠自己的docker客戶端 pull到image
? - 如果pull不到, 從docker客戶端的角度解決問題即可
? - k8s需要經(jīng)常自己pull image, 就是怕有l(wèi)atest的情況, 它每次啟動都需要重pull image
? - 參考 上述 imagePullPolicy
### Q&A
- Q: 新建的pod 處理 ImagePullBackOff 狀態(tài)
- A: 從minikube集群無法使用新建的私有docker registry倉庫
? - 網(wǎng)絡(luò)不通 minikube 不認(rèn)識k8s-master這個域名
? ? - 登錄minikube節(jié)點 編輯/etc/hosts 把k8s-master域名直接指向minikube的ip
? - 沒有證書
? ? - 根據(jù) https://docs.docker.com/engine/security/certificates/
? ? - 登錄minikube節(jié)點 創(chuàng)建 /etc/docker/certs.d/k8s-master:31320 目錄
? ? - 注意:31320是目錄名的一部分, linux目錄名可以支持:
? ? - 在該目錄下創(chuàng)建ca.crt文件, 把之前私有registry的證書, crt的那份, 內(nèi)容復(fù)制進去
? - 重新docker pull 可以發(fā)現(xiàn)從minikube節(jié)點可以pull到image了
- Q: 新建的service, 外部訪問網(wǎng)絡(luò)不通
- A: 檢查service的yaml配置, 發(fā)現(xiàn) selector App這部分寫錯了
? - 修改為正確的App 即 springbootdemo
? - 重新Apply
# 微服務(wù)內(nèi)部調(diào)用
## 目標(biāo)
- 實現(xiàn)在K8s上部署兩個微服務(wù), A和B, 實現(xiàn)A調(diào)用B
## 實現(xiàn)
- 基于之前的springbootdemo 該微服務(wù)已經(jīng)提供了restful的/路徑
? - 還提供了一個service 類型是nodeport, 內(nèi)部端口8080 外部端口31000
? - service的名字是 springbootdemo-service
? - 該服務(wù)作為我們的被調(diào)用者
? - 測試 從開發(fā)機訪問 minikube_ip:31000/
? - 類似 http://172.26.85.189:31000/
- 調(diào)用者 搞個新的Java工程
? - 從start.spring.io上搞一個springboot + web的標(biāo)準(zhǔn)工程
? - 創(chuàng)建一個RequestMApping
? - 采用Java 11的httpclient 調(diào)用 上述 提供者的微服務(wù)
? - 重點參數(shù)
? ? - host : springbootdemo-service
? ? ? - 即k8s service的名字
? ? ? - k8s會負(fù)責(zé)讓所有pod運行環(huán)境都知道這個service名對應(yīng)的ip地址
? ? ? - 類似DNS解析
? ? - port : 使用該service的內(nèi)部端口 8080
? ? ? - 注意這里不是外部端口31000
? ? - 只需注意以上兩個參數(shù)即可調(diào)通
? - 重點代碼
? ? ```
? ? @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異步調(diào)用方式
- 制作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包的名字改一下即可
? - 執(zhí)行 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調(diào)用者的微服務(wù)
? - 參考 提供者 springbootdemo的k8s.yaml
? - 把所有springbootdemo單詞都替換成springbootdemocaller
? - 修改外部端口號 為 32000 (31000已被占用, 也不能用私有倉庫占用的31320)
? - kubectl Apply 即可
- 驗證結(jié)果
? - 從開發(fā)機訪問 http://172.26.85.189:32000/