// IT Infrastructure Engineering Blog

Real-world guides for
engineers who run
production systems

Deep tutorials and sharp quick-tips on Linux, Cloud, Kubernetes, Docker, and Networking — written by someone who actually does this for a living.

4+
Flagship Articles
100%
Production-Tested
3
Affiliate Partners
// Featured Post
// Recommended — Affiliate Partners

Hosting, SSL & Domain Registration

Tools I recommend to every engineer deploying projects. Clicking through supports this blog at zero extra cost to you.

Web Hosting
Shared hosting with Namecheap!
🔒 Save 40–70% on SSL Certificates

DV, OV, EV & Wildcard certs. Secure every domain, API endpoint, and service you run.

Get SSL Certificate →
* Affiliate links — we may earn a small commission at no extra cost to you.
Linux & Shell
🐧
How to Harden a Linux Server (Ubuntu 22.04): Complete Checklist
SSH lockdown, UFW, fail2ban, sysctl hardening, auditd, and a full automated hardening script.
Deep Dive20 min
⚙️
Writing Bulletproof Shell Scripts: Error Handling Patterns
set -euo pipefail, traps, signal handling, and logging patterns that make automation scripts production-safe.
Deep Dive12 min
🔍
Linux Performance Troubleshooting: CPU, RAM, Disk, Network
A systematic approach to diagnosing slow servers using top, vmstat, iostat, and ss.
Deep Dive18 min
SSL Certificates
🔒 Save 40–70% on SSL Certificates Trusted certs for every domain and service.
Shop SSL →
Cloud — AWS / GCP / Azure
☁️
Cut Your AWS Bill by 40%: Spot Instances, Savings Plans & Rightsizing
A systematic approach to AWS cost optimization across EC2, S3, RDS, and data transfer — with real CLI commands.
Deep Dive22 min
📊
GCP Cloud Monitoring: Set Up Alerting Policies in Under an Hour
Uptime checks, VM CPU alerts, and Pub/Sub notification channels — configured via console with screenshots.
Quick Tips7 min
🔐
AWS IAM: The Least Privilege Model with Real Policy Examples
Stop using AdministratorAccess. Build scoped IAM policies, roles, and permission boundaries.
Deep Dive16 min
Kubernetes & Docker
☸️
Kubernetes Cluster Hardening: 12 Security Controls Every Engineer Must Implement
RBAC, network policies, pod security, secrets encryption, and audit logging with real YAML you can copy directly.
Deep Dive14 min
🐳
Docker Networking Deep Dive: Bridge, Host, Overlay & Macvlan
Every Docker network driver explained with architecture diagrams, real commands, and production design patterns.
Deep Dive18 min
🔐
RBAC in Kubernetes: Build a Least-Privilege Access Model From Scratch
ServiceAccounts, Roles, ClusterRoles, RoleBindings — explained with diagrams and working YAML manifests.
Deep Dive19 min
// Why theDataShark

Written by an engineer,
for engineers

Every command, script, and technique has been validated on live infrastructure — not just a tutorial server.

🛠️
Production-Ready
Every guide is validated on real production systems before it's published here.
Learn Fast
Dense, structured content. No padding — get what you need and apply it the same day.
🔄
Always Current
Articles are updated when tools change. The cheat sheets and commands stay accurate.
📥
Free & Paid Resources
Most content is free. Premium eBooks and courses go even deeper for serious engineers.
// What Readers Say

Real Feedback

★★★★★

"The Linux hardening guide alone saved me hours. I went from a bare VPS to a properly secured server in one afternoon."

RK
Rahul K.
Systems Engineer, Bengaluru
★★★★★

"The AWS cost guide helped us cut our monthly bill by ₹40,000. The rightsizing section alone paid for itself immediately."

AP
Anjali P.
Cloud Infra Analyst, Pune
★★★★★

"The Docker networking post is the clearest explanation of overlay vs macvlan I've ever read. Bookmarked permanently."

SM
Suresh M.
DevOps Engineer, Hyderabad
// Free Resource

Get the Free Linux Quick-Start Guide

50 essential commands for IT infrastructure engineers. No spam — just useful content, occasionally.

✓ Check your inbox — the guide is on its way!

No spam. Unsubscribe anytime. Used by 500+ engineers.

// Digital Products

eBooks & Courses

Everything written from real production experience — not copy-pasted from docs. Buy once, keep forever.

🐧
eBook · PDF
Linux Mastery for IT Infrastructure Engineers
From shell basics to production automation. Filesystem, process management, networking, scripting, permissions — with a 50-command cheat sheet.
₹499 / one-time
NEW
☁️
eBook · PDF
Cloud Monitoring & Alerting from Scratch
Prometheus, Grafana, CloudWatch alerts, PagerDuty integration, and runbook design for AWS and GCP environments.
₹699 / one-time
PDF
Video Course
Shell Scripting & Automation Bootcamp
Build real automation scripts from scratch — disk alerts, log rotation, health checks, deployment scripts, all production-tested.
₹999 / one-time
COURSE
🌐
Bundle · Best Value
Complete IT Infra Bundle
All three guides + course + future updates. Linux eBook + Cloud Monitoring + Shell Scripting + bonus cheat sheets included.
₹1,799 / bundle
SAVE 17%
// Recommended — Hosting & Security

Host Your Projects & Secure Them

Everything you need to go from a local project to a live, secured deployment.

Web Hosting
Namecheap
🔒 Save 40–70% on SSL Certs

DV, OV, EV & Wildcard certs for every domain and subdomain you own.

Get SSL Certificate →
* Affiliate links — we earn a small commission at no extra cost to you.
Home / Linux Server Hardening
Linux Security January 6, 2025 · 20 min read

How to Harden a Linux Server (Ubuntu 22.04): The Complete Security Checklist

