【问题标题】:How get consistent names for Pods in Kubernetes如何在 Kubernetes 中获得一致的 Pod 名称
【发布时间】:2020-07-10 07:26:37
【问题描述】:

我想在 kubernetes 中运行这个 docker 镜像: https://hub.docker.com/_/rabbitmq

这不是问题,它正在运行。问题是我需要通过开关发送“docker run”命令。对于这个图像,当在 docker 中启动容器时,你会运行这个:

docker run -d --hostname my-rabbit --name some-rabbit rabbitmq:3

yaml 文件将如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:  
  name: rb
  namespace: rabbittest
spec:
  selector:
    matchLabels:
        app: rb
  replicas: 1
  template:
    metadata:
      labels:
        app: rb
    spec:
      containers:
      - name: rb-container
        env:                    
          - name: HOSTNAME
            value: "rbnode001"
        image: rabbitmq:3-management        
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi
        volumeMounts:
          - name: azure
            mountPath: /mnt/azure
        ports:
          - containerPort: 5672
      volumes:
      - name: azure
        azureFile:
          secretName: azure-secret
          shareName: rabbittest
          readOnly: false

我的问题是,当 kubernetes 执行“docker run”命令时,如何让 kubernetes 应用 --name 和 --hostname?

【问题讨论】:

  • 你的目的是什么?为什么在 kuberneres 中运行时需要 --name--hostname
  • 因为这是在 docker 中运行特定映像的要求。从文档中:关于 RabbitMQ 需要注意的重要事项之一是它根据它所谓的“节点名称”存储数据,默认为主机名。这对于 Docker 的使用意味着我们应该为每个守护进程明确指定 -h/--hostname,这样我们就不会得到一个随机的主机名并且可以跟踪我们的数据
  • 那么,你想在环境中设置节点名吗?
  • 不,“主机名”。它可以是任何值。比如“RabbitMQ0001”。

标签: kubernetes rabbitmq


【解决方案1】:

首先,你需要创建StatefulSetsRabbitMQ

在您的 StatefulSet 中,添加此 ENV

env:
  - name: POD_NAME
    valueFrom:
      fieldRef:
        apiVersion: v1
        fieldPath: metadata.name
  - name: POD_NAMESPACE
    valueFrom:
      fieldRef:
        apiVersion: v1
        fieldPath: metadata.namespace
  - name: K8S_SERVICE_NAME
    value: rabbitmq-headless
  - name: RABBITMQ_NODENAME
    value: $(POD_NAME).$(K8S_SERVICE_NAME).$(POD_NAMESPACE).svc.cluster.local

这里,K8S_SERVICE_NAME 是 statefulset 所需的无头服务。

最后,RABBITMQ_NODENAME 将持有 HOSTNAME。

【讨论】:

  • 编辑:我错了,看起来这会覆盖 K8S 分配给 pod 的实际名称,无论我想要什么。我会试一试。 ---------------------- 这不会导致问题的要求。 Kubernetes 在 docker 中创建容器时生成的结果命令应该是“docker run -d --hostname my-rabbit --name some-rabbit rabbitmq:3”。您在此处提供的解决方案不会生成,它会生成类似 "docker run --env POD_NAME=xxxxx --env POD_NAMESPACE=yyyyy"
  • 您的问题没有直接的解决方案。你需要变通
  • 我已经接受了这个答案。有状态集创建具有可预测名称的 pod,允许我一致地引用它们。
【解决方案2】:

Kubernetes 的选项与 Docker 的选项不同。许多选项在pod spec object 中具有等价物;某些选项没有直接等效项,或者被拆分为多个层(卷挂载、发布的端口)。

对于您提到的两个选项:

  • docker run --name 设置容器的名称。在 Kubernetes 中,您通常不直接与容器交互,因此您无法设置它们的名称。 metadata: {name: } 设置 Deployment 的名称,并且生成的 Pod 具有从中派生的名称; Pod 中的容器也有名称,但很少使用这些名称。

  • docker run --hostname 设置容器认为其主机名的名称。你几乎不需要这个选项; RabbitMQ 是一个值得注意的例外。 pod 规范有一个 hostname: 选项可以设置它。

    spec:
      template:
        spec:
          hostname: my-rabbit
          containers: [...]
    

正如@Shahriar's answer 建议的那样,StatefulSet 更适合需要一些支持持久状态的部署。在这种情况下the StatefulSet automatically sets the host name based on the pod identity,所以你不需要做任何事情。

(RabbitMQ 的重要细节是主机名必须在重新创建容器时保持一致,并且如果主机名始终来自满足此规则的 StatefulSet 的 rb-0。自动生成的 Docker 容器 ID,或变量 Kubernetes Deployment pod名称,每次重启都会不同,并且 Rabbit 将失去对其状态的跟踪。)

【讨论】:

  • 不一致的主机名正是我使用 RabbitMQ 的问题。 StatefulSet 为我解决了这个问题。
猜你喜欢
  • 2019-01-07
  • 1970-01-01
  • 2022-08-23
  • 2017-05-24
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 2017-07-05
  • 2021-07-23
相关资源
最近更新 更多