# Bài 19: Spring Boot với Kubernetes

### 1\. Giới thiệu về Kubernetes

**Kubernetes** (K8s) là một nền tảng mã nguồn mở để quản lý các container. Kubernetes giúp tự động hóa việc triển khai, mở rộng và quản lý các ứng dụng container. Nó cung cấp các tính năng mạnh mẽ như cân bằng tải, quản lý tài nguyên, và tự động khôi phục lỗi.

### 2\. Lợi ích của Kubernetes

* **Tự động hóa triển khai và quản lý**: Kubernetes tự động hóa các công việc phức tạp như triển khai và quản lý ứng dụng.
    
* **Khả năng mở rộng**: Dễ dàng mở rộng hoặc thu nhỏ ứng dụng theo yêu cầu.
    
* **Tự phục hồi**: Kubernetes tự động khởi động lại các container bị lỗi, thay thế các container chết và thực hiện các kiểm tra sức khỏe định kỳ.
    
* **Cân bằng tải**: Phân phối lưu lượng mạng đến các container để tối ưu hiệu suất và độ tin cậy.
    

### 3\. Cách tích hợp Spring Boot với Kubernetes

#### 3.1. Chuẩn bị ứng dụng Spring Boot

Trước khi triển khai ứng dụng Spring Boot lên Kubernetes, bạn cần chuẩn bị ứng dụng và container hóa nó bằng Docker.

**Dockerfile cho ứng dụng Spring Boot**:

```Dockerfile
# Sử dụng image chính thức của OpenJDK làm base image
FROM openjdk:11-jre-slim

# Đặt thư mục làm việc trong container
WORKDIR /app

# Sao chép file JAR của ứng dụng vào container
COPY target/myapp.jar /app/myapp.jar

# Expose cổng mà ứng dụng sẽ chạy
EXPOSE 8080

# Lệnh để chạy ứng dụng
ENTRYPOINT ["java", "-jar", "myapp.jar"]
```

**Xây dựng image Docker**:

```bash
docker build -t myapp:latest .
```

#### 3.2. Cấu hình Kubernetes

Để triển khai ứng dụng Spring Boot lên Kubernetes, bạn cần tạo các file cấu hình Kubernetes như Deployment, Service, và ConfigMap.

**Deployment**:

```yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        ports:
        - containerPort: 8080
        env:
        - name: SPRING_DATASOURCE_URL
          value: jdbc:mysql://mysql:3306/mydb
        - name: SPRING_DATASOURCE_USERNAME
          value: root
        - name: SPRING_DATASOURCE_PASSWORD
          value: root
```

**Service**:

```yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
  type: LoadBalancer
```

**ConfigMap**:

```yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myapp-config
data:
  SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mydb
  SPRING_DATASOURCE_USERNAME: root
  SPRING_DATASOURCE_PASSWORD: root
```

#### 3.3. Triển khai ứng dụng lên Kubernetes

Để triển khai ứng dụng lên Kubernetes, bạn cần sử dụng `kubectl`, công cụ dòng lệnh của Kubernetes.

**Triển khai Deployment**:

```bash
kubectl apply -f deployment.yaml
```

**Triển khai Service**:

```bash
kubectl apply -f service.yaml
```

**Triển khai ConfigMap**:

```bash
kubectl apply -f configmap.yaml
```

#### 3.4. Kiểm tra trạng thái triển khai

Bạn có thể kiểm tra trạng thái của các Deployment và Service bằng cách sử dụng các lệnh `kubectl`.

**Kiểm tra trạng thái Deployment**:

```bash
kubectl get deployments
kubectl describe deployment myapp-deployment
```

**Kiểm tra trạng thái Service**:

```bash
kubectl get services
kubectl describe service myapp-service
```

### 4\. Ví dụ chi tiết

Dưới đây là một ví dụ chi tiết từ đầu đến cuối về cách triển khai ứng dụng Spring Boot lên Kubernetes.

#### 4.1. Tạo dự án Spring Boot

Sử dụng Spring Initializr để tạo dự án với các dependency sau:

* Spring Web
    
* Spring Data JPA
    
* MySQL Driver
    

#### 4.2. Cấu trúc dự án

