Cloud Native 43 min read

Kubernetes Deployment Node Scheduling: A Complete Guide Beyond Just Running Pods

The article explains why the default Kubernetes scheduler is insufficient for production, details the four scheduling constraints—resource, topology, performance, and governance—covers the scheduler's internal phases, and provides practical patterns, code examples, and troubleshooting steps for robust Deployment node scheduling.

Cloud Architecture
Cloud Architecture
Cloud Architecture
Kubernetes Deployment Node Scheduling: A Complete Guide Beyond Just Running Pods

1. Why the default scheduler is not enough

Many teams first think of scheduling as a single sentence: "If the cluster has free resources, the scheduler will place the Pod somewhere." That statement is true but incomplete. In real production environments a Deployment must satisfy four categories of constraints:

Resource constraints : CPU, memory, GPU, temporary storage must be sufficient.

Topology constraints : replicas should be evenly spread across nodes, zones, and racks.

Performance constraints : pods should be close to dependent services, avoid cross‑AZ latency, and run on high‑performance node pools.

Governance constraints : critical business workloads may only run on dedicated nodes, low‑priority jobs must not pre‑empt production nodes, and upgrades must preserve availability.

If no explicit scheduling policy is defined, the common outcome is not a scheduling failure but a "scheduled successfully but with poor runtime quality" situation, such as:

5 out of 10 replicas crowd onto a single node, creating a hotspot.

All replicas land in the same availability zone, causing a total outage when that zone fails.

Service and its cache, sidecar, or inference component are placed on different nodes, lengthening call paths.

Inference and online transaction workloads compete for CPU during peak hours.

After auto‑scaling, new nodes lack the expected labels, breaking the original scheduling semantics.

During a rollout, anti‑affinity and topology rules cause Pods to stay in Pending and block the rolling update.

Node scheduling is not a tiny YAML trick; it is a core part of production architecture.

2. A key insight: Deployment does not schedule directly – Pods do

Relationship chain:

Deployment -> ReplicaSet -> Pod -> Scheduler -> Node

Deployment declares the desired state (replica count, upgrade strategy, Pod template). The objects that actually enter the scheduler queue are Pods.

This leads to two important facts:

All scheduling rules are ultimately written under Pod.spec.

Each rollout, scale‑up, or scale‑down creates a new batch of Pods, triggering a fresh scheduling decision.

Therefore scheduling policies affect not only the initial placement but also rolling upgrades, HPA scaling, node expansion, and node‑failure recovery.

3. What the scheduler actually does: from "can it run?" to "where is best?"

A Pod moves through the following logical stages:

3.1 Queue – the Pod enters the scheduling queue

The scheduler processes Pods one by one rather than evaluating the whole pending set at once.

3.2 Filter – discard nodes that do not satisfy hard requirements

Typical filter criteria include:

Insufficient node resources. nodeSelector mismatch. requiredDuringSchedulingIgnoredDuringExecution node affinity not satisfied. requiredDuringSchedulingIgnoredDuringExecution pod affinity/anti‑affinity not satisfied.

Node taint not tolerated by the Pod.

Port conflicts, volume constraints, topology constraints, etc.

If no candidate node remains after filtering, the Pod stays in Pending.

3.3 Score – rank the remaining candidates

When multiple nodes survive filtering, the scheduler scores them based on:

Resource utilization.

Weighted preferences from node affinity.

Soft pod anti‑affinity constraints.

Topology spread preferences.

Image locality.

Scores contributed by additional scheduler plugins.

The node with the highest total score is selected.

3.4 Bind – bind the Pod to the chosen node

The scheduler binds the Pod to the node; the node’s kubelet then pulls the image, creates containers, and starts probes.

3.5 Preemption – optional eviction of lower‑priority Pods

If a PriorityClass is enabled and a high‑priority Pod cannot be scheduled, the scheduler may preempt lower‑priority Pods to make room, but it cannot fix mis‑configured affinity, label, or taint rules.