A production-tested, step-by-step guide to locking down a fresh Ubuntu 22.04 server. SSH lockdown, UFW firewall rules, fail2ban brute-force protection, automatic security updates, sysctl kernel hardening, audit logging, and a fully automated script you can run in under 10 minutes.

Why Server Hardening Cannot Be Optional

In 2024, automated bots scan the entire IPv4 address space continuously. A freshly provisioned cloud VPS with SSH exposed on port 22 will see login attempts within minutes of boot. Within 24 hours, thousands of brute-force attempts are normal.

Default Ubuntu installations are not insecure by design — but they are permissive by default. Every unnecessary open port, every weak configuration, every unused service is an attack surface. This guide covers every critical hardening step with real commands and explanations for each decision.

⚠ Work on a staging server first. SSH hardening steps, if done incorrectly, can lock you out permanently. Always keep a console session open while making SSH changes.

Step 1 — Initial System Update & User Setup

bash
# Update all packages and install security essentials
sudo apt update && sudo apt upgrade -y
sudo apt install -y ufw fail2ban unattended-upgrades auditd \
  audispd-plugins libpam-pwquality curl vim

# Create dedicated non-root admin user
adduser sysadmin
usermod -aG sudo sysadmin

# Verify sudo access
su - sysadmin
sudo whoami   # should return: root

Step 2 — SSH Hardening

SSH is the primary attack vector. Set up key authentication first, then lock down /etc/ssh/sshd_config.

bash — local machine
# Generate an Ed25519 key pair on your LOCAL machine
ssh-keygen -t ed25519 -C "admin@thedatashark.com" -f ~/.ssh/shark_ed25519

# Copy public key to server
ssh-copy-id -i ~/.ssh/shark_ed25519.pub sysadmin@YOUR_SERVER_IP

# Test BEFORE changing any SSH settings
ssh -i ~/.ssh/shark_ed25519 sysadmin@YOUR_SERVER_IP
sshd_config
# /etc/ssh/sshd_config.d/99-hardening.conf
Port                    2222
PermitRootLogin         no
PasswordAuthentication  no
PubkeyAuthentication    yes
AuthenticationMethods   publickey
AllowUsers              sysadmin
MaxAuthTries            3
ClientAliveInterval     300
ClientAliveCountMax     2
X11Forwarding           no
AllowTcpForwarding      no
LogLevel                VERBOSE
Ciphers   chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs      hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
bash
# Validate config before restarting
sudo sshd -t

# Restart (keep current session open!)
sudo systemctl restart sshd

# Test new connection from a SECOND terminal before closing current one
ssh -i ~/.ssh/shark_ed25519 -p 2222 sysadmin@YOUR_SERVER_IP
⚠ Critical: Open a second terminal and test the new connection before closing your existing session. If it fails, you still have the old session to fix it.

Step 3 — Firewall Configuration with UFW

Default deny everything, then explicitly allow only what you need.

bash
# Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow SSH on the new port FIRST
sudo ufw allow 2222/tcp comment 'SSH hardened port'
sudo ufw allow 80/tcp   comment 'HTTP'
sudo ufw allow 443/tcp  comment 'HTTPS'

# Enable rate limiting on SSH
sudo ufw limit 2222/tcp

# Enable — do not run this before allowing SSH!
sudo ufw enable
sudo ufw status verbose

Step 4 — Brute-Force Protection with fail2ban

ini — /etc/fail2ban/jail.d/ssh-hardened.conf
[sshd]
enabled  = true
port     = 2222
maxretry = 3
bantime  = 86400   # 24-hour ban
findtime = 600
backend  = systemd
bash
sudo systemctl restart fail2ban && sudo systemctl enable fail2ban
sudo fail2ban-client status sshd

# View current bans
sudo fail2ban-client get sshd banip

# Unban yourself if locked out
sudo fail2ban-client set sshd unbanip YOUR_IP

Step 5 — Automatic Security Updates

conf — /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

Step 6 — Kernel Parameter Hardening (sysctl)

conf — /etc/sysctl.d/99-hardening.conf
# Network hardening
net.ipv4.ip_forward=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.tcp_syncookies=1
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.conf.all.rp_filter=1

# Kernel hardening
kernel.dmesg_restrict=1
kernel.kptr_restrict=2
kernel.yama.ptrace_scope=1
kernel.sysrq=0

# Filesystem hardening
fs.protected_hardlinks=1
fs.protected_symlinks=1
fs.suid_dumpable=0
bash
sudo sysctl -p /etc/sysctl.d/99-hardening.conf

Step 7 — Audit Logging with auditd

conf — /etc/audit/rules.d/hardening.rules
# Monitor authentication files
-w /etc/passwd  -p wa -k identity
-w /etc/shadow  -p wa -k identity
-w /etc/sudoers -p wa -k sudoers

# Monitor SSH config changes
-w /etc/ssh/sshd_config -p wa -k ssh_config

# Log all sudo commands
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=-1 -k root_commands

# Make audit rules immutable (requires reboot to change)
-e 2
bash
sudo augenrules --load
sudo auditctl -s
sudo ausearch -k identity --start today

Step 8 — Disable Unnecessary Services

bash
# List all enabled services
sudo systemctl list-unit-files --state=enabled --type=service

# Disable services not needed on a server
sudo systemctl disable --now avahi-daemon   # mDNS
sudo systemctl disable --now cups           # Printing
sudo systemctl disable --now bluetooth      # Bluetooth
sudo systemctl disable --now whoopsie       # Crash reporting

# Check what's listening on network ports
sudo ss -tulnp

Bonus — Full Automated Hardening Script

