2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EKSなしIRSAへの道 ― 第1回:OIDCメタデータエンドポイントを公開する

2
Last updated at Posted at 2026-02-07

背景

Amazon EKS(Elastic Kubernetes Service)には、IAM Roles for Service Accounts(IRSA)という便利な機能があります。IRSAを利用すると、KubernetesのPodはServiceAccountを通じてIAMロールを引き受け、AWSリソースへアクセスできます。これにより、Application Load Balancer(ALB)やElastic Block Store(EBS)などのAWSリソースを、Kubernetesのリソースと簡単に連携することができます。

普段の業務ではEKS上でIRSAを大いに活用しています。最初に使った時は「よくわからんけど、マニフェストをapplyしただけでALBとかNLBとかEBSとかEFSとか作られた!すごい!!」と感動しました。この便利な仕組みを知りたくて個人環境でも再現しようと思ったのですが、EKSを使うとなると最低でも月額70ドルの課金が必要です。お金に吝嗇な私は、IRSAのためにそんな大金を使う気にはなれません。

そこで、「EC2インスタンスにkubeadmでKubernetesクラスターを構築して、IRSAを使えるようにするといいのでは?」と思い立ちました。例えばt3a.smallのインスタンス一台でKubernetesクラスターを構築して必要な時だけ起動すれば、ストレージ代も含めて月額5ドル以下に抑えられそうです。

今回は、この「EKSなしでIRSA」の試みを実現するための最初の記事です。若干長い記事ですが、よろしければ最後まで読んでいただければと思います。

本記事の内容

本記事は、kubeadmで構築したKubernetesクラスターにおいて、OIDCメタデータの公開エンドポイントとJWKS(JSON Web Key Set)エンドポイントを公開する方法について説明します。これら2つのエンドポイントを公開すると、ServiceAccountをAWSのIAMロール等の外部リソースと関連づけることが可能になります。

参考情報

本記事に記載している内容は、以下の k8s-irsa-without-eks で実現可能です。

事前知識

今回実現したいことを理解するために、OIDCによるJWTの署名検証やServiceAccountトークンの知識が必要となります。まずはそれらに関する説明をします。

OIDCプロバイダーの公開エンドポイントについて

OIDCを提供しているサービスを「OIDCプロバイダー」と呼びます。例えばAuth0やKeycloak、Oktaはこれに該当します。

OIDCプロバイダーは、「メタデータ公開エンドポイント」と呼ばれるパスを用意しています。ここには、「ログインはここに行ってください」「トークンはここで受け取れます」「公開鍵はここに置いてあります」といった情報が、1か所にまとめて書かれています。

このエンドポイントは、以下のようにホスト名の後に /.well-known/openid-configuration が付与されたパスとなります。

https://oidc-provider.com/.well-known/openid-configuration

ここにアクセスすると、例えば以下のようなJSON形式のレスポンスが返ってきます。

{
  "issuer": "https://oidc-provider.com",
  "authorization_endpoint": "https://oidc-provider.com/authorize",
  "token_endpoint": "https://oidc-provider.com/token",
  "userinfo_endpoint": "https://oidc-provider.com/userinfo",
  "jwks_uri": "https://oidc-provider.com/openid/v1/jwks",
  "end_session_endpoint": "https://oidc-provider.com/logout",

  "response_types_supported": [
    "code",
    "id_token",
    "token id_token"
  ],
  ...
}

OIDCを使うクライアントは、まずこのエンドポイントにアクセスして、それに従って認証やトークン取得を進めます。そのため、細かいURLや仕様を事前に知らなくても、OIDCの標準仕様に従って安全に連携することが可能になります。

なお、OIDCプロバイダーを外部から利用するためには、
.well-known/openid-configuration に加えて /openid/v1/jwks パスの公開も必要になります。

/openid/v1/jwks は、kube-apiserverが発行するJWTの署名検証に使われる公開鍵(JWKS: JSON Web Key Set)を提供するエンドポイントです。外部サービスは、この公開鍵を用いて、OIDC プロバイダーが発行した JWT の署名を検証します。

IRSAの仕組みを理解-JWTの署名検証.png

