注意:
- 此教程需要访问 Oracle Cloud。要注册免费账户,请参阅开始使用 Oracle Cloud Infrastructure Free Tier 。
- 它使用 Oracle Cloud Infrastructure 身份证明、租户和区间示例值。完成实验室时,请将这些值替换为特定于您的云环境的值。
使用 Nginx 入站控制器、OAuth2 代理和 Oracle 身份域保护 Kubernetes Web 服务
简介
保护 Kubernetes 托管的 Web 服务应该很容易。无论您的应用缺乏对外部身份提供者 (IdP) 集成的内置支持,还是需要单点登录 (SSO) 解决方案来简化管理并减少对每个服务使用单个身份验证机制的需求,OAuth2 代理都可以灵活地将任何应用连接到几乎任何身份提供者 (IdP)。
OAuth2 代理充当位于 Kubernetes 服务前面的反向代理。它拦截流量,将用户重定向到外部授权服务器(如 Okta 或 GitHub)进行登录,并在将请求转发到后端服务之前验证访问令牌。
目标
- 将简单的 Web 应用程序部署到 Kubernetes,使用 Nginx 入站控制器公开它,并将 OAuth2 代理配置为使用 Oracle 身份域作为 IdP。
先决条件
-
访问 Oracle Cloud Infrastructure (OCI) 租户。
-
配置为将公共子网用于负载平衡器的 Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) 集群。
-
(可选)用于更新域名系统 (Domain Name System,DNS) 域记录的访问权限。
任务 1:创建 OKE 集群
-
登录到 OCI 控制台,导航到 Oracle Container Engine for Kubernetes ,然后单击创建。
-
在创建集群向导中,单击快速创建。
-
输入以下信息,然后单击下一步。
- 名称:输入群集名称。
- Kubernetes 版本:选择要使用的版本。
- Kubernetes API 端点:选择公共端点。
- 节点类型:选择托管。
- Kubernetes worker 节点:选择专用 worker 。
- 节点计数:
1
。
-
复查并单击创建集群。等待集群变为可用。
-
更新与服务子网关联的安全列表。
-
单击服务子网。
-
单击安全列表并添加以下规则。
-
入站:
-
出站:
-
-
-
更新与 worker 节点子网关联的安全列表,以允许来自负载平衡器的连接。
-
单击 VCN 名称。
-
在资源下,选择安全列表并单击节点安全列表。
-
将以下入站规则添加到节点安全列表中。
-
单击添加入站规则。
-
任务 2:设置 Nginx 入站控制器
-
集群可用后,您可以使用 OCI Cloud Shell 访问集群。单击访问集群,然后在 OCI Cloud Shell 中复制并运行以下命令。
-
运行
kubectl get node
命令以获取可用节点的列表。 -
添加 Nginx 入站控制器 helm 系统信息库。有关更多信息,请参见 Overview of Ingress NGINX Controller 和 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 入站控制器。
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
域。 -
从左侧菜单中选择 Integrated Applications ,然后单击 Add application(添加应用程序)。
-
选择 Confidential Application(机密应用程序),然后单击 Launch workflow(启动工作流)。
-
输入应用程序的名称和说明,然后单击下一步。
-
配置应用程序 oAuth 参数。
-
在 Authorization(授权)部分中,选择 Authorization code(授权代码)。
-
输入以下 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
已知问题:注销后重定向不起作用。此处跟踪此问题:向 OIDC 提供程序的注销提供程序 URL 添加 id_token_hint 参数。
任务 5:清除资源
-
运行以下命令以删除所有 Kubernetes 部署的资源。
kubectl delete -f oauth2-proxy.yaml -f ingress.yaml -f application.yaml helm uninstall ingress-nginx
-
从 Oracle 身份域中删除应用程序。
-
删除 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 帮助中心。
Secure Kubernetes Web Services using Nginx Ingress Controller, OAuth2 Proxy, and Oracle Identity Domains
F96458-01
April 2024