repl.info

cloud-provider-openstackを使って、keystoneでk8sのユーザー認証を行う

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を使っていて困っていないので認証だけでいいかな、という気持ち。