Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: enable issue of endpointslices for k8s discovery #11654

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/kubernetes-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ jobs:

kubectl apply -f ./t/kubernetes/configs/endpoint.yaml

kubectl apply -f ./t/kubernetes/configs/endpointslices.yaml

KUBERNETES_CLIENT_TOKEN_CONTENT=$(kubectl get secrets | grep apisix-test | awk '{system("kubectl get secret -o jsonpath={.data.token} "$1" | base64 --decode")}')

KUBERNETES_CLIENT_TOKEN_DIR="/tmp/var/run/secrets/kubernetes.io/serviceaccount"
Expand Down
59 changes: 31 additions & 28 deletions apisix/discovery/kubernetes/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ local core = require("apisix.core")
local util = require("apisix.cli.util")
local local_conf = require("apisix.core.config_local").local_conf()
local informer_factory = require("apisix.discovery.kubernetes.informer_factory")
local cjson = require("cjson")


local ctx
Expand Down Expand Up @@ -60,32 +61,34 @@ local function on_endpoint_slices_modified(handle, endpoint)
core.table.clear(endpoint_buffer)

local endpointslices = endpoint.endpoints
for _, endpointslice in ipairs(endpointslices or {}) do
if endpointslice.addresses then
local addresses = endpointslices.addresses
for _, port in ipairs(endpoint.ports or {}) do
local port_name
if port.name then
port_name = port.name
elseif port.targetPort then
port_name = tostring(port.targetPort)
else
port_name = tostring(port.port)
end