kube-apiserverのOIDCエンドポイント

そして、KubernetesのAPIサーバー(kube-apiserver)にも、OIDCのメタデータ公開エンドポイントが存在します。つまりkube-apiserverは、OIDCプロバイダーとして振る舞う機能を持っています。

ここで「APIサーバーのOIDCエンドポイントは、ユーザーがkube-apiserverにログインするために使われるのでは?」と思われるかもしれませんが、これは正しくありません。この仕組みはユーザー認証のためではなく、Podで利用されるServiceAccountトークンを発行するために使われています。

ServiceAccountトークンは、Pod内では /run/secrets/kubernetes.io/serviceaccount/token に配置されますが、その中身を見るとJSON Web Token(JWT)の形式になっていることがわかります。 これは、kube-apiserverがOIDCの仕様に従ってトークンを発行しているためです。

このことから、

kube-apiserverはOIDCプロバイダーとしての機能を備えており、その役割はServiceAccountトークンの発行である

ことがわかります。

ServiceAccountトークンの利点

では、「ServiceAccountトークンがOIDCベースのJWT」だと、何が嬉しいのでしょうか。

OIDCの便利な点の一つは、「認証を自分で頑張らなくてよくなる」ことです。たとえば、ログインが必要なWebアプリを作る場合でも、OIDCプロバイダーと連携すれば、ユーザー管理や認証処理を一から実装する必要はありません。

KubernetesのServiceAccountトークンも、まさに同じ発想で設計されています。OIDCベースのJWTであるため、このトークンを使ってKubernetesの外にあるサービスへ「自分は誰か」を証明することができます。

代表的な例が、AWSのIAMロールとServiceAccountを関連付ける仕組みです。Pod自体がAWSの認証情報を保持していなくても、ServiceAccountトークンを用いることで、一時的なAWSの認証情報を取得し、各種AWSリソースを操作できます。

このように、ServiceAccountトークンをOIDCベースにすることで、Kubernetesと外部サービスとの安全かつ柔軟な連携が可能になります。

KubernetesにおけるServiceAccountトークンの署名検証

以上に説明した内容をもとに、Kubernetes版のJWTの署名検証を図にしてみました。この図では、外部サービスをAWSの各リソースにしていますが、他のサービスでも署名検証の流れは同じです。

IRSAの仕組みを理解-JWTの署名検証-k8s-2.png

kube-apiserverのOIDCエンドポイントを確認してみる

これまでの説明で、「ServiceAccountを外部サービスと連携するにはトークンの署名検証が必要で、外部サービスはkube-apiserverのOIDCエンドポイントへのアクセスが必要である」ことをおわかりいただけたかと思います。

実際にkubeadmで構築したKubernetesクラスターで、OIDCのメタデータエンドポイントにアクセスしてみましょう。今回は、クラスター内にPodを作って試してみます。

kube-apiserverは、クラスター内では以下の kubernetes というServiceリソースでサービス提供しています。

$ kubectl get svc -n default
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   95d

このため、クラスター内のネットワークでは kubernetes.default.svc.cluster.local というホスト名で名前解決が可能です。詳しくは公式ドキュメントを参照ください。

上記ホストに、curlを実行可能なPodを作ってアクセスしてみます。

kubectl run curl -it --rm --image=alpine/curl -- sh

curlのコンテナ内で、 /.well-known/openid-configuration へのアクセスを試みます。

/ # curl https://kubernetes.default.svc.cluster.local/.well-known/openid-configuration
curl: (60) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the webpage mentioned above.

SSL/TLS証明書の検証でそもそも失敗しているようです。これを解決するには、kube-apiserverのCA証明書が必要です。CA証明書はPod内に格納されているので、そのパスを指定して再度アクセスしてみます。

/ # CACERT=/run/secrets/kubernetes.io/serviceaccount/ca.crt

/ # curl --cacert "$CACERT" \
      https://kubernetes.default.svc.cluster.local/.well-known/openid-configuration
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/.well-known/\"",
  "reason": "Forbidden",
  "details": {},
  "code": 403
}

