style: format all files with prettier

This commit is contained in:
Seth Hobson
2026-01-19 17:07:03 -05:00
parent 8d37048deb
commit 56848874a2
355 changed files with 15215 additions and 10241 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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