ノート:
- このチュートリアルでは、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イングレス・コントローラを使用して公開し、Oracle Identity DomainsをIdPとして使用するようにOAuth2プロキシを構成します。
前提条件
-
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イングレス・コントローラ・ヘルム・リポジトリを追加します。詳細は、「イングレス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イングレス・コントローラをデプロイします。
helm install ingress-nginx ingress-nginx/ingress-nginx -f values-override.yaml
-
次の
yaml
ファイルをapplication.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
です。 -
-
次の
yaml
ファイルをingress.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アイデンティティ・ドメインに移動し、
OracleIdentityCloudService
ドメインをクリックします。 -
左側のメニューから「統合アプリケーション」を選択し、「アプリケーションの追加」をクリックします。
-
「Confidential Application」を選択し、「Launch workflow」をクリックします。
-
アプリケーションの名前、説明を入力し、「次」をクリックします。
-
アプリケーションのoAuthパラメータを構成します。
-
「認可」セクションで、「認可コード」を選択します。
-
次のURLを入力して、「次」をクリックします。
- リダイレクトURL:
https://<YOUR-FQDN>/oauth2/callback
。 - ログアウト後のリダイレクトURL:
https://<YOUR-FQDN>
。 - ログアウトURL:
https://<YOUR-FQDN>/oauth2/sign_out
。
- リダイレクトURL:
-
-
「Web層ポリシー」で、「スキップして後で実行」を選択し、「終了」をクリックします。
-
[アクティブ]をクリックして、アプリケーションを使用可能にします。
-
左側のメニューの「グループ」にナビゲートし、このアプリケーションとの認証を許可されたユーザーのグループを関連付けます。
-
「Client ID」および「Client Secret」をメモします。
-
OracleIdentityCloudServiceドメインをクリックし、「ドメインURL」を展開します。
例: 「アイデンティティ・ドメインURL」は
https://idcs-01234567890abcdef.identity.oraclecloud.com
になります(ポート番号を削除します)。
タスク4: OAuth2プロキシのデプロイ
OAuth2プロキシを使用して、OAuth2またはOpenID Connect (OIDC)の複雑さを処理し、アプリケーションに転送されるすべてのリクエストが認証されるようにしています。
-
次の
yaml
ファイルをoauth2-proxy.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
ポッドが実行中であることを確認します。
kubectl get pods -l k8s-app=oauth2-proxy
-
リクエスト認証にOAuth2プロキシを使用するようにNginxを構成します。
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認証ページにリダイレクトされます。認証が成功したら、アプリケーションにリダイレクトされます。
認証済ユーザーを識別する2つのヘッダーがあります。
"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 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
F96455-01
April 2024