3

现在通过将 Deployment 的副本设置为 4,我有 4 个 k8s pod。

apiVersion: v1
kind: Deployment
metadata:
  ...
spec:
  ...
  replicas: 4
...

POD 将获取数据库中的项目并使用它,数据库中的项目有一列class_name

现在我想要一个 pod 只得到一个class_name的项目。例如pod1仅获取class_name等于的项目class_name_1,并且pod2仅获取class_name等于class_name_2...的项目

所以我想将不同class_name的环境变量传递给不同的部署 POD。可以在Deployment的yaml文件中定义吗?

或者有没有其他方法可以实现我的目标?(比如在 k8s 中部署以外的其他方法)

4

3 回答 3

2

部署或其他任何东西都无助于实现您的目标。您的目标是某种逻辑,它应该通过应用程序中的代码来实现。

由于部署是同一应用程序的一些实例,唯一可能对您有用的是:使用多个部署,每个部署都有自己的任务。第一个可以获得class_name_1item,而 otherclass_name_2class_name_3。但这不是一个好主意

于 2019-04-24T08:57:51.267 回答
2

对于分布式作业处理部署不是很好,因为它们没有任何类型的排序或一致的 pod 主机名。最好使用 StatefulSet,因为它们的命名是一致的,比如 pod-0、pod-1、pod-2。您可以依赖该主机名索引。

例如,如果你的class_name_idx- 是类名列表中类名的索引,num_replicas- 是 StatefulSet 中的副本数,pod_idx- 是 Pod 在 StatefulSet 中的索引,那么 pod 应该仅在以下情况下运行作业:class_name_idx % num_replicas == pod_idx

不幸的是,无法使用Downward API在 pod 中动态获取 StatefulSet 副本的数量,因此您可以对其进行硬编码或使用 Kubernetes API 从集群中获取它。

于 2019-04-24T08:48:19.490 回答
1

我不推荐这种方法,但最接近你想要的方法是使用 stateful-set 并使用 pod 名称作为索引。

当您部署有状态集时,pod 将以其有状态集名称命名,在以下示例中:

apiVersion: v1
kind: Service
metadata:
  name: kuard
  labels:
    app: kuard
spec:
  type: NodePort
  ports:
  - port: 8080
    name: web
  selector:
    app: kuard
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: kuard
spec:
  serviceName: "kuard"
  replicas: 3
  selector:
    matchLabels:
      app: kuard
  template:
    metadata:
      labels:
        app: kuard
    spec:
      containers:
      - name: kuard
        image: gcr.io/kuar-demo/kuard-amd64:1 
        ports:
        - containerPort: 8080
          name: web

statefulset 创建的 Pod 将被命名为:

kuard-0
kuard-1
kuard-2

这样,您可以根据类命名有状态集,即:class-name创建的 pod 将是class-name-0并且您可以替换_by -。或者只是去掉名称以获取最后的索引。

要获取名称,只需读取环境变量HOSTNAME

此命名是一致的,因此您可以确保名称后始终有 0、1、2、3。如果2失败,它将被重新创建。

就像我说的那样,我不会推荐这种方法,因为您将基础架构与代码绑定在一起,并且也无法扩展(如果需要),因为每个服务都是唯一的,并且添加新实例会获得新的 id。

更好的方法是为每个类使用一个部署,并将正确的值作为环境变量传递。

于 2019-04-24T10:34:14.153 回答