DiscoveryClient for Kubernetes
此项目针对 Kubernetes 提供了 Discovery Client 的实现。此客户端允许您按名称查询 Kubernetes 端点(参见 services)。通常,Kubernetes API 服务器将服务显示为端点集合,这些端点表示 http
和 https
地址,并且客户端可以从作为 Pod 运行的 Spring Boot 应用程序对其进行访问。
This project provides an implementation of Discovery Client
for Kubernetes.
This client lets you query Kubernetes endpoints (see services) by name.
A service is typically exposed by the Kubernetes API server as a collection of endpoints that represent http
and https
addresses and that a client can
access from a Spring Boot application running as a pod.
DiscoveryClient 还可以找到类型为 ExternalName
的服务(请参阅 ExternalName services)。目前,如果将 spring.cloud.kubernetes.discovery.include-external-name-services
设置为 true
(默认为 false
),只有当服务类型支持外部名称时才可用。
DiscoveryClient can also find services of type ExternalName
(see ExternalName services). At the moment, external name support type of services is only available if the following property spring.cloud.kubernetes.discovery.include-external-name-services
is set to true
(it is false
by default).
我们支持 3 种类型的发现客户端:
There are 3 types of discovery clients that we support:
1.
Fabric8 Kubernetes Client
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-fabric8</artifactId>
</dependency>
2.
Kubernetes Java Client
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client</artifactId>
</dependency>
3.
基于 HTTP 的 DiscoveryClient
HTTP Based DiscoveryClient
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-discoveryclient</artifactId>
</dependency>
|
|
要启用 DiscoveryClient
的加载,请对相应的配置或应用程序类添加 @EnableDiscoveryClient
,如下例所示:
To enable loading of the DiscoveryClient
, add @EnableDiscoveryClient
to the according configuration or application class, as the following example shows:
@SpringBootApplication
@EnableDiscoveryClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
然后,您可以通过自动注入的方式在代码中注入客户端,如下例所示:
Then you can inject the client in your code simply by autowiring it, as the following example shows:
@Autowired
private DiscoveryClient discoveryClient;
您应该问自己的第一个问题是 DiscoveryClient
应该在哪里查找服务。在 Kubernetes 环境中,这意味着哪些命名空间。这里有 3 个选项:
The first question you should ask yourself is where a DiscoveryClient
supposed to discover services. In the kubernetes world, this means what namespace(s). There are 3 options here:
-
selective namespaces
. For example:
spring.cloud.kubernetes.discovery.namespaces[0]=ns1
spring.cloud.kubernetes.discovery.namespaces[1]=ns2
这种配置使发现客户端仅搜索命名空间 ns1
和 ns2
中的服务。
Such a configuration makes discovery client only search for services in two namespaces ns1
and ns2
.
-
all-namespaces
.
spring.cloud.kubernetes.discovery.all-namespaces=true
虽然有这样的选项,但这可能会给 kube-api 和您的应用程序带来负担。很少需要这样的设置。
While such an option exists, this can be a burden on both kube-api and your application. It is rare to need such a setting.
-
one namespace
。这是默认设置,如果你未指定以上任何一项。它基于 Namespace Resolution 中概述的规则工作。 -
one namespace
. This is the default setting, if you do not specify any of the above. It works on the rules outlined in Namespace Resolution.
上述选项以与 fabric8 和 k8s 客户端完全相同的方式执行。对于基于 HTTP 的客户端,需要在 server 上启用这些选项。可以通过在 deployment.yaml
中设置这些选项来实现,该选项用于在集群中部署图像,即使用环境变量。
The above options work exactly as written for fabric8 and k8s clients. For the HTTP based client, you need to enable those options on the server. That can be achieved by setting them in deployment.yaml
used to deploy the image in the cluster, using env variable(s).
例如:
For example:
containers:
- name: discovery-server
image: springcloud/spring-cloud-kubernetes-discoveryserver:3.0.5-SNAPSHOT
env:
- name: SPRING_CLOUD_KUBERNETES_DISCOVERY_NAMESPACES_0
value: "namespace-a"
配置命名空间后,要回答的下一个问题是发现哪些服务。考虑将其视为要应用的筛选器。默认情况下,不应用任何筛选,并且发现所有服务。如果您需要缩小发现客户端所能找到的范围,您有两个选择:
Once namespaces have been configured, the next question to answer is what services to discover. Think about it as what filter to apply. By default, no filtering is applied at all and all services are discovered. If you need to narrow what discovery client can find, you have two options:
-
仅使用符合某些服务标签的服务。此属性使用以下内容指定:
spring.cloud.kubernetes.discovery.service-labels
。它接受Map
,并且仅考虑具有此类标签(如服务定义中的metadata.labels
中所示)的服务。 -
Only take services that match certain service labels. This property is specified with:
spring.cloud.kubernetes.discovery.service-labels
. It accepts aMap
and only those services that have such labels (as seen inmetadata.labels
in the service definition) will be taken into account. -
另一个选项是使用 SpEL expression。这由
spring.cloud.kubernetes.discovery.filter
属性表示,并且它的值取决于你选择的客户端。如果你使用 fabric8 客户端,则此 SpEL 表达式必须针对io.fabric8.kubernetes.api.model.Service
类进行创建。其中一个示例可能是: -
The other option is to use SpEL expression. This is denoted by the
spring.cloud.kubernetes.discovery.filter
property, and its value depends on the client that you chose. If you use the fabric8 client, this SpEL expression must be created againstio.fabric8.kubernetes.api.model.Service
class. One such example could be:
spring.cloud.kubernetes.discovery.filter='#root.metadata.namespace matches "^.+A$"'
这告诉发现客户端仅获取具有以大写“A”结尾的 metadata.namespace
的服务。
which tells discovery client to only get services that have the metadata.namespace
that ends in upper case A
.
如果您的发现客户端基于 k8s 原生客户端,则 SpEL 表达式必须基于 io.kubernetes.client.openapi.models.V1Service
类。上面显示的相同筛选器会在这里起作用。
If your discovery client is based on k8s-native client, then the SpEL expression must be based on io.kubernetes.client.openapi.models.V1Service
class. The same filter showed above would work here.
如果您的发现客户端是基于 http 的,则 SeEL 表达式必须基于相同的 io.kubernetes.client.openapi.models.V1Service
类,唯一的区别在于这需要在部署 yaml 中设置为环境变量:
If your discovery client is the http based one, then the SeEL expression has to be based on the same io.kubernetes.client.openapi.models.V1Service
class, with the only distinction that this needs to be set as an env variable in the deployment yaml:
containers: - name: discovery-server image: springcloud/spring-cloud-kubernetes-discoveryserver:3.0.5-SNAPSHOT env: - name: SPRING_CLOUD_KUBERNETES_DISCOVERY_FILTER value: '#root.metadata.namespace matches "^.+A$"'
现在是考虑发现客户端应该返回什么的时候了。一般来说,DiscoveryClient
有两种方法:getServices
和 getInstances
。
It’s now time to think what discovery client is supposed to return back. In general, there are two methods that DiscoveryClient
has: getServices
and getInstances
.
getServices
将返回在 metadata.name
中看到的服务名称。
getServices
will return the service names as seen in the metadata.name
.
这种方法将返回唯一的服务名称,即使不同命名空间(您为搜索选择的命名空间)中存在重复。 |
This method will return unique service names, even if there are duplicates across different namespaces (that you chose for the search). |
getInstances
返回 List<ServiceInstance>
。除了 ServiceInstance
所具有的常规字段外,我们还添加了一些数据,如命名空间或 Pod 元数据(本文档中稍后会对此进行更多说明)。以下是我们目前返回的数据:
getInstances
returns a List<ServiceInstance>
. Besides the usual fields that a ServiceInstance
has, we also add some data, like namespace or pod metadata (more explanation about these will follow in the document). Here is the data that we return at the moment:
-
instanceId
- 服务实例的唯一 ID -
instanceId
- unique id of the service instance -
serviceId
- 服务的名称(与调用getServices
报告的名称相同) -
serviceId
- the name of the service (it is the same as the one reported by callinggetServices
) -
host
- 实例的 IP(或者对于ExternalName
类型服务的情况,为名称) -
host
- IP of the instance (or name in case of theExternalName
type of service) -
port
- 实例的端口号。这需要更多解释,因为选择端口号有其规则:[style="loweralpha"]
-
服务未定义端口,将返回 0(零)。
-
service has no port defined, 0 (zero) will be returned.
-
服务定义了一个端口,将返回该端口。
-
service has a single port defined, that one will be returned.
-
如果服务带有标签
primary-port-name
,我们将使用标签值中指定名称的端口号。 -
If the service has a label
primary-port-name
, we will use the port number that has the name specified in the label’s value. -
如果未显示上述标签,则我们将使用
spring.cloud.kubernetes.discovery.primary-port-name
中指定的端口名称来查找端口号。 -
If the above label is not present, then we will use the port name specified in
spring.cloud.kubernetes.discovery.primary-port-name
to find the port number. -
如果以上两者都没有指定,我们将使用名为
https
或http
的端口来计算端口号。 -
If neither of the above are specified, we will use the port named
https
orhttp
to compute the port number. -
最后,我们将选择端口列表中的第一个端口。此选项可能导致不确定的行为。
-
As a last resort we wil pick the first port in the list of ports. This last option may result in non-deterministic behaviour.
-
port
- port number of the instance. This requires a bit more explanation, as choosing the port number has its rules:[style="loweralpha"]
-
服务未定义端口,将返回 0(零)。
-
service has no port defined, 0 (zero) will be returned.
-
服务定义了一个端口,将返回该端口。
-
service has a single port defined, that one will be returned.
-
如果服务带有标签
primary-port-name
,我们将使用标签值中指定名称的端口号。 -
If the service has a label
primary-port-name
, we will use the port number that has the name specified in the label’s value. -
如果未显示上述标签,则我们将使用
spring.cloud.kubernetes.discovery.primary-port-name
中指定的端口名称来查找端口号。 -
If the above label is not present, then we will use the port name specified in
spring.cloud.kubernetes.discovery.primary-port-name
to find the port number. -
如果以上两者都没有指定,我们将使用名为
https
或http
的端口来计算端口号。 -
If neither of the above are specified, we will use the port named
https
orhttp
to compute the port number. -
最后,我们将选择端口列表中的第一个端口。此选项可能导致不确定的行为。
-
As a last resort we wil pick the first port in the list of ports. This last option may result in non-deterministic behaviour.
-
服务实例的
uri
-
uri
of the service instance -
scheme
http
或https
(取决于secure
结果) -
scheme
eitherhttp
orhttps
(depending on thesecure
result) -
metadata
of the service:[style="loweralpha"]
-
labels
(如果通过spring.cloud.kubernetes.discovery.metadata.add-labels=true
请求)。标签值可以“添加前缀”值为spring.cloud.kubernetes.discovery.metadata.labels-prefix
(如果已设置)。 -
labels
(if requested viaspring.cloud.kubernetes.discovery.metadata.add-labels=true
). Label keys can be "prefixed" with the value ofspring.cloud.kubernetes.discovery.metadata.labels-prefix
if it is set. -
annotations
(如果通过spring.cloud.kubernetes.discovery.metadata.add-annotations=true
请求)。注解值可以“添加前缀”值为spring.cloud.kubernetes.discovery.metadata.annotations-prefix
(如果已设置)。 -
annotations
(if requested viaspring.cloud.kubernetes.discovery.metadata.add-annotations=true
). Annotations keys can be "prefixed" with the value ofspring.cloud.kubernetes.discovery.metadata.annotations-prefix
if it is set. -
ports
(如果通过spring.cloud.kubernetes.discovery.metadata.add-ports=true
请求)。端口值可以“添加前缀”值为spring.cloud.kubernetes.discovery.metadata.ports-prefix
(如果已设置)。 -
ports
(if requested viaspring.cloud.kubernetes.discovery.metadata.add-ports=true
). Port keys can be "prefixed" with the value ofspring.cloud.kubernetes.discovery.metadata.ports-prefix
if it is set. -
k8s_namespace
为实例所在命名空间的值。 -
k8s_namespace
with the value of the namespace where instance resides. -
type
其中包含服务类型,例如ClusterIP
或ExternalName
-
type
that holds the service type, for exampleClusterIP
orExternalName
-
secure
如果发现的端口应视为安全。我们将使用上面概述的规则查找端口名称和号码,然后:[style="loweralpha"]
-
如果此服务已标记为
secured
,并且它具有以下任一值:["true", "on", "yes", "1"]
,则将找到的端口视为安全端口。 -
If this service has a label called
secured
with any of the values :["true", "on", "yes", "1"]
, then treat the port that was found as secure. -
如果找不到此类标签,请搜索名为
secured
的注释,并应用相同的上述规则。 -
If such a label is not found, search for an annotation called
secured
and apply the same above rules. -
如果此端口号属于
spring.cloud.kubernetes.discovery.known-secure-ports
(默认情况下,此值包含[443, 8443]
),则将端口号视为已保护。 -
If this port number is part of
spring.cloud.kubernetes.discovery.known-secure-ports
(by default this value holds[443, 8443]
), treat port number as secured. -
最后的手段是查看端口名称是否与
https
匹配;如果是则将此端口视为安全。 -
Last resort is to see if port name matches
https
; if it does treat this port as secured.
-
secure
if the port that was discovered should be treated as secure. We will use the same rules outlined above to find the port name and number, and then:[style="loweralpha"]
-
如果此服务已标记为
secured
,并且它具有以下任一值:["true", "on", "yes", "1"]
,则将找到的端口视为安全端口。 -
If this service has a label called
secured
with any of the values :["true", "on", "yes", "1"]
, then treat the port that was found as secure. -
如果找不到此类标签,请搜索名为
secured
的注释,并应用相同的上述规则。 -
If such a label is not found, search for an annotation called
secured
and apply the same above rules. -
如果此端口号属于
spring.cloud.kubernetes.discovery.known-secure-ports
(默认情况下,此值包含[443, 8443]
),则将端口号视为已保护。 -
If this port number is part of
spring.cloud.kubernetes.discovery.known-secure-ports
(by default this value holds[443, 8443]
), treat port number as secured. -
最后的手段是查看端口名称是否与
https
匹配;如果是则将此端口视为安全。 -
Last resort is to see if port name matches
https
; if it does treat this port as secured.
-
namespace
- 找到的实例的命名空间。 -
namespace
- the namespace of the found instance. -
pod-metadata
服务实例(pod)的标签和注释,格式为Map<String, Map<String, String>>
。此支持需要通过spring.cloud.kubernetes.discovery.metadata.add-pod-labels=true
和/或spring.cloud.kubernetes.discovery.metadata.add-pod-annotaations=true
启动 -
pod-metadata
labels and annotations of the service instance (pod), in the form ofMap<String, Map<String, String>>
. This support needs to be enabled viaspring.cloud.kubernetes.discovery.metadata.add-pod-labels=true
and/orspring.cloud.kubernetes.discovery.metadata.add-pod-annotaations=true
为了发现未被 kubernetes api 服务器标记为“已就绪”的服务端点地址,您可以在 application.properties
中设置以下属性(默认值:false):
To discover service endpoint addresses that are not marked as "ready" by the kubernetes api server, you can set the following property in application.properties
(default: false):
spring.cloud.kubernetes.discovery.include-not-ready-addresses=true
在出于监控目的发现服务并且将允许检查尚未就绪的服务实例的 /health
终结点时,这可能很有用。如果您希望获取 ServiceInstance
列表以便还包括 ExternalName
类型服务,则需要通过 spring.cloud.kubernetes.discovery.include-external-name-services=true
启用该支持。如此一来,当调用 DiscoveryClient::getInstances
时,这些内容也将返回。可以通过检查 ServiceInstance::getMetadata
并查找名为 type
的字段来区分 ExternalName
和任何其他类型。这将是返回的服务类型:ExternalName
/ClusterIP
等。如果您出于任何原因需要禁用 DiscoveryClient
,则可以在 application.properties
中设置以下属性:
This might be useful when discovering services for monitoring purposes, and would enable inspecting the /health
endpoint of not-ready service instances.
If you want to get the list of ServiceInstance
to also include the ExternalName
type services, you need to enable that support via: spring.cloud.kubernetes.discovery.include-external-name-services=true
. As such, when calling DiscoveryClient::getInstances
those will be returned also. You can distinguish between ExternalName
and any other types by inspecting ServiceInstance::getMetadata
and lookup for a field called type
. This will be the type of the service returned : ExternalName
/ClusterIP
, etc.
If, for any reason, you need to disable the DiscoveryClient
, you can set the following property in application.properties
:
spring.main.cloud-platform=NONE
请注意,发现客户端的支持是自动的,取决于您在何处运行应用程序。因此,可能不需要上述设置。
Note that the support of discovery client is automatic, depending on where you run the application. So the above setting might not be needed.
某些 Spring Cloud 组件使用 DiscoveryClient
来获取有关本地服务实例的信息。要做到这一点,您需要将 Kubernetes 服务名称与 spring.application.name
属性对齐。
Some Spring Cloud components use the DiscoveryClient
in order to obtain information about the local service instance. For
this to work, you need to align the Kubernetes service name with the spring.application.name
property.
|
|
Spring Cloud Kubernetes 还可以监视 Kubernetes 服务目录的更改,并相应地更新 DiscoveryClient
实现。为了启用此功能,您需要在应用程序中的配置类中添加 @EnableScheduling
。通过“监视”,我们指的是我们将每 spring.cloud.kubernetes.discovery.catalog-services-watch-delay
毫秒发布一个心跳事件(默认值为 30000
)。对于 http 发现服务器,这必须是 deployment yaml 中设置的环境变量:
Spring Cloud Kubernetes can also watch the Kubernetes service catalog for changes and update the DiscoveryClient
implementation accordingly. In order to enable this functionality you need to add
@EnableScheduling
on a configuration class in your application. By "watch", we mean that we will publish a heartbeat event every spring.cloud.kubernetes.discovery.catalog-services-watch-delay
milliseconds (by default it is 30000
). For the http discovery server this must be an environment variable set in deployment yaml:
containers: - name: discovery-server image: springcloud/spring-cloud-kubernetes-discoveryserver:3.0.5-SNAPSHOT env: - name: SPRING_CLOUD_KUBERNETES_DISCOVERY_CATALOGSERVICESWATCHDELAY value: 3000
心跳事件将包含目标引用(及其地址的所有端点的命名空间)(有关所返回内容的具体详细信息,您可以在 KubernetesCatalogWatch
中查看)。这是一个实现细节,并且心跳事件的监听器不应依赖于这些细节。而应该通过 equals
方法查看两次连续心跳之间是否存在差异。我们将负责返回一个遵守相等契约的正确实现。将在以下任一位置查询端点:- all-namespaces
(通过 spring.cloud.kubernetes.discovery.all-namespaces=true
启用)
The heartbeat event will contain the target references (and their namespaces of the addresses of all endpoints
(for the exact details of what will get returned you can take a look inside KubernetesCatalogWatch
). This is an implementation detail, and listeners of the heartbeat event
should not rely on the details. Instead, they should see if there are differences between two subsequent heartbeats via equals
method. We will take care to return a correct implementation that adheres to the equals contract.
The endpoints will be queried in either :
- all-namespaces
(enabled via spring.cloud.kubernetes.discovery.all-namespaces=true
)
-
selective namespaces
(通过spring.cloud.kubernetes.discovery.namespaces
启用),例如: -
selective namespaces
(enabled viaspring.cloud.kubernetes.discovery.namespaces
), for example: -
如果未采用上述两个路径,则通过 Namespace Resolution 对
one namespace
进行保护。 -
one namespace
via Namespace Resolution if the above two paths are not taken.
出于任何原因,如果你想禁用目录监视器,你需要设置`spring.cloud.kubernetes.discovery.catalog-services-watch.enabled=false`。对于 http 发现服务器来说,需要在部署中设置环境变量,例如: |
If, for any reasons, you want to disable catalog watcher, you need to set |
SPRING_CLOUD_KUBERNETES_DISCOVERY_CATALOGSERVICESWATCH_ENABLED=FALSE
目录监视的功能适用于我们支持的所有 3 个发现客户端,但在 http 客户端的情况下,您需要了解一些注意事项。
The functionality of catalog watch works for all 3 discovery clients that we support, with some caveats that you need to be aware of in case of the http client.
-
首先是此功能默认禁用,需要在两个位置启用:
-
在发现服务器中,在部署清单的环境变量中,例如:---- containers:
-
-
name: discovery-server image: springcloud/spring-cloud-kubernetes-discoveryserver:3.0.5-SNAPSHOT env:
-
name: SPRING_CLOUD_KUBERNETES_HTTP_DISCOVERY_CATALOG_WATCHER_ENABLED value: "TRUE"
[.iokays-original-8b038c562bb9b51064db4e3fbd90849f] * in discovery server via an environment variable in the deployment manifest, for example:---- containers: - name: discovery-server image: springcloud/spring-cloud-kubernetes-discoveryserver:3.0.5-SNAPSHOT env: - name: SPRING_CLOUD_KUBERNETES_HTTP_DISCOVERY_CATALOG_WATCHER_ENABLED value: "TRUE"
-
在发现客户端中,在
application.properties
的属性中,例如:---- spring.cloud.kubernetes.http.discovery.catalog.watcher.enabled=true
[.iokays-original-956a39fa12f3b6cdd1841aba9a32fdcb] * in discovery client, via a property in your `application.properties` for example:---- spring.cloud.kubernetes.http.discovery.catalog.watcher.enabled=true
-
The first is that this functionality is disabled by default, and it needs to be enabled in two places:
-
在发现服务器中,在部署清单的环境变量中,例如:---- containers:
-
-
name: discovery-server image: springcloud/spring-cloud-kubernetes-discoveryserver:3.0.5-SNAPSHOT env:
-
name: SPRING_CLOUD_KUBERNETES_HTTP_DISCOVERY_CATALOG_WATCHER_ENABLED value: "TRUE"
[.iokays-original-8b038c562bb9b51064db4e3fbd90849f] * in discovery server via an environment variable in the deployment manifest, for example:---- containers: - name: discovery-server image: springcloud/spring-cloud-kubernetes-discoveryserver:3.0.5-SNAPSHOT env: - name: SPRING_CLOUD_KUBERNETES_HTTP_DISCOVERY_CATALOG_WATCHER_ENABLED value: "TRUE"
-
在发现客户端中,在
application.properties
的属性中,例如:---- spring.cloud.kubernetes.http.discovery.catalog.watcher.enabled=true
[.iokays-original-956a39fa12f3b6cdd1841aba9a32fdcb] * in discovery client, via a property in your `application.properties` for example:---- spring.cloud.kubernetes.http.discovery.catalog.watcher.enabled=true
-
第二点是,这仅从版本
3.0.6
开始支持。 -
The second point is that this is only supported since version
3.0.6
and upwards. -
由于 http 发现有 two 组件:服务器和客户端,我们强烈建议在两者之间对齐版本,否则可能无法正常工作。
-
Since http discovery has two components : server and client, we strongly recommend to align versions between them, otherwise things might not work.
-
如果您决定禁用目录观察程序,则需要在服务器和客户端禁用。
-
If you decide to disable catalog watcher, you need to disable it in both server and client.
我们默认使用 Endpoints
(参见 [role="bare"][role="bare"]https://kubernetes.io/docs/concepts/services-networking/service/#endpoints)API 来了解服务的当前状态。还有另一种方式,即通过 EndpointSlices
([role="bare"][role="bare"]https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/)。可以通过一个属性(默认值为 false
)启用此支持: spring.cloud.kubernetes.discovery.use-endpoint-slices=true
。当然,您的集群也必须支持它。事实上,如果您启用了此属性,但集群不支持,我们将无法启动应用程序。如果您决定启用此支持,还需要设置适当的角色/集群角色。例如:
By default, we use the Endpoints
(see [role="bare"]https://kubernetes.io/docs/concepts/services-networking/service/#endpoints) API to find out the current state of services. There is another way though, via EndpointSlices
([role="bare"]https://kubernetes.io/docs/concepts/services-networking/endpoint-slices/). Such support can be enabled via a property: spring.cloud.kubernetes.discovery.use-endpoint-slices=true
(by default it is false
). Of course, your cluster has to support it also. As a matter of fact, if you enable this property, but your cluster does not support it, we will fail starting the application. If you decide to enable such support, you also need proper Role/ClusterRole set-up. For example:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: namespace-reader
rules:
- apiGroups: ["discovery.k8s.io"]
resources: ["endpointslices"]
verbs: ["get", "list", "watch"]