v1.10より前のバージョンだと、apiserverででexperimental-keystone-url オプションを設定し、クライアントのkubeconfigでユーザー名とパスワードを設定すればkeystone認証できていた。しかし、v1.10ではこのオプションが削除されたため、別の方法としてcloud-provider-openstackを使う。このリポジトリはいろいろ混ざっていてややこしく、LBaaSやCinderとの連携機能についても提供している(別コマンド)。
さて、cloud-provider-openstackを使ってkeystoneによるユーザー認証を実現するにはクライアント側、サーバー側それぞれで設定が必要になる。クライアント側ではKeystoneからトークンを取得し、apiserverへ送る。サーバー側であるapiserverでは受け取ったトークンを使ってkeystoneに問い合わせ、そのトークンがユーザーが発行したものであることを確認する。
まずはクライアント側の設定についてだが、cloud-provider-openstackからclient-keystone-authをダウンロードし(ビルドしてもOK)、実行可能なPATHに配置する。そして、kubeconfigのユーザーとして以下のような設定を追加、コンテキストとして利用できるようにする。
users: - name: username user: exec: apiVersion: client.authentication.k8s.io/v1beta1 command: "/path/to/client-keystone-auth" env: - name: "OS_USERNAME" value: "username" - name: "OS_PASSWORD" value: "password" - name: "OS_PROJECT_NAME" value: "project_name" args: - "--domain-name=default" - "--keystone-url=https://openstack.repl.info/auth/v3"
次にサーバー側だが、apiserverでwebhookを有効にし、webhook先をk8s-keystone-authにする。
--authentication-token-webhook-config-file=/etc/kubernetes/webhookconfig.yaml
webhookconfig.yamlは以下の通り。10.233.0.3はk8s-keystone-auth用のサービスが持つClusterIPを指定する。
--- apiVersion: v1 kind: Config preferences: {} clusters: - cluster: insecure-skip-tls-verify: true server: https://10.233.0.3:8443/webhook name: webhook users: - name: webhook contexts: - context: cluster: webhook user: webhook name: webhook current-context: webhook
k8s-keystone-authはDeploymentとして動かしておく。
--- apiVersion: v1 kind: ConfigMap metadata: name: k8s-auth-policyk8s-keystone-auth-config namespace: kube-system data: policies: | [ { "resource": { "verbs": ["get", "list", "watch"], "resources": ["pods"], "version": "*", "namespace": "default" }, "match": [ { "type": "role", "values": ["k8s-viewer"] }, { "type": "project", "values": ["demo"] } ] } ] --- apiVersion: apps/v1 kind: Deployment metadata: name: k8s-keystone-auth namespace: kube-system labels: app: k8s-keystone-auth spec: replicas: 2 selector: matchLabels: app: k8s-keystone-auth template: metadata: labels: app: k8s-keystone-auth spec: containers: - name: k8s-keystone-auth image: k8scloudprovider/k8s-keystone-auth imagePullPolicy: Always args: - ./bin/k8s-keystone-auth - --tls-cert-file - /etc/kubernetes/ssl/apiserver.pem - --tls-private-key-file - /etc/kubernetes/ssl/apiserver-key.pem - --policy-configmap-name - k8s-auth-policy - --keystone-url - {{ auth_url }} volumeMounts: - mountPath: /etc/kubernetes/ssl name: kubernetes-ssl readOnly: true ports: - containerPort: 8443 volumes: - name: kubernetes-ssl hostPath: path: /etc/kubernetes/ssl --- kind: Service apiVersion: v1 metadata: name: k8s-keystone-auth-service namespace: kube-system spec: selector: app: k8s-keystone-auth clusterIP: 10.233.0.3 ports: - protocol: TCP port: 8443 targetPort: 8443
これで、v1.10以降でもKeystoneを使った認証を行うことができる。認可についても可能なようだが、今のところ認可はRBACを使っていて困っていないので認証だけでいいかな、という気持ち。