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
CodePudding user response:
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.
CodePudding user response:
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.