Thursday, May 28, 2026

Kube-proxy in Kubernetes

Kube-proxy is a foundational Kubernetes network agent that runs on every node in a cluster. Its primary job is to translate Kubernetes Service definitions into actual network rules, enabling reliable service discovery and load balancing between containers.

Because individual Pods are ephemeral and their IP addresses change every time they are restarted or scaled, a consistent way to reach them is needed. Kube-proxy solves this by continuously monitoring the Kubernetes API server for changes to Service and EndpointSlice objects.

How It Works

Virtual IPs

When you create a Service, it gets assigned a stable, virtual IP address (ClusterIP).

Rule Generation

Kube-proxy reads this assignment and configures the node's underlying networking stack to intercept traffic headed for this virtual IP.

Routing & Load Balancing

It rewrites the packet headers so the traffic is transparently routed directly to one of the actual backend Pods backing that Service. If there are multiple Pods, it distributes the load across them.

Modes of Operation

Kube-proxy operates in one of several modes to manipulate network traffic, depending on your cluster's configuration:

iptables (Default)

Evaluates traffic sequentially using Linux iptables. It is highly reliable but can experience performance overhead in very large clusters with thousands of services.

IPVS (IP Virtual Server)

Designed for high performance, IPVS routes traffic in the Linux kernel using hash tables. It offers significantly faster lookup times and supports advanced load balancing algorithms (e.g., round-robin, least connections).

Userspace (Legacy)

The oldest mode, where kube-proxy actively intercepts traffic in user space and proxies it to the pods. It is slower and rarely used today.

A Modern Shift: eBPF

While kube-proxy has historically been a mandatory component, modern Kubernetes environments are increasingly replacing or supplementing it with eBPF-based networking plugins (like Cilium). eBPF bypasses the need to program traditional iptables or IPVS rules, operating directly within the kernel for faster, more secure network management and load balancing

Kubernetes Operator Frameworks

Framework Primary Language / Ecosystem Best For Key Advantage
Operator SDK Go, Helm, Ansible Multi-language & OLM integration Supports low-code Helm and Ansible operators
Kubebuilder Go Standard, production-grade Go operators Official Kubernetes SIG tool with clean scaffolding
Java Operator SDK Java Enterprise Java applications Native integration with Quarkus and Spring Boot
Kopf Python Rapid prototyping and Data/ML teams Highly intuitive, pythonic event handling
kube-rs Rust High-performance infrastructure Type-safe, memory-efficient, and lightweight

Kubernetes Control Plane Components


Component Name Primary Function Runs Control Loops?
kube-apiserver Exposes the Kubernetes API; acts as the entry point for all cluster communication and commands. No (It processes requests but does not run the loops).
etcd Stores the complete cluster configuration and state data in a secure, distributed key-value database. No (It is a passive data store).
kube-scheduler Assigns newly created Pods to optimal worker nodes based on resource availability and constraints. No (It focuses purely on placement decisions).
kube-controller-manager Yes. It embeds core control loops (like node, job, and endpoint controllers) that constantly watch the cluster state and drive it toward the desired configuration. Yes (Primary manager for core cluster loops).
cloud-controller-manager Connects your cluster to a cloud provider's API to manage cloud-specific resources like load balancers and storage. Yes (Specifically for cloud-infrastructure loops).

Passing Environment Variables to Kubernetes Pods

To pass environment variables to Kubernetes Pods, you can define them directly in your Pod or Deployment manifest, or pull them from external resources like ConfigMaps and Secrets.

1. Direct Definition

Use the env field within your container specification to define key-value pairs directly.

yaml
spec:
  containers:
  - name: my-container
    image: nginx
    env:
    - name: APP_COLOR
      value: "blue"

2. Using ConfigMaps (Non-Sensitive Data)

ConfigMaps allow you to decouple configuration from your image.

  • Single Key: Use valueFrom and configMapKeyRef.
  • All Keys: Use envFrom to inject every key in a ConfigMap as an environment variable.
yaml
envFrom:
- configMapRef:
    name: my-configmap

3. Using Secrets (Sensitive Data)

For passwords or API keys, use Secrets. This works similarly to ConfigMaps but provides a layer of security for sensitive data.

yaml
env:
- name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: my-secret
      key: password

4. Injecting Pod/Node Metadata (Downward API)

