feat(deployment): add Kubernetes manifests for blue-green and canary deployments - #31
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Summary of ChangesHello @hoangsonww, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request fundamentally transforms the deployment capabilities of Fusion Electronics by integrating advanced Kubernetes deployment strategies. The primary goal is to enable zero-downtime releases, controlled feature rollouts, and rapid recovery mechanisms, thereby enhancing the reliability and operational efficiency of both frontend and backend services. The changes encompass new infrastructure-as-code definitions, a dedicated CI/CD pipeline, and comprehensive documentation to support these robust deployment practices. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
✅ Deploy Preview for mern-stack-ecommerce-website ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Code Review
This pull request introduces an impressive and comprehensive set of features for enterprise-grade Kubernetes deployments, including detailed documentation, manifests for blue-green and canary strategies, and a Jenkins CI/CD pipeline. The effort to build out this infrastructure is commendable. However, the current implementation has several critical security and functional issues that must be addressed before it can be considered production-ready. Key problems include a CI/CD pipeline that ignores security vulnerabilities, insecure handling of Docker credentials, broken deployment and rollback scripts, and Kubernetes manifests that do not follow security best practices or the intended ingress architecture. My review provides specific feedback and suggestions to fix these critical flaws.
| sh ''' | ||
| npm audit --audit-level=moderate || true | ||
| cd backend && npm audit --audit-level=moderate || true | ||
| ''' |
There was a problem hiding this comment.
The build pipeline is configured to ignore the results of the npm audit security scan by using || true. This is a significant security risk as it allows the pipeline to succeed even if moderate or high-severity vulnerabilities are found in the dependencies. To enforce a secure supply chain, the pipeline should fail if vulnerabilities are detected.
npm audit --audit-level=moderate
cd backend && npm audit --audit-level=moderate
| spec: | ||
| containers: | ||
| - name: backend | ||
| image: <DOCKER_REGISTRY>/fusion-electronics-backend:latest |
There was a problem hiding this comment.
Using the :latest tag for container images in production is a critical anti-pattern. It leads to unpredictable deployments and makes rollbacks unreliable because the image content can change independently of the tag. You should use immutable tags, such as the Git commit SHA or build number, which your Jenkinsfile already generates as BUILD_TAG. This comment applies to all other Kubernetes Deployment manifests in this pull request.
image: <DOCKER_REGISTRY>/fusion-electronics-backend:${BUILD_TAG}| get_active_environment() { | ||
| local service_selector=$(kubectl get service ${APP_NAME} -n ${NAMESPACE} -o jsonpath='{.spec.selector.version}' 2>/dev/null || echo "") | ||
|
|
||
| if [ -z "$service_selector" ]; then | ||
| echo "blue" # Default to blue | ||
| else | ||
| echo "$service_selector" | ||
| fi | ||
| } |
There was a problem hiding this comment.
This script is critically flawed. The get_active_environment function attempts to query a service named fusion-electronics, which does not exist. The services are named fusion-electronics-frontend and fusion-electronics-backend. Furthermore, the script's logic assumes a single application service, but it needs to manage both the frontend and backend services independently or in unison. As it stands, the script is non-functional.
| get_active_environment() { | |
| local service_selector=$(kubectl get service ${APP_NAME} -n ${NAMESPACE} -o jsonpath='{.spec.selector.version}' 2>/dev/null || echo "") | |
| if [ -z "$service_selector" ]; then | |
| echo "blue" # Default to blue | |
| else | |
| echo "$service_selector" | |
| fi | |
| } | |
| get_active_environment() { | |
| local component=$1 # e.g., "frontend" or "backend" | |
| local service_selector=$(kubectl get service ${APP_NAME}-${component} -n ${NAMESPACE} -o jsonpath='{.spec.selector.version}' 2>/dev/null || echo "") | |
| if [ -z "$service_selector" ]; then | |
| echo "blue" # Default to blue | |
| else | |
| echo "$service_selector" | |
| fi | |
| } |
| rollback_blue_green() { | ||
| log_warning "Rolling back blue-green deployment..." | ||
|
|
||
| # Determine current active environment | ||
| local active_env=$(kubectl get service ${APP_NAME}-frontend -n ${NAMESPACE} \ | ||
| -o jsonpath='{.spec.selector.version}' 2>/dev/null || echo "") | ||
|
|
||
| if [ -z "$active_env" ]; then | ||
| log_error "Cannot determine active environment" | ||
| return 1 | ||
| fi | ||
|
|
||
| log_info "Current active environment: ${active_env}" | ||
|
|
||
| # Switch to the other environment | ||
| if [ "$active_env" == "blue" ]; then | ||
| log_info "Switching back to GREEN environment..." | ||
| bash deployment/scripts/blue-green-deploy.sh switch-to-green | ||
| else | ||
| log_info "Switching back to BLUE environment..." | ||
| bash deployment/scripts/blue-green-deploy.sh switch-to-blue | ||
| fi | ||
|
|
||
| # Verify rollback | ||
| sleep 5 | ||
| local new_env=$(kubectl get service ${APP_NAME}-frontend -n ${NAMESPACE} \ | ||
| -o jsonpath='{.spec.selector.version}' 2>/dev/null || echo "") | ||
|
|
||
| if [ "$new_env" != "$active_env" ]; then | ||
| log_success "Successfully rolled back from ${active_env} to ${new_env}" | ||
| return 0 | ||
| else | ||
| log_error "Rollback failed - still on ${active_env} environment" | ||
| return 1 | ||
| fi | ||
| } |
There was a problem hiding this comment.
The rollback_blue_green function is critically flawed as it only attempts to roll back the frontend service and completely ignores the backend. This will leave the application in an inconsistent and broken state (e.g., a new frontend pointing to an old backend). The rollback logic must patch both the frontend and backend services to point to the previous stable version.
rollback_blue_green() {
log_warning "Rolling back blue-green deployment..."
local active_env=$(kubectl get service ${APP_NAME}-frontend -n ${NAMESPACE} \
-o jsonpath='{.spec.selector.version}' 2>/dev/null || echo "")
if [ -z "$active_env" ]; then
log_error "Cannot determine active environment"
return 1
fi
log_info "Current active environment: ${active_env}"
local target_env="blue"
if [ "$active_env" == "blue" ]; then
target_env="green"
fi
log_info "Switching back to ${target_env^^} environment..."
kubectl patch service ${APP_NAME}-frontend -n ${NAMESPACE} -p "{\"spec\":{\"selector\":{\"version\":\"${target_env}\"}}}"
kubectl patch service ${APP_NAME}-backend -n ${NAMESPACE} -p "{\"spec\":{\"selector\":{\"version\":\"${target_env}\"}}}"
# Verify rollback
sleep 5
local new_env=$(kubectl get service ${APP_NAME}-frontend -n ${NAMESPACE} \
-o jsonpath='{.spec.selector.version}' 2>/dev/null || echo "")
if [ "$new_env" == "$target_env" ]; then
log_success "Successfully rolled back from ${active_env} to ${new_env}"
return 0
else
log_error "Rollback failed - still on ${active_env} environment"
return 1
fi
}| script { | ||
| echo "Pushing Docker images to registry..." | ||
| sh """ | ||
| echo ${DOCKER_CREDENTIALS_PSW} | docker login ${DOCKER_REGISTRY} -u ${DOCKER_CREDENTIALS_USR} --password-stdin |
There was a problem hiding this comment.
Piping the Docker password to docker login via echo is insecure. This can expose the password in build logs, making it accessible to anyone with log access. A more secure method is to use the withDockerRegistry block provided by the Docker Pipeline plugin, which securely handles credential injection without exposing them in logs.
withDockerRegistry([credentialsId: 'docker-credentials', url: DOCKER_REGISTRY]) {
| resources: | ||
| requests: | ||
| cpu: 200m | ||
| memory: 512Mi | ||
| limits: | ||
| cpu: 1000m | ||
| memory: 1Gi |
There was a problem hiding this comment.
The container is configured to run as the root user by default, which is a major security risk. According to the principle of least privilege, you should define a securityContext to run the container as a non-root user and with a read-only root filesystem. This significantly reduces the potential impact of a container compromise. This should be applied to all Deployment manifests.
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
securityContext:
runAsNonRoot: true
runAsUser: 1001
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL| app: fusion-electronics | ||
| component: frontend | ||
| spec: | ||
| type: LoadBalancer |
There was a problem hiding this comment.
The service is defined with type: LoadBalancer, which exposes it directly to the internet via a cloud provider's load balancer. This contradicts the architecture described, where an Ingress controller is the intended entry point. Using LoadBalancer here is redundant, more costly, and bypasses Ingress-level rules (like rate limiting). The service type should be ClusterIP to make it accessible only within the cluster by the Ingress controller.
type: ClusterIP| app: fusion-electronics | ||
| component: backend | ||
| spec: | ||
| type: LoadBalancer |
There was a problem hiding this comment.
| nginx.ingress.kubernetes.io/limit-connections: "10" | ||
| # CORS | ||
| nginx.ingress.kubernetes.io/enable-cors: "true" | ||
| nginx.ingress.kubernetes.io/cors-allow-origin: "*" |
There was a problem hiding this comment.
The CORS annotation nginx.ingress.kubernetes.io/cors-allow-origin: "*" allows requests from any origin, which is a security vulnerability. This could enable malicious websites to make requests to your API on behalf of your users. You should restrict this to the specific domain of your frontend application.
nginx.ingress.kubernetes.io/cors-allow-origin: "https://fusion-electronics.com,https://www.fusion-electronics.com"
This pull request introduces comprehensive support for enterprise-grade Kubernetes deployments for Fusion Electronics, including blue-green and canary deployment strategies, robust CI/CD pipelines (Jenkins), and detailed infrastructure, monitoring, and rollback documentation. It also adds production-ready Kubernetes manifests for blue-green deployments of both frontend and backend services, with appropriate health checks and resource management. The documentation in
ARCHITECTURE.mdandCLAUDE.mdhas been significantly expanded to cover these new deployment architectures, strategies, and operational procedures.Kubernetes Deployment Architecture & Strategies
ARCHITECTURE.mdandCLAUDE.md. This covers high availability, multi-AZ setups, and traffic management. [1] [2]backend-blue-deployment.yaml,backend-green-deployment.yaml) and frontend (frontend-blue-deployment.yaml), each with three replicas, resource limits, Prometheus annotations, and health probes. [1] [2] [3]CI/CD Pipeline Enhancements
Infrastructure & Operational Documentation
Monitoring, Health Checks, and Rollback Procedures
Security Architecture
These changes collectively enable robust, scalable, and secure enterprise deployments for Fusion Electronics, with clear operational procedures and infrastructure-as-code support.