証明書の検証は成功しましたが、次はクライアントにアクセス権がない旨のメッセージが表示されてしまいました。これを解決するには、PodにマウントされたServiceAccountのトークンを使って、自分が何者であるかを証明する必要があります。トークンを指定して、再度実行してみましょう。

/ # TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)

/ # curl --cacert "$CACERT" \
      -H "Authorization: Bearer $TOKEN" \
      https://kubernetes.default.svc.cluster.local/.well-known/openid-configuration

すると、以下のようなレスポンスが返ってきました。

{
  "issuer": "https://kubernetes.default.svc.cluster.local",
  "jwks_uri": "https://[control-plane-ip]:6443/openid/v1/jwks",
  "response_types_supported": [
    "id_token"
  ],
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ]
}

"issuer" はクラスター内でのみ利用可能なホスト名になっており、 "jwks_uri" のホスト名はコントロールプレーンのIPアドレスになっています。このままでは、外部サービスがアクセスしても「アクセスしたホスト名と違う...」という理由で、JWTの署名検証に失敗してしまいます。そのため、この2つのURLに書かれたホスト名は、外部サービスがアクセスする際のホスト名と一致させる必要があります。

また、クラスター外のローカルネットワークからは、kube-apiserverに https://[control-plane-ip]:6443 で以下のようにアクセス可能です。

$ curl -k -I https://[control-plane-ip]:6443/ 2> /dev/null | head -n 1
HTTP/2 403

Control PlaneのIPアドレスは、例えば以下のコマンドで確認できます。

$ kubectl describe node -l node-role.kubernetes.io/control-plane | grep InternalIP
  InternalIP:  [control-plane-ip]

kube-apiserverにインターネットからアクセスするには、ロードバランサやリバースプロキシを使って、パブリックIPアドレスを[control-plane-ip]:6443に転送する必要がある点も注意です。

OIDCエンドポイント公開のために必要なことの整理

これまでにわかったことを踏まえて、OIDCのメタデータエンドポイントとJWKS(JSON Web Key Set)エンドポイントを公開するのに必要なことを整理してみます。

  • (1) OIDCエンドポイントにインターネットからアクセスするための入口を作る
    • パブリックIPの確保
    • ホスト名(FQDN)でアクセス出来る状態にする
  • (2) パブリックIPへのHTTPSリクエストをOIDCエンドポイントに転送する
    • 今回は、Gateway API の Envoy Gateway を利用
  • (3) OIDCエンドポイントの "issuer""jwks_uri" のホスト名を修正する
    • (1)で決定したFQDNと同じホスト名にする
    • kube-apiserverのマニフェストの編集が必要

手順

(1) OIDCエンドポイントにインターネットからアクセスするための入口を作る

外部サービスがJWTの署名検証を行う際には、OIDCのエンドポイントへアクセスできる必要があります。そのため、OIDCエンドポイントはインターネット経由で到達可能なことが必須となります。また、OIDCエンドポイントとの通信はHTTPSで行われるため、パブリックIPに紐づいたFQDNを用意し、信頼されたTLS証明書を設定しておく必要があります。

これらを実現する方法は、私の記事になりますが以下に掲載しました。

この記事の手順7までを進めると、準備は完了です。

作成したFQDNが名前解決するかを確認するには、例えばインターネットに接続可能なLinuxマシンで以下のコマンドを実行します。これでパブリックIPが返ってくれば成功です。

$ dig +short A [FQDN名]
11.22.33.44

TLS証明書でHTTPS通信できるかどうかの確認は後の手順で行います。

(2) パブリックIPへのHTTPSリクエストをOIDCエンドポイントに転送する

続いて、パブリックIPに届いたHTTPSのリクエストをOIDCエンドポイントに転送するためのリバースプロキシを用意します。今回はEnvoy Gatewayを使います。

(2-1) Envoy Gatewayのインストール

まずは、自前で用意したKubernetesクラスターにEnvoy Gatewayをインストールします。

今回は、以下のHelmfile形式のyamlファイルを使って、Envoy GatewayのHelmチャートをインストールすることで実現します。

