Kubernetes
Overview
Kubernetes (often abbreviated as K8s) is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. It was originally developed by Google and is now maintained by the Cloud Native Computing Foundation (CNCF).
Core Concepts
Pods
Pods are the smallest deployable units in Kubernetes. A Pod represents a single instance of a running process in your cluster and can contain one or more containers that share storage and network resources.
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
containers:
- name: app-container
image: nginx:latest
ports:
- containerPort: 80
Deployments
Deployments provide declarative updates for Pods and ReplicaSets. They allow you to describe the desired state of your application, and the Deployment controller changes the actual state to match the desired state.
apiVersion: apps/v1
kind: Deployment
metadata:
name: example-deployment
spec:
replicas: 3
selector:
matchLabels:
app: example
template:
metadata:
labels:
app: example
spec:
containers:
- name: app
image: example-app:1.0
ports:
- containerPort: 8080
Services
Services provide a stable endpoint to access a group of Pods. They enable network access to a set of Pods and provide load balancing across them.
Service Types:
- ClusterIP: Exposes the service on an internal IP within the cluster (default)
- NodePort: Exposes the service on each Node's IP at a static port
- LoadBalancer: Exposes the service externally using a cloud provider's load balancer
- ExternalName: Maps the service to a DNS name
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: LoadBalancer
ConfigMaps and Secrets
ConfigMaps store non-confidential configuration data in key-value pairs, while Secrets store sensitive information such as passwords, tokens, or keys.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database_url: "postgres://db:5432"
log_level: "info"
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
password: cGFzc3dvcmQxMjM=
Note: Secret data values are base64-encoded, not encrypted. For encryption at rest, enable etcd encryption or use an external secrets manager.
Namespaces
Namespaces provide a mechanism for isolating groups of resources within a single cluster. They are useful for dividing cluster resources between multiple users or teams.
Persistent Volumes (PV) and Persistent Volume Claims (PVC)
Persistent Volumes provide a way to store data that persists beyond the lifecycle of individual Pods. PVCs are requests for storage by users.
Kubernetes Architecture
Kubernetes follows a control plane / node architecture:
Control Plane Components:
- API Server: The front-end for the Kubernetes control plane
- etcd: Consistent and highly-available key-value store for all cluster data
- Scheduler: Assigns Pods to Nodes based on resource requirements
- Controller Manager: Runs controller processes to regulate the state of the cluster
Node Components:
- kubelet: Agent that ensures containers are running in Pods
- kube-proxy: Maintains network rules for Pod communication
- Container Runtime: Software responsible for running containers (e.g., containerd, CRI-O)
Packaging with Helm
What is Helm?
Helm is the package manager for Kubernetes, often described as the "apt/yum/homebrew for Kubernetes." It simplifies the deployment and management of applications on Kubernetes clusters by packaging all the necessary resources into reusable charts.
Key Concepts
Helm Charts: A collection of files that describe a related set of Kubernetes resources. A chart contains:
Chart.yaml: Metadata about the chart (name, version, description)values.yaml: Default configuration valuestemplates/: Directory containing Kubernetes manifest templatescharts/: Directory for chart dependencies (optional)
Releases: An instance of a chart running in a Kubernetes cluster. Each installation of a chart creates a new release.
Repositories: Locations where charts can be stored and shared.
Basic Helm Chart Structure
my-app/
├── Chart.yaml
├── values.yaml
├── charts/
└── templates/
├── deployment.yaml
├── service.yaml
├── ingress.yaml
├── configmap.yaml
└── _helpers.tpl
Example Chart.yaml
apiVersion: v2
name: my-app
description: A Helm chart for my application
type: application
version: 0.1.0
appVersion: "1.0"
Example values.yaml
replicaCount: 3
image:
repository: my-app
tag: "1.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: ""
hosts:
- host: example.local
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
Template Example (templates/deployment.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.fullname" . }}
labels:
{{- include "my-app.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "my-app.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-app.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 8080
protocol: TCP
resources:
{{- toYaml .Values.resources | nindent 12 }}
Common Helm Commands
# Search for charts in repositories
helm search repo <keyword>
# Install a chart
helm install <release-name> <chart-name>
# Install with custom values
helm install <release-name> <chart-name> -f custom-values.yaml
# List all releases
helm list
# Upgrade a release
helm upgrade <release-name> <chart-name>
# Rollback to a previous release
helm rollback <release-name> <revision>
# Uninstall a release
helm uninstall <release-name>
# Create a new chart
helm create <chart-name>
# Validate chart syntax
helm lint <chart-path>
# Package a chart for distribution
helm package <chart-path>
Best Practices for Helm Charts
- Use values.yaml for configuration: Keep all configurable parameters in values.yaml rather than hardcoding them in templates
- Include resource limits: Always specify resource requests and limits for containers
- Use helper templates: Create reusable template functions in
_helpers.tplfor labels and selectors - Document your values: Add comments in values.yaml explaining each configuration option
- Version your charts: Follow semantic versioning for both chart version and app version
- Test your charts: Use
helm lintandhelm templateto validate before installation - Use .helmignore: Exclude unnecessary files from your chart package
- Implement health checks: Include liveness and readiness probes in your deployments