本文已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已不正确。
使用 Kubernetes Pet Set 的 Cassandra 的 1000 个实例
编者注: 这篇文章是关于 Kubernetes 1.3 新功能的 系列深度文章 的一部分
运行希腊宠物怪兽比赛
为了 Kubernetes 1.3 的发布,我们想对新的 Pet Set 进行测试。 通过测试 Cassandra 的 1000 个实例,我们可以确保 Kubernetes 1.3 已准备好投入生产。 继续阅读,了解我们如何使 Cassandra 适应 Kubernetes,以及我们有史以来最大的部署。
今天,使用容器处理基本有状态的应用程序相当简单。 使用持久卷,可以在 pod 中挂载磁盘,并确保数据在 pod 生命周期之外仍然存在。 然而,对于分布式有状态应用程序的部署,情况可能会变得更加棘手。 使用 Kubernetes 1.3,新的 Pet Set 组件使一切变得更加容易。 为了大规模测试这项新功能,我们决定举办希腊宠物怪兽比赛! 我们在多个可用区进行了数十万次半人马和其他古希腊怪兽的比赛。
众所周知,Kubernetes 源自古希腊语:κυβερνήτης。 这意味着舵手、飞行员、舵手或船长。 因此,为了跟踪比赛结果,我们需要一个数据存储,我们选择了 Cassandra。 Κασσάνδρα,Cassandra 是特洛伊国王普里阿摩斯和王后赫卡柏的女儿。 考虑到对古希腊语的多次引用,我们认为让古希腊怪兽比赛是合适的。
从那时起,这个故事就有点偏离了,因为 Cassandra 实际上也是宠物。 继续阅读,我们将解释。
Kubernetes 1.3 中令人兴奋的新功能之一是 Pet Set。 为了组织 Kubernetes 中容器的部署,提供了不同的部署机制。 这些组件的示例包括资源控制器和 Daemon Set。 Pet Set 是一项新功能,它提供了在 Kubernetes 中将容器部署为“宠物”的功能。 Pet Set 为宠物/pod 部署的各个方面提供了身份保证:DNS 名称、一致的存储和有序的 pod 索引。 以前,使用诸如 Deployment 和 Replication Controller 之类的组件只会部署一个具有弱解耦标识的应用程序。 弱标识非常适合管理诸如微服务之类的应用程序,其中服务发现非常重要,应用程序是无状态的,并且单个 pod 的命名无关紧要。 许多软件应用程序确实需要强标识,包括许多不同类型的分布式有状态系统。 Cassandra 是一个分布式应用程序的绝佳示例,它需要一致的网络标识和稳定的存储。
Pet Set 提供以下功能
- 一个稳定的主机名,可在 DNS 中供其他人使用。 数字基于 Pet Set 名称,从零开始。 例如 cassandra-0。
- 宠物的序号索引。 0、1、2、3 等。
- 链接到宠物的序号和主机名的稳定存储。
- 可以通过 DNS 进行对等发现。 使用 Cassandra,在创建 Pets 之前就知道对等点的名称。
- 启动和关闭排序。 知道接下来要创建哪个编号的宠物,以及在减小 Pet Set 大小时将销毁哪个宠物。 此功能对于诸如从宠物中排空数据之类的管理任务非常有用,当减小集群大小时。
如果你的应用程序具有这些要求中的一个或多个,那么它可能是 Pet Set 的候选对象。
一个相关的类比是,Pet Set 由宠物狗组成。 如果你有一只白色、棕色或黑色的狗,而棕色的狗跑掉了,你可以用另一只棕色的狗代替它,没有人会注意到。 如果随着时间的推移,你只能用白色的狗来代替你的狗,那么有人会注意到。 Pet Set 允许你的应用程序保持宠物的唯一身份或毛色。
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 RAM 的 Cassandra 并不罕见。 你会在上面注意到两个主要的新功能; 动态卷配置,当然还有 Pet Set。 上面的清单将创建 5 个 Cassandra 宠物/Pod,从数字 0 开始:cassandra-data-0、cassandra-data-1 等。
为了生成比赛数据,我们使用了另一个名为 Jobs 的 Kubernetes 功能。 编写简单的 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
既然我们在谈论怪兽,就必须来个大的。我们部署了 1,009 个 minion 节点到 Google Compute Engine (GCE),分布在 4 个可用区,运行 Kubernetes 1.3 beta 的定制版本。 我们在 beta 代码上运行此演示,因为该演示是在 1.3 发布日期之前设置的。 对于 minion 节点,选择了 GCE 虚拟机 n1-standard-8 的机器大小,即具有 8 个虚拟 CPU 和 30GB 内存的虚拟机。 这将允许在单个节点上运行一个 Cassandra 实例,这对于磁盘 I/O 是推荐的。
然后部署了 pet! 总共一千个,分布在两个不同的 Cassandra 数据中心。 Cassandra 分布式架构是专门为多数据中心部署量身定制的。 通常,为了分离工作负载,在同一物理或虚拟数据中心内部署多个 Cassandra 数据中心。 数据在所有数据中心之间复制,但数据中心之间可以有不同的工作负载,因此应用程序调优也可能不同。 名为“DC1-Analytics”和“DC1-Data”的数据中心分别部署了 500 个 pet。 比赛数据由连接到 DC1-Data 的 python 批处理作业创建,而 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 Sets 的限制
- Pet Set 是一个 alpha 资源,在 1.3 之前的任何 Kubernetes 版本中都不可用。
- 给定 pet 的存储必须由基于请求的存储类别的动态存储供应器提供,或者由管理员预先配置。
- 删除 Pet Set 不会删除任何 pet 或 Pet 存储。 您将需要手动删除您的 Pet 及其存储(如果需要)。
- 当前,所有 Pet Sets 都需要一个“管理服务”,或一个负责 pet 的网络身份的服务。 用户负责此服务。
- 当前,更新现有的 Pet Set 是一个手动过程。 您要么需要使用新镜像版本部署一个新的 Pet Set,要么逐个孤立 Pet 并更新它们的镜像,这将使它们重新加入集群。
资源和参考
- 该演示的源代码可在 GitHub 上找到:(Pet Set 示例将合并到 Kubernetes Cassandra 示例中)。
- 有关 Jobs 的更多信息
- Pet Set 的文档
- 图片来源: Cassandra 图片 和 Cyclops 图片