【问题标题】:How can I expose a Statefulset with a load balancer?如何使用负载均衡器公开 Statefulset?
【发布时间】:2019-09-13 13:12:18
【问题描述】:

我目前正在尝试创建一个 X pod 集群,每个 pod 都有一个个人持久卷。为此,我创建了一个带有 X 个副本的 StateFulSet 和一个 PersistentVolumeClaimTemplate 这部分正在工作。

问题在于似乎不可能像 deployment 那样使用 LoadBalancer 公开这些 pod(因为有状态集中的 pod 的唯一性)。

此时我试图将其公开为一个简单的部署女巫不起作用,我发现的唯一方法是一个接一个地公开每个 pod(我没有测试它,但我在 @ 上看到了它987654321@) 但它的可扩展性不高……

我没有在任何云提供商平台上运行 kubernetes,请避免使用专有命令行。

【问题讨论】:

  • 如果 pod 如此独特 - 为什么要将它们全部作为一个 StatefulSet 运行?您应该将它们作为独立部署运行并像往常一样使用负载均衡器。
  • pod 做同样的事情,它们保持以太坊区块链同步(更准确地说),然后我只希望它们的持久存储是唯一的。而且部署中不可能有 volumeClaimTemplate。
  • 有状态集并没有你想象的那么可扩展。这主要是由于它们的独特身份和持久性规定。您可能希望在它们之前创建无头服务,并拥有另一个将这些 pod 公开为普通服务的服务。关于通过负载均衡器公开所有这些,我认为这不是一个好主意。
  • 即使我尝试过的方式不是一个好主意,它也不起作用......但在我不公开它们的情况下,我如何向那些豆荚请求信息而不负载均衡器?
  • 据我所知,sataefulset 不受 deploy 或 rs 或 rc 的约束。要连接,您肯定需要服务。我建议你看看kubernetes.io/docs/tutorials/stateful-application/…

标签: kubernetes load-balancing statefulset


【解决方案1】:

问题在于,使用 LoadBalancer 以与部署相同的方式公开这些 pod 似乎是不可能的(因为 statefulset 中 pod 的唯一性)。

为什么不呢?这是我使用默认 Nginx 的 StatefulSet

$ k -n test get statefulset
NAME      DESIRED   CURRENT   AGE
web       2         2         5d
$ k -n test get pods
web-0                    1/1       Running   0          5d
web-1                    1/1       Running   0          5d

这是我的服务类型 LoadBalancer,在 Minikube 的情况下是 NodePort(实际上)

$ k -n test get svc
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
nginx     LoadBalancer   10.110.22.74   <pending>     80:32710/TCP   5d

让我们用 curl 运行一些 pod 并向 ClusterIP 发出一些请求:

$ kubectl -n test run -i --tty tools --image=ellerbrock/alpine-bash-curl-ssl -- bash
bash-4.4$ curl 10.110.22.74 &> /dev/null
bash-4.4$ curl 10.110.22.74 &> /dev/null
bash-4.4$ curl 10.110.22.74 &> /dev/null
bash-4.4$ curl 10.110.22.74 &> /dev/null

让我们看看 Nginx 日志:

$ k -n test logs web-0
172.17.0.7 - - [18/Apr/2019:23:35:04 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.61.0"
172.17.0.7 - - [18/Apr/2019:23:35:05 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.61.0"
172.17.0.7 - - [18/Apr/2019:23:35:17 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.61.0"
$ k -n test logs web-1
172.17.0.7 - - [18/Apr/2019:23:35:15 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.61.0"

172.17.0.7 - 是我的带有 curl 的 pod:

NAME                     READY     STATUS    RESTARTS   AGE       IP           NODE
tools-654cfc5cdc-8zttt   1/1       Running   1          5d        172.17.0.7   minikube

实际上,在 StatefulSet 的 pod 之间进行负载平衡的情况下,ClusterIP 完全足够了,因为您有一个 Endpoints 列表

$ k -n test get endpoints
NAME      ENDPOINTS                     AGE
nginx     172.17.0.5:80,172.17.0.6:80   5d

YAML:

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
    name: web
  selector:
    app: nginx

【讨论】:

  • 好吧,我在想必须在服务中将clusterIp 值设置为None。但它似乎与你的把戏一起工作!谢谢!
  • @yatsukino ClusterIP to None - 是无头服务,但这完全是另一个问题
  • @yatsukino 你可以在这里阅读stackoverflow.com/questions/52707840/…
  • @KonstantinVustin 不确定这个设置是如何工作的。文档提到 Statefulsets 需要与无头服务一起使用,请您解释一下。文档 - kubernetes.io/docs/concepts/workloads/controllers/statefulset/…
  • @Riddle 你可以随意使用 pod 标签选择器。是由 StatefulSet 或 Deployment 创建的 pod,它仍然只是一个 pod。 Topic starter 认为不可能以与部署相同的方式使用 LoadBalancer 公开 StatefulSet pod。我只是表明它不是。 StatefulSet 出于其他原因需要 Headless Service
猜你喜欢
  • 2021-12-07
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多