Spring Cloud和Kubernetes实战

1. Kubernetes简介

使用Minikube创建群集

Kubernetes协调一个高度可用的计算机集群,这些计算机连接起来作为一个单元工作。Kubernetes以更有效的方式自动化跨集群分发和调度应用程序容器。Kubernetes集群包含两种类型的资源:

  • Master协调集群
  • Nodes是运行应用程序的工作者,是VM或物理计算机

Nodes使用Master公开的Kubernetes API与Master进行通信。

Minikube是一种轻量级Kubernetes实现,可在本地计算机上创建VM并部署仅包含一个节点的简单集群。

使用kubectl创建部署

部署指示Kubernetes如何创建和更新应用程序的实例。

如果托管实例的节点关闭或被删除,则Deployment控制器会替换它。 这提供了一种自我修复机制来解决机器故障或维护问题。创建部署时,需要指定应用程序的容器映像以及要运行的副本数。

查看Pods和Nodes

Pods

创建部署时,Kubernetes创建了一个Pod来托管您的应用程序实例。Pod是一组一个或多个应用程序容器(例如Docker或rkt),包括共享存储(卷),IP地址和有关如何运行它们的信息。

Nodes

Pod总是在Node上运行。 Node是Kubernetes中的工作机器,可以是虚拟机器,也可以是物理机器,具体取决于集群。

使用服务公开您的应用程序

Kubernetes中的服务是一个抽象,它定义了一组逻辑Pod和一个访问它们的策略。服务启用从属Pod之间的松散耦合。与所有Kubernetes对象一样,使用YAML(首选)或JSON定义服务。通过在ServiceSpec中指定类型,可以以不同方式公开服务:

  • ClusterIP(默认) - 在群集中的内部IP上公开服务。此类型使服务只能从群集中访问。
  • NodePort - 使用NAT在集群中每个选定节点的同一端口上公开服务。使用<NodeIP>:<NodePort>使集群外部的服务可访问。 ClusterIP的超集。
  • LoadBalancer - 在当前云中创建外部负载均衡器(如果支持),并为服务分配固定的外部IP。 NodePort的超级用户。
  • ExternalName - 通过返回带有名称的CNAME记录,使用任意名称(在规范中由externalName指定)公开服务。没有使用代理。此类型需要v1.7或更高版本的kube-dns。

2. 使用Kubernetes,Spring Boot 2.0和Docker创建微服务

有三个独立的应用程序(员工服务,部门服务,组织服务),它们通过REST API相互通信。 这些Spring Boot微服务使用Kubernetes提供的一些内置机制:用于分布式配置的配置映射和机密,用于服务发现的etcd,以及用于API网关的入口。

微服务部署后Kubernetes的管理界面如下

使用配置映射和秘密注入配置

配置文件mongodb-configMap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongodb
data:
  database-name: microservices

加密配置文件mongodb-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: mongodb
type: Opaque
data:
  database-password: MTIzNDU2
  database-user: cGlvdHI=

分别执行kubectl apply -f mongodb-configMap.yaml kubectl apply -f mongodb-secret.yaml 创建配置映射。

使用Kubernetes构建服务发现

在服务中添加Spring Cloud Kubernetes依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-kubernetes</artifactId>
	<version>0.3.0.RELEASE</version>
</dependency>

在服务启动类中开启服务发现

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableMongoRepositories
@EnableSwagger2
public class EmployeeApplication {
    public static void main(String[] args) {
        SpringApplication.run(EmployeeApplication.class, args);
    }
}

使用Spring Cloud Kubernetes Ribbon来进行微服务之间的通信

在服务中添加依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-kubernetes-ribbon</artifactId>
	<version>0.3.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

