kubernetesがサポートする認証方法の全パターンを動かす

この記事は、「[Kubernetes Advent Calendar 2016](http://qiita.com/advent-calendar/2016/kubernetes)」18日目の記事です

ここでは Kubernetes がサポートする認証方法全てを手元で試してみたいと思います。
機能の説明は書いてあるが実際の使い方まで詳しく書いておらず、使い方がわからないものがあったりしたのでこれを機に全パターン確認してみます。

また、この記事は `kubernetes: 1.4.6` および `minikube: v0.13.1` で確認しています。

まずは簡単に kubernetes における認証の流れについておさらいしておきます。

kubernetes においては、ユーザーからコンテナの操作要求(CLIなどを使って)を受け取ると、クラスタを利用可能なユーザーであるかを認証し、利用可能な操作を認可で確認するというのが基本的な認証・認可の流れになります。(+ AdmissionControl もある)

また、このときの認証方法は複数組み合わせることが可能です。例えば、 X.509 証明書を使った認証と Static Toke File を組み合わせるといった感じです。それぞれが別々のオプションになっているので、指定された分だけ有効になります。それぞれ、用途によって必要な分だけ有効化するとよいです。

下記にそれぞれひつ有効化の方法とクライアントが認証してもらうために必要な設定を整理してみました。

### X.509 Client Certs
デジタル証明書を使ってユーザを認証する方法です。 kube-apiserver の引数に ``` --client-ca-file=SOMEFILE ``` を与えます。
証明書が正しく検証された場合、証明書のサブジェクトの `CN` がユーザ名として使用されます。

#### Example

kube-apiserverの引数に下記を追加します。

```
--client-ca-file=/etc/kubernetes/ca.crt
```

minikube を使ってテストする場合は下記を追加して start します。

```
--extra-config=apiserver.ClientCAFile=/path/to/ca.crt
```

クライアント側の準備として、設定ファイルにさきほどのクライアント証明書の情報とそれを利用するコンテキストの設定をします。

```
$ kubectl config set-credentials kubelet --client-certificate=/etc/kubernetes/ca.crt --client-key=/etc/kubernetes/ca.key
$ kubectl config set-context minikube-client-ca --cluster=minikube --user=hiyosi
```

上記で作成したコンテキストを使ってポッドの情報を取得してみます。

```
$ kubectl config use-context minikube-client-ca
$ kubectl get pods
=>　正しく取得できることを確認
```

### Static Token File
あらかじめファイルに記載されたトークンによりユーザを認証する方法です。 kube-apiserver の引数に ```--token-auth-file=SOMEFILE``` を与えます。引数の値として以下のような形式で定義されたファイルを渡します。

```
token,user,uid,"group1,group2,group3"
```

#### example

kube-apiserverの引数に下記を追加します。

```
--token-auth-file="/etc/kubernetes/static-token.csv"
```

minikube を使ってテストする場合は下記を追加して start します。

```
--extra-config=apiserver.TokenAuthFile=/path/to/static-token.csv
```

ここで上記 `static-token.csv` ファイルは下記のように記述されているとします。

```
31ada4fd-adec-460c-809a-9e56ceb75269,hiyosi,2001,"group1,group2,group3"
```

クライアント側の準備として、設定ファイルにさきほどのユーザ情報とそれを利用するコンテキストの設定をします。

```
$ kubectl config set-credentials hiyosi --token=31ada4fd-adec-460c-809a-9e56ceb75269
$ kubectl config set-context minikube-static-token --cluster=minikube --user=hiyosi
```

上記で作成したコンテキストを使ってポッドの情報を取得してみます。

```
$ kubectl config use-context minikube-static-token
switched to context "minikube-static-token".
$ kubectl get pods
=> 正しく取得できることを確認する
```

### Static Password File
先ほどのトークンと同じようにあらかじめファイルに記載されたユーザ名とパスワードによりユーザを認証します。 kube-apiserver に対して引数 ``` basic-auth-file ``` を与えます。引数の値として以下のような形式で定義されたパスワードファイルを渡します。

```
password,user,uid
```

#### example

kube-apiserverの引数に下記を追加します。

```
--basic-auth-file="/etc/kubernetes/static-password.csv"
```

minikube を使ってテストする場合は下記を追加して start します。

```
--extra-config=apiserver.BasicAuthFile=/path/to/static-password.csv
```

ここで上記 `static-password.csv` ファイルは下記のように記述されているとします。

```
Hogehoge,hiyosi,2001
```

クライアント側の準備として、設定ファイルにさきほどのユーザ情報とそれを利用するコンテキストの設定をします。

```
$ kubectl config set-credentials hiyosi --username=hiyosi --password=Hogehoge
$ kubectl config set-context minikube-static-password --cluster=minikube --user=hiyosi
```

上記で作成したコンテキストを使ってポッドの情報を取得してみます。

```
$ kubectl use-context hiyosi
$ kubectl get pods
=> 正しく取得できていることを確認する
```

### Service Account Tokens

Service Account Token はデフォルトで有効になっているようなので、利用するために特別必要なパラメータは必要ありません。
オプショナルなパラメータとして以下があります。
 
- ` --service-account-key-file `
  - A file containing a PEM encoded key for signing bearer tokens. If unspecified, the API server’s TLS private key will be used.
- ` --service-account-lookup `
  -  If enabled, tokens which are deleted from the API will be revoked.

#### example

サービスアカウントを作成します。

```
$ kubectl create serviceaccount test-sv-account
```

サービスアカウントが作成されたことを確認します。

```
$ kubectl get serviceaccount test-sv-account -o yaml
```

上記の結果より、`secrets` 配下の `name` の値を確認します。

```
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: 2016-12-06T08:49:42Z
  name: test-sv-account
  namespace: default
  resourceVersion: "6607"
  selfLink: /api/v1/namespaces/default/serviceaccounts/test-sv-account
  uid: ee443ef1-bb90-11e6-b0c2-f2228bfbd4f6
secrets:
- name: test-sv-account-token-61knx
```

次にその `name` 値のシークレット情報を取得します。 

```
$ kubectl get secret test-sv-account-token-61knx -o yaml
```

上記の結果より、`data` 配下の `token` の値を確認します。

```
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwdGFXNXAKYTNWaVpVTkJNQjRYRFRFMk1URXhNVEEzTlRReU1Wb1hEVEkyTVRFd09UQTNOVFF5TVZvd0ZURVRNQkVHQTFVRQpBeE1LYldsdWFXdDFZbVZEUVRDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTEplClQwQWtiS0JOdEVReXFNTjJDR25yYlBCZzF0MlNSWllaQkJJTmFrNHNTUUVBOVdJWnRlREVXK3l3YWNOZGNJRm8KZ3AyQUhyRzB6Y0tWVGZzRC9ZWHNaWkRlRHp0ZHR6NkcxZmIxL2dsRWZ0WTJ2Wlh2L2xlUENwbG1YNFJnclc1UApubVBINnlJYVJIekRrbFVYTHBpVUZQaWpzZVZzTnp2blkzNjBYWjRsODhLSXV0RnlHdkYrVDJVQmxBMWpxRDN3CnVtVWFrM0xWNnNFNkhZdkw4YlpyeWJqbVFhYi81anRXSENNVlIraWtDVDd2UlRDTUg2QkdJRlVEZ09IcCtXNzkKV0NsVGJDeUw4bDJ5cUVYQXp5V0oxaDBJTnFRK3BOR2Z2NWNPZUhZejA0SlJUL1VnNVpQRm55VWR2Sm4zNTh1NApIelNrWnN4Y1F2ZCtpNUlvK2JjQ0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUIwR0ExVWRKUVFXCk1CUUdDQ3NHQVFVRkJ3TUNCZ2dyQmdFRkJRY0RBVEFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFCUkMwS1FtdnhNOVkvUGJZVDlzaEY0SlJCT0NoSFFodGkyQkovai9za1hYK0R4czdaSgpMYm1sNmFuWlQxa1djc1RRQ1Zyb0xPcTRRd1NwY0p3UHJHK25wS2F4K1Uwa1pIN2pKQ3crTFBaV2RvMGJCcXZICnMvRXh0TnR4WEZycEljRkQvVFQxM1ZyekRaRkVuY0RJUFdGTUE5bWJNNTRHWU5STHhtMDdjWk5MWlFNZTJIVUEKU0VuaEpPWU1rLzB3TkYyOU9ObXpEK2M2d2x4OEhqU1VhYVhWaldxMUtpZDVOMVkwZ04wZXlNK3h4TStVOFZMcQpHVWlhM2l1UWcwSXAwKzlISjJoUW5VcC9weW8zRlJHQkx1ZFZ6MlgvMDJFdXVUVllueEJPUkVDUjhoWVR3UURMClVoSUdXL050SVpoemhwV2pzdmtMQllUQlFpcUtIbUlrSENNSwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
  namespace: ZGVmYXVsdA==
  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJblI1Y0NJNklrcFhWQ0o5LmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWldaaGRXeDBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5elpXTnlaWFF1Ym1GdFpTSTZJblJsYzNRdGMzWXRZV05qYjNWdWRDMTBiMnRsYmkwMk1XdHVlQ0lzSW10MVltVnlibVYwWlhNdWFXOHZjMlZ5ZG1salpXRmpZMjkxYm5RdmMyVnlkbWxqWlMxaFkyTnZkVzUwTG01aGJXVWlPaUowWlhOMExYTjJMV0ZqWTI5MWJuUWlMQ0pyZFdKbGNtNWxkR1Z6TG1sdkwzTmxjblpwWTJWaFkyTnZkVzUwTDNObGNuWnBZMlV0WVdOamIzVnVkQzUxYVdRaU9pSmxaVFEwTTJWbU1TMWlZamt3TFRFeFpUWXRZakJqTWkxbU1qSXlPR0ptWW1RMFpqWWlMQ0p6ZFdJaU9pSnplWE4wWlcwNmMyVnlkbWxqWldGalkyOTFiblE2WkdWbVlYVnNkRHAwWlhOMExYTjJMV0ZqWTI5MWJuUWlmUS5IR2Rrby1mblVSZUVEc3pOeWM4cEEwTUNZQjhPZWZIYzRFR0M4U2JDTGFKVHB2WC1leXJPMGNIc1N4RHBoVUJUM3NOUWpicW5Sbk5nUjloTkdXbW9NbkQzcmZWdUhvSmEwSEtfcWJEUE5EM0NjVlQxRnpUd0JvTWhoV0U0OV90ZWVFcGZuUXliS0llaHVmd0ZHam5iVVdnaTZDNHZFLWxpR3JUMWtkb2FhVEZ4ZGQ3MFlwTFNRU2hkQ1lqQzNCRHp6dkxvbEpwdXo2R2pkM2k5Nkw2SWhfWkhaQmFXeXB3cG1tamZiS3dmSnVfSVFZdDQ3cUxONHlVM1ZKNEtLeE5Fa2NrcXY3cGNweHIzTXIyOGZSakgyUERLcTBhY014cEgwVjAxSXgwczFKR3h2NDd3UWNqbGNHYVNBUllNaWdyVC1uNnhlLTRvaG1ITU12RzFGZGh5bUE=
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: test-sv-account
    kubernetes.io/service-account.uid: ee443ef1-bb90-11e6-b0c2-f2228bfbd4f6
  creationTimestamp: 2016-12-06T08:49:42Z
  name: test-sv-account-token-61knx
  namespace: default
  resourceVersion: "6606"
  selfLink: /api/v1/namespaces/default/secrets/test-sv-account-token-61knx
  uid: ee451e2b-bb90-11e6-b0c2-f2228bfbd4f6
type: kubernetes.io/service-account-token
```

上記 `token` の値がクライアント側にセットするトークンになるので、以下のコマンドを実行してコンテキストを作成します。
`token` の値は base64 エンコーディングされていますが、`kubectl` でセットする際にはデコードした値を使います。

```
$ kubectl config set-credentials test-sv-account --token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InRlc3Qtc3YtYWNjb3VudC10b2tlbi02MWtueCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJ0ZXN0LXN2LWFjY291bnQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJlZTQ0M2VmMS1iYjkwLTExZTYtYjBjMi1mMjIyOGJmYmQ0ZjYiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDp0ZXN0LXN2LWFjY291bnQifQ.HGdko-fnUReEDszNyc8pA0MCYB8OefHc4EGC8SbCLaJTpvX-eyrO0cHsSxDphUBT3sNQjbqnRnNgR9hNGWmoMnD3rfVuHoJa0HK_qbDPND3CcVT1FzTwBoMhhWE49_teeEpfnQybKIehufwFGjnbUWgi6C4vE-liGrT1kdoaaTFxdd70YpLSQShdCYjC3BDzzvLolJpuz6Gjd3i96L6Ih_ZHZBaWypwpmmjfbKwfJu_IQYt47qLN4yU3VJ4KKxNEkckqv7pcpxr3Mr28fRjH2PDKq0acMxpH0V01Ix0s1JGxv47wQcjlcGaSARYMigrT-n6xe-4ohmHMMvG1FdhymA
$ kubectl config set-context minikube-serviceaccount-token --cluster=minikube --user=test-sv-account
```

上記で作成したコンテキストを使ってポッドの情報を取得してみます。

```
$ kubectl config use-context minikube-serviceaccount-token 
$ kubectl get pods
=> 正しく取得できていることを確認する
```

### OpenID Connect Tokens

これは OpenID　Connect の ID トークンによって認証してもらいます。 kubernetes がプロバイダになるわけではなく、外部プロバイダによって認証され、その結果を kubernetes に渡すイメージです。これは kube-apiserver に対して以下の引数を与えます。

- `--oidc-issuer-url`
  - OpenID Connect プロバイダの URL. (e.g. https://accounts.google.com )
- `--oidc-client-id`
  - OpenID Connect プロバイダから事前に発行済みのクライアントID
- `--oidc-ca-file`
  - API サーバーが OpenID Connect プロバイダとの安全な接続を確立して検証するために使用します。デフォルトはホストのルートCAです。

以下は Experimental です。

- `--oidc-username-claim`
  - デフォルトではユーザ名として JWT の `sub` クレームが利用されるが、別のクレーム値を利用したい場合に指定
- `--oidc-groups-claim`
  - ユーザが所属するグループを表すクレーム名を指定します。文字列の配列の形式である必要があります。

#### Example

kube-apiserver の引数に以下を追加します。

``` 
--oidc-issuer-url=https://op.example.com --oidc-client-id=323f821025127910eff78b1fee4bbaf7 --oidc-ca-file=/etc/kubernetes/cert.pem 
``` 

minikube を使ってテストする場合は下記を追加して start します。

```
--extra-config=apiserver.OIDCIssuerURL=https://op.example.com --extra-config=apiserver.OIDCClientID= 323f821025127910eff78b1fee4bbaf7 --extra-config=apiserver.OIDCCAFile=/path/to/ca.pem
```

OpenID Connect プロバイダで認証後に発行される IDトークンをクレデンシャル情報としてセットします。
また、その他トークンのリフレッシュに必要な refresh_token の情報もセットします。

OpenID Connect まわりのパラメータはまだ公式ドキュメントに反映されていませんが、
http://qiita.com/superbrothers/items/3c4e3fc651e9b3e9ef02
こちらの記事でパラメータについての解説がされていますので、各パラメータについて知りたい方は参照してみてください。

```
$ kubectl config set-credentials hiyosi --token=<... id token ...> --auth-provider=oidc --auth-provider-arg=client-id=323f821025127910eff78b1fee4bbaf7 --auth-provider-arg=client-secret=9926aa8a396c616ac33b6f947b38b9a2 --auth-provider-arg=idp-certificate-authority=/etc/kubernetes/idp.crt --auth-provider-arg=refresh-token=<...refresh token...>
$ kubectl config set-context minikube-oidc --cluster=minikube --user=hiyosi
```

上記で作成したコンテキストを使ってポッドの情報を取得してみます。

```
$ kubectl config use-context minikube-oidc
$ kubectl get pods
=> 正しく取得できていることを確認する
```


### Webhoook Token Authentication

Webhook Token Authentication はクライアントから与えられたトークンをリモートサーバに問い合わせ、その結果を使って認証可否を判断するような挙動になります。

kube-apiserver に対して以下の引数を与える必要があります。

- `--authentication-token-webhook-config-file`
  - リモート webhook サービスの設定
- `--authentication-token-webhook-cache-ttl` (OPTIONAL)
  - デフォルト 2 min
- `--runtime-config=authentication.k8s.io/v1beta1=true`
  - 利用中の Kuberenetes のバージョンによっては指定する必要があると思います

config ファイルは以下のように `kubeconfig` と同じフォーマットです

```
# clusters refers to the remote service.
clusters:
  - name: name-of-remote-authn-service
    cluster:
      certificate-authority: /path/to/ca.pem         # CA for verifying the remote service.
      server: https://authn.example.com/authenticate # URL of remote service to query. Must use 'https'.

# users refers to the API server's webhook configuration.
users:
  - name: name-of-api-server
    user:
      client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
      client-key: /path/to/key.pem          # key matching the cert

# kubeconfig files require a context. Provide one for the API server.
current-context: webhook
contexts:
- context:
    cluster: name-of-remote-authn-service
    user: name-of-api-sever
  name: webhook
```

#### example

kube-apiserver の引数に以下を追加します。

`--authentication-token-webhook-config==/etc/kubernetes/webhook.config --runtime-config=authentication.k8s.io/v1beta1=true`

```webhook.config:yaml
clusters:
  - name: name-of-remote-authn-service
    cluster:
      server: http://192.168.99.1:5000/auth

# 今回はクライアント認証使わないのでコメントアウト
# users:
#   - name: name-of-api-server
#     user:
#      client-certificate: /Users/tousami/Documents/adv-cal/server.crt
#       client-key: /Users/tousami/Documents/adv-cal/server.key

current-context: webhook
contexts:
- context:
    cluster: name-of-remote-authn-service
    user: name-of-api-sever
  name: webhook
```

クライアント側の準備として、設定ファイルにトークンを利用するユーザ情報とそれを利用するコンテキストの設定をします。

```
$ kubectl config set-credentials hiyosi --token=31ada4fd-adec-460c-809a-9e56ceb75269
$ kubectl config set-context minikube-webhook --cluster=minikube --user=hiyosi
```

上記で作成したコンテキストを使ってポッドの情報を取得してみます。

```
$ kubectl config use-context minikube-static-token
switched to context "minikube-static-token".
$ kubectl get pods
=> 正しく取得できることを確認する
```

また、 curl コマンドを使って以下のように確認することもできます。

```
$ curl -H 'Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269' -X GET https://<kube-apiserverのアドレス>/api/v1/nodes
```

リモートサーバ側は kube-apiserver からの問い合わせに対して、以下のように応答する必要があります。

- 問い合わせ

```json
POST <PATH> HTTP/1.1
{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "spec": {
    "token": "(BEARERTOKEN)"
  }
}
```

- 成功

```json
{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "status": {
    "authenticated": true,
    "user": {
      "username": "janedoe@example.com",
      "uid": "42",
      "groups": [
        "developers",
        "qa"
      ],
      "extra": {
        "extrafield1": [
          "extravalue1",
          "extravalue2"
        ]
      }
    }
  }
}
```

- 失敗

```json
{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "status": {
    "authenticated": false
  }
}
```


### Autenticating Proxy

Authenticating Proxy は kube-apiserver の前段に認証処理を肩代わりしてくれるような Proxy サーバを設定する構成を想定しています。

有効にするにはkube-apiserver に対して以下の引数を与える必要があります。

- `--requestheader-username-header`
    - ユーザ名とし利用するヘッダ名。複数指定されていた場合には先頭が優先される。
- `--requestheader-client-ca-file`
    - クライアント証明書。ヘッダ名を取得する前に証明書の検証を実施する。
- `--requestheader-allowed-name` (OPTIONAL)
    - CN名のリスト。指定されていた場合には、指定されたリストのCNを持つ有効なクライアント証明書を提示する必要がある。

#### example

kube-apiserver に以下のオプションを追加します。

```
--requestheader-username-header=X-K8S-Remote-User --requestheader-client-ca-file=/path/to/ca.crt
```

minikube を使ってテストする場合には以下のオプションを追加して start します。

```
--extra-config=apiserver.RequestHeaderUsernameHeaders=X-K8S-Remote-User  --extra-config=apiserver.RequestHeaderClientCAFile=/path/to/ca.crt
```

しかし今回テストで使用しているバージョンの minikube ではこのオプションに対応していないようで、認証が成功するところまで確認できませんでした。`k8s-v1.5` のブランチには該当オプションは存在しているようだったので、 `k8s-v1.5` ブランチをビルドして試してみましたが、こちらでもまだ動かないようでした。(https://github.com/kubernetes/minikube/blob/k8s-v1.5/vendor/k8s.io/kubernetes/pkg/genericapiserver/options/server_run_options.go#L107-L108)

```
2937 localkube.go:116] Setting RequestHeaderUsernameHeaders to X-Remote-User on apiserver.
2937 localkube.go:118] Unable to set RequestHeaderUsernameHeaders to X-Remote-User. Error: Unable to find field by name: RequestHeaderUsernameHeaders
```

仮に正しく動いていた場合には以下のように、認証後のプロキシサーバのように振る舞うことで動作確認ができるのかなと思います。

```
curl  --key /etc/kubernetes/ca.key --cert /etc/kubernetes/ca.crt  -H "X-K8s-Remote-User: hiyosi" https://192.168.99.100:8443/api/v1/nodes
```

また、  `kubectl` コマンドには proxy サーバが求める認証に対しての設定を入れてやる必要があるのかなと思います。(ちゃんと試せていないのでよくわからない)

```
$ kubectl config set-credentials hiyosi --username=hiyosi <それぞれの認証方法をセット>
$ kubectl config set-context minikube-proxy --cluster=minikube --user=hiyosi
$ kubectl config use-context minikube-proxy
```

### Keystone Password

これは OpenStack の認証コンポーネントである keystone に認証を依頼するような方式になります。 kube-apiserver には以下の引数を与えます。

- `--experimental-keystone-url`
  - OpenStack Keystone の URL
- `--experimental-keystone-ca-file`
  - KeyStone サーバの証明書を検証するための証明書

##### example

kube-apiserver の引数に下記を追加します。

```
--experimental-keystone-url=https://localhost:35357/v2.0 --experimental-keystone-ca-file=/etc/kubernetes/keystone.crt
```

minikube を使っている場合には以下のような形になりそうです。(今後変更されるかもしれないので今後も同じように指定できるかは不明です)

```
--extra-config=apiserver.KeystoneURL=https://localhost:35357/v2.0  --extra-config=apiserver.KeystoneCAFile=/etc/kubernetes/keystone.crt 
```

しかし残念ながらこのオプションも現在は動かないように見えました。 過去には https://techblog.yahoo.co.jp/infrastructure/k8s_on_os/ のような記事もあるので、正しく連携できているときもあったのだとは思います。現在は minikube の環境がダメなのか、ちょっと上手くいきません。

```
keystone.go:46] Failed: Starting openstack authenticate client
handlers.go:37] Unable to authenticate the request due to an error: Failed to authenticate
```

エラーメッセージを調べていると以下の issue がありましたが、私の環境では v2 でも v3 でもどちらも同じようなエラーで連携できませんでした。

https://github.com/kubernetes/kubernetes/issues/25066

仮に動いていたとすると、基本的には basic 認証の挙動をするので以下のように設定してあげることで確認できたのではないかと思います。

```
$ kubectl config set-credentials hiyosi --username=hiyosi --password=fugafuga
$ kubectl config set-context minikube-keystone --cluster=minikube --user=hiyosi
$ kubectl config use-context minikube-keystone
```

### まとめ

最後の２つが上手く動作しなかったために、ちょっと消化不良な感じに終わってしまいました。
minikube のリポジトリに入っている kubernetes は若干古かったのですが、先日リリースされた 最新版(v1.5.0)で試せば動くものもあるかもしれません。