apisix的k8s服務發現配置
名稱空間許可權是基於Kubernetes RBAC能力的授權,透過許可權設定可以讓不同的使用者或使用者組擁有操作不同Kubernetes資源的許可權。Kubernetes RBAC API定義了四種型別:Role、ClusterRole、RoleBinding與ClusterRoleBinding,這四種型別之間的關係和簡要說明如下:
- Role:角色,其實是定義一組對Kubernetes資源(名稱空間級別)的訪問規則。
- RoleBinding:角色繫結,定義了使用者和角色的關係。
- ClusterRole:叢集角色,其實是定義一組對Kubernetes資源(叢集級別,包含全部名稱空間)的訪問規則。
- ClusterRoleBinding:叢集角色繫結,定義了使用者和叢集角色的關係。
Role和ClusterRole指定了可以對哪些資源做哪些動作,RoleBinding和ClusterRoleBinding將角色繫結到特定的使用者、使用者組或ServiceAccount上。如下圖所示。
實踐部分
1 為了讓 APISIX 能查詢和監聽 Kubernetes 的 Endpoints 資源變動,我們需要建立一個 ServiceAccount:
kind: ServiceAccount
apiVersion: v1
metadata:
name: apisix-test
namespace: default
2 以及一個具有叢集級查詢和監聽 Endpoints 資源許可權的 ClusterRole:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: apisix-test
rules:
- apiGroups: [ "" ]
resources: [ endpoints ]
verbs: [ get,list,watch ]
3 再將這個 ServiceAccount 和 ClusterRole 關聯起來:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: apisix-test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: apisix-test
subjects:
- kind: ServiceAccount
name: apisix-test
namespace: default
4 然後我們需要獲取這個 ServiceAccount 的 token 值,如果 Kubernetes 是 v1.24 之前的版本,可以透過下面的方法獲取 token 值:
$ kubectl get secrets | grep apisix-test
$ kubectl get secret apisix-test-token-879xv -o jsonpath={.data.token} | base64 -d
5 Kubernetes 從 v1.24 版本開始,不能再透過 kubectl get secret 獲取 token 了,需要使用 TokenRequest API 來獲取,首先開啟代理:
$ kubectl proxy --port=8001
Starting to serve on 127.0.0.1:8001
6 然後呼叫 TokenRequest API 生成一個 token:
$ curl 'http://127.0.0.1:8001/api/v1/namespaces/default/serviceaccounts/apisix-test/token' \
-H "Content-Type:application/json" -X POST -d '{}'
{
"kind": "TokenRequest",
"apiVersion": "authentication.k8s.io/v1",
...
"status": {
"token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImtLdHRyVzFmNTRHWGFVUjVRS3hrLVJMSElNaXM4aENLMnpfSGk1SUJhbVkifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjc5NTMzMDQwLCJpYXQiOjE2Nzk1Mjk0NDAsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0Iiwic2VydmljZWFjY291bnQiOnsibmFtZSI6ImFwaXNpeC10ZXN0IiwidWlkIjoiMzVjZWJkYTEtNGZjNC00N2JlLWIxN2QtZDA4NWJlNzU5ODRlIn19LCJuYmYiOjE2Nzk1Mjk0NDAsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmFwaXNpeC10ZXN0In0.YexM_VoumpdwZNbSkwh6IbEu59PCtZrG1lkTnCqG24G-TC0U1sGxgbXf6AnUQ5ybh-CHWbJ7oewhkg_J4j7FiSAnV_yCcEygLkaCveGIQbWldB3phDlcJ52f8YDpHFtN2vdyVTm79ECwEInDsqKhn4n9tPY4pgTodI6D9j-lcK0ywUdbdlL5VHiOw9jlnS7b60fKWBwCPyW2uohX5X43gnUr3E1Wekgpo47vx8lahTZQqnORahTdl7bsPsu_apf7LMw40FLpspVO6wih-30Ke8CNBxjpORtX2n3oteE1fi2vxYHoyJSeh1Pro_Oykauch0InFUNyEVI4kJQ720glOw",
"expirationTimestamp": "2023-03-23T00:57:20Z"
}
}
7 預設的 token 有效期只有一個小時,可以透過引數改為一年:
$ curl 'http://127.0.0.1:8001/api/v1/namespaces/default/serviceaccounts/apisix-test/token' \
-H "Content-Type:application/json" -X POST \
-d '{"kind":"TokenRequest","apiVersion":"authentication.k8s.io/v1","metadata":{"name":"apisix-test","namespace":"default"},"spec":{"audiences":["https://kubernetes.default.svc.cluster.local"],"expirationSeconds":31536000}}'
8 我們在 APISIX 的配置檔案 config.yaml 中新增如下內容( 將上面生成的 token 填寫到 token 欄位 ):
discovery:
kubernetes:
service:
schema: https
host: 127.0.0.1
port: "6443"
client:
token: ...
這裡有一個比較坑的地方,port 必須是字串,否則會導致 APISIX 啟動報錯
invalid discovery kubernetes configuration: object matches none of the required
大功告成!
參考:https://www.aneasystone.com/archives/2023/03/apisix-service-discovery.html