Conclusion: scheduling problems are usually the result of a combination of Filter, Score, resource requests, topology constraints, and release strategy rather than a single mis‑configuration.

4. The scheduling toolbox: five core mechanisms and how they collaborate

nodeSelector

– simple hard node filtering (e.g., workload=online and disk=ssd). nodeAffinity – richer node selection with required and preferred rules. podAffinity / podAntiAffinity – control how Pods relate to each other (co‑location or separation). topologySpreadConstraints – enforce balanced distribution across a topology domain. taints / tolerations – make a node reject Pods unless they explicitly tolerate the taint.

These mechanisms are not mutually exclusive; they form a layered collaboration: nodeAffinity decides which node pool a Pod may enter. podAntiAffinity prevents replicas from crowding on the same node. topologySpreadConstraints ensures global balance across zones or hosts.

5. First layer – nodeSelector and nodeAffinity

5.1 nodeSelector : the simplest and most reliable

spec:
  template:
    spec:
      nodeSelector:
        workload: online
        disk: ssd

This forces the Pod onto nodes that carry both workload=online and disk=ssd labels. Advantages: simplicity, readability, and almost no mis‑interpretation. Drawbacks:

Only exact matches.

Cannot express soft preferences like "prefer these nodes".

Limited combinatorial power.

5.2 nodeAffinity : the production‑grade choice

When more complex policies are needed, use nodeAffinity:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: workload
          operator: In
          values: ["online"]
        - key: cpu-tier
          operator: In
          values: ["high"]
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 80
      preference:
        matchExpressions:
        - key: topology.kubernetes.io/zone
          operator: In
          values: ["az-a"]
    - weight: 20
      preference:
        matchExpressions:
        - key: disk
          operator: In
          values: ["nvme"]

Two important points:

required vs preferred : requiredDuringSchedulingIgnoredDuringExecution must be satisfied for the Pod to be scheduled; preferredDuringSchedulingIgnoredDuringExecution is only a scoring factor.

The IgnoredDuringExecution suffix means the rule is evaluated only at creation time. If node labels change later, the Pod will not be evicted automatically.

Best practice: put immutable business rules under required and performance or cost optimisations under preferred .

6. Second layer – Pod affinity and anti‑affinity

Node selection solves "which kind of node", but many high‑throughput systems also need to control the relationship between services:

Services that must be close to each other (low latency).

Replicas that should not be placed together (fault isolation).

6.1 podAffinity : keep strongly coupled services together

Typical scenarios:

Gateway and its sidecar need low latency.

Business containers depend on a local cache or proxy.

Traffic paths benefit from intra‑node IPC.

affinity:
  podAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 80
      podAffinityTerm:
        labelSelector:
          matchLabels:
            app: local-risk-engine
        topologyKey: kubernetes.io/hostname

This prefers placing the current Pod on the same node as a Pod labeled app=local-risk-engine.

6.2 podAntiAffinity : avoid replica crowding

One of the most useful production capabilities:

affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchLabels:
          app: payment-gateway
      topologyKey: kubernetes.io/hostname

The rule means Pods of the payment-gateway application cannot land on the same node. Changing topologyKey to topology.kubernetes.io/zone would enforce zone‑level separation.

6.3 Anti‑affinity pitfalls

Hard anti‑affinity can easily block a rollout. The simple formula is:

required anti‑affinity requires "replicas ≤ number of topology domains".

Example: 3 replicas, hard zone anti‑affinity, but only 2 zones → at least one Pod will stay Pending. During a rolling update, if maxSurge=2 and the node pool has only 6 nodes, the extra Pods may not find distinct nodes, causing the rollout to stall.

7. Third layer – topologySpreadConstraints : balanced distribution instead of pure exclusion

Many teams treat podAntiAffinity as the only distribution tool, but it is essentially a "do not place together" hard rule. For large services the real need is:

