在Kubernetes上暴露服务#
注意
这是一个关于如何配置现有Kubernetes集群(包括涉及的注意事项)以通过SkyPilot成功对外暴露端口和服务的指南。
如果您是SkyPilot用户,并且您的集群已经设置为暴露端口, Opening Ports 解释了如何通过SkyPilot在您的任务中暴露服务。
SkyServe 和 SkyPilot 集群可以 打开端口 以暴露服务。对于在 Kubernetes 上运行的 SkyPilot 集群,我们支持两种模式来暴露端口:
默认情况下,SkyPilot 会在您的 Kubernetes 集群上创建一个 LoadBalancer Service 以暴露端口。
如果您的集群不支持LoadBalancer服务,SkyPilot也可以使用现有的Nginx IngressController来创建Ingress以暴露您的服务。
负载均衡器服务#
此模式通过Kubernetes的LoadBalancer Service暴露端口。这是SkyPilot使用的默认模式。
要使用此模式,您必须拥有支持LoadBalancer服务的Kubernetes集群:
在Google GKE、Amazon EKS或其他云托管的Kubernetes服务上,此模式开箱即用,无需额外配置。
在裸金属和自管理的Kubernetes集群上,MetalLB 可用于支持LoadBalancer服务。
使用此模式时,SkyPilot 将为您在集群上暴露的所有端口创建一个单一的负载均衡器服务。
每个端口都可以使用负载均衡器的外部IP地址和端口号进行访问。使用 sky status --endpoints 查看所有端口的外部端点。
在基于云的Kubernetes集群中,这将自动创建一个外部负载均衡器。 GKE创建一个直通负载均衡器 而AWS创建一个网络负载均衡器。 当集群被删除时,这些负载均衡器将自动终止。
注意
在使用sky local up创建的kind集群中不支持LoadBalancer服务。
注意
EKS中的默认LoadBalancer实现从打开的端口列表中随机选择一个端口用于LoadBalancer的健康检查。如果所选端口后面没有运行服务,可能会导致问题。
例如,如果一个SkyPilot任务暴露了5个端口,但只有其中2个端口后面有服务在运行,EKS可能会选择一个没有服务运行的端口,而负载均衡器将无法通过健康检查。因此,该服务将不会被分配一个外部IP地址。
要解决此问题,请确保所有端口后面都有服务在运行。
内部负载均衡器#
要将您的服务限制为仅在集群内可访问,您可以将所有SkyPilot服务设置为使用内部负载均衡器。
根据您的云环境,在SkyPilot配置文件中设置适当的注释(~/.sky/config.yaml):
# ~/.sky/config.yaml
kubernetes:
custom_metadata:
annotations:
# For GCP/GKE
networking.gke.io/load-balancer-type: "Internal"
# For AWS/EKS
service.beta.kubernetes.io/aws-load-balancer-internal: "true"
# For Azure/AKS
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
Nginx Ingress#
此模式通过创建一个由现有Nginx Ingress Controller支持的Kubernetes Ingress来暴露端口。
要使用此模式:
在您的Kubernetes集群上安装Nginx Ingress控制器。请参考文档以获取适用于您环境的安装说明。
验证
ingress-nginx-controller服务是否具有有效的外部IP:
$ kubectl get service ingress-nginx-controller -n ingress-nginx
# Example output:
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
# ingress-nginx-controller LoadBalancer 10.24.4.254 35.202.58.117 80:31253/TCP,443:32699/TCP
注意
如果EXTERNAL-IP字段是,你可以通过ingress-nginx-controller服务上的skypilot.co/external-ip注解手动指定Ingress IP或主机名。在这种情况下,不需要有效的EXTERNAL-IP字段。
例如,如果你的 ingress-nginx-controller 服务是 NodePort:
# Add skypilot.co/external-ip annotation to the nginx ingress service.
# Replace <IP> in the following command with the IP you select.
# Can be any node's IP if using NodePort service type.
$ kubectl annotate service ingress-nginx-controller skypilot.co/external-ip=<IP> -n ingress-nginx
如果EXTERNAL-IP字段是并且skypilot.co/external-ip注解不存在,
SkyPilot将使用localhost作为Ingress的外部IP,
并且该端点可能无法从集群外部访问。
更新位于
~/.sky/config的 SkyPilot 配置 以使用入口模式。
kubernetes:
ports: ingress
提示
对于RKE2和K3s,预安装的Nginx ingress默认情况下未正确配置。请按照裸金属安装说明正确设置Nginx ingress控制器。
使用此模式时,SkyPilot 会为每个打开的端口创建一个 ingress 资源和一个 ClusterIP 服务。可以通过使用 Ingress URL 加上形式为 /skypilot/{pod_name}/{port} 的路径前缀来从外部访问该端口。
使用 sky status --endpoints 查看所有端口的完整端点URL。
$ sky status --endpoints mycluster
8888: http://34.173.152.251/skypilot/test-2ea4/8888
注意
当在子路径(如入口)下暴露端口时,期望访问根路径的服务(例如,Jupyter笔记本)可能会遇到问题。为了解决这个问题,配置服务以在不同的基础URL下运行。对于Jupyter,在启动时使用–NotebookApp.base_url标志。或者,考虑使用LoadBalancer模式。