使用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
感受到环境搭建、扩展等都非常快速且容易,接下来将尝试通过文档了解其工作机制。