你好spring-cloud-kubernetes

关于spring-cloud-kubernetes

spring-cloud-kubernetes是springcloud官方推出的开源项目,用于将Spring Cloud和Spring Boot应用运行在kubernetes环境,并且提供了通用的接口来调用kubernetes服务,GitHub上官方地址是:https://github.com/spring-clo...

该项目的提交者之一,就是SpringCloud的作者之一Spencer Gibb:

系列文章列表

本文是《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来了解spring-cloud-kubernetes

spring-cloud-kubernetes项目也提供了丰富的官方demo来帮助开发者了解和学习spring-cloud-kubernetes,您可以参考《spring-cloud-kubernetes官方demo运行实战》快速体验官方demo;

实战spring-cloud-kubernetes

今天实战的内容是开发一个简单的java应用,然后将其部署在kubernetes环境(minikube 1.1.1),该应用通过spring-cloud-kubernetes调用当前kubernetes的服务;

环境信息

本次实战的环境和版本信息如下:

  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指南 》。

准备工作已经OK,开始编码吧。

源码下载

如果您不打算写代码,也可以从GitHub上下载本次实战的源码,地址和链接信息如下表所示:

名称 链接 备注
项目主页 https://github.com/zq2599/blo... 该项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blo... 该项目源码的仓库地址,https协议
git仓库地址(ssh) [email protected]:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议

这个git项目中有多个文件夹,本章源码在springcloudk8sdiscovery这个文件夹下,如下图红框所示:

开发应用

  1. 基于maven创建一个springboot应用,名为springcloudk8sdiscovery
  2. 该应用完整的pom.xml内容如下:


    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.1.RELEASE
         
    
    com.bolingcavalry
    springcloudk8sdiscovery
    0.0.1-SNAPSHOT
    springcloudk8sdiscovery
    Demo project for Spring Boot

    
        1.8
        2.1.1.RELEASE
        3.5
        2.8.2
        2.18.1
        2.21.0
        3.5.37
    

    
        
            
                org.springframework.boot
                spring-boot-dependencies
                pom
                import
                ${spring-boot.version}
            
        
    

    
        
            org.springframework.cloud
            spring-cloud-kubernetes-core
            1.0.1.RELEASE
        

        
            org.springframework.cloud
            spring-cloud-kubernetes-discovery
            1.0.1.RELEASE
        

        
            org.springframework.cloud
            spring-cloud-commons
            2.1.1.RELEASE
        

        
            org.springframework.boot
            spring-boot-starter
            2.1.1.RELEASE
        

        
            org.springframework.boot
            spring-boot-starter-web
            2.1.1.RELEASE
        

        
        
            org.springframework.boot
            spring-boot-starter-actuator
            2.1.1.RELEASE
        

        
            com.alibaba
            fastjson
            1.2.28
        
    


    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                ${spring-boot.version}
                
                    
                        
                            repackage
                        
                    
                
            

            
                
                org.apache.maven.plugins
                maven-deploy-plugin
                ${maven-deploy-plugin.version}
                
                    true
                
            
            
                org.apache.maven.plugins
                maven-surefire-plugin
                ${maven-surefire-plugin.version}
                
                    true
                    
                    false
                
            
            
                io.fabric8
                fabric8-maven-plugin
                ${fabric8.maven.plugin.version}
                
                    
                        fmp
                        
                            resource
                        
                    
                
            
        
    

    
        
            kubernetes
            
                
                    
                        io.fabric8
                        fabric8-maven-plugin
                        ${fabric8.maven.plugin.version}
                        
                            
                                fmp
                                
                                    resource
                                    build
                                
                            
                        
                        
                            
                                
                                    
                                        NodePort
                                    
                                
                            
                        
                    
                
            
        
        
            release
            
                
                    
                        io.fabric8
                        fabric8-maven-plugin
                        ${fabric8.maven.plugin.version}
                        
                            
                                fmp
                                
                                    resource
                                    helm
                                
                            
                        
                    
                
            
        

        
            integration
            
                
                    
                        io.fabric8
                        fabric8-maven-plugin
                        ${fabric8.maven.plugin.version}
                        
                            
                                fmp
                                
                                    resource
                                    build
                                
                            
                        
                    
                    
                        org.apache.maven.plugins
                        maven-failsafe-plugin
                        ${maven-failsafe-plugin.version}
                        
                            
                                run-integration-tests
                                integration-test
                                
                                    integration-test
                                    verify
                                
                            
                        
                        
                            false
                            false
                        
                    
                
            
        
    

