profile for Gajendra D Ambi on Stack Exchange, a network of free, community-driven Q&A sites

Monday, January 5, 2026

Planning k8s on hetzner for my webapps

 


I have always been a fan of rke2 but one thing I found lacking and not yet added to their tool is not adding a floating IP for master HA cluster. I use to do the following https://github.com/MrAmbiG/k8s_rke2_HA_KubeVip in such cases in my k8s clusters but getting floating an IP for this and then another for my metalLB, pay for them separately, manage them, seemed like something which I should avoid. So, I decided to go the non non agnostic way of doing these 2 things in my setup where I will be going against my lift and shift principle in IaC and go with hetzner specific config for my HA master config and ingress controller LB setup.

Infrastructure Blueprint

Architecture: Hybrid Cloud (VM masters + Bare Metal workers).

  • Operating System: openSUSE MicroOS (Immutable hosts).
  • HA & Networking: Hetzner Cloud Load Balancers for API and Ingress; Hetzner vSwitch for private networking.
  • Storage: Rook-Ceph for high-speed local block storage on workers.
  • DevOps Management: Dedicated management/jump VM within Hetzner Cloud.

Phase 1: Hetzner Account & Server Prep

  1. Generate API Token: Create a project in the Hetzner Cloud Console and generate a Read/Write API token.
  2. SSH Key: Add your public SSH key to the "Security" tab.
  3. Order Hardware:
    1. Order 3 small Cloud VMs (e.g., CPX11) for the Control Plane (masters).
    2. Order 1 small Cloud VM (e.g., CX11) for the Jump Server (DevOps).
    3. Order 3+ Bare Metal Servers (AX/EX line) for worker nodes. Ensure they have at least two identical raw drives each.
  1. Setup vSwitch: Create a Private Network (vSwitch) in the console and attach all 7+ servers (VMs and Bare Metals) to it.
  2. Security: Restrict public SSH/API access to only the public IP of your new jump server VM.

Phase 2: Deployment via Kube-Hetzner & Terraform

  1. Configure Jump VM: Log in to your new jump server VM. Install terraform, kubectl, helm, and git.
  2. Clone Project: Clone the Kube-Hetzner Terraform module.
  3. Configure terraform.tfvars:
    1.  Set os_type = "microos".
    2.   Define control_plane_count = 3 using the VM instance types.
    3. Provide the IDs of your bare metal servers as worker nodes.
    4. Ensure configuration uses the vSwitch and enables the CCM and CSI.
    5. Configure the module to provision the Hetzner Cloud Load Balancer for the K8s API endpoint (this will be the IP in your kubeconfig).
  1. Initialize & Deploy: Run terraform apply. This handles OS installation, networking, and cluster bootstrapping.
  2. Verify Taints: Confirm masters have node-role.kubernetes.io/control-plane:NoSchedule taint, and bare metal workers are untainted.

Phase 3: Storage Layer (Rook-Ceph)

  1. Keep Drives Raw: Ensure the second drive on all bare metal workers is unformatted.
  2. Install Rook Operator: Deploy the official Helm chart from your jump server.
  3. Provision OSDs: Create a CephCluster CRD to utilize the second raw drive on the worker nodes only.
  4. Define Storage Classes: Use the created rook-ceph-block (RWO) and rook-cephfs (RWX) for your applications.

Phase 4: Ingress & Load Balancing

  1. Install NGINX Ingress: Deploy NGINX Ingress Controller via Helm.
  2. Configure Managed LB: Use the standard K8s Service of type: LoadBalancer with the necessary Hetzner annotations (e.g., load-balancer.hetzner.cloud/type: "lb11") to automatically provision a second, public Hetzner Cloud Load Balancer instance.
  3. External Access: Configure your DNS records to point to the public IP address of this new managed load balancer.

Phase 5: WebApps Deployment

  1. Containerize Apps: Build and push application Docker images to a registry.
  2. Deployments & Services: Create K8s Deployment or StatefulSet manifests (which land on untainted workers).
  3. Define Ingress Rules: Use standard K8s Ingress resources, utilizing the NGINX Ingress Controller to route traffic from your public hostname to internal services.
  4. Persistent Data: Use PVCs with your rook-ceph StorageClasses to attach high-speed persistent storage for databases/uploads.

 

Tuesday, November 11, 2025

