Triển khai ứng dụng Node.js + PostgreSQL trên Kubernetes với Ingress – Hướng dẫn thực chiến từ A-Z Chuyên mục Devops 2025-06-17 7 Lượt xem 7 Lượt thích 0 Bình luận
Ảnh nhìn tổng quan
Bài viết này sẽ hướng dẫn bạn triển khai một ứng dụng Node.js kết nối PostgreSQL trên Kubernetes (Minikube), kết hợp với Ingress Controller để truy cập qua domain local simple.local.
Chúng ta sẽ:
- 
Tạo Dockerfile cho Node.js 
- 
Viết Deployment/Service/Postgres YAML 
- 
Dùng Ingress Controller routing domain 
- 
Kết nối API với DB qua Service 
- 
Debug khi gặp lỗi 404, không resolve domain 
1. Cài đặt Minikube + Ingress
minikube start --driver=docker
minikube addons enable ingressLấy IP Minikube:
minikube ip
# Ví dụ: 192.168.49.2Chính sửa /etc/hosts
sudo nano /etc/hostsThêm dòng:
192.168.49.2  simple.local2. Cấu trúc project
my-app/
├── Dockerfile
├── server.js
├── package.json
└── k8s/
    ├── api.yaml
    ├── postgres.yaml
    └── ingress.yaml3. Viết app Node.js
server.js
const express = require('express');
const { Client } = require('pg');
const app = express();
const client = new Client({
  host: process.env.PGHOST || 'postgres-service',
  user: 'postgres',
  password: 'postgres',
  database: 'mydb',
});
client.connect()
  .then(() => console.log('Connected to PostgreSQL'))
  .catch(err => console.error('Connection error', err.stack));
app.get('/', async (req, res) => {
  const result = await client.query('SELECT NOW()');
  res.send(`Time from DB: ${result.rows[0].now}`);
});
app.listen(3000, () => console.log('Server running on port 3000'));package.json
{
  "name": "simple-api",
  "version": "1.0.0",
  "main": "server.js",
  "dependencies": {
    "express": "^4.18.2",
    "pg": "^8.11.1"
  }
}Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"]4. Build & Push image
docker build -t yourdockerhub/simple-api .
docker push yourdockerhub/simple-api(Thay yourdockerhub bằng Docker Hub cá nhân) nhớ đăng nhập vào docker trước nhé !
docker login5. Viết YAML triển khai
postgres.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:15
          env:
            - name: POSTGRES_PASSWORD
              value: postgres
            - name: POSTGRES_DB
              value: mydb
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgres-storage
      volumes:
        - name: postgres-storage
          persistentVolumeClaim:
            claimName: postgres-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: postgres-service
spec:
  selector:
    app: postgres
  ports:
    - port: 5432api.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: simple-api
  template:
    metadata:
      labels:
        app: simple-api
    spec:
      containers:
        - name: simple-api
          image: yourdockerhub/simple-api
          ports:
            - containerPort: 3000
          env:
            - name: PGHOST
              value: postgres-service
---
apiVersion: v1
kind: Service
metadata:
  name: simple-api-service
spec:
  selector:
    app: simple-api
  ports:
    - port: 80
      targetPort: 3000ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-api-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: simple.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: simple-api-service
                port:
                  number: 806. Triển khai Kubernetes
kubectl apply -f k8s/postgres.yaml
kubectl apply -f k8s/api.yaml
kubectl apply -f k8s/ingress.yamlTruy cập: http://simple.local
7. Kiểm tra & Debug
Xem log container
kubectl logs deployment/simple-api
kubectl logs deployment/postgresKiểm tra ingress routing
kubectl get ingress
kubectl describe ingress simple-api-ingressCurl test:
curl -H "Host: simple.local" http://$(minikube ip)8. Kết luận
Đây là một project mẫu hoàn chỉnh dễ hiểu và cực kỳ thïch hợp cho beginner làm quen Kubernetes:
- 
Dựng app backend nối DB qua service 
- 
Dùng Ingress để routing domain 
- 
Build image tự viết và deploy trên local 
 
                        
                                         
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                     
                                                    
Bình luận (0)