上述pom.xml文件有几处需要关注:
a. 直接依赖了spring-cloud-kubernetes的以下两个库,后面才能使用spring-cloud-kubernetes的服务:

org.springframework.cloud:spring-cloud-kubernetes-core:1.0.1.RELEASE
org.springframework.cloud:spring-cloud-kubernetes-discovery:1.0.1.RELEASE

b. 使用插件fabric8-maven-plugin来构建镜像并部署到minikube环境:


  io.fabric8
  fabric8-maven-plugin
  ${fabric8.maven.plugin.version}
  
    
      fmp
      
        resource
      
    
  

c. 为fabric8-maven-plugin插件准备了三个profile,本次实战主要用到kubernetes这个:

 
  kubernetes  
   
     
       
        io.fabric8  
        fabric8-maven-plugin  
        ${fabric8.maven.plugin.version}  
         
           
            fmp  
            
              resource  
              build 
             
           
          
         
           
             
              
                 
                NodePort 
               
             
           
         
       
     
   

以上就是pom.xml的内容了,主要是添加spring-cloud-kubernetes的依赖,以及使用fabric8来构建和部署;

  1. 在application.properties文件中设置应用名称:
spring.application.name=springcloudk8sdiscovery
  1. 创建应用启动类Springcloudk8sdiscoveryApplication,可见这是个很普通的springboot启动类:
package com.bolingcavalry.springcloudk8sdiscovery;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;


@SpringBootApplication
@EnableDiscoveryClient
public class Springcloudk8sdiscoveryApplication {

    public static void main(String[] args) {
        SpringApplication.run(Springcloudk8sdiscoveryApplication.class, args);
    }
}
  1. 创建controller类,对外提供http服务,部署完成后通过这些http服务来验证功能:
@RestController
public class DiscoveryController {

    @Autowired
    private DiscoveryClient discoveryClient;

    /**
     * 探针检查响应类
     * @return
     */
    @RequestMapping("/health")
    public String health() {
        return "health";
    }

    /**
     * 返回远程调用的结果
     * @return
     */
    @RequestMapping("/getservicedetail")
    public String getservicedetail(
            @RequestParam(value = "servicename", defaultValue = "") String servicename) {
        return "Service [" + servicename + "]'s instance list : " + JSON.toJSONString(discoveryClient.getInstances(servicename));
    }

    /**
     * 返回发现的所有服务
     * @return
     */
    @RequestMapping("/services")
    public String services() {
        return this.discoveryClient.getServices().toString()
                + ", "
                + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }
}

上述代码有几点需要注意:
a. health方法用于响应kubernetes的探针检查;
b. getservicedetail方法接收名为servicename的参数,然后去服务列表中检查对应的服务对象并返回;
c. services方法返回的是所有服务的名称;

以上就是所有代码了,功能是通过autowire得到DiscoveryClient实例,再调用该实例的API取得服务信息。

接下来我们将应用构建并部署到minikube环境;

编译构建

  1. 请确保当前电脑上java、maven、minikube都是正常的;
  2. 在pom.xml文件所在目录执行以下命令,即可编译构建部署一次性完成:
mvn clean package fabric8:deploy -Pkubernetes

构建成功后,控制台输出信息如下:

...
[INFO] 
[INFO] <<< fabric8-maven-plugin:3.5.37:deploy (default-cli) < install @ springcloudk8sdiscovery <<<
[INFO] 
[INFO] 
[INFO] --- fabric8-maven-plugin:3.5.37:deploy (default-cli) @ springcloudk8sdiscovery ---
[INFO] F8: Using Kubernetes at https://192.168.121.133:8443/ in namespace default with manifest /usr/local/work/demo/springcloudk8sdiscovery/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-springcloudk8sdiscovery.json
[INFO] Using namespace: default
[INFO] Updating Deployment from kubernetes.yml
[INFO] Updated Deployment: target/fabric8/applyJson/default/deployment-springcloudk8sdiscovery.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.207 s
[INFO] Finished at: 2019-06-09T18:50:09+08:00
[INFO] ------------------------------------------------------------------------
  1. 用kubectl命令查看部署和服务,都处于正常状态:
[root@minikube springcloudk8sdiscovery]# kubectl get deployments
NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
springcloudk8sdiscovery   1/1     1            1           75m
[root@minikube springcloudk8sdiscovery]# kubectl get svc
NAME                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes                ClusterIP   10.96.0.1               443/TCP          33h
springcloudk8sdiscovery   NodePort    10.102.167.79           8080:31583/TCP   75m
  1. 执行命令minikube service springcloudk8sdiscovery --url,得到的是可以从外部访问的服务地址:http://192.168.121.133:31583 ,其中192.168.121.133是宿主机IP地址;
  2. 在浏览器上访问地址http://192.168.121.133:31583/services ,如下图,返回的"所有服务"其实是kubernetes中的所有service:

  1. 为了验证当前namespace下的所有服务都能被发现,我们再创建个服务实施,执行以下命令,会创建名为my-tomcat的部署和服务:
kubectl run my-tomcat --image=tomcat:7.0.94-jre7-alpine --replicas=2 --port=8080 \
&& kubectl expose deployment my-tomcat --port=8080 --target-port=8080 --external-ip=192.168.50.7 --type=LoadBalancer

由于下载镜像需要一定时间,所以需要稍作等待;

  1. 再去访问地址http://192.168.121.133:31583/services ,如下图,my-tomcat赫然在列:

  1. 访问地址http://192.168.121.133:31583/getservicedetail?servicename=my-tomcat ,会得到名为my-tomcat的服务信息,该信息格式化后的内容如下所示:
[
    {
        "host": "172.17.0.4",
        "instanceId": "91201db9-8aa6-11e9-a5b5-000c29fd2001",
        "metadata": {
            "run": "my-tomcat"
        },
        "port": 8080,
        "scheme": "http://",
        "secure": false,
        "serviceId": "my-tomcat",
        "uri": "http://172.17.0.4:8080"
    },
    {
        "host": "172.17.0.5",
        "instanceId": "91223cda-8aa6-11e9-a5b5-000c29fd2001",
        "metadata": {
            "$ref": "$[0].metadata"
        },
        "port": 8080,
        "scheme": "http://",
        "secure": false,
        "serviceId": "my-tomcat",
        "uri": "http://172.17.0.5:8080"
    }
]

可见spring-cloud-kubernetes的DiscoveryClient服务将kubernetes中的"service"资源与SpringCloud中的服务对应起来了,有了这个DiscoveryClient,我们在kubernetes环境就不需要eureka来做注册发现了,而是直接使用kubernetes的服务机制,此时不得不感慨SpringCloud的对DiscoveryClient的设计是如此的精妙。

至此,spring-cloud-kubernetes的初体验就结束了,通过简单的编码我们的程序在kubernetes环境可以取得service资源的信息,随着学习的深入,我们会用到更多的spring-cloud-kubernetes能力,感谢spring-cloud-kubernetes的设计者,让我们的SpringCloud应用畅游在在kubernetes世界。

疑惑待解

您可能会有些疑惑:上面的代码都是和SpringCloud相关的,和spring-cloud-kubernetes没什么关系呀,为什么程序运行起来后就能取得kubernetes环境中的服务信息呢?
此问题如果不弄清楚,后面的学习很难展开,因为我们都不知道自己的代码与kubernetes环境有什么关系,和kubernetes有没有交互?

以上问题,欢迎访问《spring-cloud-kubernetes背后的三个关键知识点》,这里面有详细的分析。

欢迎关注我的公众号

你可能感兴趣的:(云计算)