Working Jafner.dev with TLS

- TLS for hello, hello2, and dndtools
  - Documentation for adding services
This commit is contained in:
Joey Hafner 2023-03-29 23:52:38 -07:00
parent c5b2acf93b
commit 0ea8a467e1
12 changed files with 299 additions and 0 deletions

44
docs/Jafner-dev on GKE.md Normal file
View File

@ -0,0 +1,44 @@
# Exercise: jafner.dev on GKE
[Cert-Manager - Deploy cert-manager on Google Kubernetes Engine](https://cert-manager.io/docs/tutorials/getting-started-with-cert-manager-on-google-kubernetes-engine-using-lets-encrypt-for-ingress-ssl/)
## Setting Up Initial Services
1. Create cluster `gcloud container clusters create jafner-dev --preemptible --num-nodes=3`
This cluster is preemptible, which means it's basically for testing and will kill itself within 24 hours. This command will take a few minutes to create the cluster.
2. Create the example hello and hello2 deployments: `kubectl apply -f ./hello/Deployment.yaml -f ./hello2/Deployment.yaml`
3. Create the example hello and hello2 internal services: `kubectl apply -f ./hello/Service.yaml -f ./hello2/Service.yaml`
4. Create a public global static IP for the cluster to use: `gcloud compute addresses create web-ip --global`
This step is applied across the GCP project and is not necessary for a new cluster.
5. Open [Google Domains for jafner.dev](https://domains.google.com/registrar/jafner.dev/dns?hl=en) and ensure the A records for `*.jafner.dev` and `jafner.dev` are pointed at the correct IP address.
6. Create the Ingress without TLS: `kubectl apply -f ./Ingress-noTLS.yaml`
Once this ingress is created, the services should be internet accessible by domain name. Try `curl http://hello.jafner.dev` and `curl http://hello2.jafner.dev`.
7. Install cert-manager: `kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.2/cert-manager.yaml` (We use the generic merged manifest here).
After this is done, you can use `kubectl explain` for the new CustomResourceDefinitions `Certificate`, `CertificateRequest`, and `Issuer`, which are installed with Cert-manager.
8. Create staging and production Issuers for LetsEncrypt: `kubectl apply -f ./cert-manager/Issuer.yaml`
9. Create empty secret for storing SSL certificate: `kubectl apply -f ./cert-manager/Secret.yaml`
10. Apply the Ingress with TLS configured with the staging issuer: `kubectl apply -f Ingress-staging.yaml`
It will take several minutes for the background process of acquiring and loading the certificate to complete. You can check on the process with `curl -v --insecure https://hello.jafner.dev`. While the process is running, you will get an error code 35 with `SSL_ERROR_SYSCALL`. Once the process is complete, curl will return verbose certificate information and the "Hello, world!" message from the server.
11. Apply the Ingress with TLS configured with the production issuer: `kubectl apply -f Ingress.yaml`
This process will take several minutes like the previous one. Once it is complete, you should be able to access `https://hello.jafner.dev` and `https://hello2.jafner.dev` by browser.
## Adding A New Service: `dndtools`
1. Deploy the new service: `kubectl apply -f ./dndtools/Deployment.yaml -f ./dndtools/Service.yaml`
2. Edit `Ingress.yaml` to configure the new application.
1. Add the new host to `spec.tls.hosts` (e.g. 5e.jafner.dev).
2. Add a stanza to `spec.rules` for the new host. For example:
```
spec:
rules:
- host: "5e.jafner.dev"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: dndtools
port:
number: 80
```
3. Apply the edited `Ingress.yaml`: `kubectl apply -f Ingress.yaml` and wait for the changes to apply. Once changes are applied, the new service will be accessible in the browser at `https://5e.jafner.dev`.
Done!

View File

@ -0,0 +1,30 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
kubernetes.io/ingress.class: gce
kubernetes.io/ingress.allow-http: "true"
kubernetes.io/ingress.global-static-ip-name: web-ip
spec:
rules:
- host: "hello.jafner.dev"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello
port:
number: 8080
- host: "hello2.jafner.dev"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello2
port:
number: 8080

View File

@ -0,0 +1,36 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
kubernetes.io/ingress.class: gce
kubernetes.io/ingress.allow-http: "true"
kubernetes.io/ingress.global-static-ip-name: web-ip
cert-manager.io/issuer: letsencrypt-production
spec:
tls:
- secretName: web-ssl
hosts:
- hello.jafner.dev
- hello2.jafner.dev
rules:
- host: "hello.jafner.dev"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello
port:
number: 8080
- host: "hello2.jafner.dev"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello2
port:
number: 8080

47
jafner-dev/Ingress.yaml Normal file
View File

@ -0,0 +1,47 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
kubernetes.io/ingress.class: gce
kubernetes.io/ingress.allow-http: "true"
kubernetes.io/ingress.global-static-ip-name: web-ip
cert-manager.io/issuer: letsencrypt-production
spec:
tls:
- secretName: web-ssl
hosts:
- hello.jafner.dev
- hello2.jafner.dev
- 5e.jafner.dev
rules:
- host: "hello.jafner.dev"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello
port:
number: 8080
- host: "hello2.jafner.dev"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello2
port:
number: 8080
- host: "5e.jafner.dev"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: dndtools
port:
number: 80

View File

@ -0,0 +1,31 @@
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: jafner425@gmail.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
name: web-ingress
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-production
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: jafner425@gmail.com
privateKeySecretRef:
name: letsencrypt-production
solvers:
- http01:
ingress:
name: web-ingress

View File

@ -0,0 +1,9 @@
---
apiVersion: v1
kind: Secret
metadata:
name: web-ssl
type: kubernetes.io/tls
stringData:
tls.key: ""
tls.crt: ""

View File

@ -0,0 +1,23 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dndtools
spec:
selector:
matchLabels:
app: dndtools
replicas: 1
template:
metadata:
labels:
app: dndtools
spec:
containers:
- name: dndtools
image: jafner/5etools-docker
env:
- name: SOURCE
value: "GITHUB-NOIMG"
ports:
- containerPort: 80

View File

@ -0,0 +1,13 @@
---
apiVersion: "v1"
kind: "Service"
metadata:
name: "dndtools"
namespace: "default"
spec:
ports:
- protocol: "TCP"
name: web
port: 80
selector:
app: "dndtools"

View File

@ -0,0 +1,20 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello
spec:
selector:
matchLabels:
app: hello
replicas: 1
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: gcr.io/google-samples/hello-app:1.0
ports:
- containerPort: 8080

View File

@ -0,0 +1,13 @@
---
apiVersion: "v1"
kind: "Service"
metadata:
name: "hello"
namespace: "default"
spec:
ports:
- protocol: "TCP"
name: hello
port: 8080
selector:
app: "hello"

View File

@ -0,0 +1,20 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello2
spec:
selector:
matchLabels:
app: hello2
replicas: 1
template:
metadata:
labels:
app: hello2
spec:
containers:
- name: hello2
image: gcr.io/google-samples/hello-app:1.0
ports:
- containerPort: 8080

View File

@ -0,0 +1,13 @@
---
apiVersion: "v1"
kind: "Service"
metadata:
name: "hello2"
namespace: "default"
spec:
ports:
- protocol: "TCP"
name: hello2
port: 8080
selector:
app: "hello2"