```plaintext
myapp
|-- src
|   |-- main
|   |   |-- java
|   |   |   `-- com
|   |   |       `-- example
|   |   |           `-- myapp
|   |   |               |-- MySpringBootApplication.java
|   |   |               |-- entity
|   |   |               |   `-- User.java
|   |   |               |-- repository
|   |   |               |   `-- UserRepository.java
|   |   |               `-- controller
|   |   |                   `-- UserController.java
|   |   `-- resources
|   |       `-- application.properties
|-- Dockerfile
|-- deployment.yaml
|-- service.yaml
|-- configmap.yaml
|-- pom.xml
```

#### 4.3. Tạo Dockerfile

Tạo file `Dockerfile` trong thư mục gốc của dự án.

**Dockerfile**:

```Dockerfile
# Sử dụng image chính thức của OpenJDK làm base image
FROM openjdk:11-jre-slim

# Đặt thư mục làm việc trong container
WORKDIR /app

# Sao chép file JAR của ứng dụng vào container
COPY target/myapp.jar /app/myapp.jar

# Expose cổng mà ứng dụng sẽ chạy
EXPOSE 8080

# Lệnh để chạy ứng dụng
ENTRYPOINT ["java", "-jar", "myapp.jar"]
```

#### 4.4. Cấu hình ứng dụng Spring Boot

Cấu hình kết nối cơ sở dữ liệu trong file [`application.properties`](http://application.properties).

```plaintext
spring.datasource.url=${SPRING_DATASOURCE_URL}
spring.datasource.username=${SPRING_DATASOURCE_USERNAME}
spring.datasource.password=${SPRING_DATASOURCE_PASSWORD}
spring.jpa.hibernate.ddl-auto=update
```

#### 4.5. Tạo file cấu hình Kubernetes

Tạo các file `deployment.yaml`, `service.yaml`, và `configmap.yaml`.

**deployment.yaml**:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        ports:
        - containerPort: 8080
        envFrom:
        - configMapRef:
            name: myapp-config
```

**service.yaml**:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 8080
  type: LoadBalancer
```

**configmap.yaml**:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myapp-config
data:
  SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mydb
  SPRING_DATASOURCE_USERNAME: root
  SPRING_DATASOURCE_PASSWORD: root
```

#### 4.6. Xây dựng và đẩy image Docker lên registry

Xây dựng image Docker:

```bash
docker build -t myapp:latest .
```

Đăng nhập vào Docker Hub (hoặc registry khác):

```bash
docker login
```

Đẩy image lên Docker Hub:

```bash
docker tag myapp:latest myusername/myapp:latest
docker push myusername/myapp:latest
```

#### 4.7. Triển khai ứng dụng lên Kubernetes

Sử dụng `kubectl` để triển khai các file cấu hình Kubernetes.

**Triển khai ConfigMap**:

```bash
kubectl apply -f configmap.yaml
```

**Triển khai Deployment**:

```bash
kubectl apply -f deployment.yaml
```

**Triển khai Service**:

```bash
kubectl apply -f service.yaml
```

#### 4.8. Kiểm tra trạng thái triển khai

Kiểm tra trạng thái của các Deployment và Service bằng cách sử dụng `kubectl`.

**Kiểm tra trạng thái Deployment**:

```bash
kubectl get deployments
kubectl describe deployment myapp-deployment
```

**Kiểm tra trạng thái Service**:

```bash
kubectl get services
kubectl describe service myapp-service
```

### 5\. Kết luận

Trong bài viết này, chúng ta đã tìm hiểu về cách triển khai ứng dụng Spring Boot lên Kubernetes

, từ việc tạo Dockerfile, cấu hình Kubernetes, đến triển khai và kiểm tra trạng thái. Kubernetes cung cấp một nền tảng mạnh mẽ để quản lý và triển khai các ứng dụng container, giúp tự động hóa các quy trình phức tạp và tăng cường độ tin cậy và hiệu suất của ứng dụng.

Trong bài viết tiếp theo, chúng ta sẽ tìm hiểu về các best practices khi phát triển ứng dụng Spring Boot và các kỹ thuật tối ưu hiệu suất ứng dụng.
