mirror of
https://github.com/wshobson/agents.git
synced 2026-03-18 09:37:15 +00:00
style: format all files with prettier
This commit is contained in:
@@ -7,11 +7,13 @@ model: opus
|
||||
You are a Kubernetes architect specializing in cloud-native infrastructure, modern GitOps workflows, and enterprise container orchestration at scale.
|
||||
|
||||
## Purpose
|
||||
|
||||
Expert Kubernetes architect with comprehensive knowledge of container orchestration, cloud-native technologies, and modern GitOps practices. Masters Kubernetes across all major providers (EKS, AKS, GKE) and on-premises deployments. Specializes in building scalable, secure, and cost-effective platform engineering solutions that enhance developer productivity.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Kubernetes Platform Expertise
|
||||
|
||||
- **Managed Kubernetes**: EKS (AWS), AKS (Azure), GKE (Google Cloud), advanced configuration and optimization
|
||||
- **Enterprise Kubernetes**: Red Hat OpenShift, Rancher, VMware Tanzu, platform-specific features
|
||||
- **Self-managed clusters**: kubeadm, kops, kubespray, bare-metal installations, air-gapped deployments
|
||||
@@ -19,6 +21,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- **Multi-cluster management**: Cluster API, fleet management, cluster federation, cross-cluster networking
|
||||
|
||||
### GitOps & Continuous Deployment
|
||||
|
||||
- **GitOps tools**: ArgoCD, Flux v2, Jenkins X, Tekton, advanced configuration and best practices
|
||||
- **OpenGitOps principles**: Declarative, versioned, automatically pulled, continuously reconciled
|
||||
- **Progressive delivery**: Argo Rollouts, Flagger, canary deployments, blue/green strategies, A/B testing
|
||||
@@ -26,6 +29,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- **Secret management**: External Secrets Operator, Sealed Secrets, HashiCorp Vault integration
|
||||
|
||||
### Modern Infrastructure as Code
|
||||
|
||||
- **Kubernetes-native IaC**: Helm 3.x, Kustomize, Jsonnet, cdk8s, Pulumi Kubernetes provider
|
||||
- **Cluster provisioning**: Terraform/OpenTofu modules, Cluster API, infrastructure automation
|
||||
- **Configuration management**: Advanced Helm patterns, Kustomize overlays, environment-specific configs
|
||||
@@ -33,6 +37,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- **GitOps workflows**: Automated testing, validation pipelines, drift detection and remediation
|
||||
|
||||
### Cloud-Native Security
|
||||
|
||||
- **Pod Security Standards**: Restricted, baseline, privileged policies, migration strategies
|
||||
- **Network security**: Network policies, service mesh security, micro-segmentation
|
||||
- **Runtime security**: Falco, Sysdig, Aqua Security, runtime threat detection
|
||||
@@ -41,6 +46,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- **Compliance**: CIS benchmarks, NIST frameworks, regulatory compliance automation
|
||||
|
||||
### Service Mesh Architecture
|
||||
|
||||
- **Istio**: Advanced traffic management, security policies, observability, multi-cluster mesh
|
||||
- **Linkerd**: Lightweight service mesh, automatic mTLS, traffic splitting
|
||||
- **Cilium**: eBPF-based networking, network policies, load balancing
|
||||
@@ -48,6 +54,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- **Gateway API**: Next-generation ingress, traffic routing, protocol support
|
||||
|
||||
### Container & Image Management
|
||||
|
||||
- **Container runtimes**: containerd, CRI-O, Docker runtime considerations
|
||||
- **Registry strategies**: Harbor, ECR, ACR, GCR, multi-region replication
|
||||
- **Image optimization**: Multi-stage builds, distroless images, security scanning
|
||||
@@ -55,6 +62,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- **Artifact management**: OCI artifacts, Helm chart repositories, policy distribution
|
||||
|
||||
### Observability & Monitoring
|
||||
|
||||
- **Metrics**: Prometheus, VictoriaMetrics, Thanos for long-term storage
|
||||
- **Logging**: Fluentd, Fluent Bit, Loki, centralized logging strategies
|
||||
- **Tracing**: Jaeger, Zipkin, OpenTelemetry, distributed tracing patterns
|
||||
@@ -62,6 +70,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- **APM integration**: DataDog, New Relic, Dynatrace Kubernetes-specific monitoring
|
||||
|
||||
### Multi-Tenancy & Platform Engineering
|
||||
|
||||
- **Namespace strategies**: Multi-tenancy patterns, resource isolation, network segmentation
|
||||
- **RBAC design**: Advanced authorization, service accounts, cluster roles, namespace roles
|
||||
- **Resource management**: Resource quotas, limit ranges, priority classes, QoS classes
|
||||
@@ -69,6 +78,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- **Operator development**: Custom Resource Definitions (CRDs), controller patterns, Operator SDK
|
||||
|
||||
### Scalability & Performance
|
||||
|
||||
- **Cluster autoscaling**: Horizontal Pod Autoscaler (HPA), Vertical Pod Autoscaler (VPA), Cluster Autoscaler
|
||||
- **Custom metrics**: KEDA for event-driven autoscaling, custom metrics APIs
|
||||
- **Performance tuning**: Node optimization, resource allocation, CPU/memory management
|
||||
@@ -76,6 +86,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- **Storage**: Persistent volumes, storage classes, CSI drivers, data management
|
||||
|
||||
### Cost Optimization & FinOps
|
||||
|
||||
- **Resource optimization**: Right-sizing workloads, spot instances, reserved capacity
|
||||
- **Cost monitoring**: KubeCost, OpenCost, native cloud cost allocation
|
||||
- **Bin packing**: Node utilization optimization, workload density
|
||||
@@ -83,18 +94,21 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- **Multi-cloud cost**: Cross-provider cost analysis, workload placement optimization
|
||||
|
||||
### Disaster Recovery & Business Continuity
|
||||
|
||||
- **Backup strategies**: Velero, cloud-native backup solutions, cross-region backups
|
||||
- **Multi-region deployment**: Active-active, active-passive, traffic routing
|
||||
- **Chaos engineering**: Chaos Monkey, Litmus, fault injection testing
|
||||
- **Recovery procedures**: RTO/RPO planning, automated failover, disaster recovery testing
|
||||
|
||||
## OpenGitOps Principles (CNCF)
|
||||
|
||||
1. **Declarative** - Entire system described declaratively with desired state
|
||||
2. **Versioned and Immutable** - Desired state stored in Git with complete version history
|
||||
3. **Pulled Automatically** - Software agents automatically pull desired state from Git
|
||||
4. **Continuously Reconciled** - Agents continuously observe and reconcile actual vs desired state
|
||||
|
||||
## Behavioral Traits
|
||||
|
||||
- Champions Kubernetes-first approaches while recognizing appropriate use cases
|
||||
- Implements GitOps from project inception, not as an afterthought
|
||||
- Prioritizes developer experience and platform usability
|
||||
@@ -107,6 +121,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- Considers compliance and governance requirements in architecture decisions
|
||||
|
||||
## Knowledge Base
|
||||
|
||||
- Kubernetes architecture and component interactions
|
||||
- CNCF landscape and cloud-native technology ecosystem
|
||||
- GitOps patterns and best practices
|
||||
@@ -118,6 +133,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- Modern CI/CD practices and pipeline security
|
||||
|
||||
## Response Approach
|
||||
|
||||
1. **Assess workload requirements** for container orchestration needs
|
||||
2. **Design Kubernetes architecture** appropriate for scale and complexity
|
||||
3. **Implement GitOps workflows** with proper repository structure and automation
|
||||
@@ -129,6 +145,7 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
9. **Document platform** with clear operational procedures and developer guides
|
||||
|
||||
## Example Interactions
|
||||
|
||||
- "Design a multi-cluster Kubernetes platform with GitOps for a financial services company"
|
||||
- "Implement progressive delivery with Argo Rollouts and service mesh traffic splitting"
|
||||
- "Create a secure multi-tenant Kubernetes platform with namespace isolation and RBAC"
|
||||
@@ -136,4 +153,4 @@ Expert Kubernetes architect with comprehensive knowledge of container orchestrat
|
||||
- "Optimize Kubernetes costs while maintaining performance and availability SLAs"
|
||||
- "Implement observability stack with Prometheus, Grafana, and OpenTelemetry for microservices"
|
||||
- "Create CI/CD pipeline with GitOps for container applications with security scanning"
|
||||
- "Design Kubernetes operator for custom application lifecycle management"
|
||||
- "Design Kubernetes operator for custom application lifecycle management"
|
||||
|
||||
@@ -87,7 +87,7 @@ spec:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- CreateNamespace=true
|
||||
```
|
||||
|
||||
### 4. App of Apps Pattern
|
||||
@@ -165,11 +165,12 @@ spec:
|
||||
### Auto-Sync Configuration
|
||||
|
||||
**ArgoCD:**
|
||||
|
||||
```yaml
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true # Delete resources not in Git
|
||||
selfHeal: true # Reconcile manual changes
|
||||
prune: true # Delete resources not in Git
|
||||
selfHeal: true # Reconcile manual changes
|
||||
allowEmpty: false
|
||||
retry:
|
||||
limit: 5
|
||||
@@ -180,6 +181,7 @@ syncPolicy:
|
||||
```
|
||||
|
||||
**Flux:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
interval: 1m
|
||||
@@ -204,11 +206,11 @@ spec:
|
||||
strategy:
|
||||
canary:
|
||||
steps:
|
||||
- setWeight: 20
|
||||
- pause: {duration: 1m}
|
||||
- setWeight: 50
|
||||
- pause: {duration: 2m}
|
||||
- setWeight: 100
|
||||
- setWeight: 20
|
||||
- pause: { duration: 1m }
|
||||
- setWeight: 50
|
||||
- pause: { duration: 2m }
|
||||
- setWeight: 100
|
||||
```
|
||||
|
||||
### Blue-Green Deployment
|
||||
@@ -238,9 +240,9 @@ spec:
|
||||
target:
|
||||
name: db-credentials
|
||||
data:
|
||||
- secretKey: password
|
||||
remoteRef:
|
||||
key: prod/db/password
|
||||
- secretKey: password
|
||||
remoteRef:
|
||||
key: prod/db/password
|
||||
```
|
||||
|
||||
### Sealed Secrets
|
||||
@@ -268,12 +270,14 @@ kubeseal --format yaml < secret.yaml > sealed-secret.yaml
|
||||
## Troubleshooting
|
||||
|
||||
**Sync failures:**
|
||||
|
||||
```bash
|
||||
argocd app get my-app
|
||||
argocd app sync my-app --prune
|
||||
```
|
||||
|
||||
**Out of sync status:**
|
||||
|
||||
```bash
|
||||
argocd app diff my-app
|
||||
argocd app sync my-app --force
|
||||
|
||||
@@ -3,17 +3,20 @@
|
||||
## Installation Methods
|
||||
|
||||
### 1. Standard Installation
|
||||
|
||||
```bash
|
||||
kubectl create namespace argocd
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
|
||||
```
|
||||
|
||||
### 2. High Availability Installation
|
||||
|
||||
```bash
|
||||
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/ha/install.yaml
|
||||
```
|
||||
|
||||
### 3. Helm Installation
|
||||
|
||||
```bash
|
||||
helm repo add argo https://argoproj.github.io/argo-helm
|
||||
helm install argocd argo/argo-cd -n argocd --create-namespace
|
||||
@@ -22,6 +25,7 @@ helm install argocd argo/argo-cd -n argocd --create-namespace
|
||||
## Initial Configuration
|
||||
|
||||
### Access ArgoCD UI
|
||||
|
||||
```bash
|
||||
# Port forward
|
||||
kubectl port-forward svc/argocd-server -n argocd 8080:443
|
||||
@@ -31,6 +35,7 @@ argocd admin initial-password -n argocd
|
||||
```
|
||||
|
||||
### Configure Ingress
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
@@ -44,35 +49,38 @@ metadata:
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: argocd.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: argocd-server
|
||||
port:
|
||||
number: 443
|
||||
- host: argocd.example.com
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: argocd-server
|
||||
port:
|
||||
number: 443
|
||||
tls:
|
||||
- hosts:
|
||||
- argocd.example.com
|
||||
secretName: argocd-secret
|
||||
- hosts:
|
||||
- argocd.example.com
|
||||
secretName: argocd-secret
|
||||
```
|
||||
|
||||
## CLI Configuration
|
||||
|
||||
### Login
|
||||
|
||||
```bash
|
||||
argocd login argocd.example.com --username admin
|
||||
```
|
||||
|
||||
### Add Repository
|
||||
|
||||
```bash
|
||||
argocd repo add https://github.com/org/repo --username user --password token
|
||||
```
|
||||
|
||||
### Create Application
|
||||
|
||||
```bash
|
||||
argocd app create my-app \
|
||||
--repo https://github.com/org/repo \
|
||||
@@ -84,6 +92,7 @@ argocd app create my-app \
|
||||
## SSO Configuration
|
||||
|
||||
### GitHub OAuth
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
@@ -105,6 +114,7 @@ data:
|
||||
```
|
||||
|
||||
## RBAC Configuration
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
|
||||
@@ -3,38 +3,42 @@
|
||||
## ArgoCD Sync Policies
|
||||
|
||||
### Automated Sync
|
||||
|
||||
```yaml
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true # Delete resources removed from Git
|
||||
selfHeal: true # Reconcile manual changes
|
||||
prune: true # Delete resources removed from Git
|
||||
selfHeal: true # Reconcile manual changes
|
||||
allowEmpty: false # Prevent empty sync
|
||||
```
|
||||
|
||||
### Manual Sync
|
||||
|
||||
```yaml
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- PrunePropagationPolicy=foreground
|
||||
- CreateNamespace=true
|
||||
- PrunePropagationPolicy=foreground
|
||||
- CreateNamespace=true
|
||||
```
|
||||
|
||||
### Sync Windows
|
||||
|
||||
```yaml
|
||||
syncWindows:
|
||||
- kind: allow
|
||||
schedule: "0 8 * * *"
|
||||
duration: 1h
|
||||
applications:
|
||||
- my-app
|
||||
- kind: deny
|
||||
schedule: "0 22 * * *"
|
||||
duration: 8h
|
||||
applications:
|
||||
- '*'
|
||||
- kind: allow
|
||||
schedule: "0 8 * * *"
|
||||
duration: 1h
|
||||
applications:
|
||||
- my-app
|
||||
- kind: deny
|
||||
schedule: "0 22 * * *"
|
||||
duration: 8h
|
||||
applications:
|
||||
- "*"
|
||||
```
|
||||
|
||||
### Retry Policy
|
||||
|
||||
```yaml
|
||||
syncPolicy:
|
||||
retry:
|
||||
@@ -48,6 +52,7 @@ syncPolicy:
|
||||
## Flux Sync Policies
|
||||
|
||||
### Kustomization Sync
|
||||
|
||||
```yaml
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
@@ -63,6 +68,7 @@ spec:
|
||||
```
|
||||
|
||||
### Source Sync Interval
|
||||
|
||||
```yaml
|
||||
apiVersion: source.toolkit.fluxcd.io/v1
|
||||
kind: GitRepository
|
||||
@@ -76,6 +82,7 @@ spec:
|
||||
## Health Assessment
|
||||
|
||||
### Custom Health Checks
|
||||
|
||||
```yaml
|
||||
# ArgoCD
|
||||
apiVersion: v1
|
||||
@@ -110,6 +117,7 @@ data:
|
||||
## Sync Options
|
||||
|
||||
### Common Sync Options
|
||||
|
||||
- `PrunePropagationPolicy=foreground` - Wait for pruned resources to be deleted
|
||||
- `CreateNamespace=true` - Auto-create namespace
|
||||
- `Validate=false` - Skip kubectl validation
|
||||
|
||||
@@ -14,6 +14,7 @@ This skill provides step-by-step instructions for building production-ready Helm
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
|
||||
- Create new Helm charts from scratch
|
||||
- Package Kubernetes applications for distribution
|
||||
- Manage multi-environment deployments with Helm
|
||||
@@ -24,6 +25,7 @@ Use this skill when you need to:
|
||||
## Helm Overview
|
||||
|
||||
**Helm** is the package manager for Kubernetes that:
|
||||
|
||||
- Templates Kubernetes manifests for reusability
|
||||
- Manages application releases and rollbacks
|
||||
- Handles dependencies between charts
|
||||
@@ -35,11 +37,13 @@ Use this skill when you need to:
|
||||
### 1. Initialize Chart Structure
|
||||
|
||||
**Create new chart:**
|
||||
|
||||
```bash
|
||||
helm create my-app
|
||||
```
|
||||
|
||||
**Standard chart structure:**
|
||||
|
||||
```
|
||||
my-app/
|
||||
├── Chart.yaml # Chart metadata
|
||||
@@ -67,7 +71,7 @@ apiVersion: v2
|
||||
name: my-app
|
||||
description: A Helm chart for My Application
|
||||
type: application
|
||||
version: 1.0.0 # Chart version
|
||||
version: 1.0.0 # Chart version
|
||||
appVersion: "2.1.0" # Application version
|
||||
|
||||
# Keywords for chart discovery
|
||||
@@ -180,6 +184,7 @@ redis:
|
||||
**Use Go templating with Helm functions:**
|
||||
|
||||
**templates/deployment.yaml:**
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@@ -214,7 +219,8 @@ spec:
|
||||
|
||||
### 5. Create Template Helpers
|
||||
|
||||
**templates/_helpers.tpl:**
|
||||
**templates/\_helpers.tpl:**
|
||||
|
||||
```yaml
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
@@ -263,6 +269,7 @@ app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
### 6. Manage Dependencies
|
||||
|
||||
**Add dependencies in Chart.yaml:**
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
@@ -272,12 +279,14 @@ dependencies:
|
||||
```
|
||||
|
||||
**Update dependencies:**
|
||||
|
||||
```bash
|
||||
helm dependency update
|
||||
helm dependency build
|
||||
```
|
||||
|
||||
**Override dependency values:**
|
||||
|
||||
```yaml
|
||||
# values.yaml
|
||||
postgresql:
|
||||
@@ -295,6 +304,7 @@ postgresql:
|
||||
### 7. Test and Validate
|
||||
|
||||
**Validation commands:**
|
||||
|
||||
```bash
|
||||
# Lint the chart
|
||||
helm lint my-app/
|
||||
@@ -313,6 +323,7 @@ helm show values ./my-app
|
||||
```
|
||||
|
||||
**Validation script:**
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e
|
||||
@@ -334,12 +345,14 @@ echo "All validations passed!"
|
||||
### 8. Package and Distribute
|
||||
|
||||
**Package the chart:**
|
||||
|
||||
```bash
|
||||
helm package my-app/
|
||||
# Creates: my-app-1.0.0.tgz
|
||||
```
|
||||
|
||||
**Create chart repository:**
|
||||
|
||||
```bash
|
||||
# Create index
|
||||
helm repo index .
|
||||
@@ -350,6 +363,7 @@ aws s3 sync . s3://my-helm-charts/ --exclude "*" --include "*.tgz" --include "in
|
||||
```
|
||||
|
||||
**Use the chart:**
|
||||
|
||||
```bash
|
||||
helm repo add my-repo https://charts.example.com
|
||||
helm repo update
|
||||
@@ -369,6 +383,7 @@ my-app/
|
||||
```
|
||||
|
||||
**values-prod.yaml:**
|
||||
|
||||
```yaml
|
||||
replicaCount: 5
|
||||
|
||||
@@ -404,6 +419,7 @@ postgresql:
|
||||
```
|
||||
|
||||
**Install with environment:**
|
||||
|
||||
```bash
|
||||
helm install my-app ./my-app -f values-prod.yaml --namespace production
|
||||
```
|
||||
@@ -411,6 +427,7 @@ helm install my-app ./my-app -f values-prod.yaml --namespace production
|
||||
### 10. Implement Hooks and Tests
|
||||
|
||||
**Pre-install hook:**
|
||||
|
||||
```yaml
|
||||
# templates/pre-install-job.yaml
|
||||
apiVersion: batch/v1
|
||||
@@ -432,6 +449,7 @@ spec:
|
||||
```
|
||||
|
||||
**Test connection:**
|
||||
|
||||
```yaml
|
||||
# templates/tests/test-connection.yaml
|
||||
apiVersion: v1
|
||||
@@ -450,6 +468,7 @@ spec:
|
||||
```
|
||||
|
||||
**Run tests:**
|
||||
|
||||
```bash
|
||||
helm test my-app
|
||||
```
|
||||
@@ -515,17 +534,20 @@ image: {{ .Values.global.imageRegistry }}/{{ .Values.image.repository }}
|
||||
## Troubleshooting
|
||||
|
||||
**Template rendering errors:**
|
||||
|
||||
```bash
|
||||
helm template my-app ./my-app --debug
|
||||
```
|
||||
|
||||
**Dependency issues:**
|
||||
|
||||
```bash
|
||||
helm dependency update
|
||||
helm dependency list
|
||||
```
|
||||
|
||||
**Installation failures:**
|
||||
|
||||
```bash
|
||||
helm install my-app ./my-app --dry-run --debug
|
||||
kubectl get events --sort-by='.lastTimestamp'
|
||||
|
||||
@@ -41,29 +41,29 @@ my-app/
|
||||
### API Version v2 (Helm 3+)
|
||||
|
||||
```yaml
|
||||
apiVersion: v2 # Required: API version
|
||||
name: my-application # Required: Chart name
|
||||
version: 1.2.3 # Required: Chart version (SemVer)
|
||||
appVersion: "2.5.0" # Application version
|
||||
description: A Helm chart for my application # Required
|
||||
type: application # Chart type: application or library
|
||||
keywords: # Search keywords
|
||||
apiVersion: v2 # Required: API version
|
||||
name: my-application # Required: Chart name
|
||||
version: 1.2.3 # Required: Chart version (SemVer)
|
||||
appVersion: "2.5.0" # Application version
|
||||
description: A Helm chart for my application # Required
|
||||
type: application # Chart type: application or library
|
||||
keywords: # Search keywords
|
||||
- web
|
||||
- api
|
||||
- backend
|
||||
home: https://example.com # Project home page
|
||||
sources: # Source code URLs
|
||||
home: https://example.com # Project home page
|
||||
sources: # Source code URLs
|
||||
- https://github.com/example/my-app
|
||||
maintainers: # Maintainer list
|
||||
maintainers: # Maintainer list
|
||||
- name: John Doe
|
||||
email: john@example.com
|
||||
url: https://github.com/johndoe
|
||||
icon: https://example.com/icon.png # Chart icon URL
|
||||
kubeVersion: ">=1.24.0" # Compatible Kubernetes versions
|
||||
deprecated: false # Mark chart as deprecated
|
||||
annotations: # Arbitrary annotations
|
||||
icon: https://example.com/icon.png # Chart icon URL
|
||||
kubeVersion: ">=1.24.0" # Compatible Kubernetes versions
|
||||
deprecated: false # Mark chart as deprecated
|
||||
annotations: # Arbitrary annotations
|
||||
example.com/release-notes: https://example.com/releases/v1.2.3
|
||||
dependencies: # Chart dependencies
|
||||
dependencies: # Chart dependencies
|
||||
- name: postgresql
|
||||
version: "12.0.0"
|
||||
repository: "https://charts.bitnami.com/bitnami"
|
||||
@@ -79,17 +79,21 @@ dependencies: # Chart dependencies
|
||||
## Chart Types
|
||||
|
||||
### Application Chart
|
||||
|
||||
```yaml
|
||||
type: application
|
||||
```
|
||||
|
||||
- Standard Kubernetes applications
|
||||
- Can be installed and managed
|
||||
- Contains templates for K8s resources
|
||||
|
||||
### Library Chart
|
||||
|
||||
```yaml
|
||||
type: library
|
||||
```
|
||||
|
||||
- Shared template helpers
|
||||
- Cannot be installed directly
|
||||
- Used as dependency by other charts
|
||||
@@ -98,6 +102,7 @@ type: library
|
||||
## Values Files Organization
|
||||
|
||||
### values.yaml (defaults)
|
||||
|
||||
```yaml
|
||||
# Global values (shared with subcharts)
|
||||
global:
|
||||
@@ -108,7 +113,7 @@ global:
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: myapp/web
|
||||
tag: "" # Defaults to .Chart.AppVersion
|
||||
tag: "" # Defaults to .Chart.AppVersion
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# Deployment settings
|
||||
@@ -128,7 +133,7 @@ securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
- ALL
|
||||
|
||||
# Service
|
||||
service:
|
||||
@@ -165,6 +170,7 @@ serviceMonitor:
|
||||
```
|
||||
|
||||
### values.schema.json (validation)
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft-07/schema#",
|
||||
@@ -206,7 +212,8 @@ serviceMonitor:
|
||||
|
||||
### Common Templates
|
||||
|
||||
#### _helpers.tpl
|
||||
#### \_helpers.tpl
|
||||
|
||||
```yaml
|
||||
{{/*
|
||||
Standard naming helpers
|
||||
@@ -261,6 +268,7 @@ Image name helper
|
||||
```
|
||||
|
||||
#### NOTES.txt
|
||||
|
||||
```
|
||||
Thank you for installing {{ .Chart.Name }}.
|
||||
|
||||
@@ -296,13 +304,13 @@ dependencies:
|
||||
- name: postgresql
|
||||
version: "12.0.0"
|
||||
repository: "https://charts.bitnami.com/bitnami"
|
||||
condition: postgresql.enabled # Enable/disable via values
|
||||
tags: # Group dependencies
|
||||
condition: postgresql.enabled # Enable/disable via values
|
||||
tags: # Group dependencies
|
||||
- database
|
||||
import-values: # Import values from subchart
|
||||
import-values: # Import values from subchart
|
||||
- child: database
|
||||
parent: database
|
||||
alias: db # Reference as .Values.db
|
||||
alias: db # Reference as .Values.db
|
||||
```
|
||||
|
||||
### Managing Dependencies
|
||||
@@ -324,9 +332,9 @@ Generated automatically by `helm dependency update`:
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
version: 12.0.0
|
||||
- name: postgresql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
version: 12.0.0
|
||||
digest: sha256:abcd1234...
|
||||
generated: "2024-01-01T00:00:00Z"
|
||||
```
|
||||
@@ -374,6 +382,7 @@ crds/
|
||||
```
|
||||
|
||||
**Important CRD notes:**
|
||||
|
||||
- CRDs are installed before any templates
|
||||
- CRDs are NOT templated (no `{{ }}` syntax)
|
||||
- CRDs are NOT upgraded or deleted with chart
|
||||
@@ -393,7 +402,7 @@ crds/
|
||||
- Not required to follow SemVer
|
||||
|
||||
```yaml
|
||||
version: 2.3.1 # Chart version
|
||||
version: 2.3.1 # Chart version
|
||||
appVersion: "1.5.0" # Application version
|
||||
```
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ This skill provides comprehensive guidance for generating well-structured, secur
|
||||
## When to Use This Skill
|
||||
|
||||
Use this skill when you need to:
|
||||
|
||||
- Create new Kubernetes Deployment manifests
|
||||
- Define Service resources for network connectivity
|
||||
- Generate ConfigMap and Secret resources for configuration management
|
||||
@@ -27,6 +28,7 @@ Use this skill when you need to:
|
||||
### 1. Gather Requirements
|
||||
|
||||
**Understand the workload:**
|
||||
|
||||
- Application type (stateless/stateful)
|
||||
- Container image and version
|
||||
- Environment variables and configuration needs
|
||||
@@ -37,6 +39,7 @@ Use this skill when you need to:
|
||||
- Health check endpoints
|
||||
|
||||
**Questions to ask:**
|
||||
|
||||
- What is the application name and purpose?
|
||||
- What container image and tag will be used?
|
||||
- Does the application need persistent storage?
|
||||
@@ -70,41 +73,42 @@ spec:
|
||||
version: <version>
|
||||
spec:
|
||||
containers:
|
||||
- name: <container-name>
|
||||
image: <image>:<tag>
|
||||
ports:
|
||||
- containerPort: <port>
|
||||
name: http
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "250m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
env:
|
||||
- name: ENV_VAR
|
||||
value: "value"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: <app-name>-config
|
||||
- secretRef:
|
||||
name: <app-name>-secret
|
||||
- name: <container-name>
|
||||
image: <image>:<tag>
|
||||
ports:
|
||||
- containerPort: <port>
|
||||
name: http
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "250m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
env:
|
||||
- name: ENV_VAR
|
||||
value: "value"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: <app-name>-config
|
||||
- secretRef:
|
||||
name: <app-name>-secret
|
||||
```
|
||||
|
||||
**Best practices to apply:**
|
||||
|
||||
- Always set resource requests and limits
|
||||
- Implement both liveness and readiness probes
|
||||
- Use specific image tags (never `:latest`)
|
||||
@@ -119,6 +123,7 @@ spec:
|
||||
**Choose the appropriate Service type:**
|
||||
|
||||
**ClusterIP (internal only):**
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -132,13 +137,14 @@ spec:
|
||||
selector:
|
||||
app: <app-name>
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
```
|
||||
|
||||
**LoadBalancer (external access):**
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -154,10 +160,10 @@ spec:
|
||||
selector:
|
||||
app: <app-name>
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
```
|
||||
|
||||
**Reference:** See `references/service-spec.md` for service types and networking
|
||||
@@ -184,6 +190,7 @@ data:
|
||||
```
|
||||
|
||||
**Best practices:**
|
||||
|
||||
- Use ConfigMaps for non-sensitive data only
|
||||
- Organize related configuration together
|
||||
- Use meaningful names for keys
|
||||
@@ -218,6 +225,7 @@ stringData:
|
||||
```
|
||||
|
||||
**Security considerations:**
|
||||
|
||||
- Never commit secrets to Git in plain text
|
||||
- Use Sealed Secrets, External Secrets Operator, or Vault
|
||||
- Rotate secrets regularly
|
||||
@@ -236,7 +244,7 @@ metadata:
|
||||
namespace: <namespace>
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
- ReadWriteOnce
|
||||
storageClassName: gp3
|
||||
resources:
|
||||
requests:
|
||||
@@ -244,22 +252,24 @@ spec:
|
||||
```
|
||||
|
||||
**Mount in Deployment:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: app
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/app
|
||||
- name: app
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/app
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: <app-name>-data
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: <app-name>-data
|
||||
```
|
||||
|
||||
**Storage considerations:**
|
||||
|
||||
- Choose appropriate StorageClass for performance needs
|
||||
- Use ReadWriteOnce for single-pod access
|
||||
- Use ReadWriteMany for multi-pod shared storage
|
||||
@@ -281,16 +291,17 @@ spec:
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: app
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
- name: app
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
```
|
||||
|
||||
**Security checklist:**
|
||||
|
||||
- [ ] Run as non-root user
|
||||
- [ ] Drop all capabilities
|
||||
- [ ] Use read-only root filesystem
|
||||
@@ -330,6 +341,7 @@ metadata:
|
||||
**File organization options:**
|
||||
|
||||
**Option 1: Single file with `---` separator**
|
||||
|
||||
```yaml
|
||||
# app-name.yaml
|
||||
---
|
||||
@@ -351,6 +363,7 @@ kind: Service
|
||||
```
|
||||
|
||||
**Option 2: Separate files**
|
||||
|
||||
```
|
||||
manifests/
|
||||
├── configmap.yaml
|
||||
@@ -361,6 +374,7 @@ manifests/
|
||||
```
|
||||
|
||||
**Option 3: Kustomize structure**
|
||||
|
||||
```
|
||||
base/
|
||||
├── kustomization.yaml
|
||||
@@ -396,6 +410,7 @@ kube-linter lint manifest.yaml
|
||||
```
|
||||
|
||||
**Testing checklist:**
|
||||
|
||||
- [ ] Manifest passes dry-run validation
|
||||
- [ ] All required fields are present
|
||||
- [ ] Resource limits are reasonable
|
||||
@@ -411,6 +426,7 @@ kube-linter lint manifest.yaml
|
||||
**Use case:** Standard web API or microservice
|
||||
|
||||
**Components needed:**
|
||||
|
||||
- Deployment (3 replicas for HA)
|
||||
- ClusterIP Service
|
||||
- ConfigMap for configuration
|
||||
@@ -424,6 +440,7 @@ kube-linter lint manifest.yaml
|
||||
**Use case:** Database or persistent storage application
|
||||
|
||||
**Components needed:**
|
||||
|
||||
- StatefulSet (not Deployment)
|
||||
- Headless Service
|
||||
- PersistentVolumeClaim template
|
||||
@@ -435,6 +452,7 @@ kube-linter lint manifest.yaml
|
||||
**Use case:** Scheduled tasks or batch processing
|
||||
|
||||
**Components needed:**
|
||||
|
||||
- CronJob or Job
|
||||
- ConfigMap for job parameters
|
||||
- Secret for credentials
|
||||
@@ -445,6 +463,7 @@ kube-linter lint manifest.yaml
|
||||
**Use case:** Application with sidecar containers
|
||||
|
||||
**Components needed:**
|
||||
|
||||
- Deployment with multiple containers
|
||||
- Shared volumes between containers
|
||||
- Init containers for setup
|
||||
@@ -481,16 +500,19 @@ The following templates are available in the `assets/` directory:
|
||||
## Troubleshooting
|
||||
|
||||
**Pods not starting:**
|
||||
|
||||
- Check image pull errors: `kubectl describe pod <pod-name>`
|
||||
- Verify resource availability: `kubectl get nodes`
|
||||
- Check events: `kubectl get events --sort-by='.lastTimestamp'`
|
||||
|
||||
**Service not accessible:**
|
||||
|
||||
- Verify selector matches pod labels: `kubectl get endpoints <service-name>`
|
||||
- Check service type and port configuration
|
||||
- Test from within cluster: `kubectl run debug --rm -it --image=busybox -- sh`
|
||||
|
||||
**ConfigMap/Secret not loading:**
|
||||
|
||||
- Verify names match in Deployment
|
||||
- Check namespace
|
||||
- Ensure resources exist: `kubectl get configmap,secret`
|
||||
@@ -498,6 +520,7 @@ The following templates are available in the `assets/` directory:
|
||||
## Next Steps
|
||||
|
||||
After creating manifests:
|
||||
|
||||
1. Store in Git repository
|
||||
2. Set up CI/CD pipeline for deployment
|
||||
3. Consider using Helm or Kustomize for templating
|
||||
|
||||
@@ -69,143 +69,144 @@ spec:
|
||||
|
||||
# Init containers run before main containers
|
||||
initContainers:
|
||||
- name: init-db
|
||||
image: busybox:1.36
|
||||
command: ['sh', '-c', 'until nc -z db-service 5432; do sleep 1; done']
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
- name: init-db
|
||||
image: busybox:1.36
|
||||
command: ["sh", "-c", "until nc -z db-service 5432; do sleep 1; done"]
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
|
||||
# Main containers
|
||||
containers:
|
||||
- name: app
|
||||
image: myapp:1.0.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
- name: app
|
||||
image: myapp:1.0.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
|
||||
# Container ports
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
- name: metrics
|
||||
containerPort: 9090
|
||||
protocol: TCP
|
||||
# Container ports
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
- name: metrics
|
||||
containerPort: 9090
|
||||
protocol: TCP
|
||||
|
||||
# Environment variables
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: url
|
||||
# Environment variables
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: url
|
||||
|
||||
# ConfigMap and Secret references
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: app-config
|
||||
- secretRef:
|
||||
name: app-secrets
|
||||
# ConfigMap and Secret references
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: app-config
|
||||
- secretRef:
|
||||
name: app-secrets
|
||||
|
||||
# Resource requests and limits
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "250m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
# Resource requests and limits
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "250m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
|
||||
# Liveness probe
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health/live
|
||||
port: http
|
||||
httpHeaders:
|
||||
- name: Custom-Header
|
||||
value: Awesome
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
successThreshold: 1
|
||||
failureThreshold: 3
|
||||
# Liveness probe
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health/live
|
||||
port: http
|
||||
httpHeaders:
|
||||
- name: Custom-Header
|
||||
value: Awesome
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
successThreshold: 1
|
||||
failureThreshold: 3
|
||||
|
||||
# Readiness probe
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health/ready
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
successThreshold: 1
|
||||
failureThreshold: 3
|
||||
# Readiness probe
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health/ready
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
successThreshold: 1
|
||||
failureThreshold: 3
|
||||
|
||||
# Startup probe (for slow-starting containers)
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health/startup
|
||||
port: http
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
successThreshold: 1
|
||||
failureThreshold: 30
|
||||
# Startup probe (for slow-starting containers)
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health/startup
|
||||
port: http
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
successThreshold: 1
|
||||
failureThreshold: 30
|
||||
|
||||
# Volume mounts
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/app
|
||||
- name: config
|
||||
mountPath: /etc/app
|
||||
readOnly: true
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
# Volume mounts
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/app
|
||||
- name: config
|
||||
mountPath: /etc/app
|
||||
readOnly: true
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
|
||||
# Security context for container
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
# Security context for container
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
|
||||
# Lifecycle hooks
|
||||
lifecycle:
|
||||
postStart:
|
||||
exec:
|
||||
command: ["/bin/sh", "-c", "echo Container started > /tmp/started"]
|
||||
preStop:
|
||||
exec:
|
||||
command: ["/bin/sh", "-c", "sleep 15"]
|
||||
# Lifecycle hooks
|
||||
lifecycle:
|
||||
postStart:
|
||||
exec:
|
||||
command:
|
||||
["/bin/sh", "-c", "echo Container started > /tmp/started"]
|
||||
preStop:
|
||||
exec:
|
||||
command: ["/bin/sh", "-c", "sleep 15"]
|
||||
|
||||
# Volumes
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: app-data
|
||||
- name: config
|
||||
configMap:
|
||||
name: app-config
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: app-data
|
||||
- name: config
|
||||
configMap:
|
||||
name: app-config
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
|
||||
# DNS configuration
|
||||
dnsPolicy: ClusterFirst
|
||||
dnsConfig:
|
||||
options:
|
||||
- name: ndots
|
||||
value: "2"
|
||||
- name: ndots
|
||||
value: "2"
|
||||
|
||||
# Scheduling
|
||||
nodeSelector:
|
||||
@@ -214,28 +215,28 @@ spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- my-app
|
||||
topologyKey: kubernetes.io/hostname
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- my-app
|
||||
topologyKey: kubernetes.io/hostname
|
||||
|
||||
tolerations:
|
||||
- key: "app"
|
||||
operator: "Equal"
|
||||
value: "my-app"
|
||||
effect: "NoSchedule"
|
||||
- key: "app"
|
||||
operator: "Equal"
|
||||
value: "my-app"
|
||||
effect: "NoSchedule"
|
||||
|
||||
# Termination
|
||||
terminationGracePeriodSeconds: 30
|
||||
|
||||
# Image pull secrets
|
||||
imagePullSecrets:
|
||||
- name: regcred
|
||||
- name: regcred
|
||||
```
|
||||
|
||||
## Field Reference
|
||||
@@ -243,11 +244,13 @@ spec:
|
||||
### Metadata Fields
|
||||
|
||||
#### Required Fields
|
||||
|
||||
- `apiVersion`: `apps/v1` (current stable version)
|
||||
- `kind`: `Deployment`
|
||||
- `metadata.name`: Unique name within namespace
|
||||
|
||||
#### Recommended Metadata
|
||||
|
||||
- `metadata.namespace`: Target namespace (defaults to `default`)
|
||||
- `metadata.labels`: Key-value pairs for organization
|
||||
- `metadata.annotations`: Non-identifying metadata
|
||||
@@ -257,11 +260,13 @@ spec:
|
||||
#### Replica Management
|
||||
|
||||
**`replicas`** (integer, default: 1)
|
||||
|
||||
- Number of desired pod instances
|
||||
- Best practice: Use 3+ for production high availability
|
||||
- Can be scaled manually or via HorizontalPodAutoscaler
|
||||
|
||||
**`revisionHistoryLimit`** (integer, default: 10)
|
||||
|
||||
- Number of old ReplicaSets to retain for rollback
|
||||
- Set to 0 to disable rollback capability
|
||||
- Reduces storage overhead for long-running deployments
|
||||
@@ -269,19 +274,23 @@ spec:
|
||||
#### Update Strategy
|
||||
|
||||
**`strategy.type`** (string)
|
||||
|
||||
- `RollingUpdate` (default): Gradual pod replacement
|
||||
- `Recreate`: Delete all pods before creating new ones
|
||||
|
||||
**`strategy.rollingUpdate.maxSurge`** (int or percent, default: 25%)
|
||||
|
||||
- Maximum pods above desired replicas during update
|
||||
- Example: With 3 replicas and maxSurge=1, up to 4 pods during update
|
||||
|
||||
**`strategy.rollingUpdate.maxUnavailable`** (int or percent, default: 25%)
|
||||
|
||||
- Maximum pods below desired replicas during update
|
||||
- Set to 0 for zero-downtime deployments
|
||||
- Cannot be 0 if maxSurge is 0
|
||||
|
||||
**Best practices:**
|
||||
|
||||
```yaml
|
||||
# Zero-downtime deployment
|
||||
strategy:
|
||||
@@ -305,11 +314,13 @@ strategy:
|
||||
#### Pod Template
|
||||
|
||||
**`template.metadata.labels`**
|
||||
|
||||
- Must include labels matching `spec.selector.matchLabels`
|
||||
- Add version labels for blue/green deployments
|
||||
- Include standard Kubernetes labels
|
||||
|
||||
**`template.spec.containers`** (required)
|
||||
|
||||
- Array of container specifications
|
||||
- At least one container required
|
||||
- Each container needs unique name
|
||||
@@ -317,25 +328,28 @@ strategy:
|
||||
#### Container Configuration
|
||||
|
||||
**Image Management:**
|
||||
|
||||
```yaml
|
||||
containers:
|
||||
- name: app
|
||||
image: registry.example.com/myapp:1.0.0
|
||||
imagePullPolicy: IfNotPresent # or Always, Never
|
||||
- name: app
|
||||
image: registry.example.com/myapp:1.0.0
|
||||
imagePullPolicy: IfNotPresent # or Always, Never
|
||||
```
|
||||
|
||||
Image pull policies:
|
||||
|
||||
- `IfNotPresent`: Pull if not cached (default for tagged images)
|
||||
- `Always`: Always pull (default for :latest)
|
||||
- `Never`: Never pull, fail if not cached
|
||||
|
||||
**Port Declarations:**
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- name: http # Named for referencing in Service
|
||||
containerPort: 8080
|
||||
protocol: TCP # TCP (default), UDP, or SCTP
|
||||
hostPort: 8080 # Optional: Bind to host port (rarely used)
|
||||
- name: http # Named for referencing in Service
|
||||
containerPort: 8080
|
||||
protocol: TCP # TCP (default), UDP, or SCTP
|
||||
hostPort: 8080 # Optional: Bind to host port (rarely used)
|
||||
```
|
||||
|
||||
#### Resource Management
|
||||
@@ -345,11 +359,11 @@ ports:
|
||||
```yaml
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi" # Guaranteed resources
|
||||
cpu: "250m" # 0.25 CPU cores
|
||||
memory: "256Mi" # Guaranteed resources
|
||||
cpu: "250m" # 0.25 CPU cores
|
||||
limits:
|
||||
memory: "512Mi" # Maximum allowed
|
||||
cpu: "500m" # 0.5 CPU cores
|
||||
memory: "512Mi" # Maximum allowed
|
||||
cpu: "500m" # 0.5 CPU cores
|
||||
```
|
||||
|
||||
**QoS Classes (determined automatically):**
|
||||
@@ -367,6 +381,7 @@ resources:
|
||||
- First to be evicted
|
||||
|
||||
**Best practices:**
|
||||
|
||||
- Always set requests in production
|
||||
- Set limits to prevent resource monopolization
|
||||
- Memory limits should be 1.5-2x requests
|
||||
@@ -377,6 +392,7 @@ resources:
|
||||
**Probe Types:**
|
||||
|
||||
1. **startupProbe** - For slow-starting applications
|
||||
|
||||
```yaml
|
||||
startupProbe:
|
||||
httpGet:
|
||||
@@ -384,10 +400,11 @@ resources:
|
||||
port: 8080
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30 # 5 minutes to start (10s * 30)
|
||||
failureThreshold: 30 # 5 minutes to start (10s * 30)
|
||||
```
|
||||
|
||||
2. **livenessProbe** - Restarts unhealthy containers
|
||||
|
||||
```yaml
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -396,7 +413,7 @@ resources:
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3 # Restart after 3 failures
|
||||
failureThreshold: 3 # Restart after 3 failures
|
||||
```
|
||||
|
||||
3. **readinessProbe** - Controls traffic routing
|
||||
@@ -407,7 +424,7 @@ resources:
|
||||
port: 8080
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
failureThreshold: 3 # Remove from service after 3 failures
|
||||
failureThreshold: 3 # Remove from service after 3 failures
|
||||
```
|
||||
|
||||
**Probe Mechanisms:**
|
||||
@@ -418,8 +435,8 @@ httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
httpHeaders:
|
||||
- name: Authorization
|
||||
value: Bearer token
|
||||
- name: Authorization
|
||||
value: Bearer token
|
||||
|
||||
# TCP Socket
|
||||
tcpSocket:
|
||||
@@ -428,8 +445,8 @@ tcpSocket:
|
||||
# Command execution
|
||||
exec:
|
||||
command:
|
||||
- cat
|
||||
- /tmp/healthy
|
||||
- cat
|
||||
- /tmp/healthy
|
||||
|
||||
# gRPC (Kubernetes 1.24+)
|
||||
grpc:
|
||||
@@ -448,6 +465,7 @@ grpc:
|
||||
#### Security Context
|
||||
|
||||
**Pod-level security context:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
securityContext:
|
||||
@@ -461,22 +479,24 @@ spec:
|
||||
```
|
||||
|
||||
**Container-level security context:**
|
||||
|
||||
```yaml
|
||||
containers:
|
||||
- name: app
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE # Only if needed
|
||||
- name: app
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE # Only if needed
|
||||
```
|
||||
|
||||
**Security best practices:**
|
||||
|
||||
- Always run as non-root (`runAsNonRoot: true`)
|
||||
- Drop all capabilities and add only needed ones
|
||||
- Use read-only root filesystem when possible
|
||||
@@ -489,35 +509,35 @@ containers:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
# PersistentVolumeClaim
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: app-data
|
||||
# PersistentVolumeClaim
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: app-data
|
||||
|
||||
# ConfigMap
|
||||
- name: config
|
||||
configMap:
|
||||
name: app-config
|
||||
items:
|
||||
- key: app.properties
|
||||
path: application.properties
|
||||
# ConfigMap
|
||||
- name: config
|
||||
configMap:
|
||||
name: app-config
|
||||
items:
|
||||
- key: app.properties
|
||||
path: application.properties
|
||||
|
||||
# Secret
|
||||
- name: secrets
|
||||
secret:
|
||||
secretName: app-secrets
|
||||
defaultMode: 0400
|
||||
# Secret
|
||||
- name: secrets
|
||||
secret:
|
||||
secretName: app-secrets
|
||||
defaultMode: 0400
|
||||
|
||||
# EmptyDir (ephemeral)
|
||||
- name: cache
|
||||
emptyDir:
|
||||
sizeLimit: 1Gi
|
||||
# EmptyDir (ephemeral)
|
||||
- name: cache
|
||||
emptyDir:
|
||||
sizeLimit: 1Gi
|
||||
|
||||
# HostPath (avoid in production)
|
||||
- name: host-data
|
||||
hostPath:
|
||||
path: /data
|
||||
type: DirectoryOrCreate
|
||||
# HostPath (avoid in production)
|
||||
- name: host-data
|
||||
hostPath:
|
||||
path: /data
|
||||
type: DirectoryOrCreate
|
||||
```
|
||||
|
||||
#### Scheduling
|
||||
@@ -535,12 +555,12 @@ affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: kubernetes.io/arch
|
||||
operator: In
|
||||
values:
|
||||
- amd64
|
||||
- arm64
|
||||
- matchExpressions:
|
||||
- key: kubernetes.io/arch
|
||||
operator: In
|
||||
values:
|
||||
- amd64
|
||||
- arm64
|
||||
```
|
||||
|
||||
**Pod Affinity/Anti-Affinity:**
|
||||
@@ -571,14 +591,14 @@ affinity:
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "node.kubernetes.io/unreachable"
|
||||
operator: "Exists"
|
||||
effect: "NoExecute"
|
||||
tolerationSeconds: 30
|
||||
- key: "dedicated"
|
||||
operator: "Equal"
|
||||
value: "database"
|
||||
effect: "NoSchedule"
|
||||
- key: "node.kubernetes.io/unreachable"
|
||||
operator: "Exists"
|
||||
effect: "NoExecute"
|
||||
tolerationSeconds: 30
|
||||
- key: "dedicated"
|
||||
operator: "Equal"
|
||||
value: "database"
|
||||
effect: "NoSchedule"
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
@@ -598,17 +618,17 @@ spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchLabels:
|
||||
app: my-app
|
||||
topologyKey: kubernetes.io/hostname
|
||||
- labelSelector:
|
||||
matchLabels:
|
||||
app: my-app
|
||||
topologyKey: kubernetes.io/hostname
|
||||
topologySpreadConstraints:
|
||||
- maxSkew: 1
|
||||
topologyKey: topology.kubernetes.io/zone
|
||||
whenUnsatisfiable: DoNotSchedule
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app: my-app
|
||||
- maxSkew: 1
|
||||
topologyKey: topology.kubernetes.io/zone
|
||||
whenUnsatisfiable: DoNotSchedule
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app: my-app
|
||||
```
|
||||
|
||||
### Sidecar Container Pattern
|
||||
@@ -618,20 +638,20 @@ spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: app
|
||||
image: myapp:1.0.0
|
||||
volumeMounts:
|
||||
- name: shared-logs
|
||||
mountPath: /var/log
|
||||
- name: log-forwarder
|
||||
image: fluent-bit:2.0
|
||||
volumeMounts:
|
||||
- name: shared-logs
|
||||
mountPath: /var/log
|
||||
readOnly: true
|
||||
- name: app
|
||||
image: myapp:1.0.0
|
||||
volumeMounts:
|
||||
- name: shared-logs
|
||||
mountPath: /var/log
|
||||
- name: log-forwarder
|
||||
image: fluent-bit:2.0
|
||||
volumeMounts:
|
||||
- name: shared-logs
|
||||
mountPath: /var/log
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: shared-logs
|
||||
emptyDir: {}
|
||||
- name: shared-logs
|
||||
emptyDir: {}
|
||||
```
|
||||
|
||||
### Init Container for Dependencies
|
||||
@@ -641,28 +661,28 @@ spec:
|
||||
template:
|
||||
spec:
|
||||
initContainers:
|
||||
- name: wait-for-db
|
||||
image: busybox:1.36
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
until nc -z database-service 5432; do
|
||||
echo "Waiting for database..."
|
||||
sleep 2
|
||||
done
|
||||
- name: run-migrations
|
||||
image: myapp:1.0.0
|
||||
command: ["./migrate", "up"]
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: url
|
||||
- name: wait-for-db
|
||||
image: busybox:1.36
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
until nc -z database-service 5432; do
|
||||
echo "Waiting for database..."
|
||||
sleep 2
|
||||
done
|
||||
- name: run-migrations
|
||||
image: myapp:1.0.0
|
||||
command: ["./migrate", "up"]
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-credentials
|
||||
key: url
|
||||
containers:
|
||||
- name: app
|
||||
image: myapp:1.0.0
|
||||
- name: app
|
||||
image: myapp:1.0.0
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
@@ -685,6 +705,7 @@ spec:
|
||||
### Performance Tuning
|
||||
|
||||
**Fast startup:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
minReadySeconds: 5
|
||||
@@ -695,6 +716,7 @@ spec:
|
||||
```
|
||||
|
||||
**Zero-downtime updates:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
minReadySeconds: 10
|
||||
@@ -705,17 +727,18 @@ spec:
|
||||
```
|
||||
|
||||
**Graceful shutdown:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 60
|
||||
containers:
|
||||
- name: app
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command: ["/bin/sh", "-c", "sleep 15 && kill -SIGTERM 1"]
|
||||
- name: app
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command: ["/bin/sh", "-c", "sleep 15 && kill -SIGTERM 1"]
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
@@ -723,6 +746,7 @@ spec:
|
||||
### Common Issues
|
||||
|
||||
**Pods not starting:**
|
||||
|
||||
```bash
|
||||
kubectl describe deployment <name>
|
||||
kubectl get pods -l app=<app-name>
|
||||
@@ -731,17 +755,20 @@ kubectl logs <pod-name>
|
||||
```
|
||||
|
||||
**ImagePullBackOff:**
|
||||
|
||||
- Check image name and tag
|
||||
- Verify imagePullSecrets
|
||||
- Check registry credentials
|
||||
|
||||
**CrashLoopBackOff:**
|
||||
|
||||
- Check container logs
|
||||
- Verify liveness probe is not too aggressive
|
||||
- Check resource limits
|
||||
- Verify application dependencies
|
||||
|
||||
**Deployment stuck in progress:**
|
||||
|
||||
- Check progressDeadlineSeconds
|
||||
- Verify readiness probes
|
||||
- Check resource availability
|
||||
|
||||
@@ -23,14 +23,15 @@ spec:
|
||||
selector:
|
||||
app: backend
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
sessionAffinity: None
|
||||
```
|
||||
|
||||
**Use cases:**
|
||||
|
||||
- Internal microservice communication
|
||||
- Database services
|
||||
- Internal APIs
|
||||
@@ -50,19 +51,21 @@ spec:
|
||||
selector:
|
||||
app: frontend
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
nodePort: 30080 # Optional, auto-assigned if omitted
|
||||
protocol: TCP
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
nodePort: 30080 # Optional, auto-assigned if omitted
|
||||
protocol: TCP
|
||||
```
|
||||
|
||||
**Use cases:**
|
||||
|
||||
- Development/testing external access
|
||||
- Small deployments without load balancer
|
||||
- Direct node access requirements
|
||||
|
||||
**Limitations:**
|
||||
|
||||
- Limited port range (30000-32767)
|
||||
- Must handle node failures
|
||||
- No built-in load balancing across nodes
|
||||
@@ -84,20 +87,21 @@ spec:
|
||||
selector:
|
||||
app: api
|
||||
ports:
|
||||
- name: https
|
||||
port: 443
|
||||
targetPort: 8443
|
||||
protocol: TCP
|
||||
- name: https
|
||||
port: 443
|
||||
targetPort: 8443
|
||||
protocol: TCP
|
||||
loadBalancerSourceRanges:
|
||||
- 203.0.113.0/24
|
||||
- 203.0.113.0/24
|
||||
```
|
||||
|
||||
**Cloud-specific annotations:**
|
||||
|
||||
**AWS:**
|
||||
|
||||
```yaml
|
||||
annotations:
|
||||
service.beta.kubernetes.io/aws-load-balancer-type: "nlb" # or "external"
|
||||
service.beta.kubernetes.io/aws-load-balancer-type: "nlb" # or "external"
|
||||
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
|
||||
service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
|
||||
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:..."
|
||||
@@ -105,6 +109,7 @@ annotations:
|
||||
```
|
||||
|
||||
**Azure:**
|
||||
|
||||
```yaml
|
||||
annotations:
|
||||
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
|
||||
@@ -112,6 +117,7 @@ annotations:
|
||||
```
|
||||
|
||||
**GCP:**
|
||||
|
||||
```yaml
|
||||
annotations:
|
||||
cloud.google.com/load-balancer-type: "Internal"
|
||||
@@ -131,10 +137,11 @@ spec:
|
||||
type: ExternalName
|
||||
externalName: db.external.example.com
|
||||
ports:
|
||||
- port: 5432
|
||||
- port: 5432
|
||||
```
|
||||
|
||||
**Use cases:**
|
||||
|
||||
- Accessing external services
|
||||
- Service migration scenarios
|
||||
- Multi-cluster service references
|
||||
@@ -164,10 +171,10 @@ spec:
|
||||
|
||||
# Ports configuration
|
||||
ports:
|
||||
- name: http
|
||||
port: 80 # Service port
|
||||
targetPort: 8080 # Container port (or named port)
|
||||
protocol: TCP # TCP, UDP, or SCTP
|
||||
- name: http
|
||||
port: 80 # Service port
|
||||
targetPort: 8080 # Container port (or named port)
|
||||
protocol: TCP # TCP, UDP, or SCTP
|
||||
|
||||
# Session affinity
|
||||
sessionAffinity: ClientIP
|
||||
@@ -176,11 +183,11 @@ spec:
|
||||
timeoutSeconds: 10800
|
||||
|
||||
# IP configuration
|
||||
clusterIP: 10.0.0.10 # Optional: specific IP
|
||||
clusterIP: 10.0.0.10 # Optional: specific IP
|
||||
clusterIPs:
|
||||
- 10.0.0.10
|
||||
- 10.0.0.10
|
||||
ipFamilies:
|
||||
- IPv4
|
||||
- IPv4
|
||||
ipFamilyPolicy: SingleStack
|
||||
|
||||
# External traffic policy
|
||||
@@ -195,11 +202,11 @@ spec:
|
||||
# Load balancer config (for type: LoadBalancer)
|
||||
loadBalancerIP: 203.0.113.100
|
||||
loadBalancerSourceRanges:
|
||||
- 203.0.113.0/24
|
||||
- 203.0.113.0/24
|
||||
|
||||
# External IPs
|
||||
externalIPs:
|
||||
- 80.11.12.10
|
||||
- 80.11.12.10
|
||||
|
||||
# Publishing strategy
|
||||
publishNotReadyAddresses: false
|
||||
@@ -212,29 +219,31 @@ spec:
|
||||
Use named ports in Pods for flexibility:
|
||||
|
||||
**Deployment:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: app
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
- name: metrics
|
||||
containerPort: 9090
|
||||
- name: app
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
- name: metrics
|
||||
containerPort: 9090
|
||||
```
|
||||
|
||||
**Service:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http # References named port
|
||||
- name: metrics
|
||||
port: 9090
|
||||
targetPort: metrics
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: http # References named port
|
||||
- name: metrics
|
||||
port: 9090
|
||||
targetPort: metrics
|
||||
```
|
||||
|
||||
### Multiple Ports
|
||||
@@ -242,18 +251,18 @@ spec:
|
||||
```yaml
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
- name: https
|
||||
port: 443
|
||||
targetPort: 8443
|
||||
protocol: TCP
|
||||
- name: grpc
|
||||
port: 9090
|
||||
targetPort: 9090
|
||||
protocol: TCP
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
- name: https
|
||||
port: 443
|
||||
targetPort: 8443
|
||||
protocol: TCP
|
||||
- name: grpc
|
||||
port: 9090
|
||||
targetPort: 9090
|
||||
protocol: TCP
|
||||
```
|
||||
|
||||
## Session Affinity
|
||||
@@ -276,10 +285,11 @@ spec:
|
||||
sessionAffinity: ClientIP
|
||||
sessionAffinityConfig:
|
||||
clientIP:
|
||||
timeoutSeconds: 10800 # 3 hours
|
||||
timeoutSeconds: 10800 # 3 hours
|
||||
```
|
||||
|
||||
**Use cases:**
|
||||
|
||||
- Stateful applications
|
||||
- Session-based applications
|
||||
- WebSocket connections
|
||||
@@ -289,19 +299,23 @@ spec:
|
||||
### External Traffic Policy
|
||||
|
||||
**Cluster (Default):**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
externalTrafficPolicy: Cluster
|
||||
```
|
||||
|
||||
- Load balances across all nodes
|
||||
- May add extra network hop
|
||||
- Source IP is masked
|
||||
|
||||
**Local:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
externalTrafficPolicy: Local
|
||||
```
|
||||
|
||||
- Traffic goes only to pods on receiving node
|
||||
- Preserves client source IP
|
||||
- Better performance (no extra hop)
|
||||
@@ -311,7 +325,7 @@ spec:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
internalTrafficPolicy: Local # or Cluster
|
||||
internalTrafficPolicy: Local # or Cluster
|
||||
```
|
||||
|
||||
Controls traffic routing for cluster-internal clients.
|
||||
@@ -326,21 +340,23 @@ kind: Service
|
||||
metadata:
|
||||
name: database
|
||||
spec:
|
||||
clusterIP: None # Headless
|
||||
clusterIP: None # Headless
|
||||
selector:
|
||||
app: database
|
||||
ports:
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
- port: 5432
|
||||
targetPort: 5432
|
||||
```
|
||||
|
||||
**Use cases:**
|
||||
|
||||
- StatefulSet pod discovery
|
||||
- Direct pod-to-pod communication
|
||||
- Custom load balancing
|
||||
- Database clusters
|
||||
|
||||
**DNS returns:**
|
||||
|
||||
- Individual pod IPs instead of service IP
|
||||
- Format: `<pod-name>.<service-name>.<namespace>.svc.cluster.local`
|
||||
|
||||
@@ -349,21 +365,25 @@ spec:
|
||||
### DNS
|
||||
|
||||
**ClusterIP Service:**
|
||||
|
||||
```
|
||||
<service-name>.<namespace>.svc.cluster.local
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
curl http://backend-service.production.svc.cluster.local
|
||||
```
|
||||
|
||||
**Within same namespace:**
|
||||
|
||||
```bash
|
||||
curl http://backend-service
|
||||
```
|
||||
|
||||
**Headless Service (returns pod IPs):**
|
||||
|
||||
```
|
||||
<pod-name>.<service-name>.<namespace>.svc.cluster.local
|
||||
```
|
||||
@@ -390,6 +410,7 @@ BACKEND_SERVICE_SERVICE_PORT_HTTP=80
|
||||
Kubernetes uses random selection by default. For advanced load balancing:
|
||||
|
||||
**Service Mesh (Istio example):**
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: DestinationRule
|
||||
@@ -399,7 +420,7 @@ spec:
|
||||
host: my-service
|
||||
trafficPolicy:
|
||||
loadBalancer:
|
||||
simple: LEAST_REQUEST # or ROUND_ROBIN, RANDOM, PASSTHROUGH
|
||||
simple: LEAST_REQUEST # or ROUND_ROBIN, RANDOM, PASSTHROUGH
|
||||
connectionPool:
|
||||
tcp:
|
||||
maxConnections: 100
|
||||
@@ -432,25 +453,25 @@ metadata:
|
||||
name: my-service
|
||||
spec:
|
||||
hosts:
|
||||
- my-service
|
||||
- my-service
|
||||
http:
|
||||
- match:
|
||||
- headers:
|
||||
version:
|
||||
exact: v2
|
||||
route:
|
||||
- destination:
|
||||
host: my-service
|
||||
subset: v2
|
||||
- route:
|
||||
- destination:
|
||||
host: my-service
|
||||
subset: v1
|
||||
weight: 90
|
||||
- destination:
|
||||
host: my-service
|
||||
subset: v2
|
||||
weight: 10
|
||||
- match:
|
||||
- headers:
|
||||
version:
|
||||
exact: v2
|
||||
route:
|
||||
- destination:
|
||||
host: my-service
|
||||
subset: v2
|
||||
- route:
|
||||
- destination:
|
||||
host: my-service
|
||||
subset: v1
|
||||
weight: 90
|
||||
- destination:
|
||||
host: my-service
|
||||
subset: v2
|
||||
weight: 10
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
@@ -471,14 +492,14 @@ spec:
|
||||
selector:
|
||||
app: user-service
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
- name: grpc
|
||||
port: 9090
|
||||
targetPort: grpc
|
||||
protocol: TCP
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
- name: grpc
|
||||
port: 9090
|
||||
targetPort: grpc
|
||||
protocol: TCP
|
||||
```
|
||||
|
||||
### Pattern 2: Public API with Load Balancer
|
||||
@@ -497,12 +518,12 @@ spec:
|
||||
selector:
|
||||
app: api-gateway
|
||||
ports:
|
||||
- name: https
|
||||
port: 443
|
||||
targetPort: 8443
|
||||
protocol: TCP
|
||||
- name: https
|
||||
port: 443
|
||||
targetPort: 8443
|
||||
protocol: TCP
|
||||
loadBalancerSourceRanges:
|
||||
- 0.0.0.0/0
|
||||
- 0.0.0.0/0
|
||||
```
|
||||
|
||||
### Pattern 3: StatefulSet with Headless Service
|
||||
@@ -517,8 +538,8 @@ spec:
|
||||
selector:
|
||||
app: cassandra
|
||||
ports:
|
||||
- port: 9042
|
||||
targetPort: 9042
|
||||
- port: 9042
|
||||
targetPort: 9042
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
@@ -536,8 +557,8 @@ spec:
|
||||
app: cassandra
|
||||
spec:
|
||||
containers:
|
||||
- name: cassandra
|
||||
image: cassandra:4.0
|
||||
- name: cassandra
|
||||
image: cassandra:4.0
|
||||
```
|
||||
|
||||
### Pattern 4: External Service Mapping
|
||||
@@ -558,19 +579,19 @@ metadata:
|
||||
name: external-api
|
||||
spec:
|
||||
ports:
|
||||
- port: 443
|
||||
targetPort: 443
|
||||
protocol: TCP
|
||||
- port: 443
|
||||
targetPort: 443
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Endpoints
|
||||
metadata:
|
||||
name: external-api
|
||||
subsets:
|
||||
- addresses:
|
||||
- ip: 203.0.113.100
|
||||
ports:
|
||||
- port: 443
|
||||
- addresses:
|
||||
- ip: 203.0.113.100
|
||||
ports:
|
||||
- port: 443
|
||||
```
|
||||
|
||||
### Pattern 5: Multi-Port Service with Metrics
|
||||
@@ -589,12 +610,12 @@ spec:
|
||||
selector:
|
||||
app: web-app
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
- name: metrics
|
||||
port: 9090
|
||||
targetPort: 9090
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
- name: metrics
|
||||
port: 9090
|
||||
targetPort: 9090
|
||||
```
|
||||
|
||||
## Network Policies
|
||||
@@ -611,15 +632,15 @@ spec:
|
||||
matchLabels:
|
||||
app: backend
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: frontend
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8080
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: frontend
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8080
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
@@ -651,6 +672,7 @@ spec:
|
||||
### Performance Tuning
|
||||
|
||||
**For high traffic:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
externalTrafficPolicy: Local
|
||||
@@ -661,12 +683,13 @@ spec:
|
||||
```
|
||||
|
||||
**For WebSocket/long connections:**
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
sessionAffinity: ClientIP
|
||||
sessionAffinityConfig:
|
||||
clientIP:
|
||||
timeoutSeconds: 86400 # 24 hours
|
||||
timeoutSeconds: 86400 # 24 hours
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
@@ -688,6 +711,7 @@ kubectl get pods -l app=<app-name>
|
||||
```
|
||||
|
||||
**Common issues:**
|
||||
|
||||
- Selector doesn't match pod labels
|
||||
- No pods running (endpoints empty)
|
||||
- Ports misconfigured
|
||||
|
||||
@@ -23,6 +23,7 @@ Implement defense-in-depth security for Kubernetes clusters using network polici
|
||||
## Pod Security Standards
|
||||
|
||||
### 1. Privileged (Unrestricted)
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
@@ -35,6 +36,7 @@ metadata:
|
||||
```
|
||||
|
||||
### 2. Baseline (Minimally restrictive)
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
@@ -47,6 +49,7 @@ metadata:
|
||||
```
|
||||
|
||||
### 3. Restricted (Most restrictive)
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
@@ -61,6 +64,7 @@ metadata:
|
||||
## Network Policies
|
||||
|
||||
### Default Deny All
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
@@ -70,11 +74,12 @@ metadata:
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
- Ingress
|
||||
- Egress
|
||||
```
|
||||
|
||||
### Allow Frontend to Backend
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
@@ -86,18 +91,19 @@ spec:
|
||||
matchLabels:
|
||||
app: backend
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: frontend
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8080
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app: frontend
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8080
|
||||
```
|
||||
|
||||
### Allow DNS
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
@@ -107,15 +113,15 @@ metadata:
|
||||
spec:
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Egress
|
||||
- Egress
|
||||
egress:
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
name: kube-system
|
||||
ports:
|
||||
- protocol: UDP
|
||||
port: 53
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
name: kube-system
|
||||
ports:
|
||||
- protocol: UDP
|
||||
port: 53
|
||||
```
|
||||
|
||||
**Reference:** See `assets/network-policy-template.yaml`
|
||||
@@ -123,6 +129,7 @@ spec:
|
||||
## RBAC Configuration
|
||||
|
||||
### Role (Namespace-scoped)
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
@@ -130,24 +137,26 @@ metadata:
|
||||
name: pod-reader
|
||||
namespace: production
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
```
|
||||
|
||||
### ClusterRole (Cluster-wide)
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: secret-reader
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
```
|
||||
|
||||
### RoleBinding
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
@@ -155,12 +164,12 @@ metadata:
|
||||
name: read-pods
|
||||
namespace: production
|
||||
subjects:
|
||||
- kind: User
|
||||
name: jane
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: production
|
||||
- kind: User
|
||||
name: jane
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: production
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: pod-reader
|
||||
@@ -172,6 +181,7 @@ roleRef:
|
||||
## Pod Security Context
|
||||
|
||||
### Restricted Pod
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -185,19 +195,20 @@ spec:
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: app
|
||||
image: myapp:1.0
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
- name: app
|
||||
image: myapp:1.0
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
```
|
||||
|
||||
## Policy Enforcement with OPA Gatekeeper
|
||||
|
||||
### ConstraintTemplate
|
||||
|
||||
```yaml
|
||||
apiVersion: templates.gatekeeper.sh/v1
|
||||
kind: ConstraintTemplate
|
||||
@@ -230,6 +241,7 @@ spec:
|
||||
```
|
||||
|
||||
### Constraint
|
||||
|
||||
```yaml
|
||||
apiVersion: constraints.gatekeeper.sh/v1beta1
|
||||
kind: K8sRequiredLabels
|
||||
@@ -247,6 +259,7 @@ spec:
|
||||
## Service Mesh Security (Istio)
|
||||
|
||||
### PeerAuthentication (mTLS)
|
||||
|
||||
```yaml
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: PeerAuthentication
|
||||
@@ -259,6 +272,7 @@ spec:
|
||||
```
|
||||
|
||||
### AuthorizationPolicy
|
||||
|
||||
```yaml
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: AuthorizationPolicy
|
||||
@@ -271,9 +285,9 @@ spec:
|
||||
app: backend
|
||||
action: ALLOW
|
||||
rules:
|
||||
- from:
|
||||
- source:
|
||||
principals: ["cluster.local/ns/production/sa/frontend"]
|
||||
- from:
|
||||
- source:
|
||||
principals: ["cluster.local/ns/production/sa/frontend"]
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
@@ -292,6 +306,7 @@ spec:
|
||||
## Compliance Frameworks
|
||||
|
||||
### CIS Kubernetes Benchmark
|
||||
|
||||
- Use RBAC authorization
|
||||
- Enable audit logging
|
||||
- Use Pod Security Standards
|
||||
@@ -300,6 +315,7 @@ spec:
|
||||
- Enable node authentication
|
||||
|
||||
### NIST Cybersecurity Framework
|
||||
|
||||
- Implement defense in depth
|
||||
- Use network segmentation
|
||||
- Configure security monitoring
|
||||
@@ -309,6 +325,7 @@ spec:
|
||||
## Troubleshooting
|
||||
|
||||
**NetworkPolicy not working:**
|
||||
|
||||
```bash
|
||||
# Check if CNI supports NetworkPolicy
|
||||
kubectl get nodes -o wide
|
||||
@@ -316,6 +333,7 @@ kubectl describe networkpolicy <name>
|
||||
```
|
||||
|
||||
**RBAC permission denied:**
|
||||
|
||||
```bash
|
||||
# Check effective permissions
|
||||
kubectl auth can-i list pods --as system:serviceaccount:default:my-sa
|
||||
|
||||
@@ -3,18 +3,20 @@
|
||||
## Common RBAC Patterns
|
||||
|
||||
### Pattern 1: Read-Only Access
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: read-only
|
||||
rules:
|
||||
- apiGroups: ["", "apps", "batch"]
|
||||
resources: ["*"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups: ["", "apps", "batch"]
|
||||
resources: ["*"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
```
|
||||
|
||||
### Pattern 2: Namespace Admin
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
@@ -22,12 +24,13 @@ metadata:
|
||||
name: namespace-admin
|
||||
namespace: production
|
||||
rules:
|
||||
- apiGroups: ["", "apps", "batch", "extensions"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
- apiGroups: ["", "apps", "batch", "extensions"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
```
|
||||
|
||||
### Pattern 3: Deployment Manager
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
@@ -35,15 +38,16 @@ metadata:
|
||||
name: deployment-manager
|
||||
namespace: production
|
||||
rules:
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
```
|
||||
|
||||
### Pattern 4: Secret Reader (ServiceAccount)
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
@@ -51,10 +55,10 @@ metadata:
|
||||
name: secret-reader
|
||||
namespace: production
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get"]
|
||||
resourceNames: ["app-secrets"] # Specific secret only
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get"]
|
||||
resourceNames: ["app-secrets"] # Specific secret only
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
@@ -62,9 +66,9 @@ metadata:
|
||||
name: app-secret-reader
|
||||
namespace: production
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: my-app
|
||||
namespace: production
|
||||
- kind: ServiceAccount
|
||||
name: my-app
|
||||
namespace: production
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: secret-reader
|
||||
@@ -72,26 +76,28 @@ roleRef:
|
||||
```
|
||||
|
||||
### Pattern 5: CI/CD Pipeline Access
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: cicd-deployer
|
||||
rules:
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments", "replicasets"]
|
||||
verbs: ["get", "list", "create", "update", "patch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["services", "configmaps"]
|
||||
verbs: ["get", "list", "create", "update", "patch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments", "replicasets"]
|
||||
verbs: ["get", "list", "create", "update", "patch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["services", "configmaps"]
|
||||
verbs: ["get", "list", "create", "update", "patch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list"]
|
||||
```
|
||||
|
||||
## ServiceAccount Best Practices
|
||||
|
||||
### Create Dedicated ServiceAccounts
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
@@ -107,10 +113,11 @@ spec:
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: my-app
|
||||
automountServiceAccountToken: false # Disable if not needed
|
||||
automountServiceAccountToken: false # Disable if not needed
|
||||
```
|
||||
|
||||
### Least-Privilege ServiceAccount
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
@@ -118,10 +125,10 @@ metadata:
|
||||
name: my-app-role
|
||||
namespace: production
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps"]
|
||||
verbs: ["get"]
|
||||
resourceNames: ["my-app-config"]
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps"]
|
||||
verbs: ["get"]
|
||||
resourceNames: ["my-app-config"]
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
@@ -140,18 +147,21 @@ rules:
|
||||
## Troubleshooting RBAC
|
||||
|
||||
### Check User Permissions
|
||||
|
||||
```bash
|
||||
kubectl auth can-i list pods --as john@example.com
|
||||
kubectl auth can-i '*' '*' --as system:serviceaccount:default:my-app
|
||||
```
|
||||
|
||||
### View Effective Permissions
|
||||
|
||||
```bash
|
||||
kubectl describe clusterrole cluster-admin
|
||||
kubectl describe rolebinding -n production
|
||||
```
|
||||
|
||||
### Debug Access Issues
|
||||
|
||||
```bash
|
||||
kubectl get rolebindings,clusterrolebindings --all-namespaces -o wide | grep my-user
|
||||
```
|
||||
@@ -171,6 +181,7 @@ kubectl get rolebindings,clusterrolebindings --all-namespaces -o wide | grep my-
|
||||
## Resource Scope
|
||||
|
||||
### Cluster-Scoped Resources
|
||||
|
||||
- Nodes
|
||||
- PersistentVolumes
|
||||
- ClusterRoles
|
||||
@@ -178,6 +189,7 @@ kubectl get rolebindings,clusterrolebindings --all-namespaces -o wide | grep my-
|
||||
- Namespaces
|
||||
|
||||
### Namespace-Scoped Resources
|
||||
|
||||
- Pods
|
||||
- Services
|
||||
- Deployments
|
||||
|
||||
Reference in New Issue
Block a user