Shock absorber design with 9x bike's height & 2x bike's length adjustment

 

 converting kit for existing shocks at the bottom

 converting kit for existing shocks in the middle

 shocks extending beyond the cenre of the wheel

standard fixed

 shocks with 3 different heights, fixed at the end.


Here are my custom shock absorber design for bikes. This will remove the problem of compromising on the height of the bikes to accommodate good shocks. Now you can almost increase the shock travel length (better comfort) upto 50% or more without sacrificing the height. In fact, you can use the modifier shown in the 1st one to plug into your shocks which will allow you 3 riding heights depending on the rider's height, he can adjust it to suit his height. You can add it to the front and back shocks, so not only now you get 3 different heights in the front, 3 in the back, 3*3=9 different height+riding angles, it will also help you to adjust the length of the bike for the first time ever. Instead of stopping the length of the shocks at the centre of the wheel, it can now extend untill the rim of the wheel.

Wednesday, September 24, 2025

openIOT standards

 Today the requirement of an app per IOT device per vendor per platform is driving away the adoption of IOTs (Internet of Things). You have a refrigerator, washing machine, designer lights/bulbs, speaker, NAS, AC, robo vacuum, door camera, house security cameras, all from differenent companies and each of them have their own app, own registration process. So now my phone is bloated with 20 applications who are all draining my data, battery, my personal information. All 20 of them are most likely selling my data to 20000 different marketing/ad agencies & not to mention, 20 different places wher my personal data can get leaked or hacked or stolen.

Solution:

Let vendors have their own proprietory apps per device but let them also have their api approachable in a certain format, preferably in a YAML format. Most of the the things are still RW(read, write). Here is an example concept. This doesnt have to be just for mobile, it can be used for browsers too. Imagine your phone app is now just like a browser,which means you wont need a different app per website or api.

Vendor X Air conditioner. Now, the following yaml can be sent to the client (mobile app) when the connection happens via wifi or BT and based on the following data the UI can get auto populated. A lot of it can be a universal standard like constants, input_types, connect etc., The UI elements get auto rendered based on the input types and purpose, purpose_id.

Identity:
  - constants:
    - name: "sugreeva"
    - model: "X33"
    - serial_number: 0x000000000000
    - product_number: 0x000000000000
    - made_by: "vanara company pvt ltd"
    - made_at: "2020-01-01"
    - made_in: "India"
    - mac: 00:00:00:00:00:00
    - hwid: 0x000000000000
    - Purpose: "Air Conditioner"
    - purpose_id: "aircon" # a unique id for every IOT type with a different purpose, ex: washing machine will be have purpose_id "washingm"
    - image: "" # optional
    - key_values: # optional
      - key1: "value1"
      - key2: "value2"
  - input_types:
    - push: "ajax or live or push notifications, it can be a string or an integer or alphanumeric data"
    - boolean: "true or false"
    - slider: "slider, with a min value and a max value"
    - radio: "multiple options but only one can be selected"
    - checkbox: "multiple options can be selected"
    - string: "text"
    - integer: "number"
    - dropdown: "list of options"
    - kv_w_kv: "key value pairs, both are editable"
    - kv_w_v: "key value pairs, only value can be edited"
    - kv_r_kv: "key value pairs, both are read only"
    - QR: "QR code"
    - upload: "file upload"
    - bluetooth: "bluetooth"
  - connect:
    - description: "Connect to this device using the following methods"
    - wifi:
      - description: "Connect to the wifi network using the following methods"
      - QR:
        - description: "Scan the QR code to connect to the wifi network"
        - input_type: "QR"
      - manual:
        - description: "Enter the SSID and password of the wifi network"
        - input_type: "kv_w_v"
        - SSID: <user input>
        - password: <user input>
    - bluetooth:
        - description: "Connect to the bluetooth device using the following methods"
        - input_type: "bluetooth"

  - inputs:
    - description: "List of inputs that can be used to control the device"
    - system:
      - description: "List of system inputs"
      - health:
        - description: "Health of the device"
        - input_type: "push"
      - update:
        - description: "Update the device"
        - update_status:
          - description: "Status of the update, updating, updated, last update failed, no updates etc.,"
          - input_type: "push"
        - update_progress:
          - description: "Progress of the update, it can be a % or a number"
          - input_type: "push"
        - alert:
          - description: "Alert when an update is available"
          - input_type: "push"
      - tags:
        - description: "System tags for the device"
        - input_type: "kv_r_kv"
        - key1: value1
        - key2: value2
      warranty:
        - description: "Warranty of the device"
    - user:
      - description: "List of user inputs available for the user"
      - tags:
        - description: "User tags for the device"
        - input_type: "kv_w_kv"
        - key1: value1
        - key2: value2
        - key3: value3
        - key4: value4
      - temperature:
        - description: "Set the temperature"
        - input_type: "slider"
        - min: 0
        - max: 100
      - fan_speed:
        - description: "Set the fan speed"
        - input_type: "radio"
        - options:
          - low
          - medium
          - high
          - cool
          - dry
          - auto
      - power:
        - description: "Turn the device on or off"
        - input_type: "radio"
        - options:
          - on
          - off
          - restart
      - maintenace:
        - description: "Perform maintenance on the device"
        - healthcheck:
          - description: "Check the health of the device"
          - input_type: "checkbox"
          - options: # If only one option, then just display a submit button or cofirm button
            - confirm
        - clean:
          - description: "Clean the device"
          - input_type: "checkbox"
          - options: # If only one option, then just display a submit button or cofirm button
            - confirm
      - powerful:
        - description: "powerful mode, users more power"
        - input_type: "boolean"
      - swing_vertical:
        - description: "Swing the device vertically"
        - input_type: "toggle"
        - options:
          - left
          - right
          - center
          - left to right
      - swing_horizontal:
        - description: "Swing the device horizontally"
        - input_type: "toggle"
        - options:
          - top
          - bottom
          - center
          - top to bottom



