Kubernetes Advanced
Master advanced Kubernetes: Ingress controllers, Helm package management, HPA autoscaling, and production best practices.
Master advanced Kubernetes: Ingress controllers, Helm package management, HPA autoscaling, and production best practices. This hands-on tutorial focuses on practical implementation of kubernetes advanced concepts.
Kubernetes Advanced
Build on core concepts with advanced Kubernetes features for production deployments.
Ingress
Ingress exposes HTTP and HTTPS routes from outside the cluster to services within.
# Ingress resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
- www.example.com
secretName: tls-secret
rules:
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-v1
port:
number: 80
- path: /v2
pathType: Prefix
backend:
service:
name: api-v2
port:
number: 80
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
Installing NGINX Ingress Controller
# Helm installation
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
# Verify
kubectl get svc -n ingress-nginx
kubectl get ingressclasses
Advanced Ingress Patterns
# Canary deployment
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-canary
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
backend:
service:
name: app-v2
port:
number: 80
Helm - Kubernetes Package Manager
Helm simplifies Kubernetes application deployment through charts—packages of pre-configured Kubernetes resources.
Chart Structure
mychart/
├── Chart.yaml # Chart metadata
├── values.yaml # Default configuration values
├── values-production.yaml # Environment-specific values
├── charts/ # Chart dependencies
├── templates/ # Kubernetes manifest templates
│ ├── _helpers.tpl # Named templates
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ ├── configmap.yaml
│ └── NOTES.txt # Post-install instructions
└── README.md
Chart.yaml
apiVersion: v2
name: my-application
description: A Helm chart for my application
type: application
version: 1.2.3
appVersion: "2.0.0"
kubeVersion: ">=1.24.0-0"
keywords:
- web
- api
home: https://example.com
sources:
- https://github.com/example/myapp
maintainers:
- name: DevOps Team
email: devops@example.com
dependencies:
- name: postgresql
version: 12.1.0
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: redis
version: 17.3.0
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
Template Examples
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "mychart.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "mychart.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: {{ .Values.service.port }}
protocol: TCP
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- if .Values.livenessProbe.enabled }}
livenessProbe:
{{- toYaml .Values.livenessProbe | nindent 12 }}
{{- end }}
# values.yaml
replicaCount: 2
image:
repository: nginx
tag: "1.25"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: "letsencrypt"
hosts:
- host: app.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: app-tls
hosts:
- app.example.com
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 250m
memory: 128Mi
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
env:
- name: LOG_LEVEL
value: info
- name: CACHE_TTL
value: "3600"
Helm Commands
# Create new chart
helm create mychart
# Install chart
helm install myapp ./mychart
helm install myapp ./mychart -f values-production.yaml
helm install myapp ./mychart --set replicaCount=5
# Upgrade
helm upgrade myapp ./mychart
helm upgrade --install myapp ./mychart # Install or upgrade
# List releases
helm list
helm list --all-namespaces
# Get values
helm get values myapp
helm get manifest myapp
# Rollback
helm history myapp
helm rollback myapp 2
# Uninstall
helm uninstall myapp
# Repository management
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm search repo nginx
helm search hub postgresql
# Lint and template
helm lint ./mychart
helm template myapp ./mychart
helm template myapp ./mychart --debug
# Package chart
helm package ./mychart
Horizontal Pod Autoscaler (HPA)
Automatically scales the number of pod replicas based on observed metrics.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: app-deployment
minReplicas: 2
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: packets-per-second
target:
type: AverageValue
averageValue: 1k
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
# Create HPA
kubectl autoscale deployment app-deployment --min=2 --max=10 --cpu-percent=80
# View HPA
kubectl get hpa
kubectl describe hpa app-hpa
# Metrics server required
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Cluster Autoscaler
Automatically adjusts the size of the Kubernetes cluster.
# Cluster Autoscaler deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-autoscaler
namespace: kube-system
spec:
template:
spec:
containers:
- name: cluster-autoscaler
image: registry.k8s.io/autoscaling/cluster-autoscaler:v1.27.0
command:
- ./cluster-autoscaler
- --cloud-provider=aws
- --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/my-cluster
- --balance-similar-node-groups
- --skip-nodes-with-system-pods=false
Pod Disruption Budgets
Ensure minimum availability during voluntary disruptions.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: app-pdb
spec:
minAvailable: 2
# or maxUnavailable: 1
selector:
matchLabels:
app: myapp
Network Policies
Control traffic flow between pods and namespaces.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-network-policy
namespace: production
spec:
podSelector:
matchLabels:
role: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
- podSelector:
matchLabels:
role: web
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
role: database
ports:
- protocol: TCP
port: 5432
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
StatefulSets
For stateful applications requiring stable network identity and storage.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: "postgres-headless"
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:15
ports:
- containerPort: 5432
name: postgres
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "standard"
resources:
requests:
storage: 10Gi
Jobs and CronJobs
Job
apiVersion: batch/v1
kind: Job
metadata:
name: data-migration
spec:
template:
spec:
containers:
- name: migrator
image: myapp:latest
command: ["python", "migrate.py"]
restartPolicy: OnFailure
backoffLimit: 4
activeDeadlineSeconds: 600
ttlSecondsAfterFinished: 86400
CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-job
spec:
schedule: "0 2 * * *" # Daily at 2 AM
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:latest
command:
- /bin/sh
- -c
- |
pg_dump -h db -U user mydb > /backups/backup-$(date +%Y%m%d).sql
restartPolicy: OnFailure
Production Best Practices
Security Checklist
# Pod Security Context
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Resource Management
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
Liveness and Readiness
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
Quiz
Quiz
Question 1 of 5What is Helm used for in Kubernetes?
Next Steps
Now let's explore cloud computing with AWS—the foundation of modern cloud infrastructure.