"Allow co‑location, but keep the overall distribution balanced and avoid a one‑sided skew."

7.1 Why it fits large Deployments better

Assume 60 replicas across 3 zones and 30 nodes. What matters is not that any two replicas never share a node, but that:

Replica counts per zone stay roughly equal.

No single node becomes a hotspot.

Scaling, shrinking, and upgrades preserve the balance. topologySpreadConstraints naturally enforces these goals.

7.2 Key parameters

topologySpreadConstraints:
- maxSkew: 1
  topologyKey: topology.kubernetes.io/zone
  whenUnsatisfiable: DoNotSchedule
  labelSelector:
    matchLabels:
      app: payment-gateway
topologyKey

: the dimension to balance (node, zone, rack, etc.). maxSkew: allowed maximum difference between the most and least loaded domains. whenUnsatisfiable: DoNotSchedule blocks scheduling if balance cannot be kept; ScheduleAnyway prefers balance but still allows placement. labelSelector: selects which Pods participate in the spread calculation.

7.3 Example of skew calculation

With three zones holding 4, 3, and 3 replicas respectively, the max‑skew is 1 and the constraint is satisfied. If the distribution becomes 6, 2, 2, the skew is 4, violating maxSkew: 1.

7.4 Production recommendation

For online transaction, gateway, and API services, the typical pattern is:

Use nodeAffinity.required to select the core online node pool.

Use podAntiAffinity.preferred to avoid stacking on a single host.

Use topologySpreadConstraints to enforce cross‑AZ balance.

8. Fourth layer – taints and tolerations : who may enter a dedicated node

Affinity answers "where I want to go"; taints/tolerations answer "who is allowed to enter".

8.1 The essence of a taint

Example: mark GPU nodes as dedicated.

kubectl taint nodes gpu-node-1 dedicated=gpu:NoSchedule

Pods without a matching toleration cannot be scheduled onto that node.

8.2 The essence of a toleration

tolerations:
- key: dedicated
  operator: Equal
  value: gpu
  effect: NoSchedule

This does not guarantee placement on a GPU node; it merely allows it. To make GPU nodes the preferred target, combine the toleration with nodeSelector or nodeAffinity and request GPU resources.

8.3 A robust dedicated‑node pattern

Label nodes with capability and pool identity.

Apply a taint that rejects unrelated Pods.

Pods declare tolerations + nodeAffinity + resource requests.

This prevents accidental placement while still allowing the intended Pods to land on the dedicated pool.

9. Combining mechanisms: three common production design patterns

Individual YAML snippets are simple; the real challenge is combining them sensibly.

9.1 Pattern 1 – High‑availability core online services

Typical for order, payment, member, and risk‑control APIs that are latency‑sensitive and cost‑aware.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: payment-gateway
  namespace: prod
spec:
  replicas: 6
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1
  selector:
    matchLabels:
      app: payment-gateway
  template:
    metadata:
      labels:
        app: payment-gateway
        tier: core-api
    spec:
      priorityClassName: online-critical
      terminationGracePeriodSeconds: 60
      nodeSelector:
        workload: online
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: workload
                operator: In
                values: ["online"]
              - key: node-pool
                operator: In
                values: ["core-trading"]
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 60
            preference:
              matchExpressions:
              - key: disk
                operator: In
                values: ["nvme"]
          - weight: 40
            preference:
              matchExpressions:
              - key: instance-family
                operator: In
                values: ["c7", "c8"]
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  app: payment-gateway
              topologyKey: kubernetes.io/hostname
        topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: payment-gateway
        - maxSkew: 2
          topologyKey: kubernetes.io/hostname
          whenUnsatisfiable: ScheduleAnyway
          labelSelector:
            matchLabels:
              app: payment-gateway
      containers:
      - name: gateway
        image: registry.example.com/payment-gateway:v3.4.2
        ports:
        - name: http
          containerPort: 8080
        resources:
          requests:
            cpu: "800m"
            memory: "1Gi"
          limits:
            cpu: "2"
            memory: "2Gi"
        startupProbe:
          httpGet:
            path: /actuator/health
            port: 8080
          failureThreshold: 30
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /actuator/ready
            port: 8080
          periodSeconds: 5
          timeoutSeconds: 2
          failureThreshold: 3
        livenessProbe:
          httpGet:
            path: /actuator/live
            port: 8080
          periodSeconds: 10
          timeoutSeconds: 2
          failureThreshold: 3
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 15"]