# EOF

Wednesday, August 13, 2025

Internet companies nerf your profile/accounts online

 It was probably first noticed widely on twitter with the name *shadow banning* and it still exists even though name changed to x. This is not new. Youtube has been doing it for ages, they boost or nerf certain content or the creator depending on whether the creator or content is profit friendly or not. Everyone who knows this from ages somehow thinks that video game companies don't do it or it is just the bots employed by these companies who disagree with you. I myself know this from my own personal experience where a game called apex legends by repsawn+EA keeps nerfing free user's accounts, boost consistant spender's accounts and their gameplay. They feed free users to consistantly spending users as cannon fodder. Free users are those who do not spend money to buy virtual items in the game. They haven't spend money and most probably won't. There are also statistics in these games and I have seen on multiple occasionson how they undo/overwrite/modify your statistics all of a sudden includingthe hours you have spent. ex: daily challanges. Everyday they reset at 3.30pm IST. I start doing them around 4pm IST. I did that yesterday and today when I checked around 3.14pm, the daily challange itself was changed. I have not played octane in like a month but one of the daily challange is to play the octane 4 times and it shows that I have completed that part. I have completed 2/5 daily challanges. 1 of the incomplete challange was get 10 kills or assists. I have like 15 minutes and I would definitely won't be able to do it even though I have nearly 10k hours on this game. 4 days ago 1 of the daily challange was to get 10knock outs. I was playing as fuse. I got stuck at 8 KOs and every thing else was just getting counted as assists. After hours and hours, aftger 50 assists, I got 10KOs and that too when I started exiting the game within first 5 minutes of the game If I don't get a KO or a kill count because then the AI realised that the game is not going to get my free time without giving me something in return.

Monday, August 11, 2025

The Godaddy scam

 


I have heard of this scam but I didnt believe it.

  • Keep receiving mails about domains expiring soon, even though auto renew is set and the sometimes the early renewal is already done
  • keep receiveing mails about payment method missing but when I login and check, the credit card info is still present and tested to be working, including paypal.
  • You end up ignoring such mails later, thinking that it is just another false flag, just like before and boom, you lose your domain.
  • I cannot confirm but I heard that it is an organised scam by employee+buyer to do this to the owner of a domain that they are intersted in, keep torturing him/her with fake alerts, enough fake alerts to make sure that they soon start ignoring such mails and once they do, the auto renew somehow fails or never triggers the auto renewal and you lose your domain.
The above btw has happened to me, I fortunately bought that domain again from some other provider and then transferred it to godaddy. I want to know whether such things have happened with you as well. Most of my domains are .in and I am thinking of transferring all to cloudflare.