このエントリはKubernetesアドベントカレンダー2014の10日目です。
今日はクラウドの(というか情報システムの)鬼門、データストレージについてです。
Volume
4日目で紹介したとおり、dockerではデータをコンテナの管理外に出す、ホストのディレクトリをマウントする、という2つの方法でデータを外出しできます。コンテナ管理外に出したデータは他コンテナからもマウントできますが、コンテナの削除と共に消えます。
KubernetesではVolumeの種類は今のところ以下の3種類です。
EmptyDir
:docker run
するときに-v DIR
した時と似た挙動をしますHostDir
:docker run
するときに-v HOSTDIR:DIR
した時と同じ挙動をしますGCEPersistentDisk
: GCE外部ディスクです。AWSで言うところのEBSですね
似た というのが気になりますね。 詳しく見てみましょう。
動作させてみる
Kubernetesでは container manifest
で Pod
、 Service
、 ReplicationController
を定義します。
syntaxなどは以下が参考になります。
Container-optimized Google Compute Engine images - Google Compute Engine — Google Cloud Platform
今回はnginxのコンテナを作って動作を見てみます。
このファイルを /root/volumetest.yaml
として保存しておき、
kubectl
に読み込ませて Pod
を作成します。
apiVersion: v1beta1
kind: Pod
id: mynginx
desiredState:
manifest:
version: v1beta1
id: mynginx
containers:
- name: nginx
image: dockerfile/nginx
cpu: 100
memory: 50000000
ports:
- containerPort: 80
hostPort: 8000
volumeMounts:
- name: tmp
mountPath: /tmp
- name: docroot
mountPath: /usr/share/nginx/html
readOnly: true
volumes:
- name: tmp
source:
emptyDir: {}
- name: docroot
source:
hostDir:
path: /opt/kubernetes/examples/guestbook/php-redis
kubectl
で Pod
を作成します。
[root@localhost kubernetes]# cluster/kubectl.sh create pod -f /root/volumetest.yaml
mynginx
[root@localhost kubernetes]# cluster/kubectl.sh get pods
NAME IMAGE(S) HOST LABELS STATUS
mynginx dockerfile/nginx 127.0.0.1/ Running
起動できたら中をのぞいてみましょう。 とこんな感じになっています。
[root@localhost kubernetes]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3c06d3a4716e dockerfile/nginx:latest "nginx" 6 seconds ago Up 5 seconds k8s_nginx.e3acd9a9_mynginx.default.etcd_e8c242d0-7d57-11e4-9f54-080027ba52c4_7d382584
1ef629d75e17 kubernetes/pause:latest "/pause" 7 seconds ago Up 6 seconds 0.0.0.0:8000->80/tcp k8s_net.163f8d3c_mynginx.default.etcd_e8c242d0-7d57-11e4-9f54-080027ba52c4_5b914090
[root@localhost kubernetes]# docker inspect 3c06d3a4716e | jq '.[].Volumes'
{
"/var/log/nginx": "/var/lib/docker/vfs/dir/4ae5ca2d3794dc0112417f53caa11352d918b641b0a6916eae65853fd2e09a56",
"/usr/share/nginx/html": "/opt/kubernetes/examples/guestbook/php-redis",
"/tmp": "/var/lib/kubelet/mynginx/volumes/empty/tmp",
"/etc/nginx/sites-enabled": "/var/lib/docker/vfs/dir/2d688a570e7fdfa22df96bdb314b6efcf9a3b79558c6a37d656d867975dd1693",
"/etc/nginx/conf.d": "/var/lib/docker/vfs/dir/4dcdb706eae6632a45552294ae1236023d7175cc85eb06f7c9c7d9472a3ae49e",
"/etc/nginx/certs": "/var/lib/docker/vfs/dir/f1479991bfce4f14600da51d254571922818cbd0a2c30a45a2aba3d04451f9b9",
"/dev/termination-log": "/var/lib/kubelet/mynginx/nginx/3c06d3a4716ee7465c3d0afa19072c73c7cc45de571a68fc92e286e195cae05b"
}
- dockerfileで指定されたVolumeはdocker本来の領域(/var/lib/docker/vfs...)に
- Kubernetesで指定したVolume(emptyDir)はkubelet配下(default: /var/lib/kubelet)に
- Kubernetesで指定したMountVolume(hostDir)は指定したディレクトリに
マッピングされています。
1,と2の違いとしては、dockerfileで指定した領域(1)のライフサイクルはコンテナと同一ですが、 Kubernetesで指定したVolumeはライフサイクルがPodになります。 そのためコンテナを不意に停止して別のコンテナが穴埋めで起動した場合に、データを引き継ぐことができます。 似た挙動、というのはこのライフサイクルの違いになります。
現状の実装はホストマシンべったりですが、 GCEPersistentDisk
もあることですし、
EBSのような展開は期待できますね。
他にもGlusterFSなどを組み合わせることもできそうですし、いい感じになっていくのではないでしょうか!?