Last modified February 20, 2018

Accessing Pods and Services from the Outside

Once you have a Pod or Service running on your cluster, you might want to access it from outside your cluster. There’s currently three ways to do that:

Setting up a public Ingress

Before we explain how to set up Ingress for a Service, please read the next section carefully to make sure the guide matches your situation as a Giant Swarm user.

Knowing your Ingress base domain

Setting up Ingress means to make Services publicly available via DNS names. For an application facing the public, you will eventually want to set up names ending in your own domain.

However, for development or test purposes, you can use the fact that every Giant Swarm installation maps to a DNS zone. We call this the Ingress Base Domain.

In our cloud installation, for example, the Ingress Base Domain is

So Ingresses can automatically use the following DNS name schema:

We’ll explain in a minute what PREFIX and CLUSTER_ID are.

Adapt this tutorial for you

To make the rest of the tutorial match your situation, please set your Ingress Base Domain in the field below:


Setting up Ingress

Your Giant Swarm cluster comes with an Ingress Controller based on NGINX, which we run for you in your clusters. You can expose Services publicly by setting up a simple Ingress. You can do this with an ingress manifest.

Let’s look at the following YAML, which you can use as a template for your Ingress manifest:

apiVersion: extensions/v1beta1
kind: Ingress
  namespace: NAMESPACE
  - host:
      - path: /
          serviceName: SERVICE_NAME
          servicePort: SERVICE_PORT

All parts in uppercase letters are placeholders, to be replaced according to your individual requirements. In detail:

  • INGRESS_NAME: This name identifies the ingress within your namespace. As with all other kubernetes, it’s up to you how you name it.
  • NAMESPACE: The namespace of the service you’d like to expose. The ingress must reside in the same namespace, so it’s useful to make it part of the metadata in the manifest.
  • PREFIX: A subdomain name of your choice. This must be unique among all ingresses of this cluster. If you like, you can make this the same as INGRESS_NAME.
  • CLUSTER_ID: The ID of the Kubernetes cluster the service you’d like to expose is running on. This should be a string consisting of five letters and numbers.
  • SERVICE_NAME: The name of your service, as defined in the attribute of your service’s manifest.
  • SERVICE_PORT: The port of your service to connect to, as defined in the spec.ports array of your service’s manifest.

The host attribute defines the fully qualified host name via which your service will be accessible. As you can see, it consists of your self-chosen prefix, your cluster ID, and finally the ingress base domain.

Once you adapted the template above to according to your requirements and stored it to a file named e. g. ingress.yaml, you can create your Ingress using kubectl:

kubectl apply -f ingress.yaml

It will take a moment for the Ingress to be created. You can look up the new Ingress using kubectl like this (replacing NAMESPACE and INGRESS_NAME):

kubectl -n NAMESPACE describe ing/INGRESS_NAME

Once the Ingress is up, you will be able to access your service publicly at a URL like this (again replacing the placeholders):

Currently, this is limited to exposing by default on port 80. Support for TLS will be added soon.

For additional features and options, please see our documentation around Advanced Ingress Configuration.

Forwarding an authenticated port with kubectl port-forward

Forwarding a port with kubectl is fairly easy, however, it only works with single Pods and not with Services. Thus you need the exact pod name. You can either get this manually by running

kubectl -n NAMESPACE get pods

and looking for the right pod name. Or by running following script.

POD=$(kubectl get pods -n NAMESPACE --selector <label-key>=<label-value> \
    -o template --template '{{range .items}}{{}} {{.status.phase}}{{"\n"}}{{end}}' \
    | grep Running | head -1 | cut -f1 -d' ')

Be sure to have your Pod labeled accordingly so you can find it with the above selector.

After this you can run

kubectl port-forward -n NAMESPACE ${POD} <local-port>:<pod-port>

or to have it running in the background

kubectl port-forward -n NAMESPACE $POD <local-port>:<pod-port> &

Now you can access your Pod locally via localhost:<local-port>.

Access any service from through the API proxy

The Kubernetes API comes with an inbuilt proxy, which you can use to access Services deployed on your cluster. The URL schema is

If the service does not use a named port, PORT_NAME must be the port number.

Access will only be granted to clients which

  • trust the API’s server certificate, which means they trust the Certificate Authority (CA) that signed it and
  • provide a valid client certificate.

The Giant Swarm web user interface shows you how to obtain the certificate files.

To make these certificates available to HTTP clients/browsers, see our guide Establishing Trust to Your Cluster’s CA and Importing Certificates which explains this for different clients on various platforms.


Assuming you have a service elasticsearch with a port named es in the logging namespace, you could access the Elasticsearch index stats API like this:

curl -v -u username:password \
  --cacert ./ca.pem \
  --cert ./crt.pem \
  --key ./key.pem \

Further reading