1. 程式人生 > >spring-cloud-kubernetes官方demo執行實戰

spring-cloud-kubernetes官方demo執行實戰

關於spring-cloud-kubernetes

spring-cloud-kubernetes是springcloud官方推出的開源專案,用於將Spring Cloud和Spring Boot應用執行在kubernetes環境,並且提供了通用的介面來呼叫kubernetes服務,GitHub上官方地址是:https://github.com/spring-cloud/spring-cloud-kubernetes

系列文章列表

本文是《spring-cloud-kubernetes實戰系列》的第一篇,全文連結如下:

  1. 《spring-cloud-kubernetes官方demo執行實戰》
  2. 《你好spring-cloud-kubernetes》
  3. 《spring-cloud-kubernetes背後的三個關鍵知識點》
  4. 《spring-cloud-kubernetes的服務發現和輪詢實戰(含熔斷)》
  5. 《spring-cloud-kubernetes與SpringCloud Gateway》
  6. 《spring-cloud-kubernetes與k8s的configmap》

官方demo

官方提供了簡單的demo用於快速瞭解spring-cloud-kubernetes,但是成功執行此demo需要做一些設定和修改,這也是此文的意義所在,接下來我們一起實戰這個demo;

環境資訊

本次實戰的環境和版本資訊如下:

  1. 作業系統:CentOS Linux release 7.6.1810
  2. minikube:1.1.1
  3. Java:1.8.0_191
  4. Maven:3.6.0
  5. fabric8-maven-plugin外掛:3.5.37
  6. spring-cloud-kubernetes:1.0.1.RELEASE

上面提到的linux、minikube、java、maven,請確保已全部準備好,關於linux環境下minikube的安裝和啟動請參考《Linux安裝minikube指南 》。

下載原始碼

官方demo包含在整個spring-cloud-kubernetes開源專案中,因此要下載整個開源專案,由於主幹的提交一直很活躍,因此最好下載個release版本,我這裡下載的是v1.0.1.RELEASE,如下圖紅框所示,地址是:https://github.com/spring-cloud/spring-cloud-kubernetes/releases

修改maven設定

需要事先修改maven的設定,否則編譯構建的時候會報錯:

  1. 開啟maven的配置檔案settings.xml,完整路徑是apache-maven-3.6.0/conf/settings.xm;
  2. 在settings.xml檔案內,找到pluginGroups節點,在裡面增加兩行,修改完成後效果如下:
<pluginGroups>
    <pluginGroup>io.fabric8</pluginGroup>
    <pluginGroup>org.springframework.boot</pluginGroup>
  </pluginGroups>
  1. 修改完畢儲存退出,maven設定完成;

如果您想了解該錯誤的細節,請參考文章《使用fabric8-maven-plugin外掛的錯誤處理(No plugin found for prefix 'fabric8')》;

編譯專案原始碼

  1. 將上圖中的原始碼下載解壓,得到一個新的資料夾spring-cloud-kubernetes-1.0.1.RELEASE;
  2. 進入資料夾spring-cloud-kubernetes-1.0.1.RELEASE,執行命令mvn clean compile -U,完全編譯整個工程,由於要下載大量依賴庫所以較為耗時,我這裡是二十分鐘以上(這一步不是必須的,看個人愛好吧),構建通過後如下所示:
[INFO] Reactor Summary for Spring Cloud Kubernetes 1.0.1.RELEASE:
[INFO] 
[INFO] Spring Cloud Kubernetes :: Dependencies ............ SUCCESS [  0.077 s]
[INFO] Spring Cloud Kubernetes ............................ SUCCESS [  2.575 s]
[INFO] Spring Cloud Kubernetes :: Core .................... SUCCESS [01:51 min]
[INFO] Spring Cloud Kubernetes :: Config .................. SUCCESS [ 21.357 s]
[INFO] Spring Cloud Kubernetes :: Discovery ............... SUCCESS [  6.473 s]
[INFO] Spring Cloud Kubernetes :: Ribbon .................. SUCCESS [ 31.616 s]
[INFO] Spring Cloud Kubernetes :: Starter ................. SUCCESS [  0.558 s]
[INFO] Spring Cloud Kubernetes :: Starter :: Config ....... SUCCESS [  0.569 s]
[INFO] Spring Cloud Kubernetes :: Starter :: Ribbon ....... SUCCESS [  0.595 s]
[INFO] Spring Cloud Kubernetes :: Starter :: All .......... SUCCESS [  0.571 s]
[INFO] Spring Cloud Kubernetes :: Examples ................ SUCCESS [  0.558 s]
[INFO] Spring Cloud Kubernetes :: Examples :: Reload ConfigMap SUCCESS [  9.077 s]
[INFO] Spring Cloud Kubernetes :: Examples :: Hello World . SUCCESS [  1.323 s]
[INFO] Spring Cloud Kubernetes :: Leader .................. SUCCESS [  7.395 s]
[INFO] Spring Cloud Kubernetes :: Examples :: Leader Election SUCCESS [  0.594 s]
[INFO] Spring Cloud Kubernetes :: Istio ................... SUCCESS [ 12.788 s]
[INFO] Spring Cloud Kubernetes :: Integration Tests ....... SUCCESS [  0.574 s]
[INFO] Spring Cloud Kubernetes :: Integration Tests :: Simple Core SUCCESS [02:14 min]
[INFO] Spring Cloud Kubernetes :: Integration Tests :: Simple Configmap SUCCESS [  0.646 s]
[INFO] Spring Cloud Kubernetes :: Integration Tests :: Istio SUCCESS [  0.623 s]
[INFO] Spring Cloud Kubernetes :: Integration Tests :: Discovery Parent SUCCESS [  0.564 s]
[INFO] Spring Cloud Kubernetes :: Integration Tests :: Discovery Service A SUCCESS [  0.605 s]
[INFO] Spring Cloud Kubernetes :: Integration Tests :: Discovery Service B SUCCESS [  0.625 s]
[INFO] Spring Cloud Kubernetes :: Integration Tests :: Discovery Client SUCCESS [  0.608 s]
[INFO] Spring Cloud Kubernetes :: Integration Tests :: Discovery Tests SUCCESS [  1.440 s]
[INFO] Spring Cloud Kubernetes Docs ....................... SUCCESS [  0.583 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  05:53 min
[INFO] Finished at: 2019-06-08T19:32:19+08:00
[INFO] ------------------------------------------------------------------------
  1. 進入目錄spring-cloud-kubernetes-1.0.1.RELEASE/spring-cloud-kubernetes-examples/kubernetes-hello-world-example,這裡面就是官方的入門demo,執行以下命令開始構建並且會部署到minikube:
mvn clean package fabric8:deploy -Pkubernetes

構建和部署完成後,控制檯輸出以下資訊:

...
[INFO] Installing /usr/local/work/demo/spring-cloud-kubernetes-1.0.1.RELEASE/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/target/kubernetes-hello-world-1.0.1.RELEASE-sources.jar to /root/.m2/repository/org/springframework/cloud/kubernetes-hello-world/1.0.1.RELEASE/kubernetes-hello-world-1.0.1.RELEASE-sources.jar
[INFO] 
[INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ kubernetes-hello-world <<<
[INFO] 
[INFO] 
[INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ kubernetes-hello-world ---
[INFO] F8: Using Kubernetes at https://192.168.121.133:8443/ in namespace default with manifest /usr/local/work/demo/spring-cloud-kubernetes-1.0.1.RELEASE/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/target/classes/META-INF/fabric8/kubernetes.yml 
[INFO] Using namespace: default
[INFO] Creating a Service from kubernetes.yml namespace default name kubernetes-hello-world
[INFO] Created Service: spring-cloud-kubernetes-examples/kubernetes-hello-world-example/target/fabric8/applyJson/default/service-kubernetes-hello-world.json
[INFO] Using namespace: default
[INFO] Creating a Deployment from kubernetes.yml namespace default name kubernetes-hello-world
[INFO] Created Deployment: spring-cloud-kubernetes-examples/kubernetes-hello-world-example/target/fabric8/applyJson/default/deployment-kubernetes-hello-world.json
[INFO] F8: HINT: Use the command `kubectl get pods -w` to watch your pods start up
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  16.047 s
[INFO] Finished at: 2019-06-08T19:50:50+08:00
[INFO] ------------------------------------------------------------------------
  1. 檢視服務,已經建立了,型別是NodePort ,並且將8080埠對映到宿主機的30700埠,說明可以用http://宿主機IP:30700來訪問此服務:
[root@minikube kubernetes-hello-world-example]# kubectl get services
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes               ClusterIP   10.96.0.1        <none>        443/TCP          10h
kubernetes-hello-world   NodePort    10.108.214.207   <none>        8080:30700/TCP   4m
  1. 檢視部署,發現始終未能進入READY狀態:
[root@minikube kubernetes-hello-world-example]# kubectl get deployments
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
kubernetes-hello-world   0/1     1            0           4m46s
  1. 檢視pod,發現新建的pod始終未能進入READY狀態:
[root@minikube kubernetes-hello-world-example]# kubectl get pods
NAME                                      READY   STATUS    RESTARTS   AGE
kubernetes-hello-world-7578f45c5d-hr4r7   0/1     Running   1          6m
  1. 從上面的資訊可以看出,部署雖然已經完成,但是pod是不可用的,訪問網頁試試,如下圖,果然無法訪問:

    檢查問題

  2. 執行命令kubectl describe pod kubernetes-hello-world-7578f45c5d-hr4r7檢查pod的具體情況,如下圖紅框所示,兩個探針檢查都失敗了:
  3. 再看看控制檯輸出的pod基本情況,裡面有探針的資訊,如下圖所示,兩個探針的地址都是/health:
  4. 開啟demo的原始碼,如下所示,根本就沒有路徑為/health的服務:
@RestController
public class HelloController {

        private static final Log log = LogFactory.getLog(HelloController.class);

        @Autowired
        private DiscoveryClient discoveryClient;

        @RequestMapping("/")
        public String hello() {
                return "Hello World";
        }

        @RequestMapping("/services")
        public List<String> services() {
                return this.discoveryClient.getServices();
        }
}

現在真相大白了:部署到minikube上的pod,配置了探針地址是/health,但是服務中並沒有此路徑,因此探針檢查一直無法通過;

解決問題

搞清楚問題之後就可以動手解決問題了,這裡有兩種解決方式:
第一種,修改HelloController.java,增加一個方法,對應的地址是/health的服務;
第二種,修改deployment的配置,將探針地址改為現有的服務,例如"/",這是個可用的服務;

第一種方法很簡單,留給讀者您來完成吧,我們來試試第二種:

  1. 執行以下命令,開始編輯deployment:
kubectl edit deployment kubernetes-hello-world
  1. 在編輯頁面上找到兩個探針的配置,都從"/health"改成"/",如下圖兩個紅框所示:
  2. 修改完畢後,像普通vim操作一樣"wq"儲存退出,配置會立即生效,稍等一會兒再看pod情況,發現pod的name已經變了,並且狀態已經成為Ready,證明舊的pod已經銷燬,新的pod被建立並且探針測試通過:
[root@minikube examples]# kubectl get pods
NAME                                      READY   STATUS    RESTARTS   AGE
kubernetes-hello-world-6c5f75ff74-dnm2q   1/1     Running   0          15s
  1. 訪問地址http://192.168.121.133:30700 ,服務正常(192.168.121.133是宿主機IP地址),如下圖:

    官方解釋

    官方的demo無法在minikube上正常執行,還要我們自己去修改配置或者原始碼,官方的demo不應該會這樣,在kubernetes-hello-world-example工程內的README.md文件中發現了對此問題的說明,如下圖紅框所示,fabric8的maven外掛在生成探針配置的是時候配錯了URL,因此官方建議我們去修改deployment的配置,將探針的地址從"/health"改為"/actuator/heath",這個問題已經被提交到了fabric8社群,並且貼出了連結:

    許可權問題

    剛才我們看過了HelloController.java的原始碼,裡面還有個路徑為"/services"的介面,在minikube環境下訪問此介面可以成功返回,內容是當前minikube環境的服務資訊,但是如果部署在正式的kubernetes環境,訪問此介面會返回以下錯誤:
Message: Forbidden!Configured service account doesn't have access. Service account may have been revoked. services is forbidden: User "system:serviceaccount:default:default" cannot list resource "services" in API group "" in the namespace "default"

也就是說當前的system:serviceaccount賬號是沒有許可權通過API server訪問"services"資源的,此時最快的解決辦法是提升賬號許可權:

kubectl create clusterrolebinding permissive-binding \
  --clusterrole=cluster-admin \
  --user=admin \
  --user=kubelet \
  --group=system:serviceaccounts

注意:以上辦法只能用於開發和測試環境,不要用在生產環境,在生產環境應該參考Kubernetes的RBAC授權相關設定來處理。

修改原始碼時遇到的錯誤怎麼規避

如果您想嘗試修改demo的原始碼並且部署上去,在編譯階段可能遇到以下問題:

[root@minikube kubernetes-hello-world-example]# mvn clean package fabric8:deploy -Pkubernetes
[INFO] Scanning for projects...
[INFO] 
[INFO] ----------< org.springframework.cloud:kubernetes-hello-world >----------
[INFO] Building Spring Cloud Kubernetes :: Examples :: Hello World 1.0.1.RELEASE
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ kubernetes-hello-world ---
[INFO] Deleting /usr/local/work/demo/spring-cloud-kubernetes-1.0.1.RELEASE/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/target
[INFO] 
[INFO] --- maven-checkstyle-plugin:3.0.0:check (checkstyle-validation) @ kubernetes-hello-world ---
[INFO] 開始檢查……
[ERROR] /usr/local/work/demo/spring-cloud-kubernetes-1.0.1.RELEASE/spring-cloud-kubernetes-examples/kubernetes-hello-world-example/src/main/java/org/springframework/cloud/kubernetes/examples/HelloController.java:33: 當前行匹配非法表示式: 'Trailing whitespace'。 [Regexp]
檢查完成。
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.976 s
[INFO] Finished at: 2019-06-08T22:15:37+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:3.0.0:check (checkstyle-validation) on project kubernetes-hello-world: Failed during checkstyle execution: There is 1 error reported by Checkstyle 8.12 with checkstyle.xml ruleset. -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

出現上述問題的原因是maven-checkstyle-plugin外掛檢查程式碼的style沒有通過,我試過在mvn命令中新增skip引數,也試過在pom.xml中新增maven-checkstyle-plugin節點並且配置為skip,結果都沒有用,最終用以下方法成功規避了此問題:

  1. 開啟pom.xml檔案;
  2. 找到節點properties(如果沒有就建立),增加以下三個屬性配置,這樣配置的作用是在style檢查失敗、校驗失敗、單元測試程式碼檢查失敗這三種情況下,都不會導致整個maven構建的失敗:
<properties>
        <maven-checkstyle-plugin.failsOnError>false</maven-checkstyle-plugin.failsOnError>
        <maven-checkstyle-plugin.failsOnViolation>false</maven-checkstyle-plugin.failsOnViolation>
        <maven-checkstyle-plugin.includeTestSourceDirectory>false</maven-checkstyle-plugin.includeTestSourceDirectory></properties>

至此,官方demo的部署和執行都完成了,對spring-cloud-kubernetes算是有了初步認識,接下來的實戰中,我們一起去深入的瞭解spring-cloud-kubernetes,看看kubernetes上的springcloud應用怎麼開發;

歡迎關注我的公眾號:程式設計師欣宸

相關推薦

spring-cloud-kubernetes官方demo執行實戰

關於spring-cloud-kubernetes spring-cloud-kubernetes是springcloud官方推出的開源專案,用於將Spring Cloud和Spring Boot應用執行在kubernetes環境,並且提供了通用的介面來呼叫kubernetes服務,GitHub上官方地址是:

spring-cloud-kubernetes的服務發現和輪詢實戰(含熔斷)

本文是《spring-cloud-kubernetes實戰系列》的第四篇,主要內容是在kubernetes上部署兩個應用:Web-Service和Account-Service,通過spring-cloud-kubernetes提供的註冊發現能力,實現Web-Service呼叫Account-Service提

微信小遊戲 - 開發工具安裝 - 官方 Demo 執行

安裝開發工具      有了《微信小遊戲 - 理論介紹 - 賬號註冊 - 開發前準備》小程式帳號之後,需要一個開發工具來進行開發小程式/遊戲。前往 開發者工具下載頁面 ,根據自己的作業系統下載對應的安裝包進行安裝。有關開發者工具更詳細的介紹可以檢

Spring Cloud Eureka高可用落地實戰

一、原理 如圖所示,多臺Server端之間相互註冊(這裡以兩臺Server為例),Client端向所有的Server端註冊。 二、Server端配置 1. 新增依賴 <dependency>   <groupId>org.springframework.cloud&l

Spring Cloud Kubernetes容器化實踐

隨著公司業務量和產品線的增加,專案越來越多,普通運維繫統架構對整個軟體研發生命週期的管理越來越難,效率低下,難以統一管理。近年來Docker統一了容器標準,對於軟體開發流程產生了深遠的影響,Docker可以一次打包,處處執行。過去幾年Kubernetes平臺發展日新月益,K

Spring Cloud Config官方文件》快速啟動

原文連結 第二部分 Spring Cloud 配置 1.3.5.BUILD-SNAPSHOT Spring Cloud 配置為分散式系統中的外部配置提供伺服器和客戶端支援。藉助Config Server,您可以在所有環境中管理應用程式的外部屬性。客戶端和伺服器上的概念與Spring Envir

Spring Cloud Netflix官方文件》7.宣告式 REST 客戶端: Feign

原文連結 Feign 是一個宣告式的web服務客戶端。它使得編寫web服務客戶端更簡單,建立一個介面並加上註解就能使用Feign了,它還支援JAX-RS型別的註解,可插入式的編碼和解碼,Spring cloud 為他加入了spring mvc的註解支援,以及在spring web開發過程中預設

Spring Cloud Netflix官方文件》2. 服務發現:Eureka伺服器

原文連結 譯者:Acamy 2. 服務發現:Eureka伺服器 2.1 如何建立Eureka伺服器 引用org.springframework.cloud的spring-cloud-starter-eureka-server就可以建立Eureka伺服器。在當前Spring Cloud版本中如何

Spring Cloud Config官方文件》之嵌入配置伺服器

原文連結 8. 嵌入配置伺服器 Config伺服器作為一個獨立的應用程式執行得最好,但是如果你需要,你可以將它嵌入到另一個應用程式中。只需使用 @EnableConfigServer註釋。在這種情況下可選屬性spring.cloud.config.server.bootstrap將會是可用的,

Spring Cloud Config官方文件》之推送通知和Spring Cloud匯流排

9. 推送通知和Spring Cloud匯流排 許多原始碼儲存庫提供者(例如Github,Gitlab或Bitbucket)會通過webhook通知你儲存庫中的變化。您可以通過提供商的使用者介面將webhook配置為您感興趣的URL和一組事件。例如, Github 將通過一個包含提交列表的JS

Spring Cloud Config官方文件》之Spring Cloud Config Server

原文連結 5. Spring Cloud Config Server 伺服器為外部配置(名稱 – 值對或同等的YAML內容)提供了一個HTTP、基於資源的API。伺服器很容易使用@EnableConfigServer註釋嵌入到Spring Boot應用程式中 。所以這個應用是一個配置伺服器:

Spring Cloud Config官方文件》之提供替代格式

原文連結 6. 提供替代格式 來自環境節點的預設JSON格式非常適合Spring應用程式使用,因為它直接對映到 Environment抽象。如果您願意,您可以通過向資源路徑(“.yml”,“.yaml”或“.properties”)新增字尾來使用與YAML或Java屬性相同的資料。對於那些不關

Spring Cloud Config官方文件》翻譯邀請

校對完之後被評為A級會升級您為譯者,並加入譯者溝通群。如果在本站翻譯超過十篇文章,將有禮品贈送,比如簽名版的《Java併發程式設計的藝術》或者其他圖書。如果譯文釋出到併發網公眾號,讚賞歸譯者所有。如果你喜歡使用markdown編寫文章,可以將markdown生成後的HTML複製到網站上進行提交(複製到文字框

Spring Cloud Netflix官方文件》翻譯邀請

11月天漸漸變亮,本月併發網開始組織翻譯Spring Cloud大家庭,本文是第一篇《Spring Cloud Netflix官方文件》,歡迎有興趣的同學參與。 方 騰飛花名清英,併發網(i

Spring Cloud Netflix官方文件》10. 使用 Sidecar支援多語言

原文連結 你有non-jvm語言也想使用Eureka,Ribbon和Config Server? Spring Cloud Netflix Sidecar靈感來自Netflix Prana,它包含一個簡單的http api去獲取給定服務的所有例項(主機和埠)。你也可以通過嵌入式Zuul代理代理

Spring Cloud Config官方文件》之提供純文字

原文連結 7. 提供純文字 而不是使用Environment抽象(或YAML或其他屬性格式中的替代表示形式),應用程式可能需要通用的純文字配置檔案,並且是針對其環境來定製。配置伺服器通過/{name}/{profile}/{label}/{path} 在“名稱”,“配置檔案”和“標籤”與常規環

Spring Cloud Config官方文件》之Spring Cloud Config客戶端

10.  Spring Cloud Config客戶端 Spring Boot應用程式可以立即利用Spring Config伺服器(或應用程式開發人員提供的其他外部屬性資源),還可以獲取與Environment更改事件有關的一些其他有用的功能。 10.1 配置第一引導 這是在類路徑上具有Sp

Spring Cloud Netflix官方文件》3.熔斷器:Hystrix Clients

原文連結 Netfilix建立了一個名為Hystrix的庫,實現了熔斷器模式。在微服務架構中,它通常有多個服務呼叫層。 圖3.1 微服務圖 一個底層服務的故障會引發直至使用者互動層的連鎖故障。在一個設定時長為“metrics.rollingStats.timeInMilliseconds”

Spring Cloud Config官方文件》加密和解密

原文連結 5.2 健康指標 Config Server 附帶一個健康指標(Health Indicator),用於檢查配置的 EnvironmentRepository 是否正常工作。預設情況下,它會為 EnvironmentRepository請求一個名為 app 的應用程式,這個預設的pr

Spring Cloud Netflix官方文件》1.服務發現:Eureka客戶端

原文連結 譯者:Acamy 1.     服務發現:Eureka客戶端 服務發現是微服務架構的關鍵原則之一。使用手動配置或一些約定方式來處理多服務多例項的方式是非常困難,並且十分脆弱的。Eureka同時是Netflix服務發現的服務端和客戶端。服務端可以通過配置和部署實現高可用,實現方式是每個