spring-cloud-kubernetes與SpringCloud Gateway

本文是《spring-cloud-kubernetes實戰系列》的第五篇,主要內容是在kubernetes上部署一個SpringCloud Gateway應用,該應用使用了spring-cloud-kubernetes框架,能夠將請求轉發到kubernetes環境中的其餘服務上;html

系列文章列表

  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》

本文大綱

接下來的內容由如下幾部分組成:java

  1. 什麼是SpringCloud Gateway
  2. SpringCloud Gateway實戰參考
  3. kubernetes上的SpringCloud Gateway
  4. 實戰環境信息
  5. 實戰源碼下載
  6. 開發webdemo
  7. 開發k8sgatewaydemo
  8. 解決權限問題
  9. 最後一個疑問

什麼是SpringCloud Gateway

SpringCloud Gateway是SpringCloud技術棧下的網關服務框架,在基於SpringCloud的微服務環境中,外部請求會到達SpringCloud Gateway應用,該應用對請求作轉發、過濾、鑑權、熔斷等前置操做,一個典型的請求響應流程以下所示: 在這裏插入圖片描述git

SpringCloud Gateway實戰參考

若是您以前沒有使用過SpringCloud Gateway,推薦您閱讀《速體驗SpringCloud Gateway》,有時間的話動手實戰效果更佳,只需編寫少許代碼就能快速熟悉這個SpringCloud技術棧中很是重要的功能;程序員

kubernetes上的SpringCloud Gateway

注意如下兩個知識點:github

  1. SpringCloud Gateway之因此能將外部請求路由到正確的後臺服務上,是由於註冊中心的存在,SpringCloud Gateway能夠在註冊中心取得全部服務的信息,所以它能夠根據路徑和服務的對應關係,將請求轉發到對應的服務上;
  2. 若是您看過本系列的上一篇 《spring-cloud-kubernetes的服務發現和輪詢實戰(含熔斷)》,您就知道spring-cloud-kubernetes框架能夠獲取kubernetes環境內的全部服務(這裏說的服務就是kubernetes的service);

將以上兩個知識點結合起來,因而能夠推測:<font color="blue">運行在kubernetes環境的SpringCloud Gateway應用,若是使用了spring-cloud-kubernetes框架就能獲得kubernetes的service列表,所以能夠承擔網關的角色,將外部請求轉發至kubernetes內的service上,最終到達對應的Pod;</font>web

架構以下圖所示,請注意黃色背景的對話框,裏面標識了關鍵操做: 在這裏插入圖片描述 至此,理論分析已經完成,咱們來實戰驗證這個理論,接下來咱們開發兩個java應用:spring

  1. 先開發一個普通的web服務,名爲webdemo,提供一個http接口;
  2. 再開發一個SpringCloud Gateway應用,名爲k8sgatewaydemo;

環境信息

本次實戰的環境和版本信息以下:shell

  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
  7. spring cloud:Greenwich.SR2
  8. springboot:2.1.6.RELEASE

源碼下載

若是您不打算寫代碼,也能夠從GitHub上下載本次實戰的源碼,地址和連接信息以下表所示:express

名稱 連接 備註
項目主頁 https://github.com/zq2599/blog_demos 該項目在GitHub上的主頁
git倉庫地址(https) https://github.com/zq2599/blog_demos.git 該項目源碼的倉庫地址,https協議
git倉庫地址(ssh) git@github.com:zq2599/blog_demos.git 該項目源碼的倉庫地址,ssh協議

</br>apache

這個git項目中有多個文件夾,本章的兩個應用分別在webdemo和k8sgatewaydemo文件夾下; 下圖紅框中是webdemo應用的源碼: 在這裏插入圖片描述 下圖紅框中是k8sgatewaydemo應用的源碼: 在這裏插入圖片描述 下面是詳細的編碼過程;

開發webdemo

webdemo是個極其普通的spring boot應用,<font color="red">和SpringCloud沒有任何關係</font>;

  1. webdemo提供一個http接口,將請求header中名爲extendtag的參數返回給請求方,controller類以下:
@RestController
@RequestMapping("/hello")
public class HelloController {

    @RequestMapping(value = "time", method = RequestMethod.GET)
    public String hello(HttpServletRequest request){

        return "hello, "
                + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())
                + ", extendtag ["
                + request.getHeader("extendtag")
                + "]";
    }
}
  1. 啓動類WebdemoApplication.java:
@SpringBootApplication
public class WebdemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebdemoApplication.class, args);
    }
}
  1. 要注意的是pom.xml,裏面經過名爲<font color="blue">fabric8-maven-plugin</font>的maven插件,將webdemo快速部署到minikube環境:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>webdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>webdemo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.1.6.RELEASE</spring-boot.version>
        <fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <!--skip deploy -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>${maven-deploy-plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven-surefire-plugin.version}</version>
                <configuration>
                    <skipTests>true</skipTests>
                    <!-- Workaround for https://issues.apache.org/jira/browse/SUREFIRE-1588 -->
                    <useSystemClassLoader>false</useSystemClassLoader>
                </configuration>
            </plugin>
            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>fabric8-maven-plugin</artifactId>
                <version>${fabric8.maven.plugin.version}</version>
                <executions>
                    <execution>
                        <id>fmp</id>
                        <goals>
                            <goal>resource</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>kubernetes</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.fabric8</groupId>
                        <artifactId>fabric8-maven-plugin</artifactId>
                        <version>${fabric8.maven.plugin.version}</version>
                        <executions>
                            <execution>
                                <id>fmp</id>
                                <goals>
                                    <goal>resource</goal>
                                    <goal>build</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <enricher>
                                <config>
                                    <fmp-service>
                                        <type>NodePort</type>
                                    </fmp-service>
                                </config>
                            </enricher>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>
  1. 以上就是webdemo應用的內容了,接下來要編譯、構建、部署到minikube環境,在pom.xml執行如下命令便可:
mvn clean install fabric8:deploy -Dfabric8.generator.from=fabric8/java-jboss-openjdk8-jdk -Pkubernetes

部署完成後終端輸出相似以下成功信息:

