Docker - Traefik

Intro

Following a Working Example how to get Traefik and a few Dummy Containers running on Docker. If you wanna have a bit advanced Example and put some Variables in a “.env” File, you may wanna check this Post.

Requirements

Linux Host with Docker see here, Public IP Adress and rechable Port 80 & 443

two FQDN pointing to your IP:

  • traefik.yourdomain.de
  • whoami.yourdomain.de

Docker Traefik Example

cat << EOF > docker-compose.yml
version: "3.3"

services:
  traefik:
    image: "traefik:v2.9"
    container_name: "traefik"
    command:
      # Traefik Log
      - "--log.level=DEBUG"
      - "--log.filePath=/logs/traefik.log"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      # Access Log
      - "--accesslog=true"
      - "--accesslog.filePath=/logs/access.log"
      # Prometheus metrics
      ## Enable prometheus metrics
      - "--metrics.prometheus=true"
      ## Create a manual router instead of the default one.
      - "--metrics.prometheus.manualrouting=true"
      - "--metrics.prometheus.addrouterslabels=true"
    ports:
      - "80:80"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./logs/:/logs/"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.dashboard.rule=Host(`traefik.yourdomain.de`)"
      - "traefik.http.routers.dashboard.entrypoints=web"
      - "traefik.http.routers.dashboard.service=api@internal"
      # Auth: dasboard/XXXXXXXX
      - "traefik.http.routers.dashboard.middlewares=dashboard_auth"
      - "traefik.http.middlewares.dashboard_auth.basicauth.users=dashboard:$$XXXXXXXXXXXXXXXXXXXX"

  whoami:
    image: "traefik/whoami"
    container_name: "simple-service"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.yourdomain.de`)"
      - "traefik.http.routers.whoami.entrypoints=web"
EOF

Up

docker compose up -d

Redirect HTTP to HTTPS

replace MAIL@YOURDOMAIN.DE, traefik.yourdomain.de and whoami.yourdomain.de with the appropriate Values …

K8s - Kubernetes

Show Contexts

kubectl config get-contexts
CURRENT   NAME                           CLUSTER                        AUTHINFO                             NAMESPACE
*         do-fra1-k8s-1-24-xxxxxxxxxxx   do-fra1-k8s-1-24-xxxxxxxxxxx   do-fra1-k8s-1-24-xxxxxxxxxxxxxxxxx
          do-fra1-k8s-1-25-xxxxxxxxxxx   do-fra1-k8s-1-25-xxxxxxxxxxx   do-fra1-k8s-1-25-xxxxxxxxxxxxxxxxx
          do-fra1-k8s-xxxxx              do-fra1-k8s-xxxxx              do-fra1-k8s-xxxxxxxxxxx

Delete old Contexts

kubectl config delete-context do-fra1-k8s-xxxxx

Any Comments ?

sha256: f12aa09936d175b3e23f2eebc1c152675d68dce6096b9ec02d7f8429b954b4fe

K3s - Kubernetes

Let’s give a Try with Kubernetes Mini, K3s

Source

Overview

TestSetup

Booting a few VM’s on my ESX Host. All of them got 4 CPU’s, 32 GB RAM, 100G Disk

1 MasterNode

  • Master

3 WorkerNodes

  • Worker01
  • Worker02
  • Worker03

All Maschines are Running Debian Latest, that’s Version 11.6 at the Moment

Setup Master

curl -sfL https://get.k3s.io | sh -
root@master:~/bin/test_kubernetes# curl -sfL https://get.k3s.io | sh -
[INFO]  Finding release for channel stable
[INFO]  Using v1.25.4+k3s1 as release
[INFO]  Downloading hash https://github.com/k3s-io/k3s/releases/download/v1.25.4+k3s1/sha256sum-amd64.txt
[INFO]  Downloading binary https://github.com/k3s-io/k3s/releases/download/v1.25.4+k3s1/k3s
[INFO]  Verifying binary download
[INFO]  Installing k3s to /usr/local/bin/k3s
[INFO]  Skipping installation of SELinux RPM
[INFO]  Creating /usr/local/bin/kubectl symlink to k3s
[INFO]  Creating /usr/local/bin/crictl symlink to k3s
[INFO]  Skipping /usr/local/bin/ctr symlink to k3s, command exists in PATH at /usr/bin/ctr
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s.service
[INFO]  systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO]  systemd: Starting k3s

Show Nodes

kubectl get nodes
root@master:~/bin/test_kubernetes# kubectl get nodes
NAME     STATUS   ROLES                  AGE   VERSION
master   Ready    control-plane,master   70s   v1.25.4+k3s1

Show Token

cat /var/lib/rancher/k3s/server/node-token 
K10032f55153f52072a1e41f80f06551078dece476a44217e5a06facdfa6fd0f985::server:a70b4452634b7d2c4f9d33ab8808eb19

on all Worker Nodes

update hosts as root

Django on Gooogle Cloud

I’ll give a try running an Application on Google Cloud. Not with great sucess :(

Source

Get Cloud List, Active Account

gcloud auth list
gcloud config set account 'username@gmail.com'

List Projects

gcloud config list project
[core]
project = cloud-run-372113

Your active configuration is: [cloudshell-6045]
username@cloudshell:~ (cloud-run-372113)$

Set Project ID

gcloud config set project cloud-run-372113
username@cloudshell:~ (cloud-run-372113)$ gcloud config set project cloud-run-372113
Updated property [core/project].

Enable API

gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  run.googleapis.com
username@cloudshell:~ (cloud-run-372113)$ gcloud services enable \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  run.googleapis.com
ERROR: (gcloud.services.enable) User [username@gmail.com] does not have permission to access projects instance [cloud-run-372113] (or it may not exist): Project 'cloud-run-372113' not found or permission denied.
Help Token: AXyIxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- '@type': type.googleapis.com/google.rpc.PreconditionFailure
  violations:
  - subject: ?error_code=210002&type=Project&resource_id=cloud-run-372113
    type: googleapis.com
- '@type': type.googleapis.com/google.rpc.ErrorInfo
  domain: serviceusage.googleapis.com
  metadata:
    resource_id: cloud-run-372113
    type: Project
  reason: RESOURCES_NOT_FOUND
username@cloudshell:~ (cloud-run-372113)$

Any Comments ?

sha256: bbf813a31c1281e47acfdca36d3b92b75b87039c93d4f295cd9a5825953e8628

Docker on Freebsd

Fireup FreeBSD 14 Instance on AWS ?!?

Install Packages

pkg install gmake go git vim

Install Lima

git clone https://github.com/lima-vm/lima /opt/lima

Patch File

cat << EOF > /opt/lima/pkg/sshutil/sshutil_others.go
//go:build !darwin && !linux
// +build !darwin,!linux

package sshutil

import (
        "runtime"

        "github.com/sirupsen/logrus"
)

func detectAESAcceleration() bool {
        var err error
        const fallback = runtime.GOARCH == "amd64"
        logrus.WithError(err).Warnf("cannot detect whether AES accelerator is available, assuming %v", fallback)
        return fallback
}
EOF

Build

gmake

Copy Binaries

cp /opt/lima/_output/bin/* /usr/local/bin/

mkdir -p /usr/local/share/doc/lima && cp -r /opt/lima/_output/share/doc/lima/* /usr/local/share/doc/lima/
cp -r /opt/lima/_output/share/lima /usr/local/share/lima

Install QEMU

pkg install qemu-nox11

Get CPU

root@freebsd:/opt/lima # qemu-system-x86_64 -cpu help | grep -i cascadelake
x86 Cascadelake-Server    (alias configured by machine type)
x86 Cascadelake-Server-noTSX  (alias of Cascadelake-Server-v3)
x86 Cascadelake-Server-v1  Intel Xeon Processor (Cascadelake)
x86 Cascadelake-Server-v2  Intel Xeon Processor (Cascadelake) [ARCH_CAPABILITIES]
x86 Cascadelake-Server-v3  Intel Xeon Processor (Cascadelake) [ARCH_CAPABILITIES, no TSX]
x86 Cascadelake-Server-v4  Intel Xeon Processor (Cascadelake) [ARCH_CAPABILITIES, no TSX]
x86 Cascadelake-Server-v5  Intel Xeon Processor (Cascadelake) [ARCH_CAPABILITIES, EPT switching, XSAVES, no TSX]

Export CPU

export QEMU_SYSTEM_X86_64="qemu-system-x86_64 -cpu Cascadelake-Server"

Start Lima

switch to user

Hashicorp - Vault

some Hands’on with Hashicorp Vault

Source

https://developer.hashicorp.com/vault/docs/get-started/developer-qs

Install on macos

brew tap hashicorp/tap
brew install hashicorp/tap/vault

Run on Docker

in Background, you have to kill it later

docker run -d -p 8200:8200 -e 'VAULT_DEV_ROOT_TOKEN_ID=dev-only-token' vault
Unseal Key: 2KTIMp0Md52V2xTb0txxxxxxxxxxxxxxxxxxxxxxxxx=
Root Token: dev-only-token

this is a dev instance only and has no persistent data. don’t worry.

Open Browser

  • http://localhost:8200 -> root token

Export in Terminal

export VAULT_ADDR='http://0.0.0.0:8200'
export VAULT_TOKEN="dev-only-token"

Set Key

curl  --header "X-Vault-Token: $VAULT_TOKEN" \
      --header "Content-Type: application/json" \
      --request POST \
      --data '{"data": {"password": "Hashi123"}}' \
      -s http://127.0.0.1:8200/v1/secret/data/my-secret-password

-> Data get’s written to Store …

Docker - Container

Stuff for the running Containers

List running Containers

$ docker ps
CONTAINER ID  IMAGE   COMMAND                  CREATED          STATUS          PORTS                    NAMES
f99ad3355bae  blog    "/home/docker/init_a…"   14 minutes ago   Up 14 minutes   0.0.0.0:3031->3031/tcp   quizzical_bardeen

Shell into Containter

docker exec -it f99ad3355bae bash

first build cache

apt-get update

install Tools

  • netstat
  • ps
  • tcpdump
apt-get install -y net-tools procps tcpdump telnet netcat

Any Comments ?

sha256: 27a1368fbcb11db26404131aeb2b0e15d07bc32f61df6389a7c685df61bfc5aa

Alpine - Pandas on Docker Image

How to install Pandas on Alpine Linux

Run Alpine Container

docker run -it alpine

add packages

apk update
apk add python3 py3-pip gcc python3-dev g++

add / build pandas

time pip install pandas
real 26m 13.14s
user 30m 46.40s
sys   3m 27.51s

Happy Pandas !


Any Comments ?

sha256: afb99c7e3ed003bee48b65795a153c4fe7835fe3dae0759b70ab2bfb5adc4fd5

Fastapi

FastAPI - Dependencies and Custom Headers

Source

Code

from fastapi import Depends, FastAPI, Header, HTTPException

app = FastAPI()


async def verify_token(x_token: str = Header()):
    if x_token != "fake-super-secret-token":
        raise HTTPException(status_code=400, detail="X-Token header invalid")


async def verify_key(x_key: str = Header()):
    if x_key != "fake-super-secret-key":
        raise HTTPException(status_code=400, detail="X-Key header invalid")
    return x_key


@app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)])
async def read_items():
    return [{"item": "Foo"}, {"item": "Bar"}]

Test’s

Failed

no Custom Header

curl -s http://localhost/api/items/ |jq
{
  "detail": [
    {
      "loc": [
        "header",
        "x-token"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    },
    {
      "loc": [
        "header",
        "x-key"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

adding “x-token”

Acme-DNS

Web

A simplified DNS server with a RESTful HTTP API to provide a simple way to automate ACME DNS challenges. Sounds promising, right ? Let’s give try ;)

Setup

fireup a new OpenBSD VM

  • let’s do it in London.
  • ip: 100.10.20.30

patch, update, add go

doas su -
syspatch
pkg_add -Vu
pkg_add go

clone repo and build acme-dns

cd /root
git clone https://github.com/joohoi/acme-dns
cd acme-dns
export GOPATH=/tmp/acme-dns
go build
cp acme-dns /usr/local/sbin/

Create Selfsign Cert

the RESTful API need’s a Cert. Let’s use a selfsigned Cert for this demonstration.