Introduction to Kubernetes
In our previous lecture, we explored container orchestration principles and compared various platforms. Now, we'll dive deep into Kubernetes (often abbreviated as K8s), which has emerged as the de facto standard for container orchestration.
Kubernetes, Greek for "helmsman" or "pilot," was originally developed by Google based on their internal system called Borg. In 2014, Google open-sourced Kubernetes, and it was later donated to the Cloud Native Computing Foundation (CNCF). Today, it's a mature, production-ready platform used by organizations of all sizes to run containerized applications at scale.
Kubernetes stands out for its comprehensive approach to container orchestration, rich ecosystem, and passionate community. It's designed to be extensible, allowing developers to add custom resources and controllers for specialized workloads. This flexibility, combined with its declarative approach to infrastructure, makes Kubernetes suitable for a wide range of applications, from simple web services to complex, stateful applications.
In this lecture, we'll explore the core concepts and components of Kubernetes, building the foundation you need to deploy and manage applications effectively.
Kubernetes Architecture
High-Level Architecture
At a high level, Kubernetes consists of a control plane (master components) and worker nodes:
Control Plane Components
The control plane is the brain of Kubernetes, responsible for making global decisions about the cluster:
- API Server (kube-apiserver): The front end of the Kubernetes control plane, exposing the Kubernetes API. All communication between components goes through the API server.
- etcd: A consistent and highly-available key-value store used as Kubernetes' backing store for all cluster data.
- Scheduler (kube-scheduler): Watches for newly created pods with no assigned node and selects a node for them to run on.
- Controller Manager (kube-controller-manager): Runs controller processes that regulate the state of the cluster (node controller, replication controller, endpoints controller, etc.).
- Cloud Controller Manager: Links the cluster to cloud provider APIs, allowing the cluster to interact with cloud resources.
Node Components
Worker nodes are the machines that run your applications and cloud workflows:
- kubelet: An agent that runs on each node, ensuring containers are running in a pod. It takes a set of PodSpecs and ensures the containers described are running and healthy.
- kube-proxy: Maintains network rules on nodes, allowing network communication to your pods from inside or outside the cluster.
- Container Runtime: The software responsible for running containers (Docker, containerd, CRI-O, etc.).
Addons
Kubernetes clusters often include additional components to provide cluster features:
- DNS: Cluster DNS for service discovery
- Dashboard: Web UI for cluster management
- Container Resource Monitoring: Records metrics about containers
- Cluster-level Logging: Saves container logs to a central log store
- Network Plugins: Implements the Container Network Interface (CNI)
Communication Flow
Understanding how components communicate helps troubleshoot issues:
Kubernetes Object Model
Understanding Kubernetes Objects
Kubernetes objects are persistent entities that represent the state of your cluster. They describe:
- What containerized applications are running
- The resources available to them
- Policies around how they behave (restart, upgrade, fault-tolerance)
Every object includes two nested fields:
- Spec: Provided by you, describes the desired state
- Status: Provided by Kubernetes, describes the current state
Kubernetes constantly works to make the current state match the desired state.
Object Definitions
Objects are typically defined in YAML files with these required fields:
# Basic structure of a Kubernetes object definition
apiVersion: v1 # Which API version to use
kind: Pod # What kind of object
metadata: # Data to uniquely identify the object
name: nginx-pod
labels:
app: nginx
spec: # The desired state of the object
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Core Kubernetes Objects
Let's explore the fundamental objects that form the building blocks of Kubernetes applications:
Pods - The Basic Unit
Pod Concept
A Pod is the smallest deployable unit in Kubernetes. It represents a single instance of a running process in your cluster.
Think of a Pod as a logical host - it contains one or more containers that:
- Share the same network namespace (IP address and ports)
- Share the same IPC namespace
- Share the same hostname
- Can communicate using localhost
- Can share storage volumes
An analogy for a Pod is an apartment in a building. The apartment (Pod) can have one or more rooms (containers) that share common facilities (network, storage). The building itself is the node, housing multiple apartments.
Pod Lifecycle
Pods have a defined lifecycle:
- Pending: The Pod has been accepted but containers are not yet running
- Running: At least one container is running
- Succeeded: All containers have terminated successfully
- Failed: At least one container has terminated with failure
- Unknown: The state couldn't be determined
Pod Definition
Here's a simple Pod definition:
apiVersion: v1
kind: Pod
metadata:
name: web-app
labels:
app: web
tier: frontend
spec:
containers:
- name: web-app
image: nginx:1.19
ports:
- containerPort: 80
resources:
limits:
cpu: "0.5"
memory: "512Mi"
requests:
cpu: "0.2"
memory: "256Mi"
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 10
Multi-Container Pods
While you can run multiple containers in a Pod, it's best to keep them focused on a single concern. Here's an example of a Pod with a main container and a sidecar:
apiVersion: v1
kind: Pod
metadata:
name: web-app-with-logging
spec:
containers:
- name: web-app
image: nginx:1.19
ports:
- containerPort: 80
volumeMounts:
- name: logs
mountPath: /var/log/nginx
- name: log-collector
image: fluent/fluentd:v1.11
volumeMounts:
- name: logs
mountPath: /var/log/nginx
readOnly: true
volumes:
- name: logs
emptyDir: {}
Pod Placement and Scheduling
You can influence where Pods are scheduled using:
- Node Selectors: Simple key-value matching
- Node Affinity/Anti-Affinity: More sophisticated node selection
- Pod Affinity/Anti-Affinity: Placing Pods relative to other Pods
- Taints and Tolerations: Node-level restrictions
# Node selector example
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
nodeSelector:
gpu: "true"
containers:
- name: gpu-container
image: ml-training:latest
When to Use Pods Directly vs. Controllers
Direct Pod usage is rare in production and usually limited to:
- Development and testing
- One-time jobs
- Static Pods managed by the kubelet
In most cases, you'll use controllers like Deployments or StatefulSets to manage Pods.
Controllers for Pod Management
Understanding Controllers
Controllers are control loops that watch the state of your cluster and make changes to move the current state towards the desired state. They manage the lifecycle of Pods and provide additional features like scaling and updates.
Deployments
Deployments provide declarative updates for Pods and ReplicaSets. They're ideal for stateless applications.
Key features of Deployments:
- Scaling up and down
- Rolling updates
- Rollbacks to previous versions
- Pause and resume of deployments
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
resources:
limits:
cpu: "0.5"
memory: "512Mi"
requests:
cpu: "0.2"
memory: "256Mi"
ReplicaSets
ReplicaSets ensure a specified number of Pod replicas are running at any given time. Usually, you don't create ReplicaSets directly but use Deployments instead.
# Usually created automatically by Deployments
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
StatefulSets
StatefulSets are used for applications that require stable network identities and persistent storage, like databases.
Key features of StatefulSets:
- Stable, unique network identifiers
- Stable, persistent storage
- Ordered, graceful deployment and scaling
- Ordered, automated rolling updates
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: "postgres"
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:13
ports:
- containerPort: 5432
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "standard"
resources:
requests:
storage: 10Gi
DaemonSets
DaemonSets ensure all (or some) nodes run a copy of a Pod. As nodes are added to the cluster, Pods are added to them.
Common uses for DaemonSets:
- Cluster storage daemons
- Log collection daemons
- Node monitoring daemons
- Network plugins
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v3.0.1
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
Jobs and CronJobs
Jobs create Pods that run until successful completion. CronJobs create Jobs on a schedule.
Use cases:
- Batch processing
- Data migrations
- Backups
- Scheduled reports
# Job example
apiVersion: batch/v1
kind: Job
metadata:
name: data-processor
spec:
template:
spec:
containers:
- name: processor
image: data-processor:latest
restartPolicy: OnFailure
# CronJob example
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-backup
spec:
schedule: "0 2 * * *" # Every day at 2 AM
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:latest
restartPolicy: OnFailure
Choosing the Right Controller
The right controller depends on your application's requirements:
| Controller | Best For | Examples |
|---|---|---|
| Deployment | Stateless applications | Web servers, API services, microservices |
| StatefulSet | Stateful applications | Databases, clustered applications, applications requiring stable IDs |
| DaemonSet | Node-level operations | Monitoring agents, log collectors, network plugins |
| Job | One-time tasks | Data processing, migrations, batch operations |
| CronJob | Scheduled tasks | Backups, reports, periodic cleanups |
Service Discovery and Networking
The Service Abstraction
Services provide a stable endpoint to access a group of Pods. They solve the problem of Pod IP addresses changing due to scaling, failures, or upgrades.
Services use selectors to identify the Pods they should send traffic to and provide load balancing automatically.
Service Types
Kubernetes offers several types of Services:
- ClusterIP: Internal-only IP address, accessible only 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 a Service to a DNS name rather than to a selector
Service Definition Examples
# ClusterIP Service (default)
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- port: 80
targetPort: 8080
type: ClusterIP
# NodePort Service
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # Optional, Kubernetes assigns if not specified
type: NodePort
# LoadBalancer Service
apiVersion: v1
kind: Service
metadata:
name: public-service
spec:
selector:
app: public
ports:
- port: 80
targetPort: 8080
type: LoadBalancer
Service Discovery
Kubernetes provides built-in service discovery through:
- Environment Variables: For each active Service, Kubernetes injects environment variables into Pods
- DNS: Kubernetes DNS server watches for new Services and creates DNS records
Using DNS is the recommended approach. Services are accessible at {service-name}.{namespace}.svc.cluster.local.
Ingress Controllers
Ingress is not a Service type but a higher-level resource that manages external access to Services, typically HTTP:
Ingress provides:
- Load balancing
- SSL termination
- Name-based virtual hosting
- Path-based routing
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /app
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
tls:
- hosts:
- example.com
secretName: example-tls
Configuration and Secrets
ConfigMaps
ConfigMaps allow you to decouple configuration from container images, making applications more portable:
# Creating a ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.host: "db.example.com"
database.port: "5432"
ui.properties: |
color.background=white
color.foreground=black
theme=light
# Using a ConfigMap in a Pod
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: database.port
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
Secrets
Secrets are similar to ConfigMaps but designed for sensitive data. They are:
- Base64 encoded (not encrypted by default)
- Stored in etcd
- Only distributed to nodes that run Pods needing them
- Loaded into memory (not written to disk)
# Creating a Secret
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
data:
username: YWRtaW4= # base64 encoded "admin"
password: cGFzc3dvcmQxMjM= # base64 encoded "password123"
# Using a Secret in a Pod
apiVersion: v1
kind: Pod
metadata:
name: db-client
spec:
containers:
- name: db-client
image: db-client:1.0
env:
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-credentials
Secret Management Best Practices
For production environments, consider these best practices:
- Use an external secrets management solution (HashiCorp Vault, AWS Secrets Manager, etc.)
- Enable encryption at rest for etcd
- Implement RBAC to restrict Secret access
- Use Secret immutability to prevent unwanted changes
- Regularly rotate secrets
Storage in Kubernetes
Understanding Kubernetes Storage
Containers are ephemeral by nature, so any data stored inside a container is lost when the container restarts. Kubernetes provides several abstractions to handle persistent storage:
Basic Volumes
Volumes are tied to a Pod's lifecycle and support many types:
- emptyDir: Empty directory created when a Pod is assigned to a Node
- hostPath: Mounts a directory from the Node's filesystem
- configMap/secret: Mount ConfigMap or Secret as a volume
- nfs: NFS share mounted into the Pod
- Various cloud provider volumes: AWS EBS, Azure Disk, GCE PD, etc.
# Pod with an emptyDir volume
apiVersion: v1
kind: Pod
metadata:
name: cache-pod
spec:
containers:
- name: app
image: app:1.0
volumeMounts:
- name: cache-volume
mountPath: /cache
volumes:
- name: cache-volume
emptyDir: {}
Persistent Volumes and Claims
For storage that exists beyond a Pod's lifecycle:
- PersistentVolume (PV): Cluster-wide storage resource provisioned by an administrator
- PersistentVolumeClaim (PVC): Request for storage by a user
- StorageClass: Describes the "class" of storage offered
# StorageClass definition
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
# PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-claim
spec:
storageClassName: fast
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
# Pod using a PVC
apiVersion: v1
kind: Pod
metadata:
name: database
spec:
containers:
- name: db
image: postgres:13
volumeMounts:
- name: data-volume
mountPath: /var/lib/postgresql/data
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: data-claim
Dynamic Provisioning
StorageClasses enable dynamic provisioning of PersistentVolumes when PersistentVolumeClaims are created:
- Define a StorageClass with a provisioner
- Create a PVC that references the StorageClass
- The provisioner automatically creates a PV that matches the PVC
- The PVC is bound to the new PV
This automation simplifies storage management in cloud environments.
Role-Based Access Control (RBAC)
RBAC Concepts
RBAC is a method of regulating access to resources based on roles assigned to users. In Kubernetes, it involves:
- Subjects: Who can access (Users, Groups, ServiceAccounts)
- Resources: What can be accessed (Pods, Services, etc.)
- Verbs: What actions can be performed (get, list, create, etc.)
- Roles/ClusterRoles: Collections of rules that define permissions
- RoleBindings/ClusterRoleBindings: Bind subjects to roles
RBAC Examples
# Role (namespace-scoped)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
# RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
# ClusterRole (cluster-wide)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
# ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: managers
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
ServiceAccounts
ServiceAccounts provide identities for processes running in Pods to interact with the Kubernetes API:
# Creating a ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-service-account
namespace: default
# Using a ServiceAccount in a Pod
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
serviceAccountName: app-service-account
containers:
- name: app
image: app:1.0
RBAC Best Practices
- Follow the principle of least privilege
- Use namespaces to isolate resources
- Create specific roles for specific tasks
- Audit RBAC permissions regularly
- Use groups rather than individual users when possible
- Consider using an external identity provider
Namespaces and Resource Isolation
Understanding Namespaces
Namespaces provide a mechanism for isolating groups of resources within a cluster. They are particularly useful in multi-tenant environments where multiple teams or projects share a Kubernetes cluster.
Namespaces provide:
- Scope for names (resources must have unique names within a namespace)
- Basis for authorization policies
- Ability to limit resources per namespace
# Creating a namespace
apiVersion: v1
kind: Namespace
metadata:
name: development
# Deploying to a specific namespace
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: development
spec:
# ... deployment details ...
Resource Quotas
ResourceQuotas provide constraints that limit aggregate resource consumption per namespace:
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: development
spec:
hard:
pods: "20"
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
services: "10"
persistentvolumeclaims: "5"
Limit Ranges
LimitRanges set default resource limits for Pods in a namespace:
apiVersion: v1
kind: LimitRange
metadata:
name: dev-limits
namespace: development
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 256Mi
defaultRequest:
cpu: 100m
memory: 128Mi
max:
cpu: 2
memory: 1Gi
min:
cpu: 50m
memory: 64Mi
Practical Exercise: Deploying a Multi-tier Application
Scenario
In this exercise, you'll deploy a simple multi-tier web application consisting of:
- A frontend web server (Nginx)
- A backend API service (Node.js)
- A database (MongoDB)
Exercise Tasks
- Create a namespace for the application
- Deploy the MongoDB database using a StatefulSet with persistent storage
- Deploy the backend API using a Deployment
- Deploy the frontend using a Deployment
- Create Services for all components
- Set up an Ingress for external access
- Configure the application using ConfigMaps and Secrets
Solution Outline
Here's a starting point for your solution:
# 1. Create namespace
apiVersion: v1
kind: Namespace
metadata:
name: web-app
# 2. ConfigMap for application configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: web-app
data:
api.url: "http://backend-service:3000"
database.host: "mongo-service"
database.port: "27017"
database.name: "webappdb"
# 3. Secret for database credentials
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
namespace: web-app
type: Opaque
data:
username: YWRtaW4=
password: cGFzc3dvcmQxMjM=
# 4. MongoDB StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongo
namespace: web-app
spec:
serviceName: "mongo-service"
replicas: 1
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongo
image: mongo:4.4
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
volumeMounts:
- name: mongo-data
mountPath: /data/db
volumeClaimTemplates:
- metadata:
name: mongo-data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
# 5. MongoDB Service
apiVersion: v1
kind: Service
metadata:
name: mongo-service
namespace: web-app
spec:
selector:
app: mongo
ports:
- port: 27017
targetPort: 27017
clusterIP: None # Headless service for StatefulSet
# 6. Backend API Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: web-app
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: your-backend-image:latest
ports:
- containerPort: 3000
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: database.port
- name: DB_NAME
valueFrom:
configMapKeyRef:
name: app-config
key: database.name
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
# 7. Backend Service
apiVersion: v1
kind: Service
metadata:
name: backend-service
namespace: web-app
spec:
selector:
app: backend
ports:
- port: 3000
targetPort: 3000
# 8. Frontend Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: web-app
spec:
replicas: 3
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: your-frontend-image:latest
ports:
- containerPort: 80
env:
- name: API_URL
valueFrom:
configMapKeyRef:
name: app-config
key: api.url
# 9. Frontend Service
apiVersion: v1
kind: Service
metadata:
name: frontend-service
namespace: web-app
spec:
selector:
app: frontend
ports:
- port: 80
targetPort: 80
# 10. Ingress for external access
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
namespace: web-app
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: web-app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 3000
Complete this exercise by applying these manifests to a Kubernetes cluster. You may need to adjust the images and specific details to match your environment.
Conclusion
Kubernetes provides a powerful platform for container orchestration with a rich set of abstractions. By understanding these core concepts, you can effectively deploy and manage applications in a containerized environment.
Key takeaways from this lecture include:
- Kubernetes Architecture: Control plane and worker nodes working together to manage applications
- Pods: The basic building blocks that contain your containers
- Controllers: Higher-level abstractions like Deployments and StatefulSets that manage Pods
- Services: Stable networking endpoints for accessing your applications
- Configuration: ConfigMaps and Secrets for managing application settings
- Storage: Persistent volumes for data that outlives container restarts
- RBAC: Security controls for access management
- Namespaces: Logical isolation of resources within a cluster
As you continue your Kubernetes journey, remember that mastering these fundamental concepts will provide a solid foundation for working with this powerful platform.
Additional Resources
- Kubernetes Official Documentation
- Kubernetes Basics Interactive Tutorial
- Kubernetes Examples Repository
- KubeAcademy by VMware
- Certified Kubernetes Administrator (CKA)
- kubectl Cheat Sheet
- Helm Documentation - Package manager for Kubernetes
- Lens - Kubernetes IDE for simplified management