Kubernetes では kubernetes-dashboard という各種リソースを見るためのダッシュボードが提供されている。
ブラウザ上で色々確認できるので便利なのだが、ログイン時は下のように自身の token か kubeconfig ファイルをアップロードする必要がある。
Kubernetes へのログインで Certificate や Token を使っている場合はそのままアップロードすればいいものの、 OIDC を設定したクラスタで OIDC 経由でログインしている場合は ID token を取得する必要があり、めんどくさい。
そこで、
- oauth2-proxy で kubernetes 向けの OIDC ID token を dex から取得
- ingress-nginx で ID token を Authorization header に Bearer token として付与し、 kubernetes-dashboard に送信
することでシームレスに見れるようにする。
dex
kubernetes が使っている client と同じ client id を使うので dex で新しく client を発行する必要はないが、 Callback URL を新たに登録する必要がある。
staticClients: - id: kubernetes-client redirectURIs: - ... - 'https://{k8s dashboard domain}/oauth2/callback' ...
oauth2-proxy
oauth2-proxy は dex から id token を取得し、 ingress-nginx に Authorization Header として渡す役割を果たす。以下のような環境変数を設定すると良い。
- name: OAUTH2_PROXY_PROVIDER value: oidc - name: OAUTH2_PROXY_OIDC_ISSUER_URL value: {OIDC issuer url} - name: OAUTH2_PROXY_COOKIE_DOMAINS value: {k8s dashboard domain} - name: OAUTH2_PROXY_WHITELIST_DOMAINS value: {k8s dashboard domain} # Re-validate OAuth token per 1 hour - name: OAUTH2_PROXY_COOKIE_REFRESH value: 9m # id token の期限より短くする - name: OAUTH2_PROXY_SCOPE value: "openid profile groups offline_access email" # offline_access は refresh token の取得に使う。 email は oauth2-proxy の動作に必須 - name: OAUTH2_PROXY_SET_AUTHORIZATION_HEADER value: "true"
ポイントは OAUTH2_PROXY_SET_AUTHORIZATION_HEADER
で、これを true にすることで id token を Authorization Header として ingress-nginx に渡すことができる。
ingress-nginx
ingress-nginx は oauth2-proxy にリダイレクト(& reverse proxy)して Authorization Header を取得し、それを付けた上で kubernetes-dashboard に reverse proxy する。
構成としては、oauth2-proxy に reverse proxy するための認証がない Ingress と、kubernetes-dashboard に reverse proxy するための auth_request 付き Ingress を用意することになる。
oauth2-proxy 用 Ingress
oauth2-proxy の認証まわりの endpoint である /oauth2
配下を oauth2-proxy の service にわたす。
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/force-ssl-redirect: "true" spec: rules: - host: {k8s dashboard host} http: paths: - path: /oauth2/ pathType: Prefix backend: service: name: kubernetes-dashboard-oauth2-proxy port: number: 80
kubernetes-dashboard 用 Ingress
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" nginx.ingress.kubernetes.io/force-ssl-redirect: "true" nginx.ingress.kubernetes.io/auth-response-headers: "Authorization" nginx.ingress.kubernetes.io/auth-url: "https://{k8s dashboard host}/oauth2/auth" nginx.ingress.kubernetes.io/auth-signin: "https://{k8s dashboard host}/oauth2/start?rd=$scheme://$host$escaped_request_uri" spec: rules: - host: kubernetes-dashboard.kmc.gr.jp http: paths: - path: / pathType: Prefix backend: service: name: kubernetes-dashboard port: number: 443
ポイントは nginx.ingress.kubernetes.io/auth-response-headers: "Authorization"
を設定することで、これで oauth2-proxy から来た Authorization Header を Request Header に設定して kubernetes-dashboard にリクエストを送ってくれる。
これで、 kuberentes-dashboard へのリクエストに OIDC で認証された kubernetes において valid な Authorization Header が乗るようになり、ユーザーの権限で Kubenetes dashboard が閲覧・編集できるようになった*1。
*1:最初の Token を求める画面は出なくなる