集成Kubernetes来构建微服务-springcloud⼊门教程
Spring Cloud和Kubernetes是⽬前Java平台下微服务应⽤的使⽤得最多的产品。然⽽,当谈到微服务架构时,它们有时被描述为具有竞争⼒的解决⽅案。它们都在微服务架构中实现流⾏的模式,如服务发现、分布式配置、负载平衡或断路。当然,他们的做法不同。Kubernetes 是⼀个⽤于运⾏、扩展和管理容器化应⽤程序的平台。Kubernetes 最重要的组件之⼀是etcd。该⾼度可⽤的键值存储负责存储所有集数据,包括服务注册表和应⽤程序配置。我们不能⽤任何其他⼯具代替它。可以使⽤Istio或 Linkerd等第三⽅组件来实现更⾼级的路由和负载均衡策略。要在 Kubernetes 上部署和运⾏应⽤程序,我们⽆需在源代码中添加任何内容。编排和配置是在应⽤程序之外实现的——在平台上。
Spring Cloud 提出了⼀种不同的⽅法。所有组件都必须在应⽤程序端包含和配置。它为我们提供了许多与⽤于云原⽣开发的各种⼯具和框架集成的可能性。但是,⼀开始 Spring Cloud 是围绕 Eureka、Ribbon等 Netflix OSS 组件构建的、Hystrix 或 Zuul。它为我们提供了⼀种机制,可以轻松地将它们包含到我们基于微服务的架构中,并将它们与其他云原⽣组件集成。⼀段时间后,必须重新考虑这种⽅法。今天,我们有很多由 Spring Cloud 开发的组件,⽐如 Spring Cloud Gateway(Zuul 替代品)、Spring Cloud Load Balancer(Ribbon 替代品)、Spring Cloud Circuit Breaker(Hystrix 替代品)。还有⼀个相对较新的与Kubernetes集成的项⽬——Spring Cloud Kubernetes。
为什么选择 Spring Cloud Kubernetes?
在我们将微服务迁移到 OpenShift 时,Spring Cloud Kubernetes 项⽬正处于孵化阶段。由于我们没有任何其他有趣的从 Spring Cloud 迁移到 OpenShift 的选择,包括从 Spring Boot 应⽤程序中删除⽤于发现(Eureka 客户端)和配置(Spring Cloud Config 客户端)的组件。当然,我们仍然可以使⽤其他 Spring Cloud 组件,如 OpenFeign、Ribbon(通过 Kubernetes 服务)或 Sleuth。那么,问题是我们真的需要Spring Cloud Kubernetes 吗?哪些功能对我们来说会很有趣。
⾸先,让我们看看在 Spring Cloud Kubernetes ⽂档站点上构建⼀个新框架的动机。
Spring Cloud Kubernetes 提供使⽤ Kubernetes 原⽣服务的 Spring Cloud 通⽤接⼝实现。此存储库中提供的项⽬的主要⽬标是促进在 Kubernetes 内运⾏的 Spring Cloud 和 Spring Boot 应⽤程序的集成。
简单来说,Spring Cloud Kubernetes 提供了与Kubernetes Master API 的集成,以允许以 Spring Cloud 的⽅式使⽤发现、配置和负载平衡。
在本⽂中,我将介绍 Spring Cloud Kubernetes 的以下有⽤功能:
使⽤ DiscoveryClient ⽀持在所有命名空间中扩展发现
在 Spring Cloud Kubernetes Config 中使⽤ ConfigMap 和 Secrets 作为 Spring Boot 属性源
使⽤ Spring Cloud Kubernetes pod 健康指标实现健康检查
启⽤ Spring Cloud Kubernetes
假设我们将使⽤ Spring Cloud Kubernetes 提供的更多功能,我们应该将以下依赖项包含到我们的 Maven 中l。它包含⽤于发现、配置和功能区负载平衡的模块。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-all</artifactId>
</dependency>
跨所有命名空间的发现
Spring Cloud Kubernetes 通过提供DiscoveryClient. 我们还可以利⽤与 Ribbon 客户端的内置集成,在不使⽤ Kubernetes 服务的情况下直接与Pod 通信。Ribbon 客户端可以被更⾼级别的 HTTP 客户端——OpenFeign 所利⽤。要实现这样的模型,我们必须启⽤发现客户端、Feign 客户端和 Mongo 存储库,因为我们使⽤ Mongo 数据库作为后端存储。
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableMongoRepositories
public class DepartmentApplication {
public static void main(String[] args) {
SpringApplication.run(DepartmentApplication.class, args);
}
}
让我们考虑⼀下我们有三个微服务的场景,每个微服务都部署在不同的命名空间中。划分命名空间只是⼀个逻辑分组,例如我们有三个不同的团队负责每个微服务,我们希望只将命名空间的权限授予负责给定应⽤程序的团队。在位于不同命名空间的应⽤程序之间的通信中,我们必须在调⽤ URL 上包含⼀个命名空间名称作为前缀。我们还需要设置⼀个可能因应⽤程序⽽异的端⼝号。在这种情况下,Spring Cl
oud Kubernetes 发现会提供帮助。由于 Spring Cloud Kubernetes 与主 API 集成,因此能够获取为同⼀应⽤程序创建的所有 pod 的 IP。这是说明我们场景的图表。
要启⽤跨所有命名空间的发现,我们只需要使⽤以下属性。
spring:
cloud:
kubernetes:
discovery:
all-namespaces: true
现在,我们可以实现负责消费⽬标端点的 Feign 客户端接⼝。这是来⾃部门服务的⽰例客户端,专门⽤于与员⼯服务进⾏通信。
@FeignClient(name = "employee")
public interface EmployeeClient {
@GetMapping("/department/{departmentId}")
List<Employee> findByDepartment(@PathVariable("departmentId") String departmentId);
}
Spring Cloud Kubernetes 需要访问 Kubernetes API,以便能够检索为单个服务运⾏的 pod 的地址列表。使⽤ Minikube 时最简单的⽅法
是ClusterRoleBinding使⽤cluster-admin特权创建默认值。运⾏以下命令后,您可以确保每个 Pod 都有⾜够的权限与 Kubernetes API 通信。
$ kubectl create clusterrolebinding admin --clusterrole=cluster-admin --serviceaccount=default:default
使⽤ Kubernetes PropertySource 进⾏配置
Spring Cloud Kubernetes PropertySource实现允许我们直接在应⽤程序中使⽤ConfigMap和使⽤,Secret⽽⽆需将它们注⼊Deployment. 默认⾏为基于metadata.name inside ConfigMap or Secret,它必须与应⽤程序名称相同(由其spring.application.name属性定义)。您还可以使⽤更⾼级的⾏为,您可以为配置注⼊定义命名空间和对象的⾃定义名称。您甚⾄可以使⽤多个ConfigMap或Secret实例。但是,我们使⽤默认⾏为,因此假设我们有以下内容l:
spring:
application:
name: employee
我们将定义以下内容ConfigMap:
kind: ConfigMap
apiVersion: v1
metadata:
name: employee
data:
sole: "%d{HH:mm:ss} ${LOG_LEVEL_PATTERN:-%5p} %m%n"
spring.cloud.kubernetes.discovery.all-namespaces: "true"
db.database: "admin"
db.host: "mongodb.default"
或者,您可以在ConfigMap.
apiVersion: v1
kind: ConfigMap
metadata:
name: employee
data:
application.yaml: |-
sole: "%d{HH:mm:ss} ${LOG_LEVEL_PATTERN:-%5p} %m%n"
spring.cloud.kubernetes.discovery.all-namespaces: true
spring怎么读取yaml
spring:
data:
mongodb:
database: admin
host: mongodb.default
在配置映射中,我们定义了 Mongo 位置、⽇志模式和负责允许多命名空间发现的属性。Mongo 凭据应在Secret对象内部定义。规则与配置映射相同。
apiVersion: v1
kind: Secret
metadata:
name: employee
type: Opaque
data:
db.username: UGlvdF8xMjM=
db.password: cGlvdHI=
值得注意的是,出于安全原因,默认情况下不启⽤通过 API 使⽤机密。但是,我们已经设置了默认cluster-admin⾓⾊,所以我们不必担⼼。我们唯⼀需要做的就是通过 Spring Cloud Kubernetes 的 API 启⽤使⽤机密,默认情况下该 API 是禁⽤的。为此,我们必须在l.
spring:
cloud:
kubernetes:
secrets:
enableApi: true
在 Minikube 上部署 Spring Cloud 应⽤程序
⾸先,让我们使⽤kubectl create namespace命令创建所需的命名空间。下⾯是创建命名空间的命令a,b,c和d。
然后,让我们通过执⾏ Maven mvn clean install命令来构建代码。
我们还需要设置cluster-admin新创建的命名空间,以允许在这些命名空间内运⾏的 Pod 读取主 API。
现在,让我们看看我们的 Kubernetes 部署清单。它⾮常简单,因为它没有从ConfigMap和注⼊任何属性Secret。它已经由 Spring Cloud Kubernetes Config 执⾏。这是employee-service的部署 YAML ⽂件。
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: piomin/employee:1.1
ports:
-
containerPort: 8080
最后,我们可以在 Kubernetes 上部署我们的应⽤程序。每个微服务有ConfigMap,Secret,Deployment和Service对象。YAML 清单在/kubernetes⽬录内的 Git 存储库中可⽤。我们使⽤kubectl apply如下所⽰的命令依次应⽤它们。
出于测试⽬的,您可以通过定义NodePort类型在节点外公开⽰例应⽤程序。
apiVersion: v1
kind: Service
metadata:
name: department
labels:
app: department
spec:
ports:
- port: 8080
protocol: TCP
selector:
app: department
type: NodePort
公开有关 Pod 的信息
使⽤ Spring Cloud Kubernetes,每个 Spring Boot 应⽤程序都会公开有关 pod ip、pod 名称和命名空间名称的信息。要输⼊它,您需要调⽤/info端点,如下所⽰。
microservices-with-spring-cloud-kubernetes-info
这是部署所有⽰例微服务和⽹关后分布在所有命名空间之间的 pod 列表。
还有⼀个部署列表。
运⾏⽹关
我们架构中的最后⼀个元素是⽹关。我们使⽤ Spring Cloud Netflix Zuul,它通过 Ribbon 客户端与 Kubernetes 发现集成。它公开了分布在多个命名空间中的所有⽰例微服务的 Swagger ⽂档。这是所需依赖项的列表。
<dependencies>
<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-all</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</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>
</dependencies>
路由的配置⾮常简单。我们只需要使⽤ Spring Cloud Kubernetes 发现功能。
apiVersion: v1
kind: ConfigMap
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论