✓ How to use: Save as harden.sh, review and edit the VARIABLES section at the top, then run sudo bash harden.sh. Every action is logged to /var/log/harden-DATE.log.
bash — harden.sh
#!/bin/bash
# harden.sh — Ubuntu 22.04 Server Hardening Script
# theDataShark.com — Review VARIABLES before running!
set -euo pipefail

ADMIN_USER="sysadmin"
SSH_PORT="2222"
LOG_FILE="/var/log/harden-$(date +%Y%m%d-%H%M%S).log"
exec > >(tee -a "$LOG_FILE") 2>&1

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
log "=== theDataShark Hardening Script ==="

## 1. Update
apt update -q && apt upgrade -y -q
apt install -y -q ufw fail2ban unattended-upgrades auditd

## 2. UFW
ufw --force reset
ufw default deny incoming; ufw default allow outgoing
ufw allow "${SSH_PORT}/tcp" comment "SSH"
ufw allow 80/tcp; ufw allow 443/tcp
ufw limit "${SSH_PORT}/tcp"
ufw --force enable
log "UFW enabled."

## 3. SSH
cp /etc/ssh/sshd_config "/etc/ssh/sshd_config.bak.$(date +%Y%m%d)"
cat > /etc/ssh/sshd_config.d/99-hardening.conf <## 4. fail2ban
cat > /etc/fail2ban/jail.d/ssh-hardened.conf <## 5. sysctl
cat > /etc/sysctl.d/99-hardening.conf <## 6. Auto updates
cat > /etc/apt/apt.conf.d/20auto-upgrades <

Quick Reference Checklist

// Ubuntu 22.04 Server Hardening Checklist
System fully updated — apt update && apt upgrade
Non-root admin user created with sudo access
SSH key pair generated and copied to server
SSH port changed from 22 to custom port
Root SSH login disabled — PermitRootLogin no
Password authentication disabled
UFW enabled with default deny incoming
UFW rate limiting on SSH port enabled
fail2ban installed, configured, and active
Unattended security upgrades enabled
sysctl hardening parameters applied
auditd installed and audit rules loaded
Unnecessary services disabled

Wrapping Up

Server hardening is not a one-time task. Run sudo lynis audit system periodically to get a scored security report. Aim for 70+ on a standard web server. The steps in this guide stop the vast majority of automated attacks before they even get started.

→ Want this as a downloadable PDF checklist? The Complete IT Infra Bundle includes this hardening guide, the Kubernetes security checklist, and a Bash scripting workbook in clean PDF format.
SSL Certificates
🔒 Save 40–70% on SSL CertificatesSecure your hardened server with a trusted cert.
Shop SSL →
Home / AWS Cost Optimization
AWS Cost Optimization January 14, 2025 · 22 min read

Cut Your AWS Bill by 40%: Spot Instances, Savings Plans, Rightsizing & More

AWS bills spiral quickly if you're not actively managing spend. This guide walks through a systematic approach to eliminating waste across EC2, S3, RDS, and data transfer — with real CLI commands, cost analysis techniques, and proven strategies that don't compromise reliability.

// Typical Savings by Strategy
What these strategies save — real-world estimates
60–90%
Spot Instances
30–72%
Savings Plans
20–40%
EC2 Rightsizing
50–70%
S3 Tiering
65–70%
Stop Non-Prod

The Right Mindset for AWS Cost Optimization

AWS cost optimization is not about being cheap. It's about paying for what you actually use, at the right commitment level, with the right pricing model. The difference between a $5,000/month bill and a $3,000/month bill for the same infrastructure is almost entirely down to matching your purchasing model to your actual usage patterns.

→ Before you start: You'll need AWS CLI configured (aws configure) and IAM permissions for Cost Explorer, EC2, S3, and RDS. Most commands use the AWS CLI — install and configure it first.

Step 1 — Get Visibility: Cost Explorer & Budget Alerts

bash — AWS CLI
# Cost breakdown by service for last month
aws ce get-cost-and-usage \
  --time-period Start=$(date -d "last month" +%Y-%m-01),End=$(date +%Y-%m-01) \
  --granularity MONTHLY \
  --metrics "BlendedCost" \
  --group-by Type=DIMENSION,Key=SERVICE \
  --query 'ResultsByTime[].Groups[].{Service:Keys[0],Cost:Metrics.BlendedCost.Amount}' \
  --output table

# Create a $500/month budget with 80% alert
aws budgets create-budget \
  --account-id $(aws sts get-caller-identity --query Account --output text) \
  --budget '{"BudgetName":"MonthlySpend","BudgetLimit":{"Amount":"500","Unit":"USD"},"TimeUnit":"MONTHLY","BudgetType":"COST"}' \
  --notifications-with-subscribers '[{"Notification":{"NotificationType":"ACTUAL","ComparisonOperator":"GREATER_THAN","Threshold":80},"Subscribers":[{"SubscriptionType":"EMAIL","Address":"you@thedatashark.com"}]}]'
✓ Pro Tip: Tag everything in AWS with at minimum Environment (prod/staging/dev) and Project. Cost allocation tags let you break down spend by project in Cost Explorer — without them, you're flying blind.

Step 2 — EC2 Rightsizing with Compute Optimizer

bash
# Opt in to Compute Optimizer (free)
aws compute-optimizer update-enrollment-status --status Active

# Get rightsizing recommendations
aws compute-optimizer get-ec2-instance-recommendations \
  --query 'instanceRecommendations[].{
    Instance:instanceArn,
    Current:currentInstanceType,
    Finding:finding,
    Recommended:recommendationOptions[0].instanceType,
    MonthlySavings:recommendationOptions[0].estimatedMonthlySavings.value
  }' \
  --output table