helmfile-envoy-gateway.yaml
releases:
  - name: eg
    chart: oci://docker.io/envoyproxy/gateway-helm
    version: 1.6.2
    createNamespace: true
    namespace: envoy-gateway-system
    values:
      - config:
          envoyGateway:
            provider:
              type: Kubernetes
              kubernetes:
                deploy:
                  type: GatewayNamespace # Envoy Proxyをnamespace指定でデプロイするのに必要

次のコマンドを実行します。

helmfile apply -f helmfile-envoy-gateway.yaml

Helmチャートのデプロイに成功したら、次のようなカスタムリソースが作成されていることを確認できます。

Gateway APIのカスタムリソース

$ kubectl api-resources --api-group=gateway.networking.k8s.io | head -n4
NAME                 SHORTNAMES   APIVERSION                           NAMESPACED   KIND
backendtlspolicies   btlspolicy   gateway.networking.k8s.io/v1         true         BackendTLSPolicy
gatewayclasses       gc           gateway.networking.k8s.io/v1         false        GatewayClass
gateways             gtw          gateway.networking.k8s.io/v1         true         Gateway

Envoy Gatewayのカスタムリソース

$ kubectl api-resources --api-group=gateway.envoyproxy.io | head -n4
NAME                     SHORTNAMES   APIVERSION                       NAMESPACED   KIND
backends                 be           gateway.envoyproxy.io/v1alpha1   true         Backend
backendtrafficpolicies   btp          gateway.envoyproxy.io/v1alpha1   true         BackendTrafficPolicy
clienttrafficpolicies    ctp          gateway.envoyproxy.io/v1alpha1   true         ClientTrafficPolicy

また、Envoy Gatewayのコントローラーがインストールされていることも確認できます。

$ kubectl get pod -A -l app.kubernetes.io/instance=eg
NAMESPACE              NAME                             READY   STATUS    RESTARTS   AGE
envoy-gateway-system   envoy-gateway-656884489f-62bgm   1/1     Running   0          11m

(2-2) Gateway API(Envoy Gateway)のカスタムリソースをデプロイ

続いて、Gateway APIのカスタムリソースをデプロイします。主要リソースだけで言うと、デプロイの順番は「GatewayClass → Gateway → HTTPRoute」となります。

まずは、以下のマニフェストでGatewayClassリソースをデプロイします。

GatewayClass

以下のマニフェストで、GatewayClassリソースをデプロイします。

envoy.gatewayclass.yaml
# EnvoyProxyリソースの説明は後述
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: eg-hostnet
  namespace: envoy-gateway-system
spec:
  extraArgs:
  - --use-dynamic-base-id
  provider:
    type: Kubernetes
    kubernetes:
      useListenerPortAsContainerPort: true
      envoyDaemonSet:
        patch:
          type: StrategicMerge
          value:
            spec:
              template:
                spec:
                  hostNetwork: true
                  dnsPolicy: ClusterFirstWithHostNet
                  containers:
                  - name: envoy
                    securityContext:
                      allowPrivilegeEscalation: false
                      privileged: false
                      runAsUser: 0
                      runAsGroup: 0
                      runAsNonRoot: false
                      capabilities:
                        drop: ["ALL"]
                        add: ["NET_BIND_SERVICE"]
      envoyService:
        type: ClusterIP
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
  name: envoy-gateway
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
  parametersRef:
    group: gateway.envoyproxy.io
    kind: EnvoyProxy
    name: eg-hostnet
    namespace: envoy-gateway-system

EnvoyProxyはEnvoy Gatewayのカスタムリソースで、Envoy Gatewayが配備するEnvoyの動作設定(Podの属性やServiceの種類など)をカスタマイズするためのリソースです。今回はEnvoy Gatewayをリバースプロキシとして、ホストネットワーク上の443番で待ち受けさせたいので、EnvoyProxyにこの設定を記述しています。

このマニフェストをapplyします。

kubectl apply -f envoy.gatewayclass.yaml

GatewayClassリソースが作成されることを確認します。

$ kubectl get gatewayclass
NAME            CONTROLLER                                      ACCEPTED   AGE
envoy-gateway   gateway.envoyproxy.io/gatewayclass-controller   True       13s
Gateway

