Monday, June 8, 2026

Ansible Cheat Sheet

Ansible is an agentless automation platform used for:
  • Server configuration
  • Application deployment
  • Infrastructure provisioning
  • Patch management
  • Security hardening
  • Cloud automation
  • Kubernetes automation
Unlike Puppet or Chef, Ansible does not require agents on managed machines. It typically communicates through:
  • SSH (Linux)
  • WinRM (Windows)

1. Core Ansible Architecture

Before learning commands, understand the overall architecture.

+------------------+
| Control Node |
| (Ansible Server) |
+--------+---------+
|
SSH / WinRM
|
------------------------------------------------
| | |
+-------------+ +-------------+ +-------------+
| Managed Node| | Managed Node| | Managed Node|
| Server1 | | Server2 | | Server3 |
+-------------+ +-------------+ +-------------+

Components

Component Purpose
Control Node Machine where Ansible runs
Managed Node Target machine
Inventory List of managed nodes
Playbook Automation instructions
Module Unit of work
Role Reusable collection of tasks
Variables Dynamic values
Facts Information collected from hosts

2. Installation and Verification

Ubuntu

sudo apt update
sudo apt install ansible

RHEL

sudo dnf install ansible

Verify Installation

ansible --version
Example Output:
ansible [core 2.18]

3. Inventory (Most Important Concept)

Inventory tells Ansible:

Which machines should be managed?

Static Inventory

[web]
web1.example.com
web2.example.com

[db]
db1.example.com
db2.example.com

Host Groups

[web]
web1
web2

[db]
db1
db2

[production:children]
web
db
production
├── web
│  ├── web1
│  └── web2
└── db
    ├── db1
    └── db2

4. Checking Inventory

List All Hosts

ansible all --list-hosts

List Specific Group

ansible web --list-hosts

Display Inventory

ansible-inventory -i inventory.ini --list

Visual Tree

ansible-inventory -i inventory.ini --graph

5. First Ad-Hoc Command

Ad-hoc commands are one-time executions used for quick administrative tasks without creating a playbook.

Ping All Servers

ansible all -m ping
Example Output
web1 | SUCCESS
web2 | SUCCESS
db1  | SUCCESS
db2  | SUCCESS

Check Uptime

ansible all -m command -a "uptime"

Check Memory Usage

ansible all -m shell -a "free -h"
Tip: Ad-hoc commands are ideal for troubleshooting, verification, quick updates, and emergency operations.

6. Modules

Modules are the fundamental building blocks of Ansible automation.

Playbook

Tasks

Modules

Common Modules

Module Purpose
ping Connectivity test
command Execute command
shell Execute shell command
copy Copy files
file Manage files/directories
package Install packages
apt Ubuntu package management
yum RHEL package management
service Manage services
user User management
cron Cron job management
git Git repository operations
reboot Reboot machines
uri HTTP requests

Example Module Usage

- name: Install nginx
  apt:
    name: nginx
    state: present
Here, apt is the module being executed.

7. Playbooks

Playbooks are YAML files that describe automation workflows.

Simple Playbook Example

---
- name: Install nginx
  hosts: web

  tasks:
    - name: Install package
      apt:
        name: nginx
        state: present

Run Playbook

ansible-playbook nginx.yml
Think of a playbook as a reusable automation script written in YAML.

8. Anatomy of a Playbook

---
- name: Web setup
  hosts: web
  become: true

  vars:
    package_name: nginx

  tasks:
    - name: Install package
      apt:
        name: "{{ package_name }}"
        state: present

Main Sections

Section Purpose
hosts Target machines
become Privilege escalation (sudo)
vars Variables
tasks Work to perform
handlers Triggered tasks
roles Reusable components

9. Variables

Variables make playbooks flexible and reusable.

Define Variables

vars:
  app_port: 8080

Use Variables

{{ app_port }}

Command Line Variables

ansible-playbook deploy.yml -e app_port=9090

Inventory Variables

web1 ansible_host=10.0.0.1 app_port=8080
Best Practice: Use variables extensively instead of hardcoding values directly into playbooks.

15. Limiting Execution

Very important in production environments. Limiting execution allows you to target only specific hosts or groups instead of running against the entire inventory.

Run on One Host

ansible-playbook site.yml --limit web1

Run on a Group

ansible-playbook site.yml --limit web

Run on Multiple Hosts