# Check average CPU utilisation over 30 days
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-0123456789abcdef0 \
  --start-time $(date -d "30 days ago" --utc +%FT%TZ) \
  --end-time $(date --utc +%FT%TZ) \
  --period 86400 --statistics Average Maximum \
  --query 'sort_by(Datapoints,&Timestamp)[].{Date:Timestamp,Avg:Average,Max:Maximum}' \
  --output table
Average CPU %RecommendationTypical Saving
< 5%Downsize 2 sizes or switch to t-series burstable40–60%
5–20%Downsize 1 instance size20–40%
20–60%Current size appropriate — focus on pricing model0% from resize
> 80%Consider upsize or horizontal scaling

Step 3 — Spot Instances: 60–90% Cheaper

Spot Instances use spare EC2 capacity at up to 90% discount. AWS can reclaim them with 2 minutes notice. Ideal for: batch processing, CI/CD build agents, stateless web tier, dev/test environments.

bash
# Check current Spot vs On-Demand pricing
aws ec2 describe-spot-price-history \
  --instance-types m5.xlarge \
  --product-descriptions "Linux/UNIX" \
  --start-time $(date --utc +%FT%TZ) \
  --query 'SpotPriceHistory[].{AZ:AvailabilityZone,Price:SpotPrice}' \
  --output table

# Launch Spot with interruption handling
aws ec2 run-instances \
  --image-id ami-0abcdef1234567890 \
  --instance-type m5.xlarge \
  --instance-market-options '{"MarketType":"spot","SpotOptions":{"SpotInstanceType":"one-time","InstanceInterruptionBehavior":"terminate"}}' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=spot-worker}]'
✓ Best practice: Use EC2 Auto Scaling with mixed instances policy rather than individual Spot requests. Configure at least 3–5 instance types across 2–3 AZs to maximise availability and minimise interruptions.

Step 4 — Savings Plans & Reserved Instances

Plan TypeFlexibilityMax DiscountBest For
Compute Savings PlanAny EC2/Lambda/Fargate66%Most workloads
EC2 Instance Savings PlanInstance family in 1 region72%Stable EC2
Standard Reserved InstanceExact type/region72%Known stable workloads
Convertible RICan change family54%Moderate flexibility
✓ Purchase strategy: Start with a 1-year Compute Savings Plan at no upfront. Cover only your baseline — keep 20–30% on-demand or Spot for variable load. You can always buy more later.
// Recommended — Domain & Hosting

Deploy Your Cloud Projects with a Real Domain

Every production deployment needs a domain and proper SSL. These are the services we use.

Dynadot
Namecheap
🔒 Save 40–70% on SSL Certs

Secure every endpoint behind your load balancer. DV, Wildcard, OV.

Get SSL →
* Affiliate links — small commission at no extra cost to you.

Step 5 — S3 Cost Optimization: Storage Classes & Lifecycle Policies

json — lifecycle-policy.json
{
  "Rules": [{
    "ID": "auto-tiering",
    "Status": "Enabled",
    "Filter": { "Prefix": "" },
    "Transitions": [
      { "Days": 30,  "StorageClass": "STANDARD_IA" },
      { "Days": 90,  "StorageClass": "INTELLIGENT_TIERING" },
      { "Days": 365, "StorageClass": "GLACIER_IR" }
    ],
    "NoncurrentVersionExpiration": { "NoncurrentDays": 90 },
    "AbortIncompleteMultipartUpload": { "DaysAfterInitiation": 7 }
  }]
}
bash
aws s3api put-bucket-lifecycle-configuration \
  --bucket your-bucket-name \
  --lifecycle-configuration file://lifecycle-policy.json

Step 6 — RDS Cost Cuts

  • Use Aurora Serverless v2 for dev/staging — scales to 0.5 ACUs when idle
  • Stop non-production instances outside working hours using EventBridge + Lambda
  • Purchase RDS Reserved Instances for 24/7 production databases — 30–60% discount
  • Migrate gp2 EBS to gp3 — same performance, 20% cheaper, takes 2 CLI commands
  • Enable storage auto-scaling with a max limit rather than provisioning the maximum upfront

Step 7 — Data Transfer: The Hidden Cost Nobody Talks About

Transferring data into AWS is free. Transferring data out to the internet costs $0.09/GB. Cross-region is $0.02/GB. Key strategies:

  • Use CloudFront — egress pricing is cheaper, and it caches content globally
  • Keep traffic in the same AZ — cross-AZ costs $0.01/GB each way
  • Use VPC Endpoints for S3 and DynamoDB — eliminates NAT Gateway processing costs

Step 8 — Automate Stop-Start Schedules

bash — EventBridge stop/start rules
# Stop dev instances at 8pm IST (14:30 UTC) Mon-Fri
aws events put-rule \
  --name "StopDevInstances" \
  --schedule-expression "cron(30 14 ? * MON-FRI *)" \
  --state ENABLED

# Start dev instances at 9am IST (03:30 UTC) Mon-Fri
aws events put-rule \
  --name "StartDevInstances" \
  --schedule-expression "cron(30 3 ? * MON-FRI *)" \
  --state ENABLED

# Quick manual stop of all dev instances
aws ec2 describe-instances \
  --filters "Name=tag:Environment,Values=dev" "Name=instance-state-name,Values=running" \
  --query 'Reservations[].Instances[].InstanceId' --output text | \
  xargs aws ec2 stop-instances --instance-ids

AWS Cost Optimization Checklist

ActionServiceTypical ImpactEffort
Enable Cost Explorer + budget alertsAllVisibilityLow
Tag all resourcesAllVisibilityLow
Enable Compute OptimizerEC2Sizing dataLow
Downsize instances <10% CPU avgEC220–60%Medium
Move batch/CI to SpotEC260–90%Medium
Buy 1-year Compute Savings PlanEC2/Lambda30–66%Low
Add S3 lifecycle policiesS320–70%Low
Add VPC Endpoints for S3/DynamoDBData transfer10–30%Low
Stop non-prod nights/weekendsEC2/RDS65–70%Medium
Migrate gp2 EBS → gp3EBS20%Low
Delete unattached EBS + old snapshotsEBSVariableLow

