DEV Community 👩‍💻👨‍💻

Gregory Haynes
Gregory Haynes

Posted on

Cloud-Native IRC with WeeChat on Kubernetes

Not long ago I switched away from using terminal based IRC and began to use a combination of clients which make use of the WeeChat Relay protocol. For those not familiar with this, it is a daemon built in to WeeChat which allows your client to act like an IRC bouncer (similar to ZNC). Using this, I was able to switch to glowing-bear (a web based IRC client) for desktop/laptop and weechat-android for my mobile devices. Now, without the need for a terminal, and by relying solely on HTTP (WebSockets to be precise) and TLS I was able to move my IRC in to Kubernetes where vhosting and TLS termination are done by the ingress controller. This has the great benefit of sharing resources (notably a public IP and certificate management) with the various other services I run. It can also easily be run on any Kubernetes provider. Finally, this is another "pet" off my plate which is always a great feeling - now my only infrastructure concern here is the state of my shared Kubernetes cluster.

Prerequisites

In order for this to work we need a Kubernetes cluster, a computer capable of creating docker images, and a docker registry I could upload images to and serve them to my Kubernetes cluster. In order for vhosting and TLS (highly recommended) to work I used ingress-nginx and cert-manager. Setting up both of these is beyond the scope of this guide and may vary by hosting provider. Your hosting provider may also provide its own ingress controller and certificate management which may be easier and better to us.

Heres a diagram of what our setup will look like when were done:
k8s-weechat-arch-diagram

Throughout this guide we will also refer to a repository which contains a Dockerfile, where to place your WeeChat configuration, etc. so this will needed to be cloned with the following command. We also assume the user has then cd'd in to this repository.

git clone https://github.com/greghaynes/k8s-weechat
cd k8s-weechat

WeeChat Configuration

Inside of the repository we cloned there is a weechat-configuration directory. This directory gets copied in to our docker image and specifies the configuration files WeeChat uses. Although this method has some downsides (needing to build, push, deploy for configuration changes) it hasn't been a major issue for me as this configuration changes rarely and can also be updated remotely (using /set).

In this directory is a relay.conf file. This controls the running of our WeeChat relay which is how our clients will connect. The first thing to notice is the line which specifies the password for clients to connect. It's a good idea to change this:

password = ""

The other important block is where we specify our relay port/protocol:

[port]
weechat = 8001

This specifies we will be using the weechat protocol on port 8001. It is worth noting that we do not have SSL enabled here as we will be terminating SSL on our ingress gateway.

If there are other configuration options you would like to specify (such as autoconnect options) you can copy in an irc.conf or other config file to this directory and it will be added to the weechat configuration directory in our image.

Docker Image

In order to run WeeChat in Kubernetes we are going to create our own docker image which runs weechat-headless (an alternate weechat command which doesn't spawn the console UI). There are a few Dockerfiles floating around for this but they are all very minimal which led me to make my own, at least then I have the benefit of knowledge.

In our example repository we have the following Dockerfile:

FROM alpine:edge

LABEL maintainer="greg@greghaynes.net"

ENV HOME /home/user

RUN ["apk", "add", "--no-cache", "weechat", "weechat-perl", "weechat-python", "weechat-aspell", "ca-certificates", "aspell-en", "python", "perl"]

RUN ["adduser", "-D", "-h", "$HOME", "user"]
RUN ["mkdir", "-p", "$HOME/.weechat"]
RUN ["chown", "-R", "user:user", "$HOME"]
ADD --chown=user:user weechat-config/* /home/user/.weechat/
WORKDIR $HOME

USER user

ENTRYPOINT weechat-headless

As you can see, this image is based on alpine and installs WeeChat, some extra plugins and dependencies, and then copies our weechat-configuration directory in to $HOME/.weechat.

Then build this image and upload it to a docker registry with the following command:

docker build -t <my-registry-url>/weechat .
docker push <my-registry-url>/weechat

Kubernetes Deployment

Now that we have a docker image our Kubernetes deployment is relatively straightforward. We are creating a deployment using the image we created with a replica count of 1 (since this isn't an application we can scale out). We are also exposing port 8001 as that is the port our relay listens on. This deployment can be found in the example repo at k8s/deployment.yaml:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: weechat
  name: weechat
  namespace: weechat
spec:
  replicas: 1
  selector:
    matchLabels:
      app: weechat
  template:
    metadata:
      labels:
        app: weechat
    spec:
      containers:
        image: <my-registry-url>/weechat
        imagePullPolicy: Always
        name: weechat
        ports:
        - containerPort: 8001
          protocol: TCP

Make sure to replace the image: line with the URL you pushed your docker image to. We then apply this with the following command:

kubectl apply -f k8s/deployment.yaml

At this point Kubernetes should be creating our WeeChat instance! You can check on the status by running:

kubectl get pods -n weechat

Kubernetes Ingress

In order for ingress and TLS to work we need to have both ingress-nginx and cert-manager installed in our Kubernetes cluster. If you are on a hosted provided there is likely a better method of performing this section if you consult your provider's documentation.

The following ingress definition creates an ingress controller which cert-manager can understand:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    certmanager.k8s.io/acme-challenge-type: http01
    certmanager.k8s.io/issuer: <certmanager-issuer>
  name: weechat
  namespace: weechat
spec:
  rules:
  - host: <my-hostname>
    http:
      paths:
      - backend:
          serviceName: weechat
          servicePort: 8001
        path: /
  tls:
  - hosts:
    - <my-hostname>
    secretName: irc-cert

Note that needs to be upadated with the hostname you will use to reach your Kubernetes cluster from the public internet. You also will have created a certmanager-issuer during installation and you need to update that value accordingly.

Connecting

We should now have a public, SSL secured weechat relay running in our Kubernetes. The last step is to connect to this from a client. For this I enjoy using Glowing Bear. You'll need to fill out this site with the following configuration, taking care to update my-hostname and password:

Glowing Bear Settings

And with that you should be up and running!

Top comments (1)

Collapse
kostrahb profile image
Vojtěch Kletečka

Hi, have you considered building only image without configuration (or with simple base configuration) and connecting configuration via kubernetes volumes? It's definitely easier because you provide general image, user provides configuration and the image is reusable

🌚 Browsing with dark mode makes you a better developer.

It's a scientific fact.