ansible-playbook site.yml --limit web1,web2

Exclude a Host

ansible-playbook site.yml --limit 'web:!web2'

16. Privilege Escalation

Used when tasks require root or administrator privileges.

Enable Privilege Escalation

become: true

Equivalent to:

sudo

17. Parallelism

Ansible executes tasks in parallel across hosts. The number of parallel workers is controlled by the forks setting.

Check Current Forks Value

ansible-config dump | grep forks

Default:

5

Override Fork Count

ansible-playbook site.yml -f 20

Increasing forks can significantly speed up operations on large inventories.


18. Success and Failure Checking

Typical Playbook Result

ok=10
changed=2
unreachable=0
failed=0
Field Meaning
ok Already compliant
changed Configuration was modified
unreachable SSH / connectivity issue
failed Task execution failed

Detailed Output

ansible-playbook site.yml -vvv

Dry Run

ansible-playbook site.yml --check

Show Differences

ansible-playbook site.yml --check --diff

19. Roles

As Ansible projects grow, playbooks can become large and difficult to maintain. Roles provide a standardized way to organize automation into reusable components.

Why Use Roles?

  • Improves project structure
  • Encourages reuse across environments
  • Separates configuration, templates, variables, and tasks
  • Makes large automation projects manageable

Typical Role Structure

roles/
└── nginx/
    ├── tasks/
    │   └── main.yml
    ├── handlers/
    │   └── main.yml
    ├── templates/
    ├── files/
    ├── vars/
    │   └── main.yml
    ├── defaults/
    │   └── main.yml
    └── meta/
        └── main.yml

Using a Role

---
- hosts: web
  roles:
    - nginx

Create a Role Skeleton

ansible-galaxy role init nginx

This automatically creates the complete directory structure.


20. Templates (Jinja2)

Templates allow configuration files to be generated dynamically using variables.

Example Template

nginx.conf.j2

server {
    listen 80;
    server_name {{ domain_name }};
}

Deploy Template

- name: Deploy nginx configuration
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf

Variable Example

domain_name: example.com

Generated output:

server {
    listen 80;
    server_name example.com;
}

Templates are one of the most heavily used features in real-world Ansible deployments.


21. Ansible Vault

Production environments frequently contain sensitive information such as:

  • Passwords
  • API Keys
  • Cloud Credentials
  • Database Secrets
  • Certificates

Ansible Vault encrypts these values so they can safely reside in source control repositories.

Create an Encrypted File

ansible-vault create secrets.yml

Edit an Existing Vault

ansible-vault edit secrets.yml

Encrypt an Existing File

ansible-vault encrypt secrets.yml

Run a Playbook Using Vault

ansible-playbook site.yml --ask-vault-pass

Using a Vault Password File

ansible-playbook site.yml \
  --vault-password-file vault.pass

This is the preferred method for CI/CD pipelines.


22. Rebooting All Machines

A common operational task is rebooting a fleet of servers after:

  • Kernel upgrades
  • Operating system patches
  • Security updates
  • Infrastructure maintenance

Using the Reboot Module

---
- hosts: all
  become: true

  tasks:
    - name: Reboot servers
      reboot:

Specify Reboot Timeout

---
- hosts: all
  become: true

  tasks:
    - name: Reboot servers
      reboot:
        reboot_timeout: 600

The playbook waits until the host becomes reachable again before proceeding.

Run Against a Specific Group

---
- hosts: web

  tasks:
    - reboot:

Run Against the Entire Inventory

ansible-playbook reboot.yml

Run Against a Subset

ansible-playbook reboot.yml --limit web

For large environments, combine reboots with serial execution to avoid restarting every server simultaneously.

---
- hosts: web
  serial: 2

  tasks:
    - reboot:
Production Tip:
Use serial when rebooting clusters, application servers, or databases to prevent full-service outages during maintenance windows.

23. Serial Execution (Rolling Updates)

Serial execution allows Ansible to update servers in batches rather than all at once. This is commonly used for rolling updates in production environments to minimize downtime.

Example

---
- hosts: web
  serial: 1

  tasks:
    - name: Update package
      apt:
        name: nginx
        state: latest

Execution Flow

web1 → complete
web2 → complete
web3 → complete
Production Use Case:
Ideal for application deployments, operating system patching, and service upgrades where availability must be maintained during updates.

24. Dynamic Inventory