Key production values: nodeAffinity.required guarantees entry into the core online node pool. podAntiAffinity.preferred avoids co‑location without blocking the rollout. topologySpreadConstraints enforces cross‑AZ balance. minReadySeconds, readiness probes, and preStop improve rolling‑upgrade stability. maxSurge/maxUnavailable together with distribution constraints decide whether the rollout has enough spare capacity.

9.2 Pattern 2 – GPU inference services with exclusive nodes

Typical for large‑model inference, vision, recommendation, or vector compute.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: image-inference
  namespace: ai
spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: image-inference
  template:
    metadata:
      labels:
        app: image-inference
    spec:
      tolerations:
      - key: dedicated
        operator: Equal
        value: gpu
        effect: NoSchedule
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: accelerator
                operator: In
                values: ["nvidia"]
              - key: node-pool
                operator: In
                values: ["gpu-serving"]
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            preference:
              matchExpressions:
              - key: topology.kubernetes.io/zone
                operator: In
                values: ["az-a", "az-b"]
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: kubernetes.io/hostname
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: image-inference
      containers:
      - name: server
        image: registry.example.com/ai/image-inference:2.1.0
        resources:
          requests:
            cpu: "4"
            memory: "16Gi"
            nvidia.com/gpu: "1"
          limits:
            cpu: "8"
            memory: "24Gi"
            nvidia.com/gpu: "1"
        ports:
        - containerPort: 9000
          name: http
        readinessProbe:
          httpGet:
            path: /ready
            port: 9000
          initialDelaySeconds: 10
          periodSeconds: 5

Key points:

Hard nodeAffinity.required guarantees placement on GPU nodes.

Tolerations allow only Pods that explicitly accept the GPU taint. topologySpreadConstraints prevents all inference Pods from landing on the same host.

Resource requests ensure the scheduler reserves GPU capacity.

9.3 Pattern 3 – Offline batch jobs isolated from online transactions

Typical for end‑of‑day reconciliation, reporting, feature‑calculation, or log replay.

Online node pool: label workload=online.

Batch node pool: label workload=batch and taint dedicated=batch:NoSchedule.

Batch Pods add a matching toleration so they can only run on batch nodes.

This guarantees that even if batch jobs consume all CPU, they never starve online services.

10. Engineering upgrades: scheduling must be designed together with high‑concurrency systems

Scheduling isolated from release strategy, autoscaling, priority, or capacity planning often leads to "locally correct, globally failing" outcomes.

10.1 Scheduling constraints must be accounted for in the rollout plan

When calculating capacity you cannot look only at replicas: 6. You must also consider the peak during a rolling update:

upgrade_peak_replicas = desired_replicas + maxSurge

Example: replicas=10 with maxSurge=30% yields a possible 13 Pods simultaneously.

If you also have hard anti‑affinity on hostnames and only 10 nodes in the pool, the extra Pods may stay Pending and block the rollout.

10.2 Scheduling must cooperate with HPA and Cluster Autoscaler

Typical HPA configuration:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: payment-gateway
spec:
  minReplicas: 6
  maxReplicas: 30
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: payment-gateway
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 65

If scheduling constraints are too strict, the HPA may increase the replica count but many Pods remain Pending (a "false" scale‑up).

When a Cluster Autoscaler is present, verify that newly created nodes automatically receive the required labels and taints, that the node‑pool limit is sufficient, and that new nodes are added in the correct availability zones.

