🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

What is the TCP/IP Stack? Explained Simply for DevOps Engineers

TCP/IP is the foundation of all internet communication. Here's a clear explanation of the layers, protocols, and why they matter for debugging network issues in DevOps.

DevOpsBoys5 min read
Share:Tweet

Every network request your application makes — HTTP, database connections, Kubernetes pod communication — goes through the TCP/IP stack. Understanding it helps you debug connection issues, understand network policies, and design better systems.

The Layers

TCP/IP is organized in four layers. Think of each layer as adding an envelope around the data:

Application Layer    → HTTP, HTTPS, DNS, SSH, gRPC
Transport Layer      → TCP, UDP
Internet Layer       → IP (IPv4, IPv6)
Network Access Layer → Ethernet, WiFi (physical transmission)

Each layer adds a header to the data, and the receiving end strips each header back off.

Application Layer

This is where your application lives. You write code that speaks HTTP, gRPC, or PostgreSQL's wire protocol. You don't think about packets or addresses — you just send/receive data.

python
# HTTP request - application layer
import requests
response = requests.get("https://api.devopsboys.com/posts")
 
# Database connection - application layer
import psycopg2
conn = psycopg2.connect(host="postgres-service", port=5432, dbname="mydb")

The application layer uses well-known port numbers:

  • HTTP: 80, HTTPS: 443
  • SSH: 22
  • PostgreSQL: 5432
  • Redis: 6379
  • Kafka: 9092

Why it matters for DevOps:

bash
# Check if a port is open (application-level)
curl -v http://my-service:8080/health
 
# Test TLS certificate
openssl s_client -connect api.devopsboys.com:443
 
# Check listening ports
ss -tlnp  # Linux
netstat -tlnp

Transport Layer: TCP vs UDP

The transport layer provides the communication channel between two processes.

TCP (Transmission Control Protocol):

  • Connection-based (establishes a connection before sending data)
  • Guaranteed delivery (retransmits lost packets)
  • In-order delivery (packets arrive in the right order)
  • Slower than UDP but reliable

Used by: HTTP, HTTPS, SSH, PostgreSQL, Redis

TCP handshake (3-way):

Client → SYN (I want to connect)
Server → SYN-ACK (I acknowledge, I also want to connect)
Client → ACK (I acknowledge your acknowledgment)
[Connection established — data can flow]

When you see "connection refused" — the server received your SYN but nothing is listening on that port.

When you see "connection timed out" — your SYN packet never reached the server (firewall blocking, wrong IP, network down).

UDP (User Datagram Protocol):

  • No connection setup
  • No guaranteed delivery (packets can be lost)
  • No ordering guarantee
  • Much faster and lower overhead than TCP

Used by: DNS (port 53), video streaming, gaming, metrics (StatsD, some Prometheus exporters)

For DevOps:

bash
# Test TCP connectivity
telnet redis-service 6379  # old school
nc -zv redis-service 6379  # modern
 
# Test UDP
nc -zu dns-service 53
 
# Watch TCP connections
ss -s  # summary statistics
ss -t state established  # active TCP connections
 
# Connection states
ss -tn
# LISTEN     → server waiting for connections
# ESTABLISHED → active connection
# TIME_WAIT   → connection recently closed (normal, goes away after 2 min)
# CLOSE_WAIT  → remote side closed, your app hasn't closed yet (possible bug)

CLOSE_WAIT connections that accumulate point to a bug where your application isn't closing connections properly.

Internet Layer: IP Addressing

IP gives every machine an address. Like a street address — needed so packets know where to go.

IPv4: 32-bit address, written as 4 numbers (192.168.1.100)

10.0.0.0/8        Private range (often used in cloud VPCs)
172.16.0.0/12     Private range (often used by Docker)
192.168.0.0/16    Private range (home networks)
127.0.0.1         Loopback (localhost)

CIDR notation: /24 means 24 bits are the network, 8 bits are the host = 254 usable addresses

bash
# Your machine's IP addresses
ip addr show  # Linux
# Look for inet 10.0.x.x or 172.x.x.x
 
# Route table (where traffic goes)
ip route show
# default via 172.17.0.1  ← default gateway (internet traffic goes here)
# 10.0.0.0/24 dev eth0    ← local network traffic
 
# Trace the path packets take
traceroute api.devopsboys.com
# Shows each router hop between you and the destination

In Kubernetes: Each pod gets its own IP from the pod CIDR range. The Kubernetes CNI (Cilium, Calico, Flannel) manages this.

bash
kubectl get pod my-app -o wide
# Shows the pod's IP address
 
# Kubernetes service IPs are virtual (handled by kube-proxy)
kubectl get service my-service

DNS: The Address Book

DNS translates hostnames to IP addresses. Without it, you'd need to remember IPs for everything.

bash
# Look up a hostname
dig api.devopsboys.com
nslookup api.devopsboys.com
 
# See which DNS server you're using
cat /etc/resolv.conf
 
# In Kubernetes, CoreDNS handles DNS
# Service names resolve to ClusterIP
nslookup my-service.my-namespace.svc.cluster.local

Common DNS issues in Kubernetes:

bash
# Pod can't resolve service names
kubectl exec -it my-pod -- nslookup kubernetes.default
# If this fails, CoreDNS is broken
 
# Check CoreDNS pods
kubectl get pods -n kube-system -l k8s-app=kube-dns

Network Access Layer: Physical Transmission

Ethernet, WiFi, fiber — the physical bits traveling between machines. As a DevOps engineer, you rarely interact with this layer directly, but you might see it in:

bash
# Check physical interface stats
ip link show eth0
ethtool eth0  # more detailed stats
 
# Packet drops at physical layer
ip -s link show eth0 | grep -A 5 "RX:"
# errors: 0    dropped: 123  <- dropped packets could indicate hardware issues

Putting It Together: What Happens When You curl an API

bash
curl https://api.devopsboys.com/posts
  1. DNS lookup: resolve api.devopsboys.com → IP 104.21.x.x
  2. TCP handshake: SYN → SYN-ACK → ACK to port 443
  3. TLS handshake: negotiate encryption (HTTPS = HTTP + TLS)
  4. HTTP request: GET /posts HTTP/2 over the encrypted connection
  5. Response: server sends HTTP response body
  6. TCP teardown: FIN → ACK → FIN → ACK

Understanding this flow helps when debugging:

  • DNS failure: hostname resolves to wrong IP or not at all
  • TCP timeout: firewall blocking, server down
  • TLS error: certificate expired, hostname mismatch
  • HTTP 5xx: application-level error, server running but failing

Debugging Network Issues: Quick Reference

bash
# Is the service reachable? (Layer 3/4)
ping 10.0.0.5       # ICMP ping (may be blocked in Kubernetes)
nc -zv 10.0.0.5 8080  # TCP port check
 
# DNS working? (Application layer)
dig my-service.default.svc.cluster.local
nslookup my-service
 
# Is something listening on the port?
ss -tlnp | grep 8080
 
# Active connections
ss -tn state established
 
# Packet-level debugging
tcpdump -i eth0 -n port 8080  # capture packets on port 8080
tcpdump -i eth0 host 10.0.0.5 -n  # capture traffic to/from specific host
 
# Network performance
iperf3 -c target-host  # bandwidth test

The OSI and TCP/IP models appear abstract, but they map directly to real tools and real debugging. Knowing which layer a problem is at — DNS, TCP connection, TLS, or application — cuts your debugging time in half.

🔧

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments