使用Kubernets Pet Set部署上千个Cassandra实例

本文讲的是使用Kubernets Pet Set部署上千个Cassandra实例【编者的话】本文是 Kubernetes1.3 五日谈 中的一篇文章,主要介绍Pet Set以及使用Pet Set部署上千个Cassandra实例,通过模拟古希腊巨兽之间的赛跑数据,验证Cassandra集群的可用性。译者在结尾处简单介绍了Pet Set,不了解的同学可以先看看(主要是因为译者不太了解,欢迎熟悉的同学批评指正)。

古希腊巨兽赛跑比赛(The Greek Pet Monster Races)

随着 Kubernetes 1.3 的发布,我们希望加快新功能Pet Set的发展速度。通过测试部署上千 Cassandra 实例,我们确定Kubernetes 1.3已经适用于生产环境。接下来将介绍我们是如何通过Kubernetes搭建我们有史以来最大的Cassandra集群。

使用容器部署基本的有状态应用程序是比较容易的,通过持久化volume在pod中挂载一个磁盘,就能确保在pod生命周期结束后保留下数据。然而,部署分布式有状态应用程序还是比较困难,不过,Kubernetes 1.3中的 Pet Set 能够解决这种困难。为了大规模测试Pet Set,我们将进行一次“古希腊神话巨兽赛跑比赛”(The Greek Pet Monster Races)。我们让半人马兽(Centaurs)与其他古希腊巨兽在多个区域上进行成百上千次比赛。

备注:所谓的比赛只是作者通过模拟赛跑过程产生一些时间序列随机数,然后将这些数据存放在Cassandra中,解释可以参考 gpmr
众所周知,Kubernetes来源于古希腊神话中的κυβερνήτης,词义为:舵手(helmsman、steersman)、飞行员(pilot)或者船长(ship master)。为了追踪比赛结果,我们需要一个数据仓储,我们选择使用Cassandra。在古希腊神话中,Cassandra(Κασσάνδρα)是特洛伊国王普里阿摩斯(Priam)和王后赫卡帕(Hecuba)的女儿。既然Kubernetes和Cassandra都与古希腊文化有关,我们就打算进行一次古希腊巨兽之间的赛跑比赛。

上面的故事有点带偏了Cassandra,其实在本文中Cassandra是部署在Pet中的应用程序,接下来我们将介绍Pet Set。

Pet Set是Kubernetes 1.3版本中令人兴奋的新功能之一。在Kubernetes中为了对容器部署进行组织管理,可以使用不同的部署机制,例如Resource Controllers以及Daemon Set。Pet Sets是一种新功能,在Kubernetes中,其将容器部署划分成多个Pet,并保证每个Pet都有确定性的唯一身份,身份内容包括DNS域名、一致性存储以及顺序化pod索引。在此之前,使用Deployments和Replication Controllers进行部署,只会给应用程序分配一个非耦合的弱身份。弱身份比较适合微服务等应用程序,这类应用程序不关心pod的名称,其重点在于服务发现,并且这些应用程序是无状态的。然而有很多软件应用程序是需要强身份,例如多种不同类型的分布式有状态系统。Cassandra就是一个比较好的例子,它需要一致的网络标识以及固定的存储。

Pet Sets提供了如下功能:
  • 在DNS中具有固定的hostname,同一个Pet Set中的Pet hostname以Pet Set名称为基础,加上从0开始的顺序化数字,例如cassandra-0。
  • 顺序化索引,例如0、1、2、3。
  • 链接到Pet序列以及hostname的固定存储。
  • 通过DNS发现同伴,在Pet创建之前,同伴的名称是已知的。
  • 顺序启动与销毁Pet,通过Pet编号,下一个需要被创建的Pet是已知的,并且当Pet Set规模减小时,哪些Pet需要被销毁也是已知的。当缩减集群规模时,对于从一个Pet中抽取数据这类管理任务来说,该功能是非常有用的。

如果你的应用程序具有如上需求,可以考虑使用Pet Set进行部署。我们来举个形象的例子,假设你有一个宠物集合(Pet Set)由宠物狗(Pet dog)组成。你有白色、棕色或者黑色的宠物狗,然后棕色的宠物狗突然逃跑了,当你用另外一直棕色宠物狗来替换原来的那只,没有人会发现;如果你用白色的宠物狗进行替换,就会有人察觉到。Pet Set可以让你Pet中运行的应用程序持有一个唯一的身份。

