我创建了一个具有以下 yaml 定义的 pod。
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: praveensripati/docker-demo:1.2
ports:
- containerPort: 3000
现在我公开了 pod,它创建了一个服务。
kubectl expose pod myapp-pod --type=NodePort
容器上的3000端口暴露给节点上的31728端口。我可以使用端口 31728 上的curl 访问该页面。
kubectl get service myapp-pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-pod NodePort 10.107.254.254 <none> 3000:31728/TCP 5s
这次我想公开的服务不是随机端口,而是在端口 80 上。因此我使用 --port 将端口号指定为 80。服务细节有点奇怪。它表示容器上的端口 80 暴露给节点上的端口 31316。另外,我可以在随机端口(本例中为 31316)而不是端口 80 上使用curl 访问该页面。
kubectl expose pod myapp-pod --type=NodePort --target-port=3000 --port=80
kubectl get service myapp-pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-pod NodePort 10.105.123.73 <none> 80:31316/TCP 12s
我无法在特定端口上公开服务,而不能在随机端口上公开服务。我尝试了几种组合并阅读了k8s文档,但没有成功。
如何在特定端口而不是随机端口上公开服务?
您的问题是关于在特定端口上公开 NodePort 类型的服务。为此,您需要在服务定义中的
nodePort
下指定 ports
字段。
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 3000
nodePort: 32321
type: NodePort
请注意,它必须在配置中提供的给定范围内。默认为
30000-32767
。可以使用 --service-node-port-range
选项在 kube-apiserver配置中指定此范围。
当现有 Dashboard 服务已存在时,将其删除。
kubectl delete service kubernetes-dashboard -n kube-system
将仪表板部署公开为 NodePort。
kubectl expose deployment kubernetes-dashboard -n kube-system --type=NodePort
上面将分配一个随机端口 >= 30000。因此,使用 Patch 命令将该端口分配给已知的、未使用的且所需的端口 >= 30000。
kubectl patch service kubernetes-dashboard --namespace=kube-system --type='json' --patch='[{"op": "replace", "path": "/spec/ports/0/nodePort", "value":30000}]'
如果您的集群没有 LoadBalancer Provider,您可以在节点网络接口的 IP 中指定 externalIPs。
例如:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: ClusterIP
externalIPs:
- 125.100.99.101 # Node1-IP
- 125.100.99.102 # Node2-IP
- 192.168.55.112 # Node2-IP2
selector:
pod: nginx
ports:
- name: http
port: 80
- name: https
port: 443
这将在指定节点上监听80和443,并转发到nginx服务。
我遇到了同样的问题,我发现在不修改文件的情况下做到这一点的唯一方法是:
k expose --type=NodePort deployment nginx --port 80 --name nginx-ep-patch --overrides '{ "apiVersion": "v1","spec":{"ports": [{"port":80,"protocol":"TCP","targetPort":80,"nodePort":30080}]}}'
service/nginx-ep-patch exposed
这样我们就将配置在线路径化了,30080端口就暴露了:
$ k describe svc nginx-ep-patch
Name: nginx-ep-patch
Namespace: default
Labels: app=nginx
Annotations: <none>
Selector: app=nginx
Type: NodePort
IP: 10.96.51.148
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 30080/TCP
Endpoints: 10.244.0.6:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
我会尽力在这里回答您的疑问。
此外,我可以在随机端口上使用curl访问该页面 (在本例中为 31316)而不是端口 80。
-- Because, kubernetes exposed the port 31316 on the host (maps to the service) and hence it can be accessed on host:31316.
-- Service port is visible only within the kubernetes cluster. You can exec into a pod container and do a curl on servicename:service port instead of the NodePort.
注意术语 -
container port:
端口容器监听。 Service port:
kubernetes 服务在集群内部 ip 上暴露的端口,并映射到容器端口。 Nodeport:
主机上暴露并映射到 kubernetes 服务的端口。
我们可以在特定节点端口上公开 Kubernetes 服务。
端口值必须在 30000-32767 之间。
我们可以将服务公开到以下服务类型的特定端口:
节点端口
负载均衡器
找到下面的示例 myservice.yaml 文件:
apiVersion: v1
kind: Service
metadata:
name: app1
spec:
type: NodePort/LoadBalancer
ports:
- name: "80"
port: 80
nodePort: 32062
targetPort: 80
selector:
appone: app1
app: test
注意:在上面的服务 yaml 文件中,我们可以指定服务类型 NodePort 或 Loadbalancer。
对于需要使用kubectl命令的用户,可以使用
create nodeport
命令创建指定端口的NodePort服务:
kubectl create nodeport NAME [--tcp=port:targetPort] [--dry-run=server|client|none]
例如:
kubectl create service nodeport myservice --node-port=31000 --tcp=3000:80
您可以查看 Kubectl 参考资料了解更多:
apiVersion: v1
kind: Service
metadata:
name: argocd-server-30k-node-port
namespace: argocd
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30000
selector:
app.kubernetes.io/name: argocd-server