尽管LoadBalancer是一个不可否认的推荐解决方案(尤其是在云环境中),但值得一提的是,NodePort还具有负载均衡功能。
您在特定节点上访问NodePort
服务这一事实并不意味着您只能以这种方式访问Pods
已在该特定节点上安排的服务。
正如您在NodePort
服务规范中所读到的:
每个节点都将该端口(每个节点上的相同端口号)代理到您的Service
.
因此,通过访问一个特定节点上的端口30080
,您的请求不会直接发送到Pod
该节点上安排的一些随机的。它被代理到Service
对象,这是一个跨越所有节点的抽象。这可能是这里的关键点,因为您的NodePort
服务没有以任何方式与节点绑定,您使用其 IP 来访问您的 pod。
因此,Service 能够使用简单的循环算法NodePort
将客户端请求路由到集群中的所有 Pod 。
您可以使用以下方法轻松验证它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
然后验证您的 pod 是否安排在不同的节点上:
kubectl get pods -o wide
列出所有节点:
kubectl get nodes -o wide
并选择要用于访问 pod 的节点的 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
然后尝试NodePort
使用先前选择的节点的 IP 访问通过服务公开的 pod。您可能需要尝试普通模式和私有/隐身模式,甚至是不同的浏览器(简单刷新可能不起作用),但最终您会看到不同的请求落在不同节点上调度的 pod 上。
请记住,如果您决定使用NodePort
您将无法使用众所周知的端口。实际上,它甚至可能是可行的,因为您可以30000-32767
使用选项1-1024
将默认端口范围(--service-node-port-range