From 33ff8e247f423cf03a6c93377a5a910f22cda4ff Mon Sep 17 00:00:00 2001 From: elijah Date: Fri, 27 Jan 2023 15:21:55 +0800 Subject: [PATCH 1/2] docs: add document for k8s mtls --- docs/zh/latest/discovery/kubernetes.md | 92 +++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 10 deletions(-) diff --git a/docs/zh/latest/discovery/kubernetes.md b/docs/zh/latest/discovery/kubernetes.md index 17342882082a..1ee9bcb7fa32 100644 --- a/docs/zh/latest/discovery/kubernetes.md +++ b/docs/zh/latest/discovery/kubernetes.md @@ -278,16 +278,6 @@ nodes("release/default/plat-dev:port") 调用会得到如下的返回值: ## Q&A -**Q: 为什么只支持配置 token 来访问 Kubernetes APIServer?** - -A: 一般情况下,我们有三种方式可以完成与 Kubernetes APIServer 的认证: - -- mTLS -- Token -- Basic authentication - -因为 lua-resty-http 目前不支持 mTLS, Basic authentication 不被推荐使用,所以当前只实现了 Token 认证方式。 - **Q: APISIX 继承了 NGINX 的多进程模型,是否意味着每个 APISIX 工作进程都会监听 Kubernetes Endpoints?** A: Kubernetes 服务发现只使用特权进程监听 Kubernetes Endpoints,然后将其值存储到 `ngx.shared.DICT` 中,工作进程通过查询 `ngx.shared.DICT` 来获取结果。 @@ -343,3 +333,85 @@ A: 假定你指定的 [_ServiceAccount_](https://kubernetes.io/docs/tasks/config ```shell kubectl -n apisix get secret kubernetes-discovery-token-c64cv -o jsonpath={.data.token} | base64 -d ``` + +**Q: 如何为 [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 创建 TLS 证书进而使用 mTLS 认证?** + +A: 假定你使用以上的 [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 声明式定义来创建 `ServiceAccount`,请按如下步骤来创建 TLS 证书。 + +1. 创建 rsa 私钥: + +```shell +openssl genrsa -out k8s_mtls.key 4096 +``` + +2. 创建证书签名请求(CSR)对象发送到 Kubernetes API + +CSR 配置文件如下: + +``` +[req] +default_bits = 2048 +default_md = sha256 +distinguished_name = dn +prompt = no + +[dn] +CN = system:serviceaccount:default:apisix-test +O = system:serviceaccounts + +[v3_ext] +authorityKeyIdentifier = keyid,issuer:always +basicConstraints = CA:TRUE +keyUsage = keyEncipherment,dataEncipherment +extendedKeyUsage = clientAuth +``` + +创建 CSR: + +```shell +openssl req -new -key k8s_mtls.key -config k8s_mtls_csr.cnf -out k8s_mtls.csr -nodes +``` + +Kubernetes CSR 资源声明式定义如下: + +```yaml +apiVersion: certificates.k8s.io/v1 +kind: CertificateSigningRequest +metadata: + name: k8s-mtls-csr +spec: + groups: + - system:authenticated + request: ${BASE64_CSR} + signerName: kubernetes.io/kube-apiserver-client + usages: + - digital signature + - key encipherment + - client auth +``` + +获取 csr 文件内容并替换 `BASE64_CSR` 环境变量,创建 Kubernetes CSR 资源: +```shell +export BASE64_CSR=$(cat ./k8s_mtls.csr | base64 | tr -d '\n') +cat k8s_mtls_csr.yaml | envsubst | kubectl apply -f - +``` + +3. 手动批准证书签名请求(CSR): + +```shell +kubectl certificate approve k8s-mtls-csr +``` + +4. 下载颁发的证书并将其保存本地文件 `k8s_mtls.pem`: + +```shell +kubectl get csr k8s-mtls-csr -o jsonpath='{.status.certificate}' | base64 --decode > k8s_mtls.pem +``` + +5. 下载 CA 证书文件: + +```shell +kubectl get secrets | grep apisix-test | awk '{system("kubectl get secret -o jsonpath=\"{.data.ca\.crt}\" "$1" | base64 -d")}' > k8s_mtls_ca.pem +``` + +现在你可以使用证书文件 `k8s_mtls.pem`,证书私钥 `k8s_mtls.key` 及 CA 证书 `k8s_mtls_ca.pem` 文件进行 mTLS 认证,如果你想要进一步了解更多 TLS 证书详细内容,请参阅 [_Manage TLS Certificates in a Cluster_](https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/)。 From c486361aec657a087d843a56c325ebe0fa60151d Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 29 Jan 2023 11:45:18 +0800 Subject: [PATCH 2/2] docs: update document --- docs/zh/latest/discovery/kubernetes.md | 112 +++++++++++-------------- 1 file changed, 51 insertions(+), 61 deletions(-) diff --git a/docs/zh/latest/discovery/kubernetes.md b/docs/zh/latest/discovery/kubernetes.md index 1ee9bcb7fa32..48dc57b94b2f 100644 --- a/docs/zh/latest/discovery/kubernetes.md +++ b/docs/zh/latest/discovery/kubernetes.md @@ -334,84 +334,74 @@ A: 假定你指定的 [_ServiceAccount_](https://kubernetes.io/docs/tasks/config kubectl -n apisix get secret kubernetes-discovery-token-c64cv -o jsonpath={.data.token} | base64 -d ``` -**Q: 如何为 [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 创建 TLS 证书进而使用 mTLS 认证?** +**Q: 如何使用 mTLS 认证连接 Kubernetes?** -A: 假定你使用以上的 [_ServiceAccount_](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) 声明式定义来创建 `ServiceAccount`,请按如下步骤来创建 TLS 证书。 +A: 假定你在 Kubernetes 集群外启动 APISIX,请按如下步骤来获取 TLS 证书。 -1. 创建 rsa 私钥: +1. 从 Kubernetes 配置中取得证书、私钥及 CA 证书: -```shell -openssl genrsa -out k8s_mtls.key 4096 -``` - -2. 创建证书签名请求(CSR)对象发送到 Kubernetes API - -CSR 配置文件如下: - -``` -[req] -default_bits = 2048 -default_md = sha256 -distinguished_name = dn -prompt = no - -[dn] -CN = system:serviceaccount:default:apisix-test -O = system:serviceaccounts - -[v3_ext] -authorityKeyIdentifier = keyid,issuer:always -basicConstraints = CA:TRUE -keyUsage = keyEncipherment,dataEncipherment -extendedKeyUsage = clientAuth -``` - -创建 CSR: +获取客户端证书: ```shell -openssl req -new -key k8s_mtls.key -config k8s_mtls_csr.cnf -out k8s_mtls.csr -nodes +kubectl config view --raw -o 'jsonpath={.users[0].user.client-certificate-data}'| base64 -d > k8s_mtls.pem ``` -Kubernetes CSR 资源声明式定义如下: - -```yaml -apiVersion: certificates.k8s.io/v1 -kind: CertificateSigningRequest -metadata: - name: k8s-mtls-csr -spec: - groups: - - system:authenticated - request: ${BASE64_CSR} - signerName: kubernetes.io/kube-apiserver-client - usages: - - digital signature - - key encipherment - - client auth -``` +获取证书对应私钥: -获取 csr 文件内容并替换 `BASE64_CSR` 环境变量,创建 Kubernetes CSR 资源: ```shell -export BASE64_CSR=$(cat ./k8s_mtls.csr | base64 | tr -d '\n') -cat k8s_mtls_csr.yaml | envsubst | kubectl apply -f - +kubectl config view --raw -o 'jsonpath={.users[0].user.client-key-data}'| base64 -d > k8s_mtls.key ``` -3. 手动批准证书签名请求(CSR): +获取 CA 证书: ```shell -kubectl certificate approve k8s-mtls-csr +kubectl config view --raw -o 'jsonpath={.clusters[0].cluster.certificate-authority-data}'| base64 -d > k8s_mtls_ca.pem ``` -4. 下载颁发的证书并将其保存本地文件 `k8s_mtls.pem`: +2. 在 APISIX 服务发现配置中配置 mTLS 方式连接 Kubernetes 集群。 -```shell -kubectl get csr k8s-mtls-csr -o jsonpath='{.status.certificate}' | base64 --decode > k8s_mtls.pem +单集群模式: + +```yaml +ssl: + ssl_trusted_certificate: /var/certs/k8s_mtls_ca.pem + ssl_protocols: TLSv1.2 TLSv1.3 +discovery: + kubernetes: + service: + schema: "https" + host: "" + port: "" + client: + cert_file: /var/certs/k8s_mtls.pem + key_file: /var/certs/k8s_mtls.key + ssl_verify: true ``` -5. 下载 CA 证书文件: +多集群模式: -```shell -kubectl get secrets | grep apisix-test | awk '{system("kubectl get secret -o jsonpath=\"{.data.ca\.crt}\" "$1" | base64 -d")}' > k8s_mtls_ca.pem +```yaml +ssl: + ssl_trusted_certificate: /var/certs/k8s_mtls_ca.pem + ssl_protocols: TLSv1.2 TLSv1.3 +discovery: + kubernetes: + - id: first + service: + schema: "https" + host: "" + port: "" + client: + cert_file: /var/certs/k8s_mtls.pem + key_file: /var/certs/k8s_mtls.key + ssl_verify: true + - id: second + service: + schema: "https" + host: "" + port: "" + client: + cert_file: /var/certs/k8s_mtls.pem + key_file: /var/certs/k8s_mtls.key + ssl_verify: true ``` - -现在你可以使用证书文件 `k8s_mtls.pem`,证书私钥 `k8s_mtls.key` 及 CA 证书 `k8s_mtls_ca.pem` 文件进行 mTLS 认证,如果你想要进一步了解更多 TLS 证书详细内容,请参阅 [_Manage TLS Certificates in a Cluster_](https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/)。