Tag Cloud
Currently Reading
Latest Book Reviews
- Rancher Deep Dive Posted on March 31, 2023
- Leveraging Kustomize for Kubernetes Manifests Posted on March 24, 2023
- Automating Workflows with GitHub Actions Posted on October 13, 2022
- Deep-Dive Terraform on Azure Posted on August 30, 2022
- Effective DevOps Posted on January 5, 2022 All Book Reviews
Latest Posts
- Kubestronaut Journey Part 1: Kubernetes and Cloud Native Associate (KCNA) Posted on December 28, 2024
- Simple Bash KVM Virtual Machine Startup and Shutdown Script Posted on December 14, 2024
- Deploying Keycloak Identity Provider (IdP) for secure Rancher User Authentication Part 1 Posted on December 12, 2024
- Let's Encrypt Posted on December 10, 2024
- Deploying Rancher on my Homelab Posted on December 7, 2024
December 28, 2024
Kubestronaut Journey Part 1: Kubernetes and Cloud Native Associate (KCNA)
by Alpha01
It’s been almost three years since I’ve obtained the Certified Kubernetes Application Developer (CKAD) and Certified Kubernetes Administrator (CKA) certifications. I was originally planning on recertifying these two Kubernetes certifications, however while at KubeCon last month, I was exited to learn about the Kubestronaut Program, which is a recognition to Kubernetes professionals that pass all five Kubernetes certifications. So I decided to accept the challenge and not only recertify my existing two certifications, but also take and pass the remaining three other certifications Kubernetes and Cloud Native Associate (KCNA), Cloud Native Security Associate (KCSA), and Certified Kubernetes Security Specialist (CKS) so I can become a “Kubestronaut”.
For my first exam on this journey, I’ve decided to start with the Kubernetes and Cloud Native Associate, which is the easiest of them all. To prepare for the exam, I used the Udemy Kubernetes Certified (KCNA) + Hands On Labs + Practice Exams course (8 hours) and the O’Reilly Kubernetes and Cloud Native Associate (KCNA) course (5 hours).
Difficult Level
Low, this was a very easy exam. I think anyone with moderate Kubernetes knowledge, can just use the Udemy Kubernetes Certified (KCNA) + Hands On Labs + Practice Exams course as their only study material can pass this exam. Thus said, this is also assuming that the candidate has also basic high-level knowledge of cloud and cloud native technologies. I’m pretty confident that I could’ve taken this exam without going through any of the mention study courses and I still would’ve easily passed it. However since this is meant to prepare myself for the more challenging exams, I’m still glad I study for this exam. I even learned new stuff along the way which is the main point of this entire journey!
I was able to successfully pass this exam with a score of 95/100. Next on my list will be completing (recertifying) the Certified Kubernetes Application Developer.
Study Resources
- Udemy Kubernetes Certified (KCNA) + Hands On Labs + Practice Exams
- O’Reilly Kubernetes and Cloud Native Associate (KCNA)
kubernetes
kubestronaut
]
December 14, 2024
Simple Bash KVM Virtual Machine Startup and Shutdown Script
by Alpha01
Given that I don’t want my Intel NUC homelab mini pc to sound like a jet engine all day. I wrote a simple bash script that would automatically startup and shutdown my kubernetes VMs easily each day. The script is cron friendly and it works like a charm.
# Start VMs
./rancher.sh start
# Stop (non-gracefully, use virsh shutdown instead)
./rancher.sh destroy
#!/bin/bash
# set -x
VMS="rancher rke2"
action=$1
if [ -z $action ]; then
echo "No action passed"
exit 1
elif [[ "$action" != "destroy" && "$action" != "start" ]]; then
echo "Unsupported action: $action"
exit 1
else
echo "Doing $action"
fi
function vm () {
vm=$1
current_vm_state=""
tmp=$(virsh list --all | grep " $vm " | awk '{ print $3}')
if ([ "x$tmp" == "x" ] || [ "x$tmp" != "xrunning" ])
then
echo "$vm does not exist or is shutdown!"
current_vm_state="destroy"
else
echo "$vm is running!"
current_vm_state="start"
fi
if [ "$action" != "$current_vm_state" ]; then
virsh $action $vm
fi
}
for vm in $VMS; do
vm "$vm"
done
bash
rancher
kubernetes
]
December 12, 2024
Deploying Keycloak Identity Provider (IdP) for secure Rancher User Authentication Part 1
by Alpha01
No words can explain the constant headaches I’ve gotten throughout my career when working with LDAP in the Unix/Linux world. While I’ve had plenty of experience working with it in the past (https://www.rubysecurity.org/tag/ldap), it’s certainly not the easiest or pleasant thing to work with. So I’m glad to see new (to me at least) Identity Provider (IdP) tools like Keycloak that can help us manage user identities, authentication, and access control across applications and systems in a much easier fashion. But more importantly supporting integrations with authentication mechanisms like OpenID Connect (OIDC), OAuth2, SAML to name a few.
Environment Setup
To get up and running quickly, I opted to deploy Keycloak on a Ubuntu 24.04 VM instead of the container/kubernetes approach.
1). Install required packages.
apt install openjdk-21-jre unzip
2). Download and extract keycloak.
cd /opt
wget https://github.com/keycloak/keycloak/releases/download/26.0.5/keycloak-26.0.5.zip
unzip keycloak-26.0.5.zip
ln -s keycloak-26.0.5 keycloak
3). Setup SSL certificates. At this stage, I had manually issued an Let’s Encrypt SSL certificate for sso.rubyninja.org
for Keycloak. and copied it over to /opt/keycloak/conf/certs
4). Update the following settings on /opt/keycloak/conf/keycloak.conf
.
# Hostname for the Keycloak server.
hostname=sso.rubyninja.org
# The file path to a private key in PEM format.
https-certificate-key-file=/opt/keycloak/conf/certs/MYKEY.key
# The file path to a server certificate or certificate chain in PEM format.
https-certificate-file=/opt/keycloak/conf/certs/MYCERT.crt
5). Create initial bootstrap admin username/password
/opt/keycloak/bin/kc.sh bootstrap-admin user
Enter username [temp-admin]:temp-admin
Enter password:
Enter password again:
5). Start up the application
screen -dm /opt/keycloak/bin/kc.sh start --verbose
After login in with the temp-admin account, I had to manually create a separate admin user.
By no means this is a production ready setup, but for a homelab environment for testing, this setup is more than sufficient for me.
Resources
Tags: [kubernetes
rancher
keycloak
security
]
December 10, 2024
Let's Encrypt
by Alpha01
I’ve been using Let’s Encrypt for years, and it came to me that I’ve hardly ever really mentioned this awesome service at all! Let’s Encrypt is awesome, plain and simple. I use to throughout my homelab to setup and configure secure access.
Using this awesome is really straight forward. I use the acme.sh script for all ssh requests. The acme.sh script is simple and works beautifully.
Setup
I use the git repository setup method.
git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
./acme.sh --install -m [email protected]
The setup process will create a ~/.acme.sh
configuration environment that the script will use to save your Let’s Encrypt issued certificates in.
I use the Automatic DNS API integration approach to verify and issue certificates. For this to work with Cloudflare, I simply just needed to create an API key and export the following two variables.
export CF_Key="EXAMPLEKEY"
export CF_Email="[email protected]"
Afterwards, it’s just a matter of using the acme.sh script.
For example:
./acme.sh --issue --dns dns_cf -d rubyninja.org -d *.antoniobaltazar.com -d *.rubyninja.org -d *.k8s.rubyninja.org -d *.rubysecurity.org
The really cool thing is that the script is smart enough to save the environments under ~/.acme.sh/account.conf
for future use (certs are valid for 90 days). In addition it supports wildcards certificates, as well as it being cron friendly!
Resources
- https://github.com/acmesh-official/acme.sh
- https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_cf
- https://developers.cloudflare.com/fundamentals/api/get-started/create-token/
letsencrypt
security
]
December 7, 2024
Deploying Rancher on my Homelab
by Alpha01
Finally! A new post on my technical site that I feel it’s post worthy. So, I’ve been working with Rancher on a daily basis for a few years now. The last time I ran this awesome application on my homelab, I was using RKE for the Kubernetes distribution. This time I’m using the new and improved RKE2.
I wanted to have a Rancher environment on my homelab so I can experiment and play around with this awesome piece of technology. So I decided to spend some time setting up a fully functional Rancher environment on my homelab.
This is just the initial setup doc, of course I’m going to be adding more components to overly engineer my Rancher and Kubernetes homelab environment as much as possible.
Homelab Infra
- Ubuntu Host System (Intel NUC)
- Hypervisor: KVM
- Networking: BIND DNS and ISC DHCP
VM Host Information
- OS: Ubuntu 24.04.x
- Hostname: https://rancher.k8s.rubyninja.org/
- Kubernetes Distribution: RKE2 v1.30.5+rke2r1
Stack
- Rancher Community (Management Plane)
- MetalLB (LB IP Addressing)
- Nginx Ingress Controller (Ingress)
- Cert-manager ACME Let’s Encrypt Issuer (SSL/TLS)
- Istio (Service Mesh)
- Keycloak (Identity Provider)
- Knative (Serverles)
- Longhorn (Block Storage)
- Minio (Object Storage)
- Grafana Loki (Logs)
0). Added the following Helm chart repositories:
helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
helm repo add jetstack https://charts.jetstack.io
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add metallb https://metallb.github.io/metallb
helm repo update
1). Disabled rke2-ingress-nginx add-on /etc/rancher/rke2/config.yaml
disable: rke2-ingress-nginx
2). Install RKE2
curl -sfL https://get.rke2.io | sh -
systemctl enable rke2-server.service
export PATH=$PATH:/var/lib/rancher/rke2/bin/
export KUBECONFIG=/etc/rancher/rke2/rke2.yam
3). Install MetalLB
helm install metallb metallb/metallb --version 0.14.8 --create-namespace -n metallb-system
4). MetalLB Configuration for the Nginx Ingress Controller for Rancher
kubectl -n metallb-system apply -f - <<EOF
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: rancher
spec:
addresses:
- 192.168.1.71-192.168.1.73
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: rancher
spec:
ipAddressPools:
- rancher
EOF
5). Install Nginx Ingress Controller.
helm install ingress-nginx ingress-nginx/ingress-nginx --version 4.11.3 -n ingress-system
6). Install cert-manager.
helm upgrade \
cert-manager jetstack/cert-manager \
--install \
--create-namespace \
--namespace cert-manager \
--version v1.16.1 \
--set crds.enabled=true \
--set dns01RecursiveNameservers="8.8.8.8:53" \
--set dns01RecursiveNameserversOnly=true \
--set global.logLevel=4
I needed to use Google’s Public DNS for the recursive nameserver, otherwise it will default to my local BIND DNS which cert-manger owner verification process would fail because the requesting SSL/TLS certificates for rancher.k8s.rubyninja.org
are hosted on local homelab BIND DNS server.
7). I’m using the DNS verification process for cert-manager Let’s Encrypt. So I needed to configure cert-manager to talk to Cloudflare since rubyninja.org
public domain is hosted by them.
Create API key as outlined on the Cloudflare Create API token document, and create the Kubernetes Secret with the corresponding API key data.
kubectl create secret generic cloudflare-cred --from-literal api-key="<retracted>" -n cert-manager
8). Now I was able to configure my ClusterIssuer
cert-manager resource.
kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-cloudflare-prod
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: <RETRACTED>
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-cloudflare-prod-key
solvers:
- dns01:
cloudflare:
email: <RETRACTED>
apiKeySecretRef:
name: cloudflare-cred
key: api-key
selector:
dnsZones:
- "rubyninja.org"
EOF
9). Created the cattle-namespace
namespace for the Certificate
cert-manager object and SSL/TLS issued certificate that will be saved as a Kubernetes secret and later be used for the Rancher installation.
kubectl create ns cattle-system
kubectl -n cattle-system apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: rancher-k8s-rubyninja-org
spec:
dnsNames:
- rancher.k8s.rubyninja.org
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: letsencrypt-cloudflare-prod
secretName: rancher-k8s-rubyninja-org
EOF
Afterwards, the kubernetes.io/tls type Secret rancher-k8s-rubyninja-org
was created on the cattle-system namespace with the corresponding certificate key pair issued by Let’s Encrypt. The Cert-manager Troubleshooting documentation has really straight forward explanation of the entire issuer process in case you run into problems getting an SSL/TLS certificate.
10). Finally, install Rancher.
helm upgrade --install rancher rancher-stable/rancher --version 2.9.2 \
--namespace cattle-system \
--set hostname=rancher.k8s.rubyninja.org \
--set agentTLSMode="system-store" \
--set ingress.ingressClassName=nginx \
--set ingress.tls.source="secret" \
--set ingress.tls.secretName="rancher-k8s-rubyninja-org" \
--set bootstrapPassword="ChangeMe12345"
NOTE: For some reason the default bootstrap password didn’t seem to work for me, so I had to manually reset it at the Pod level.
kubectl --kubeconfig $KUBECONFIG -n cattle-system exec $(kubectl --kubeconfig $KUBECONFIG -n cattle-system get pods -l app=rancher | grep '1/1' | head -1 | awk '{ print $1 }') -- reset-password
Resources
- https://developers.cloudflare.com/fundamentals/api/get-started/create-token/
- https://cert-manager.io/docs/configuration/acme/dns01/#setting-nameservers-for-dns01-self-check
- https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/
- https://cert-manager.io/docs/troubleshooting/
- https://medium.com/nerd-for-tech/ensure-having-a-rancher-admin-4ee62cd066e1
kubernetes
rancher
cert-manager
letsencrypt
]