Instead of manually maintaining inventory files, Ansible can dynamically discover infrastructure by querying cloud providers and virtualization platforms.

Supported Platforms

  • AWS EC2
  • Azure Virtual Machines
  • Google Cloud Platform (GCP) Instances
  • VMware Environments

How It Works

Cloud API
    ↓
Dynamic Inventory
    ↓
Ansible

Whenever infrastructure changes, Ansible automatically retrieves the latest host information from the provider, eliminating manual inventory updates.


25. Ansible Galaxy

Ansible Galaxy is the official public repository for reusable Ansible roles and collections.

Install a Role

ansible-galaxy role install geerlingguy.nginx

You can get the installation command from the ansible galaxy documentation. For example, the above command is taken from https://galaxy.ansible.com/ui/standalone/roles/geerlingguy/nginx/

Benefits

  • Reuse community-maintained automation
  • Reduce development effort
  • Adopt proven best practices
  • Accelerate infrastructure provisioning

26. Error Handling

Ansible provides structured error handling using the block, rescue, and always keywords.

Example

- block:

    - name: risky task
      command: something

  rescue:

    - name: recovery
      debug:
        msg: failed

  always:

    - name: cleanup
      debug:
        msg: cleanup

Programming Equivalent

Ansible Programming Equivalent
block try
rescue catch
always finally

This structure allows playbooks to recover gracefully from failures while ensuring cleanup operations always execute.


27. Project Structure (Recommended)

For maintainable enterprise-grade automation, organize your Ansible projects using a consistent directory structure.

ansible-project/
│
├── inventory/
│   ├── dev
│   ├── test
│   └── prod
│
├── playbooks/
│   ├── deploy.yml
│   ├── reboot.yml
│   └── patch.yml
│
├── roles/
│   ├── nginx
│   ├── mysql
│   └── common
│
├── group_vars/
├── host_vars/
│
├── templates/
├── files/
│
└── ansible.cfg

Benefits

  • Improved maintainability
  • Clear separation of responsibilities
  • Environment-specific configuration management
  • Scalability for large infrastructure projects

28. Most Important Commands Cheat Sheet

Purpose Command
Check version ansible --version
Ping all hosts ansible all -m ping
List inventory ansible-inventory --list
Inventory graph ansible-inventory --graph
Gather facts ansible all -m setup
Run command ansible all -m command -a "uptime"
Execute playbook ansible-playbook site.yml
Dry run ansible-playbook site.yml --check
Limit hosts ansible-playbook site.yml --limit web
Run tags ansible-playbook site.yml --tags install
Verbose mode ansible-playbook site.yml -vvv
Create role ansible-galaxy role init nginx
Reboot hosts ansible all -m reboot
Encrypt secrets ansible-vault create secrets.yml
Conclusion:
The combination of inventories, playbooks, roles, templates, vaults, and dynamic inventories forms the foundation of real-world Ansible automation at enterprise scale.

Ansible block, rescue, and always

In Ansible, a block logically groups multiple tasks together, allowing you to control execution flow and handle errors as a single unit. The always keyword defines a sequence of tasks within a block that execute regardless of whether the tasks inside the block succeeded or failed.

1. How the block and always Structure Works

This combination is conceptually similar to a try/finally construct in programming languages such as Python and Java.

Execution Flow
  1. block: The primary sequence of tasks you want to execute.
  2. rescue (optional): A sequence of tasks that runs only if a task inside the block fails.
  3. always: A sequence of tasks that runs unconditionally, whether the block succeeds, fails, or is handled by the rescue section.

2. When to Use always

The always section is best suited for guaranteed cleanup operations and state restoration that must occur regardless of playbook execution outcomes.

Common Use Cases
  • Deleting temporary files, scripts, or installer packages.
  • Releasing locks or closing connections.
  • Restoring maintenance windows or re-enabling monitoring alerts.
  • Ensuring specific services are restarted or left in a healthy state.

3. Code Example

The following playbook demonstrates how block, rescue, and always work together:

- hosts: web_servers
  tasks:
    - name: Run main operations with error handling
      block:
        - name: Step 1 - Perform deployment tasks
          ansible.builtin.command: /bin/deploy_app

        - name: Step 2 - Verify application status
          ansible.builtin.command: /bin/verify_app

      rescue:
        - name: Rollback deployment on failure
          ansible.builtin.command: /bin/rollback_deploy

      always:
        - name: Clean up temporary installer files
          ansible.builtin.file:
            path: /tmp/app_installer.tar.gz
            state: absent

        - name: Re-enable monitoring alerts
          ansible.builtin.uri:
            url: https://monitoring.local
            method: POST
