I’m Eric Tummers, Software Architect at Statistics Netherlands, and this is how I work

My jobs description says Software Architect. I’m guiding my team through the technical hurdles and do some programming/testing/analysing myself. We follow the scrum guide and are working towards continuous integration and deployment. We do this in small steps. Every sprint we complete means the retrospective is done in the pub.

I expect the best and I give the best. Here’s the beer. Here’s the entertainment. Now have fun. That’s an order!
Rasczak

Location: Sittard, NL
Current Gig: Software Architect, CBS
Word that best describes how you work: remote
Current mobile device: iPhone SE 2nd gen
Current computer: MacBook Air M1

What apps/software/tools can’t you live without? Why?

Evernote: I’m a fan for years now.
Spotlight on Mac and Ueli on Windows: for quick start apps and other things.
Microsoft To Do: work tasks, chores, groceries, planning, every task is there.

What’s your workspace setup like?

My home workspace is a Macbook Air M1 connected to a Benq 24 inch monitor (BL2420PT). For input I use the logitech keyboard and mouse (MX800). There is a wireless charger for my iPhone SE or Airpods and a desk lamp (like the Pixar luxo Jr.) This is my main workspace.

When I go to the office I’m free to work from a coffee table with my MacBook Air M1 or hook it up to an external monitor. We’re a hybrid working organisation so the laptop moves with me in my rainbow backpack.

We communicate with each other via zoom and slack. So those apps are my virtual workspace. Does that count?

What’s your best time-saving shortcut/life hack?

Timebox. Start on a task and spent the time you’ve got to get the best result. Get someone to look at it, get feedback. Then decide if the result is final or to spent some more time.

Besides your phone and computer, what gadget can’t you live without and why?

I replaced my Garmin FR235 with the Garmin FR745. It has smart watch features, an optical heart rate monitor and music. I now go on a run without my phone.
My Apple Airpods 2. Easy to use, small and good sound. Replaced my old first gen with the second gen with wireless charging case – still the best wireless earbuds for me.

What everyday thing are you better at than everyone else? What’s your secret?

Learning new things. My current project lets me implement new things (joy) Also I try to learn the things I know to my team or anyone who listens.
I have a basic understanding of how things work and try to map new things on there. For the details I have a Pluralsight subscription and black belt google skills.

What do you listen to while you work?

My alarm clock plays classical music to wake me up in the morning. The car stereo plays about everything (grunge, rock, kids stories) driving to work. When I need some focus I play drum and bass on my headphones. My ringtone is still Run riot by Camo & Krooked, although it is muted since I got a Garmin.

What are you currently reading?

Nerds. A fun view of the things a nerd does, likes and hates. Good read to get me out of the working mindset.

How do you recharge? What do you do when you want to forget about work?

Spending quality time with my wife and daughters. Phone on silent, no screens, no work. 
Also sports like running, fitness, climbing and snowboarding to keep me fit and healthy.

Fill in the blank: I’d love to see _________ answer these same questions.

Eric Rosen a chess streamer I follow on YouTube. This is someone who does what he loves and loves what he does.

What’s the best advice you’ve ever received?

someecards.com - Make a shit first draft you cannot edit a blank page
I believe this is a variant on a Hemingway quote.

Is there anything else you’d like to add that might be interesting to readers?

Learn Powershell. There is so much possible with Powershell. If you can learn one thing this year pick Powershell.

Original idea from Lifehacker.com.

Posted in Uncategorized | Tagged , , , , , , , | Leave a comment

Log collection with fluent-bit and ELK

ELK = Elasticsearch, Logstash and Kibana

We are moving to Kubernetes with our applications. So I’ve installed Rancher Desktop om my laptop to get some hands-on experience. I’ll post my findings here.

When pods startup we can get the logs from the command line

kubectl logs <podname> -f

When pods go away we cannot get the logs from that pod anymore. This is by design and a solution is to collect the logs. For this I’m using fluent-bit to get the logs and ELK to store and view the logs.

Elasticsearch

First I’ll deploy Elasticsearch – I had to tune down the resources since my laptop has limited memory. Deployment and Service yaml below:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    component: elasticseach-logging
  name: elasticsearch-logging