if endpointslice.conditions and endpointslice.condition.ready then
local nodes = endpoint_buffer[port_name]
if nodes == nil then
nodes = core.table.new(0, #endpointslices * #addresses)
endpoint_buffer[port_name] = nodes
if type(endpointslices) == "table" then
for _, endpointslice in ipairs(endpointslices) do
if endpointslice.addresses then
local addresses = endpointslice.addresses
for _, port in ipairs(endpoint.ports or {}) do
local port_name
if port.name then
port_name = port.name
elseif port.targetPort then
port_name = tostring(port.targetPort)
else
port_name = tostring(port.port)
end

for _, address in ipairs(endpointslices.addresses) do
core.table.insert(nodes, {
host = address.ip,
port = port.port,
weight = handle.default_weight
})
if endpointslice.conditions and endpointslice.conditions.ready then
local nodes = endpoint_buffer[port_name]
if nodes == nil then
nodes = core.table.new(0, #endpointslices * #addresses)
endpoint_buffer[port_name] = nodes
end

for _, address in ipairs(addresses) do
core.table.insert(nodes, {
host = address.ip,
port = port.port,
weight = handle.default_weight
})
end
end
end
end
Expand Down Expand Up @@ -431,7 +434,7 @@ local function single_mode_init(conf)

local default_weight = conf.default_weight
local endpoints_informer, err
if conf.watch_endpoint_slices_schema then
if conf.watch_endpoint_slices then
endpoints_informer, err = informer_factory.new("discovery.k8s.io", "v1",
"EndpointSlice", "endpointslices", "")
else
Expand All @@ -445,7 +448,7 @@ local function single_mode_init(conf)
setup_namespace_selector(conf, endpoints_informer)
setup_label_selector(conf, endpoints_informer)

if conf.watch_endpoint_slices_schema then
if conf.watch_endpoint_slices then
endpoints_informer.on_added = on_endpoint_slices_modified
endpoints_informer.on_modified = on_endpoint_slices_modified
else
Expand Down Expand Up @@ -537,7 +540,7 @@ local function multiple_mode_init(confs)
local default_weight = conf.default_weight

local endpoints_informer, err
if conf.watch_endpoint_slices_schema then
if conf.watch_endpoint_slices then
endpoints_informer, err = informer_factory.new("discovery.k8s.io", "v1",
"EndpointSlice", "endpointslices", "")
else
Expand All @@ -551,7 +554,7 @@ local function multiple_mode_init(confs)
setup_namespace_selector(conf, endpoints_informer)
setup_label_selector(conf, endpoints_informer)

if conf.watch_endpoint_slices_schema then
if conf.watch_endpoint_slices then
endpoints_informer.on_added = on_endpoint_slices_modified
endpoints_informer.on_modified = on_endpoint_slices_modified
else
Expand Down
13 changes: 8 additions & 5 deletions docs/en/latest/discovery/kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ A: The Kubernetes service discovery only uses privileged processes to [_List-Wat

**Q: What permissions do [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) require?**

A: ServiceAccount requires the permissions of cluster-level [ get, list, watch ] endpoints resources, the declarative definition is as follows:
A: ServiceAccount requires the permissions of cluster-level [ get, list, watch ] endpoints and endpointslices resources, the declarative definition is as follows:

```yaml
kind: ServiceAccount
Expand All @@ -315,11 +315,14 @@ metadata:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: apisix-test
name: apisix-test
rules:
- apiGroups: [ "" ]
resources: [ endpoints,endpointslices ]
verbs: [ get,list,watch ]
- apiGroups: [ "" ]
resources: [ endpoints]
verbs: [ get,list,watch ]
- apiGroups: [ "discovery.k8s.io" ]
resources: [ endpointslices ]
verbs: [ get,list,watch ]
---

apiVersion: rbac.authorization.k8s.io/v1
Expand Down
13 changes: 8 additions & 5 deletions docs/zh/latest/discovery/kubernetes.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ A: Kubernetes 服务发现只使用特权进程监听 Kubernetes Endpoints,然

**Q: [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 需要的权限有哪些?**

A: [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 需要集群级 [ get,list,watch ] endpoints 资源的的权限,其声明式定义如下:
A: [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 需要集群级 [ get,list,watch ] endpoints and endpointslices 资源的的权限,其声明式定义如下:

```yaml
kind: ServiceAccount
Expand All @@ -313,11 +313,14 @@ metadata:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: apisix-test
name: apisix-test
rules:
- apiGroups: [ "" ]
resources: [ endpoints,endpointslices ]
verbs: [ get,list,watch ]
- apiGroups: [ "" ]
resources: [ endpoints]
verbs: [ get,list,watch ]
- apiGroups: [ "discovery.k8s.io" ]
resources: [ endpointslices ]
verbs: [ get,list,watch ]
---

apiVersion: rbac.authorization.k8s.io/v1
Expand Down
5 changes: 4 additions & 1 deletion t/kubernetes/configs/account.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ metadata:
name: apisix-test
rules:
- apiGroups: [ "" ]
resources: [ endpoints ]
resources: [ endpoints]
verbs: [ get,list,watch ]
- apiGroups: [ "discovery.k8s.io" ]
resources: [ endpointslices ]
verbs: [ get,list,watch ]
---
apiVersion: rbac.authorization.k8s.io/v1
Expand Down
61 changes: 61 additions & 0 deletions t/kubernetes/configs/endpointslices.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file excepslicet in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

kind: Namespace
apiVersion: v1
metadata:
name: ns-a
---

kind: EndpointSlice
apiVersion: discovery.k8s.io/v1
metadata:
name: epslice
namespace: ns-a
addressType: IPv4
endpoints: [ ]
---

kind: Namespace
apiVersion: v1
metadata:
name: ns-b
---

kind: EndpointSlice
apiVersion: discovery.k8s.io/v1
metadata:
name: epslice
namespace: ns-b
addressType: IPv4
endpoints: [ ]
---

kind: Namespace
apiVersion: v1
metadata:
name: ns-c
---

kind: EndpointSlice
apiVersion: discovery.k8s.io/v1
metadata:
name: epslice
namespace: ns-c
addressType: IPv4
endpoints: [ ]
---
Loading
Loading