In the above code, ansible.builtin.command is a package that runs the script file/executable file specified against it. 

4. Execution Scenarios

Scenario block rescue always
All tasks succeed ✅ Runs ❌ Skipped ✅ Runs
Task fails inside block ❌ Fails ✅ Runs ✅ Runs
Rollback succeeds Completed Completed ✅ Runs

5. Key Takeaway

Think of Ansible's execution flow as:

block → rescue → always
  • block performs the primary work.
  • rescue handles failures and recovery actions.
  • always guarantees cleanup and state restoration.
This pattern is ideal for deployments, upgrades, maintenance operations, and any automation workflow that requires reliable cleanup regardless of success or failure.

Architectural Comparison of Hash Map Implementations

This table compares how Java, C#, Python, and JavaScript implement their native hash-map data structures, including collision handling, performance characteristics, memory layouts, concurrency support, and alternative sorted-map implementations.

Architectural Dimension Java (HashMap) C# (Dictionary) Python (dict) JavaScript (Map)
Language Interface Type Map<K, V> (Blueprint) IDictionary<TKey, TValue> Built-in native type Native ES6 standard class object
Primary Concrete Class HashMap<K, V> Dictionary<TKey, TValue> dict Map
Key Order Preservation ❌ No (Unpredictable) ❌ No (Unpredictable) ✅ Yes (Insertion order since Python 3.7) ✅ Yes (Strict insertion order)
Missing Key Behavior Returns null Throws KeyNotFoundException Throws KeyError Returns undefined
Allows Null Keys / Values Keys: Yes (Max 1)
Values: Yes
Keys: ❌ No (Throws error)
Values: Yes
Keys: Yes (as None)
Values: Yes
Keys: Yes
Values: Yes
Allows Duplicate Keys / Values Keys: ❌ No (Overwrites)
Values: Yes
Keys: ❌ No (Overwrites)
Values: Yes
Keys: ❌ No (Overwrites)
Values: Yes
Keys: ❌ No (Overwrites)
Values: Yes
Average Time Complexity O(1) (Constant) O(1) (Constant) O(1) (Constant) O(1) (Constant)
Worst-Case Time Complexity O(log n) (Logarithmic) O(n) (Linear) O(n) (Linear) O(n) (Linear)
Collision Resolution Logic Chaining: Linked List that dynamically converts to a Red-Black Tree Chaining via Arrays: Flattened array entries tracking numeric chain indexes Open Addressing: Sequential slot probing using an erratic jumps formula Open Addressing: Deterministic hashing loops inside engine backing store
Hash Function Control Developer can override via .hashCode() Developer can override via .GetHashCode() Developer can override via __hash__() Controlled entirely by the engine
Hash Function Vulnerability Protection Treeification fallback protects against hash-flooding Randomized internal seeds across domains/processes SipHash randomization on every application startup Randomized seed initialized inside the V8 engine context
Storage Layout Location Reference on Stack, Structures on Heap Reference on Stack, Structures on Heap Reference on Stack, Structures on Heap Reference on Stack, Structures on Heap
Memory Contiguity Sparse bucket array points to fragmented Node objects across Heap Flat, contiguous entry arrays. Packs value types directly inside Split-array layout. Integer index grid + dense packed entry array Contiguous backing-store table pointing to heap objects
Default Load Factor 0.75 (Resize at 75% capacity) 1.00 (Resize when bucket bounds are hit) 0.66 (2/3 capacity) 0.50 (Resize when half-empty)
Deletion Management Unlinks linked-list nodes or tree leaves directly Updates entry metadata tracking pointers to -1 Inserts Tombstone markers for future searches Marks backing-store index as dead/empty
Native Tree Alternative TreeMap (O(log n), sorted keys) SortedDictionary (O(log n), sorted keys) None in Standard Library (Requires sortedcontainers) None in Standard Library (Requires NPM packages)
Multithreading Protection ConcurrentHashMap (Lock Striping / CAS) ConcurrentDictionary (Fine-grained segmented mutexes) Protected by the Global Interpreter Lock (GIL) Single-threaded Event Loop architecture
Key Takeaway: Although all four implementations provide average O(1) lookup performance, their internal architectures differ significantly. Java emphasizes worst-case guarantees through treeification, C# optimizes for memory locality with contiguous arrays, Python prioritizes cache-friendly open addressing, and JavaScript relies on engine-managed hash-table implementations optimized for browser and runtime environments.

