Kubernetes workloads can be exposed to each other, and to the public using Services and Ingresses. A Service allocates a dedicated IP for the exposed application, whereas an Ingress works for HTTP based protocols and alleviates the need for a separate IP for each endpoint. For stateless web-services, using the Serverless framework is another option where the application is deployed with a TLS enabled hostname and auto-scaling for you.
Internal, cluster local services should be configured as regular
Exposing services to the Internet is done by deploying a
LoadBalancer service type with an annotation to allocate a public IP for the service. Without the annotation, a static private IP will be allocated, this is mostly useful for services accessed from outside the cluster via a Site to Site VPN.
Depending upon where you've requested your workloads to run, public IP pools are accessible via the region location in the following manner:
Address Pool Label
sshd-public-service.yamlapiVersion: v1kind: Servicemetadata:annotations:metallb.universe.tf/address-pool: public-ord1metallb.universe.tf/allow-shared-ip: defaultname: sshdspec:type: LoadBalancerexternalTrafficPolicy: Localports:- name: sshdport: 22protocol: TCPtargetPort: sshdselector:app.kubernetes.io/name: sshd
The traditional Kubernetes pattern is one or many Pods with dynamic internal IPs exposed behind a Service or Ingress with a static IP. For certain use cases, where there would only be one Pod behind a service, it can make sense to attach the Service IP directly to the Pod. A Pod would then have a static public IP as it's Pod IP. All connections originating from the pod will have this IP as it's source, and the Pod will see this as it's local IP. This is a non standard approach for containers, and should be used only when the traditional Service / Pod pattern is not feasible. Directly attaching the Service IP is beneficial in the following scenarios:
The application needs to expose a large number of ports (above 10), where listing them out in the service definition is impractical
The application needs to see the service IP on the network interface inside the pod
Connections originating from the Pod to the outside need to originate from the Service IP
The application needs to receive all traffic regardless of type and port
A Virtual Machine type workload where a static IP provides a more native experience
Please note that an application that directly attaches a Service IP can run with a maximum of 1 replica, as there would otherwise be multiple Pods with the same Pod IP. Traffic to the Pod will not be filtered, all inbound traffic to the IP will be sent to the pod. To provide security, NetworkPolicies can be applied.
A stub Service needs to be created to allocate the IP. The Service should expose only port
1 as in the example below.
apiVersion: v1kind: Servicemetadata:name: my-appannotations:metallb.universe.tf/address-pool: public-ord1spec:externalTrafficPolicy: Localtype: LoadBalancerports:- port: 1 # Do not change thistargetPort: attachprotocol: TCPname: attachselector:coreweave.cloud/ignore: ignore # Do not change this
To attach the IP from the Service directly to a Pod, annotate the Pod spec.
Using an Ingress for HTTP based applications are beneficial as it saves IP addresses and automatically provides a DNS name as well as TLS certificate to allow access to your application via
https. CoreWeave already has all the infrastructure setup including the Ingress Controller, all you need to do is deploy an
Ingress manifest. The hostname of the Ingress needs to be in the format of
<app>.<namespace>.<region>.ingress.coreweave.cloud. The example below demonstrates an Ingress called
my-app exposed via an Ingress in the ORD1 region for a namespace
apiVersion: networking.k8s.io/v1beta1kind: Ingressmetadata:annotations:cert-manager.io/cluster-issuer: letsencrypt-prodingress.kubernetes.io/force-ssl-redirect: "true"ingress.kubernetes.io/ssl-redirect: "true"traefik.ingress.kubernetes.io/redirect-entry-point: httpslabels:app.kubernetes.io/name: my-appname: my-appspec:rules:- host: my-app.tenant-test-default.ord1.ingress.coreweave.cloudhttp:paths:- backend:serviceName: my-appservicePort: httppath: /pathType: ImplementationSpecifictls:- hosts:- my-app.tenant-test-default.ord1.ingress.coreweave.cloudsecretName: my-app-tls # This secret is automatically created for you