使用Pet Set的应用程序示例:
  • 集群化软件,例如Cassandra、Zookeeper、etcd或者需要固有关系的弹性化软件。
  • 数据库软件,例如MySQL或者PostgreSQL,这种需要单一实例在任何时候都挂上一个持久化volume。

只有当你的应用程序需要如上所述的一些属性时才建议使用Pet Set,因为管理无状态的pod要更加容易。

让我们回归比赛!

正如刚刚所述,使用Pet Set部署Cassandra是一个完美的示例。一个Pet Set非常类似于 Replica Controller ,只是其多了些额外的功能。如下是YAML文件示例:
# Headless service to provide DNS lookup
apiVersion: v1
kind: Service
metadata:
labels:
app: cassandra
name: cassandra
spec:
clusterIP: None
ports:
- port: 9042
selector:
app: cassandra-data
----
# new API name
apiVersion: "apps/v1alpha1"
kind: PetSet
metadata:
name: cassandra
spec:
serviceName: cassandra
# replicas are the same as used by Replication Controllers
# except pets are deployed in order 0, 1, 2, 3, etc
replicas: 5
template:
metadata:
  annotations:
    pod.alpha.kubernetes.io/initialized: "true"
  labels:
    app: cassandra-data
spec:
  # just as other component in Kubernetes one
  # or more containers are deployed
  containers:
  - name: cassandra
    image: "cassandra-debian:v1.1"
    imagePullPolicy: Always
    ports:
    - containerPort: 7000
      name: intra-node
    - containerPort: 7199
      name: jmx
    - containerPort: 9042
      name: cql
    resources:
      limits:
        cpu: "4"
        memory: 11Gi
      requests:
       cpu: "4"
       memory: 11Gi
    securityContext:
      privileged: true
    env:
      - name: MAX_HEAP_SIZE
        value: 8192M
      - name: HEAP_NEWSIZE
        value: 2048M
      # this is relying on guaranteed network identity of Pet Sets, we
      # will know the name of the Pets / Pod before they are created
      - name: CASSANDRA_SEEDS
        value: "cassandra-0.cassandra.default.svc.cluster.local,cassandra-1.cassandra.default.svc.cluster.local"
      - name: CASSANDRA_CLUSTER_NAME
        value: "OneKDemo"
      - name: CASSANDRA_DC
        value: "DC1-Data"
      - name: CASSANDRA_RACK
        value: "OneKDemo-Rack1-Data"
      - name: CASSANDRA_AUTO_BOOTSTRAP
        value: "false"
      # this variable is used by the read-probe looking
      # for the IP Address in a `nodetool status` command
      - name: POD_IP
        valueFrom:
          fieldRef:
            fieldPath: status.podIP
    readinessProbe:
      exec:
        command:
        - /bin/bash
        - -c
        - /ready-probe.sh
      initialDelaySeconds: 15
      timeoutSeconds: 5
    # These volume mounts are persistent. They are like inline claims,
    # but not exactly because the names need to match exactly one of
    # the pet volumes.
    volumeMounts:
    - name: cassandra-data
      mountPath: /cassandra_data
# These are converted to volume claims by the controller
# and mounted at the paths mentioned above.  Storage can be automatically
# created for the Pets depending on the cloud environment.
volumeClaimTemplates:
- metadata:
  name: cassandra-data
  annotations:
    volume.alpha.kubernetes.io/storage-class: anything
spec:
  accessModes: [ "ReadWriteOnce" ]
  resources:
    requests:
      storage: 380Gi  

你会看到这些容器是比较大的,一般生产环境中Cassandra只用8个CPU以及16GB内存。你需要注意两个关键的新功能,即动态volume供应(dynamic volume provisioning)以及Pet Set。通过上述的YAML文件将会创建5个Cassandra Pet,并且从第0个开始启动,即cassandra-data-0、cassandra-data-1等等。

为了给这场比赛产生数据,我们使用了Kubernetes的另一个功能,即Jobs。使用简单的python代码在比赛过程的每一秒为巨兽产生一个随机速度,然后将速度、位置信息、获胜者、其他数据点以及度量数据存放到Cassandra。为了数据可视化,我们使用JHipster来构建一个AngularJS UI界面,然后使用D3进行图表化。