它使用@EnableFeignClients批注启用Feign客户端。 它的工作原理与基于Spring Cloud Netflix Eureka的发现相同。 OpenFeign使用Ribbon进行客户端负载平衡。 Spring Cloud Kubernetes Ribbon提供了一些bean,强制Ribbon通过Fabric8 KubernetesClient与Kubernetes API进行通信。

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableMongoRepositories
@EnableSwagger2
public class EmployeeApplication {

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

使用Docker构建微服务并在Kubernetes上部署

Docker构建文件

FROM openjdk:8-jre-alpine
ENV APP_FILE employee-1.0.jar
ENV APP_HOME /usr/apps
EXPOSE 8080
COPY target/$APP_FILE $APP_HOME/
WORKDIR $APP_HOME
ENTRYPOINT ["sh", "-c"]
CMD ["exec java -jar $APP_FILE"]

创建服务镜像

cd employee
docker build -t jiangjj/employee:1.0 .
cd department
docker build -t jiangjj/department:1.0 .
cd organization
docker build -t jiangjj/organization:1.0 .

服务在Kubernetes上创建部署和服务的配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: employee
  labels:
    app: employee
spec:
  replicas: 1
  selector:
    matchLabels:
      app: employee
  template:
    metadata:
      labels:
        app: employee
    spec:
      containers:
      - name: employee
        image: jiangjj/employee:1.0
        ports:
        - containerPort: 8080
        env:
        - name: MONGO_DATABASE
          valueFrom:
            configMapKeyRef:
              name: mongodb
              key: database-name
        - name: MONGO_USERNAME
          valueFrom:
            secretKeyRef:
              name: mongodb
              key: database-user
        - name: MONGO_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongodb
              key: database-password
---
apiVersion: v1
kind: Service
metadata:
  name: employee
  labels:
    app: employee
spec:
  ports:
  - port: 8080
    protocol: TCP
  selector:
    app: employee

创建服务的配置

kubectl apply -f k8s\employee-deployment.yaml
kubectl apply -f k8s\department-deployment.yaml
kubectl apply -f k8s\organization-deployment.yaml

使用Kubernetes Ingress构建API网关

Ingress是一组规则,允许传入请求到达下游服务。 在我们的微服务架构中,ingress扮演着API网关的角色。

ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gateway-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  backend:
    serviceName: default-http-backend
    servicePort: 80
  rules:
  - host: microservices.info
    http:
      paths:
      - path: /employee
        backend:
          serviceName: employee
          servicePort: 8080
      - path: /department
        backend:
          serviceName: department
          servicePort: 8080
      - path: /organization
        backend:
          serviceName: organization
          servicePort: 8080

必须执行以下命令才能将上述配置应用于Kubernetes集群

kubectl apply -f k8s\ingress.yaml

使用Swagger2在网关上启用API规范

Zuul将仅作为服务Swagger API的网关,这是网关服务项目中使用的依赖项列表

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-kubernetes</artifactId>
	<version>0.3.0.RELEASE</version>
</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-kubernetes-ribbon</artifactId>
	<version>0.3.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger-ui</artifactId>
	<version>2.9.2</version>
</dependency>
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger2</artifactId>
	<version>2.9.2</version>
</dependency>

Kubernetes发现客户端将检测群集上公开的所有服务。我们只想显示三个微服务的文档,这就是为Zuul定义以下路由的原因

zuul:
  routes:
    department:
      path: /department/**
    employee:
      path: /employee/**
    organization:
      path: /organization/**

现在我们可以使用ZuulProperties bean从Kubernetes发现中获取路由的地址,并将它们配置为Swagger资源

@Component
public class GatewayApi {
    @Autowired
    ZuulProperties properties;
    @Primary
    @Bean
    public SwaggerResourcesProvider swaggerResourcesProvider() {
        return () -> {
            List resources = new ArrayList();
            properties.getRoutes().values().stream()
                    .forEach(route -> resources.add(createResource(route.getId(), "2.0")));
            return resources;
        };
    }
    private SwaggerResource createResource(String location, String version) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(location);
        swaggerResource.setLocation("/" + location + "/v2/api-docs");
        swaggerResource.setSwaggerVersion(version);
        return swaggerResource;
    }
}

gateway在Kubernetes上的配置如下

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gateway
  labels:
    app: gateway
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gateway
  template:
    metadata:
      labels:
        app: gateway
    spec:
      containers:
      - name: gateway
        image: jiangjj/gateway:1.0
        ports:
        - containerPort: 8080
        env:
        - name: MONGO_DATABASE
          valueFrom:
            configMapKeyRef:
              name: mongodb
              key: database-name
        - name: MONGO_USERNAME
          valueFrom:
            secretKeyRef:
              name: mongodb
              key: database-user
        - name: MONGO_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongodb
              key: database-password
---
apiVersion: v1
kind: Service
metadata:
  name: gateway
  labels:
    app: gateway
spec:
  type: NodePort
  ports:
  - port: 8080
    nodePort: 31237
    protocol: TCP
  selector:
    app: gateway

部署后通过gateway查看API页面

源码地址:https://github.com/jiangjj/spring-cloud-kubernetes

转载于:https://my.oschina.net/u/869718/blog/2250375

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值