Whatever looks "Smarter" on paper, is not always so! The Interesting case of HashMaps

Data Locality, CPU Caches, and the Hidden Performance of Hash Maps

Algorithms that look pure and elegant on a whiteboard often choke in production if they don't respect the physics of modern CPU caches and memory layouts. Data locality and hardware sympathy beat algorithmic purity every single time.

Almost every modern language provides hash maps, although the implementations are different in each language. When we compare implementations of hashing algorithms across Python, C#, Java, and JavaScript, it distinctively emerges that whatever looks smarter on paper is not always practically so.


Python's Counter-Intuitive Win (Hardware over Theory)

The Theory

When hash collisions occur, languages like Java take the mathematically elegant route—they branch off into separate data structures such as Linked Lists or Red-Black Trees.

Python takes a seemingly chaotic route called Open Addressing, where colliding items are "scrambled" and placed into the next available empty slot.

The Problem

This looks messy on paper.

  • Deleting an item forces Python to leave behind Tombstones (sentinel markers).
  • These markers ensure future searches continue to work correctly.
  • The runtime must actively filter out dead entries during iteration.

The Practical Reality

Python wins because of modern CPU architecture.

Java's elegant tree-based structures force the processor into Pointer Hopping—jumping across fragmented memory locations throughout RAM.

These jumps create expensive CPU Cache Misses, which significantly slow execution.

Python instead stores its hash table as a dense, flat array of sequential memory locations.

Modern CPUs are optimized for exactly this pattern because they aggressively preload contiguous memory into ultra-fast:

  • L1 Cache
  • L2 Cache
  • Cache Lines

As a result, Python's seemingly messy implementation frequently outperforms mathematically cleaner designs.


The Tree vs. HashMap Paradox (The Cache Line Miracle)

The Theory

On paper, Tree Maps appear superior to HashMaps.

Their advantages seem compelling:

  • Memory is allocated only when needed.
  • No empty padding slots.
  • No periodic rehashing operations.
  • Guaranteed O(log n) performance.
  • Data remains naturally sorted.
Theoretical Complexity:

Lookup Time = O(log n)

The Practical Reality

In real-world production systems, HashMaps routinely outperform Trees in both speed and memory efficiency.

The Memory Trap

Trees avoid empty slots, but every entry must be wrapped inside a heavy Node object.

Each node contains structural metadata such as:

  • Left Pointer
  • Right Pointer
  • Parent Pointer
  • Color Flag (for Red-Black Trees)
  • Object Headers

This overhead frequently consumes 3 to 4 times more memory than the unused padding found in a HashMap.

The CPU Trap

Searching a Tree forces the CPU through multiple expensive steps:

  1. Evaluate the current node.
  2. Read a memory pointer.
  3. Fetch the next node from RAM.
  4. Wait for memory access.
  5. Jump again.
  6. Repeat until the target is found.

A HashMap takes a dramatically different path:

  1. Compute a hash value.
  2. Calculate the target index.
  3. Jump directly to a contiguous memory location.
  4. Read the value.

The processor performs fewer memory jumps and enjoys significantly better cache utilization.


Side-by-Side Comparison

Aspect Tree Map HashMap
Theoretical Lookup O(log n) Average O(1)
Memory Allocation Node per entry Dense contiguous array
Cache Friendliness Poor Excellent
Pointer Chasing Heavy Minimal
Sorted Order Yes No
Real-World Speed Often Slower Often Faster
Memory Efficiency Metadata Heavy Usually Better
Key Takeaway:
Modern software performance is often determined less by mathematical elegance and more by how efficiently a data structure interacts with CPU caches, memory locality, and hardware architecture. In many real-world workloads, cache-friendly HashMaps outperform theoretically cleaner Tree-based structures because contiguous memory access is dramatically faster than pointer chasing across RAM.

Sunday, June 7, 2026

Nodejs : Useful miniscripts