[INFO] 
[INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ webdemo <<<
[INFO] 
[INFO] 
[INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ webdemo ---
[INFO] F8: Using Kubernetes at https://192.168.121.133:8443/ in namespace default with manifest /usr/local/work/k8s/webdemo/target/classes/META-INF/fabric8/kubernetes.yml 
[INFO] Using namespace: default
[INFO] Updating a Service from kubernetes.yml
[INFO] Updated Service: target/fabric8/applyJson/default/service-webdemo.json
[INFO] Using namespace: default
[INFO] Updating Deployment from kubernetes.yml
[INFO] Updated Deployment: target/fabric8/applyJson/default/deployment-webdemo.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:  11.804 s
[INFO] Finished at: 2019-07-07T21:32:26+08:00
[INFO] ------------------------------------------------------------------------
  1. 查看service和pod,確認一切正常:
[root@minikube webdemo]# kubectl get service
NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes       ClusterIP   10.96.0.1       <none>        443/TCP          29d
webdemo          NodePort    10.106.98.137   <none>        8080:30160/TCP   115m
[root@minikube webdemo]# kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
webdemo-c9f774b9-gsbgx            1/1     Running   0          3m13s
  1. 使用minikube命令取得webdemo服務對外暴露的地址:
[root@minikube webdemo]# minikube service webdemo --url
http://192.168.121.133:30160

可見外部經過地址:http://192.168.121.133:30160 便可訪問到webdemo應用; 7. 在瀏覽器輸入地址:http://192.168.121.133:30160/hello/time ,便可驗證webdemo的http接口是否正常,以下圖,因爲header中沒有extendtag屬性,所以返回的extendtag爲null: 在這裏插入圖片描述 至此,webdemo在minikue上已經正常運行,該開發gateway應用了;

開發k8sgatewaydemo

  1. 基於maven建立一個名爲k8sgatewaydemo的springboot應用,pom.xml內容以下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.bolingcavalry</groupId>
    <artifactId>k8sgatewaydemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>k8sgatewaydemo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-boot.version>2.1.6.RELEASE</spring-boot.version>
        <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>
        <maven-compiler-plugin.version>3.5</maven-compiler-plugin.version>
        <maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
        <maven-failsafe-plugin.version>2.18.1</maven-failsafe-plugin.version>
        <maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
        <fabric8.maven.plugin.version>3.5.37</fabric8.maven.plugin.version>
        <springcloud.kubernetes.version>1.0.1.RELEASE</springcloud.kubernetes.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-kubernetes-core</artifactId>
            <version>${springcloud.kubernetes.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-kubernetes-discovery</artifactId>
            <version>${springcloud.kubernetes.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
            <version>${springcloud.kubernetes.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <!--skip deploy -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>${maven-deploy-plugin.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${maven-surefire-plugin.version}</version>
                <configuration>
                    <skipTests>true</skipTests>
                    <!-- Workaround for https://issues.apache.org/jira/browse/SUREFIRE-1588 -->
                    <useSystemClassLoader>false</useSystemClassLoader>
                </configuration>
            </plugin>
            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>fabric8-maven-plugin</artifactId>
                <version>${fabric8.maven.plugin.version}</version>
                <executions>
                    <execution>
                        <id>fmp</id>
                        <goals>
                            <goal>resource</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>kubernetes</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.fabric8</groupId>
                        <artifactId>fabric8-maven-plugin</artifactId>
                        <version>${fabric8.maven.plugin.version}</version>
                        <executions>
                            <execution>
                                <id>fmp</id>
                                <goals>
                                    <goal>resource</goal>
                                    <goal>build</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <enricher>
                                <config>
                                    <fmp-service>
                                        <type>NodePort</type>
                                    </fmp-service>
                                </config>
                            </enricher>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

上述pom文件中有如下幾點須要注意: 第1、 依賴spring-cloud-kubernetes-core和spring-cloud-kubernetes-discovery,這樣能用到spring-cloud-kubernetes提供的服務發現能力; 第2、依賴spring-cloud-starter-gateway,這樣能用上SpringCloud的gateway能力; 第3、不要依賴spring-boot-starter-web,會和spring-cloud-starter-gateway衝突,啓動時拋出如下異常:

2019-07-06 08:12:09.188  WARN 1 --- [           main] ConfigServletWebServerApplicationContext : 
Exception encountered during context initialization - 
cancelling refresh attempt: 
org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'routeDefinitionRouteLocator' defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class]: 
Unsatisfied dependency expressed through method 'routeDefinitionRouteLocator' parameter 1; 
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'modifyRequestBodyGatewayFilterFactory' defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration.class]: 
Unsatisfied dependency expressed through method 'modifyRequestBodyGatewayFilterFactory' parameter 0; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.http.codec.ServerCodecConfigurer' available: 
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
  1. 開發SpringCloud Gateway的啓動類K8sgatewaydemoApplication.java,裏面也包含了網關路由配置的實例化,除了配置路徑和轉發服務的關係,還在請求的header中添加了extendtag屬性,請注意註釋的內容:
@SpringBootApplication
@EnableDiscoveryClient
public class K8sgatewaydemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(K8sgatewaydemoApplication.class, args);
    }

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                //增長一個path匹配,以"/customize/hello/"開頭的請求都在此路由
                .route(r -> r.path("/customize/hello/**")
                        //表示將路徑中的第一級參數刪除,用剩下的路徑與webdemo的路徑作拼接,
                        //這裏就是"lb://webdemo/hello/",能匹配到webdemo的HelloController的路徑
                        .filters(f -> f.stripPrefix(1)
                                //在請求的header中添加一個key&value
                                .addRequestHeader("extendtag", "geteway-" + System.currentTimeMillis()))
                        //指定匹配服務webdemo,lb是load balance的意思
                        .uri("lb://webdemo")
                ).build();
    }
}

從上述代碼可見,K8sgatewaydemoApplication與普通環境下的SpringCloud Gateway並沒有差異,都是經過EnableDiscoveryClient註解獲取服務列表,配置RouteLocator實現路由邏輯; 3. 配置文件application.yml的內容:

spring:
  application:
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lowerCaseServiceId: true
  1. 以上就是k8sgatewaydemo應用的內容了,接下來要編譯、構建、部署到minikube環境,在pom.xml執行如下命令便可:
mvn clean install fabric8:deploy -Dfabric8.generator.from=fabric8/java-jboss-openjdk8-jdk -Pkubernetes

部署完成後終端輸出相似以下成功信息:

[INFO] 
[INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ k8sgatewaydemo <<<
[INFO] 
[INFO] 
[INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ k8sgatewaydemo ---
[INFO] F8: Using Kubernetes at https://192.168.121.133:8443/ in namespace default with manifest /usr/local/work/k8s/k8sgatewaydemo/target/classes/META-INF/fabric8/kubernetes.yml 
[INFO] Using namespace: default
[INFO] Updating a Service from kubernetes.yml
[INFO] Updated Service: target/fabric8/applyJson/default/service-k8sgatewaydemo.json
[INFO] Using namespace: default
[INFO] Updating Deployment from kubernetes.yml
[INFO] Updated Deployment: target/fabric8/applyJson/default/deployment-k8sgatewaydemo.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.538 s
[INFO] Finished at: 2019-07-07T22:04:48+08:00
[INFO] ------------------------------------------------------------------------
  1. 查看service和pod,確認一切正常:
[root@minikube k8sgatewaydemo]# clear
[root@minikube k8sgatewaydemo]# kubectl get service
NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
k8sgatewaydemo   NodePort    10.97.94.238    <none>        8080:31352/TCP   129m
kubernetes       ClusterIP   10.96.0.1       <none>        443/TCP          29d
webdemo          NodePort    10.106.98.137   <none>        8080:30160/TCP   145m
[root@minikube k8sgatewaydemo]# kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
k8sgatewaydemo-6fbb79885c-r2jfn   1/1     Running   0          33s
webdemo-c9f774b9-gsbgx            1/1     Running   0          32m
  1. 使用minikube命令取得webdemo服務對外暴露的地址:
[root@minikube k8sgatewaydemo]# minikube service k8sgatewaydemo --url
http://192.168.121.133:31352

可見外部經過地址:http://192.168.121.133:31352 便可訪問到k8sgatewaydemo應用; 7. 在瀏覽器輸入地址:http://192.168.121.133:31352/customize/hello/time ,便可驗證k8sgatewaydemo做爲網關應用,可否將路徑中帶有<font color="blue">customize</font>的請求轉發到webdemo應用,而且在請求header中添加名爲entendtag的屬性,以下圖,瀏覽器展現的內容是webdemo的http接口返回的,而且extendtag的內容也不爲空了,而是k8sgatewaydemo在轉發前寫入的: 在這裏插入圖片描述 上述結果代表已能夠證實咱們以前的推測是正確的:SpringCloud Gateway應用在使用了spring-cloud-kubernetes提供的註冊發現能力後,能夠將請求轉發到kubernetes環境中的服務上; 也就是說,藉助spring-cloud-kubernetes框架,你在SpringCloud環境開發的SpringCloud Gateway應用,能夠以很小的代價遷移到kubernetes環境,與kubernetes環境中的service能夠很好的交互,而原有的eureka註冊中心也能夠不用了;

解決權限問題

若是您的spring-cloud-kubernetes在向webdemo轉發請求時拋出如下錯誤,那是由於遇到了kubernetes的權限問題:

2019-07-06 04:46:40.042  WARN 1 --- [erListUpdater-1] c.n.l.PollingServerListUpdater           : Failed one update cycle
io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: GET at: https://10.96.0.1/api/v1/namespaces/default/endpoints/account-service. Message: Forbidden!Configured service account doesn't have access. Service account may have been revoked. endpoints "account-service" is forbidden: User "system:serviceaccount:default:default" cannot get resource "endpoints" in API group "" in the namespace "default".
        at io.fabric8.kubernetes.client.dsl.base.OperationSupport.requestFailure(OperationSupport.java:476) ~[kubernetes-client-4.1.0.jar!/:na]
        at io.fabric8.kubernetes.client.dsl.base.OperationSupport.assertResponseCode(OperationSupport.java:413) ~[kubernetes-client-4.1.0.jar!/:na]
        at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:381) ~[kubernetes-client-4.1.0.jar!/:na]
        at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:344) ~[kubernetes-client-4.1.0.jar!/:na]
        at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleGet(OperationSupport.java:313) ~[kubernetes-client-4.1.0.jar!/:na]
        at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleGet(OperationSupport.java:296) ~[kubernetes-client-4.1.0.jar!/:na]
        at io.fabric8.kubernetes.client.dsl.base.BaseOperation.handleGet(BaseOperation.java:794) ~[kubernetes-client-4.1.0.jar!/:na]
        at io.fabric8.kubernetes.client.dsl.base.BaseOperation.getMandatory(BaseOperation.java:210) ~[kubernetes-client-4.1.0.jar!/:na]


        at io.fabric8.kubernetes.client.dsl.base.BaseOperation.get(BaseOperation.java:177) ~[kubernetes-client-4.1.0.jar!/:na]
        at org.springframework.cloud.kubernetes.ribbon.KubernetesServerList


.getUpdatedListOfServers(KubernetesServerList.java:75) ~[spring-cloud-kubernetes-ribbon-1.0.1.RELEASE.jar!/:1.0.1.RELEASE]
        at com.netflix.loadbalancer.DynamicServerListLoadBalancer.updateListOfServers(DynamicServerListLoadBalancer.java:240) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
        at com.netflix.loadbalancer.DynamicServerListLoadBalancer$1.doUpdate(DynamicServerListLoadBalancer.java:62) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
        at com.netflix.loadbalancer.PollingServerListUpdater$1.run(PollingServerListUpdater.java:116) ~[ribbon-loadbalancer-2.3.0.jar!/:2.3.0]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_191]
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_191]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_191]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_191]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_191]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_191]
        at java.lang.Thread.run(Thread.java:748) [na:1.8.0_191]

