如何从互联网访问Kubernetes集群中监听9000端口的应用?
嘿,我来一步步帮你搞定这个Kubernetes部署和外网访问的问题——这确实是最基础的用例,咱们拆成几个核心步骤来做,保证你能快速跑起来:
首先得确保你的应用已经打包成Docker镜像,并且推送到一个Kubernetes集群能访问到的镜像仓库(比如Docker Hub,或者你的私有仓库)。如果还没做的话,简单操作如下:
- 写好适配你应用的Dockerfile(比如基于Node.js、Python基础镜像,把应用代码复制进去,暴露9000端口)
- 构建镜像:
docker build -t your-app-image:v1 . - 推送到镜像仓库:
docker push your-app-image:v1
Deployment是K8s里用来管理应用副本、保证应用持续运行的核心资源。创建一个名为deployment.yaml的文件,内容如下:
apiVersion: apps/v1 kind: Deployment metadata: name: your-app-deployment spec: replicas: 2 # 运行2个应用副本,可根据需求调整 selector: matchLabels: app: your-app template: metadata: labels: app: your-app spec: containers: - name: your-app-container image: your-app-image:v1 # 替换成你刚才推送的镜像地址 ports: - containerPort: 9000 # 和你应用监听的端口保持一致
执行部署命令:kubectl apply -f deployment.yaml
之后用kubectl get pods查看Pod状态,当所有Pod的状态变成Running,就说明应用在集群内部跑起来了。
这是实现外网访问的关键,K8s提供了几种常用的暴露方式,咱们从简单到复杂说:
方式一:NodePort(适合测试/集群节点有公网IP的场景)
NodePort会在集群的每个节点上开放一个固定端口(范围30000-32767),将外部流量转发到你的应用。创建service-nodeport.yaml:
apiVersion: v1 kind: Service metadata: name: your-app-nodeport spec: type: NodePort selector: app: your-app # 必须和Deployment里的Pod标签一致 ports: - protocol: TCP port: 9000 # Service内部的访问端口 targetPort: 9000 # 转发到容器的端口,和应用监听端口一致 nodePort: 30000 # 可选,指定节点端口,不填的话K8s会自动分配一个
执行命令:kubectl apply -f service-nodeport.yaml
用kubectl get service your-app-nodeport查看分配的NodePort,之后就可以通过集群任意节点的公网IP:NodePort访问应用,比如http://your-node-public-ip:30000。
方式二:LoadBalancer(适合云服务商托管的K8s集群)
如果你的K8s集群是AWS EKS、GKE、阿里云ACK这类云服务商托管的,用LoadBalancer类型的Service最方便——创建后云服务商会自动给你分配一个公网负载均衡器IP。创建service-loadbalancer.yaml:
apiVersion: v1 kind: Service metadata: name: your-app-loadbalancer spec: type: LoadBalancer selector: app: your-app ports: - protocol: TCP port: 80 # 外网用80端口访问,更友好 targetPort: 9000 # 转发到容器的9000端口
执行kubectl apply -f service-loadbalancer.yaml,然后用kubectl get service your-app-loadbalancer查看EXTERNAL-IP列,等IP分配完成后,直接访问http://your-external-ip就能打开应用了。
方式三:Ingress(适合多应用共享域名的场景)
如果要部署多个应用,想用自定义域名访问,就用Ingress。首先需要在集群里安装Ingress Controller(比如NGINX Ingress Controller),然后创建Ingress资源文件ingress.yaml:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: your-app-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: your-custom-domain.com # 替换成你的域名 http: paths: - path: / pathType: Prefix backend: service: name: your-app-clusterip # 先创建一个ClusterIP类型的Service指向你的应用 port: number: 9000
把你的域名解析到Ingress Controller的公网IP,之后就能通过http://your-custom-domain.com访问应用了。
不管用哪种暴露方式,都可以先在集群内部验证应用是否正常:
- 用
kubectl port-forward pod/your-pod-name 9000:9000(替换成你的Pod名称) - 本地访问
localhost:9000,确认应用能正常响应,再尝试外网访问。
内容的提问来源于stack exchange,提问作者Martin Dvoracek