Wrapping Up

A methodical sweep through these strategies routinely delivers 30–50% savings with no degradation in performance or reliability. Start with Cost Explorer and Compute Optimizer — both free. Let the data tell you where money is going before committing to purchasing changes.

→ Need more? The Cloud Monitoring & Alerting eBook includes a dedicated chapter on AWS cost alerting, Savings Plans analysis, and automated cost anomaly detection.
SSL Certificates
🔒 Save 40–70% on SSL CertificatesTrusted DV, OV, EV & Wildcard certs.
Shop SSL →
Home / Docker Networking Deep Dive
Docker Networking January 22, 2025 · 18 min read

Docker Networking Deep Dive: Bridge, Host, Overlay, Macvlan & Custom Networks Explained

Most engineers use Docker networks without understanding how they work — and that leads to debugging sessions that take hours. This guide covers every Docker network driver, explains container DNS resolution, and walks through production network design patterns with working examples.

How Docker Networking Actually Works

Docker networking is built on three Linux kernel primitives: network namespaces, virtual Ethernet pairs (veth), and Linux bridges. When you start a container, Docker creates a new network namespace for it. This gives the container its own isolated network stack — its own routing table, interfaces, and iptables rules.

// Docker Default Bridge Architecture
  HOST
  ┌────────────────────────────────────────────────────┐
  │  ┌─────────────┐    ┌─────────────┐               │
  │  │ Container A │    │ Container B │               │
  │  │ eth0        │    │ eth0        │               │
  │  │ 172.17.0.2  │    │ 172.17.0.3  │               │
  │  └──────┬──────┘    └──────┬──────┘               │
  │         │ veth pair        │ veth pair             │
  │  ┌──────┴──────────────────┴──────┐               │
  │  │       docker0 bridge           │               │
  │  │       172.17.0.1/16            │               │
  │  └───────────────┬────────────────┘               │
  │                  │ iptables NAT / MASQUERADE       │
  │  ┌───────────────┴────────────────┐               │
  │  │    eth0 (host NIC)  192.168.x  │               │
  │  └────────────────────────────────┘               │
  └────────────────────────────────────────────────────┘
bash
# See all Docker networks
docker network ls

# Inspect bridge network details
docker network inspect bridge

# See Docker iptables NAT rules
sudo iptables -t nat -L DOCKER -n --line-numbers

Bridge Network — The Default

The bridge driver is Docker's default. Containers on the default bridge can communicate by IP but not by container name — this is the most commonly misunderstood limitation.

bash
docker run -d --name web nginx:alpine
docker run -d --name db  postgres:15-alpine -e POSTGRES_PASSWORD=secret

# This FAILS on the default bridge — no DNS by name
docker exec web ping -c2 db
# ping: bad address 'db'

# IP works — but hardcoding IPs in production is wrong
docker inspect db --format '{{.NetworkSettings.IPAddress}}'
⚠ Don't use the default bridge in production. No DNS by name, no network isolation between unrelated containers. Always use custom named networks.

Custom Bridge Networks — The Right Way

Custom bridge networks provide automatic DNS resolution by container name, network-level isolation, and dynamic connect/disconnect.

bash
# Create a custom bridge network
docker network create \
  --driver bridge \
  --subnet 192.168.10.0/24 \
  --gateway 192.168.10.1 \
  app-network

# Start containers on the custom network
docker run -d --name web --network app-network nginx:alpine
docker run -d --name db  --network app-network postgres:15-alpine \
  -e POSTGRES_PASSWORD=secret

# DNS by name works automatically
docker exec web ping -c2 db
# PING db (192.168.10.3) — success!

# Connect an existing container to a second network
docker network connect monitoring-net web
// Recommended — Deploy Your Docker Apps

Get a Domain + SSL for Your Dockerized Projects

Once your containers are running, you need a domain and HTTPS in front of your Nginx reverse proxy.

Dynadot
Namecheap
🔒 Save 40–70% on SSL Certs

Add TLS termination to your Nginx proxy. Wildcard certs cover all subdomains.

Get SSL →
* Affiliate links — small commission at no extra cost to you.

Host Network — Maximum Performance

Removes all network isolation. The container shares the host's network stack — no veth, no bridge, no NAT overhead. Use for: Prometheus node_exporter, Datadog agent, high-throughput brokers.

bash
# No -p port mapping needed — binds directly to host port 80
docker run -d --network host --name nginx-host nginx:alpine
curl http://localhost:80   # connects directly — zero NAT overhead
AspectBridgeHost
Network isolation✓ Full isolation✗ No isolation
Port mapping requiredYes (-p 80:80)No — direct
Performance overheadSmall (NAT)None
Use caseMost appsMonitoring agents, high-throughput

Overlay Network — Multi-Host Communication

Allows containers on different Docker hosts to communicate as if on the same network. Uses VXLAN encapsulation. Requires Docker Swarm mode.

// Overlay Network Architecture
  Host 1 (192.168.1.10)      Host 2 (192.168.1.11)
  ┌─────────────────────┐    ┌─────────────────────┐
  │  ┌───────────────┐  │    │  ┌───────────────┐  │
  │  │  Container A  │  │    │  │  Container B  │  │
  │  │  10.0.0.3     │  │VXLAN│  │  10.0.0.4     │  │
  │  └───────┬───────┘  │◄───►  └───────┬───────┘  │
  │  [overlay bridge]   │UDP  │  [overlay bridge]   │
  └─────────────────────┘4789 └─────────────────────┘
