附註:
- 此教學課程需要存取 Oracle Cloud。若要註冊免費帳戶,請參閱開始使用 Oracle Cloud Infrastructure Free Tier 。
- 它使用 Oracle Cloud Infrastructure 憑證、租用戶及區間的範例值。完成實驗室時,請將這些值取代為您雲端環境特有的值。
使用 Nginx Ingress Controller、OAuth2 Proxy 和 Oracle Identity Domains 保護 Kubernetes Web 服務
簡介
保護 Kubernetes 代管的 Web 服務應該很容易。無論您的應用程式缺乏外部身分識別提供者 (IdP) 整合的內建支援,或您需要單一登入 (SSO) 解決方案來簡化管理並減少每個服務的個別認證機制的需求,OAuth2 代理主機都提供將任何應用程式連線至幾乎任何身分識別提供者 (IdP) 的彈性。
OAuth2 代理主機可作為位於您 Kubernetes 服務前的反向代理主機。它會攔截流量、將使用者重新導向至外部授權伺服器 (例如 Okta 或 GitHub) 以進行登入,並在將要求轉送至後端服務之前驗證存取記號。
目標
- 將簡單的 Web 應用程式部署至 Kubernetes、使用 Nginx Ingress Controller 顯示此應用程式,以及將 OAuth2 代理主機設定為使用 Oracle Identity Domains 作為 IdP。
必要條件
-
存取 Oracle Cloud Infrastructure (OCI) 租用戶。
-
設定為使用公用子網路作為負載平衡器的 Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) 叢集。
-
(選擇性) 存取以更新「網域名稱系統 (DNS)」網域的記錄。
作業 1:建立 OKE 叢集
-
登入 OCI 主控台,瀏覽至 Oracle Container Engine for Kubernetes ,然後按一下建立。
-
在建立叢集精靈中,按一下快速建立。
-
輸入下列資訊,然後按一下下一步。
- 名稱:輸入叢集名稱。
- Kubernetes 版本:選取想要使用的版本。
- Kubernetes API 端點:選取公用端點。
- 節點類型:選取受管理。
- Kubernetes 工作節點:選取專用工作者。
- 節點計數:
1
。
-
複查並按一下建立叢集。等待叢集變成可用。
-
更新與服務子網路關聯的安全清單。
-
按一下服務子網路。
-
按一下安全清單,然後新增下列規則。
-
傳入:
-
傳出:
-
-
-
更新與工作節點子網路關聯的安全清單,以允許來自負載平衡器的連線。
-
按一下 VCN 名稱。
-
在資源下,選取安全清單,然後按一下節點安全清單。
-
將下列輸入規則新增至節點安全清單。
-
按一下新增傳入規則。
-
作業 2:設定 Nginx 傳入控制器
-
叢集可用之後,您便可以使用 OCI Cloud Shell 存取叢集。按一下存取叢集,然後在 OCI Cloud Shell 中複製並執行下列命令。
-
執行
kubectl get node
命令以取得可用節點清單。 -
新增 Nginx Ingress Controller helm 儲存區域。如需詳細資訊,請參閱傳入 NGINX 控制器簡介和 helm 。
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update
-
建立
values-override.yaml
檔案。controller: allowSnippetAnnotations: true service: annotations: oci.oraclecloud.com/load-balancer-type: "lb" service.beta.kubernetes.io/oci-load-balancer-backend-protocol: "TCP" service.beta.kubernetes.io/oci-load-balancer-shape: "flexible" service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10" service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "10"
-
部署 Nginx Ingress Controller。
helm install ingress-nginx ingress-nginx/ingress-nginx -f values-override.yaml
-
儲存下列名為
application.yaml
的yaml
檔案。--- # Create ClusterIP service apiVersion: v1 kind: Service metadata: name: httpbin labels: app: httpbin spec: ports: - port: 5000 targetPort: 5000 selector: app: httpbin --- # Deployment of a sample web application apiVersion: apps/v1 kind: Deployment metadata: name: httpbin spec: replicas: 2 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: containers: - image: mendhak/http-https-echo imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 5000 env: - name: HTTP_PORT value: "5000"
-
建立應用程式資源。
kubectl apply -f application.yaml
-
為與負載平衡器關聯的公用 IP 位址建立 DNS 記錄。
-
取得負載平衡器的公用 IP 位址。
$ kubectl get svc ingress-nginx-controller NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller LoadBalancer 10.96.152.30 158.180.61.74 80:31957/TCP,443:30838/TCP 32s
-
建立 DNS 記錄。如果您沒有 DNS 伺服器,我們將會使用免費的萬用字元 DNS 服務 nip.io 。
在此情況下, FQDN 為
158-180-61-74.nip.io
。 -
-
儲存下列名為
ingress.yaml
的yaml
檔案。注意:請務必使用您的 FQDN 更新主機項目。
--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: httpbin-ingress-nginx spec: ingressClassName: nginx tls: - hosts: - "<YOUR-FQDN>" rules: - host: "<YOUR-FQDN>" http: paths: - pathType: Prefix path: "/" backend: service: name: httpbin port: number: 5000
-
請執行下列命令來建立傳入資源。
kubectl apply -f ingress.yaml
-
測試服務的連線。
$ curl -k https://<YOUR-FQDN> { "path": "/", "headers": { "host": "158-180-61-74.nip.io", "x-request-id": "b0320217391a922acecbfe10758b3ffe", "x-real-ip": "10.0.10.167", "x-forwarded-for": "10.0.10.167", "x-forwarded-host": "158-180-61-74.nip.io", "x-forwarded-port": "443", "x-forwarded-proto": "https", "x-forwarded-scheme": "https", "x-scheme": "https", "user-agent": "curl/7.87.0", "accept": "*/*" }, "method": "GET", "body": "", "fresh": false, "hostname": "158-180-61-74.nip.io", "ip": "10.0.10.167", "ips": [ "10.0.10.167" ], "protocol": "https", "query": {}, "subdomains": [ "158-180-61-74" ], "xhr": false, "os": { "hostname": "httpbin-644874bcdb-ll4mb" }, "connection": {} }
工作 3:在 Oracle 識別網域中設定機密應用程式
-
瀏覽至 OCI 主控台中的 Oracle Identity Domains ,然後按一下
OracleIdentityCloudService
網域。 -
從左側功能表中選取整合的應用程式,然後按一下新增應用程式。
-
選取機密應用程式,然後按一下啟動工作流程。
-
輸入應用程式名稱、描述,然後按一下下一步。
-
設定應用程式 oAuth 參數。
-
在授權區段中,選取授權代碼。
-
輸入下列 URL,然後按一下下一步。
- 重新導向 URL:
https://<YOUR-FQDN>/oauth2/callback
。 - 登出後重新導向 URL:
https://<YOUR-FQDN>
。 - 登出 URL:
https://<YOUR-FQDN>/oauth2/sign_out
。
- 重新導向 URL:
-
-
在 Web 層原則中,選取略過並稍後執行,然後按一下完成。
-
按一下啟動來啟用應用程式。
-
瀏覽至左側功能表中的群組,並將允許認證的使用者群組與此應用程式建立關聯。
-
請注意用戶端 ID 和用戶端密碼。
-
按一下 OracleIdentityCloudService 網域,然後展開網域 URL 。
例如:識別網域 URL 將會是
https://idcs-01234567890abcdef.identity.oraclecloud.com
(我們會將連接埠號碼刪除)。
工作 4:部署 OAuth2 代理主機
我們使用 OAuth2 代理主機來處理 OAuth2 或 OpenID Connect (OIDC) 複雜性,並確保所有轉送至應用程式的要求都會經過認證。
-
儲存下列名為
oauth2-proxy.yaml
的yaml
檔案,並以適用的值取代預留位置。注意:
-
<Identity Domain URL>
:https://idcs-01234567890abcdef.identity.oraclecloud.com/
-
<Identity Domain FQDN>
:idcs-01234567890abcdef.identity.oraclecloud.com
--- apiVersion: apps/v1 kind: Deployment metadata: labels: k8s-app: oauth2-proxy name: oauth2-proxy spec: replicas: 1 selector: matchLabels: k8s-app: oauth2-proxy template: metadata: labels: k8s-app: oauth2-proxy spec: containers: - args: - --provider=oidc - --provider-display-name="Oracle Identity Domains" - --oidc-issuer-url=<Identity Domain URL> - --redirect-url=https://<YOUR-FQDN>/oauth2/callback - --upstream=file:///dev/null - --http-address=0.0.0.0:4180 - --email-domain=* - --set-xauthrequest=true - --session-cookie-minimal=true - --whitelist-domain=<Identity Domain FQDN> env: - name: OAUTH2_PROXY_CLIENT_ID value: "<APPLICATION_CLIENT_ID>" - name: OAUTH2_PROXY_CLIENT_SECRET value: "<APPLICATION_CLIENT_SECRET>" # docker run -ti --rm python:3-alpine python -c 'import secrets,base64; print(base64.b64encode(base64.b64encode(secrets.token_bytes(16))));' - name: OAUTH2_PROXY_COOKIE_SECRET value: "<OUTPUT_OF_THE_ABOVE_DOCKER_COMMAND>" image: quay.io/oauth2-proxy/oauth2-proxy:latest imagePullPolicy: Always name: oauth2-proxy ports: - containerPort: 4180 protocol: TCP --- apiVersion: v1 kind: Service metadata: labels: k8s-app: oauth2-proxy name: oauth2-proxy spec: ports: - name: http port: 4180 protocol: TCP targetPort: 4180 selector: k8s-app: oauth2-proxy --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: oauth2-proxy annotations: nginx.ingress.kubernetes.io/configuration-snippet: | set $xheader ""; if ( $request_uri = "/oauth2/sign_out" ){ set $xheader "https://<Identity Domain FQDN>/oauth2/v1/userlogout; } proxy_set_header X-Auth-Request-Redirect ${xheader}; spec: ingressClassName: nginx rules: - host: <YOUR-FQDN> http: paths: - path: /oauth2 pathType: Prefix backend: service: name: oauth2-proxy port: number: 4180 tls: - hosts: - <YOUR-FQDN>
-
-
將 OAuth2 代理主機建置到 OKE。
kubectl apply -f oauth2-proxy.yaml
確認 Pod 正在執行中。
kubectl get pods -l k8s-app=oauth2-proxy
-
將 Nginx 設定為使用 OAuth2 代理主機進行要求認證。
以認證註解更新
ingress.yaml
檔案。--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: httpbin-ingress-nginx annotations: nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth" nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri" nginx.ingress.kubernetes.io/auth-response-headers: "x-auth-request-user, x-auth-request-email" spec: ingressClassName: nginx tls: - hosts: - "<YOUR-FQDN>" rules: - host: "<YOUR-FQDN>" http: paths: - pathType: Prefix path: "/" backend: service: name: httpbin port: number: 5000
-
嘗試連線您的應用程式。您應該被重導至 Oracle 認證頁面。驗證成功後,您應重新導向至您的應用程式。
識別認證的使用者有兩個標頭。
"x-auth-request-user": "xxxx@oracle.com" "x-auth-request-email": "xxxx@oracle.com"
-
若要從應用程式登出,您可以前往頁面上的
/oauth2/sign_out
。https://<YOUR-FQDN>/oauth2/sign_out
已知問題:登出後重新導向無法運作。此處會追蹤此問題:新增 id_token_hint 參數至 OIDC 提供者的登出提供者 URL 。
作業 5:清除資源
-
請執行下列命令以刪除所有 Kubernetes 部署的資源。
kubectl delete -f oauth2-proxy.yaml -f ingress.yaml -f application.yaml helm uninstall ingress-nginx
-
從 Oracle Identity Domains 刪除應用程式。
-
刪除 OKE 叢集。
-
刪除為 OKE 叢集建立的 VCN。
注意:
-
您必須等待 OKE 叢集與節點集區刪除結束。
-
VCN 名稱包含 OKE 叢集的名稱:
oke-vcn-quick-<oke-cluster-name>-<random-string>
。
-
相關連結
認可
- 作者 - Andrei Ilas (主要雲端架構師)
其他學習資源
瀏覽 docs.oracle.com/learn 的其他實驗室,或前往 Oracle Learning YouTube 頻道存取更多免費學習內容。此外,請造訪 education.oracle.com/learning-explorer 以成為 Oracle Learning Explorer。
如需產品文件,請造訪 Oracle Help Center 。
Secure Kubernetes Web Services using Nginx Ingress Controller, OAuth2 Proxy, and Oracle Identity Domains
F96459-01
April 2024