続いて、Gatewayリソースを以下のマニフェストで作成します。

apiserver.gateway.yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: apiserver-gateway
  namespace: default
spec:
  gatewayClassName: envoy-gateway
  listeners:
  - name: https
    protocol: HTTPS
    port: 443
    hostname: "[FQDN名]" # 手順(1)で用意したFQDNを記載
    tls:                 # cert-managerで作成したTLS証明書を指定
      mode: Terminate
      certificateRefs:
      - kind: Secret
        name: cert-tls

このマニフェストをapplyします。

kubectl apply -f apiserver.gateway.yaml

すると、Gatewayリソースが作成されます。

$ kubectl get gateway -n default
NAME                CLASS           ADDRESS         PROGRAMMED   AGE
apiserver-gateway   envoy-gateway   10.111.58.170   True         14s

上記出力で、PROGRAMMEDtrue になっているかを確認してください。

上手く行っていれば、以下のようなリバースプロキシ用のPod(Deployment)とServiceリソースが作成されているはずです。

$ kubectl get po -n default -l app.kubernetes.io/managed-by=envoy-gateway
NAME                      READY   STATUS    RESTARTS   AGE
apiserver-gateway-nssng   2/2     Running   0          61s

$ kubectl get svc -n default -l app.kubernetes.io/managed-by=envoy-gateway
NAME                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
apiserver-gateway   ClusterIP   10.111.58.170   <none>        443/TCP   2m41s
HTTPRoute

さらに、リバースプロキシの転送ルールを記載したHTTPRouteリソースを作成するために、以下のマニフェストを用意します。

apiserver.httproute.yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: apiserver-route
  namespace: default
spec:
  parentRefs:
  - name: apiserver-gateway
  hostnames:
  - "[FQDN名]"           # 手順(1)で用意したFQDNを記載
  rules:
  - backendRefs:
    - name: kubernetes   # 転送先はkube-apiserver
      namespace: default
      port: 443
    matches:             # OIDCのエンドポイントのみに転送を限定する
    - path:
        type: Exact
        value: /.well-known/openid-configuration
    - path:
        type: Exact
        value: /openid/v1/jwks

このマニフェストをapplyします。

kubectl apply -f apiserver.httproute.yaml

リソースが作成されたことを確認します。

$ kubectl get httproute -n default
NAME              HOSTNAMES      AGE
apiserver-route   ["[FQDN名]"]   11s

その他の必要な対応

ここまで進めれば、ようやくOIDCのエンドポイントに接続できるようになります。

$ curl -I https://[FQDN名]/.well-known/openid-configuration 2>/dev/null | head -n 1
HTTP/2 400

しかしながら、400のステータスコードが返ってきてしまいます。

kubectl logs -n default ds/apiserver-gateway --tail=1 | jq

でEnvoy Gatewayのログを見ると、次のように出力されていました。

{
  ...
  "response_code": 400,
  "response_code_details": "via_upstream",
  ...
  "upstream_cluster": "httproute/default/apiserver-route/rule/0",
  "upstream_host": "[control-plane-ip]:6443",
  ...
}

この出力から「400のステータスコードはバックエンド、つまりkube-apiserverが返している」ことがわかります。理由は、kube-apiserverはHTTPSでlistenしているにも関わらず、Envoy GatewayはHTTPでプロキシしようとしているためです。

そこで、BackendTLSPolicyリソースを用意して、Gatewayからkube-apiserverの接続をHTTPSで実施するようにします。

以下がマニフェストです。

apiserver.backendtlspolicy.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
  name: apiserver-backend-tls
  namespace: default
spec:
  targetRefs:
  - group: ""
    kind: Service
    name: kubernetes
  validation:
    hostname: kubernetes.default.svc
    caCertificateRefs: # kube-apiserverのCA証明書を使う設定
    - group: ""
      kind: ConfigMap
      name: kube-root-ca.crt

このマニフェストをapplyします。

kubectl apply -f apiserver.backendtlspolicy.yaml

すると、kube-apiserverからレスポンスが返るようになりました。