bash — Swarm required
docker swarm init --advertise-addr 192.168.1.10

docker network create \
  --driver overlay \
  --subnet 10.0.0.0/24 \
  --attachable \
  app-overlay

docker service create --name web --network app-overlay --replicas 3 -p 80:80 nginx:alpine

Macvlan & IPvlan — Direct L2 Network Access

Macvlan assigns a real MAC address to each container, making it visible on your physical network. Routers see containers as standalone devices. Ideal for network appliances, legacy apps, Pi-hole DNS.

bash
# Enable promiscuous mode on host NIC
sudo ip link set eth0 promisc on

# Create macvlan network
docker network create \
  --driver macvlan \
  --subnet 192.168.1.0/24 \
  --gateway 192.168.1.1 \
  --ip-range 192.168.1.192/27 \
  --opt parent=eth0 \
  macvlan-net

# Container gets a real IP on your LAN
docker run -d --name pihole --network macvlan-net \
  --ip 192.168.1.200 pihole/pihole:latest

# Reachable from any device on your network
ping 192.168.1.200

None Network — Full Isolation

bash
# Container gets only loopback — no network access
docker run --network none --rm alpine ip addr show
# Only lo (127.0.0.1) — completely isolated

Container DNS Resolution Explained

DNS in custom networks is handled by Docker's embedded DNS server at 127.0.0.11. Every container on a custom network uses this as its resolver. It resolves container names, service names, and network aliases — falling back to the host's DNS for external queries.

bash
# Check container's DNS config
docker exec web cat /etc/resolv.conf
# nameserver 127.0.0.11

# Add network aliases — multiple names for one container
docker run -d --name primary-db \
  --network app-network \
  --network-alias database \
  --network-alias db \
  postgres:15-alpine

# DNS round-robin — run 3 containers with same alias
for i in 1 2 3; do
  docker run -d --name "api-$i" --network app-network --network-alias api nginx:alpine
done
docker run --rm --network app-network alpine nslookup api
# Returns all 3 IPs — basic load balancing via DNS

Docker Compose Networking Patterns

yaml — Multi-tier isolation pattern
services:
  # Public-facing proxy — on public-net only
  nginx:
    image: nginx:alpine
    ports: ["80:80", "443:443"]
    networks: [public-net]

  # App bridges both networks
  app:
    image: myapp:latest
    networks: [public-net, private-net]
    environment:
      - DB_HOST=postgres

  # Database — private-net only, NOT reachable from nginx
  postgres:
    image: postgres:15-alpine
    networks: [private-net]

  redis:
    image: redis:7-alpine
    networks: [private-net]

networks:
  public-net:
    driver: bridge
  private-net:
    driver: bridge
    internal: true  # No outbound internet
✓ The internal: true flag prevents outbound internet access from containers on that network. Databases should almost never have direct internet access.

Network Troubleshooting Reference

bash — Troubleshooting Toolkit
## 1. Which networks is the container on?
docker inspect CONTAINER --format '{{json .NetworkSettings.Networks}}' | python3 -m json.tool

## 2. Check IP, gateway, DNS
docker exec CONTAINER ip addr show
docker exec CONTAINER ip route show
docker exec CONTAINER cat /etc/resolv.conf

## 3. Test DNS resolution
docker exec CONTAINER nslookup OTHER_CONTAINER
docker exec CONTAINER nslookup google.com

## 4. Test TCP connectivity
docker exec CONTAINER nc -zv OTHER_CONTAINER 5432

## 5. Run a debug container (netshoot has everything)
docker run --rm -it \
  --network container:PROBLEM_CONTAINER \
  nicolaka/netshoot bash
# netshoot includes: tcpdump, nmap, curl, dig, ss, iperf3 and more

## 6. Capture traffic between containers
docker run --rm -it \
  --network container:CONTAINER_NAME \
  --cap-add NET_ADMIN \
  nicolaka/netshoot \
  tcpdump -i eth0 -nn
SymptomLikely CauseCheck
Can't resolve namesOn default bridge, not customcat /etc/resolv.conf — must show 127.0.0.11
Name resolves, connection refusedService not listening or wrong portss -tulnp inside container
No internet from containeriptables MASQUERADE missing or internal: trueiptables -t nat -L POSTROUTING
Port not reachable from hostPort not published with -pdocker port CONTAINER
Containers on different networks can't talkExpected — networks are isolatedConnect both to a shared network

Production Network Design Patterns

Pattern 1 — Frontend/Backend segmentation: Only the reverse proxy connects to both public and private networks. Databases are completely hidden from the internet. This is the Compose example above — use it as your default.

Pattern 2 — Per-application isolated networks: Each app gets its own network. A compromised container in App A cannot reach App B's database. Create one bridge network per application on multi-tenant servers.

Pattern 3 — Shared monitoring network: Connect Prometheus to all application networks so it can scrape metrics from every container — without those containers having access to each other.

bash — Per-app isolation
docker network create app1-net
docker network create app2-net

# App1 and App2 are completely isolated
docker run -d --name app1-web --network app1-net nginx:alpine
docker run -d --name app2-web --network app2-net nginx:alpine

# Connect Prometheus to both (monitoring access without cross-app access)
docker network connect app1-net prometheus
docker network connect app2-net prometheus

Wrapping Up

Docker networking decision tree: single host + isolation → custom bridge. Single host + performance → host. Multi-host → overlay. Physical network access → macvlan. No network → none. Always use custom bridge networks, always set internal: true for database networks, and keep nicolaka/netshoot handy for debugging.

→ Going deeper? The Kubernetes Cluster Hardening guide covers NetworkPolicies — the production-grade version of Docker network isolation for orchestrated workloads.
SSL Certificates
🔒 Save 40–70% on SSL CertificatesSecure your reverse proxy with trusted SSL.
Shop SSL →
Home/Kubernetes Cluster Hardening
Kubernetes Security December 18, 2024 · 14 min read

