我如何在 kubernetes 中使用单个服务设置对多个节点的访问?
How would I set up access to multiple Nodes with a single Service in kubernetes?
我正在尝试使用单个服务 yaml 在多个节点上设置对 Pods 的访问。 Pods 都具有相同的标签(例如,label:app
),但分布在多个节点上,而不是在单个节点上。
据我所知,我可以设置一个服务来通过 NodePort 转发对 Pod 的访问,例如:
spec:
type: NodePort
selector:
label: app
ports:
targetPort: 5000
nodePort: 30000
其中访问节点上的端口 30000 转发到 pod 上的端口 5000。
如果我在多个节点上有 pods,客户端是否可以访问单个端点,例如服务本身,以循环方式获得任何 pod?或者客户端是否需要访问特定节点上的一组 pods,使用该节点的 IP,如 xx.xx.xx.xx:30000
?
如果您正在寻找您的应用程序服务的单一入口点并且它在云基础设施中 运行 那么您可以使用 Load balancer 服务(而不是节点端口),它将分配一个外部 IP用于您的服务,可用于从外部系统访问您的服务。
spec:
ports:
- name: httpsPort
port: 443
protocol: TCP
targetPort: 443
selector:
label: app
type: LoadBalancer
如果您在同一个集群中有多个服务需要从外部系统访问,那么您可以使用 Ingress.
谢谢
基鲁巴
虽然LoadBalancer is an undeniably recommended solution (especially in cloud environment), it's worth mentioning that NodePort也有负载均衡能力。
您在特定节点上访问 NodePort
服务这一事实并不意味着您只能通过这种方式访问已安排在该特定节点上的 Pods
。
如您在 NodePort
服务 specification 中所读:
Each node proxies that port (the same port number on every Node)
into your Service
.
因此,通过访问一个特定节点上的端口 30080
,您的请求不会直接发送到某个随机 Pod
,安排在该节点上。它被代理到 Service
对象,这是一个跨越所有节点的抽象。这可能是这里的关键点,因为您的 NodePort
服务没有以任何方式绑定到您用来访问 pods.
的节点的 IP
因此 NodePort
服务能够使用简单的 循环算法 .
将客户端请求路由到集群中的所有 pods
您可以使用以下内容轻松验证它 Deployment
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
initContainers:
- name: init-myservice
image: nginx:1.14.2
command: ['sh', '-c', "echo $MY_NODE_NAME > /usr/share/nginx/html/index.html"]
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- mountPath: /usr/share/nginx/html
name: cache-volume
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
这将允许您测试您的 http 请求将发送到哪个节点。您可能还需要稍微扩展一下 Deployment
以确保使用所有节点:
kubectl scale deployment nginx-deployment --replicas=9
然后验证您的 pods 是否安排在不同的节点上:
kubectl get pods -o wide
列出您的所有节点:
kubectl get nodes -o wide
并选择您要用来访问您的 pods 的节点的 IP 地址。
现在您可以通过 运行:
公开 Deployment
kubectl expose deployment nginx-deployment --type NodePort --port 80 --target-port 80
或者如果您想自己指定端口号,例如作为 30080
,应用以下 NodePort
服务定义作为 kubectl expose
不允许您指定确切的 nodePort
值:
apiVersion: v1
kind: Service
metadata:
name: nginx-deployment
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
然后尝试使用先前选择的节点的 IP 访问通过 NodePort
服务公开的 pods。您可能需要同时尝试正常模式和 private/incognito 模式,甚至需要尝试不同的浏览器(简单的刷新可能无法正常工作),但最终您会看到不同的请求落在 pods 上,安排在不同的节点上。
请记住,如果您决定使用 NodePort
,您将无法使用 众所周知的端口 。实际上它甚至可能是可行的,因为您可以使用 --service-node-port-range
选项将 kube-apiserver 配置中的默认端口范围 (30000-32767
) 更改为类似 1-1024
的内容,但不推荐这样做可能会导致一些意想不到的问题。
我正在尝试使用单个服务 yaml 在多个节点上设置对 Pods 的访问。 Pods 都具有相同的标签(例如,label:app
),但分布在多个节点上,而不是在单个节点上。
据我所知,我可以设置一个服务来通过 NodePort 转发对 Pod 的访问,例如:
spec:
type: NodePort
selector:
label: app
ports:
targetPort: 5000
nodePort: 30000
其中访问节点上的端口 30000 转发到 pod 上的端口 5000。
如果我在多个节点上有 pods,客户端是否可以访问单个端点,例如服务本身,以循环方式获得任何 pod?或者客户端是否需要访问特定节点上的一组 pods,使用该节点的 IP,如 xx.xx.xx.xx:30000
?
如果您正在寻找您的应用程序服务的单一入口点并且它在云基础设施中 运行 那么您可以使用 Load balancer 服务(而不是节点端口),它将分配一个外部 IP用于您的服务,可用于从外部系统访问您的服务。
spec:
ports:
- name: httpsPort
port: 443
protocol: TCP
targetPort: 443
selector:
label: app
type: LoadBalancer
如果您在同一个集群中有多个服务需要从外部系统访问,那么您可以使用 Ingress.
谢谢 基鲁巴
虽然LoadBalancer is an undeniably recommended solution (especially in cloud environment), it's worth mentioning that NodePort也有负载均衡能力。
您在特定节点上访问 NodePort
服务这一事实并不意味着您只能通过这种方式访问已安排在该特定节点上的 Pods
。
如您在 NodePort
服务 specification 中所读:
Each node proxies that port (the same port number on every Node) into your
Service
.
因此,通过访问一个特定节点上的端口 30080
,您的请求不会直接发送到某个随机 Pod
,安排在该节点上。它被代理到 Service
对象,这是一个跨越所有节点的抽象。这可能是这里的关键点,因为您的 NodePort
服务没有以任何方式绑定到您用来访问 pods.
因此 NodePort
服务能够使用简单的 循环算法 .
您可以使用以下内容轻松验证它 Deployment
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
initContainers:
- name: init-myservice
image: nginx:1.14.2
command: ['sh', '-c', "echo $MY_NODE_NAME > /usr/share/nginx/html/index.html"]
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- mountPath: /usr/share/nginx/html
name: cache-volume
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
这将允许您测试您的 http 请求将发送到哪个节点。您可能还需要稍微扩展一下 Deployment
以确保使用所有节点:
kubectl scale deployment nginx-deployment --replicas=9
然后验证您的 pods 是否安排在不同的节点上:
kubectl get pods -o wide
列出您的所有节点:
kubectl get nodes -o wide
并选择您要用来访问您的 pods 的节点的 IP 地址。
现在您可以通过 运行:
公开Deployment
kubectl expose deployment nginx-deployment --type NodePort --port 80 --target-port 80
或者如果您想自己指定端口号,例如作为 30080
,应用以下 NodePort
服务定义作为 kubectl expose
不允许您指定确切的 nodePort
值:
apiVersion: v1
kind: Service
metadata:
name: nginx-deployment
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
然后尝试使用先前选择的节点的 IP 访问通过 NodePort
服务公开的 pods。您可能需要同时尝试正常模式和 private/incognito 模式,甚至需要尝试不同的浏览器(简单的刷新可能无法正常工作),但最终您会看到不同的请求落在 pods 上,安排在不同的节点上。
请记住,如果您决定使用 NodePort
,您将无法使用 众所周知的端口 。实际上它甚至可能是可行的,因为您可以使用 --service-node-port-range
选项将 kube-apiserver 配置中的默认端口范围 (30000-32767
) 更改为类似 1-1024
的内容,但不推荐这样做可能会导致一些意想不到的问题。