kubernetes https ingress rule

4/1/2020

I have defined in rancher an external service and an ingress rule that allows me to access my service using: http://test.mycluster.ml

What I should change to make https://test.mycluster.ml instead of http?

Now I have this:

apiVersion: v1
kind: Service
metadata:
  name: test
  namespace: default
spec:
  externalName: main.mycluster.ml
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  sessionAffinity: None
  type: ExternalName

and an ingress rule like this:

apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    annotations:
      nginx.ingress.kubernetes.io/upstream-vhost: main.mycluster.ml
    name: test
    namespace: default
  spec:
    rules:
    - host: test.mycluster.ml
      http:
        paths:
        - backend:
            serviceName: test
            servicePort: 80

How to do it?

I have tried changing the service to be on port 443 and target 80 and the ingress to be on 443 but no success

 apiVersion: v1
    kind: Service
    metadata:
      name: test
      namespace: default
    spec:
      externalName: main.mycluster.ml
      ports:
      - port: 443
        protocol: TCP
        targetPort: 80
      sessionAffinity: None
      type: ExternalName

and an ingress rule like this:

apiVersion: extensions/v1beta1
  kind: Ingress
  metadata:
    annotations:
      nginx.ingress.kubernetes.io/upstream-vhost: main.mycluster.ml
    name: test
    namespace: default
  spec:
    rules:
    - host: test.mycluster.ml
      http:
        paths:
        - backend:
            serviceName: test
            servicePort: 443
-- bogdanbrudiu
kubernetes
nginx-ingress
rancher

3 Answers

4/1/2020

You can't simply convert your ingress by changing the port from 80 to 443.

Firstly you have to install the NGINX Ingress controller and than Configure TLS with Let's Encrypt certificates and cert-manager. You can check these documents with more detailed steps on how to implement this solution:

Secure Kubernetes Services with Ingress, TLS and Let's Encrypt

Deploying Nginx Ingress and a Cert-Manager Controller on GKE using Helm 3

-- mWatney
Source: StackOverflow

4/1/2020

At the present time, your ingress server receives a request an unencrypted request on port 80 and forward it to the port 80 of your service.

So if you want to switch to encrypted 443 TCP port (aka https):

  • is the firewall / security group in front of the ingress server authorizes request to port 443 ?
  • is that your ingress server or your pod(s) which start the SSL connection ?
  • if this is the ingress, you need to configure it to accept SSL connection and set a certificate for the domain test.mycluster.ml
  • if this is the pod(s), you need to configure them to accept SSL connection and set a certificate for the domain test.mycluster.ml
-- Kartoch
Source: StackOverflow

4/8/2020

This looks like bad practice (tls termination for incoming requests while outgoing requests are still in plain http). Please take a look at usage of service type: ExternlName - in the links below- for comunicating internal services with external services) however:

  • Assuming you are using nginx-ingress controller maintained by kubernetes community.
  • For service type: ExternalName the cluster DNS Service returns a CNAME record with the value of value specified in spec.externalName. In your example specified ports will not take an effect:

spec:
  externalName: main.mycluster.ml
  ports:
  - port: 443
    protocol: TCP
    targetPort: 80
  • Example using service type: externalName. Please take a look at spec.tls part:

apiVersion: v1
kind: Service
metadata:
  name: example
spec:
  type: ExternalName
  externalName: example.com
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/upstream-vhost: example.com    # add custom your upstream host
spec:
  rules:
  - host: xxx.xx
    http:
      paths:
      - backend:
          serviceName: example
          servicePort: 80
        path: /
  tls:                    # missing tls part
  - hosts:                 
    - xxx.xx
    secretName: api-cert  

In this example by default the controller redirects to HTTPS if TLS is enabled for that ingress

In default controller configuration this parameter looks like: nginx.ingress.kubernetes.io/ssl-redirect: "true"

Additional information:


openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE} -out ${CERT_FILE} -subj "/CN=${HOST}/O=${HOST}"
  • Create kubernetes tls secret

kubectl create secret tls api-cert --key ${KEY_FILE} --cert ${CERT_FILE}
  • Configure ingress resource with spec.tls section (host and tls secret)

Please keep in mind that using kubernetes service type: ExternalName with ingress servicePort: 443 will try to reach your external domain with 443 port and (if the external service is listening on 80 port this solution will not work).

As workaround you can use Service without selector:


kind: Service
apiVersion: v1
metadata:
 name: example2
spec:
 ports:
 - port: 443
   targetPort: 80
---
kind: Endpoints
apiVersion: v1
metadata:
 name: example2
subsets:
 - addresses:
     - ip: 93.184.216.34
   ports:
     - port: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/upstream-vhost: example.com    # add custom your upstream host
spec:
  rules:
  - host: xxx.xx
    http:
      paths:
      - backend:
          serviceName: example2
          servicePort: 443
        path: /
  tls:
  - hosts:
    - xxx.xx
    secretName: api-cert

Use kubectl describe ingress <your_ingress> take a look at he outgoing backend_service with applied port.

Rules:
  Host             Path  Backends
  ----             ----  --------
  xxx.xx  
                   /   example2:443 (93.184.216.34:80)

Hope this help

-- Hanx
Source: StackOverflow