Expose port 80 on Digital Ocean's managed Kubernetes without a load balancer

You can deploy an Ingress configured to use the host network and port 80/443.

  1. DO's firewall for your cluster doesn't have 80/443 inbound open by default.

    If you edit the auto-created firewall the rules will eventually reset themselves. The solution is to create a separate firewall also pointing at the same Kubernetes worker nodes:

$ doctl compute firewall create \
--inbound-rules="protocol:tcp,ports:80,address:0.0.0.0/0,address:::/0 protocol:tcp,ports:443,address:0.0.0.0/0,address:::/0" \
--tag-names=k8s:CLUSTER_UUID \
--name=k8s-extra-mycluster

(Get the CLUSTER_UUID value from the dashboard or the ID column from doctl kubernetes cluster list)

  1. Create the nginx ingress using the host network. I've included the helm chart config below, but you could do it via the direct install process too.

EDIT: The Helm chart in the above link has been DEPRECATED, Therefore the correct way of installing the chart would be(as per the new docs) is :

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

After this repo is added & updated

# For Helm 2
$ helm install stable/nginx-ingress --name=myingress -f myingress.values.yml

# For Helm 3
$ helm install myingress stable/nginx-ingress -f myingress.values.yml

#EDIT: The New way to install in helm 3
helm install myingress ingress-nginx/ingress-nginx -f myingress.values.yaml

myingress.values.yml for the chart:

---
controller:
  kind: DaemonSet
  hostNetwork: true
  dnsPolicy: ClusterFirstWithHostNet
  daemonset:
    useHostPort: true
  service:
    type: ClusterIP
rbac:
  create: true
  1. you should be able to access the cluster on :80 and :443 via any worker node IP and it'll route traffic to your ingress.

  2. since node IPs can & do change, look at deploying external-dns to manage DNS entries to point to your worker nodes. Again, using the helm chart and assuming your DNS domain is hosted by DigitalOcean (though any supported DNS provider will work):

# For Helm 2
$ helm install --name=mydns -f mydns.values.yml stable/external-dns

# For Helm 3
$ helm install mydns stable/external-dns -f mydns.values.yml

mydns.values.yml for the chart:

---
provider: digitalocean
digitalocean:
  # create the API token at https://cloud.digitalocean.com/account/api/tokens
  # needs read + write
  apiToken: "DIGITALOCEAN_API_TOKEN"
domainFilters:
  # domains you want external-dns to be able to edit
  - example.com
rbac:
  create: true
  1. create a Kubernetes Ingress resource to route requests to an existing Kubernetes service:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: testing123-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: testing123.example.com             # the domain you want associated
      http:
        paths:
          - path: /
            backend:
              serviceName: testing123-service  # existing service
              servicePort: 8000                # existing service port
  1. after a minute or so you should see the DNS records appear and be resolvable:
$ dig testing123.example.com             # should return worker IP address
$ curl -v http://testing123.example.com  # should send the request through the Ingress to your backend service

(Edit: editing the automatically created firewall rules eventually breaks, add a separate firewall instead).