skip to Main Content

Usually when I deploy a Simple HTTPS server in VM I do

Create Certificate with ip

$ openssl req -new -x509 -keyout private_key.pem -out public_cert.pem -days 365 -nodes
Generating a RSA private key
..+++++
.................................+++++
writing new private key to 'private_key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:IN
State or Province Name (full name) [Some-State]:Tamil Nadu
Locality Name (eg, city) []:Chennai
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Company ,Inc
Organizational Unit Name (eg, section) []: company division
Common Name (e.g. server FQDN or YOUR name) []:35.222.65.55 <----------------------- this ip should be server ip very important
Email Address []:

Start Simple HTTPS Python Server

# libraries needed: 
from http.server import HTTPServer, SimpleHTTPRequestHandler
import ssl , socket

# address set
server_ip = '0.0.0.0'
server_port = 3389

# configuring HTTP -> HTTPS
httpd = HTTPServer((server_ip, server_port), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile='./public_cert.pem',keyfile='./private_key.pem', server_side=True)
httpd.serve_forever()

now this works fine for

Curl from local

curl --cacert /Users/padmanabanpr/Downloads/public_cert.pem --cert-type PEM   https://35.222.65.55:3389

now how to deploy the same to kubernetes cluster and access via load-balancer?

Assuming i have

  • public docker nginx container with write access , python3 , and this python https server file
  • deployment yaml with nginx
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-nginx-server
  labels:
    app: external-nginx-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: external-nginx-server
  template:
    metadata:
      labels:
        app: external-nginx-server
    spec:
      containers:
      - name: external-nginx-server
        image: <docker nginx public image>
        ports:
        - containerPort: 3389

---
kind: Service
apiVersion: v1
metadata:
  name: external-nginx-service
spec:
  selector:
    app: external-nginx-server
  ports:
  - protocol: TCP
    port: 443
    name: https
    targetPort: 3389
  type: LoadBalancer

2

Answers


  1. To do the same in Kubernetes you need to create a Secret with the certificate in it, like this one:

    kind: Secret
    apiVersion: v1
    metadata:
      name: my-tls-secret
    data:
      tls.crt: BASE64-ENCODED CERTIFICATE
      tls.key: BASE64-ENCODED KEY
    

    Then you need to mount it inside all the pods that require it:

    # deployment.yml
    volumes:
    - name: my-tls
      secret:
        secretName: my-tls-secret
    containers:
    - name: external-nginx-server
      image: <docker nginx public image>
      volumeMounts:
      - name: my-tls
        # Here will appear the "tls.crt" and "tls.key", defined in the secret's data block.
        # Kubernetes will take care to decode the contents and make them separate files.
        mountPath: /etc/nginx/tls
    

    But this is pain to manage manually! You will have to track the certificate expiration date, renew the secret, restart the pods… There is a better way.

    You can install an ingress conroller (NGINX, for example) and the certificate manager for Kubernetes. The certificate manager will take care to issue certificates (via LetsEncrypt or other providers), save them as secrets, and update them before the expiration date.

    An ingress controller is a centralized endpoint to your cluster. You can make it to handle connections to multiple applications, just like with normal NGINX installation. The benefit of it in this case is that you will not have to mount certificates if there is a new one or an update. The ingress controller will take care of that for you.

    The links above will lead you to the documentation, where you can find the details on how to install and use these.

    Login or Signup to reply.
  2. Great answer by anemyte, if you want to just try for testing purpose

    i would suggest creating the Docker image of your application and running it without the Nginx on Kubernetes.

    there is no need to run the Nginx deployment you can directly expose the service like you have done service type LoadBalancer.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: python-docker
      labels:
        app: python-docker
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: python-docker
      template:
        metadata:
          labels:
            app: python-docker
        spec:
          containers:
          - name: python-docker
            image: <Your image form docker hub or ECR or any>
            ports:
            - containerPort: 3389
    
    ---
    kind: Service
    apiVersion: v1
    metadata:
      name: python-docker
    spec:
      selector:
        app: python-docker
      ports:
      - protocol: TCP
        port: 443
        name: https
        targetPort: 3389
      type: LoadBalancer
    

    this YAML will same give you IP of Loadblancer and you can use it for testing.

    If you have a requirement of running the multiple service and want single point to handle request you can install the Nginx ingress controller.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search