在Kubernetes中,当使用复制控制器时如何设置Pods的名称?

28

我有一个简单的复制控制器yaml文件,它看起来像这样:

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    spec:
      containers:
      - image: library/nginx:3.2
        imagePullPolicy: IfNotPresent
        name: nginx
        ports:
        - containerPort: 80
    metadata:
      labels:
        app: nginx

在运行这个复制控制器之后,我将会得到3个不同的pod, 它们的名称为 "nginx-xxx",其中 "xxx" 代表一个由字母和数字随机组成的字符串。

我想要指定由复制控制器创建的pod的名称,使得它们的名称可以分别是 "nginx-01"、"nginx-02"、"nginx-03"。此外,如果例如 pod "nginx-02" 由于某种原因被关闭,复制控制器将会自动创建另一个 nginx pod,并且我希望这个新的 nginx pod 的名称仍然是 "nginx-02"。

我想知道这是否可能?谢谢!


4
我也对这个答案很感兴趣。就“为什么有人需要这个”做出回应,对于我的情况,我们使用Prometheus/Grafana进行监控,我们希望避免随着时间的推移建立一个无限的主机名列表。 - GaspardP
3个回答

11

你应该使用 StatefulSet 而不是 Replication Controllers。此外,Replication Controllers 已被 ReplicaSets 取代。

StatefulSet Pod 具有唯一的标识,由序数组成。对于具有 N 个副本的 StatefulSet,StatefulSet 中的每个 Pod 将被分配一个整数序数,从 0 到 N-1,该序数在集合中是唯一的。StatefulSet 中的每个 Pod 从 StatefulSet 的名称和 Pod 的序数派生其主机名。

StatefulSets 满足您的要求,因此在部署中使用它。

请尝试以下部署文件:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
      volumes:
      - name: www
        emptyDir:

10
这可以使用statefulsets实现,自版本1.9以来已经退出beta。引用文档:使用kind: StatefulSet时,

Pod具有唯一标识符,由序数、稳定的网络标识符和稳定的存储组成。该标识符固定在Pod上,无论它被(rescheduled)调度到哪个节点。

StatefulSet中的每个Pod都从StatefulSet的名称和Pod的序数派生其主机名。构建主机名的模式为$(statefulset name)-$(ordinal)

因此,在上面的示例中,您将获得nginx-0nginx-1nginx-2

5
如果您运行无状态的工作负载,我无法想象为什么您希望将固定标识符与每个对象关联,如果您的意图是运行特定 pod 的 N 个副本。
使用 ReplicaSet/ReplicationController 没有办法做到这一点。当控制器创建新的 pods 时,它们的名称会有一个自动生成的后缀。
如果这确实是您想要的(固定标识符/序数索引),则 StatefulSet 资源 可以满足此属性,该资源自 Kubernetes v1.9 开始稳定。但是,它还附带了您可能不需要的其他保证。

1
例如,我想让我的Pod知道它们可以访问的FQDN名称。目前,Pod甚至无法从环境变量中确定其IP地址(例如10-42-25-26.dev.pod.cluster.local)。这个需求的背景是构建一个监控解决方案(如Hystrix/Turbine仪表板)。将无状态的Pod转换为StatefulSets只是为了实现上述目标,似乎有些不太妥当。 - Sergey Shcherbakov
1
避免使用环境变量,因为它是为了向后兼容旧版本的Docker而设计的,这些版本具有链接功能,现在已经被弃用。主机、端口环境变量需要按顺序执行。最好将Pod公开为服务,默认模式下,Pod是副本集的一部分,并将该副本集公开为服务,集群DNS将始终动态指向正确的集群IP地址,并更新FQDN,例如service.namespace.svc.cluster.local或您覆盖的任何集群默认基本名称。 - Walid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接