$ curl https://[FQDN名]/.well-known/openid-configuration
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/.well-known/openid-configuration\"",
  "reason": "Forbidden",
  "details": {},
  "code": 403
}

しかし、既に説明したようにkube-apiserverのOIDCエンドポイントから情報を取得するにはJWT等を用いた認証認可が必要になるため、まだやりたいことを実現できません。

そこで、次のマニフェストで定義されるリソースを作成して、OIDCのエンドポイントのみは認証認可を不要とする設定にします。

allow-oidc-public.clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: allow-oidc-discovery-and-jwks
rules:
  - nonResourceURLs:
      - "/.well-known/openid-configuration"
      - "/openid/v1/jwks"
    verbs:
      - "get"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: allow-oidc-discovery-and-jwks-to-anonymous
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: allow-oidc-discovery-and-jwks
subjects:
  - kind: Group
    name: system:unauthenticated
    apiGroup: rbac.authorization.k8s.io

上記マニフェストを適用します。

kubectl apply -f allow-oidc-public.clusterrole.yaml

これでようやく、OIDCエンドポイントから必要な情報を取得できるのを、以下のように確認できます。

まずは、OIDCメタデータのエンドポイントの確認です。

curl https://[FQDN名]/.well-known/openid-configuration 2>/dev/null | jq

以下が出力です。

{
  "issuer": "https://kubernetes.default.svc.cluster.local",
  "jwks_uri": "https://[control-plane-ip]:6443/openid/v1/jwks",
  "response_types_supported": [
    "id_token"
  ],
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ]
}

続いて、JWKSエンドポイントにアクセスしてみます。

curl https://[FQDN名]/openid/v1/jwks 2>/dev/null | jq

以下が出力です。

{
  "keys": [
    {
      "use": "sig",
      "kty": "RSA",
      "kid": "awrVdy...",
      "alg": "RS256",
      "n": "qRcf8S...",
      "e": "A..."
    }
  ]
}

(3) OIDCエンドポイントの "issuer""jwks_uri" のホスト名を修正する

最後に、OIDCエンドポイントに記載されたホスト名を、外部サービスがアクセスする際のホスト名と同じになるように修正します。具体的には、kube-apiserverのマニフェスト(/etc/kubernetes/manifests/kube-apiserver.yaml)において、起動コマンド実行時の引数を以下のように変更します。

/etc/kubernetes/manifests/kube-apiserver.yaml の差分
spec:
  containers:
  - command:
     - kube-apiserver
     ...
     - --requestheader-group-headers=X-Remote-Group
     - --requestheader-username-headers=X-Remote-User
     - --secure-port=6443
-    - --service-account-issuer=https://kubernetes.default.svc.cluster.local
+    - --service-account-issuer=https://[FQDN名]
+    - --service-account-jwks-uri=https://[FQDN名]/openid/v1/jwks
     - --service-account-key-file=/etc/kubernetes/pki/sa.pub
     - --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
     - --service-cluster-ip-range=10.96.0.0/12
     ...

変更後、kube-apiserverが再起動してReadyになるまで待ちます。

  • 注意点
    • kube-apiserver.yaml のマニフェストのバックアップを同じディレクトリに作ると、バックアップ側の内容が読まれてデプロイされてしまう可能性があります。
    • 今回の変更により、いくつかのPod(CNIだとcilium-operator等)が起動しなくなってしまう可能性が高いです。その場合は該当PodのDeploymentやDaemonSetを再起動すると解決するはずです。

再度、curlでOIDCのメタデータエンドポイントにアクセスします。

curl https://[FQDN名]/.well-known/openid-configuration 2>/dev/null | jq

すると、次のようにホスト名が変わっているのを確認できます。

{
  "issuer": "https://[FQDN名]",
  "jwks_uri": "https://[FQDN名]/openid/v1/jwks",
  "response_types_supported": [
    "id_token"
  ],
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ]
}

おわりに

「EKSなしでIRSA」を実現する第一歩として、kube-apiserverのOIDCのエンドポイントを公開することができました。次回記事では、AWSにOIDCプロバイダーやIAMロールを作成して、KubernetesのServiceAccountでAWSリソースにアクセスできることを確認します。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?