Docker Kubernetes
Using Kubernetes with Docker allows you to manage containerized applications at scale with features like automated deployment, scaling, and operations. This guide covers key concepts, steps to set up Kubernetes with Docker, examples, and best practices for deploying Dockerized Express.js applications to Kubernetes.
Key Concepts of Kubernetes
- Pod: The smallest deployable unit in Kubernetes, which can contain one or more containers.
- Service: An abstraction that defines a logical set of Pods and a policy to access them.
- Deployment: Manages the deployment and scaling of Pods.
- ConfigMap: Stores configuration data as key-value pairs.
- Secret: Stores sensitive data such as passwords and API keys.
- Ingress: Manages external access to services, typically HTTP/HTTPS.
- Namespace: A way to divide cluster resources between multiple users.
Setting Up the Project
Initialize a new Express.js project and create a Dockerfile:
// Initialize a new project
// npm init -y
// Install Express
// npm install express
// Create the project structure
// mkdir src
// touch src/index.js Dockerfile .dockerignore .gitignore
// .gitignore
node_modules
.env
// .dockerignore
node_modules
npm-debug.log
Creating an Express Application
Create a simple Express application:
Example: index.js
// src/index.js
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello, Docker Kubernetes!');
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}/`);
});
Creating a Dockerfile
Create a Dockerfile to containerize your Express application:
Example: Dockerfile
// Dockerfile
FROM node:14
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
COPY package*.json ./
RUN npm install
# Bundle app source
COPY . .
# Expose port 3000 to the outside world
EXPOSE 3000
# Run app when the container launches
CMD ["node", "src/index.js"]
Building and Running the Docker Container
Build and run the Docker container for your Express application:
// Build the Docker image
docker build -t my-express-app .
// Run the Docker container
docker run -d -p 3000:3000 --name my-express-app my-express-app
// Open http://localhost:3000 in your browser to see the application running
Setting Up Kubernetes
Set up a Kubernetes cluster and deploy your application:
Creating a Kubernetes Deployment
// deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-express-app
spec:
replicas: 3
selector:
matchLabels:
app: my-express-app
template:
metadata:
labels:
app: my-express-app
spec:
containers:
- name: my-express-app
image: my-express-app:latest
ports:
- containerPort: 3000
Creating a Kubernetes Service
// service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-express-service
spec:
selector:
app: my-express-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
Deploying to Kubernetes
// Apply the deployment and service
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
// Check the status of the deployment
kubectl get deployments
// Check the status of the service
kubectl get services
// Open the external IP of the service in your browser to see the application running
Using ConfigMaps and Secrets
Manage configuration and sensitive data:
Creating a ConfigMap
// configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
NODE_ENV: production
MONGO_URL: mongodb://db:27017/mydatabase
Creating a Secret
// secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
db_password: $(echo -n "mysecretpassword" | base64)
Using ConfigMap and Secret in Deployment
// deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-express-app
spec:
replicas: 3
selector:
matchLabels:
app: my-express-app
template:
metadata:
labels:
app: my-express-app
spec:
containers:
- name: my-express-app
image: my-express-app:latest
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: my-config
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: my-secret
key: db_password
Setting Up Ingress
Manage external access to your services:
Creating an Ingress Resource
// ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-express-service
port:
number: 80
// Apply the ingress resource
kubectl apply -f ingress.yaml
// Check the status of the ingress
kubectl get ingress
// Update your DNS settings to point to the external IP of the ingress controller
// Open http://myapp.example.com in your browser to see the application running
Best Practices for Kubernetes with Docker
- Use Namespaces: Isolate resources by using namespaces for different environments and teams.
- Implement Health Checks: Use readiness and liveness probes to ensure container health.
- Automate Deployments: Use CI/CD pipelines to automate the deployment process.
- Monitor and Log: Integrate monitoring and logging tools to track the health and performance of your applications.
- Secure Access: Use RBAC (Role-Based Access Control) to manage access to your Kubernetes cluster.
- Optimize Resources: Set resource requests and limits to optimize resource usage and prevent overcommitment.
- Use ConfigMaps and Secrets: Manage configuration and sensitive data separately from your application code.
Testing Kubernetes Setup
Test your Kubernetes setup to ensure it works correctly:
Example: Testing with Mocha and Chai
// Install Mocha and Chai
// npm install --save-dev mocha chai
// test/app.test.js
const chai = require('chai');
const expect = chai.expect;
const axios = require('axios');
describe('Express App', () => {
it('should return Hello, Docker Kubernetes!', async () => {
const response = await axios.get('http://localhost:3000');
expect(response.data).to.equal('Hello, Docker Kubernetes!');
});
});
// Add test script to package.json
// "scripts": {
// "test": "mocha"
// }
// Run tests
// docker build -t my-express-app .
// docker run -p 3000:3000 my-express-app
// npm test
Key Points
- Pod: The smallest deployable unit in Kubernetes, which can contain one or more containers.
- Service: An abstraction that defines a logical set of Pods and a policy to access them.
- Deployment: Manages the deployment and scaling of Pods.
- ConfigMap: Stores configuration data as key-value pairs.
- Secret: Stores sensitive data such as passwords and API keys.
- Ingress: Manages external access to services, typically HTTP/HTTPS.
- Namespace: A way to divide cluster resources between multiple users.
- Follow best practices for using Kubernetes with Docker, such as using namespaces, implementing health checks, automating deployments, monitoring and logging, securing access, optimizing resources, and managing configuration and sensitive data with ConfigMaps and Secrets.
Conclusion
Using Kubernetes with Docker allows you to manage containerized applications at scale with features like automated deployment, scaling, and operations. By understanding and implementing the key concepts, steps, examples, and best practices covered in this guide, you can effectively deploy Dockerized Express.js applications to Kubernetes. Happy coding!