You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Kubernetes不同命名空间设置Deployment默认副本数?

How to Set Default Replica Counts for Deployments per Namespace

Great question! Kubernetes doesn’t offer a built-in way to define namespace-specific default replica counts for Deployments out of the box, but you can easily implement this using a Mutating Admission Webhook. This component intercepts Kubernetes API requests (like when creating a Deployment) and modifies the resource’s configuration before it’s saved to the cluster’s etcd store—exactly what we need to inject default replicas based on the target namespace.

How It Works

The webhook will:

  • Intercept all CREATE requests for Deployments
  • Check the namespace the Deployment is being created in
  • If the Deployment doesn’t explicitly set spec.replicas, inject the appropriate default value (2 for production, 1 for staging)
  • Leave explicitly set replica counts untouched (so users can still override the default if needed)

Step-by-Step Implementation

1. Build the Webhook Service

You’ll need a small web service that handles admission review requests. Below is a simplified Python/Flask example (you could also use Go, Node.js, etc.):

import base64
import json
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/mutate', methods=['POST'])
def mutate_deployment():
    admission_review = request.get_json()
    deployment = admission_review['request']['object']
    namespace = admission_review['request']['namespace']
    request_uid = admission_review['request']['uid']

    # Only modify Deployments that don't have replicas specified
    if deployment['kind'] == 'Deployment' and 'replicas' not in deployment['spec']:
        # Set default replicas based on namespace
        if namespace == 'production':
            target_replicas = 2
        elif namespace == 'staging':
            target_replicas = 1
        else:
            # Leave default (Kubernetes uses 1 if not set)
            return jsonify({
                'apiVersion': 'admission.k8s.io/v1',
                'kind': 'AdmissionReview',
                'response': {
                    'uid': request_uid,
                    'allowed': True
                }
            })
        
        # Generate JSON patch to add the replicas field
        patch = json.dumps([
            {
                'op': 'add',
                'path': '/spec/replicas',
                'value': target_replicas
            }
        ])
        encoded_patch = base64.b64encode(patch.encode()).decode()

        return jsonify({
            'apiVersion': 'admission.k8s.io/v1',
            'kind': 'AdmissionReview',
            'response': {
                'uid': request_uid,
                'allowed': True,
                'patchType': 'JSONPatch',
                'patch': encoded_patch
            }
        })
    
    # Allow the request without modification if replicas are already set
    return jsonify({
        'apiVersion': 'admission.k8s.io/v1',
        'kind': 'AdmissionReview',
        'response': {
            'uid': request_uid,
            'allowed': True
        }
    })

if __name__ == '__main__':
    # Run with HTTPS (required for Kubernetes webhooks)
    app.run(host='0.0.0.0', port=443, ssl_context=('/certs/tls.crt', '/certs/tls.key'))

2. Package and Deploy the Webhook

  • Package the service into a container image (e.g., using a Dockerfile)
  • Deploy the service to your cluster (we’ll use the kube-system namespace for this example) with necessary permissions:
# ServiceAccount for the webhook
apiVersion: v1
kind: ServiceAccount
metadata:
  name: deployment-replicas-webhook
  namespace: kube-system

---
# ClusterRole to allow reading Deployment resources
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: deployment-replicas-webhook
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch"]

---
# Bind the ClusterRole to the ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: deployment-replicas-webhook
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: deployment-replicas-webhook
subjects:
- kind: ServiceAccount
  name: deployment-replicas-webhook
  namespace: kube-system

---
# Deployment for the webhook service
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-replicas-webhook
  namespace: kube-system
spec:
  replicas: 2
  selector:
    matchLabels:
      app: deployment-replicas-webhook
  template:
    metadata:
      labels:
        app: deployment-replicas-webhook
    spec:
      serviceAccountName: deployment-replicas-webhook
      containers:
      - name: webhook
        image: your-registry/deployment-replicas-webhook:v1
        ports:
        - containerPort: 443
        volumeMounts:
        - name: certs
          mountPath: /certs
          readOnly: true
      volumes:
      - name: certs
        secret:
          secretName: deployment-replicas-webhook-certs

---
# Service to expose the webhook internally
apiVersion: v1
kind: Service
metadata:
  name: deployment-replicas-webhook
  namespace: kube-system
spec:
  selector:
    app: deployment-replicas-webhook
  ports:
  - port: 443
    targetPort: 443

3. Configure TLS Certificates

Kubernetes requires webhooks to use HTTPS. You can generate certificates manually, but using cert-manager is recommended for automated management. Once you have your CA and service certificates stored in a Secret (deployment-replicas-webhook-certs), update the deployment above to mount them.

4. Register the Mutating Webhook

Finally, create a MutatingWebhookConfiguration to tell Kubernetes to route Deployment creation requests to your webhook:

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: deployment-replicas-webhook
webhooks:
- name: deployment-replicas.kube-system.svc
  clientConfig:
    service:
      name: deployment-replicas-webhook
      namespace: kube-system
      path: "/mutate"
    caBundle: <BASE64_ENCODED_CA_CERTIFICATE>
  rules:
  - apiGroups: ["apps"]
    apiVersions: ["v1"]
    operations: ["CREATE"]
    resources: ["deployments"]
  sideEffects: None
  admissionReviewVersions: ["v1"]
  namespaceSelector:
    # Optional: Limit to specific namespaces if needed
    matchExpressions:
    - key: kubernetes.io/metadata.name
      operator: In
      values: ["production", "staging"]

Testing the Setup

  1. Create a Deployment in production without specifying replicas:

    kubectl create deployment test-prod --image=nginx -n production
    

    Check the replica count: kubectl get deploy test-prod -n production should show 2/2.

  2. Create a Deployment in staging without specifying replicas:

    kubectl create deployment test-staging --image=nginx -n staging
    

    Check the replica count: kubectl get deploy test-staging -n staging should show 1/1.

  3. Try creating a Deployment with explicit replicas (it should remain unchanged):

    kubectl create deployment test-override --image=nginx --replicas=3 -n production
    

    This should stay at 3 replicas.

Key Notes

  • Flexibility: You can easily update the webhook logic to add more namespaces or adjust default replica counts later.
  • Overrides: Users can always explicitly set spec.replicas to override the default, which is preserved by the webhook.
  • Certificates: Keep your TLS certificates updated—cert-manager can handle this automatically to avoid downtime.

内容的提问来源于stack exchange,提问作者max_

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:03:56