“minikube教程中提到,我需要直接访问服务的随机nodePort,这对于手动测试是有效的。当您使用kubectl expose命令创建类型为NodePort的服务对象时,无法选择NodePort端口。要选择NodePort端口,您需要创建一个YAML定义文件。以下示例演示了如何在类型为Nodeport的服务对象中手动指定端口。”
apiVersion: v1
kind: Service
metadata:
name: example-nodeport
spec:
type: NodePort
selector:
app: hello
ports:
- name: example-port
protocol: TCP
port: 1234
targetPort: 50001
nodePort: 32222
您可以通过以下命令应用上述
YAML
定义:
$ kubectl apply -f FILE_NAME.yaml
只有当
nodePort
端口可用时,才会创建上述服务对象。
“但是我不明白,在实际集群中,服务如何没有一个固定的全球可访问端口。”
在由云提供商管理的集群(例如GKE)中,您可以使用类型为
LoadBalancer
的服务对象,该对象将具有固定的外部IP和固定端口。
具有公共IP的节点的集群可以使用类型为
NodePort
的服务对象将流量引导到集群中。
在
minikube
环境中,您可以使用类型为
LoadBalancer
的服务对象,但是它将具有最后一段描述的一些警告。
一点解释:
NodePort
Nodeport
在每个节点IP上以静态端口公开服务。 它允许外部流量通过
NodePort
端口进入。此端口将自动分配从
30000
到
32767
的范围内。
您可以按照
此手册更改默认的
NodePort
端口范围。
当创建一个类型为
NodePort
的服务对象时,您可以通过查看此
answer来了解发生了什么。
想象一下:
- 您的节点具有IP地址:
192.168.0.100
192.168.0.101
192.168.0.102
- 您的Pod在端口
50001
上响应hello
,并且它们具有IP地址:
10.244.1.10
10.244.1.11
10.244.1.12
- 您的服务是:
NodePort
(端口32222
),其中包括:
ClusterIP
:
- IP:
10.96.0.100
port
:7654
targetPort
:50001
关于
targetPort
的说明。这是一个定义在
pod上的端口,例如Web服务器。
根据上面的例子,您将得到带有
hello
响应的:
节点IP:节点端口
(所有的POD都可以回应 hello
):
192.168.0.100:32222
192.168.0.101:32222
192.168.0.102:32222
集群IP:端口
(所有的POD都可以回应 hello
):
POD IP:目标端口
(只有接收请求的POD可以回应 hello
)
10.244.1.10:50001
10.244.1.11:50001
10.244.1.12:50001
您可以使用以下命令检查访问:
$ curl http://节点IP:节点端口
在你提到的例子中:
$ kubectl expose deployment/mysrv --type=NodePort --port=1234
会发生什么:
- 它将在您的
minikube
实例上分配一个随机端口,范围从30000
到32767
,将进入此端口的流量指向pod。
- 此外,它将创建一个端口为
1234
的ClusterIP
在上面的示例中,没有参数targetPort
。如果未提供targetPort
,则与命令中的port
相同。
进入NodePort
的流量将直接路由到pod,而不会进入ClusterIP
。
从minikube
的角度来看,NodePort
将是您的minikube
实例上的端口。其IP地址将取决于所使用的虚拟化程序。将其暴露在本地计算机之外将严重依赖于操作系统。
类型为LoadBalancer
(1)的服务对象与外部LoadBalancer
(2)之间存在区别:
LoadBalancer
(1)类型的服务对象允许使用云服务提供商的LoadBalancer
(2)将服务暴露在外部。它是Kubernetes环境中的一个服务,通过服务控制器可以调度创建外部LoadBalancer
(2)。
- 外部
LoadBalancer
(2)是云服务提供商提供的负载均衡器,它将在第4层操作。
LoadBalancer
(1)类型服务的示例定义:
apiVersion: v1
kind: Service
metadata:
name: example-loadbalancer
spec:
type: LoadBalancer
selector:
app: hello
ports:
- port: 1234
targetPort: 50001
nodePort: 32222
应用上述YAML
将创建一个类型为LoadBalancer
的服务(1)
具体看:
ports:
- port: 1234
这个定义将同时:
- 将外部
LoadBalancer
(2)的port
指定为1234
- 将
ClusterIP
的port
指定为1234
想象一下:
- 您的外部
LoadBalancer
(2)有:
ExternalIP
: 34.88.255.5
port
:7654
- 您的节点具有以下IP:
192.168.0.100
192.168.0.101
192.168.0.102
- 您的Pods使用端口
50001
响应hello
,它们的IP地址为:
10.244.1.10
10.244.1.11
10.244.1.12
- 您的服务是:
NodePort
(端口32222
)具有:
ClusterIP
:
- IP:
10.96.0.100
port
:7654
targetPort
:50001
根据上述示例,您将获得以下响应:hello
:
ExternalIP
:port
(所有的Pod都可以回应 hello
):
NodeIP:NodePort
(所有的Pod都可以回应 hello
):
192.168.0.100:32222
192.168.0.101:32222
192.168.0.102:32222
ClusterIP:port
(所有的Pod都可以回应 hello
):
PodIP:targetPort
(只有接收请求的Pod能够回应 hello
)
10.244.1.10:50001
10.244.1.11:50001
10.244.1.12:50001
ExternalIP
可以通过命令 $ kubectl get services
进行检查
流量传输方式:
客户端 -> LoadBalancer:port
(2) -> NodeIP:NodePort
-> Pod:targetPort
注意:此功能仅适用于支持外部负载均衡器的云提供商或环境。
-- Kubernetes.io: 创建外部负载均衡器
在支持负载均衡器的云提供商上,将会提供一个外部IP地址以访问服务。在Minikube上,LoadBalancer
类型通过minikube service
命令使服务可访问。
-- Kubernetes.io: Hello minikube
Minikube
可以创建LoadBalancer
类型的服务对象(1),但不会创建外部LoadBalancer
(2)。
在命令$ kubectl get services
中,ExternalIP
状态为等待中。
为了解决没有外部LoadBalancer
(2)的问题,可以调用$ minikube tunnel
,它将在主机和minikube
环境之间创建一条路由,以直接访问ClusterIP
的CIDR
。