From 5e95fb3a0c4f98f2fdf9ff7c3cb0deb2dcab60ad Mon Sep 17 00:00:00 2001 From: Joey Hafner Date: Wed, 29 Mar 2023 23:52:38 -0700 Subject: [PATCH] Working Jafner.dev with TLS - TLS for hello, hello2, and dndtools - Documentation for adding services --- homelab/docs/Jafner-dev on GKE.md | 44 +++++++++++++++++++ homelab/jafner-dev/Ingress-noTLS.yaml | 30 +++++++++++++ homelab/jafner-dev/Ingress-staging.yaml | 36 ++++++++++++++++ homelab/jafner-dev/Ingress.yaml | 47 +++++++++++++++++++++ homelab/jafner-dev/cert-manager/Issuer.yaml | 31 ++++++++++++++ homelab/jafner-dev/cert-manager/Secret.yaml | 9 ++++ homelab/jafner-dev/dndtools/Deployment.yaml | 23 ++++++++++ homelab/jafner-dev/dndtools/Service.yaml | 13 ++++++ homelab/jafner-dev/hello/Deployment.yaml | 20 +++++++++ homelab/jafner-dev/hello/Service.yaml | 13 ++++++ homelab/jafner-dev/hello2/Deployment.yaml | 20 +++++++++ homelab/jafner-dev/hello2/Service.yaml | 13 ++++++ 12 files changed, 299 insertions(+) create mode 100644 homelab/docs/Jafner-dev on GKE.md create mode 100644 homelab/jafner-dev/Ingress-noTLS.yaml create mode 100644 homelab/jafner-dev/Ingress-staging.yaml create mode 100644 homelab/jafner-dev/Ingress.yaml create mode 100644 homelab/jafner-dev/cert-manager/Issuer.yaml create mode 100644 homelab/jafner-dev/cert-manager/Secret.yaml create mode 100644 homelab/jafner-dev/dndtools/Deployment.yaml create mode 100644 homelab/jafner-dev/dndtools/Service.yaml create mode 100644 homelab/jafner-dev/hello/Deployment.yaml create mode 100644 homelab/jafner-dev/hello/Service.yaml create mode 100644 homelab/jafner-dev/hello2/Deployment.yaml create mode 100644 homelab/jafner-dev/hello2/Service.yaml diff --git a/homelab/docs/Jafner-dev on GKE.md b/homelab/docs/Jafner-dev on GKE.md new file mode 100644 index 00000000..2fd3afc6 --- /dev/null +++ b/homelab/docs/Jafner-dev on GKE.md @@ -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! \ No newline at end of file diff --git a/homelab/jafner-dev/Ingress-noTLS.yaml b/homelab/jafner-dev/Ingress-noTLS.yaml new file mode 100644 index 00000000..4ea2670f --- /dev/null +++ b/homelab/jafner-dev/Ingress-noTLS.yaml @@ -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 diff --git a/homelab/jafner-dev/Ingress-staging.yaml b/homelab/jafner-dev/Ingress-staging.yaml new file mode 100644 index 00000000..f77d0932 --- /dev/null +++ b/homelab/jafner-dev/Ingress-staging.yaml @@ -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 diff --git a/homelab/jafner-dev/Ingress.yaml b/homelab/jafner-dev/Ingress.yaml new file mode 100644 index 00000000..62d45b6f --- /dev/null +++ b/homelab/jafner-dev/Ingress.yaml @@ -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 \ No newline at end of file diff --git a/homelab/jafner-dev/cert-manager/Issuer.yaml b/homelab/jafner-dev/cert-manager/Issuer.yaml new file mode 100644 index 00000000..d0fdb15d --- /dev/null +++ b/homelab/jafner-dev/cert-manager/Issuer.yaml @@ -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 diff --git a/homelab/jafner-dev/cert-manager/Secret.yaml b/homelab/jafner-dev/cert-manager/Secret.yaml new file mode 100644 index 00000000..c23487e1 --- /dev/null +++ b/homelab/jafner-dev/cert-manager/Secret.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: web-ssl +type: kubernetes.io/tls +stringData: + tls.key: "" + tls.crt: "" \ No newline at end of file diff --git a/homelab/jafner-dev/dndtools/Deployment.yaml b/homelab/jafner-dev/dndtools/Deployment.yaml new file mode 100644 index 00000000..1fe62164 --- /dev/null +++ b/homelab/jafner-dev/dndtools/Deployment.yaml @@ -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 diff --git a/homelab/jafner-dev/dndtools/Service.yaml b/homelab/jafner-dev/dndtools/Service.yaml new file mode 100644 index 00000000..c25c1eb8 --- /dev/null +++ b/homelab/jafner-dev/dndtools/Service.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: "v1" +kind: "Service" +metadata: + name: "dndtools" + namespace: "default" +spec: + ports: + - protocol: "TCP" + name: web + port: 80 + selector: + app: "dndtools" diff --git a/homelab/jafner-dev/hello/Deployment.yaml b/homelab/jafner-dev/hello/Deployment.yaml new file mode 100644 index 00000000..b0e349f6 --- /dev/null +++ b/homelab/jafner-dev/hello/Deployment.yaml @@ -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 diff --git a/homelab/jafner-dev/hello/Service.yaml b/homelab/jafner-dev/hello/Service.yaml new file mode 100644 index 00000000..46279f36 --- /dev/null +++ b/homelab/jafner-dev/hello/Service.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: "v1" +kind: "Service" +metadata: + name: "hello" + namespace: "default" +spec: + ports: + - protocol: "TCP" + name: hello + port: 8080 + selector: + app: "hello" diff --git a/homelab/jafner-dev/hello2/Deployment.yaml b/homelab/jafner-dev/hello2/Deployment.yaml new file mode 100644 index 00000000..96865262 --- /dev/null +++ b/homelab/jafner-dev/hello2/Deployment.yaml @@ -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 diff --git a/homelab/jafner-dev/hello2/Service.yaml b/homelab/jafner-dev/hello2/Service.yaml new file mode 100644 index 00000000..aef70c56 --- /dev/null +++ b/homelab/jafner-dev/hello2/Service.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: "v1" +kind: "Service" +metadata: + name: "hello2" + namespace: "default" +spec: + ports: + - protocol: "TCP" + name: hello2 + port: 8080 + selector: + app: "hello2"