Kubernetes Cluster Hardening: 12 Security Controls Every Engineer Must Implement

Your cluster is running — but is it secure? Walk through RBAC, network policies, pod security standards, secrets encryption at rest, and audit logging with real YAML manifests you can apply directly to production.

Most Kubernetes clusters are deployed with security as an afterthought. The defaults are permissive, tokens get mounted everywhere, and network traffic flows freely between pods. In production, this is a disaster waiting to happen.

⚠ Before you start: Apply these changes to a staging cluster first. PodSecurity enforcement and NetworkPolicies can break existing workloads if not rolled out carefully.

1. Enable and Enforce RBAC

bash
# Find all subjects with cluster-admin
kubectl get clusterrolebindings \
  -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.roleRef.name}{"\t"}{range .subjects[*]}{.kind}/{.name}{" "}{end}{"\n"}{end}' \
  | grep cluster-admin
yaml — deploy-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: deploy-manager
rules:
- apiGroups: ["apps"]
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch", "update", "patch"]
✓ Pro tip: Use kubectl auth can-i --list --as=system:serviceaccount:NAMESPACE:SA to audit exactly what a service account can do before deploying.

2. Apply Pod Security Standards

bash
# Enforce restricted policy on production namespace
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=latest \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/audit=restricted
yaml — restricted pod spec
securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  seccompProfile:
    type: RuntimeDefault
  capabilities:
    drop: ["ALL"]

3. Implement Network Policies

By default, all pods can talk to all other pods. Start with a default-deny-all policy, then selectively open required traffic.

yaml — default-deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes: [Ingress, Egress]
---
# Allow frontend → backend traffic only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  podSelector:
    matchLabels: { app: backend }
  policyTypes: [Ingress]
  ingress:
  - from:
    - podSelector:
        matchLabels: { app: frontend }
    ports: [{ protocol: TCP, port: 8080 }]

4. Encrypt Secrets at Rest

yaml — encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources: ["secrets"]
  providers:
  - aescbc:
      keys:
      - name: key1
        secret: <base64-encoded-32-byte-key>
  - identity: {}
bash
# Generate a 32-byte encryption key
head -c 32 /dev/urandom | base64

# Re-encrypt all existing secrets after enabling
kubectl get secrets --all-namespaces -o json | kubectl replace -f -

5. Enable Audit Logging

yaml — audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
  resources: [{ group: "", resources: ["secrets"] }]
- level: RequestResponse
  resources: [{ group: "", resources: ["pods/exec", "pods/portforward"] }]
- level: None
  users: ["system:kube-proxy"]
  verbs: ["watch"]
- level: Metadata

6–12. Remaining Controls

#ControlKey Action
6Restrict Container ImagesUse OPA Gatekeeper / Kyverno to allowlist trusted registries
7Harden the API ServerDisable anonymous auth, set --authorization-mode=RBAC,Node
8Secure etcdTLS client certs, restrict access to API server only
9Set Resource LimitsCPU/memory requests and limits on every container
10Disable Default SA TokenSet automountServiceAccountToken: false on deployments
11Use Admission ControllersEnable OPA/Gatekeeper for policy-as-code enforcement
12Scan Images for CVEsIntegrate Trivy into CI pipeline, block on critical vulns

Wrapping Up

Security hardening is an ongoing practice. Start with RBAC, network policies, and pod security standards — they have the highest impact. Automate scanning in CI and review audit logs weekly.

→ Want the checklist as a PDF? The Complete IT Infra Bundle includes a Kubernetes Security Hardening checklist with all 12 controls, YAML manifests, and a runbook template.
SSL Certificates
🔒 Save 40–70% on SSL CertificatesSecure every Kubernetes ingress endpoint.
Shop SSL →
// About theDataShark

Built by an Engineer,
for Engineers

No agency. No content farm. A working IT infrastructure engineer sharing what actually works in production.

DS

theDataShark

IT Infrastructure Engineer · India

I'm an IT infrastructure engineer with hands-on experience managing Linux servers, cloud environments (AWS & GCP), Kubernetes clusters, and CI/CD pipelines in production. I started theDataShark because I was tired of tutorials written by people who had clearly never deployed anything to a real server.

Every article on this site is tested on live infrastructure before it's published. The commands work. The scripts run. The configs are real.

What You'll Find Here

🐧

Linux & Shell

Server hardening, shell scripting, system performance, and the commands you'll use every day.

☁️

Cloud (AWS/GCP)

Cost optimization, monitoring, IAM, and infrastructure patterns that scale without breaking the bank.

☸️

Kubernetes

Security hardening, resource management, RBAC, and production-grade cluster configurations.

🐳

Docker & Networking

Container networking deep dives, multi-stage builds, Compose patterns, and image optimization.

The Content Philosophy

  • No fluff. If a section doesn't make you a better engineer, it gets cut.
  • Working code only. Every command, script, and config is tested before it appears here.
  • Honest recommendations. Affiliate links are clearly labeled. Only tools actually used are recommended.

Courses & eBooks

For engineers who want to go deeper, I publish premium eBooks and courses — dense, practical, no-filler guides. Browse the courses →

Get in Touch

Topic suggestion, error in a guide, or want to discuss a collaboration? Send a message →

// Disclosure

This site contains affiliate links for Namecheap, The SSL Store, and Dynadot. We earn a small commission if you purchase through these links — at no extra cost to you. Full disclosure →

// Contact

Get in Touch

Article suggestions, error reports, partnerships, or purchase support — all welcome.

✉️

General Enquiries

Article suggestions, feedback, or anything else.

