Kubernetes Expert
Purpose
Provide expert guidance on Kubernetes architecture, deployments, services, networking, security, and production-ready cluster management.
When to Use This Skill
- Deploying applications to Kubernetes
- Creating Kubernetes manifests
- Helm chart development
- Cluster setup and configuration
- Troubleshooting K8s issues
- Implementing GitOps
- Setting up monitoring and logging
- Security hardening
Core Concepts
Workloads
- Pod - Smallest deployable unit
- Deployment - Declarative updates for Pods
- StatefulSet - Stateful applications
- DaemonSet - Run on all nodes
- Job/CronJob - Batch processing
Services & Networking
- Service - Stable network endpoint
- Ingress - HTTP/HTTPS routing
- NetworkPolicy - Pod-to-pod network rules
- DNS - Service discovery
Configuration
- ConfigMap - Configuration data
- Secret - Sensitive data
- PersistentVolume - Storage
- StorageClass - Dynamic provisioning
Production-Ready Deployment
1. Application Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
namespace: production
labels:
app: webapp
version: v1
spec:
replicas: 3
revisionHistoryLimit: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
version: v1
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: webapp-sa
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
containers:
- name: webapp
image: myregistry.io/webapp:v1.2.3
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
protocol: TCP
env:
- name: PORT
value: "8080"
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: redis.host
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secrets
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health/live
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /health/ready
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 3
startupProbe:
httpGet:
path: /health/startup
port: http
initialDelaySeconds: 0
periodSeconds: 10
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 30
volumeMounts:
- name: config
mountPath: /app/config
readOnly: true
- name: cache
mountPath: /app/cache
volumes:
- name: config
configMap:
name: app-config
- name: cache
emptyDir: {}
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- webapp
topologyKey: kubernetes.io/hostname
tolerations:
- key: "app"
operator: "Equal"
value: "webapp"
effect: "NoSchedule"
2. Service Configuration
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: production
labels:
app: webapp
spec:
type: ClusterIP
selector:
app: webapp
ports:
- name: http
port: 80
targetPort: http
protocol: TCP
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
---
apiVersion: v1
kind: Service
metadata:
name: webapp-headless
namespace: production
spec:
clusterIP: None
selector:
app: webapp
ports:
- name: http
port: 80
targetPort: http
3. Ingress Configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp-ingress
namespace: production
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
secretName: webapp-tls
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp
port:
number: 80
4. HorizontalPodAutoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: webapp-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: webapp
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: "1000"
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
5. ConfigMap & Secrets
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
data:
redis.host: "redis-master.database.svc.cluster.local"
redis.port: "6379"
log.level: "info"
feature.flags: |
{
"newFeature": true,
"betaFeature": false
}
---
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: production
type: Opaque
stringData:
url: "postgresql://user:pass@postgres:5432/mydb"
username: "dbuser"
password: "secure-password"
6. PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: webapp-data
namespace: production
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-ssd
resources:
requests:
storage: 10Gi
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ssd
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
iops: "3000"
throughput: "125"
encrypted: "true"
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer
Helm Charts
Chart Structure
mychart/
├── Chart.yaml
├── values.yaml
├── values-prod.yaml
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── configmap.yaml
│ ├── secret.yaml
│ ├── hpa.yaml
│ ├── _helpers.tpl
│ └── NOTES.txt
└── charts/
Chart.yaml
apiVersion: v2
name: webapp
description: A Helm chart for webapp
type: application
version: 1.0.0
appVersion: "1.2.3"
dependencies:
- name: postgresql
version: "12.1.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
values.yaml
replicaCount: 3
image:
repository: myregistry.io/webapp
pullPolicy: IfNotPresent
tag: ""
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: api.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: webapp-tls
hosts:
- api.example.com
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 20
targetCPUUtilizationPercentage: 70
postgresql:
enabled: true
auth:
username: webapp
database: webapp
Deployment Template with Helm
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "webapp.fullname" . }}
labels:
{{- include "webapp.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "webapp.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "webapp.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 8080
resources:
{{- toYaml .Values.resources | nindent 12 }}
Security Best Practices
1. Pod Security Standards
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
2. NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: webapp-netpol
namespace: production
spec:
podSelector:
matchLabels:
app: webapp
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
egress:
- to:
- namespaceSelector:
matchLabels:
name: database
ports:
- protocol: TCP
port: 5432
- to:
- podSelector:
matchLabels:
app: redis
ports:
- protocol: TCP
port: 6379
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
3. RBAC
apiVersion: v1
kind: ServiceAccount
metadata:
name: webapp-sa
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: webapp-role
namespace: production
rules:
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: webapp-rolebinding
namespace: production
subjects:
- kind: ServiceAccount
name: webapp-sa
namespace: production
roleRef:
kind: Role
name: webapp-role
apiGroup: rbac.authorization.k8s.io
Monitoring
Prometheus ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: webapp
namespace: production
spec:
selector:
matchLabels:
app: webapp
endpoints:
- port: http
path: /metrics
interval: 30s
GitOps with ArgoCD
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: webapp
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/myrepo
targetRevision: main
path: k8s/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Troubleshooting Commands
# Check pod status
kubectl get pods -n production
# View pod logs
kubectl logs -n production webapp-xxx --tail=100 -f
# Describe pod
kubectl describe pod -n production webapp-xxx
# Execute command in pod
kubectl exec -it -n production webapp-xxx -- /bin/sh
# Port forward
kubectl port-forward -n production webapp-xxx 8080:8080
# Check events
kubectl get events -n production --sort-by='.lastTimestamp'
# Top pods
kubectl top pods -n production
# Restart deployment
kubectl rollout restart deployment/webapp -n production
# Check rollout status
kubectl rollout status deployment/webapp -n production
This skill ensures production-ready, secure, and scalable Kubernetes deployments.