如下是Job的配置示例:
apiVersion: batch/v1
kind: Job
metadata:
name: pet-race-giants
labels:
name: pet-races
spec:
parallelism: 2
completions: 4
template:
metadata:
  name: pet-race-giants
  labels:
    name: pet-races
spec:
  containers:
  - name: pet-race-giants
    image: py3numpy-job:v1.0
    command: ["pet-race-job", --length=100", "--pet=Giants", "--scale=3"]
    resources:
      limits:
        cpu: "2"
      requests:
        cpu: "2"
  restartPolicy: Never

既然是巨兽,那集群规模可不能小。我们在 Google Compute Engine (GCE)的四个区域上使用Kubernetes 1.3 beta版部署了1009个minion结点。我们在beta版代码上运行这个demo,是因为在构建这个demo时1.3版本还未正式发布。对于minion结点,使用的是GCE上“n1-standard-8”类型的虚机,其具有8个CPU以及30GB内存。

最终,所有的pet都部署好了。一千个实例被分成了两个不同的Cassandra数据中心。Cassandra的分布式架构特别适合多数据中心的部署方式。通常为了分离工作负载,同一个物理或虚拟数据中心上会部署多个Cassandra数据中心。在多个数据中心之间数据是重复的,但是不同数据中心的工作负载可能是不一样的,因此应用程序的性能也可能是不一样的。两个数据中心分别命名为'DC1-Analytics'和'DC1-Data',每个数据中心各自部署了500个pet。由批量python Jobs产生的数据存放到DC1-Data中,而JHipster UI则连接到DC1-Analytics。

最终的集群规模如下:
  • 8072核,master结点使用了24核,所有的minion结点使用了剩下的部分。
  • 1009个IP地址。
  • Google Cloud Platform上通过Kubernetes配置了1009个路由。
  • 100510GB持久化磁盘,供给Minion结点以及Master结点使用。
  • 380020GB SSD磁盘,master使用了20GB,而每一个Cassandra Pet使用了340GB。
  • 1000个Cassandra实例。

是的,我们确实部署了1000个pet,但我们不希望看到的事情也发生了。当Cassandra集群启动后,有333个结点或者服务没起来,或者数据丢失了。

1.3版本中Pet Sets的局限性

  • Pet Set是具有α属性的资源,1.3版本以前的Kubernetes都不能使用。
  • Pet所使用的存储必须是通过基于请求获取存储的动态存储供应器提供(dynamic storage provisioner)或者是通过管理员事先提供。
  • 删除Pet Set并不会删除任何的Pet或者Pet的存储。你必须手动删除Pet及其存储。
  • 目前,所有的Pet Set都需要一个“管理服务(governing service)”,或者是一个可以管理Pet网络标识的服务。这个服务由使用者自己负责。
  • 目前,更新已有的Pet Set需要手动操作。你可以重新构建一个使用新版镜像的Pet Set,或者一个一个地替换已有Pet的镜像,然后重新把它加入到集群中。

来源与引用

  • demo程序的代码可以在GitHub上获取(Pet Set示例会被合并到Kubernetes Cassandra示例中)。
  • 关于Jobs的更多资料,可见Jobs
  • Pet Set文档
  • 所用图片:CassandraCyclops

译者补充:什么是Pet Set?

参考Kubernetes官网的介绍 Pet Sets

首先,什么是Pet?Pet是一个有状态应用程序,本质上它是一个具有确定性名称以及唯一身份的Pod,身份内容包括:
  • DNS中可以识别的固定hostname
  • 顺序化索引(Pet名称组成:PetSetName-Ordinal)
  • 链接到索引与hostname的固定存储

顾名思义,Pet Set就是Pet集合,它具有特定数量的Pet,其目的就在于解耦集群化有状态应用程序,例如MySQL、PostgreSQL等数据库应用程序,或者Zookeeper、Etcd以及Elasticsearch等集群化应用程序。一般集群化应用程序都是部署在固定的结点上,具有永久性存储以及静态的IP地址,并且在部署过程中需要在结点之间建立一定的关联联系。而Pet Set会给每个应用程序实例分配一个身份,这样应用程序实例就不必固定在物理基础服务上,实例之间依靠身份建立联系。

原文链接:Thousand Instances of Cassandra using Kubernetes Pet Set(翻译:肖远昊)

原文发布时间为:2016-07-27

本文作者:肖远昊

本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

原文标题:使用Kubernets Pet Set部署上千个Cassandra实例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值