# 初入江湖(K8S)

## 先決條件

在開始之前，請確保您的系統上已安裝 Docker 和 Docker Compose，並且將Docker Desktop 開啟 Kubernetes。

啟用指南參考官網：[前往](https://docs.docker.com/desktop/kubernetes/)

<div><figure><img src="https://1934262382-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRmnDr9RXeSmhkUmaUsX7%2Fuploads%2FiZVHVXw1D6GiWvd9agg4%2Fkubernetes_1.png?alt=media&#x26;token=364742ab-c838-47fd-85b1-5a39c5c66350" alt=""><figcaption><p>啟用kubernetes</p></figcaption></figure> <figure><img src="https://1934262382-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRmnDr9RXeSmhkUmaUsX7%2Fuploads%2FhVbR8EUruJP4j8QRg1RQ%2Fkubernetes_2.png?alt=media&#x26;token=b2dc2e9a-c04e-4206-be1b-519adf1dfbb7" alt=""><figcaption><p>確認啟用狀態</p></figcaption></figure></div>

在開始練習之前，我們應該對 Docker 和 Kubernetes 有一定的基本概念，否則會感到困惑。我自己也還有一些細節需要釐清，這就是我們需要深入了解的地方。教學相長，讓我們一同學習！

這次的測試內容為一個最基本的系統架構，包括：

1. MySQL
2. Spring Boot

這是最基礎、最簡單、也是最常見的架構之一。先不包含網管部分的架構，因為我認為這不應該是後端工程師必須具備的技能，不過你若對這方面有需求，網路上有很多資源可以參考。

廢話不多說，上扣！

## 步驟清單

1. 建立 MySQL 服務
2. 確認 MySQL 服務狀況與連線設定
3. 打包專案
4. 撰寫 Dockerfile 建立專案 image
5. Image push 到 Docker Hub（可選）
6. 建立 Spring Boot 服務
7. 進行測試

### 步驟一 至 二：建立 MySQL 服務

以下是一個建立 MySQL 服務的範例，主要包含了建立持久儲存空間、對外曝露的 Service Node 以及建立 MySQL 服務的三個步驟。

檔案名稱：`CreateMySQLV2.yml`

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: mysql-pv-claim
    labels:
        app: mysql
spec:
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
    labels:
        app.kubernetes.io/name: mysql
    name: mysql
spec:
    replicas: 1
    selector:
        matchLabels:
            app.kubernetes.io/name: mysql
    template:
        metadata:
            labels:
                app.kubernetes.io/name: mysql
        spec:
            containers:
                -   image: mysql:8
                    name: mysql
                    env:
                        # 在實際使用時使用密鑰
                        - name: MYSQL_ROOT_PASSWORD
                          value: 1qaz2wsx
                    ports:
                        -   containerPort: 3306
                            name: mysql
                    volumeMounts:
                        -   name: mysql-persistent-storage
                            mountPath: /var/lib/mysql
            volumes:
                -   name: mysql-persistent-storage
                    persistentVolumeClaim:
                        claimName: mysql-pv-claim
---
apiVersion: v1
kind: Service
metadata:
    labels:
        app.kubernetes.io/name: mysql
    name: mysql-service
spec:
    selector:
        app.kubernetes.io/name: mysql
    ports:
        - protocol: TCP
          port: 3309
          targetPort: 3306
          nodePort: 32700
    type: LoadBalancer
```

部署指令：

```shell
kubectl apply -f CreateMySQLV2.yml
```

在執行專案打包前，我們需要確認 MySQL 的內部 IP，可以使用以下指令：

```shell
kubectl get all --output=wide
```

確認可以連線後，可以手動建立資料或在測試專案的 `\resources\db\migration\init.sql` 中有 SQL 可以執行。

<div><figure><img src="https://1934262382-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRmnDr9RXeSmhkUmaUsX7%2Fuploads%2Fo6bi7qmRqeu8qfqhyFgB%2Fkubernetes_3.png?alt=media&#x26;token=dd3d85d1-f845-43c0-9fef-1d8c0fd04bc6" alt=""><figcaption><p>確認 MySQL 對外 IP 與 Port</p></figcaption></figure> <figure><img src="https://1934262382-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRmnDr9RXeSmhkUmaUsX7%2Fuploads%2Fp9VB3QLomJNEXiuf8ErE%2Fkubernetes_4.png?alt=media&#x26;token=39b2f1d3-0872-42ee-9ca8-2accf15f7434" alt=""><figcaption><p>Test connection</p></figcaption></figure></div>

### **步驟三 至 五**：Build image&#x20;

1. 將 MySQL 曝露的 IP 與 Port 寫入 YAML 檔案
2. Package、Build Image，將 Image Push 到 Docker Hub（非必要）

```sh
# Build image command
docker build -t casterhsu/normal:v2 -f ./normal.Dockerfile .
```

### **步驟六**：Deploy

這是一個簡易的部署 Spring Boot 的範例。在將服務部署在 Kubernetes 上，需要做以下事項：

1. 如果有設定 `imagePullPolicy: Never` 則不需將 Image Push 到 Docker Hub
2. 執行 Kubernetes 部署指令

檔案名稱：`CreateNormalV2.yml`

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    labels:
        app.kubernetes.io/name: normal-project
    name: normal
spec:
    replicas: 1
    selector:
        matchLabels:
            app.kubernetes.io/name: normal-project
    template:
        metadata:
            labels:
                app.kubernetes.io/name: normal-project
        spec:
            containers:
                - image: casterhsu/normal:v2
                  imagePullPolicy: Never #當前永遠不從 registry 拉取最新的映像。
                  name: normal-container
                  ports:
                      - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
    labels:
        app.kubernetes.io/name: normal-project
    name: normal-project-service
spec:
    selector:
        app.kubernetes.io/name: normal-project
    ports:
        - protocol: TCP
          port: 9000
          targetPort: 8080
          nodePort: 32701
    type: LoadBalancer
```

部署指令：

```shell
kubectl apply -f CreateNormalV2.yml
```

### **步驟七**：Testing

進行測試，並查看結果。

<figure><img src="https://1934262382-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRmnDr9RXeSmhkUmaUsX7%2Fuploads%2FSQoRdXapXRwEQ2F1WrLT%2Fkubernetes_5.png?alt=media&#x26;token=c535104c-821f-4a7d-a9ea-7eb671bc98c6" alt=""><figcaption></figcaption></figure>

### 參考與附件

* GitHub：[前往](https://github.com/MinchangHsu/normal)
* 基礎教學：[前往](https://chengweihu.com/kubernetes-tutorial-1-pod-node/)
* Minikube：[前往](https://minikube.sigs.k8s.io/docs/)
* Kubernetes官網：[前往](https://kubernetes.io/)
* 國人GitBook：[前往](https://kubernetes.feisky.xyz/)  [繁中版本](https://xu-min-chang.gitbook.io/kubernetes/)

## 結語

這次的實戰範例以 Docker 和 Kubernetes 為基礎，展示了建立一個基本系統架構的步驟。透過實際的操作，我們深入了解了如何建立 MySQL 服務和 Spring Boot 服務，以及在 Kubernetes 上的部署過程。

在這個過程中，我們學到了以下重點：

1. **基本概念的重要性**：在開始之前，對 Docker 和 Kubernetes 有一定的基本觀念是至關重要的，否則可能會感到困惑。
2. **系統架構的基礎**：範例中使用了最基本且最常見的系統架構，包括 MySQL 和 Spring Boot。這是一個適合初學者入門的例子。
3. **Kubernetes 實戰**：通過實際操作，我們學到了如何在 Kubernetes 上建立服務，包括 YAML 檔案的編寫、部署指令的執行等。

最後，這個實戰範例為我們提供了實際的練習機會，強調了基本觀念的重要性，同時也激發了我們對於 Docker 和 Kubernetes 更深入學習的動力。在未來的學習過程中，我們可以進一步挑戰更複雜的系統架構，不斷精進自己的技能。教學相長，讓我們共同進步！


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xu-min-chang.gitbook.io/caster-develop-note/kubernetes/chu-ru-jiang-hu-k8s.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
