欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

spring-cloud-kubernetes官方demo运行实战

程序员文章站 2022-10-15 16:40:19
关于spring cloud kubernetes spring cloud kubernetes是springcloud官方推出的开源项目,用于将Spring Cloud和Spring Boot应用运行在kubernetes环境,并且提供了通用的接口来调用kubernetes服务,GitHub上官 ......

关于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与springcloud gateway》

官方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
spring-cloud-kubernetes官方demo运行实战

修改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是不可用的,访问网页试试,如下图,果然无法访问:
    spring-cloud-kubernetes官方demo运行实战

    检查问题

  2. 执行命令kubectl describe pod kubernetes-hello-world-7578f45c5d-hr4r7检查pod的具体情况,如下图红框所示,两个探针检查都失败了:
    spring-cloud-kubernetes官方demo运行实战
  3. 再看看控制台输出的pod基本情况,里面有探针的信息,如下图所示,两个探针的地址都是/health
    spring-cloud-kubernetes官方demo运行实战
  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"改成"/",如下图两个红框所示:
    spring-cloud-kubernetes官方demo运行实战
  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地址),如下图:
    spring-cloud-kubernetes官方demo运行实战

    官方解释

    官方的demo无法在minikube上正常运行,还要我们自己去修改配置或者源码,官方的demo不应该会这样,在kubernetes-hello-world-example工程内的readme.md文档中发现了对此问题的说明,如下图红框所示,fabric8的maven插件在生成探针配置的是时候配错了url,因此官方建议我们去修改deployment的配置,将探针的地址从"/health"改为"/actuator/heath",这个问题已经被提交到了fabric8社区,并且贴出了链接:
    spring-cloud-kubernetes官方demo运行实战

    权限问题

    刚才我们看过了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运行实战