spec:
  selector:
    matchLabels:
      component: elasticsearch-logging
  template:
    metadata:
      labels:
        component: elasticsearch-logging
    spec:
      containers:
      - name: elasticsearch
        image: docker.elastic.co/elasticsearch/elasticsearch:7.17.16
        env:
        - name: discovery.type
          value: single-node
        ports:
        - containerPort: 9200
          name: http
          protocol: TCP
        resources:
          limits:
            cpu: 500m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 1Gi
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-logging
spec:
  type: NodePort
  selector:
    component: elasticsearch-logging
  ports:
  - port: 9200
    targetPort: 9200

After deployment the container will need some time to start. Just let it do it’s thing.

Fluent-bit

Fluent-bit is the part that collects the logs from disk and sends them to some storage solution. We’ll let it send the logs to Elasticsearch. For this I use the helm chart from https://github.com/fluent/helm-charts. The default values.yaml needs to be edited to send the logs to the correct address. Changes shown. below.

  outputs: |
    [OUTPUT]
        Name es
        Match kube.*
        Host elasticsearch-logging.logging.svc.cluster.local
        Logstash_Format On
        Retry_Limit 5

Now the logs are send to Elasticsearch it is time to view them.

Kibana

The visualisation tool from elastic.co is Kibana. Again I’ll deploy this linking to Elasticsearch. Deployment, Service and Ingress yaml below:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    component: kibana
  name: kibana
spec:
  selector:
    matchLabels:
      component: kibana
  template:
    metadata:
      labels:
        component: kibana
    spec:
      containers:
      - name: kibana
        image: docker.elastic.co/kibana/kibana:7.17.16
        env:
        - name: ELASTICSEARCH_HOSTS
          value: '["http://elasticsearch-logging:9200"]'
        ports:
        - containerPort: 5601
          name: http
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: kibana
spec:
  type: NodePort
  selector:
    component: kibana
  ports:
  - port: 5601
    targetPort: 5601
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kibana
spec:
  ingressClassName: nginx
  rules:
    - host: kibana.localdev.me
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: kibana
                port:
                  number: 5601

I’m using an ingress to get to the Kibana UI. The domain localdev.me points to 127.0.0.1 and is free to use. Works great.

Viewing the logs

On first opening the Kibana UI it notifies me about creating an index pattern. Just follow along and create the index with logstash and @timestamp.

Now I can filter the logs on the namespace containing my demo applications (Nginx website and Rstudio plumber webapi) and view the logs.

Logs are saved to Elasticsearch and can be viewed after the pod is removed.

Posted in Tooling | Tagged | Leave a comment

Enable metrics server on Rancher Desktop

We are moving to Kubernetes with our applications. So I’ve installed Rancher Desktop om my laptop to get some hands-on experience. I’ll post my findings here.

Metrics server and Metrics API

With the Metrics API you can get CPU and Memory usage from your nodes or pods. By default this is not working in Rancher Desktop.

kubectl top node
error: Metrics API not available
kubectl top pod -A --sort-by memory
error: Metrics API not available

The documentation shows you’ll need a Metrics Server to get this working. Also a location with deployment information is provided. But there is a faster method for Rancher Desktop.

Extensions

Rancher Desktop provides extensions from a “marketplace”. Look for tachometer and install it.

Now the Metrics Server is installed and the Metrics API will work. You’ll also get an interactive view of the pods resource usage in the Rancher Desktop Tachometer tab.

References

Kubernetes documentation https://kubernetes.io/docs/tasks/debug/debug-cluster/resource-metrics-pipeline
Tachometer on docker hub https://hub.docker.com/extensions/julianb90/tachometer

Posted in Tooling | Tagged | Leave a comment

Commit to git from classic release pipeline

We have Azure Devops Server to manage our solutions. The version we currently run comes with yaml build pipelines and classic release pipelines. It is “easy” to commit and push to git from a yaml pipeline with the repository resource definition (details on microsoft learn) You need to do some extra lifting in the classic pipeline.

First enable the “Allow scripts to access the OAuth token” – this makes the $env:SYSTEM_ACCESSTOKEN available to scripts. It is located on the Agent job part inside the Additional options.

Now you can clone the repo with a task like powershell. Make sure to set the working directory.