Since Node.js is a scripting language, we can use the "-e" switch to evaluate the text which immediately follows. This allows us to run small scripts ( may be one-liners) without saving them to a .js file. These Node.js one-liners are extremely useful for quick automation, debugging, testing, and system administration tasks directly from the terminal without creating separate JavaScript files. The best one I think is the first one, which allows us to directly test a web server, which on accessing port 3000 will print "Hello" in the browser. 

Use Case Terminal Command What It Does
Instant HTTP Server
node -e "require('http').createServer((req,res)=>res.end('Hello')).listen(3000)"
Spins up a minimal web server on port 3000 that responds to every request with "Hello".
JSON Pretty-Printer
node -e "console.log(JSON.stringify(JSON.parse(process.argv[1]), null, 2))" '{"a":1,"b":2}'
Takes a raw, minified JSON string from the arguments and formats it with clean, readable spacing.
File Downloader
node -e "require('https').get('https://example.com', r => r.pipe(process.stdout))"
Acts as a lightweight curl alternative to stream data from a URL straight to your terminal.
System Resource Check
node -e "const os = require('os'); console.log({ free_GB: (os.freemem()/1024**3).toFixed(2), total_GB: (os.totalmem()/1024**3).toFixed(2), cpus: os.cpus().length })"
Queries the host machine's total/free RAM (converted to GB) and displays the CPU core count.
Secure Token Generator
node -e "console.log(require('crypto').randomBytes(20).toString('hex'))"
Uses Node's crypto module to generate a random, secure 40-character hex string for passwords or keys.
JSON Directory Lister
node -e "console.log(JSON.stringify(require('fs').readdirSync('.')))"
Scans the current folder and outputs the list of files formatted cleanly as a valid JSON array.
Quick Tip:
All of these commands use Node.js's -e flag, which allows JavaScript code to be executed directly from the terminal without creating a separate .js file.

minkube with kindnet does not support Network Policies. What I loose due to it and what is the solution? (Minikube, Kindnet, and NetworkPolicy Limitations)

By default, Minikube uses Kindnet as its networking plugin. Unfortunately, Kindnet does not support Kubernetes NetworkPolicies. As a result, any NetworkPolicy YAML files you apply are accepted by the Kubernetes API server, but no actual network filtering or firewall rules are enforced.

This means your cluster behaves as if no NetworkPolicies exist at all.

What Cannot Be Tested with Kindnet?

Because Kindnet ignores NetworkPolicies, several important security and networking scenarios cannot be validated.


1. Pod Isolation (Default Deny)

What You Can't Test:

  • Zero Trust networking models.
  • Default-deny ingress policies.
  • Default-deny egress policies.
  • Explicit allow-list based communication.

Behavior in Kindnet:

Every pod can freely communicate with every other pod in every namespace, regardless of any NetworkPolicy objects you create.


2. Namespace Isolation

What You Can't Test:

  • Blocking communication between namespaces.
  • Separating Development, QA, and Production environments.
  • Multi-tenant namespace security boundaries.

Behavior in Kindnet:

Cross-namespace communication remains completely unrestricted.


3. Microservice Segmentation (Application Firewalls)

What You Can't Test:

Policies such as:

Only Pods with the label:

role=frontend

may connect to:

database pods on port 5432

Behavior in Kindnet:

Any pod in the cluster can attempt to connect directly to your database service, making it impossible to validate application-layer network segmentation.


4. Ingress and Egress Traffic Control

What You Can't Test:

Ingress Restrictions

  • Allowing traffic only from a specific API Gateway.
  • Restricting access to approved frontend services.
  • Blocking requests from unauthorized workloads.

Egress Restrictions

  • Blocking outbound internet access.
  • Allowing communication only to approved services.
  • Restricting external API calls.
  • Enforcing outbound compliance policies.

Behavior in Kindnet:

Pods can freely communicate with:

  • Any internal cluster service.
  • Any namespace.
  • Any external IP address.
  • Any public internet endpoint.

5. CIDR-Based IP Allow Lists and Block Lists

What You Can't Test:

  • Allow traffic only from a trusted corporate subnet.
  • Block traffic from untrusted IP ranges.
  • Restrict communication using CIDR rules.
  • External network whitelisting and blacklisting.

Behavior in Kindnet:

CIDR-based filtering policies are ignored entirely.

Quick Comparison

Capability Kindnet Calico
NetworkPolicy Enforcement ❌ No ✅ Yes
Pod Isolation ❌ No ✅ Yes
Namespace Isolation ❌ No ✅ Yes
Ingress/Egress Policies ❌ No ✅ Yes
CIDR Filtering ❌ No ✅ Yes

