Kubernetes - Docker Desktop and SSL Termination
This article will go over a minimal configuration Kubernetes for SSL/TLS termination with Docker Desktop. This article is mostly for my self and not finding an tutorial/article that had all this information in a single spot.
This article will be a list of commands and configurations that can be used to setup Docker Desktop. It will also include resources that can be used to expand on what could is not in the article.
Table of Contents
To start off you can use this table of contents to jump to any of the section provided by this article.
- Create Kubernetes Dashboard
- Configure TLS Keys and Ingress
- Create Http Echo Services
- Check that it Works
- Appendix
Create Kubernetes Dashboard
This section will be quick, showing how to get the Kubernetes Dashboard, a UX that can be accessed from the browser. Following the commands below expects you to have Kubernetes and Kubectl setup, and at least know a little bit of the CLI.
Run the commands below to setup the Kubernetes Dashboard in Kubernetes. You can checkout to file content in the appendix below.
# Create Base kubernetes-dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc6/aio/deploy/recommended.yaml
# Service - Dashboard Service Account
kubectl create -f ./001_create-new-service-account.yml
# Service - Dashboard Cluster Role Binding
kubectl create -f ./002_create-cluster-role-binding.yml
You should now be able to open a browser and navigate to: http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/overview?namespace=default. You will need to open the proxy to the Kubernetes cluster, the command is available below in Helpful Commands.
Configure TLS Keys and Ingress
Next we will add the secret key and certificate for our TLS to the Kubernetes cluster and also setup the Ingress for accessing our services eternally from the cluster. You will need to generate a cert and key for your domain, checkout the turorial here for generating them for the Nginx Ingress: Prerequisites - NGINX Ingress Controller
Here we create a generic secret key called "k8s-test-ingress.com", to match the domain name we will be tieing our Ingress domain too. Example file content is located below in the Appendix. We then use the deploy.yaml provided by the kubernetes/ingress-nginx repository to create a Cloud based Nginx Ingress.
# Create a secret container for our TLS files
kubectl create secret generic k8s-test-ingress.com --from-file=tls.crt=k8s-test-ingress.com.crt --from-file=tls.key=k8s-test-ingress.com.key
# Using kubernetes/ingress-nginx to create Cloud Ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.40.1/deploy/static/provider/cloud/deploy.yaml
Create Http Echo Services
Here we create the HTTP echo server services, this allows us to see some content and verify our settings are correct. We can then create an Ingress, this ingress has settings that tie it back to our secret TLS settings, and a rule that will direct traffic to the HTTP services. Example file content is located below in the Appendix.
# Http Echo Server Services
kubectl create -f ./003_create-http-service.yml
# Create HTTP Ingress
kubectl create -f ./004_create-http-ingress.yml
Check that it Works
To check that the configuration works navigate to, k8s-test-ingress.com, make sure your hosts file is updated. Include a line for 127.0.0.1 k8s-test-ingress.com
, this will redirect our browser to our Kubernetes Cluster.
Appendix
Resource Links Used
- Welcome - NGINX Ingress Controller - The Nginx Ingress Controller Setup
- Installation Guide - NGINX Ingress Controller - The Nginx Ingress Controller Installation Guide
- Learn Kubernetes Basics | Kubernetes - A basics Kubernetes tutorial
- Ingress | Kubernetes - Details about Services and Networking for Ingress Concepts
- WSL+Docker: Kubernetes on the Windows Desktop - Setting up of the Kubernetes using Docker Desktop for Window
Helpful Commands
Kubectl Proxy Command
This command will open a proxy from your machine to the Kubernetes Cluster, usually if you have any issues also having this running will fix them.
kubectl proxy
Kubectl Admin User Token Command
You will need to run this command below and use it to get an Access Token for the Dashboard.
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')
Example output from the above get access token command, you want the long encoded string from the Data > token: section.
~~~ bash Name: admin-user-token-hs6dt Namespace: kubernetes-dashboard Labels:
Annotations: kubernetes.io/service-account.name: admin-user
kubernetes.io/service-account.uid: 3fcb5af8-e776-4f81-82e3-1a2882099983
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 20 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImV4NzV6R0ljck1uUklpOGxYVk91bmhfZmpxZVlYV0h4STdDUV9PSGQwbTAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLWhzNmR0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIzZmNiNWFmOC1lNzc2LTRmODEtODJlMy0xYTI4ODIwOTk5ODMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.D2rj1pA0cNXqoa61NOXfv8A4EsHRZkLIAUr3fbgmz6W7yi95X8Ldd1sx1ytUBRSs7B-SkyxiPNTojOsouvbKpJ28jPGvINxjV7WWU_F0QHZK5M6iM-rAiHP5ckR6c_Qy6cbwDpoW2Cpc_7CP3Q6R3CcJEOMtd-u0_c_ZAb48y8KnR78IkKZPjh0YIDDmZONqSs3O2ESKdi_sKzckQ--Dcnti8vwPXIvNDExc30sNfFK22FM0UIU-Oa_Ur4Q4X6EjaedahvwoUFKpj3crAlFPYylv7zwsOQvi8Et3OF2c6j9ldTN9xivOzX8iLkNVFJlY5a_DjNWt7Kop_YmvleFvBA
~~~
Supplemental File Content
001_create-new-service-account.yml file content
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
002_create-cluster-role-binding.yml file content
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
003_create-http-service.yml file content
apiVersion: apps/v1
kind: Deployment
metadata:
name: http-svc
spec:
replicas: 1
selector:
matchLabels:
app: http-svc
template:
metadata:
labels:
app: http-svc
spec:
containers:
- name: http-svc
image: gcr.io/kubernetes-e2e-test-images/echoserver:2.1
ports:
- containerPort: 8080
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
---
apiVersion: v1
kind: Service
metadata:
name: http-svc
labels:
app: http-svc
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: http-svc
004_create-http-ingress.yml file content
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
# Enable client certificate authentication
# nginx.ingress.kubernetes.io/auth-tls-verify-client: "off"
# Create the secret containing the trusted ca certificates
# nginx.ingress.kubernetes.io/auth-tls-secret: "default/ca-secret"
# Specify the verification depth in the client certificates chain
# nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
# Specify an error page to be redirected to verification errors
# nginx.ingress.kubernetes.io/auth-tls-error-page: "http://www.mysite.com/error-cert.html"
# Specify if certificates are passed to upstream server
nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true"
name: nginx-test
namespace: default
spec:
rules:
- host: k8s-test-ingress.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /
tls:
- hosts:
- k8s-test-ingress.com
secretName: k8s-test-ingress.com
k8s-test-ingress.com.crt file content
-----BEGIN CERTIFICATE-----
MIIEVTCCAr2gAwIBAgIQfd5u56cRVZxIhH8h2Z2OXTANBgkqhkiG9w0BAQsFADB/
MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExKjAoBgNVBAsMIUNPRFlB
TkhPUk4tUENcY29keWFAQ09EWUFOSE9STi1QQzExMC8GA1UEAwwobWtjZXJ0IENP
RFlBTkhPUk4tUENcY29keWFAQ09EWUFOSE9STi1QQzAeFw0yMDEwMDMxMzUzNDFa
Fw0zMDEwMDMxMzUzNDFaMFUxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBj
ZXJ0aWZpY2F0ZTEqMCgGA1UECwwhQ09EWUFOSE9STi1QQ1xjb2R5YUBDT0RZQU5I
T1JOLVBDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAveL782jb3WBE
rOELGNG+aOmaM65UYYmRQsk4mJVRA4mkcV+6CP7zAeSIR00A8QAwPEhGPWVxZnLk
hl5/l1Q74VZeOV+Li8qARbkWFoRDBRGZDEa0u4VhG+Bk6znOdxrh5o2pGZHE78KC
qHdB3FfCJMMpLLmcmPE0NtfV6ScD6MyGF8cHgR4ioR4BE0MJ2YW7wMKWvDESI9Ti
CAvzqs/4p8GofIPnJtkPPYNzyjyYECtieFKSRf+AEgwS3Khwf00WtVCFHR6fyLkM
OtW251uh99ebEgfledEayL1YzjSmPHVhErCMWdLy1sRT7faIzSkr3OfMZKQGFEl2
8ADnbnaXlQIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYB
BQUHAwEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBQ4XbzEiX1Fp8N/oRfDSJbZ
tGYC2DAfBgNVHREEGDAWghRrOHMtdGVzdC1pbmdyZXNzLmNvbTANBgkqhkiG9w0B
AQsFAAOCAYEAWhDpGlalkY7Jeswq7/5uaPVH76E77na57KOZDyx7mz1rRZyqP9RV
GOv8hg+hr5ACYZ0MW/2tjV5AKvXeligKhMHmLIzkOfCf2hKlnxmqxzrN14Qmr+a6
iuQbu9GB+oPh2jZgq1jZrKf1G8FZ2hDmD899Ro9F32DS+aWq+BljLuSFtk/HE6zK
oOtLCPQCIs4C/aeIXD/j6GgXErkMDBG0JmpROcmN6NhtoXPnwyQGpvSwRw3RVWLz
zpExR1nPzkqgp5PW09icBIUEPrJ9gsTq3yt9+g9NCcrNmRY7kVzzXYDkcknJnWbj
OzETGN9CCDxKTEZMiLcAHqq8EgWj6G/cCTzQac6BRDenOCTyrPu4kX7cPjBFXVHs
jceHXyj7Imgv830eC1SPZK1qag4+D+V4Wdun8wY8VVEEmz/3y/VZtJPin0zmTpMm
RJ6mF76zzjazatXHe7LdicMCKgE2dVvlqdna2MYqss5X/n1zM4Ca8U20RqZeqLP7
hD4QyQB4D9Jl
-----END CERTIFICATE-----
k8s-test-ingress.com.key file content
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC94vvzaNvdYESs
4QsY0b5o6ZozrlRhiZFCyTiYlVEDiaRxX7oI/vMB5IhHTQDxADA8SEY9ZXFmcuSG
Xn+XVDvhVl45X4uLyoBFuRYWhEMFEZkMRrS7hWEb4GTrOc53GuHmjakZkcTvwoKo
d0HcV8IkwyksuZyY8TQ219XpJwPozIYXxweBHiKhHgETQwnZhbvAwpa8MRIj1OII
C/Oqz/inwah8g+cm2Q89g3PKPJgQK2J4UpJF/4ASDBLcqHB/TRa1UIUdHp/IuQw6
1bbnW6H315sSB+V50RrIvVjONKY8dWESsIxZ0vLWxFPt9ojNKSvc58xkpAYUSXbw
AOdudpeVAgMBAAECggEATvW4Nzt/UcraQ9lAuA1f1FhvWtY/GGAQG2l5M1nD2mi+
DLb1sQ/zFPJnCN8oaQ7e//I94wHv6d4U0Rsyi0bnr4gunkTwzixispuIZ8yP4eez
cLtmJCQOgX0J+haLmFOBZFG743oOHnUPx+XvaSTFAmx1DrgQOjjysWuG8/DZW1AY
PfxMmrz/G5da4kgW9SgK1oTJbZtqeZonKxsIHZp6mUd7asWraje9pfUgnPtQMlH3
IGMl94cRLZdtA1WBpHK9tLAZkOCysZhLg7q/j/M9x20hJNUbUz7MPco14oqcaCdw
lE3BHkiEd9ywUzCvbYeJ3EGdJPAo+AhWa3/iud1U8QKBgQDD8HVKER8RraFb1Qiz
UrklYRXo/TTCLz/vcrNVw+ne7KE6SuHB6pZWEhQo3rKIbbzoPMYfHRfCC/8V/4v8
RDwx0ic5e/M+T4x7eVQ5c+Ha4pcr18/vxu/dDJpUtTJdTFZlp2J2BJWYiKUlnr/m
Rt77CjQsaKu3AwYRkJuiBFuTmwKBgQD4F5H4I5dEH4B+EwapEU+THkJ0O8PWA6TC
cA0F1Dy1ogHDNJd0G1pIxCbmDGF4AMzaU/N/HwNkGZWMmcCvqAfRd2DsVGHLMEAE
3PO5skZvBOqutguemJhGXycTwm5S1PSgwKdtgdN6PZPs5GCoLXjAjNqwpMh+yUHB
2MeMChmsjwKBgQCDBFCJPDWYLo/MxgBRWCkxE2ABMP6MMegAhqPf32aMh5GvVs7q
SaBI4UHVqkOa8jX03F5mA6AVQsxIu12xSzcs4ScVSwp1Sd/X2GM3H4OQRx9qU55Y
6J8PIhQ4PAj3VcoXovs1iw80tXooU6RhqFYFaudEIqFfeIggSp+mkF9jrQKBgFzg
vhXuhRfMz1bjmo+62laScoB/S16YuJrORiHThfLdttk0nCqsfs1VGdbv9aFuc0Kd
QUBrBOL5rQIZIYjhWCP0FEYFhSMDakQnz9rKQhIX/h/wKUNzjzZxMvjzxkeeUALK
fSPDAb/2w6VhDkqH03gKg2i0GBdXExYWKQZlVZ1DAoGBALdeOR5oncjn4DdR1b8D
V+ba0j2Zsr1e49HD2XxQLXwSMDJkC8P4+o/jeLI6xiH0f6Ay/+D/MDH3Zf346r5k
0OX/FomX9vAZJ2MUeueBwSTGsXkMRk8NMMhyUECPpWjz4cR+XCz+OkJxhnlKntWe
m6K+NiiYev8m+c3cRaMJzvp9
-----END PRIVATE KEY-----