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