Switching Minikube to Calico

If you need to test NetworkPolicies properly, destroy the current Kindnet-based cluster and recreate it using Calico.

minikube delete --all

minikube start \
  --driver=docker \
  --network-plugin=cni \
  --cni=calico \
  --nodes=2
Recommendation:
If your goal is to locally test Kubernetes security, NetworkPolicies, Zero Trust networking, namespace isolation, service segmentation, or Istio authorization policies, always use a CNI plugin such as Calico or Cilium rather than Kindnet.

day-to-day commands in minikube and KinD

 Minikube

docker context use default

docker context ls

minikube start 
minikube start --nodes 3
minikube start --driver=<driver name>   e.g. "docker" , "virtualbox" 

minikube config set driver <driver_name>

minikube profile list

minikube status

minikube delete --all --purge

minikube node add
kubectl get nodes

minikube node delete minikube-m02


kubectl get pods    <= get user created pods
kubectl get pods -n kube-system   <= get system created pods

//GET network pluggin
kubectl get pods -n kube-system | grep -E "net|cni|flannel|calico|cilium|kube-router|kindnet"
kubectl get nodes -o jsonpath='{.items[*].status.images[*].name}' | tr ' ' '\n' | grep -E "cni|kindnet|calico|flannel|cilium" | sort -u

minikube ssh "ls /etc/cni/net.d/"
  • If it returns 10-kindnet.conflist, your network plugin is Kindnet. (kindnet is default for minikube)
  • If it returns 10-calico.conflist or k8s.d/, it will list the respective active plugin.

  • kubectl get configmaps
    kubectl get secrets

    kubectl describe configmap <configmap-name>


    kubectl describe node <node-name>
    kubectl describe node minikube-m02
    kubectl describe pods
    kubectl describe nodes


    To know what details k8s gives on executing a command, kubectl explain <resource> e.g. kubectl explain pods

    kubectl api-resources


    =========================================================
    KinD
    kind --version

    kind get clusters
    kind create cluster 

    by default kind creates a cluster named "kind", which appears as "kind-kind" on list of clusters. 
    by default kind creates a cluster with  one control plane and two nodes. 

    to create  named cluser : 
    Creation should be done in "wsl -d Ubuntu" environment. this can be invoked through powershell.
    kind create cluster --name mycluster
    kind delete cluster --name mycluster

    to alter the number of nodes created, create a yaml file and use it.

    ==================
    my-kind-config.yaml
    ==================
    kind: Cluster
    apiVersion: kind.x-k8s.io/v1aplha4
    nodes:
    - role: control-plane
    - role: worker
    - role: worker
    ==================
    NOTE: apiVersion is required, other wise you will get "unknown apiVersion" error. 

    kind create cluster --name mycluster --config my-kind-config.yaml


    kubectl get nodes
    NAME                      STATUS     ROLES           AGE   VERSION
    mycluster-control-plane   Ready   control-plane   22s   v1.33.1
    mycluster-worker          Ready   <none>          10s   v1.33.1
    mycluster-worker2         Ready   <none>          10s   v1.33.1

    NOTE: even if you have both minikube and kind running, kind nodes will be seen in wsl only and minikube nodes from  PS/normal command prompt only. 



    kubectl rollout restart daemonset prometheus-prometheus-node-exporter -n monitoring
    daemonset.apps/prometheus-prometheus-node-exporter restarted

    kubectl port-forward prometheus-grafana-649459765f-ncbxv  3000 -n monitoring
    kubectl port-forward <pod-name> <host-computer-port> -n <namespace>


    kubectl --namespace monitoring get secrets prometheus-grafana -o jsonpath="{.data.admin-password}" | base64 -d ; echo



    helm list --all-namespaces
    NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                           APP VERSION
    node-exporter   monitoring      1               2026-06-08 09:38:00.795361989 +0000 UTC deployed        prometheus-node-exporter-4.55.0 1.11.1
    prometheus      monitoring      1               2026-06-08 09:23:33.520121361 +0000 UTC deployed        kube-prometheus-stack-86.2.0    v0.91.0

    Ansible Cheat Sheet

    Ansible is an agentless automation platform used for: Server configuration Application deployment Infrastructure provisioning Patc...