10.3 PriorityClass – let critical traffic survive first

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: online-critical
value: 100000
preemptionPolicy: PreemptLowerPriority
globalDefault: false
description: "Critical online services"

High priority helps a Pod win resources under contention, but it cannot solve label mismatches, topology capacity limits, or missing tolerations.

10.4 PodDisruptionBudget – guarantee availability during maintenance

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: payment-gateway-pdb
spec:
  minAvailable: 4
  selector:
    matchLabels:
      app: payment-gateway

If you also require cross‑AZ balance and a relatively high minAvailable, the system must be able to satisfy both the distribution constraints and the PDB during node maintenance or upgrades.

11. Full case study: designing scheduling for an e‑commerce payment gateway

11.1 Business background

Usual replica count 8, auto‑scales to 24.

Must be deployed across three availability zones.

Latency‑sensitive; cross‑AZ traffic should be minimized.

Must not share nodes with offline tasks.

During a rollout at least 75 % of instances must stay available.

A single node failure must not reduce capacity by more than 20 %.

11.2 Design translation into scheduling language

Allow only nodes labeled workload=online and node-pool=core-trading.

Node pool must span three AZs.

Enforce cross‑AZ balance with maxSkew=1.

Use soft host‑level anti‑affinity to avoid many replicas on the same node.

HPA peak 24 + maxSurge=2 → plan for 26 Pods during a rollout.

Define a PDB to guarantee a minimum number of running Pods.

11.3 Capacity estimation

With soft host‑level anti‑affinity, the main capacity questions are:

Each AZ must be able to host roughly 9 replicas.

If one AZ fails, the remaining two AZs must absorb the extra load.

Node resource headroom must stay away from saturation, otherwise rolling updates cannot place new Pods.

For critical online services, node pools should be sized to cover "peak scaling + rollout overlap + single‑AZ failure" rather than just the steady‑state replica count.

11.4 Why hard host‑level anti‑affinity is discouraged here

If the service can reach 24 replicas but the node pool only has 18 nodes, a hard host anti‑affinity would block scaling. The recommended approach is:

Use topologySpreadConstraints for hard AZ balance.

Use soft host anti‑affinity ( preferred) for dispersion.

Provide sufficient resource requests and node‑pool redundancy to absorb peaks.

This reflects the engineering trade‑off: hard AZ distribution is a strong availability requirement, while perfect host isolation is an ideal that should not jeopardize scaling or rollout success.

12. Production troubleshooting: what to look at when a Pod stays Pending

12.1 Step 1 – inspect Pod events

kubectl describe pod payment-gateway-xxxx -n prod

Key information is in the Events section, e.g.:

"0/12 nodes are available: 3 Insufficient cpu, 4 node(s) didn't match Pod's node affinity, 5 node(s) had untolerated taint".

"0/6 nodes are available: 6 node(s) didn't match pod anti‑affinity rules".

"0/9 nodes are available: 3 node(s) didn't satisfy existing pods anti‑affinity rules, 6 node(s) didn't match topology spread constraints".

These messages pinpoint which filter condition blocked scheduling.

12.2 Step 2 – verify node labels and taints

kubectl get nodes --show-labels
kubectl describe node node-1

Common mismatches:

Node missing expected labels.

Label name typo.

Newly auto‑scaled nodes lack required labels.

Node has a taint but the Pod lacks a matching toleration.

12.3 Step 3 – check whether "resource insufficient" is amplified by constraints

The cluster may have enough total CPU/memory, but after applying node selectors, affinity, and topology rules the effective capacity can be far smaller.

Therefore you must evaluate the effective capacity after all constraints , not just the raw cluster resources.

12.4 Step 4 – examine rollout‑related conflicts

Pending Pods often appear only during a rollout. Verify:

Whether maxSurge is too large for the node pool.

Whether maxUnavailable is too small, preventing old Pods from terminating.

Whether old Pods are stuck because of PDB, lingering connections, or failing probes.

