Tuesday, June 24, 2025

QNAP and Rancher, A Match Made in Permissions Hell

 


I've been running some services that utilize AI Agents and wanted to request history for the agents to use and while there are several types of storage to use, PostgreSQL is one of the most recommended.   Since I'm only using it to provide limited history I didn't want to run a full VM to host the server and hosting PostgreSQL storage over NFS is frowned upon in this establishment.    We required non-network filesystem storage.  (yes, I get the irony here)

So, I wanted to provide an ext4 / xfs persistent volume for my PostgreSQL server, but didn't want to just do writethrough to the physical host which I don't backup.  I do on the other hand backup my NAS and since I do that.  Seems like a good location to storage my pgdata.

My primary stack (at this moment anyhow) is Proxmox running Rocky Linux VMs running a SUSE Rancher Kubernetes cluster utilizing a QNAP NAS for storage.

To utilize the QNAP, there is a QNAP CSI Driver for Kubernetes that seem to fit the bill.  I went through the process of installing the plugin, but alas.  It wouldn't start.  It presented several errors and I would work through them only to end up back at the first error and there was no Kubernetes "Service" created as the pods failed to start.

The issue ended up being focused around Rancher permissions preventing the pods from starting.

time="2025-06-23T16:04:05Z" level=error msg="error syncing 'trident': error installing Trident using CR 'trident' in namespace 'trident'; err: reconcile failed; failed to patch Trident installation namespace trident; admission webhook \"rancher.cattle.io.namespaces\" denied the request: Unauthorized, requeuing"

 Following that error, it then provided the following two errors.

level=info msg="No Trident deployments found by label." label="app=controller.csi.trident.qnap.io" namespace=trident

and...

 level=info msg="No Trident daemonsets found by label." label="app=node.csi.trident.qnap.io" namespace=trident

While a tried a few things to resolve this, I did end up going to the developers and it seems someone just previous to me had the same issue and was able to use a workaround to resolve it by running the following command:

kubectl label namespaces trident pod-security.kubernetes.io/enforce=privileged pod-security.kubernetes.io/audit=privileged pod-security.kubernetes.io/warn=privileged

This labelling of the namespace effectively resolved the issue and allowed the plugin / service to be installed.

 

Tuesday, June 17, 2025

ChatGPT In Your Discord Server using n8n

 



So, everyone is going stir-crazy over these AI Agents like ChatGPT, Google Gemini, and Claude.  I figured as a project and learning experience.  I would write a Discord bot in Python and use webhooks to allow it to talk to my n8n deployment to interact with ChatGPT and respond to the Discord channel

Well, I have successfully done it, but it's not perfect.   The main issue is, depending on what you ask it.  ChatGPT will respond with a large swath of text and Discord limits you to 2,000 characters (4,000 if you have Nitro upgrade)

When this happens, the Discord node that talks to the Discord webhook just fails when it tries to send responses that are larger than the current limit.    I suspect I can just have ChatGPT respond to a Python or JavaScript code which can divide the response up into multiple messages.  Though I haven't went through that process yet.

The current process is I created a text chatroom in Discord called Oracle.  I created a Python Discord bot that joins the server and monitors that channel.  It ignores any messages that aren't directed at the bot. 

ie: "@OracleBot [Question for ChatGPT]"    (mine is not named OracleBot, but I digress)

The bot then takes that message and strips of his name and trims the text then sends that message to my n8n server where I have a workflow that accepts messages from a webhook.

That webhook forwards the message to an AI Agent which has ChatGPT (and some other tools that accesses data that I have) connected to it to resolve questions.

Once the question has been resolved, the AI Agent sends the response to a Discord node that then sends the response directly to the channel where the questions was asked. 

Here is a flowchat of the happenings:



So, while the Discord bot sends the message to n8n, it does not actually respond to the bot itself.  It sends it to a Discord webhook that injects the message into the chatroom as if it was coming from the bot.

n8n flow for a Discord ChatGPT Bot

At some point, I will provide my Python Discord bot, but it's a hack job at this point and I want to clean it up and possibly add some nice features to it.    Once I do that, I can update this post with that code.




Upgrading Kubernetes via Rancher UI Completes Incomplete

 

At work and at home I primarily run on-prem Kubernetes with k3s and utilize SUSE Rancher UI.  These two tools make for a nice combination for running Kubernetes.

While Rancher is certainly nice for managing the cluster, I tend to do most of my deployments from the cli with kubectl.

Anyhow, I was having issues with my clusters when I would upgrade Kubernetes.   SUSE suggests upgrading your cluster via the Rancher UI for upgrades.   This has always been problematic for me as it would upgrade one node, but none of the others.

ie after triggering Rancher to upgrade Kubernetes I get...

 

NAME                                STATUS        ROLES                  AGE    VERSION

mynode1.mydomain.com     Ready    control-plane,master   290d   v1.32.5+k3s1

mynode2.mydomain.com     Ready    control-plane,master   289d   v1.31.9+k3s1

mynode3.mydomain.com     Ready    control-plane,master   289d   v1.31.9+k3s1

 So today this blog post is about how to correct this half-hearted upgrade.   The important thing is you must remember the parameters you used to install your cluster with in the first place. (take note!)

While it depends if you're installing the first node vs secondary master nodes or worker nodes.  It will look something like this:

curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=stable K3S_URL=[RANCHER_URL] K3S_TOKEN=[TOKEN] sh -  

Ensure you keep a copy of whatever your install configuration was and you can use it to upgrade your nodes at a later date.   In my case, I just ran the install command again on each of the nodes and rectified the issue.

NAME                                STATUS        ROLES                  AGE    VERSION

mynode1.mydomain.com     Ready    control-plane,master   290d   v1.32.5+k3s1

mynode2.mydomain.com     Ready    control-plane,master   289d   v1.32.5+k3s1

mynode3.mydomain.com     Ready    control-plane,master   289d   v1.32.5+k3s1

You can easily setup Ansible to perform these updates to make them more simple to perform.  Especially of you have a large cluster or clusters.

 Hopefully that helps someone who landed in my boat.