Kubernetes API Aggregated 是什麼

一、什麼是 Aggregated API Server

1.1、概述

Aggregated(聚合的)API server 是爲了將原來的 API server 這個巨石(monolithic)應用給拆分開,爲了方便用戶開發自己的 API server 集成進來,而不用直接修改 Kubernetes 官方倉庫的代碼,這樣一來也能將 API server 解耦,方便用戶使用實驗特性。這些 API server 可以跟 core API server 無縫銜接,使用 kubectl 也可以管理它們。

1.7+ 版本中,聚合層和 kube-apiserver 一起運行。在擴展資源被註冊前,聚合層不執行任何操,要註冊其 API,用戶必需添加一個 APIService 對象,該對象需在 Kubernetes API 中聲明 URL 路徑,聚合層將發送到該 API 路徑(e.g. /apis/myextension.mycompany.io/v1/…)的所有對象代理到註冊的 APIService。

通常,通過在集羣中的一個 Pod 中運行一個 extension-apiserver 來實現 APIService。如果已添加的資源需要主動管理,這個 extension-apiserver 通常需要和一個或多個控制器配對。

1.2、設計理念

  • api的擴展性:這樣k8s的開發人員就可以編寫自己的API服務器來公開他們想要的API。集羣管理員應該能夠使用這些服務,而不需要對核心庫存儲庫進行任何更改。
  • 豐富了APIs:核心kubernetes團隊阻止了很多新的API提案。通過允許開發人員將他們的API作爲單獨的服務器公開,並使集羣管理員能夠在不對核心庫存儲庫進行任何更改的情況下使用它們,這樣就無須社區繁雜的審查了
  • 開發分階段實驗性API的地方:新的API可以在單獨的聚集服務器中開發,當它穩定之後,那麼把它們封裝起來安裝到其他集羣就很容易了。
  • 確保新API遵循kubernetes約定:如果沒有這裏提出的機制,社區成員可能會被迫推出自己的東西,這可能會或可能不遵循kubernetes約定。

Aggregator for Kubernetes-style API servers: dynamic registration, discovery summarization, secure proxy

二、認證流程

2.1、工作方式

與自定義資源定義(CRD)不同,除標準的 Kubernetes apiserver 外,Aggregation API 還涉及另一個服務器:Extension apiserver。Kubernetes apiserver 將需要與您的 Extension apiserver 通信,並且您的 Extension apiserver 也需要與 Kubernetes apiserver 通信。爲了確保此通信的安全,Kubernetes apiserver 使用 x509 證書向 Extension apiserver 認證。

  1. Kubernetes apiserver:對發出請求的用戶身份認證,並對請求的 API 路徑執行鑑權
  2. Kubernetes apiserver (aggregator):將請求轉發到 Extension apiserver (aggregated apiserver)
  3. Extension apiserver:認證來自 Kubernetes apiserver 的請求
  4. Extension apiserver:對來自原始用戶的請求鑑權
  5. Extension apiserver:執行

image-20200225102139429

2.2、Kubernetes Apiserver 認證和授權

假設我們已經在 Kubernetes apiserver 註冊了 Extension apiserver。

當用戶請求訪問 path ,Kubernetes apiserver 使用它的標準認證和授權配置來對用戶認證,以及對特定 path 的鑑權,到目前爲止,所有內容都是標準的 Kubernetes API 請求,認證與鑑權,接下來 Kubernetes apiserver 現在準備將請求發送到 Extension apiserver。

2.3、Kubernetes Apiserver 代理請求

Kubernetes apiserver 現在將請求發送或代理到註冊以處理該請求的 Extension apiserver。爲此,它需要了解幾件事:

  1. Kubernetes apiserver 應該如何向 Extension apiserver 認證,以通知 Extension apiserver 通過網絡發出的請求來自有效的 Kubernetes apiserver?
  2. Kubernetes apiserver 應該如何通知 Extension apiserver 原始請求已通過認證的用戶名和組?

簡而言之,就是 Kubernetes apiserver 已經認證和鑑權用戶的請求,怎麼這這些信息傳遞給 Extension apiserver,爲提供這兩條信息,我們必須使用若干標誌來配置 Kubernetes apiserver。

