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

Leave a Reply

Your email address will not be published. Required fields are marked *