--- title: 'k8s 基礎' disqus: hackmd --- [TOC] <style> #doc { min-width: 1200px; margin-left: 200px; } </style> # K8s Node 定義  :::info Master Node是由etcd、kube-controller-manager、kube-apiserver、kubescheduler構成 ::: **Etcd** * 用來存放 Kubernetes Cluster 的資料作為備份,當 Master 因為某些原因而故障時,我們可以透過 etcd 幫我們還原 Kubernetes 的狀態 **kube-controller-manager** * 負責管理並運行 Kubernetes controller 的組件,簡單來說 controller 就是 Kubernetes 裡一個個負責監視 Cluster 狀態的 Process * 這些 Process 會在 Cluster 與預期狀態(desire state)不符時嘗試更新現有狀態(current state) * controller-manager 的監控與嘗試更新也都需要透過訪問 kube-apiserver 達成 * controller 包含以下四種: * Node controller * 當節點有問題時負責通知與回應 * Replication controller * 用來管理 Pod 的數量及狀態,並可確保有指定數量的 Pod 正在運行 * Endpoints controller * 用來結合 Pod 和 Service 的物件 * Service Account & Token controllers * 建立預設的帳號、為新的 namespace 建立新的 API 存取 token **kube-apiserver** * 管理整個 Kubernetes 所需 API 的接口(Endpoint) * 負責 Node 之間的溝通橋樑,每個 Node 彼此不能直接溝通,必須要透過 apiserver 轉介 * 負責 Kubernetes 中的請求的身份認證與授權 **Kubescheduler** * 整個 K8S 的 Pods 調度員,scheduler 會監視新建立但還沒有被指定要跑在哪個 Node 上的 Pod,並根據每個 Node 上面資源規定、硬體限制等條件去協調出一個最適合放置的 Node 讓該 Pod 跑 :::info WorkerNode是由kubelet、kube-Proxy、Container Runtime構成 ::: **Kubelet** * kubelet相當於 node agent,用於管理該 Node 上的所有 pods以及與 master node 即時溝通。 **kube-Proxy** * kube-proxy則是會將目前該 Node 上所有 Pods 的資訊傳給 iptables,讓 iptables 即時獲得在該 Node 上所有 Pod 的最新狀態。 **Container Runtime** * 該 Node 真正負責容器執行的程式,以 Docker 容器為例其對應的 Container Runtime 就是 Docker Engine。 --- # K8s Object 定義  :::info Basic ::: * Pod * Pod是k8s中可以被創造或是發布的最小的單位,一個 Pod 在k8s世界中就相當於一個application。Pod有以下特點: 1. 每個 Pod 都有屬於自己的 yaml 檔 2. 一個Pod裡面可以包含一個或多個Docker Container ( 或者是其他 Container) 3. 在同一個Pod裡面的Containers,可以用Local Port互相溝通 * Service * k8s服務是一個abstraction,它定義了一組邏輯Pod和一個訪問它們的策略 - 有時稱為micro-service。負責不同Pod之間的溝通。 * Volume * k8s服務中的Volume與Docker的Volume是類似的概念,他們都是為了在虛擬化系統中,因該設計的pod或是container生命週期是短暫的,為了要保存資料的永久性和完整性所做的方法,也就是保存資料用的,也可以用作共享資料,無論是在不同的pod或是container之間,但是k8s的Volume不同於Docker的是,它會有明確的生命週期,且能在產生pod時加入屬於Volume不同的參數,像是要掛載的檔案系統類型等等(如:NFS),簡言之它具有更大的彈性,另外它可在container切換時保持存在,以達到交換資料的目的。 * Namespace * 所謂的Namespace,是劃分不同使用者能使用多少資源的方法(resource quota),舉例來說:CPU或是memory分配的多寡,在少量的使用者場景中(幾個或幾十個),這樣的功能是不需要的,此外,若是分配不同資源,並不需要使用不同的Namespace,只要在同個Namespace下定義不同的label即可。在管理k8s系統中的情況,最常使用到的是kube-system這個Namespace。 :::info Abstraction ::: * ReplicaSet * 複製集,是基於Replication Controller的改良版,本質差異是在selector的支援多寡,在現在的使用情境下,我們不會直接操作到ReplicaSet,每個不同的Deployment會有他們自己的ReplicaSet,並會自動調配,除非我們有對於複製集有特殊設定需求,不然一般直接套用Deployment的預設即可,ReplicaSet顧名思義是讓同個Pod有多個分身在同時運行,舉例來說:這樣的好處是在更新的時候不會讓使用者斷線 * Deployment * 部署,Deployment Controller提供Pods和ReplicaSets可定義的更新,k8s下的Deployment有許多feature可以使用,如:create、update、roll back、pause、resume等,針對Deployment的替代方案可以使用kubectl rolling update這個指令。 * StatefulSet * StatefulSet管理一組Pod的部署(Deployment)和擴展(scaling),並提供有關這些Pod的排序和唯一性的保證。 * 與部署(Deployment)類似的是,StatefulSet管理基於相同容器規範的Pod。與部署(Deployment)不同的是,StatefulSet為其Pod保持標籤(label)。 * 這些Pod是根據相同的規範創建的,但不可互換:每個Pod都有一個永久性的標籤(label),它可以在任何重新安排時保留。 * DaemonSet * DaemonSet能確保部份或所有node運行Pod的副本持續運行。 * 刪除DaemonSet將清除它創建的Pod。 * Job * Job創建一個或多個pod,並確保指定數量的Pod工作完成後終止。 * 刪除Job將清除它創建的Pod。 * Job還可以用於並行運行多個Pod。 --- # Tool ```bash= -- 查看 主服務狀態 kubectl get componentstatuses -- 查看 現有Namespace kubectl get namespace -- 查看 pod/service/rc 較多資訊 kubectl get all -o wide ``` --- # Pod yaml 建立 pod, 並指定特定label的node k8s-web-pod-node-selector.yaml ```yaml= apiVersion: v1 kind: Pod # 定義類型 metadata: name: k8s-net-pod # 資源名稱 labels: # 該pod 的label app: k8s-net-pod spec: # 資源狀態 containers: # 單一Container的設定,可以單一Pod設定多個Container - name: web # 該Container在該Pod的名稱 image: test_project/v1 # docker image 名稱 imagePullPolicy: IfNotPresent # 預設為 Always (每次都重遠端拉取Image),通過設定 IfNotPresent或Never来使用local Image ports: - containerPort: 80 livenessProbe: # 設定healthCheck httpGet: path: /host/CheckHealth # healthCheck API Path port: 80 # healthCheck API Port initialDelaySeconds: 15 # 服務啟動後 幾秒後做healthCheck default=0 min=0 periodSeconds: 15 # 每隔幾秒Check一次 default=10 min=1 timeoutSeconds: 30 # timeout時間 default=1 min=1 successThreshold: 1 # 呼叫幾次成功後 會更改狀態回success default=1 min=1 failureThreshold: 3 # 呼叫幾次失敗後 會更改狀態回failure default=1 min=1 nodeSelector: SpecifyNode: node_test1 # 指定部屬到含有 label SpecifyNode=node_test1 的 node中 ``` --- # Service 功能: 在Node 與 Pod 之間的橋樑, 幫忙轉接IP ```bash= -- 當Node建立好後, 建立expose service kubectl expose pod/k8s-net-pod --name=k8s-net-service --port=80 --type=NodePort -- 查看目前 service 所有資訊 kubectl -ojson get service k8s-net-service ``` 更新Service 的nodeport 的方式 ```bash= 1. 編輯service kubectl edit service k8s-net-service => 直接修改完後, ESC :wq 退出 2. 更新yaml檔後 重新apply kubectl apply service -f k8s-web-service-demo.yaml 3. 更新yaml檔後 重新 replace kubectl replace service -f k8s-web-service-demo.yaml **若沒有yaml檔 可匯出當前Service的yaml檔設定 進行修改 **kubectl get service k8s-net-service -o yaml > k8s-web-service-demo.yaml ** apply 與 replace差異 apply => 若有現有service 則 更新, 若無 則創建 replace => 刪除現有service 重新創建 apply 可更新部分設定, 故不需完整的yaml檔 replace 則需完整的yaml檔, 因需要重新創建 4. Patch更新 kubectl patch service k8s-net-service --type='json' -p='[{"op": "replace", "path": "/spec/ports/0/nodePort", "value":31500}]' ``` yaml檔 建立 service k8s-web-service.yaml ```yaml= apiVersion: v1 kind: Service metadata: name: k8s-net-service spec: selector: app: k8s-net-pod ports: - protocol: TCP port: 80 targetPort: nodePort: 31000 type: NodePort ``` # ReplicationController 功能: 1. 用來管理Pod的數量以及狀態的controller 2. 在Replication Controller設定檔中可以指定同時有多少個相同的Pods運行在Kubernetes Cluster上 3. 當某一Pod發生crash, failed,而終止運行時,Replication Controller會幫我們自動偵測,並且自動創建一個新的Pod,確保Pod運行的數量與設定檔的指定的數量相同 4. 當機器重新開啟時,之前在機器上運行的 Replication Controller 會自動被建立,確保pod隨時都在運行 ```bash= # 建立 ReplicationController kubectl apply -f k8s-web-rc.yaml # 自動擴展 pod數量 kubectl scale --replicas=4 -f k8s-web-rc.yaml # 刪除RC時 其所指定label的pod 也會一併被刪除 kubectl describe rc my-replication-controller # 刪除RC時 保留pods kubectl describe rc my-replication-controller --cascade=false ``` yaml檔 建立 ReplicationController k8s-web-rc.yaml ```yaml= apiVersion: v1 kind: ReplicationController metadata: name: my-replication-controller spec: replicas: 3 # 欲創建pods 的數量 selector: app: k8s-net-pod template: metadata: labels: # 創建pods 的 label app: k8s-net-pod spec: containers: - name: web image: test_project/v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 ``` # Deployment 功能: 1. 部署一個應用服務(application) 2. 協助 applications 升級到某個特定版本 3. 服務升級過程中做到無停機服務遷移(zero downtime deployment) 4. 可以Rollback到先前版本 :::info 會自動創建Replica Sets (為 ReplicationController 的進化版,提供更彈性的selector設定) ::: ```bash= # 建立 deployent kubectl apply -f k8s-web-deployment.yaml # 查看 deployment 較多資訊 kubectl get deploy -o wide # 更新 Image版本 kubectl set image deploy/my-deployment web=test_project/v2 --record # 查看 deployment滾動更新 紀錄 kubectl rollout history deploy my-deployment # 回滾 deployment至上一個版本 kubectl rollout undo deploy my-deployment # 回滾 deployment至某指定版本 kubectl rollout undo deploy my-deployment --to-revision=4 ``` yaml檔 建立 Deployment k8s-web-deployment.yaml ```yaml= apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: replicas: 3 selector: matchLabels: app: k8s-net-pod template: metadata: labels: app: k8s-net-pod spec: containers: - name: web image: test_project/v2 imagePullPolicy: IfNotPresent ports: - containerPort: 80 livenessProbe: httpGet: path: /host/CheckHealth port: 80 nodeSelector: SpecifyNode: node_test1 ``` # Lable 功能: 1. 每個物件可以同時擁有許多個labels(multiple labels) 2. 可以透過 Selector,幫我們縮小要尋找的物件 3. 目前 API 提供不再只是一個 key對應一個value(Equality-based requirement)的關係,我們也可以使用 matchExpressions 來設定更有彈性的Labels ```bash= # 新增 label 至 指定pod中 kubectl label pods k8s-net-pod env=production ``` ###### tags: `k8s`
×
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