--- title: Pivotal Container Service (PKS)でkubeloginを使う方法 tags: ["Kubernetes", "PKS", "UAA", "OpenID Connect"] categories: ["Dev", "CaaS", "Kubernetes", "PKS"] date: 2018-10-03T04:27:02Z updated: 2019-08-21T08:36:17Z --- > ⚠️ 【Updated】 ⚠️ > > Enterprise PKS 1.5で `pks get-kubeconfig --sso-auto` オプションが追加され、ブラウザでUAAログインできるようになりました。 > > 下記の作業は**行わないでください**。また、以下の設定を行なっている場合はPKS 1.5にアップグレードする前に削除してください。 [Pivotal Container Service (PKS) 1.2](https://docs.pivotal.io/runtimes/pks/1-2/)でUAAを使ったOpenID Connectに対応しました。 が、公式ドキュメントではCluster UserはcurlコマンドでID TokenとRefersh Tokenをとるように説明されています。 または[Knowledge Base](https://community.pivotal.io/s/article/script-to-automate-generation-of-the-kubeconfig-for-the-kubernetes-user)でトークン取得用の[スクリプト](https://pivotal.my.salesforce.com/sfc/p/U0000000YQaz/a/0e0000000lSX/8rROyDWP7fxbHx7KulEG.JLbbFxr0Xh4RPVOxq49q.k)が紹介されています。 curlで各トークンを抽出するのは手間がかかるので、[@int128さん](https://twitter.com/int128)作の[`kubelogin`](https://github.com/int128/kubelogin)を使う方法を説明します。 PKSでOIDC連携をする場合は、UAAのクライアントのclient_idは`pks_cluster_client`固定になります。デフォルトでは`authorization_code` grant_typeがサポートされていないので、 PKS管理者は`uaac`コマンドでクライアントの情報を更新します。また、`kubelogin`が期待するredirect_uriの[http://localhost:8000](http://localhost:8000)も設定します。 ``` uaac target https://${PKS_DOMAIN}:8443 --skip-ssl-validation uaac token client get admin -s ${ADMIN_SECRET} uaac client update pks_cluster_client \ --authorized_grant_types password,refresh_token,authorization_code \ --redirect_uri http://localhost:8000 ``` PKSのk8sクラスタユーザーは`~/.kube/config`に次の設定を行います。 ```yaml apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJTi.... server: https://demo.pks.example.com:8443 name: demo contexts: - context: cluster: demo user: demo@example.com name: demo current-context: demo users: - name: demo@example.com user: auth-provider: config: client-id: pks_cluster_client cluster_client_secret: "" idp-issuer-url: https://api.pks.example.com:8443/oauth/token name: oidc ``` PKSのk8sクラスタユーザーは[kubelogin](https://github.com/int128/kubelogin)をインストールします。 ``` brew tap int128/kubelogin brew install kubelogin ``` `kubelogin`でログインします。 ``` kubelogin --insecure-skip-tls-verify ``` kubectl pluginに対応しているので、`kubectl login`でも利用可能です。 ``` kubectl login --insecure-skip-tls-verify ``` UAAのログイン画面がWebブラウザで自動で開きます。 ![image](https://user-images.githubusercontent.com/106908/45886776-eff0b680-bdf4-11e8-88fe-c8181fe083b1.png) ![image](https://user-images.githubusercontent.com/106908/45886808-06970d80-bdf5-11e8-87f9-a2f4d8b63fc6.png) ![image](https://user-images.githubusercontent.com/106908/45886815-0b5bc180-bdf5-11e8-91f4-73ac51387ad5.png) 次のようなログが出力されます。 ``` 2018/09/21 23:04:04 Reading ~/.kube/config 2018/09/21 23:04:04 Using current-context: demo 2018/09/21 23:04:04 Open http://localhost:8000 for authorization 2018/09/21 23:04:05 GET / 2018/09/21 23:04:24 GET /?code=j6Nob0u8a1&state=74d6d46531b2a620 2018/09/21 23:04:24 Got token for subject=f01a100c-e730-42a0-abf9-88c93606efa2 2018/09/21 23:04:24 Updated ~/.kube/config ``` `id-token`と`refresh-token`が`~/.kube/config`に自動で追加されます。 ```yaml apiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJTi.... server: https://demo.pks.example.com:8443 name: demo contexts: - context: cluster: demo user: demo@example.com name: demo current-context: demo users: - name: demo@example.com user: auth-provider: config: client-id: pks_cluster_client cluster_client_secret: "" id-token: eyJhbGciOiJSUzI1NiIsImtp.... idp-issuer-url: https://api.pks.example.com:8443/oauth/token refresh-token: eyJhbGciOiJSUzI1NiI.... name: oidc ``` あとはPKSクラスタ管理者が`RoleBinding`の設定をすればOKです。 例: ```yaml apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata: name: edit-binding namespace: demo roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: edit subjects: - kind: User name: demo@example.com namespace: demo ``` --- `uaac`コマンドを使わずにOpsManagerのapply changesでUAA ClientをアップデートするHackを紹介します。 このやり方だと、PKSアップデートのタイミングで`pks_cluster_client`がオーバーライドされてもその後からさらに更新をかけることができます。 次のようなRuntime Configを作成します。 ```yaml cat <<'EOF' > support-kubelogin.yml releases: - name: os-conf version: "20.0.0" url: "https://bosh.io/d/github.com/cloudfoundry/os-conf-release?v=20.0.0" sha1: "a60187f038d45e2886db9df82b72a9ab5fdcc49d" addons: - name: support-kubelogin jobs: - name: pre-start-script release: os-conf properties: script: | #!/bin/bash echo "Waiting until UAA is up" until $(curl --output /dev/null -k --silent --head --fail https://((pks_api_hostname)):8443/info); do printf '.' sleep 5 done ACCESS_TOKEN=$(curl -s -u ((uaa_client_id)):((uaa_client_secret)) -k https://((pks_api_hostname)):8443/oauth/token -d grant_type=client_credentials | sed -n 's/.*access_token":"\([^"]*\).*/\1/p') curl -k https://((pks_api_hostname)):8443/oauth/clients/pks_cluster_client -X PUT \ -H "Content-Type: application/json" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -d '{ "client_id" : "pks_cluster_client", "authorized_grant_types" : [ "password", "refresh_token", "authorization_code" ], "redirect_uri" : [ "http://localhost:8000" ] }' include: jobs: - name: kube-apiserver release: kubo EOF ``` `service_admin_client`など、`clients.admin` authorityを持ったUAAクライアントの情報を設定します。 `service_admin_client`のClient CredentialはOpsManagerから取得できます。 ![image](https://user-images.githubusercontent.com/106908/52913677-c2585c80-3303-11e9-98a6-e9f49f33d50e.png) ``` bosh -n update-runtime-config --name=support-kubelogin support-kubelogin.yml -v pks_api_hostname=api.pks.example.com -v uaa_client_id=service_admin_client -v uaa_client_secret= --no-redact ``` でOps ManagerでApply Changes。