hello@thedatashark.com
🤝

Partnerships & Sponsorships

Interested in sponsoring a post or newsletter edition?

partnerships@thedatashark.com
🐛

Found an Error?

If a command or config is wrong or outdated — I'll fix it and credit you.

corrections@thedatashark.com
📦

Purchase Support

Issues with a download or course access after payment.

support@thedatashark.com

Send a Message

✓ Opening your email client with the message pre-filled. Thank you!

Or email directly: hello@thedatashark.com

// FAQ

Frequently Asked Questions

Everything about the blog, courses, purchases, and affiliate links.

About the Blog

All content is written by a single working IT infrastructure engineer based in India. No guest posts, no outsourced writers. Every article is written, tested, and published by the same person who runs the site.
Yes — every command, script, YAML manifest, and configuration block is validated on live infrastructure before publication. If something breaks or becomes outdated, the article gets updated. Corrections are welcome at corrections@thedatashark.com.
New articles are published 1–2 times per week. Quality is prioritised over volume — a well-tested 20-minute deep dive is more valuable than five shallow posts. Subscribe to the newsletter to get notified of new content.
Absolutely. Topic suggestions and error reports are very welcome. Use the contact page or email corrections@thedatashark.com directly. If your error report leads to a correction, you'll be credited in the article.

Courses & eBooks

After payment is confirmed, you'll receive an instant download link by email. Files are DRM-free PDFs — no special software needed, works on any device. Save them to your phone, tablet, laptop, or cloud storage.
The eBooks are written for working IT professionals with basic terminal exposure. If you know how to SSH into a server and run basic commands, you're ready. You don't need prior scripting experience — guides build concepts progressively.
Yes. All purchases include lifetime updates. When a guide is revised or expanded, existing customers receive the updated version at no extra charge.
7-day no-questions-asked refund if you're not satisfied. Email support@thedatashark.com with your order details and the refund will be processed within 48 hours.
UPI, credit/debit cards, and net banking (via Razorpay) for Indian customers. International credit/debit cards via Gumroad. theDataShark never stores payment information.

Newsletter

New article notifications (1–2 per week), occasional quick-tip emails, and early access to new courses and guides. No promotional spam, no third-party promotions, no selling your email.
Every email contains a one-click unsubscribe link at the bottom. You can also email hello@thedatashark.com and your address will be removed within 24 hours. The newsletter runs on EmailOctopus and is GDPR-compliant.

Affiliates

Currently: Namecheap (web hosting), The SSL Store (SSL certificates), and Dynadot (domain registration). All three are genuinely used and recommended. Affiliate links are always clearly labeled.
No — you pay exactly the same price whether you use an affiliate link or go directly to the vendor. The commission comes from their marketing budget. Using affiliate links is a free way to support this blog.
// Legal

Privacy Policy

How theDataShark collects, uses, and protects your information.

Last updated: January 2025

This Privacy Policy describes how theDataShark ("we", "us"), operating at thedatashark.com, collects and uses personal information when you visit our website or purchase our products.

Information We Collect

Information you provide directly

  • Email address — when you subscribe to the newsletter via EmailOctopus
  • Name and email — when you use the contact form
  • Payment information — processed by Gumroad or Razorpay; we never see or store your card details

Information collected automatically

  • Analytics data — page views, session duration, traffic sources via Google Analytics 4 (aggregated and anonymised)
  • Cookies — Google Analytics uses cookies to distinguish visitors; affiliate tracking links use cookies to track referrals
  • Server logs — standard logs including IP address, browser type, and pages visited, retained by Namecheap's hosting infrastructure

How We Use Your Information

  • To send the newsletter you subscribed to
  • To respond to contact form messages
  • To process and deliver product purchases
  • To understand site traffic and improve content
  • To track affiliate referrals for commission purposes

Third-Party Services

Your Rights

You have the right to access, correct, or delete your personal data at any time. Email hello@thedatashark.com. Newsletter subscribers can unsubscribe at any time via the link in any email.

Children's Privacy

This website is not directed at children under 13. We do not knowingly collect personal information from children.

Changes to This Policy

Changes will be posted on this page with an updated date. Continued use of the site after changes constitutes acceptance of the updated policy.

Contact

hello@thedatashark.com

// Legal

Affiliate Disclosure

Full transparency about how this site earns from affiliate partnerships.

Last updated: January 2025

theDataShark participates in affiliate marketing programs. When you click certain links and make a purchase, we may earn a commission — at no additional cost to you.

Our Affiliate Partners

Namecheap (Web Hosting)

We participate in the Namecheap affiliate program. Namecheap is recommended because it's the hosting provider used to run this website — reliable shared hosting at competitive prices, suitable for beginners and small projects.

The SSL Store (SSL Certificates)

We participate in The SSL Store affiliate program via Commission Junction. SSL certificates are necessary for any production web deployment, and The SSL Store offers significant discounts (40–70%) over retail pricing.

Dynadot (Domain Registration)

We participate in the Dynadot affiliate program. Dynadot is recommended for its competitive pricing, free WHOIS privacy protection, and clean DNS management interface.

How It Works

  • When you click an affiliate link, a cookie is stored in your browser for a tracking period (typically 30–90 days)
  • If you make a purchase within that window, we receive a commission from the vendor
  • You pay the same price you'd pay going directly to the vendor
  • Affiliate links are identified on this site with a label or the "▸" symbol

Editorial Independence

Affiliate relationships do not influence editorial content. We only recommend services we have personally used and believe provide genuine value. We do not accept payment for editorial coverage or article placement.

FTC Compliance

This disclosure complies with the U.S. Federal Trade Commission's guidelines on endorsements (16 CFR Part 255) and equivalent requirements in other jurisdictions.

Questions

Email hello@thedatashark.com