Deploying squid 🦑 in k3s on an RPI4B
Tags: tutorial, docker, devops, kubernetes
Published: 2021-12-27 20:07:49

## What is k3s?
K3s is lightweight Kubernetes which is easy to install and is a single binary under 100 MB by Rancher. One can read more about it [here](https://rancher.com/docs/k3s/latest/en/).

## Installing K3s?
K3s provides an installation script that is a convenient way to install it as a service on systemd or openrc based systems. This script is available at https://get.k3s.io. To install K3s using this method, just run:

```
curl -sfL https://get.k3s.io | sh -
```

After running this installation:

* The K3s service will be configured to automatically restart after node reboots or if the process crashes or is killed
* Additional utilities will be installed, including kubectl, crictl, ctr, k3s-killall.sh, and k3s-uninstall.sh
* A kubeconfig file will be written to /etc/rancher/k3s/k3s.yaml and the kubectl installed by K3s will automatically use it

## Why Squid?
Well I've been using Squid Proxy on my Raspberry Pi 2B for quite some time and I really wanted to get my hands dirty with Kubernetes.

## What is Squid?
Taken from the [ArchWiki](https://wiki.archlinux.org/title/Squid) Squid is a caching proxy for HTTP, HTTPS and FTP, providing extensive access controls. 

### Let's begin
I couldn't find a squid proxy container for my raspberry pi so I had to roll out my own Containerfile.

{% gist https://gist.github.com/afro-coder/809384996d03e69917620ad769a123b5 file=Containerfile %}

Now we can build this image with the version tag, this is important if you wish to rollout new changes to your application, having the latest flag is good having a version tag in your deployment is better, this is what I've observed and it's also a deployment strategy.

```
podman build squid-proxy:v1 .
```
The problem now is how do I get Kubernetes to recognize this image that I've built? Since it's not on Docker Hub. I could, well deploy this to Docker Hub too, but, I didn't I instead spun up a docker registry container.

```
podman run -d -p 5000:5000 --restart on-failure --name registry registry:2
```

Then I ran the following
```
podman build -t localhost:5000/squid-proxy:v1 .
podman push --tls-verify=false localhost:5000/squid-proxy:v1
```
Note: The `--tls-verify=false` is required as we don't have TLS and the image push fails, since this is for learning purposes I've done it without TLS.

## Deploying Squid🦑 to Kubernetes.
I'm still pretty new to Kubernetes, the basic unit of Kubernetes is a pod, a pod is something that can hold multiple containers within it. While I can deploy this within a pod directly I didn't, Kubernetes will do that for me via the deployment file.

If you want to get an overview of how Kubernetes works you can watch this video by @techworld_with_nana, [Kubernetes Course](https://www.youtube.com/watch?v=X48VuDVv0do)

I decided to go this way, Create a LoadBalancer Service and a Deployment that would deploy SQUID to Kubernetes.

{% gist https://gist.github.com/afro-coder/809384996d03e69917620ad769a123b5 file=squid-deployment.yaml %}

I have yet to find the docs that share all the fields for the YAML, but this is pretty much how the the image is deployed
```
spec:
      volumes:
        - name: log-dir
          emptyDir: {}
      containers:
      - name: squid
        image: localhost:5000/squid-proxy:v2
          #imagePullPolicy: Never
        ports:
        - containerPort: 3128
        volumeMounts:
          - name: log-dir
            mountPath: "/var/log/squid"
      - name: tailer
        image: busybox
        command:
        - "/bin/sh"
        - "-c"
        args:
          - tail -F /var/log/squid/access.log
        volumeMounts:
          - name: log-dir
            mountPath: "/var/log/squid"
```
There is a `volume` folder that is common for both the containers since SQUID doesn't send logs to `STDOUT`

To run this you can simply do
```
$ kubectl apply -f squid-deployment.yml
deployment.apps/squid-dployment unchanged
service/squid-service unchanged
```

This will create a Service and Deployment will create a pod

```
$ kubectl get service
$ kubectl get service
```
Output
```
$ kubectl get svc
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
kubernetes      ClusterIP      10.43.0.1       <none>           443/TCP          48d
squid-service   LoadBalancer   10.43.114.127   192.168.31.151   3128:32729/TCP   3d14h
```
To get the deployments
```
$ kubectl get deploy
$ kubectl get deployment
```
Which will show the following
```
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
squid-deployment   1/1     1            1           7d19h
```

The last thing is to get the pods.
```
$ kubectl get po OR kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
squid-dployment-86bfc8d664-swwzj   2/2     Running   0          4d14h
svclb-squid-service-54nrc          1/1     Running   0          4d1h
```

Once everything is up and running you can see the following in the curl headers.
![Curl Image Headers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lb5rfizddne6ukxq8caw.png)

To see the logs and follow them you can do the following.
```
kubectl logs service/squid-service -c tailer -f
```
That's all.

This is a simple and easy deployment using Kubernetes, if I've made any mistakes or you would like to suggest any changes please drop a comment below <3