v0.11.0から導入されたSecret APIを試してみます。試したのは15/03/08時点のHEADです。
Secret APIは名前の通りSSHの秘密鍵やパスワードなどの秘密データを保存するためのAPIです。主な目的はPodが秘密データを安全に取得して利用できるようにするためのものです。Pod(Node)にデータを配布する方法は自由にできるようにプラグイン形式になっているようです。現在はetcdに保存して取得するものが実装されています。詳しいことはドキュメントを読みましょう。導入の経緯はこのあたりですPR4126, PR4514。
秘密データを保存する
Secret APIの使い方はまともなドキュメントがまだないですが、一番それらしいのはopenshiftのexampleの中にあります。
フォーマットとしては以下のようにkindにSecret
を指定してdataに複数の秘密データを入れておきます。dataのvalueにはbase64で入れる必要があります。
# secret.yml
apiVersion: v1beta1
kind: Secret
id: kubernetes-secret
data:
foo: _secret-data-1_
bar: _secret-data-2_
今回はfooのデータとしてfoo-secret
、barのデータとしてbar-secret
を入れることにします。
$ echo -n foo-secret | base64 --wrap=0
Zm9vLXNlY3JldA==
$ echo -n bar-secret | base64 --wrap=0
YmFyLXNlY3JldA==
$ cat secret.yml
apiVersion: v1beta1
kind: Secret
id: kubernetes-secret
data:
foo: Zm9vLXNlY3JldA==
bar: YmFyLXNlY3JldA==
あとはkubectl create
で作成するだけです。
$ kubectl create -f secret.yml
kubernetes-secret
データはetcdに入っています。もちろん暗号化はされていません。
$ etcdctl --no-sync ls --recursive /registry/secrets/
/registry/secrets/default
/registry/secrets/default/kubernetes-secret
$ etcdctl --no-sync get /registry/secrets/default/kubernetes-secret | jq .
{
"type": "Opaque",
"data": {
"foo": "Zm9vLXNlY3JldA==",
"bar": "YmFyLXNlY3JldA=="
},
"namespace": "default",
"apiVersion": "v1beta1",
"creationTimestamp": "2015-03-08T08:26:04Z",
"uid": "c2d4db23-c56c-11e4-8d70-08002763b728",
"id": "kubernetes-secret",
"kind": "Secret"
}
あとヘルプには出てこないですが実はkubectlからも参照できます。削除もkubectl delete secrets
で可能です。
$ kubectl get secrets
NAME DATA
kubernetes-secret 2
$ kubectl get secrets kubernetes-secret -o json
{
"kind": "Secret",
"id": "kubernetes-secret",
"uid": "c2d4db23-c56c-11e4-8d70-08002763b728",
"creationTimestamp": "2015-03-08T08:26:04Z",
"selfLink": "/api/v1beta1/secrets/kubernetes-secret?namespace=default",
"resourceVersion": 7621,
"apiVersion": "v1beta1",
"namespace": "default",
"data": {
"bar": "YmFyLXNlY3JldA==",
"foo": "Zm9vLXNlY3JldA=="
},
"type": "Opaque"
}
Podから参照する
ちなみに以下の方法では動きませんでした。
PodからSecretを参照する方法もいくつか用意(プラグイン)するようですが、今あるのはボリュームとしてマウントする方法のみです。
examples/guestbook/redis-master-controller.json
を少し修正してSecretを使うように書き換えます。ポイントはcontainerからは単にボリュームをマウントするようにするのと、volumesのソースにsecret
を指定することです。
# redis.yml
apiVersion: v1beta1
kind: ReplicationController
id: redis-master-controller
desiredState:
replicas: 1
replicaSelector:
name: redis-master
podTemplate:
desiredState:
manifest:
version: v1beta1
id: redis-master
containers:
- name: redis-master
image: dockerfile/redis
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /etc/secret-volume
name: secret-volume
readOnly: true
volumes:
- name: secret-volume
source:
secret:
target:
kind: Secret
name: kubernetes-secret
namespace: default
labels:
name: redis-master
app: redis
labels:
name: redis-master
$ kubectl create -f sample/redis.yml
redis-master-controller
$ kubectl get po
POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS CREATED
redis-master-controller-i7hvs 10.244.87.6 redis-master dockerfile/redis 172.17.8.103/172.17.8.103 app=redis,name=redis-master Running 6 seconds
172.17.8.103
はnode-02
なのでdocker containerに直接アクセスしてマウントされているか確認します。
$ ssh node-02 'docker ps'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7f255ec5f83 dockerfile/redis:latest "redis-server /etc/r 48 seconds ago Up 47 seconds k8s_redis-master.810715e9_redis-master-controller-i7hvs.default.api_6abb1233-c56e-11e4-8d70-08002763b728_1cfff4fb
3d00a7472b66 kubernetes/pause:go "/pause" 48 seconds ago Up 47 seconds k8s_POD.5efe987_redis-master-controller-i7hvs.default.api_6abb1233-c56e-11e4-8d70-08002763b728_709dd17a
1d0c5a165143 google/cadvisor:0.10.1 "/usr/bin/cadvisor - 2 hours ago Up 2 hours 8080/tcp, 0.0.0.0:4194->4194/tcp cadvisor
## inspectでマウントされているか確認する
$ ssh node-02 'docker inspect b7f255ec5f83' | jq '.[].Volumes'
{
"/etc/secret-volume": "/var/lib/kubelet/pods/6abb1233-c56e-11e4-8d70-08002763b728/volumes/kubernetes.io~empty-dir/secret-volume",
"/dev/termination-log": "/var/lib/kubelet/pods/6abb1233-c56e-11e4-8d70-08002763b728/containers/redis-master/b7f255ec5f83c777472a589b6ff899f91b2210f509bea1eca35cebb82e93ac92",
"/data": "/var/lib/docker/vfs/dir/e1c55258f2e650ed631801a9ed1161f9065f12ebac726b4349e3894fd33d37bf"
}
## execでマウントの中身を見る
$ ssh node-02 'docker exec b7f255ec5f83 ls -al /etc/secret-volume'
total 8
drwxr-x--- 2 root root 4096 Mar 7 16:10 .
drwxr-xr-x 1 root root 4096 Mar 7 16:10 ..
というわけでマウントはできたけど、Secretはうまくとれなかったです。原因までは今回は調べていません。できていればファイルとしてSecretが保存されているので、アプリケーションからはそれを自分で読んで使うというスタイルになります。
自分で消化するのではなく環境変数としてexportする機能も追加される予定です(PR4710)。
15/03/21追記
再度最新版で確認したところ無事秘密データがマウントされていました。
$ ssh node-01 'docker exec 7d5aa958003f ls -al /etc/secret-volume'
total 12
drwxrwxrwt 2 root root 80 Mar 21 10:33 .
drwxr-xr-x 1 root root 4096 Mar 21 10:33 ..
-rwxr-xr-x 1 root root 10 Mar 21 10:34 bar
-rwxr-xr-x 1 root root 10 Mar 21 10:34 foo
$ ssh node-01 'docker exec 7d5aa958003f cat /etc/secret-volume/bar'
bar-secret
$ ssh node-01 'docker exec 7d5aa958003f cat /etc/secret-volume/foo'
foo-secret