无论你的应用程序是否在Kubernetes内运行,本指南前面描述的所有功能都同样有效。这对开发和故障排除真的很有帮助。从开发的角度来看,这可以让你启动你的Spring Boot应用,并调试属于这个项目的一个模块。你不需要将其部署在Kubernetes中,因为该项目的代码依赖于 Fabric8 Kubernetes Java客户端,它是一个fluent DSL,可以通过使用 http 协议与Kubernetes服务器的REST API进行通信。
Kubernetes 感知是基于Spring Boot API的,特别是基于 ConditionalOnCloudPlatform。该属性将自动检测你的应用程序当前是否部署在kubernetes中。可以通过 spring.main.cloud-platform 来覆盖该设置。
例如,如果你需要测试一些功能,但不想部署到一个集群,只需设置:spring.main.cloud-platform=KUBERNETES。这将使 spring-cloud-kubernetes 像部署在一个真正的集群中一样行动。
如果你的 classpath 上有
spring-cloud-starter-bootstrap
或者正在设置spring.cloud.bootstrap.enabled=true
,那么你将不得不在bootstrap.{properties|yml}
中设置spring.main.cloud-platform
(或特定的配置文件)。此外,请注意这些属性:spring.cloud.kubernetes.config.enabled
和spring.cloud.kubernetes.secrets.enabled
只有在你的 classpath 上有spring-cloud-starter-bootstrap
或者设置spring.cloud.bootstrap.enabled=true
时,在bootstrap.{properties|yml}
中的设置才会生效。
在3.0.x之前的Spring Cloud Kubernetes版本中,Kubernetes 感知是通过 spring.cloud.kubernetes.enabled 属性实现的。该属性已被删除,不受支持。相反,我们使用Spring Boot API ConditionalOnCloudPlatform。如果需要明确启用或禁用这一感应,请使用 spring.main.cloud-platform=NONE/KUBERNETES。
当应用程序在Kubernetes内以pod形式运行时,一个名为 kubernetes 的 Spring profile 会自动被激活。这让你可以定制配置,定义Spring Boot应用在 Kubernetes 平台内部署时应用的bean(例如,不同的开发和生产配置)。
当你在应用程序的 classpath 中包含 spring-cloud-kubernetes-fabric8-istio 模块时,一个新的 profile 就会被添加到应用程序中,前提是该应用程序是在安装了 Istio 的Kubernetes集群中运行。然后你可以在你的Bean和 @Configuration 类中使用spring @Profile("istio") 注解。
Istio 感知模块使用 me.snowdrop:istio-client 与 Istio API 交互,让我们发现流量规则、断路器等,使我们的Spring Boot应用能够轻松地消费这些数据,根据环境动态地配置自己。
Spring Boot使用 HealthIndicator 来暴露应用程序的健康信息。这使得它在向用户公开与健康有关的信息方面非常有用,并使它很适合作为 readiness 探针 使用。
Kubernetes健康指标(是核心模块的一部分)暴露了以下信息:
你可以通过在 application.[properties | yaml] 中设置 management.health.kubernetes.enabled 为 false 来禁用这个 HealthContributor。
Spring Cloud Kubernetes 包括一个 InfoContributor,它将Pod信息添加到Spring Boot的 /info Acturator端点。
你可以通过在 application.[properties | yaml] 中设置 management.info.kubernetes.enabled 为 false 来禁用这个 InfoContributor。
Spring Cloud Kubernetes Leader 选举机制使用Kubernetes ConfigMap 实现了Spring Integration 的 Leader 选举API。
多个应用程序实例竞争领导权(leadership),但领导权只授予一个。当被授予领导权时,leader 应用程序会收到一个带有 leadership Context 的 OnGrantedEvent application event。应用程序周期性地尝试获得领导权,领导权授予第一个调用者。一个leader将一直是一个leader,直到它被从集群中移除,或者它放弃了它的领导权。当领导权被移除时,前一个 leader 会收到 OnRevokedEvent application event。在移除之后,集群中的任何实例都可以成为新的 leader,包括旧的 leader。
要在你的项目中包含它,请添加以下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes-fabric8-leader</artifactId>
</dependency>
要指定用于 leader 选举的 configmap 的名称,请使用以下属性:
spring.cloud.kubernetes.leader.config-map-name=leader
该项目包括Spring Cloud Load Balancer,用于基于 Kubernetes Endpoints 的负载均衡,并提供了基于Kubernetes Service的负载均衡器的实现。要将其纳入你的项目,请添加以下依赖 :
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client-loadbalancer</artifactId>
</dependency>
要启用基于 Kubernetes Service name 的负载均衡,请使用以下属性。然后负载均衡器将尝试使用地址调用应用程序,例如 service-a.default.svc.cluster.local:
spring.cloud.kubernetes.loadbalancer.mode=SERVICE
要启用所有命名空间的负载均衡,请使用以下属性。遵守 spring-cloud-kubernetes-discovery
模块的属性。
spring.cloud.kubernetes.discovery.all-namespaces=true
如果一个服务需要通过HTTPS访问,你需要在你的服务定义中添加一个标签(add)或注解(annotation),名称为 secured
,值为 true
,然后负载均衡器将使用HTTPS向该服务发出请求。
本项目中提供的大多数组件都需要知道命名空间。对于Kubernetes(1.3以上),命名空间作为 service account secret 的一部分提供给pod,并由客户端自动检测。对于早期版本,它需要作为环境变量指定给pod。做到这一点的快速方法如下:
env:
- name: "KUBERNETES_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: "metadata.namespace"
对于支持集群内更精细的基于角色的访问的Kubernetes发行版,你需要确保使用 spring-cloud-kubernetes 运行的pod能够访问 Kubernetes API。对于你分配给deployment或pod的任何服务账户(service account),你需要确保它们有正确的角色。
根据要求,你需要 get、list 和 watch 以下资源的许可
依赖 | 资源 |
---|---|
spring-cloud-starter-kubernetes-fabric8 | pods, services, endpoints |
spring-cloud-starter-kubernetes-fabric8-config | configmaps, secrets |
spring-cloud-starter-kubernetes-client | pods, services, endpoints |
spring-cloud-starter-kubernetes-client-config | configmaps, secrets |
出于开发的目的,你可以在你的 default
服务账户中添加 cluster-reader
的权限。在生产系统中,你可能希望提供更细化的权限。
下面 的Role 和 RoleBinding 是 default
账户的命名空间权限的一个例子:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: YOUR-NAME-SPACE
name: namespace-reader
rules:
- apiGroups: [""]
resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
verbs: ["get", "list", "watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: namespace-reader-binding
namespace: YOUR-NAME-SPACE
subjects:
- kind: ServiceAccount
name: default
apiGroup: ""
roleRef:
kind: Role
name: namespace-reader
apiGroup: ""
在Kubernetes中,服务注册由平台控制,应用程序本身并不像在其他平台中那样控制注册。因此,使用 spring.cloud.service-registry.auto-registration.enabled 或设置 @EnableDiscoveryClient(autoRegister=false) 在Spring Cloud Kubernetes中没有效果。
Kubernetes 提供了 将 ConfigMap 或 Secret 挂载到应用程序的容器中作为卷 的能力。当 ConfigMap 或 Secret 的内容发生变化时, 挂载的卷就会根据这些变化进行更新。
然而,除非你重新启动应用程序,否则Spring Boot不会自动更新这些变化。Spring Cloud 提供了刷新 application context 的能力,无需重启应用程序,方法是点击 actuator 的 /refresh 端点,或通过使用 Spring Cloud Bus 发布 RefreshRemoteApplicationEvent。
为了实现在Kubernetes上运行的Spring Cloud应用程序的这种配置刷新,你可以将 Spring Cloud Kubernetes Configuration Watcher controller 部署到你的Kubernetes集群中。
该应用程序以容器形式发布,可在 Docker Hub 上使用。然而,如果你需要定制配置 watcher 的行为,或者喜欢自己构建镜像,你可以很容易地从 GitHub上的源代码 构建自己的镜像并使用它。
Spring Cloud Kubernetes Configuration Watcher 可以通过两种方式向应用程序发送刷新通知。
通过HTTP,在这种情况下,被通知的应用程序必须有 /refresh actuator 端点暴露出来,并且可以从集群内访问。
使用Spring Cloud Bus,在这种情况下,你将需要在你的集群中部署一个message broker,以便应用程序使用。
下面是一个 deployment YAML 的样本,你可以用来将 Kubernetes Configuration Watcher 部署到 Kubernetes:
---
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: Service
metadata:
labels:
app: spring-cloud-kubernetes-configuration-watcher
name: spring-cloud-kubernetes-configuration-watcher
spec:
ports:
- name: http
port: 8888
targetPort: 8888
selector:
app: spring-cloud-kubernetes-configuration-watcher
type: ClusterIP
- apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: spring-cloud-kubernetes-configuration-watcher
name: spring-cloud-kubernetes-configuration-watcher
- apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app: spring-cloud-kubernetes-configuration-watcher
name: spring-cloud-kubernetes-configuration-watcher:view
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: namespace-reader
subjects:
- kind: ServiceAccount
name: spring-cloud-kubernetes-configuration-watcher
- apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: namespace-reader
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
verbs: ["get", "list", "watch"]
- apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-cloud-kubernetes-configuration-watcher-deployment
spec:
selector:
matchLabels:
app: spring-cloud-kubernetes-configuration-watcher
template:
metadata:
labels:
app: spring-cloud-kubernetes-configuration-watcher
spec:
serviceAccount: spring-cloud-kubernetes-configuration-watcher
containers:
- name: spring-cloud-kubernetes-configuration-watcher
image: springcloud/spring-cloud-kubernetes-configuration-watcher:2.0.1-SNAPSHOT
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
port: 8888
path: /actuator/health/readiness
livenessProbe:
httpGet:
port: 8888
path: /actuator/health/liveness
ports:
- containerPort: 8888
Service Account 和相关的角色绑定对于 Spring Cloud Kubernetes 配置的正常工作非常重要。controller 需要读取 Kubernetes 集群中的 ConfigMaps、Pods、Services、Endpoints和Secrets 数据的权限。
大家好,我是Doker品牌的Sinbad,欢迎点赞和评论,您的鼓励是我们持续更新的动力!欢迎加微信进入技术群聊!