使用Kubernetes构建Cassandra环境

为了理解Kubernetes,首先要拥有运行和操作的实际感。关于其运作机制,稍后可以通过阅读文档进行总结。

环境:VirtualBox
CoreOS Alpha 845.0.0
Kernel版本:4.2.2
docker版本:1.8.3

关于CoreOS,我会在以后学习。目前对于它我还不太了解,所以有很多不知道的东西。

确认 Kubernetes 环境

1.1. 检查etcd是否正常运行。

使用etcdctl命令来检查集群状态。

$ etcdctl cluster-health
member ce2a822cea30bfca is healthy: got healthy result from http://localhost:2379
cluster is healthy

etcd是一个键值存储系统,用于存储可由CoreOS构成的集群中的所有节点访问的数据。

确认顶级键

$ etcdctl ls
/registry
/coreos.com

要获取value,需要使用get方法指定端点。对于目录,返回的结果会是一个类似以下的目录。

$ etcdctl get /coreos.com/              
/coreos.com: is a directory

按照以下方式,可以输出所有的层次结构信息。

etcdctl ls / --recursive

※和养动物员相似。

可以指定 endpoint,并通过 GET 方式获取实际数据的样子。

$ etcdctl get /coreos.com/network/config
{"Network":"10.2.0.0/16","Backend":{"Type":"vxlan"}}

1.2. 验证 Kubernetes 的服务是否正常运行。

$ 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的状态。

展示带有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)、复制控制器(rc)、服务(svc)、节点、事件(ev)、组件状态(cs)、限制范围(limits)、节点(no)、持久卷(pv)、持久卷声明(pvc)或资源配额)。

$ 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

将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

使用Kubernetes来构建Cassandra环境。

http://kubernetes.io/v1.0/docs/user-guide/configuring-containers.html
http://kubernetes.io/v1.0/examples/cassandra/README.html

以下是两个链接,第一个链接是关于配置容器的用户指南,第二个链接是关于Cassandra的示例说明。

2.1. 创建Pod

使用 Kubernetes 的 API 资源架构来创建配置文件。
在 Kubernetes 中,应用程序的最小单元是 Pod,所以首先要定义 Pod。Pod 会被调度到相同的主机上。Pod 内的所有容器共享网络命名空间,并且卷也可以共享(可选)。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) 或 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. 创建服务

在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に所属

创建服务。

$ kubectl create -f cassandra-service.yaml 
services/cassandra

请确认服务是否已创建。

$ 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. 创建复制控制器

通过Kubernetes,可以轻松地构建和扩展Cassandra集群。
复制控制器会复制一组相同类型的Pod,根据指定的Pod数量添加或删除Pod。

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列表,并进行标签过滤,选择标签名为cassandra的Pod。可以查看到两个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

一方面,使用复制控制器生成的随机字符串被附加上了。使用nodetool来检查集群的状态以确保其正常运行。使用kubectl exec,在容器内执行命令。(kubectl exec POD -c CONTAINER — COMMAND [args…])通过-t选项将stdin作为tty流传递给容器,通过-i选项将stdin传递给容器。

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

感受到环境搭建、扩展等都非常快速且容易,接下来将尝试通过文档了解其工作机制。

广告
将在 10 秒后关闭
bannerAds