本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
使用 Kubernetes Pet Set 实现千个 Cassandra 实例
编者按:这篇博文是关于 Kubernetes 1.3 新特性的系列深度文章之一
运行希腊神兽竞赛
为了Kubernetes 1.3 发布,我们想对新的 Pet Set 进行一番测试。通过测试上千个 Cassandra 实例,我们可以确保 Kubernetes 1.3 已为生产做好准备。请继续阅读,了解我们如何将 Cassandra 适配到 Kubernetes,并进行了有史以来最大规模的部署。
如今,将容器与基本有状态应用程序一起使用相当简单。使用持久卷,您可以在 Pod 中挂载磁盘,并确保您的数据在 Pod 生命周期结束后仍然存在。然而,对于分布式有状态应用程序的部署,事情可能会变得更加棘手。通过 Kubernetes 1.3,新的 Pet Set 组件让一切变得容易得多。为了大规模测试这项新功能,我们决定举办希腊神兽竞赛!我们在数百个可用区内进行了数十万场比赛,赛马和许多其他古希腊怪物参加了比赛。
众所周知,Kubernetes 一词源于古希腊语:κυβερνήτης。这意味着舵手、领航员、船长或船主。因此,为了记录比赛结果,我们需要一个数据存储,我们选择了 Cassandra。Κασσάνδρα,卡桑德拉,她是特洛伊国王普里阿摩斯和赫卡柏女王的女儿。鉴于多次提及古希腊语,我们认为举办古希腊怪物比赛是合适的。
从那时起,故事就有点偏离了,因为卡桑德拉实际上也是 Pet。请继续阅读,我们将进行解释。
Kubernetes 1.3 中一项令人兴奋的新功能是 Pet Set。为了组织 Kubernetes 内部容器的部署,提供了不同的部署机制。这些组件的例子包括 Resource Controller 和 Daemon Set。Pet Sets 是一项新功能,它提供了在 Kubernetes 内部部署容器作为 Pet 的能力。Pet Sets 保证了 Pet/Pod 部署的各个方面的身份:DNS 名称、一致存储和有序的 Pod 索引。以前,使用 Deployment 和 Replication Controller 等组件,只会部署一个具有弱解耦身份的应用程序。弱身份非常适合管理微服务等应用程序,在这种情况下,服务发现很重要,应用程序是无状态的,并且单个 Pod 的命名无关紧要。许多软件应用程序确实需要强身份,包括许多不同类型的分布式有状态系统。Cassandra 是一个需要一致网络身份和稳定存储的分布式应用程序的绝佳例子。
Pet Sets 提供以下功能
- 一个稳定的主机名,可在 DNS 中供他人使用。编号基于 Pet Set 名称,从零开始。例如 cassandra-0。
- Pet 的序数索引。0、1、2、3 等。
- 与 Pet 的序数和主机名相关联的稳定存储。
- 通过 DNS 可以进行对等发现。对于 Cassandra,在创建 Pet 之前就知道对等体的名称。
- 启动和拆除顺序。知道下一个要创建的 Pet 的编号,以及在缩小 Pet Set 大小时将被销毁的 Pet。此功能对于在缩小集群大小时,从 Pet 中排出数据等管理任务非常有用。
如果您的应用程序具有其中一项或多项要求,则它可能是 Pet Set 的候选者。
一个相关的类比是,一个 Pet Set 由宠物狗组成。如果您有一只白色、棕色或黑色的狗,而棕色的狗跑掉了,您可以换一只棕色的狗,没有人会注意到。如果随着时间的推移,您只用白色的狗来替换您的狗,那么有人就会注意到。Pet Set 允许您的应用程序保持 Pet 独特的身份或毛色。
Pet Set 的示例工作负载
- 像 Cassandra、Zookeeper、etcd 或 Elastic 这样的集群软件需要稳定的成员资格。
- 像 MySQL 或 PostgreSQL 这样的数据库,需要随时连接到持久卷的单个实例。
只有当您的应用程序需要这些属性中的部分或全部时,才使用 Pet Set。将 Pod 作为无状态副本进行管理要容易得多。
回到我们的比赛!
正如我们所提到的,Cassandra 是通过 Pet Set 部署的完美候选者。Pet Set 非常类似于 Replica Controller,但增加了一些新功能。下面是一个 YAML 清单示例
提供 DNS 查找的无头服务
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
您可能会注意到这些容器的尺寸相当大,在生产环境中运行具有 8 个 CPU 和 16GB 内存的 Cassandra 并不罕见。您会注意到上面有两个关键的新功能:动态卷配置,当然还有 Pet Set。上面的清单将创建 5 个 Cassandra Pet/Pod,从数字 0 开始:cassandra-data-0、cassandra-data-1 等。
为了生成比赛数据,我们使用了 Kubernetes 的另一个功能,称为 Jobs。编写了简单的 Python 代码来生成比赛中怪物每秒的随机速度。然后将这些数据、位置信息、获胜者、其他数据点和指标存储在 Cassandra 中。为了可视化数据,我们使用 JHipster 生成了一个带有 Java 服务的 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) 部署了 1,009 个 Minion 节点,分布在 4 个区域,运行自定义版本的 Kubernetes 1.3 beta。我们在 beta 代码上运行这个演示,因为演示是在 1.3 发布日期之前设置的。对于 Minion 节点,选择了 GCE 虚拟机 n1-standard-8 机器尺寸,即具有 8 个虚拟 CPU 和 30GB 内存的虚拟机。它允许在一个节点上运行单个 Cassandra 实例,这对于磁盘 I/O 是推荐的。
然后部署了 Pet!一千个 Pet,分布在两个不同的 Cassandra 数据中心。Cassandra 分布式架构是专门为多数据中心部署量身定制的。通常,为了分离工作负载,多个 Cassandra 数据中心部署在相同的物理或虚拟数据中心内。数据在所有数据中心之间复制,但数据中心之间工作负载可能不同,因此应用程序调优也可能不同。名为“DC1-Analytics”和“DC1-Data”的数据中心各部署了 500 个 Pet。比赛数据由连接到 DC1-Data 的 Python Batch Jobs 创建,JHipster UI 连接到 DC1-Analytics。
以下是最终数据
- 8,072 个核心。Master 使用 24 个,Minion 节点使用其余的
- 1,009 个 IP 地址
- Kubernetes 在 Google Cloud Platform 上设置了 1,009 条路由
- Minion 和 Master 使用了 100,510 GB 的持久磁盘
- 380,020 GB SSD 持久磁盘。Master 使用 20 GB,每个 Cassandra Pet 使用 340 GB。
- 部署了 1,000 个 Cassandra 实例。是的,我们部署了 1,000 个 Pet,但有一个真的不想加入派对!从技术上讲,在 Cassandra 设置中,我们可以在不损失服务或数据的情况下损失 333 个节点。
1.3 版本中 Pet Set 的限制
- Pet Set 是一个 alpha 资源,在 Kubernetes 1.3 之前的任何版本中都不可用。
- 给定 Pet 的存储必须由基于所请求存储类的动态存储提供程序进行配置,或由管理员预先配置。
- 删除 Pet Set 不会删除任何 Pet 或 Pet 存储。您需要手动删除您的 Pet 及其存储。
- 所有 Pet Set 目前都需要一个“管理服务”,即负责 Pet 网络身份的服务。用户负责此服务。
- 更新现有 Pet Set 目前是一个手动过程。您要么需要部署一个具有新镜像版本的新 Pet Set,要么逐个孤立 Pet 并更新其镜像,然后将其重新加入集群。
资源和参考资料
- 演示的源代码可在 GitHub 上获取:(Pet Set 示例将合并到 Kubernetes Cassandra 示例中)。
- 有关 Jobs 的更多信息
- Pet Set 的文档
- 图片来源:Cassandra 图片 和 Cyclops 图片