2.3.1、Kubernetes Apiserver 客戶端認證

Kubernetes apiserver 通過 TLS 連接到 Extension apiserver,並使用客戶端證書認證,這裏 Kubernetes apiserver (aggregator or proxy) 是 Extension apiserver 的客戶端。必須在啓動時使用提供的標誌向 Kubernetes apiserver 提供以下內容:

  • 通過 --proxy-client-key-file 指定私鑰文件
  • 通過 --proxy-client-cert-file 簽名的客戶端證書文件
  • 通過 --requestheader-client-ca-file 簽署客戶端證書文件的 CA 證書
  • 通過 --requestheader-allowed-names 在簽署的客戶證書中有效的公用名(CN)

Kubernetes apiserver 將使用由 –proxy-client-*-file 指示的文件來通過 Extension apiserver 驗證。爲了使合規的 Extension apiserver 能夠將該請求視爲有效,必須滿足以下條件:

  1. 連接必須使用由 CA 簽署的客戶端證書,該證書的證書位於 --requestheader-client-ca-file 中。
  2. 連接必須使用客戶端證書,該客戶端證書的 CN 是 --requestheader-allowed-names 中列出的證書之一。 注意:您可以將此選項設置爲空白,即爲--requestheader-allowed-names=""。這將向擴展 apiserver 指示任何 CN 是可接受的。

使用這些選項啓動時,Kubernetes apiserver 將:

  1. 使用它們來通過 Extension apiserver 的認證。
  2. 在名爲 kube-system 命名空間中創建一個 configmap extension-apiserver-authentication ,它將在其中放置 CA 證書和允許的 CN。反過來,Extension apiserver 可以檢索這些內容以驗證請求。

2.3.2、原始請求用戶名和組

當 Kubernetes apiserver 將請求代理到 Extension apiserver 時,它將向 Extension apiserver 通知原始請求已成功通過其驗證的用戶名和組。它在其代理請求的 http 標頭中提供這些。您必須將要使用的標頭名稱告知 Kubernetes apiserver。

  • 通過--requestheader-username-headers 標明用來保存用戶名的頭部
  • 通過--requestheader-group-headers 標明用來保存 group 的頭部
  • 通過--requestheader-extra-headers-prefix 標明用來保存拓展信息前綴的頭部

這些標頭名稱也放置在extension-apiserver-authentication 的 configmap 中,因此 Extension apiserver 可以檢索和使用它們。

2.4、Extension apiserver 認證

Extension apiserver 在收到來自 Kubernetes apiserver 的代理請求後,必須驗證該請求確實確實來自有效的身份驗證代理,該認證代理由 Kubernetes apiserver 履行。Extension apiserver 通過以下方式對其認證:

  1. 如上所述,從kube-system中的 configmap 中檢索以下內容:
  • 客戶端 CA 證書 --requestheader-client-ca-file
  • 允許名稱(CN)列表 --requestheader-allowed-names
  • 用戶名,組和其他信息的頭部。
  1. 使用以下證書檢查 TLS 連接是否已通過認證:
  • 由其證書與檢索到的 CA 證書匹配的 CA 簽名。
  • 在允許的 CN 列表中有一個 CN,除非列表爲空,在這種情況下允許所有 CN。
  • 從適當的頭部中提取用戶名和組。

如果以上均通過,則該請求是來自合法認證代理(在本例中爲 Kubernetes apiserver)的有效代理請求。

爲了具有檢索 configmap 的權限,Extension apiserver 需要適當的角色。在 kube-system 名字空間中有一個默認角色extension-apiserver-authentication-reader 可用於設置。

2.5、Extension apiserver 對請求鑑權

Extension apiserver 現在可以驗證從標頭檢索的user/group是否有權執行給定請求。通過向 Kubernetes apiserver 發送標準 SubjectAcce***eview 請求來實現。

SubjectAcce***eviewauthorization.k8s.io API 組的一部分資源,它將 API 服務器授權公開給外部服務。該 API 組中的其他資源可以通過如下命令查看:

kubectl get --raw /apis/authorization.k8s.io/v1/

