想了解 spring-cloud-kubernetes,那就先来实战一把官方demo
摘要:官方提供了简单的demo用于快速了解spring-cloud-kubernetes,我们就来一起将此demo源码编译构建,然后在kubernetes环境运行。
本文分享自华为云社区《spring-cloud-kubernetes官方demo运行实战》,作者: 程序员欣宸 。
关于spring-cloud-kubernetes
spring-cloud-kubernetes是spring cloud官方推出的开源项目,用于将Spring Cloud和Spring Boot应用运行在kubernetes环境,并且提供了通用的接口来调用kubernetes服务,GitHub上官方地址是:https://github.com/spring-cloud/spring-cloud-kubernetes
官方demo
官方提供了简单的demo用于快速了解spring-cloud-kubernetes,我们就来一起将此demo源码编译构建,然后在kubernetes环境运行;
环境信息
本次实战的环境和版本信息如下:
- 操作系统:CentOS Linux release 7.6.1810
- minikube:1.1.1
- Java:1.8.0_191
- Maven:3.6.0
- fabric8-maven-plugin插件:3.5.37
- 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>
3、修改完毕保存退出,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] ------------------------------------------------------------------------
3、进入目录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] ------------------------------------------------------------------------
4、查看服务,已经创建了,类型是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
5、查看部署,发现始终未能进入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
6、查看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
7、从上面的信息可以看出,部署虽然已经完成,但是pod是不可用的,访问网页试试,如下图,果然无法访问:

检查问题
1、执行命令kubectl describe pod kubernetes-hello-world-7578f45c5d-hr4r7检查pod的具体情况,如下图红框所示,两个探针检查都失败了:

2、再看看控制台输出的pod基本情况,里面有探针的信息,如下图所示,两个探针的地址都是/health:

3、打开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
2、在编辑页面上找到两个探针的配置,都从"/health"改成"/",如下图两个红框所示:

3、修改完毕后,像普通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
4、访问地址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,结果都没有用,最终用以下方法成功规避了此问题:
- 打开pom.xml文件;
- 找到节点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应用怎么开发;
问题处理
感谢jason9211的提醒,如果读者您也遇到类似问题,请参考如下:
如果在deploy时遇到 “the server could not find the requested resource”问题,
建议把fabric8.maven.plugin的版本升级到4.2.0即可。
<fabric8.maven.plugin.version>4.2.0</fabric8.maven.plugin.version>
想了解 spring-cloud-kubernetes,那就先来实战一把官方demo的更多相关文章
- Spring Cloud Config整合Spring Cloud Kubernetes,在k8s上管理配置
1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! Kubernetes有专门的ConfigMap和Secret来管理配置,但它也有一些局限性,所以还是希望通过Spring C ...
- Springboot整合Spring Cloud Kubernetes读取ConfigMap,支持自动刷新配置
1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! Docker & Kubernetes相关文章:容器技术 之前介绍了Spring Cloud Config的用法,但 ...
- 朱晔和你聊Spring系列S1E11:小测Spring Cloud Kubernetes @ 阿里云K8S
有关Spring Cloud Kubernates(以下简称SCK)详见https://github.com/spring-cloud/spring-cloud-kubernetes,在本文中我们主要 ...
- 《Spring Cloud与Docker微服务架构实战》配套代码
不才写了本使用Spring Cloud玩转微服务架构的书,书名是<Spring Cloud与Docker微服务架构实战> - 周立,已于2017-01-12交稿.不少朋友想先看看源码,现将 ...
- Spring Cloud Gateway过滤器精确控制异常返回(实战,完全定制返回body)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 Spring Cloud Gateway应用 ...
- Spring Cloud与Docker微服务架构实战 PDF版 内含目录
Spring Cloud与Docker微服务架构实战 目录 1 微服务架构概述 1 1.1 单体应用架构存在的问题1 1.2 如何解决单体应用架构存在的问题3 1.3 什么是微服务3 1.4 微服务 ...
- Spring Cloud Gateway过滤器精确控制异常返回(实战,控制http返回码和message字段)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 前文<Spring Cloud Gat ...
- 【Spring Cloud & Alibaba全栈开源项目实战】:SpringBoot整合ELK实现分布式登录日志收集和统计
一. 前言 其实早前就想计划出这篇文章,但是最近主要精力在完善微服务.系统权限设计.微信小程序和管理前端的功能,不过好在有群里小伙伴的一起帮忙反馈问题,基础版的功能已经差不多,也在此谢过,希望今后大家 ...
- 基于 Spring Cloud 完整的微服务架构实战
本项目是一个基于 Spring Boot.Spring Cloud.Spring Oauth2 和 Spring Cloud Netflix 等框架构建的微服务项目. @作者:Sheldon地址:ht ...
随机推荐
- 常用获取inflate的写法
1. //context:上下文, resource:要转换成view对象的layout的id, root:将layout用root(ViewGroup)包一层作为codify ...
- 广播接收者案例_ip拨号器
(1)定义一个类继承BroadCastReceiver public class OutGoingCallReceiver extends BroadcastReceiver { //当接收到外拨电话 ...
- ARC下的内存管理
1.ARC下单对象内存管理 局部变量释放对象随之被释放 int main(int argc, const char * argv[]) { @autoreleasepool { Person *p = ...
- WEB前端开发--1(Web前端开发综述)
Web前端开发 Web--Web系统 前端--网页上为用户呈现的部分 开发--编写代码 1. 前端与后端 前端:网页上为用户呈现的部分 后端:与数据库进行交互,完成数据存取 2. 网站与 ...
- web测试学习大纲
Web测试 Web测试体系介绍 网络协议 Web开发 基础 原理 前端分析 安全性测试 可用性,兼容性 功能测试(同系统测试) 理解网络协议 互联网历史沿革 Web系统基础 Web核心技术 web服务 ...
- 微服务从代码到k8s部署应有尽有系列(七、支付服务)
我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...
- Hbuilderx换行问题(属性合并一行展示)
1. 标签折行,非吾所愿(格式化代码快捷键:Ctrl + K) 2. 打开工具-设置 3. 点击左侧插件配置,点击右边下侧jsbeautify 4. 将原本的折行长度由120改为1200(长度可根据 ...
- Qunar风控安全产品的探索之路
李建威.2017年7月以春招实习生的身份加入去哪儿网,毕业后一直在从事抓取与反抓取相关工作,先后负责搭建过智能打码.设备指纹以及环境检测等服务.目前主要负责反爬风控的基础安全产品建设.对各类作弊原理感 ...
- 基于Windows系统应用的权限维持
1.dll劫持 生成dll 通过msf将dll木马上传到目标应用程序的dll文件夹里面,然后通过msf来将木马dll名称和正常dll名称进行互换 远程开启监听,然后一旦目标机器的应用程序运行就会触发d ...
- Unicode 详细介绍
总结起来为啥需要Unicodey就是为了适应全球化的发展,便于不同语言之间的兼容交互,而ASCII不再能胜任此任务了 UTF-8 与UTF-16的区别 UTF-8的优缺点 程序员那么到底该如何选择呢? ...