有没有办法在多个节点中的 pod 之间进行负载平衡?
Is there a way to do a load balancing between pod in multiple nodes?
我有一个用 rke 部署的 kubernetes 集群 由 3 个不同服务器中的 3 个节点组成,在这些服务器中有 1 个 pod,它是 运行 yatsukino/healthereum 这是一个ethereum/client-go:stable 的个人修改。
问题是我不明白如何添加外部 ip 来发送请求到 pods are
我的 pods 可能处于 3 种状态:
- 他们正在同步以太坊区块链
- 由于同步问题,他们重新启动了
- 它们是同步的,一切都很好
我不希望我的负载均衡器将请求转移到第一个状态,只有第三点认为我的 pod 是最新的。
我一直在 kubernetes 文档中搜索,但(可能是因为理解错误)我只在唯一节点内找到 pods 的负载平衡。
这是我的部署文件:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: goerli
name: goerli-deploy
spec:
replicas: 3
selector:
matchLabels:
app: goerli
template:
metadata:
labels:
app: goerli
spec:
containers:
- image: yatsukino/healthereum
name: goerli-geth
args: ["--goerli", "--datadir", "/app", "--ipcpath", "/root/.ethereum/geth.ipc"]
env:
- name: LASTBLOCK
value: "0"
- name: FAILCOUNTER
value: "0"
ports:
- containerPort: 30303
name: geth
- containerPort: 8545
name: console
livenessProbe:
exec:
command:
- /bin/sh
- /app/health.sh
initialDelaySeconds: 20
periodSeconds: 60
volumeMounts:
- name: app
mountPath: /app
initContainers:
- name: healthcheck
image: ethereum/client-go:stable
command: ["/bin/sh", "-c", "wget -O /app/health.sh http://my-bash-script && chmod 544 /app/health.sh"]
volumeMounts:
- name: app
mountPath: "/app"
restartPolicy: Always
volumes:
- name: app
hostPath:
path: /app/
为了负载平衡和公开您的 pods,您可以使用 https://kubernetes.io/docs/concepts/services-networking/service/
为了检查 Pod 何时准备就绪,您可以使用调整您的活跃度和就绪度探测器,如 https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
所述
对于探测,您可能需要考虑 exec 操作,例如执行检查所需内容并根据状态返回 0 或 1 的脚本。
上面的回答解释了概念,但是关于你的问题anout services和external ip;您必须声明服务,例如;
apiVersion: v1
kind: Service
metadata:
name: goerli
spec:
selector:
app: goerli
ports:
- port: 8545
type: LoadBalancer
type: LoadBalancer
将在 public 云中分配一个外部地址,或者如果您使用 metallb 之类的东西。使用 kubectl get svc goerli
检查您的地址。如果外部地址是 "pending" 你有问题...
如果这是您自己的设置,您可以使用 externalIPs
分配您自己的外部 ip;
apiVersion: v1
kind: Service
metadata:
name: goerli
spec:
selector:
app: goerli
ports:
- port: 8545
externalIPs:
- 222.0.0.30
externalIPs
可以从集群外部使用,但是您必须自己将流量路由到 任何 节点,例如;
ip route add 222.0.0.30/32 \
nexthop via 192.168.0.1 \
nexthop via 192.168.0.2 \
nexthop via 192.168.0.3
假设你的 k8s 节点有 ip 192.168.0.x。这将为您的节点设置 ECMP 路由。当您从集群外部向 222.0.0.30:8545 发出请求时,k8s 将在您的 ready PODs.
之间进行负载平衡
当容器启动时,Kubernetes 可以配置为等待一个可配置的
在执行第一次准备检查之前要经过的时间。在那之后,它
定期调用探测器并根据就绪探测器的结果采取行动。如果一个
pod 报告它还没有准备好,它已从服务中删除。如果吊舱变成
再次准备好,它被重新添加。
与 liveness probes 不同,如果容器未通过就绪检查,它不会被杀死或
重新启动。这是 liveness 和 readiness 探测之间的一个重要区别。
Liveness 探测器通过杀死不健康的容器并更换来保持 pods 健康
他们与新的、健康的,而就绪探测器确保只有 pods
准备好服务请求接收它们。这在容器期间最有必要
启动,但在容器 运行 一段时间后也很有用。
我想你可以使用探针来实现你的目标
我有一个用 rke 部署的 kubernetes 集群 由 3 个不同服务器中的 3 个节点组成,在这些服务器中有 1 个 pod,它是 运行 yatsukino/healthereum 这是一个ethereum/client-go:stable 的个人修改。 问题是我不明白如何添加外部 ip 来发送请求到 pods are
我的 pods 可能处于 3 种状态:
- 他们正在同步以太坊区块链
- 由于同步问题,他们重新启动了
- 它们是同步的,一切都很好
我不希望我的负载均衡器将请求转移到第一个状态,只有第三点认为我的 pod 是最新的。
我一直在 kubernetes 文档中搜索,但(可能是因为理解错误)我只在唯一节点内找到 pods 的负载平衡。
这是我的部署文件:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: goerli
name: goerli-deploy
spec:
replicas: 3
selector:
matchLabels:
app: goerli
template:
metadata:
labels:
app: goerli
spec:
containers:
- image: yatsukino/healthereum
name: goerli-geth
args: ["--goerli", "--datadir", "/app", "--ipcpath", "/root/.ethereum/geth.ipc"]
env:
- name: LASTBLOCK
value: "0"
- name: FAILCOUNTER
value: "0"
ports:
- containerPort: 30303
name: geth
- containerPort: 8545
name: console
livenessProbe:
exec:
command:
- /bin/sh
- /app/health.sh
initialDelaySeconds: 20
periodSeconds: 60
volumeMounts:
- name: app
mountPath: /app
initContainers:
- name: healthcheck
image: ethereum/client-go:stable
command: ["/bin/sh", "-c", "wget -O /app/health.sh http://my-bash-script && chmod 544 /app/health.sh"]
volumeMounts:
- name: app
mountPath: "/app"
restartPolicy: Always
volumes:
- name: app
hostPath:
path: /app/
为了负载平衡和公开您的 pods,您可以使用 https://kubernetes.io/docs/concepts/services-networking/service/
为了检查 Pod 何时准备就绪,您可以使用调整您的活跃度和就绪度探测器,如 https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
所述对于探测,您可能需要考虑 exec 操作,例如执行检查所需内容并根据状态返回 0 或 1 的脚本。
上面的回答解释了概念,但是关于你的问题anout services和external ip;您必须声明服务,例如;
apiVersion: v1
kind: Service
metadata:
name: goerli
spec:
selector:
app: goerli
ports:
- port: 8545
type: LoadBalancer
type: LoadBalancer
将在 public 云中分配一个外部地址,或者如果您使用 metallb 之类的东西。使用 kubectl get svc goerli
检查您的地址。如果外部地址是 "pending" 你有问题...
如果这是您自己的设置,您可以使用 externalIPs
分配您自己的外部 ip;
apiVersion: v1
kind: Service
metadata:
name: goerli
spec:
selector:
app: goerli
ports:
- port: 8545
externalIPs:
- 222.0.0.30
externalIPs
可以从集群外部使用,但是您必须自己将流量路由到 任何 节点,例如;
ip route add 222.0.0.30/32 \
nexthop via 192.168.0.1 \
nexthop via 192.168.0.2 \
nexthop via 192.168.0.3
假设你的 k8s 节点有 ip 192.168.0.x。这将为您的节点设置 ECMP 路由。当您从集群外部向 222.0.0.30:8545 发出请求时,k8s 将在您的 ready PODs.
之间进行负载平衡当容器启动时,Kubernetes 可以配置为等待一个可配置的 在执行第一次准备检查之前要经过的时间。在那之后,它 定期调用探测器并根据就绪探测器的结果采取行动。如果一个 pod 报告它还没有准备好,它已从服务中删除。如果吊舱变成 再次准备好,它被重新添加。 与 liveness probes 不同,如果容器未通过就绪检查,它不会被杀死或 重新启动。这是 liveness 和 readiness 探测之间的一个重要区别。 Liveness 探测器通过杀死不健康的容器并更换来保持 pods 健康 他们与新的、健康的,而就绪探测器确保只有 pods 准备好服务请求接收它们。这在容器期间最有必要 启动,但在容器 运行 一段时间后也很有用。
我想你可以使用探针来实现你的目标