引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8-all</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
spring-cloud-starter-bootstrap
不引入的话,不会启用bootstrap,也就不会加载Kubernetes ConfigMaps和Secrets
权限设置
无论是服务发现,还是加载ConfigMap/Secret,都需要访问k8s api,app需要具备相应的访问控制权限
- apiVersion: v1
kind: ServiceAccount
metadata:
namespace: default #服务和配置部署的namespace
name: spring-cloud-sa #定义服务账号,Deployment中指定pod使用该sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default #服务和配置部署的namespace
name: namespace-reader #定义角色名
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["configmaps", "secrets"]
verbs: ["get", "list"]
- apiGroups: ["", "extensions", "apps"]
resources: ["pods", "services", "endpoints"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: mozi-namespace-reader-binding #定义RoleBinding名称
namespace: default #服务和配置部署的namespace
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: namespace-reader
subjects:
- kind: ServiceAccount
name: spring-cloud-sa
另外设置pod的serviceAccountName为spring-cloud-sa
apiVersion: apps/v1
kind: Deployment
metadata:
...
spec:
...
template:
spec:
serviceAccountName: spring-cloud-sa # 设置SA
containers:
...
服务发现
首先,k8s服务的名称和应用的spring.application.name
属性对齐
启用DiscoveryClient
要启用DiscoveryClient
,就要添加@EnableDiscoveryClient
(但实测下来,不加这个注解,也可以注入DiscoveryClient
)
@SpringBootApplication
@EnableDiscoveryClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
从哪里(namespace)发现服务
设置从哪个namespace中查找服务
-
指定多个namespace
spring.cloud.kubernetes.discovery.namespaces[0]=ns1 spring.cloud.kubernetes.discovery.namespaces[1]=ns2
-
所有namespace
spring.cloud.kubernetes.discovery.all-namespaces=true
-
不配置指定,使用默认设置,一般就是应用所在的namespace
发现哪些服务
默认不会过滤,可以通过以下方式缩小发现的服务范围
通过服务标签匹配
spring.cloud.kubernetes.discovery.service-labels
匹配 Service的metadata.labels
使用SpEL表达式匹配
设置spring.cloud.kubernetes.discovery.filter
例如,发现Service中metadata.namespace
的值以大写A结尾
spring.cloud.kubernetes.discovery.filter='#root.metadata.namespace matches "^.+A$"'
ConfigMap和Secret配置管理
ConfigMap配置
指定单个ConfigMap
ConfigMap的metadata.name
- 要么是应用名(
spring.application.name
) - 要么是
bootstrap.yml
里配置的spring.cloud.kubernetes.config.name
(这个默认就是应用名)
指定多个ConfigMap
spring:
application:
name: cloud-k8s-app
cloud:
kubernetes:
config:
name: default-name
namespace: default-namespace
sources:
# Spring Cloud Kubernete会查找命令空间default-namespace中ConfigMap c1
- name: c1
# Spring Cloud Kubernetes会查找命名空间n2中ConfigMap default-name
- namespace: n2
# Spring Cloud Kubernetes会查找命名空间n3中ConfigMap c3
- namespace: n3
name: c3
- 如果没有指定
spring.cloud.kubernetes.config.namespace
,一般会查询应用所在的namespace - sources中,如果属性名相同,则排在后面的ConfigMap最终生效
Secret配置
敏感数据,例如数据库密码等,建议使用Secret配置,默认enable-api是false,需要改成true,其他设置跟ConfigMap一样
spring:
cloud:
kubernetes:
secrets:
enable-api: true
ConfigMap和Secret的优先级
在同时启用configmap和secret的情况下,当有相同的值时,ConfigMap的优先级更高