Apache APISIX Ingress Controller 是一款以 Apache APISIX 作為資料面的 Kubernetes Ingress Controller 開源工具,目前已經更新到 v1.3 版本,實現瞭如證書管理、負載均衡、金絲雀釋出等功能。
長久以來,證書管理都不是一件簡單的事情,雖然 Apache APISIX Ingress Controller 支援從 Kubernetes Secrets 資源中提取證書和私鑰,並轉換為 Apache APISIX 可識別的 SSL 物件,但這只是整個證書管理鏈中的一部分,證書的頒發、輪轉、吊銷邏輯依然需要管理員執行,尤其當證書數量比較多時,工作量往往並不小,因而會佔用管理員不少的時間。
Cert Manager 是一款致力於在 Kubernetes 平臺上簡化證書管理的軟體,它支援對接許多不同的證書源,如 Let's Encrypt 和 HashiCorp Vault。
如果你在使用 Apache APISIX Ingress Controller 時,遇到了證書管理的麻煩,那麼使用 Cert Manager 將會是一個不錯的選擇,本文將介紹如何透過 Cert Manager 來建立證書並對接到 Apache APISIX Ingress Controller。
步驟一:環境準備
如果你希望按照本文的指導進行實際的操作,請確保以下環境和工具已準備就緒:
請注意,下文所有的操作都將在 ingress-apisix 名稱空間中執行,因此需要先建立該名稱空間:kubectl create namespace ingress-apisix
步驟二:安裝 Apache APISIX Ingress Controller
我們可以透過 Helm 來安裝 Apache APISIX Ingress Controller,包括資料面的 Apache APISIX 和 etcd 叢集。
helm repo add apisix https://charts.apiseven.com
helm repo update
helm install apisix apisix/apisix --set gateway.tls.enabled=true --set ingress-controller.enabled=true --namespace ingress-apisix
點選檢視詳細安裝介紹。
步驟三:安裝 Cert Manager
透過 Helm 來安裝 Cert Manager,點選可檢視詳細安裝介紹。
helm install cert-manager jetstack/cert-manager --namespace ingress-apisix --set prometheus.enabled=false --set installCRDs=true
安裝完畢後請等待一會後檢視元件的執行狀態,確保所有元件都已正常執行,你可以透過如下命令進行檢視。
kubectl get all -n ingress-apisix
返回結果如下所示,表示所有元件都已正常執行。
NAME READY STATUS RESTARTS AGE
pod/apisix-5d99956d88-j68sj 1/1 Running 0 63s
pod/apisix-69459554d4-btnwn 0/1 Terminating 0 57m
pod/apisix-etcd-0 1/1 Running 0 57m
pod/apisix-etcd-1 1/1 Running 0 57m
pod/apisix-etcd-2 0/1 Running 0 50s
pod/apisix-ingress-controller-7b5c767cc7-j62hb 1/1 Running 0 55m
pod/cert-manager-5ffd4f6c89-q9f7m 1/1 Running 0 45m
pod/cert-manager-cainjector-748dc889c5-nrvkh 1/1 Running 0 45m
pod/cert-manager-startupapicheck-kmgxf 0/1 Completed 0 45m
pod/cert-manager-webhook-bc964d98b-mkjj7 1/1 Running 0 45m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/apisix-admin ClusterIP 10.96.16.25 <none> 9180/TCP 57m
service/apisix-etcd ClusterIP 10.96.232.251 <none> 2379/TCP,2380/TCP 57m
service/apisix-etcd-headless ClusterIP None <none> 2379/TCP,2380/TCP 57m
service/apisix-gateway NodePort 10.96.118.75 <none> 80:32039/TCP,443:30107/TCP 57m
service/apisix-ingress-controller ClusterIP 10.96.13.76 <none> 80/TCP 57m
service/cert-manager-webhook ClusterIP 10.96.182.188 <none> 443/TCP 45m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/apisix 1/1 1 1 57m
deployment.apps/apisix-ingress-controller 1/1 1 1 57m
deployment.apps/cert-manager 1/1 1 1 45m
deployment.apps/cert-manager-cainjector 1/1 1 1 45m
deployment.apps/cert-manager-webhook 1/1 1 1 45m
NAME DESIRED CURRENT READY AGE
replicaset.apps/apisix-5d99956d88 1 1 1 63s
replicaset.apps/apisix-69459554d4 0 0 0 57m
replicaset.apps/apisix-ingress-controller-74c6b5fbdd 0 0 0 57m
replicaset.apps/apisix-ingress-controller-7b5c767cc7 1 1 1 55m
replicaset.apps/apisix-ingress-controller-7d58db957c 0 0 0 55m
replicaset.apps/cert-manager-5ffd4f6c89 1 1 1 45m
replicaset.apps/cert-manager-cainjector-748dc889c5 1 1 1 45m
replicaset.apps/cert-manager-webhook-bc964d98b 1 1 1 45m
NAME READY AGE
statefulset.apps/apisix-etcd 2/3 57m
NAME COMPLETIONS DURATION AGE
job.batch/cert-manager-startupapicheck 1/1 6m24s 45m
Kubernetes Controller Manager 的機制決定了 Pod 名稱會有所不同。
步驟四:申請證書並測試
首先我們需要配置證書頒發物件。
# issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: issuer
namespace: ingress-apisix
spec:
selfSigned: {}
並建立自簽名證書頒發者。
kubectl apply -f issuer.yaml
請注意,自簽名頒發物件不推薦使用在生產環境中!更多證書頒發物件的配置請參考這裡。
然後為域名httpbin.org
建立一張證書。
# httpbin-cert.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: httpbin
namespace: ingress-apisix
spec:
secretName: httpbin
duration: 2160h # 90d
renewBefore: 360h # 15d
subject:
organizations:
- foo
commonName: httpbin.org
isCA: false
privateKey:
algorithm: RSA
encoding: PKCS1
size: 2048
usages:
- server auth
dnsNames:
- "httpbin.org"
- "*.httpbin.org"
issuerRef:
name: issuer
kind: Issuer
group: cert-manager.io
kubectl apply -f httpbin-cert.yaml
此時需要檢視對應 Secrets 是否已經被建立。
kubectl get secrets -n ingress-apisix httpbin
NAME TYPE DATA AGE
httpbin kubernetes.io/tls 3 2m5s
透過上述驗證,該 Secrets 物件的建立事件已經被 Apache APISIX Ingress Controller 捕獲到,我們嘗試訪問 Apache APISIX Ingress Controller 來驗證證書是否生效,首先我們需要建立額外的路由物件。
# 建立後端
kubectl run httpbin --image kennethreitz/httpbin --namespace ingress-apisix
kubectl expose pod httpbin -n ingress-apisix --port 80
# 定義 ApisixTls 物件
apiVersion: apisix.apache.org/v1
kind: ApisixTls
metadata:
name: httpbin
namespace: ingress-apisix
spec:
hosts:
- httpbin.org
secret:
name: httpbin
namespace: ingress-apisix
---
# 定義訪問後端的路由
apiVersion: apisix.apache.org/v2beta1
kind: ApisixRoute
metadata:
name: httpbin
namespace: ingress-apisix
spec:
http:
- name: httpbin
match:
paths:
- /*
hosts:
- httpbin.org
backends:
- serviceName: httpbin
servicePort: 80
接下來訪問服務 apisix-gateway
。注意,預設情況下該服務的型別為 NodePort
,你可以根據需要修改其型別,比如你的 Kubernetes 叢集是雲廠商託管的,則可以考慮將其修改為 LoadBalancer
型別,以獲取一個外部可達的 IP。
這裡我們透過埠轉發的方式將服務對映到本地。
kubectl port-forward -n ingress-apisix svc/apisix-gateway 8443:443
然後開始配置訪問。
curl https://httpbin.org:8443/json --resolve 'httpbin.org:8443:127.0.0.1' -sk
{
"slideshow": {
"author": "Yours Truly",
"date": "date of publication",
"slides": [
{
"title": "Wake up to WonderWidgets!",
"type": "all"
},
{
"items": [
"Why <em>WonderWidgets</em> are great",
"Who <em>buys</em> WonderWidgets"
],
"title": "Overview",
"type": "all"
}
],
"title": "Sample Slide Show"
}
}
經過上述操作,可以看到訪問成功,說明證書已經生效。注意,由於證書是自簽名的,這裡需要加上 -k
選項來忽略證書的校驗。
此外,如果你想要輪轉證書,刪除 httpbin
這一 Secret 物件即可,Cert Manager 會立刻建立一個新的 httpbin Secret 物件,並且包含新的證書。
總結
本文主要講解了如何利用 Cert Manager 在 Apache APISIX Ingress Controller 中進行證書的建立和管理。想了解更多關於 Apache APISIX Ingress 的介紹與內容,可參考本篇文章 或者參與 Apache APISIX Ingress 專案每兩週舉行的線上討論,分享當下專案進度、最佳實踐及設計思路等多個話題,可檢視具體 issue 瞭解更多。