Kubernetesを理解するために、まずは動かし感覚を掴む。どんな仕組みかは後でドキュメントを読でまとめる。
環境:VirtualBox
CoreOS Alpha 845.0.0
Kernel version:4.2.2
docker version:1.8.3
CoreOSについては後日勉強。知らないことが今の時点では多いので。
1. kubernetes環境の確認
1.1. etcdが正常に動作しているか確認する。
クラスタの状態をetcdctlコマンドを使用して確認する。
$ etcdctl cluster-health
member ce2a822cea30bfca is healthy: got healthy result from http://localhost:2379
cluster is healthy
※etcdはKVSで、CoreOSを使って構成するクラスタの全ノードがアクセス可能なデータを格納するために使用される。
topレベルのKeyを確認
$ etcdctl ls
/registry
/coreos.com
valueを得るにはgetでエンドポイントを指定。ディレクトリの場合は以下のようにディレクトリと返ってくる。
$ etcdctl get /coreos.com/
/coreos.com: is a directory
以下のようにすれば全ての階層構造情報を出力できる。
etcdctl ls / --recursive
※zookeeperと似ている。
実際のデータがどのように見えるか、endpointを指定してgetする。
$ etcdctl get /coreos.com/network/config
{"Network":"10.2.0.0/16","Backend":{"Type":"vxlan"}}
1.2. kubernetesのserviceが正常に動作しているか確認する。
$ systemctl status kubelet.service
● kubelet.service
Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2015-10-29 05:52:17 UTC; 5h 21min ago
Main PID: 601 (kubelet)
Memory: 4.8M
CPU: 592ms
CGroup: /system.slice/kubelet.service
├─601 /usr/bin/kubelet --api_servers=http://127.0.0.1:8080 --register-node=true -...
└─966 journalctl -f
・・・
$ docker ps |grep kube-api
c5a23f6f1e0b gcr.io/google_containers/hyperkube:v1.0.6 "/hyperkube apiserver" 5 hours ago Up 5 hours k8s_kube-apiserver.ae2b1f58_kube-apserver-172.17.4.99_kube-system_b5fd6f0b2e57f08b39d588afd25c9206_c57e302b
864e167abf14 gcr.io/google_containers/pause:0.8.0 "/pause" 5 hours ago Up 5 hours k8s_POD.e4cc795_kube-apiserver-172.17.4.99_kube-system_b5fd6f0b2e57f08b39d588afd25c9206_c1bedd4a
1.3. kubernetesのstatusを確認する。
masterのアドレスやkubernetes.io/cluster-service=trueのラベルを持ったサービスの情報を表示する。
$ kubectl cluster-info
Kubernetes master is running at https://172.17.4.99:443
KubeDNS is running at https://172.17.4.99:443/api/v1/proxy/namespaces/kube-system/services/kube-dns
リソース情報(pods (po), replication controllers (rc), services (svc), nodes, events (ev), component statuses (cs), limit ranges (limits), nodes (no), persistent volumes (pv), persistent volume claims (pvc) or resource quotas)を表示する。
$ kubectl get nodes
NAME LABELS STATUS
172.17.4.99 kubernetes.io/hostname=172.17.4.99 Ready
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
kubeconfigの設定を表示
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority: /home/core/ssl/ca.pem
server: https://172.17.4.99:443
name: vagrant
contexts:
- context:
cluster: vagrant
user: vagrant-admin
name: vagrant
current-context: vagrant
kind: Config
preferences: {}
users:
- name: vagrant-admin
user:
client-certificate: /home/core/ssl/admin.pem
client-key: /home/core/ssl/admin-key.pem
2. Kubernetesを使って、cassandra環境の構築
http://kubernetes.io/v1.0/docs/user-guide/configuring-containers.html
http://kubernetes.io/v1.0/examples/cassandra/README.html
2.1. Podの作成
KubernetesのAPI Resource Schemaを使用して設定ファイルを作成
Kubernetesではアプリケーションの最小単位はPodなので、Podの定義をまず行う。Podは同じホスト上にスケジューリングされる。Pod内の全てのコンテナはnetwork namespaceを共有し、volumeもシェア可能(オプション)。KubernetesはPod内でコンテナを生成する。
apiVersion: v1 #現在のバージョンはv1
kind: Pod # Podについて定義することを明示
metadata:
labels:
name: cassandra # label名
name: cassandra #生成されるPodの名前。クラスタ内でuniqueでなければならない。Pod内のコンテナ名はcontainers[0].name
spec:
containers:
- args:
- /run.sh
resources:
limits:
cpu: "0.1" # cluster managerに0.1cpuを要求
image: gcr.io/google_containers/cassandra:v5 #Docker Image名。イメージはデフォルトではDocker Hubから取得
name: cassandra
ports: #外部に公開する方法とポートを定義
- name: cql #Cassandra Query Language
containerPort: 9042
- name: thrift
containerPort: 9160
volumeMounts:
- name: data
mountPath: /cassandra_data
env: #Cassandraのパラメータ
- name: MAX_HEAP_SIZE
value: 512M
- name: HEAP_NEWSIZE
value: 100M
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumes:
- name: data
emptyDir: {}
作った設定ファイルを指定してリソース(Pod)を作成する。
$ kubectl create -f cassandra.yaml
pods/cassandra
Podが作成されたかどうか確認
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
cassandra 0/1 Running 0 8s
Resourceの詳細について確認。以下はPodだがpods (po)以外に, replicationcontrollers (rc), services (svc), nodes (no), events (ev), componentstatuses (cs), limitRanges (limits), persistentVolumes (pv), persistentVolumeClaims (pvc), resourceQuotas (quota) or secretsが指定可能。
$ kubectl describe pod cassandra
Name: cassandra
Namespace: default
Image(s): gcr.io/google_containers/cassandra:v5
Node: 172.17.4.99/172.17.4.99
Labels: name=cassandra
Status: Running
Reason:
Message:
IP: 10.2.67.6
Replication Controllers: <none>
Containers:
cassandra:
Image: gcr.io/google_containers/cassandra:v5
Limits:
cpu: 100m
State: Running
Started: Fri, 30 Oct 2015 01:13:29 +0000
Ready: True
Restart Count: 0
Conditions:
Type Status
Ready True
Events:
FirstSeen LastSeen Count From SubobjectPath Reason Message
Fri, 30 Oct 2015 01:13:29 +0000 Fri, 30 Oct 2015 01:13:29 +0000 1 {scheduler } scheduled Successfully assigned cassandra to 172.17.4.99
Fri, 30 Oct 2015 01:13:29 +0000 Fri, 30 Oct 2015 01:13:29 +0000 1 {kubelet 172.17.4.99} implicitly required container POD pulled Pod container image "gcr.io/google_containers/pause:0.8.0" already present on machine
Fri, 30 Oct 2015 01:13:29 +0000 Fri, 30 Oct 2015 01:13:29 +0000 1 {kubelet 172.17.4.99} implicitly required container POD created Created with docker id 2843e181382d
Fri, 30 Oct 2015 01:13:29 +0000 Fri, 30 Oct 2015 01:13:29 +0000 1 {kubelet 172.17.4.99} implicitly required container POD started Started with docker id 2843e181382d
Fri, 30 Oct 2015 01:13:29 +0000 Fri, 30 Oct 2015 01:13:29 +0000 1 {kubelet 172.17.4.99} spec.containers{cassandra} created Created with docker id d77752ffb587
Fri, 30 Oct 2015 01:13:29 +0000 Fri, 30 Oct 2015 01:13:29 +0000 1 {kubelet 172.17.4.99} spec.containers{cassandra} started Started with docker id d77752ffb587
2.2. Serviceの作成
KubernetesではServiceは同じタスクを処理するPodの集まりとして定義される。
apiVersion: v1 #現在のバージョンはv1
kind: Service #Serviceについて定義
metadata:
labels:
name: cassandra
name: cassandra
spec:
ports:
- port: 9042
selector: #query over labels(Podsのセット). このサービスに所属するPodを選択。
name: cassandra #この例ではcassandoraというlabelが付いたPodがこのserviceに所属
Serviceを作成。
$ kubectl create -f cassandra-service.yaml
services/cassandra
Serviceが作成されているか確認
$ kubectl get services
NAME LABELS SELECTOR IP(S) PORT(S)
cassandra name=cassandra name=cassandra 10.3.0.80 9042/TCP
kubernetes component=apiserver,provider=kubernetes <none> 10.3.0.1 443/TCP
$ kubectl describe service cassandra
Name: cassandra
Namespace: default
Labels: name=cassandra
Selector: name=cassandra
Type: ClusterIP
IP: 10.3.0.80
Port: <unnamed> 9042/TCP
Endpoints: 10.2.67.6:9042
Session Affinity: None
No events.
Pod内のContainerのログを出力
$ kubectl logs cassandra
2.3. Replication Controllerの作成
Kubernetesにより、Cassandraクラスタを容易に構築、スケールすることができる。
Replication Controllerは同質のPodのセットをレプリケートする。指定するPodの数になるようPodをadd,removeする。
apiVersion: v1 #現在のバージョンはv1
kind: ReplicationController #Replication Controllerを定義
metadata:
labels:
name: cassandra
name: cassandra
spec:
replicas: 1 #replicaの数
selector: #controllerのselector query
name: cassandra
template:
metadata:
labels:
name: cassandra
spec:
containers:
- command:
- /run.sh
resources:
limits:
cpu: 0.1
env:
- name: MAX_HEAP_SIZE
value: 512M
- name: HEAP_NEWSIZE
value: 100M
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: gcr.io/google_containers/cassandra:v5
name: cassandra
ports:
- containerPort: 9042
name: cql
- containerPort: 9160
name: thrift
volumeMounts:
- mountPath: /cassandra_data
name: data
volumes:
- name: data
emptyDir: {}
Controllerを作成する
$ kubectl create -f cassandra-controller.yaml
replicationcontrollers/cassandra
Controllerが作成されているか確認する
$ kubectl get rc
CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS
cassandra cassandra gcr.io/google_containers/cassandra:v5 name=cassandra 1
$ kubectl describe rc cassandra
Name: cassandra
Namespace: default
Image(s): gcr.io/google_containers/cassandra:v5
Selector: name=cassandra
Labels: name=cassandra
Replicas: 1 current / 1 desired
Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 Failed
No events.
2.4. クラスタをスケールアウト、スケールイン
pod数を2へスケールアウトする。
$ kubectl scale rc cassandra --replicas=2
scaled
クラスタ内のpod一覧を出力し、label name=cassandraでフィルタリングする。2つのcassandra podを確認することができる。
$ kubectl get pods -l="name=cassandra"
NAME READY STATUS RESTARTS AGE
cassandra 1/1 Running 0 10h
cassandra-vb3mp 1/1 Running 0 1m
片方はreplication controllerによって生成されたランダムな文字列が付加されている。
nodetoolを使用して、正しく動作しているかクラスタの状態を調べる。kubectl execを使用し、コンテナの中でコマンドを実行。(kubectl exec POD -c CONTAINER -- COMMAND [args...])
-tでstdinをtty、-iでコンテナに対してstdinをpassする。
core@localhost ~ $ kubectl exec -ti cassandra -- nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
DN 10.2.67.7 ? 256 100.0% 186ce662-cc93-4e6c-90f2-1c58ffd5834a rack1
UN 10.2.64.3 199.82 KB 256 100.0% b5a7fb71-58f3-4870-8cf4-c8218feb46e6 rack1
cqlshを実行。このと指定するのはServiceのIPアドレスもしくはサービス名。
$ kubectl get service cassandra
NAME LABELS SELECTOR IP(S) PORT(S)
cassandra name=cassandra name=cassandra 10.3.0.80 9042/TCP
$ kubectl exec -ti cassandra -- cqlsh 10.3.0.80
Connected to Test Cluster at 10.3.0.80:9042.
[cqlsh 5.0.1 | Cassandra 2.1.7 | CQL spec 3.2.0 | Native protocol v3]
Use HELP for help.
cqlsh>
$ kubectl exec -ti cassandra -- cqlsh cassandra.default.cluster.local
環境の構築、スケールアウトなどは非常に速く、しかも容易であることを実感。次からはドキュメントベースでどういう仕組みなのかを調べてみる。。