###### tags: `lsa` `ncnu` # Week 11 (2023/05/04) - Book mode: https://hackmd.io/@ncnu-opensource/book [TOC] --- - docker-compose.yml ```c= version: "3.9" services: demowebapi: image: httpd:latest ports: - 8900:80 deploy: replicas: 2 resources: limits: cpus: "0.30" memory: 500M reservations: cpus: '0.20' memory: 100M placement: constraints: - node.role == worker ``` - 在 manager node 部屬 stack,docker swarm 會再把 tasks 部屬到各個 node - 部屬使用 docker-compose.yml 進行部屬 - `docker stack deploy -c <composeFileName> <stack name>` - `-c` compose 路徑 - 如果需要重新部屬,再下一次指令就好 - `docker stack ls`列出所有 stack - `docker stack services <stack name>` 列出此 stack 服務 - `docker service ls` 列出所有的服務 - 可以看一下是不是所有的 `replicas` 是不是有正常運行(2/2) - 不正常運行 `replocas` 會顯示 0/2 - `docker service ps <service name>` 列出服務所有的 replica task ## Kubernetes - 又稱為 k8s - 由 Google 開發的工具,使用的原因和 docker swarm 類似 : - 有效率地管理和部屬多台容器在多個伺服器 - k8s 有更多的 component, object 可以使用 :point_right: 對於大規模的公司的伺服器管理更有效率 ### 架構 - 會先建立一個 k8s 的叢集,由 Master node (control plane) 和其他的 woker node 共同運作  - woker node 主要負責執行實際運作的 pod - Master node 會負責部屬、管理 worker node 和其他運作的 pod - 大部分情況下一個 pod 裡面只會有一個 container,如果太多 container 就容易互相搶奪資源(因為資源是共享的) - 如果是彼此相依性很高的 container 就會集中在同一個 container - Adapter pattern 標準化容器應用程式的輸出 - (舉例)有兩個不同的應用城市,分別是 node.js and php 開發,而且他們各有 package 可以算出 server 對於每一次的 request 的 request time,但格式不同。一個是 [日期,總回應時間],另外一個 [開始時間,結束時間]。想要把這兩個不同的計算方式紀錄成同樣的格式,就可以用 Adapter pattern - service mesh : 一個管理層,管理 pod 之間的流量 - 主要實作方式 : 在每個 pod 之中新增一個額外的 container 作為 proxy - 當有流量進出 pod,流量都會先經過此 container - 再去 service mesh control plane ( 針對不同 pod 的流量的不同設定 ) 確認對此流量,需採取哪些行動。 - 可以用 mTLS 的方式對 pod 間做流量加密,需要有特定的 pod 才可以連接其他的 pod  :::info ### mTLS - 一種加密方式,會先確認連線雙方的身份是符合自己宣告的,再為雙方建立加密通道。 ::: - 主要常見來在 k8s 中實現 service mesh 的軟體 : - [istio](https://istio.io/latest/) - [linkerd](https://linkerd.io/) - Master node (control plane) 常用的 componemt - apiserver: 驗證是不是有權限,如果有權限就可以做 CRUD - kube-controller-manager - 持續透過 api-server 監控整個叢集內部的狀態的 daemon,裡面是由多個 controller 組成 - cloud controller - controller 會去和雲端供應商自己設定 api 溝通叢集內部的狀態 - controller會檢查叢集中視不是有 node 不正常,會先去詢問雲端供應商是否要把 node 移除 - service controller - etcd - woker node 常用的 compoent - kubelet - 會依照由 mater node 指派給自己傅的 podSpec(pod 規格) - container runtime 容器的執行環境 - CNI:CNCF 組織開發的 poject,配置容器網路的規範和實際執行的函式庫組成的 - deplotment - 在一般的情況下m會有多個 pod 組成,藉由 service 讓外部存取deployment 管理的 pods - deployment 會確保 pod 維持在一定的數量,如果其中有 pod 被刪掉或是無法運作,就會自己嘗試建立新的 pod - Service - 有一個固定 IP > 舊的 pod 被刪掉,再建立新的 pod ,前後兩者的 IP 會相同 - 可以綁定一群的 pods - 藉由連到 service , node 上的 kube-proxy 預設的 mode 就會使用 iptables 導向這個服務綁定的其中一個正常的 pod - kube-proxy 常用的 mode - iptables - ipvs - 數量在 service 較多 - 一個 load balancer,使用 hash table 存放 service 對應的 pod 的 IP,可以把 service 的流量轉發到 pod ### K8s 簡單實做 web application - 先建立一個 pod : `k8s.yml` > 每個資源都會有自己的 yml ```yml= apiVersion: v1 kind: Pod metadata: name: kubernetes-demo-pod-1 labels: app: demoApp spec: containers: - name: kubernetes-demo-container-1 image: hcwxd/purple-whale ports: - containerPort: 3000 ``` - `apiVersion` : 要使用的 `k8s api` 版本 - `vx` : `x` 為數字 - 查看目前的 `k8s` 有哪些 `api-version` : ```cmd= microk8s kubectl api-version ``` - `kind` : 要建立的資源種類 - 常見種類 : `Pod`、`Node`、`Service`、`Namespace`、`ReplicationController` - `metdata` : 此資源的資訊 - `metadata.name` : 此資源的名字 - `metadata.labels` : 此資源的標籤 - `spec` 資源的規格 - `containers` : 此資源容器的規格 - `containerPort` : 該 container 允許外部存取的 port - `microk8s kubectl get pods` 查看目前的 pod - `status` 一開始的建立狀態為 `pending`,開始執行為 `running` - `curl localhost:3000` 看一下本地的 port 有沒有跑起來 - 缺點 - 不容易管理 - 容易忘記 `pod` 開了哪些 port - 沒有 load balance - 沒有高可用性 ### Deployment ( 進階 componet) - 為 `pod` 和 `ReplicaSet` 提供宣告式的部屬和管理方式 :point_right: 方便更新 `pods` - `ReplicaSet` : - 由多個功能相同的 `pods` 所組成 - 負責管理 `pod` 的數量 : 若有 `pod` 掛掉, 會嘗試建立新的,維持設定的數量 - 系統高可用性 : 可以維持 pod 可用性 - `Deployment` : - 位於 `ReplicaSet` 上 : 因此當更新 `pods` 時,不需要實際控制 `ReplicaSet` - `ReplicaSet` 已經可以維持 `pod` 可用性,為什麼還要 `Deployment` ? - 要神不知鬼不覺的更新(使用者沒發覺系統正在更新),就可以使用 `Deployment` - 如果只有 `ReplicaSet` : - 需要自己建立==新的`ReplicaSet`==,且在此 ==新的`ReplicaSet`== 新增更新好的 `pod` - 同時也須把==舊的`ReplicaSet`== 底下所有的==舊的 `pods`== 砍掉 - 如果有 `Deployment` : - 只需在 `Deployment` 中選擇更新採用的策略,`Deployment`會自動依照策略更新  - 可以讓服務在使用者感覺不到的情況下更新 (Rolling update),而通常更新 `Deployment` 會採用兩種不同策略 : 1. **Rolling Update Strategy** - 逐漸替換舊的 `pod` - 使用者感受影響最小 - 整體更新時間較長 - 設定欄位 - `maxSurge` : 同時最多被新建的 `pod` 數量 - `maxUnvailable` : 在更新的過程中作多不能使用的 `pod` 數量 - ex: ReplicaSet=3, maxSurge=1,maxUnavailable=0  2. **Recreation Strategy** - 一次把所有的 `pod` 更新 - 優點 - 更新整體時間較短 - 缺點 - 服務會有一段時間完全不能使用 - 版本控制 : - 變更 `Deployment` 的設定後,可以還原到之前不同版本。 ## 實做 - `deployment.yaml` ```yml= apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 0 maxSurge: 1 template: metadata: labels: app: demoApp spec: containers: - name: kubernetes-demo-container image: hcwxd/kubernetes-demo ports: - containerPort: 3000 selector: matchLabels: app: demoApp ``` - `replicas`: 要建立幾個複製的 pod - `template`: `pod` 建立時統一的設定 - 在 k8s 建立 yaml file ```cmd= microk8s kubectl create -f deployment.yaml ``` - 看一下目前的 deployment ```cmd= microk8s kubectl get deployment ``` - 看一下被 deployment 部屬的 ReplicaSet ```cmd= microk8s kubectl get replicaset ``` - 此 ReplicaSet 的 pods ```cmd= microk8s kubectl get pods ``` - 實做功能 - deployment 的目的:在使用者無感的情況下更新 ### namespace - 不同的專案可用不同的名字區分 - 優點 - 方便管理不同的專案 - 區分不同專案可以使用不同主機不同的資源 - `microk8s kubectl config view | grep namespace` 查看目前是在哪一個 namespace - `microk8s kubectl create namespace namespace_name` 新增 namespace - `microk8s kubectl config set-context --current --namespace=<namespace>` 切換 namespace - ResourceQuota - 不同的 namespace 可以使用多少資源 - `compute-quotas` - 計算 CPU, memory 資源限制 - `requests` 保政治少有多少資源可以使用 - `limits` namespace 最多可以是用多少資源 :point_right: limit > request - `object-quotas` component 的資源限制 - `pods` - `services`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up