<p>I am trying to create an API that serves HTTPS traffic publicly and is reachable by an IP address (not the domain), using a GKE cluster. Docker images have been tested locally. They were capable of serving HTTPS on their own, but as far as I've come to realize, this is not necessary for the setup that I am imagining.</p>

<p>So what I've come up with so far is to have a Kubernetes Service exposing it's 8443 port and having an Ingress load balancer mapping to that port and using self-signed certificates created using <a href="https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-multi-ssl#creating_secrets" rel="nofollow noreferrer">this tutorial</a> - <code>basic-ingress-secret</code> referred in the template. The only thing I have skipped is the domain binding given I am not in the possession of a domain. I hoped it would bind the certificate to the external IP, but this is unfortunately not the case (have tried to attach an IP to a CN of the certificate, as some users have noted <a href="https://stackoverflow.com/questions/1095780/are-ssl-certificates-bound-to-the-servers-ip-address">here</a>).</p>

<p>This is my yaml for service:</p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  name: some-node
spec:
  selector:
    app: some
  ports:
  - protocol: "TCP"
    port: 8443
    targetPort: 8443
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: some-node-deploy
spec:
  selector:
    matchLabels:
      app: some
  replicas: 3
  template:
    metadata:
      labels:
        app: some
    spec:
      containers:
      - name: some-container
        image: "gcr.io/some-27417/some:latest"
</code></pre>

<p>This is my yaml for Ingress:</p>

<pre><code>apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: basic-ingress
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: basic-ingress-secret
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: some-node
          servicePort: 8443
</code></pre>

<p>It is way simpler than these documentations explain.</p>

<p>1.- Create the self-signed certs</p>

<pre><code>openssl req -newkey rsa:2048 -nodes -keyout tls.key -out tls.csr
openssl x509 -in tls.csr -out tls.crt -req -signkey tls.key
</code></pre>

<p>2.- Create the secret</p>

<pre><code>kubectl create secret tls basic-ingress-secret --cert tls.crt --key tls.key
</code></pre>

<p>3.- Create the Ingress object</p>

<pre><code>apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: basic-ingress
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: basic-ingress-secret
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: some-node
          servicePort: 8443
</code></pre>

<p>Note: To make is work on GKE, your service must be of type <code>NodePort</code></p>

<pre><code>$ kubectl describe svc some-node
Name:                     some-node
Namespace:                default
Labels:                   run=nginx
Annotations:              &lt;none&gt;
Selector:                 run=nginx
Type:                     NodePort
IP:                       10.60.6.214
Port:                     &lt;unset&gt;  8443/TCP
TargetPort:               80/TCP
NodePort:                 &lt;unset&gt;  30250/TCP
Endpoints:                10.56.0.17:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   &lt;none&gt;
</code></pre>
