rewrite of ingress (#10958)

* rewrite of ingress

- reset and rewritten to provide more clarity and directness on what
  ingress is and does.

* cleanup from review

- also normalized Ingress -> ingress through-out
This commit is contained in:
Joseph Heck
2018-11-16 12:37:21 -08:00
committed by k8s-ci-robot
parent 6f3b8cbd9b
commit fe46040b2e
@@ -13,48 +13,90 @@ weight: 40
{{% capture body %}}
## Terminology
Throughout this doc you will see a few terms that are sometimes used interchangeably elsewhere, that might cause confusion. This section attempts to clarify them.
For the sake of clarity, this guide defines the following terms:
* Node: A single virtual or physical machine in a Kubernetes cluster.
* Cluster: A group of nodes firewalled from the internet, that are the primary compute resources managed by Kubernetes.
* Edge router: A router that enforces the firewall policy for your cluster. This could be a gateway managed by a cloud provider or a physical piece of hardware.
* Cluster network: A set of links, logical or physical, that facilitate communication within a cluster according to the [Kubernetes networking model](/docs/concepts/cluster-administration/networking/). Examples of a Cluster network include Overlays such as [flannel](https://github.com/coreos/flannel#flannel) or SDNs such as [OVS](https://www.openvswitch.org/).
* Cluster network: A set of links, logical or physical, that facilitate communication within a cluster according to the [Kubernetes networking model](/docs/concepts/cluster-administration/networking/).
* Service: A Kubernetes [Service](/docs/concepts/services-networking/service/) that identifies a set of pods using label selectors. Unless mentioned otherwise, Services are assumed to have virtual IPs only routable within the cluster network.
## What is Ingress?
Typically, services and pods have IPs only routable by the cluster network. All traffic that ends up at an edge router is either dropped or forwarded elsewhere. Conceptually, this might look like:
Ingress, added in Kubernetes v1.1, exposes HTTP and HTTPS routes from outside the cluster to
{{< link text="services" url="/docs/concepts/services-networking/service/" >}} within the cluster.
Traffic routing is controlled by rules defined on the ingress resource.
```none
internet
|
------------
[ Services ]
```
An Ingress is a collection of rules that allow inbound connections to reach the cluster services.
```
internet
|
[ Ingress ]
--|-----|--
[ Services ]
```
It can be configured to give services externally-reachable URLs, load balance traffic, terminate SSL, offer name based virtual hosting, and more. Users request ingress by POSTing the Ingress resource to the API server. An [Ingress controller](#ingress-controllers) is responsible for fulfilling the Ingress, usually with a loadbalancer, though it may also configure your edge router or additional frontends to help handle the traffic in an HA manner.
An ingress can be configured to give services externally-reachable URLs, load balance traffic, terminate SSL, and offer name based virtual hosting. An [ingress controller](#ingress-controllers) is responsible for fulfilling the ingress, usually with a loadbalancer, though it may also configure your edge router or additional frontends to help handle the traffic.
An ingress does not expose arbitrary ports or protocols. Exposing services other than HTTP and HTTPS to the internet typically
uses a service of type [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport) or
[Service.Type=LoadBalancer](/docs/concepts/services-networking/service/#loadbalancer).
## Prerequisites
Before you start using the Ingress resource, there are a few things you should understand. The Ingress is a beta resource, not available in any Kubernetes release prior to 1.1. You need an Ingress controller to satisfy an Ingress, simply creating the resource will have no effect.
{{< feature-state for_k8s_version="v1.1" state="beta" >}}
GCE/Google Kubernetes Engine deploys an ingress controller on the master. You can deploy any number of custom ingress controllers in a pod. You must annotate each ingress with the appropriate class, as indicated [here](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers) and [here](https://git.k8s.io/ingress-gce/examples/PREREQUISITES.md#ingress-class).
Before you start using an ingress, there are a few things you should understand. The ingress is a beta resource. You will need an ingress controller to satisfy an ingress, simply creating the resource will have no effect.
Make sure you review the [beta limitations](https://github.com/kubernetes/ingress-gce/blob/master/BETA_LIMITATIONS.md#glbc-beta-limitations) of this controller. In environments other than GCE/Google Kubernetes Engine, you need to [deploy a controller](https://git.k8s.io/ingress-nginx/README.md) as a pod.
GCE/Google Kubernetes Engine deploys an [ingress controller](#ingress-controllers) on the master. Review the
[beta limitations](https://github.com/kubernetes/ingress-gce/blob/master/BETA_LIMITATIONS.md#glbc-beta-limitations)
of this controller if you are using GCE/GKE.
In environments other than GCE/Google Kubernetes Engine, you may need to
[deploy an ingress controller](https://kubernetes.github.io/ingress-nginx/deploy/). There are a number of
[ingress controller](#ingress-controllers) you may choose from.
## Ingress controllers
In order for the ingress resource to work, the cluster must have an ingress controller running. This is unlike other types of controllers, which run as part of the `kube-controller-manager` binary, and are typically started automatically with a cluster. Choose the ingress controller implementation that best fits your cluster.
* Kubernetes as a project currently supports and maintains [GCE](https://git.k8s.io/ingress-gce/README.md) and
[nginx](https://git.k8s.io/ingress-nginx/README.md) controllers.
Additional controllers include:
* [Contour](https://github.com/heptio/contour) is an [Envoy](https://www.envoyproxy.io) based ingress controller
provided and supported by Heptio.
* F5 Networks provides [support and maintenance](https://support.f5.com/csp/article/K86859508)
for the [F5 BIG-IP Controller for Kubernetes](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest).
* [HAProxy](http://www.haproxy.org/) based ingress controller
[jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress) which is mentioned on the blog post
[HAProxy Ingress Controller for Kubernetes](https://www.haproxy.com/blog/haproxy_ingress_controller_for_kubernetes/).
[HAProxy Technologies](https://www.haproxy.com/) offers support and maintenance for HAProxy Enterprise and
the ingress controller [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress).
* [Istio](https://istio.io/) based ingress controller
[Control Ingress Traffic](https://istio.io/docs/tasks/traffic-management/ingress/).
* [Kong](https://konghq.com/) offers [community](https://discuss.konghq.com/c/kubernetes) or
[commercial](https://konghq.com/api-customer-success/) support and maintenance for the
[Kong Ingress Controllerfor Kubernetes](https://konghq.com/blog/kubernetes-ingress-controller-for-kong/).
* [NGINX, Inc.](https://www.nginx.com/) offers support and maintenance for the
[NGINX Ingress Controller for Kubernetes](https://www.nginx.com/products/nginx/kubernetes-ingress-controller).
* [Traefik](https://github.com/containous/traefik) is a fully featured ingress controller
([Let's Encrypt](https://letsencrypt.org), secrets, http2, websocket), and it also comes with commercial
support by [Containous](https://containo.us/services).
{{< note >}}
Review the documentation for your controller to find its specific support policy.
{{< /note >}}
You may deploy [any number of ingress controllers](https://git.k8s.io/ingress-nginx/docs/user-guide/multiple-ingress.md#multiple-ingress-controllers) within a cluster.
When you create an ingress, you should annotate each ingress with the appropriate
[`ingress-class`](https://git.k8s.io/ingress-gce/examples/PREREQUISITES.md#ingress-class) to indicate which ingress
controller should be used if more than one exists within your cluster.
If you do not define a class, your cloud provider may use a default ingress provider.
## The Ingress Resource
A minimal Ingress might look like:
A minimal ingress example:
```yaml
apiVersion: extensions/v1beta1
@@ -73,41 +115,41 @@ spec:
servicePort: 80
```
*POSTing this to the API server will have no effect if you have not configured an [Ingress controller](#ingress-controllers).*
__Lines 1-6__: As with all other Kubernetes resources, an ingress needs `apiVersion`, `kind`, and `metadata` fields.
For general information about working with config files, see [deploying applications](/docs/tasks/run-application/run-stateless-application-deployment/), [configuring containers](/docs/tasks/configure-pod-container/configure-pod-configmap/), [managing resources](/docs/concepts/cluster-administration/manage-deployment/).
Ingress frequently uses annotations to configure some options depending on the ingress controller, an example of which
is the [rewrite-target annotation](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md).
Different [ingress controller](#ingress-controllers) support different annotations. Review the documentation for
the ingress controller you are using to learn which annotations are supported and valid options.
__Lines 1-6__: As with all other Kubernetes config, an Ingress needs `apiVersion`, `kind`, and `metadata` fields. For general information about working with config files, see [deploying applications](/docs/tasks/run-application/run-stateless-application-deployment/), [configuring containers](/docs/tasks/configure-pod-container/configure-pod-configmap/), [managing resources](/docs/concepts/cluster-administration/manage-deployment/) and [ingress configuration rewrite](https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md).
__Lines 7-9__: Ingress [spec](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status)
has all the information needed to configure a loadbalancer or proxy server. Most importantly, it
contains a list of rules matched against all incoming requests. Ingress resource only supports rules
for directing http traffic.
__Lines 7-9__: Ingress [spec](https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status) has all the information needed to configure a loadbalancer or proxy server. Most importantly, it contains a list of rules matched against all incoming requests. Currently the Ingress resource only supports http rules.
__Lines 10-11__: Each http rule contains the following information:
__Lines 10-11__: Each http rule contains the following information: A host (e.g.: foo.bar.com, defaults to * in this example), a list of paths (e.g.: /testpath) each of which has an associated backend (test:80). Both the host and path must match the content of an incoming request before the loadbalancer directs traffic to the backend.
* An optional host. In this example, no host is specified, so the rule will apply to all inbound
HTTP traffic through the IP address that will be connected. If a host is provided, for example:
foo.bar.com, the rules will apply on to that host)
* a list of paths (e.g.: /testpath) each of which has an associated backend defined with a `serivceName`
and `servicePort`. Both the host and path must match the content of an incoming request before the
loadbalancer directs traffic to the referenced service.
__Lines 12-14__: A backend is a service:port combination as described in the [services doc](/docs/concepts/services-networking/service/). Ingress traffic is typically sent directly to the endpoints matching a backend.
__Lines 12-14__: A backend is a service:port combination as described in the [services doc](/docs/concepts/services-networking/service/).
Ingress traffic is typically sent directly to the endpoints matching a backend.
__Global Parameters__: For the sake of simplicity the example Ingress has no global parameters, see the [API reference](https://releases.k8s.io/{{< param "githubbranch" >}}/staging/src/k8s.io/api/extensions/v1beta1/types.go) for a full definition of the resource. One can specify a global default backend in the absence of which requests that don't match a path in the spec are sent to the default backend of the Ingress controller.
## Ingress controllers
In order for the Ingress resource to work, the cluster must have an Ingress controller running. This is unlike other types of controllers, which typically run as part of the `kube-controller-manager` binary, and which are typically started automatically as part of cluster creation. Choose the ingress controller implementation that best fits your cluster, or implement a new ingress controller.
* Kubernetes currently supports and maintains [GCE](https://git.k8s.io/ingress-gce/README.md) and [nginx](https://git.k8s.io/ingress-nginx/README.md) controllers.
* F5 Networks provides [support and maintenance](https://support.f5.com/csp/article/K86859508) for the [F5 BIG-IP Controller for Kubernetes](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest).
* [Kong](https://konghq.com/) offers [community](https://discuss.konghq.com/c/kubernetes) or [commercial](https://konghq.com/api-customer-success/) support and maintenance for the [Kong Ingress Controller for Kubernetes](https://konghq.com/blog/kubernetes-ingress-controller-for-kong/)
* [Traefik](https://github.com/containous/traefik) is a fully featured ingress controller
([Let's Encrypt](https://letsencrypt.org), secrets, http2, websocket...), and it also comes with commercial support by [Containous](https://containo.us/services)
* [NGINX, Inc.](https://www.nginx.com/) offers support and maintenance for the [NGINX Ingress Controller for Kubernetes](https://www.nginx.com/products/nginx/kubernetes-ingress-controller)
* [HAProxy](http://www.haproxy.org/) based ingress controller [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress) which is mentioned on this blog post [HAProxy Ingress Controller for Kubernetes](https://www.haproxy.com/blog/haproxy_ingress_controller_for_kubernetes/). [HAProxy Technologies](https://www.haproxy.com/) offers support and maintenance for HAProxy Enterprise and the ingress controller [jcmoraisjr/haproxy-ingress](https://github.com/jcmoraisjr/haproxy-ingress).
* [Istio](https://istio.io/) based ingress controller [Control Ingress Traffic](https://istio.io/docs/tasks/traffic-management/ingress/)
{{< note >}}
Review the documentation for your controller to find its specific support policy.
{{< /note >}}
A default backend is often configured in an ingress controller that will service any requests that don't match a path in the spec.
## Before you begin
The following document describes a set of cross-platform features exposed through the Ingress resource. Ideally, all Ingress controllers should fulfill this specification, but we're not there yet. We currently support and maintain [GCE](https://git.k8s.io/ingress-gce/README.md) and [nginx](https://git.k8s.io/ingress-nginx/README.md) controllers. If you use the F5 BIG-IP Controller, see [Use the BIG-IP Controller as a Kubernetes Ingress Controller](http://clouddocs.f5.com/containers/latest/kubernetes/kctlr-k8s-ingress-ctlr.html).
Ideally, all ingress controllers should fulfill this specification, but the various ingress
controllers operate slightly differently. The Kubernetes project supports and maintain
[GCE](https://git.k8s.io/ingress-gce/README.md) and [nginx](https://git.k8s.io/ingress-nginx/README.md)
ingress controllers.
{{< note >}}
Make sure you review your controller's specific docs so you understand the caveats.
Make sure you review your [ingress controller](#ingress-controllers)'s specific docs to understand the caveats.
{{< /note >}}
## Types of Ingress
@@ -115,8 +157,8 @@ Make sure you review your controller's specific docs so you understand the cavea
### Single Service Ingress
There are existing Kubernetes concepts that allow you to expose a single Service
(see [alternatives](#alternatives)), however you can do so through an Ingress
as well, by specifying a *default backend* with no rules.
(see [alternatives](#alternatives)). You can also do this with an ingress by specifying a
*default backend* with no rules.
{{< codenew file="service/networking/ingress.yaml" >}}
@@ -131,29 +173,32 @@ NAME HOSTS ADDRESS PORTS AGE
test-ingress * 107.178.254.228 80 59s
```
Where `107.178.254.228` is the IP allocated by the Ingress controller to satisfy
this Ingress.
Where `107.178.254.228` is the IP allocated by the ingress controller to satisfy
this ingress.
{{< note >}}
Ingress controllers and load balancers may take a minute or two to allocate an IP address. Until that time you
will often see the address listed as `<pending>`.
{{< /note >}}
### Simple fanout
As described previously, Pods within kubernetes have IPs only visible on the
cluster network, so we need something at the edge accepting ingress traffic and
proxying it to the right endpoints. This component is usually a highly available
loadbalancer. An Ingress allows you to keep the number of loadbalancers down
A fanout configuration routes traffic from a single IP address to more than one service, based on the HTTP URI being requested.
An ingress allows you to keep the number of loadbalancers down
to a minimum. For example, a setup like:
```shell
foo.bar.com -> 178.91.123.132 -> / foo s1:80
/ bar s2:80
foo.bar.com -> 178.91.123.132 -> / foo service1:4200
/ bar service2:8080
```
would require an Ingress such as:
would require an ingress such as:
```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
name: simple-fanout-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
@@ -163,22 +208,22 @@ spec:
paths:
- path: /foo
backend:
serviceName: s1
servicePort: 80
serviceName: service1
servicePort: 4200
- path: /bar
backend:
serviceName: s2
servicePort: 80
serviceName: service2
servicePort: 8080
```
When you create the Ingress with `kubectl create -f`:
When you create the ingress with `kubectl create -f`:
```shell
kubectl describe ingress test
kubectl describe ingress simple-fanout-example
```
```shell
Name: test
Name: simple-fanout-example
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
@@ -186,8 +231,8 @@ Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo s1:80 (10.8.0.90:80)
/bar s2:80 (10.8.0.91:80)
/foo service1:4200 (10.8.0.90:4200)
/bar service2:8080 (10.8.0.91:8080)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
@@ -196,18 +241,19 @@ Events:
Normal ADD 22s loadbalancer-controller default/test
```
The Ingress controller will provision an implementation specific loadbalancer
that satisfies the Ingress, as long as the services (`s1`, `s2`) exist.
The ingress controller will provision an implementation specific loadbalancer
that satisfies the ingress, as long as the services (`s1`, `s2`) exist.
When it has done so, you will see the address of the loadbalancer at the
Address field.
{{< note >}}
You need to create a default-http-backend [Service](/docs/concepts/services-networking/service/) if necessary.
Depending on the [ingress controller](#ingress-controllers) you are using, you may need to
create a default-http-backend [Service](/docs/concepts/services-networking/service/).
{{< /note >}}
### Name based virtual hosting
Name-based virtual hosts use multiple host names for the same IP address.
Name-based virtual hosts support routing HTTP traffic to multiple host names at the same IP address.
```none
foo.bar.com --| |-> foo.bar.com s1:80
@@ -215,45 +261,45 @@ foo.bar.com --| |-> foo.bar.com s1:80
bar.foo.com --| |-> bar.foo.com s2:80
```
The following Ingress tells the backing loadbalancer to route requests based on
The following ingress tells the backing loadbalancer to route requests based on
the [Host header](https://tools.ietf.org/html/rfc7230#section-5.4).
```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: s1
serviceName: service1
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: s2
serviceName: service2
servicePort: 80
```
__Default Backends__: An Ingress with no rules, like the one shown in the previous
__Default Backends__: An ingress with no rules, like the one shown in the previous
section, sends all traffic to a single default backend. You can use the same
technique to tell a loadbalancer where to find your website's 404 page, by
specifying a set of rules *and* a default backend. Traffic is routed to your
default backend if none of the Hosts in your Ingress match the Host in the
default backend if none of the Hosts in your ingress match the Host in the
request header, and/or none of the paths match the URL of the request.
### TLS
You can secure an Ingress by specifying a [secret](/docs/concepts/configuration/secret)
that contains a TLS private key and certificate. Currently the Ingress only
You can secure an ingress by specifying a [secret](/docs/concepts/configuration/secret)
that contains a TLS private key and certificate. Currently the ingress only
supports a single TLS port, 443, and assumes TLS termination. If the TLS
configuration section in an Ingress specifies different hosts, they will be
configuration section in an ingress specifies different hosts, they will be
multiplexed on the same port according to the hostname specified through the
SNI TLS extension (provided the Ingress controller supports SNI). The TLS secret
SNI TLS extension (provided the ingress controller supports SNI). The TLS secret
must contain keys named `tls.crt` and `tls.key` that contain the certificate
and private key to use for TLS, e.g.:
@@ -264,46 +310,54 @@ data:
tls.key: base64 encoded key
kind: Secret
metadata:
name: testsecret
name: testsecret-tls
namespace: default
type: Opaque
```
Referencing this secret in an Ingress will tell the Ingress controller to
secure the channel from the client to the loadbalancer using TLS:
Referencing this secret in an ingress will tell the ingress controller to
secure the channel from the client to the loadbalancer using TLS. You need to make
sure the TLS secret you created came from a certificate that contains a CN
for `sslexample.foo.com`.
```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: no-rules-map
name: tls-example-ingress
spec:
tls:
- secretName: testsecret
backend:
serviceName: s1
servicePort: 80
- hosts: sslexample.foo.com
secretName: testsecret-tls
rules:
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
```
Note that there is a gap between TLS features supported by various Ingress
{{< note >}}
There is a gap between TLS features supported by various ingress
controllers. Please refer to documentation on
[nginx](https://git.k8s.io/ingress-nginx/README.md#https),
[GCE](https://git.k8s.io/ingress-gce/README.md#frontend-https), or any other
platform specific Ingress controller to understand how TLS works in your environment.
platform specific ingress controller to understand how TLS works in your environment.
{{< /note >}}
### Loadbalancing
An Ingress controller is bootstrapped with some load balancing policy settings
that it applies to all Ingress, such as the load balancing algorithm, backend
An ingress controller is bootstrapped with some load balancing policy settings
that it applies to all ingress, such as the load balancing algorithm, backend
weight scheme, and others. More advanced load balancing concepts
(e.g. persistent sessions, dynamic weights) are not yet exposed through the
Ingress. You can still get these features through the
ingress. You can still get these features through the
[service loadbalancer](https://github.com/kubernetes/ingress-nginx).
With time, we plan to distill load balancing patterns that are applicable
cross platform into the Ingress resource.
It's also worth noting that even though health checks are not exposed directly
through the Ingress, there exist parallel concepts in Kubernetes such as
through the ingress, there exist parallel concepts in Kubernetes such as
[readiness probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/)
which allow you to achieve the same end result. Please review the controller
specific docs to see how they handle health checks (
@@ -312,7 +366,7 @@ specific docs to see how they handle health checks (
## Updating an Ingress
Say you'd like to add a new Host to an existing Ingress, you can update it by editing the resource:
To update an existing ingress to add a new Host, you can update it by editing the resource:
```shell
kubectl describe ingress test
@@ -362,7 +416,8 @@ spec:
..
```
Saving the yaml will update the resource in the API server, which should tell the Ingress controller to reconfigure the loadbalancer.
Saving the yaml will update the resource in the API server, which should tell the
ingress controller to reconfigure the loadbalancer.
```shell
kubectl describe ingress test
@@ -388,28 +443,30 @@ Events:
Normal ADD 45s loadbalancer-controller default/test
```
You can achieve the same by invoking `kubectl replace -f` on a modified Ingress yaml file.
You can achieve the same by invoking `kubectl replace -f` on a modified ingress yaml file.
## Failing across availability zones
Techniques for spreading traffic across failure domains differs between cloud providers. Please check the documentation of the relevant Ingress controller for details. Please refer to the federation [doc](/docs/concepts/cluster-administration/federation/) for details on deploying Ingress in a federated cluster.
Techniques for spreading traffic across failure domains differs between cloud providers.
Please check the documentation of the relevant [ingress controller](#ingress-controllers) for
details. You can also refer to the [federation documentation](/docs/concepts/cluster-administration/federation/)
for details on deploying ingress in a federated cluster.
## Future Work
* Various modes of HTTPS/TLS support (e.g.: SNI, re-encryption)
* Requesting an IP or Hostname via claims
* Combining L4 and L7 Ingress
* More Ingress controllers
Please track the [L7 and Ingress proposal](https://github.com/kubernetes/kubernetes/pull/12827) for more details on the evolution of the resource, and the [Ingress repository](https://github.com/kubernetes/ingress/tree/master) for more details on the evolution of various Ingress controllers.
Track [SIG Network](https://github.com/kubernetes/community/tree/master/sig-network)
for more details on the evolution of the ingress and related resources. You may also track the
[ingress repository](https://github.com/kubernetes/ingress/tree/master) for more details on the
evolution of various ingress controllers.
## Alternatives
You can expose a Service in multiple ways that don't directly involve the Ingress resource:
You can expose a Service in multiple ways that don't directly involve the ingress resource:
* Use [Service.Type=LoadBalancer](/docs/concepts/services-networking/service/#loadbalancer)
* Use [Service.Type=NodePort](/docs/concepts/services-networking/service/#nodeport)
* Use a [Port Proxy](https://git.k8s.io/contrib/for-demos/proxy-to-service)
{{% /capture %}}
{{% capture whatsnext %}}