爲了使 Extension apiserver 本身被鑑權可以向 Kubernetes apiserver 提交 SubjectAcce***eview 請求,它需要正確的權限。Kubernetes 包含一個具有相應權限的名爲system:auth-delegator 的默認 ClusterRole,可以將其授予 Extension apiserver 的服務帳戶。

2.6、Extension apiserver 執行

如果SubjectAcce***eview通過,則擴展 apiserver 執行請求。

三、部署過程

3.1、安裝 cfssl

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/local/bin/cfssl-certinfo
cd /usr/local/bin/
chmod +x cfssl cfssljson cfssl-certinfo

3.2、創建 CA

3.2.3、CA 配置文件

$ cat > aggregator-ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "aggregator": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF
  • profiles : 可以定義多個 profiles,分別指定不同的過期時間、使用場景等參數;後續在簽名證書時使用某個 profile。
  • signing :表示該證書可用於簽名其它證書;生成的 aggregator-ca.pem 證書中 CA=TRUE
  • server auth :表示 Client 可以用該 CA 對 Server 提供的證書進行驗證。
  • client auth :表示 Server 可以用該 CA 對 Client 提供的證書進行驗證。

3.2.3、創建 CA 證書籤名請求

$ cat > aggregator-ca-csr.json <<EOF
{
  "CN": "aggregator",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Shanghai",
      "L": "Shanghai",
      "O": "k8s",
      "OU": "wzlinux"
    }
  ],
    "ca": {
       "expiry": "87600h"
    }
}
  • “CN”Common Name,kube-apiserver 從證書中提取該字段作爲請求的用戶名 (User Name);瀏覽器使用該字段驗證網站是否合法。
  • “O”Organization,kube-apiserver 從證書中提取該字段作爲請求用戶所屬的組 (Group);

3.2.4、生成 CA 證書和私鑰

cfssl gencert -initca aggregator-ca-csr.json | cfssljson -bare aggregator-ca

3.3、創建 kubernetes 證書

3.3.1、創建 aggregator 證書籤名請求

$ cat > aggregator-csr.json <<EOF
{
    "CN": "aggregator",
    "hosts": [
      "127.0.0.1",
      "172.18.0.101",
      "172.18.0.102",
      "172.18.0.103",
      "10.96.0.1",
      "kubernetes",
      "kubernetes.default",
      "kubernetes.default.svc",
      "kubernetes.default.svc.cluster",
      "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "Shanghai",
            "L": "Shanghai",
            "O": "k8s",
            "OU": "wzlinux"
        }
    ]
}

如果 hosts 字段不爲空則需要指定授權使用該證書的 IP 或域名列表,由於該證書後續kubernetes master 集羣使用,所以上面指定kubernetes master 集羣的主機 IP 和 kubernetes 服務的服務 IP(一般是 kube-apiserver 指定的 service-cluster-ip-range 網段的第一個 IP,如 10.96.0.1)。

3.3.2、生成 aggreagtor 證書和私鑰

cfssl gencert -ca=aggregator-ca.pem -ca-key=aggregator-ca-key.pem -config=aggregator-ca-config.json -profile=aggregator aggregator-csr.json | cfssljson -bare aggregator

3.3.3、分發證書

將生成的證書和祕鑰文件(後綴名爲.pem)拷貝到 Master 節點的 /etc/kubernetes/pki 目錄下備用。

3.4、開啓聚合層 API

kube-apiserver 增加以下配置:

--requestheader-client-ca-file=/etc/kubernetes/pki/aggregator-ca.pem
--requestheader-allowed-names=aggregator
--requestheader-extra-headers-prefix=X-Remote-Extra-
--requestheader-group-headers=X-Remote-Group
--requestheader-username-headers=X-Remote-User
--proxy-client-cert-file=/etc/kubernetes/pki/aggregator.pem
--proxy-client-key-file=/etc/kubernetes/pki/aggregator-key.pem

前面創建的證書的 CN 字段的值必須和參數 –requestheader-allowed-names 指定的值 aggregator 相同。

重啓 kube-apiserver:

$ systemctl daemon-reload
$ systemctl restart kube-apiserver

如果 kube-proxy 沒有在 Master 上面運行,kube-proxy 還需要添加配置:

--enable-aggregator-routing=true

參考

歡迎大家掃碼關注,獲取更多信息

Kubernetes API Aggregated 是什麼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章