rubysecurity.org

Cloud Architect / DevOps Engineer / SRE / Developer | /root

Home About Books Blog Portfolio Archive

Tag Cloud


Currently Reading

Certified Kubernetes Administrator (CKA) Study Guide
Certified Kubernetes Administrator (CKA) Study Guide
38 / 155 Pages


Latest Book Reviews

Latest Posts


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

Tags: [ kubernetes rancher cert-manager letsencrypt ]
September 15, 2024

Where am I, once again?

by Alpha01

Well my last post in this site sure didn’t aged well. Needless to say, I’ve failed miserably on keeping this site more active. While, theirs tons of reasons (good ones of course), it’s inexcusable for me to not have written useful tech content. I’ve been working using really complex technologies, but at home, I’ve kept my homelab personal projects to a minimal. This slightly explains just a little why I’ve been quiet these last two years in here. Thus said, I’ve found new motivation to keep this site more active. So this time around they’ll be more new content in here.

Tags: [ cloud ]
August 5, 2023

Where am I?

by Alpha01

It’s exactly one year since I’ve written something meaningful on this tech blog. They’re certainly many reasons (or excuses) on why I haven’t been active these past 365 days. First and foremost is work, while I do get to work with really awesome and new technologies as part of my job as a Cloud Engineer. I do not post anything related to what I’m doing at work, since I’m obviously on an NDA with my employer.

Thus said, the primary reason why I’ve been fairly quiet for a year, is that I’ve been shifting my personal time off to non-tech or homelab related activities (work-life balance you can say). This doesn’t mean that I’m getting rid off my homelab or anything like that. I still have a lots of blog post drafts and ideas of new cool apps to explore and write about. As well as I’m still reading tech related books (this will certainly never stop!).

Excuses aside, I’m hoping to return to continue writing posts in here soon.

Tags: [ cloud ]
August 6, 2022

Moved antoniobaltazar.com to GitHub Pages

by Alpha01

Since I recently shutdown one my Intel Nuc homelab servers due to space, in addition to going forward I’ll be using public clouds for any testing that requires additional extensive computing. I was forced to migrate off my portfolio from a Kubernetes platform. I’ve been in a GitHub Pages honeymoon, so this was my first choice to move the site too. Since the portfolio site is a simple Node app, the containerized app was already a complete static site. The only dynamic aspect of the application is the custom Gulp automation that is used to compile the Sass assets.

The only changes I made to get the site to easily publish to Git Hub Pages was restructuring the site files under the _site directory. By default this is the directory that gets used by the configure-pages, upload-pages-artifact, and deploy-pages actions. GitHub has awesome documentation, using their examples I was able to quickly write a Workflow to build the node site, and publish it to GitHub Pages. It was a very extremely easy process! The difficult process was all my fault.

A while back, I consolidated my Blog, Photos, and Collection Wordpress sites under the domain antoniobaltazar.com. This presented a problem because I can’t simply update DNS and point antoniobaltazar.com to GitHub Pages because it will break access to my other WordPress sites. I use Cloudflare free DNS hosting, so I have very limited access to their Rewrite Page Rules features. So this meant that I would still need to keep antoniobaltazar.com DNS pointing to my current infrastructure, rather than having the complex redirects at the DNS level. Fortunately setting the redirects at the Varnish (http 80) and Nginx (https 443) app level was extremely easy.

Nginx

On the Nginx side of things, I didn’t had to change anything on my configuration. Nginx serves as an SSL termination proxy on my environment, so all incoming antoniobaltazar.com https requests are automatically forwarded to my http Varnish backend.

location / {
    proxy_pass   http://my-varnish-backend/;

    ### Set headers ####
    proxy_set_header        Accept-Encoding   "";
    proxy_set_header        Host            $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

    ### Most PHP, Python, Rails, Java App can use this header ###
    #proxy_set_header X-Forwarded-Proto https;##
    #This is better##
    proxy_set_header        X-Forwarded-Proto $scheme;
    add_header              Front-End-Https   on;
    add_header              X-Powered-By "Unicorns";
    add_header              X-hacker "Alpha01";

    client_max_body_size 10m;

    # These headers are only accessible internally
    #more_clear_headers 'x-generator';
    #more_clear_headers 'x-drupal-cache';

    # We expect the downsteam servers to redirect to the right hostname, so don't do any rewrites here.
    proxy_redirect     off;
}

Varnish

Its in Varnish where all the magic happens. For the configuration I’m simply redirecting all antoniobaltazar.com requests that don’t belong to my WordPress sites, to the GitHub Pages location https://alpha01.github.io/antoniobaltazar.com.

sub vcl_recv {
    # Portoflio is now hosted on GitHub Pages
    if (req.http.host ~ "(?i)^(www.)?antoniobaltazar\.(com|org)" && (req.url !~ "/(blog|collection|photos)")) {
        set req.http.host = "https://alpha01.github.io";
        return (synth(750, req.http.host + "/antoniobaltazar.com" + req.url));
    }
}

sub vcl_backend_error {
    # Take care of custom redirects
    if (beresp.status == 750) {
        set beresp.http.Location = beresp.reason;
        set beresp.status = 301;
        return(deliver);
    }
} 

Not a pretty solution, but it does the job.

Tags: [ github varnish nginx jekyll ]
August 5, 2022

Goodbye Drupal, Hello Jekyll

by Alpha01

Ever since the Drupal Project had announced support for Drupal was going to drop on November 1, 2023. I’ve been dreading the fact that I was going to be forced to upgrade to Drupal 9. This is mainly because I’m using some modules that I know are no longer being actively developed, and I’ve made some changes to my theme that I know for certain will not be compatible with the new version of Drupal.

I’ve looked into some static site generations like, Harp and Surge in the past, I but didn’t seemed to get a proper workflow with them to replace Drupal or WordPress for that matter. While I’m not new to the GitHub Pages world, I am new to it’s built-in integration with Jekyll. Recently, I had to use this feature for a work project, and I must say the GitHub Pages built-in integration is Jekyll awesome! Jekyll is a fantastic piece of software. The documentation is very comprehensible and easy to follow.

So I decided to migrate this site from Drupal 7 to Jekyll. The migration process was relatively painless. The Jekyll project has tons of exporters, including one for Drupal 7. The only caveat (though expected) was that the exported posts were using the content type and taxonomies set for Drupal. In Jekyll these are differently, so after few global search and replace tasks, I was able to easily transform the exported data into useable valid Jekyll content. As far as the theming is concerned, I tried to follow a similar look and view as the previous Drupal 7 site. Overall, as a person with a decent (though at times limited since JavaScript is not my forté) web development skills, customizing Jekyll has been a straight forward process. I would even say it’s easier than Drupal development!

Perhaps the only drawback of the built-in integration with GitHub Pages and Jekyll is that you only have a set of plugins and themes to work with. This became evident when I was creating a custom pagination page, and GitHub Pages uses a older version of the pagination plugin that isn’t compatible with newer v2 version which most examples found in when Google searching! Thus said, nothing can prevent you from using GitHub Actions to build and publish a Jekyll (or anything static site generator) generated site regardless of plugins or themes.

This site is now hosted on GitHub Pages, instead of on my homelab infrastructure.

Tags: [ jekyll github ]