基于ECR、EKS的容器化应用CI/CD部署:无镜像标签变更的滚动更新问题
Nice one! I’ve dealt with this exact scenario when building CI/CD pipelines for EKS using Lambda, so I know exactly what you’re looking for. Let’s break down how to replicate that kubectl rollout restart deployment behavior without changing your image tags.
kubectl rollout restart in Lambda (Python/Node.js) for EKS The Core Idea
kubectl rollout restart deployment doesn’t modify your image tag at all. Under the hood, it adds or updates an annotation in the Deployment’s pod template (like kubectl.kubernetes.io/restartedAt with a timestamp). Kubernetes detects this change to the pod template and triggers a rolling update, recreating pods with the same image tag but fresh configurations. We can mirror this logic directly in our Lambda functions using the Kubernetes client libraries.
Python Implementation (kubernetes-client/python)
First, make sure your Lambda has the necessary IAM permissions to interact with your EKS cluster (e.g., eks:DescribeCluster and Kubernetes API permissions to update Deployments). Here’s a working function:
from kubernetes import client, config from datetime import datetime def lambda_handler(event, context): # Load EKS configuration (uses Lambda's IAM role for authentication) config.load_incluster_config() # Use this if Lambda runs inside EKS; use load_kube_config for external (not recommended) apps_v1 = client.AppsV1Api() # Update these values to match your deployment deployment_name = "your-deployment-name" namespace = "default" # Fetch the current deployment deployment = apps_v1.read_namespaced_deployment(deployment_name, namespace) # Initialize annotations if they don't exist if not deployment.spec.template.metadata.annotations: deployment.spec.template.metadata.annotations = {} # Add/update the restart trigger annotation with a UTC timestamp deployment.spec.template.metadata.annotations["kubectl.kubernetes.io/restartedAt"] = datetime.utcnow().isoformat() # Apply the update to the deployment apps_v1.patch_namespaced_deployment( name=deployment_name, namespace=namespace, body=deployment ) return { "status": "success", "message": f"Deployment {deployment_name} triggered for rolling update successfully" }
Node.js Implementation (@kubernetes/client-node)
For Node.js, use the official Kubernetes client and follow similar logic:
const k8s = require('@kubernetes/client-node'); exports.handler = async (event) => { const kc = new k8s.KubeConfig(); kc.loadFromDefault(); // Uses Lambda's IAM role for EKS authentication const appsV1Api = kc.makeApiClient(k8s.AppsV1Api); // Update these values to match your deployment const deploymentName = "your-deployment-name"; const namespace = "default"; // Fetch the current deployment const deployment = await appsV1Api.readNamespacedDeployment(deploymentName, namespace); // Initialize annotations if missing if (!deployment.body.spec.template.metadata.annotations) { deployment.body.spec.template.metadata.annotations = {}; } // Add/update the restart trigger annotation deployment.body.spec.template.metadata.annotations["kubectl.kubernetes.io/restartedAt"] = new Date().toISOString(); // Apply the patch to trigger rolling update await appsV1Api.patchNamespacedDeployment( deploymentName, namespace, deployment.body ); return { statusCode: 200, body: JSON.stringify({ message: `Deployment ${deploymentName} is now rolling out with existing image tag` }) }; };
Key Notes
- IAM Permissions: Ensure your Lambda’s execution role has permissions to access your EKS cluster and update Deployments. The easiest way is to use IAM Roles for Service Accounts (IRSA) if your Lambda runs in EKS, or attach a policy with
eks:DescribeClusterand Kubernetes RBAC permissions fordeployments.apps/update. - Patch vs Replace: Using
patchinstead ofreplaceis safer — it only updates the annotation field instead of overwriting the entire Deployment configuration, avoiding accidental overwrites of other changes. - Custom Annotations: You don’t have to use the
kubectl.kubernetes.io/restartedAtannotation — any unique change to the pod template (like a custommyapp.com/restart-triggerannotation with a timestamp) will work. - Verify Rollout: To confirm the update is working, you can add logic to check the rollout status using
read_namespaced_deployment_status(Python) orreadNamespacedDeploymentStatus(Node.js) in your Lambda.
内容的提问来源于stack exchange,提问作者Edcel Cabrera Vista