You can expose Pod information (like its IP address or the Node name it's running on) as environment variables using fieldRef.

yaml
env:
- name: MY_POD_IP
  valueFrom:
    fieldRef:
      fieldPath: status.podIP

5. Using Command Line (kubectl)

You can quickly update environment variables for an existing Deployment or ReplicaSet without editing the YAML file manually.

  • Set variable: kubectl set env deployment/my-deploy APP_ENV=prod
  • Remove variable: kubectl set env deployment/my-deploy APP_ENV-

Summary of Methods

Method Best For Reference Field
Direct Simple, static values env
ConfigMap Non-sensitive app config configMapKeyRef or envFrom
Secret Credentials/Tokens secretKeyRef or envFrom
Downward API Pod/Node metadata fieldRef

Wednesday, May 27, 2026

Getting environment variables in React app

To get environment variables in React, the method depends on the tool you used to build your project. React environment variables are embedded into the application during the build process.

1. If you are using Create React App (CRA)

Variable Prefix

You must prefix your variables with REACT_APP_ for React to recognize them.

Create File

Create a .env file in the root folder (not in src).

REACT_APP_API_URL=https://api.example.com
    

Access in Code

Use process.env.

const apiUrl = process.env.REACT_APP_API_URL;
    


2. If you are using Vite

Variable Prefix

You must prefix your variables with VITE_.

Create File

Create a .env file in the root folder.

VITE_API_URL=https://api.example.com
    

Access in Code

Use import.meta.env.

const apiUrl = import.meta.env.VITE_API_URL;
    

Important Rules

Restart the Server

You must restart your development server (e.g., npm start or npm run dev) whenever you change the .env file for the changes to take effect.

Security

Never store sensitive secrets like private API keys in these files. Because React is a client-side framework, these variables are visible to anyone who inspects your app's source code in the browser.

Gitignore

Always add .env to your .gitignore file to avoid pushing local configuration or keys to your repository.

Kubernetes Topology Spread Constraints

Topology spread constraints are rules in Kubernetes used to control how Pods are distributed across your cluster's failure domains (such as regions, zones, or specific nodes). They ensure high availability and efficient resource utilization by preventing all replicas of an application from being concentrated in a single location.

Why Use Them?

Without topology constraints, a scaling event or node failure could take down your application if all pods land on the same host or availability zone. By defining these constraints, you ensure that Pods are spread evenly.

Core Components

A topology spread constraint requires a few key parameters:

topologyKey

The node label used to define the topology domain (e.g., kubernetes.io/hostname for nodes, or topology.kubernetes.io/zone for availability zones).

maxSkew

The maximum allowed difference in the number of Pods between any two topology domains. For example, if maxSkew is 1, and you have two zones, one zone can have 4 pods and the other 5, but not 3 and 5.

whenUnsatisfiable

Tells the scheduler what to do if the constraint cannot be met. You can choose to DoNotSchedule (reject the pod until the cluster changes) or ScheduleAnyway (place it regardless, prioritizing the most balanced node available).

labelSelector

Identifies which set of Pods the constraint applies to (usually based on their labels).

Example Configuration

Here is how you define a topologySpreadConstraints rule in a Deployment or ReplicaSet to spread pods evenly across different zones:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: web
      containers:
      - name: web-container
        image: nginx

Topology Spread vs. Pod Anti-Affinity

While Pod Anti-Affinity is often used to prevent Pods from landing on the same node, it is an "all-or-nothing" binary rule. Topology Spread Constraints provide a much more flexible and gradual approach. Instead of just blocking co-location, they allow you to fine-tune exactly how uneven the distribution (skew) can be across your infrastructure.

Cordon and Drain in Kubernetes

Cordon and drain are administrative operations in Kubernetes used to safely take a worker node offline for maintenance, upgrades, or decommissioning. "Cordoning" marks the node as unschedulable for new pods, while "draining" safely evicts all existing pods to other healthy nodes.

These commands prevent workload disruption and protect data during cluster administration. Here is a breakdown of how both processes work: 

1. Cordon: Closing the Door to New Work

When you cordon a node, Kubernetes stops scheduling new pods on that machine.

  • What happens: The node's status changes to SchedulingDisabled.
  • Effect on existing workloads: None. Any pods currently running on the node continue to operate normally until they finish or are deleted.
  • When to use it: When you want to gracefully phase out a node or prepare it for a drain, but you want existing pods to finish their current tasks first. 

2. Drain: Emptying the Node

When you drain a node, you perform a full evacuation of the machine.

  • What happens: First, Kubernetes automatically cordons the node to ensure no new pods land on it. Then, it gently evicts all running pods.
  • Effect on existing workloads: The pods are gracefully terminated on the current node and recreated on other available nodes in your cluster.
  • When to use it: When you need to safely shut down the server, reboot it, or perform hardware/OS maintenance without causing downtime for your applications. 

How to Execute (Commands)

These operations are performed using the kubectl command-line tool.

  • To cordon a node: kubectl cordon <node-name>
  • To drain a node: kubectl drain <node-name>
  • To reverse the process (make it available again): kubectl uncordon <node-name>

Best Practices & Things to Know

  • DaemonSets: By default, the drain command will not evict pods that are part of a DaemonSet (as these typically run on every node to provide cluster-wide services). You have to pass the --ignore-daemonsets flag to force the drain.
  • PodDisruptionBudgets (PDB): When you drain a node, Kubernetes respects PDBs to ensure a minimum number of replicas remain running to prevent service outages. 

Kube-proxy in Kubernetes

Kube-proxy is a foundational Kubernetes network agent that runs on every node in a cluster. Its primary job is...