處理方法是建立ServiceAccount對象,步驟以下:

  1. 建立名爲<font color="blue">fabric8-rbac.yaml</font>的文件,內容以下:
# NOTE: The service account `default:default` already exists in k8s cluster.
# You can create a new account following like this:
#---
#apiVersion: v1
#kind: ServiceAccount
#metadata:
#  name: <new-account-name>
#  namespace: <namespace>

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: fabric8-rbac
subjects:
  - kind: ServiceAccount
    # Reference to upper's `metadata.name`
    name: default
    # Reference to upper's `metadata.namespace`
    namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
  1. 執行如下命令便可建立ServiceAccount對象:
kubectl apply -f fabric8-rbac.yaml
  1. 再在瀏覽器上繼續剛纔的驗證,能夠操做成功;

最後一個疑問

再回顧一下k8sgatewaydemo的開發過程,您會發現除了依賴spring-cloud-kubernetes對應的maven庫,咱們並無顯式調用spring-cloud-kubernetes相關的API或者作相關配置,就獲取了所在kubernetes環境的原生服務,這是怎麼回事呢?爲什麼成本如此的低? 答案就在《spring-cloud-kubernetes背後的三個關鍵知識點》一文中,推薦您回顧一下此文。

至此,spring-cloud-kubernetes框架下的SpringCloud Gateway開發實戰就完成了,但願本文能幫助您更好的理解和使用spring-cloud-kubernetes,更加高效的將應用向容器化遷移。

歡迎關注個人公衆號:程序員欣宸

在這裏插入圖片描述

原文出處:https://www.cnblogs.com/bolingcavalry/p/11462999.html

相關文章
相關標籤/搜索