Whether new and old versions both participate in the same anti‑affinity or spread calculations.

Whether the node pool still has spare capacity at the rollout peak.

13. Five most common scheduling anti‑patterns

13.1 Anti‑pattern 1 – make everything required

All hard constraints make the system elegant on paper but extremely fragile in reality. Use required only for true SLA, isolation, or compliance needs; prefer preferred or ScheduleAnyway for performance or cost optimisations.

13.2 Anti‑pattern 2 – only configure anti‑affinity, ignore topology balance

Host‑level anti‑affinity prevents co‑location, yet cross‑AZ distribution can still be heavily skewed. Host dispersion and AZ balance address different problems and must be configured separately.

13.3 Anti‑pattern 3 – ad‑hoc node labeling without a naming convention

Scheduling ultimately depends on labels. Inconsistent or temporary labels erode scheduling semantics. Node labeling should be part of infrastructure governance, not a manual after‑thought.

13.4 Anti‑pattern 4 – design for normal replica count only, ignore peaks

Capacity must cover three peak scenarios:

HPA scaling peak.

Rollout overlap peak.

Failure‑domain (AZ) peak.

13.5 Anti‑pattern 5 – treat scheduling problems as pure "resource" issues

Often the cluster has enough CPU/memory, but Pods stay pending because of label mismatches, missing tolerations, constraint conflicts, or insufficient topology domains.

14. A reusable production design methodology

Define hard constraints (must‑enter production pool, GPU requirement, cross‑AZ distribution, isolation from offline tasks) and soft goals (prefer NVMe, co‑locate with certain services, avoid host crowding, stay near traffic entry).

Identify the topology dimensions you need: node ( kubernetes.io/hostname), zone ( topology.kubernetes.io/zone), region, or custom rack label.

Perform capacity planning against peak scenarios (release surge, HPA max, AZ failure). Ask:

How many extra Pods appear during a rollout?

Can HPA max replicas still satisfy all constraints?

Does the system survive loss of one AZ or a few nodes?

Do auto‑scaled nodes automatically receive the correct labels and taints?

Only after the label taxonomy, node‑pool isolation, and topology strategy are settled, write the YAML that combines nodeAffinity, podAntiAffinity, topologySpreadConstraints, tolerations, and release parameters.

15. Conclusion – scheduling is a cluster‑governance capability, not a deployment detail

Recall the opening question: why is the default scheduler insufficient?

Because default scheduling solves "can it run?" whereas production architecture must answer:

Is the service stable?

Is it fast enough?

Can it scale when needed?

Will a rollout get stuck?

How much capacity is lost when a node fails?

Do different workloads interfere with each other?

The correct way to think about Deployment node scheduling is to understand the five pillars: nodeAffinity – decides which node pool a Pod may enter. podAffinity / podAntiAffinity – controls service proximity or isolation. topologySpreadConstraints – balances replicas across topology domains. taints / tolerations – defines admission boundaries for dedicated pools.

Release strategy, HPA, PDB, and PriorityClass must be co‑designed with the above scheduling rules.

In a mature Kubernetes production system, scheduling is never an isolated YAML tweak; it is part of a closed loop that includes capacity planning, fault‑domain design, node‑pool governance, release mechanisms, and elasticity strategies.

If your team has moved beyond "just get the Pod running" and now cares about cross‑AZ balance, node‑pool isolation, rollout peak capacity, and critical‑traffic priority, you have entered the next stage of Kubernetes scheduling governance – and it is worth doing it right.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

deploymentKubernetesNode SchedulingtaintstopologySpreadConstraintsnodeAffinitypodAntiAffinity
Cloud Architecture
Written by

Cloud Architecture

Focuses on cloud‑native and distributed architecture engineering, sharing practical solutions and lessons learned. Covers microservice governance, Kubernetes, observability, and stability engineering to help your systems run stable, fast, and cost‑effectively.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.