LoginSignup
11
8

More than 5 years have passed since last update.

Kubernetesを使ってCassandra環境を構築

Posted at

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内でコンテナを生成する。

cassandra.yaml
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の集まりとして定義される。

cassandra-service.yaml
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する。

cassandra-controller.yaml
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

環境の構築、スケールアウトなどは非常に速く、しかも容易であることを実感。次からはドキュメントベースでどういう仕組みなのかを調べてみる。。

11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8