Write-Host 'Clone repo'
# create base64 encoded version of the access token
$B64Pat = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$env:SYSTEM_ACCESSTOKEN"))
# git with extra header
git -c http.extraHeader="Authorization: Basic $B64Pat" clone  https://AZURE_DEVOPS_URL/_git/REPOSITORY
# move into the repository folder
push-location REPOSITORY
git checkout main

Make your change and commit + push with a task. Make sure to set the same working directory – like the folder with the artefact from the build.

Write-Host 'Add, commit and push file'
$B64Pat = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("`:$env:SYSTEM_ACCESSTOKEN"))
# move into the repository folder
push-location REPOSITORY
# create / update file
Copy-Item -Path ../deployment.yaml -Destination overlays/dev/deployment.yaml -Force
# stage file
git add overlays/dev/deployment.yaml
# provide use info
git config user.email "info@erictummers.com"
git config user.name "build agent"
# commit using the build number
git commit -m "updated deployment to $(Build.BuildNumber)"
# pull and push
git -c http.extraHeader="Authorization: Basic $B64Pat" pull
git -c http.extraHeader="Authorization: Basic $B64Pat" push

In the clean up we remove the repository as a good practice. Again make sure to set the same working directory.

Write-Host 'Clean up'
Remove-Item REPOSITORY -Recurse -Force

Now the file is changed in git from a classic pipeline.

References

Posted in Development | Tagged , | Leave a comment

Rancher Desktop and K3s allowed-unsafe-sysctls

Today I’ve got this error

SysctlForbidden kubelet forbidden sysctl: "net.ipv6.conf.all.disable_ipv6" not whitelisted

Rancher desktop will not accept all sysctls. Some are allowed, but most options are not. To get this working you have to add the setting to the allowed-unsafe-sysctls list.

podSecurityContext:                        
  sysctls:                                 
    - name: net.ipv6.conf.all.disable_ipv6 
      value: '1' 

⭐️ Tip: you can see hidden files in Finder on Mac by pressing CMD + Shift + .

Open ~/library/Application Support/rancher-desktop/lima/_config/override.yaml and add the extra options to K3S_EXEC. Be sure to specify the complete value since the setting is overwritten not appended. Use commas with multiple values.

In the example below I’ve added the option to specify net.ipv6.conf.all.disable_ipv6 next to the default setting values net.ipv4.ip_forward and net.ipv6.conf.all.forwarding. Scroll horizontal to see everything.

env:
  K3S_EXEC: --kubelet-arg=allowed-unsafe-sysctls=net.ipv4.ip_forward,net.ipv6.conf.all.forwarding,net.ipv6.conf.all.disable_ipv6

You can validate the change has been applied by looking at the logfile ~/Library/Logs/rancher-desktop/k3s.log. Here you can find the “default” value before you change it with the override.yaml edit above.

time="2023-12-01T11:35:33Z" level=info msg="Running kubelet --address=0.0.0.0 --allowed-unsafe-sysctls=net.ipv4.ip_forward,net.ipv6.conf.all.forwarding,net.ipv6.conf.all.disable_ipv6 --anonymous-auth=false

References

https://docs.rancherdesktop.io/how-to-guides/provisioning-scripts/

Posted in Development, Security | Tagged , , | Leave a comment

Show container info on hosted static webpage with nginx server side includes

We are creating a CICD pipeline for apps hosting on Kubernetes. One of the things we like to do is to have the build number or any other version information visible in the UI. To achieve this with static webpages hosted in nginx we are using the server side include module and an environment variable.

Setup

The static webpages are hosted in nginx. In the html file(s) we add a special tag for server side include to print a variable.

<p>
    Hello there you are running container version 
    <!--# echo var="version" default="unknown" -->
</p>   

To enable the server side include module we provide a template that nginx processes before starting. This template will override the default website configuration to enable the server side include module and expand an environment variable.

# short version of the template
server {
    listen       80;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        ssi    on;
        set    $version "${CONTAINER_VERSION}";
    }
}

Both the html file(s) and the template are copied into the container during docker build. When the container starts nginx will proces the template, enable ssi and expand the environment variable CONTAINER_VERSION. When hosting a html file with a server side include it will be executed and we see the version as part of the webpage.

For a detailed description and working code see my GitHub https://github.com/erictummers/nginx_k8s_ssi_demo

Posted in Development | Tagged , , , | Leave a comment