[{"data":1,"prerenderedAt":3211},["ShallowReactive",2],{"$Nehrp7Lchg":3},[4,1023,1692,2525],{"_path":5,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":9,"description":10,"layout":11,"series":12,"image":13,"keywords":18,"head":23,"body":37,"_type":1017,"_id":1018,"_source":1019,"_file":1020,"_stem":1021,"_extension":1022},"/blog/k8s-intro/00","k8s-intro",false,"","Kubernetes 基本介紹","Kubernetes (k8s) 是一個用於管理容器 Container 的開源軟體，一般被稱為 Container Orchestration Platform。K8s 的前身是由 Google 內部開發的 Borg 項目，並於2014年公開發布。在那之後由 CNCF 接手到 2018 年畢業，並且擁有一個龐大且快速增長的完整生態系統。","post","Kubernetes",{"src":14,"alt":15,"width":16,"height":17},"hero.png","hero",750,536,[19,20,21,22],"container","k8s","tech","cloud",{"meta":24},[25,28,31,34],{"name":26,"content":27},"author","小貓貓工程師",{"name":29,"content":30},"read","11 min read",{"property":32,"content":33},"article:published_time","2020-12-11T00:00:00.000Z",{"property":35,"content":36},"article:modified_time","2023-03-20T00:00:00.000Z",{"type":38,"children":39,"toc":980},"root",[40,63,72,79,84,124,128,134,139,142,148,172,177,223,236,257,260,266,275,281,286,433,448,454,466,539,547,550,556,561,567,580,604,610,622,632,660,666,679,712,749,755,810,816,828,840,846,872,893,899,930,936,977],{"type":41,"tag":42,"props":43,"children":44},"element","p",{},[45,48,54,56,61],{"type":46,"value":47},"text","Kubernetes (k8s) ",{"type":41,"tag":49,"props":50,"children":51},"sup",{},[52],{"type":46,"value":53},"[1]",{"type":46,"value":55},"是一個用於管理容器 Container 的開源軟體，一般被稱為 Container Orchestration Platform。K8s 的前身是由 Google 內部開發的 Borg 項目，並於2014年公開發布。在那之後由 CNCF ",{"type":41,"tag":49,"props":57,"children":58},{},[59],{"type":46,"value":60},"[2]",{"type":46,"value":62}," 接手到 2018 年畢業，並且擁有一個龐大且快速增長的完整生態系統。",{"type":41,"tag":64,"props":65,"children":66},"footnote-block",{},[67],{"type":41,"tag":42,"props":68,"children":69},{},[70],{"type":46,"value":71},"[1] Kubernetes（k8s）從K到S中間共有8個字符，名稱源自古希臘語，意思為舵手或飛行員。\n‌‌[2] Cloud Native Computing Foundation（CNCF），雲端原生運算基金會，致力於Github上的快速成長的開源技術推廣。",{"type":41,"tag":73,"props":74,"children":76},"h2",{"id":75},"deployment-從傳統部署到容器化部署",[77],{"type":46,"value":78},"Deployment - 從傳統部署到容器化部署",{"type":41,"tag":42,"props":80,"children":81},{},[82],{"type":46,"value":83},"要想知道 Kubernetes 和 Containerized Deployment 的重要性，首先需要了解到部署演變歷史：",{"type":41,"tag":85,"props":86,"children":89},"section",{"className":87},[88],"pl-6",[90,97,102,108,113,119],{"type":41,"tag":91,"props":92,"children":94},"h3",{"id":93},"traditional-deployment-傳統部署",[95],{"type":46,"value":96},"Traditional Deployment - 傳統部署",{"type":41,"tag":42,"props":98,"children":99},{},[100],{"type":46,"value":101},"傳統部署會直接在服務器上運行應用程序，這樣無法控制應用程序可能消耗的資源(CPU, Memory)，從而導致資源分配問題。如果應用程序消耗了運行它的服務器的大部分資源，則此高負載可能會導致同一物理服務器上運行的其他應用程序出現性能問題。一種解決方案是在每個服務器上運只運行一個應用程序，但這將導致資源利用不足，維護成本增加。",{"type":41,"tag":91,"props":103,"children":105},{"id":104},"virtualized-deployment-虛擬化部署",[106],{"type":46,"value":107},"Virtualized Deployment - 虛擬化部署",{"type":41,"tag":42,"props":109,"children":110},{},[111],{"type":46,"value":112},"在虛擬化部署時代，多個虛擬機（VM）帶來了解決方案的開端。虛擬化使將應用程序隔離在同一服務器上運行的不同 VM 之間，從而提供安全層和更好的資源分配。‌‌此解決方案降低了硬件的成本，但每個 VM 仍需要與傳統部署相同的管理和維護",{"type":41,"tag":91,"props":114,"children":116},{"id":115},"containerized-deployment-容器化部署",[117],{"type":46,"value":118},"Containerized Deployment - ‌容器化部署",{"type":41,"tag":42,"props":120,"children":121},{},[122],{"type":46,"value":123},"‌容器化部署，說到這必須先說說容器 Container。容器包括其運行環境以及應用程序運行所需的所有 Library 和 Dependency。具有不同需求的容器可以在同一台 VM 或服務器上運行，並且共享資源。而且容器相當容易移植，並且可以輕鬆地在不同的雲端和 OS 發行版之間運行，從而使軟件對硬件的依賴性越來越低，並降低了維護成本",{"type":41,"tag":125,"props":126,"children":127},"hr",{},[],{"type":41,"tag":73,"props":129,"children":131},{"id":130},"container-orchestration-管理容器化部署",[132],{"type":46,"value":133},"Container Orchestration - 管理容器化部署",{"type":41,"tag":42,"props":135,"children":136},{},[137],{"type":46,"value":138},"在 Production Environment 裡一般會運行大量的容器，並且需要管理應用程式的容器以確保沒有停機時間。理論上要手動管理成千上萬個同時運行的容器得可行性是很低的。‌‌Kubernetes 能夠管理容器化的應用程式（Containerized Application）的生命週期，定義應用程式該如何運行，如何與外界的其他應用程序交互，同時提供可預測性 Predictability、可擴展性 Scalability、高可用性 High Availability。",{"type":41,"tag":125,"props":140,"children":141},{},[],{"type":41,"tag":73,"props":143,"children":145},{"id":144},"kubernetes-architecture-體系結構",[146],{"type":46,"value":147},"Kubernetes Architecture - 體系結構",{"type":41,"tag":42,"props":149,"children":150},{},[151,153,159,161,170],{"type":46,"value":152},"在 Kubernetes 的概念裡，一台機器或是 VM 被稱作一個_",{"type":41,"tag":154,"props":155,"children":156},"strong",{},[157],{"type":46,"value":158},"節點 Node",{"type":46,"value":160},"_。而 Kubernetes 能夠在多個節點之間使用共享網路連結，這樣多個節點被稱為",{"type":41,"tag":154,"props":162,"children":163},{},[164],{"type":41,"tag":165,"props":166,"children":167},"em",{},[168],{"type":46,"value":169},"集群 Cluster",{"type":46,"value":171},"。 Kubernetes 上的組件 (Component) 和工作負載 (Wordload) 都在此 Cluster 上進行配置。",{"type":41,"tag":42,"props":173,"children":174},{},[175],{"type":46,"value":176},"Kubernetes Cluster 中的每個 Node 在系統中都有特定的角色，一般來說分為以下兩大類：",{"type":41,"tag":85,"props":178,"children":180},{"className":179},[88],[181,187,192,198],{"type":41,"tag":91,"props":182,"children":184},{"id":183},"master",[185],{"type":46,"value":186},"Master",{"type":41,"tag":42,"props":188,"children":189},{},[190],{"type":46,"value":191},"Master (主節點) 是 Kubernetes Cluster 的大腦。一般會在上面配置核心組件，用於在其餘服務器的運行狀況檢查、公開許多不同的 API、安排 Workload、並編排不同組件之間的通信。Master 是一個 Cluster 的主要聯繫點，在 Production 環境中正常會有多個 Master 來達成高可用性 High Availability。",{"type":41,"tag":91,"props":193,"children":195},{"id":194},"node",[196],{"type":46,"value":197},"Node",{"type":41,"tag":42,"props":199,"children":200},{},[201,203,212,214,221],{"type":46,"value":202},"Node (節點) 是其餘服務器的總稱，也被稱為節點。一般會經由 Master  安排各種容器在上面運行，這意味著它們中的每一個都需要在其上安裝 Container Runtime（例如 ",{"type":41,"tag":204,"props":205,"children":209},"a",{"href":206,"rel":207},"https://translate.googleusercontent.com/translate_c?depth=1&%3Bpto=aue&%3Brurl=translate.google.com&%3Bsl=en&%3Bsp=nmt4&%3Btl=zh-TW&%3Bu=https%3A%2F%2Fwww.scaleway.com%2Fen%2Fdocs%2Fhow-to-install-docker-community-edition-ubuntu-bionic-beaver%2F&%3Busg=ALkJrhitnF8GG2oHmzoROBMH9ZmJ2Q69-Q&ref=blog.ewocker.com",[208],"nofollow",[210],{"type":46,"value":211},"Docker",{"type":46,"value":213}," 或 ",{"type":41,"tag":204,"props":215,"children":218},{"href":216,"rel":217},"https://translate.googleusercontent.com/translate_c?depth=1&%3Bpto=aue&%3Brurl=translate.google.com&%3Bsl=en&%3Bsp=nmt4&%3Btl=zh-TW&%3Bu=https%3A%2F%2Fcri-o.io%2F&%3Busg=ALkJrhh0MWCd0Mx2Iv9i5kSkK_1oESFRZw&ref=blog.ewocker.com",[208],[219],{"type":46,"value":220},"CRI-O",{"type":46,"value":222},"）。",{"type":41,"tag":42,"props":224,"children":225},{},[226,234],{"type":41,"tag":154,"props":227,"children":228},{},[229],{"type":41,"tag":165,"props":230,"children":231},{},[232],{"type":46,"value":233},"Kubernetes Cluster 中運行的不同基礎組件可確保*應用程序的所需狀態與 Cluster 的實際狀態相匹配。",{"type":46,"value":235},"若應用程序的所需狀態發生變化，Master 將通過在 Node 上創建或銷毀 Container，以及調整各項網路設定來恢復應用程序的所需狀態。",{"type":41,"tag":42,"props":237,"children":238},{},[239,241,248,249,255],{"type":46,"value":240},"用戶與 Master 之間的溝通直接用 API 或通過提交 ",{"type":41,"tag":242,"props":243,"children":245},"code",{"className":244},[],[246],{"type":46,"value":247},"JSON",{"type":46,"value":213},{"type":41,"tag":242,"props":250,"children":252},{"className":251},[],[253],{"type":46,"value":254},"YAML",{"type":46,"value":256}," 設置檔案。該設置檔案包含有關創建內容和管理方法的說明，由決定如何部署應用程序的組件安排。",{"type":41,"tag":125,"props":258,"children":259},{},[],{"type":41,"tag":73,"props":261,"children":263},{"id":262},"kubernetes-component-組件",[264],{"type":46,"value":265},"Kubernetes Component - 組件",{"type":41,"tag":42,"props":267,"children":268},{},[269],{"type":41,"tag":270,"props":271,"children":274},"img",{"alt":272,"src":273},"Components of Kubernetes","components.svg",[],{"type":41,"tag":73,"props":276,"children":278},{"id":277},"master-component-主組件",[279],{"type":46,"value":280},"Master Component - 主組件",{"type":41,"tag":42,"props":282,"children":283},{},[284],{"type":46,"value":285},"Master Component 是一個 Cluster 的控制平面。這些組件用於製定有關 Cluster 的決策，以及檢測和響應事件。‌‌Kubernetes Cluster 需要運行多個應用程序。它們是用於保證 Cluster 的健康狀態和進行通信和控制的組件。",{"type":41,"tag":85,"props":287,"children":289},{"className":288},[88],[290,295,337,342,366,371,381,386,404,409],{"type":41,"tag":91,"props":291,"children":293},{"id":292},"etcd",[294],{"type":46,"value":292},{"type":41,"tag":42,"props":296,"children":297},{},[298,304,306,311,313,319,321,327,329,335],{"type":41,"tag":204,"props":299,"children":302},{"href":300,"rel":301},"https://translate.googleusercontent.com/translate_c?depth=1&%3Bpto=aue&%3Brurl=translate.google.com&%3Bsl=en&%3Bsp=nmt4&%3Btl=zh-TW&%3Bu=https%3A%2F%2Fetcd.io%2F&%3Busg=ALkJrhgjzrSBW4FdAUjks-wl9C7xjt2MCg&ref=blog.ewocker.com",[208],[303],{"type":46,"value":292},{"type":46,"value":305}," 是一個兼具一致性和高可用的分布式",{"type":41,"tag":154,"props":307,"children":308},{},[309],{"type":46,"value":310},"键值存储 key-value store",{"type":46,"value":312},"，Kubernetes 使用 etcd 儲存設置",{"type":41,"tag":242,"props":314,"children":316},{"className":315},[],[317],{"type":46,"value":318},"configuration data",{"type":46,"value":320},"、狀態 ",{"type":41,"tag":242,"props":322,"children":324},{"className":323},[],[325],{"type":46,"value":326},"status",{"type":46,"value":328},"、元資料 ",{"type":41,"tag":242,"props":330,"children":332},{"className":331},[],[333],{"type":46,"value":334},"metadata",{"type":46,"value":336},"。",{"type":41,"tag":91,"props":338,"children":340},{"id":339},"kube-apiserver",[341],{"type":46,"value":339},{"type":41,"tag":42,"props":343,"children":344},{},[345,350,352,357,359,364],{"type":41,"tag":242,"props":346,"children":348},{"className":347},[],[349],{"type":46,"value":339},{"type":46,"value":351}," 是公開 Kubernetes API 主要組件。它是Kubernetes控制平面的前端，也是用戶與集群進行交互的主要手段。",{"type":41,"tag":242,"props":353,"children":355},{"className":354},[],[356],{"type":46,"value":339},{"type":46,"value":358}," 是唯一與",{"type":41,"tag":242,"props":360,"children":362},{"className":361},[],[363],{"type":46,"value":292},{"type":46,"value":365}," 進行直接通信的組件。",{"type":41,"tag":91,"props":367,"children":369},{"id":368},"kube-scheduler",[370],{"type":46,"value":368},{"type":41,"tag":42,"props":372,"children":373},{},[374,379],{"type":41,"tag":242,"props":375,"children":377},{"className":376},[],[378],{"type":46,"value":368},{"type":46,"value":380}," 主要功能是監測尚未分配節點的工作負載 （Pod），並為它們分配到一個節點上運行。分配決策的考慮因素包括 Pod 所需的資源需求（如 cpu, memory）、軟硬件以及策略約束 （constraints）、親和性規範（affinity）、數據位置（data locality）、工作負載間的干擾、以及最後時限（deadline）。",{"type":41,"tag":91,"props":382,"children":384},{"id":383},"kube-controller-manager",[385],{"type":46,"value":383},{"type":41,"tag":42,"props":387,"children":388},{},[389,395,397,402],{"type":41,"tag":242,"props":390,"children":392},{"className":391},[],[393],{"type":46,"value":394},"kube-controller-manage",{"type":46,"value":396}," 主要是運行控制器",{"type":41,"tag":49,"props":398,"children":399},{},[400],{"type":46,"value":401},"[3]",{"type":46,"value":403},"的主組件。為了降低複雜性，所有控制器都在單個進程中運行。其中包括 Node Controller 節點控制器、Replication Controller 副本控制器、Endpoint Controller 端點控制器、Service Account & Token Controllers 服務帳戶和令牌控制器。",{"type":41,"tag":91,"props":405,"children":407},{"id":406},"cloud-controller-manager",[408],{"type":46,"value":406},{"type":41,"tag":42,"props":410,"children":411},{},[412,417,419,424,426,431],{"type":41,"tag":242,"props":413,"children":415},{"className":414},[],[416],{"type":46,"value":406},{"type":46,"value":418},"是 Cluster 在雲提供商上運行時，負責控制雲端資源的控制平面組件，使其鏈接到雲提供商的應用編程接口。與 ",{"type":41,"tag":242,"props":420,"children":422},{"className":421},[],[423],{"type":46,"value":383},{"type":46,"value":425}," 類似，",{"type":41,"tag":242,"props":427,"children":429},{"className":428},[],[430],{"type":46,"value":406},{"type":46,"value":432}," 將多個控制器在單個進程中運行。其中包括 Node Controller 節點控制器、Route Controller 路由控制器、Service Controller 服務控制器。",{"type":41,"tag":64,"props":434,"children":435},{},[436],{"type":41,"tag":42,"props":437,"children":438},{},[439,441,446],{"type":46,"value":440},"[3] 控制器 Controller，是一個專門負責",{"type":41,"tag":154,"props":442,"children":443},{},[444],{"type":46,"value":445},"確保期望狀態 (Desired State) 符合當前狀態 (Current State)",{"type":46,"value":447}," 的組件",{"type":41,"tag":73,"props":449,"children":451},{"id":450},"node-component-節點組件",[452],{"type":46,"value":453},"Node Component - 節點組件",{"type":41,"tag":42,"props":455,"children":456},{},[457,459,464],{"type":46,"value":458},"在 Kubernetes 中執行 Workload（運行容器）的服務器稱為",{"type":41,"tag":154,"props":460,"children":461},{},[462],{"type":46,"value":463},"節點",{"type":46,"value":465},"。節點可以是VM或物理機。",{"type":41,"tag":85,"props":467,"children":469},{"className":468},[88],[470,475,499,504,514,520],{"type":41,"tag":91,"props":471,"children":473},{"id":472},"kubelet",[474],{"type":46,"value":472},{"type":41,"tag":42,"props":476,"children":477},{},[478,483,485,490,492,497],{"type":41,"tag":242,"props":479,"children":481},{"className":480},[],[482],{"type":46,"value":472},{"type":46,"value":484}," 運行在每個節點上，類似於一個代理。其確保容器在 Pod",{"type":41,"tag":49,"props":486,"children":487},{},[488],{"type":46,"value":489},"[4]",{"type":46,"value":491}," 中處於運行狀態並健康。",{"type":41,"tag":242,"props":493,"children":495},{"className":494},[],[496],{"type":46,"value":472},{"type":46,"value":498}," 只管理 Kubernetes 創建的容器。",{"type":41,"tag":91,"props":500,"children":502},{"id":501},"kube-proxy",[503],{"type":46,"value":501},{"type":41,"tag":42,"props":505,"children":506},{},[507,512],{"type":41,"tag":242,"props":508,"children":510},{"className":509},[],[511],{"type":46,"value":501},{"type":46,"value":513}," 是 Cluster 中的每個 Node 上運行的網絡代理。其維護 Node 上的網絡規則，以允許從內部或外部連接與 Cluster 內的 Pod 通信。",{"type":41,"tag":91,"props":515,"children":517},{"id":516},"container-runtime",[518],{"type":46,"value":519},"container runtime",{"type":41,"tag":42,"props":521,"children":522},{},[523,525,530,532,537],{"type":46,"value":524},"Kubernetes 能夠管理容器，但不能運行它們。因此需要一個",{"type":41,"tag":242,"props":526,"children":528},{"className":527},[],[529],{"type":46,"value":519},{"type":46,"value":531}," 來負責運行容器。Kubernetes支持多種",{"type":41,"tag":242,"props":533,"children":535},{"className":534},[],[536],{"type":46,"value":519},{"type":46,"value":538},"，例如 Docker 或 containerd 以及Kubernetes CRI。",{"type":41,"tag":64,"props":540,"children":541},{},[542],{"type":41,"tag":42,"props":543,"children":544},{},[545],{"type":46,"value":546},"[4] Pod，Kubernetes 中的最小運行單位，往下閱讀更多資訊。",{"type":41,"tag":125,"props":548,"children":549},{},[],{"type":41,"tag":73,"props":551,"children":553},{"id":552},"kubernetes-core-concept-概念",[554],{"type":46,"value":555},"Kubernetes Core Concept - 概念",{"type":41,"tag":42,"props":557,"children":558},{},[559],{"type":46,"value":560},"Kubernetes 使用容器來部署應用程序，但它也使用其他抽象層來提供擴展、彈性和生命週期管理功能。",{"type":41,"tag":91,"props":562,"children":564},{"id":563},"pod",[565],{"type":46,"value":566},"Pod",{"type":41,"tag":568,"props":569,"children":570},"note-img",{},[571],{"type":41,"tag":42,"props":572,"children":573},{},[574,578],{"type":41,"tag":270,"props":575,"children":577},{"alt":563,"src":576},"pod.png",[],{"type":46,"value":579},"\npod",{"type":41,"tag":42,"props":581,"children":582},{},[583,588,590,595,597,602],{"type":41,"tag":242,"props":584,"children":586},{"className":585},[],[587],{"type":46,"value":566},{"type":46,"value":589}," 是 Kubernetes 中的最小可部署單元。一個 ",{"type":41,"tag":242,"props":591,"children":593},{"className":592},[],[594],{"type":46,"value":566},{"type":46,"value":596}," 是由一或多個容器組成的，同一個 ",{"type":41,"tag":242,"props":598,"children":600},{"className":599},[],[601],{"type":46,"value":566},{"type":46,"value":603},"  中的容器使用相同的網絡地址 IP、存儲資源 Volume、以及有關如何管理這些容器的信息。",{"type":41,"tag":91,"props":605,"children":607},{"id":606},"service",[608],{"type":46,"value":609},"Service",{"type":41,"tag":568,"props":611,"children":612},{},[613],{"type":41,"tag":42,"props":614,"children":615},{},[616,620],{"type":41,"tag":270,"props":617,"children":619},{"alt":606,"src":618},"service.png",[],{"type":46,"value":621},"\nservice",{"type":41,"tag":42,"props":623,"children":624},{},[625,630],{"type":41,"tag":242,"props":626,"children":628},{"className":627},[],[629],{"type":46,"value":609},{"type":46,"value":631}," 是一個抽象定義，其提供了一個穩定的 IP 地址，並通過將請求重定向到服務中的不同 Pod 來充當負載平衡器 Load Balancer。服務抽象允許在不更改應用程序配置的情況下橫向擴展或替換失效的 Pod。",{"type":41,"tag":42,"props":633,"children":634},{},[635,637,642,644,650,652,658],{"type":46,"value":636},"默認情況下，",{"type":41,"tag":242,"props":638,"children":640},{"className":639},[],[641],{"type":46,"value":609},{"type":46,"value":643}," 僅使用內部可路由的 IP 地址可用，但可以透過定公開。‌‌這可以通過使用 ",{"type":41,"tag":242,"props":645,"children":647},{"className":646},[],[648],{"type":46,"value":649},"NodePort",{"type":46,"value":651}," 配置來完成，該配置通過在每個節點外部網絡接口上打開靜態端口 Static Port 來工作。或者可以使用該 ",{"type":41,"tag":242,"props":653,"children":655},{"className":654},[],[656],{"type":46,"value":657},"LoadBalancer",{"type":46,"value":659}," 服務在雲提供商處創建一個外部負載均衡器。但是，僅當存在雲控制器管理器時，此服務才有效。",{"type":41,"tag":91,"props":661,"children":663},{"id":662},"replicaset-deployment",[664],{"type":46,"value":665},"ReplicaSet & Deployment",{"type":41,"tag":568,"props":667,"children":668},{},[669],{"type":41,"tag":42,"props":670,"children":671},{},[672,677],{"type":41,"tag":270,"props":673,"children":676},{"alt":674,"src":675},"replicaset & deployment","deploy.png",[],{"type":46,"value":678},"\nreplicaset & deployment",{"type":41,"tag":42,"props":680,"children":681},{},[682,688,690,695,697,702,704,710],{"type":41,"tag":242,"props":683,"children":685},{"className":684},[],[686],{"type":46,"value":687},"Replicaset",{"type":46,"value":689}," 確保在任何時間下都有指定數量的 Pod 在運行。",{"type":41,"tag":242,"props":691,"children":693},{"className":692},[],[694],{"type":46,"value":687},{"type":46,"value":696}," 的任務是根據需要創建和刪除Pod，以達到所需的狀態。",{"type":41,"tag":242,"props":698,"children":700},{"className":699},[],[701],{"type":46,"value":687},{"type":46,"value":703}," 可以通過 Pod 中的 ",{"type":41,"tag":242,"props":705,"children":707},{"className":706},[],[708],{"type":46,"value":709},"metadata.ownerReference",{"type":46,"value":711}," 了解何為其附屬 Pod，因此可以根據 Pod 的狀態安排任務。",{"type":41,"tag":42,"props":713,"children":714},{},[715,721,723,728,730,734,740,742,747],{"type":41,"tag":242,"props":716,"children":718},{"className":717},[],[719],{"type":46,"value":720},"Deployment",{"type":46,"value":722}," 是比 ",{"type":41,"tag":242,"props":724,"children":726},{"className":725},[],[727],{"type":46,"value":687},{"type":46,"value":729}," 更高層次的概念，是管理副本集並使用許多其他功能為 Pod 提供更新聲明。",{"type":41,"tag":731,"props":732,"children":733},"br",{},[],{"type":41,"tag":242,"props":735,"children":737},{"className":736},[],[738],{"type":46,"value":739},"Deployment Controller",{"type":46,"value":741}," 運行 ",{"type":41,"tag":242,"props":743,"children":745},{"className":744},[],[746],{"type":46,"value":687},{"type":46,"value":748}," 中指定的應用程序的多個副本 Replicas。萬一任何 Pod 可能發生故障或無法響應，該 Pod 將被替換直到實際狀態等於所需狀態為止。",{"type":41,"tag":91,"props":750,"children":752},{"id":751},"statefulset",[753],{"type":46,"value":754},"StatefulSet",{"type":41,"tag":42,"props":756,"children":757},{},[758,763,765,771,773,776,782,784,789,791,796,798,801,803,808],{"type":41,"tag":242,"props":759,"children":761},{"className":760},[],[762],{"type":46,"value":754},{"type":46,"value":764}," 能夠像 ",{"type":41,"tag":242,"props":766,"children":768},{"className":767},[],[769],{"type":46,"value":770},"Deployments",{"type":46,"value":772}," 一樣管理 Pod，但還會維護每個 Pod 的粘性標識。Pod 是從相同的基礎創建的，但不可互換。",{"type":41,"tag":731,"props":774,"children":775},{},[],{"type":41,"tag":242,"props":777,"children":779},{"className":778},[],[780],{"type":46,"value":781},"StatefulSet Controller",{"type":46,"value":783}," 的操作模式與任何其他 Controller 相同。",{"type":41,"tag":242,"props":785,"children":787},{"className":786},[],[788],{"type":46,"value":781},{"type":46,"value":790}," 通過進行必要的更新以從集群的實際狀態變為所需狀態，來維護 ",{"type":41,"tag":242,"props":792,"children":794},{"className":793},[],[795],{"type":46,"value":754},{"type":46,"value":797}," 對像中定義的所需狀態。",{"type":41,"tag":731,"props":799,"children":800},{},[],{"type":46,"value":802},"\n即使將 Pod 移動到另一個 Node，",{"type":41,"tag":242,"props":804,"children":806},{"className":805},[],[807],{"type":46,"value":754},{"type":46,"value":809}," 將保持其中每個 Pod 的唯一性，基於數字的名稱也會保留。",{"type":41,"tag":91,"props":811,"children":813},{"id":812},"daemonset",[814],{"type":46,"value":815},"DaemonSet",{"type":41,"tag":568,"props":817,"children":818},{},[819],{"type":41,"tag":42,"props":820,"children":821},{},[822,826],{"type":41,"tag":270,"props":823,"children":825},{"alt":812,"src":824},"daemonset.png",[],{"type":46,"value":827},"\ndaemonset",{"type":41,"tag":42,"props":829,"children":830},{},[831,833,838],{"type":46,"value":832},"Pod Controller 的另一種類型稱為 ",{"type":41,"tag":242,"props":834,"children":836},{"className":835},[],[837],{"type":46,"value":815},{"type":46,"value":839},"。它確保所有（或某些）節點都運行 Pod 的副本。對於大多數用例，在何處運行 Pod 無關緊要，但是在某些情況下，要求單個 Pod 在所有節點上運行。這對於聚集日誌文件、收集指標、或運行網絡存儲群集很有用。",{"type":41,"tag":91,"props":841,"children":843},{"id":842},"job-cronjob",[844],{"type":46,"value":845},"Job & CronJob",{"type":41,"tag":42,"props":847,"children":848},{},[849,855,857,862,864,870],{"type":41,"tag":242,"props":850,"children":852},{"className":851},[],[853],{"type":46,"value":854},"Job",{"type":46,"value":856}," ",{"type":41,"tag":154,"props":858,"children":859},{},[860],{"type":46,"value":861},"能夠",{"type":46,"value":863},"管理任務，直到任務運行完成。其可以並行運行多個 Pod，它們對於批處理任務 ",{"type":41,"tag":242,"props":865,"children":867},{"className":866},[],[868],{"type":46,"value":869},"batch-oriented tasks",{"type":46,"value":871}," 很有用。",{"type":41,"tag":42,"props":873,"children":874},{},[875,877,883,885,891],{"type":46,"value":876},"Kubernetes 中的 ",{"type":41,"tag":242,"props":878,"children":880},{"className":879},[],[881],{"type":46,"value":882},"CronJob",{"type":46,"value":884}," 就像 Linux 中的傳統 ",{"type":41,"tag":242,"props":886,"children":888},{"className":887},[],[889],{"type":46,"value":890},"cron",{"type":46,"value":892}," 作業類似。它們可用於在特定時間或間隔運行任務，常見的有備份或清除任務。",{"type":41,"tag":91,"props":894,"children":896},{"id":895},"volume",[897],{"type":46,"value":898},"Volume",{"type":41,"tag":42,"props":900,"children":901},{},[902,907,909,914,916,921,923,928],{"type":41,"tag":242,"props":903,"children":905},{"className":904},[],[906],{"type":46,"value":898},{"type":46,"value":908}," 是 Pod 中的容器可訪問的資料夾 directory。Kubernetes 使用其自身的 ",{"type":41,"tag":242,"props":910,"children":912},{"className":911},[],[913],{"type":46,"value":898},{"type":46,"value":915}," 定義，從而允許所有容器共享數據並保持可用狀態，直到終止 Pod。Kubernetes ",{"type":41,"tag":242,"props":917,"children":919},{"className":918},[],[920],{"type":46,"value":898},{"type":46,"value":922}," 具有明確的生命週期。這意味著當 Pod 不再存在時，Pod 中的數據將被破壞。這也意味著 ",{"type":41,"tag":242,"props":924,"children":926},{"className":925},[],[927],{"type":46,"value":898},{"type":46,"value":929}," 不是用於存儲持久數據的好解決方案。",{"type":41,"tag":91,"props":931,"children":933},{"id":932},"persistent-volume",[934],{"type":46,"value":935},"Persistent Volume",{"type":41,"tag":42,"props":937,"children":938},{},[939,941,946,948,953,955,960,962,968,970,975],{"type":46,"value":940},"為了避免將 ",{"type":41,"tag":242,"props":942,"children":944},{"className":943},[],[945],{"type":46,"value":898},{"type":46,"value":947}," 生命週期的約束與 Pod 生命週期綁定在一起，",{"type":41,"tag":242,"props":949,"children":951},{"className":950},[],[952],{"type":46,"value":935},{"type":46,"value":954}," 允許為 Cluster 配置獨立於 Pod 生命週期的存儲資源。‌‌終止 Pod 後，將根據該 ",{"type":41,"tag":242,"props":956,"children":958},{"className":957},[],[959],{"type":46,"value":898},{"type":46,"value":961}," 的回收策略來確定是否保留該 ",{"type":41,"tag":242,"props":963,"children":965},{"className":964},[],[966],{"type":46,"value":967},"Volume。",{"type":46,"value":969},"策略可以是手動刪除該 ",{"type":41,"tag":242,"props":971,"children":973},{"className":972},[],[974],{"type":46,"value":898},{"type":46,"value":976}," 或者終止該 Pod 時刪除。‌‌",{"type":41,"tag":125,"props":978,"children":979},{},[],{"title":8,"searchDepth":981,"depth":981,"links":982},2,[983,989,990,994,995,1002,1007],{"id":75,"depth":981,"text":78,"children":984},[985,987,988],{"id":93,"depth":986,"text":96},3,{"id":104,"depth":986,"text":107},{"id":115,"depth":986,"text":118},{"id":130,"depth":981,"text":133},{"id":144,"depth":981,"text":147,"children":991},[992,993],{"id":183,"depth":986,"text":186},{"id":194,"depth":986,"text":197},{"id":262,"depth":981,"text":265},{"id":277,"depth":981,"text":280,"children":996},[997,998,999,1000,1001],{"id":292,"depth":986,"text":292},{"id":339,"depth":986,"text":339},{"id":368,"depth":986,"text":368},{"id":383,"depth":986,"text":383},{"id":406,"depth":986,"text":406},{"id":450,"depth":981,"text":453,"children":1003},[1004,1005,1006],{"id":472,"depth":986,"text":472},{"id":501,"depth":986,"text":501},{"id":516,"depth":986,"text":519},{"id":552,"depth":981,"text":555,"children":1008},[1009,1010,1011,1012,1013,1014,1015,1016],{"id":563,"depth":986,"text":566},{"id":606,"depth":986,"text":609},{"id":662,"depth":986,"text":665},{"id":751,"depth":986,"text":754},{"id":812,"depth":986,"text":815},{"id":842,"depth":986,"text":845},{"id":895,"depth":986,"text":898},{"id":932,"depth":986,"text":935},"markdown","content:1.blog:015.k8s-intro:00.md","content","1.blog/015.k8s-intro/00.md","1.blog/015.k8s-intro/00","md",{"_path":1024,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":1025,"description":1026,"layout":11,"series":12,"image":1027,"keywords":1028,"head":1029,"body":1037,"_type":1017,"_id":1689,"_source":1019,"_file":1690,"_stem":1691,"_extension":1022},"/blog/k8s-intro/01","開始使用 Kubernetes (上)","要開始了解 Kubernetes，首先要先創建出一個實體來用於學習。",{"src":14,"alt":15,"width":16,"height":17},[19,20,21,22],{"meta":1030},[1031,1032,1034,1036],{"name":26,"content":27},{"name":29,"content":1033},"7 min read",{"property":32,"content":1035},"2021-02-10T00:00:00.000Z",{"property":35,"content":36},{"type":38,"children":1038,"toc":1679},[1039,1066,1069,1074,1079,1121,1124,1130,1135,1141,1161,1302,1308,1315,1374,1380,1408,1415,1486,1493,1526,1534,1577,1580,1586,1609,1612,1617,1647,1676],{"type":41,"tag":1040,"props":1041,"children":1042},"note",{},[1043,1061],{"type":41,"tag":42,"props":1044,"children":1045},{},[1046,1048,1051,1053,1059],{"type":46,"value":1047},"💡 我個人是使用 mac，所以下面有關於安裝的想關內容會以 mac 為主。",{"type":41,"tag":731,"props":1049,"children":1050},{},[],{"type":46,"value":1052},"\n幾乎所有的工具我都是使用 ",{"type":41,"tag":242,"props":1054,"children":1056},{"className":1055},[],[1057],{"type":46,"value":1058},"asdf",{"type":46,"value":1060},"來安裝的，非常推薦使用！",{"type":41,"tag":42,"props":1062,"children":1063},{},[1064],{"type":46,"value":1065},"💡 下面 asciinema 影片裡的所有指令直接 highlight 用於複製貼上！",{"type":41,"tag":125,"props":1067,"children":1068},{},[],{"type":41,"tag":73,"props":1070,"children":1072},{"id":1071},"kubectl",[1073],{"type":46,"value":1071},{"type":41,"tag":1075,"props":1076,"children":1078},"asciinema",{"id":1077},"389003",[],{"type":41,"tag":42,"props":1080,"children":1081},{},[1082,1084,1089,1091,1096,1098,1105,1107,1112,1114,1119],{"type":46,"value":1083},"在開始使用 k8s 之前，首先需要安裝 ",{"type":41,"tag":242,"props":1085,"children":1087},{"className":1086},[],[1088],{"type":46,"value":1071},{"type":46,"value":1090}," 。 ",{"type":41,"tag":242,"props":1092,"children":1094},{"className":1093},[],[1095],{"type":46,"value":1071},{"type":46,"value":1097}," 是一個 k8s 命令行工具，用於部署應用、檢視日誌、及各種和 k8s cluster 的互動。我個人喜歡使用 asdf 來安裝這類工具，但是根據",{"type":41,"tag":204,"props":1099,"children":1102},{"href":1100,"rel":1101},"https://kubernetes.io/zh/docs/tasks/tools/install-kubectl/?ref=blog.ewocker.com",[208],[1103],{"type":46,"value":1104},"官方文檔",{"type":46,"value":1106},"來安裝也是非常容易的。上面是一段很隨便的 ",{"type":41,"tag":242,"props":1108,"children":1110},{"className":1109},[],[1111],{"type":46,"value":1075},{"type":46,"value":1113},"，主要只是演示一些非常簡單的 ",{"type":41,"tag":242,"props":1115,"children":1117},{"className":1116},[],[1118],{"type":46,"value":1071},{"type":46,"value":1120}," 。",{"type":41,"tag":125,"props":1122,"children":1123},{},[],{"type":41,"tag":73,"props":1125,"children":1127},{"id":1126},"創建-kubernetes-clusters",[1128],{"type":46,"value":1129},"創建 Kubernetes Clusters",{"type":41,"tag":42,"props":1131,"children":1132},{},[1133],{"type":46,"value":1134},"從零開始創建一個 Kubernetes Cluster 實際上是非常繁雜的一件事，但在開源社群的推動下，現在已經逐漸變得越來越簡單了。這裡將會簡單介紹各個常見的創建 Kubernetes 方法。",{"type":41,"tag":91,"props":1136,"children":1138},{"id":1137},"local",[1139],{"type":46,"value":1140},"Local",{"type":41,"tag":42,"props":1142,"children":1143},{},[1144,1146,1152,1154,1160],{"type":46,"value":1145},"在本地創建 k8s 是相較起來比較簡單且快速的辦法，非常適合用於各種測試和學習。常見的工具有 ",{"type":41,"tag":242,"props":1147,"children":1149},{"className":1148},[],[1150],{"type":46,"value":1151},"minikube",{"type":46,"value":1153}," 和 ",{"type":41,"tag":242,"props":1155,"children":1157},{"className":1156},[],[1158],{"type":46,"value":1159},"kind",{"type":46,"value":336},{"type":41,"tag":1162,"props":1163,"children":1164},"ul",{},[1165,1226],{"type":41,"tag":1166,"props":1167,"children":1168},"li",{},[1169,1179,1183,1188,1190,1195,1197,1204,1206,1211,1213,1218,1220,1225],{"type":41,"tag":1170,"props":1171,"children":1172},"h4",{"id":1151},[1173],{"type":41,"tag":204,"props":1174,"children":1177},{"href":1175,"rel":1176},"https://minikube.sigs.k8s.io/docs/?ref=blog.ewocker.com",[208],[1178],{"type":46,"value":1151},{"type":41,"tag":1075,"props":1180,"children":1182},{"id":1181},"388793",[],{"type":41,"tag":242,"props":1184,"children":1186},{"className":1185},[],[1187],{"type":46,"value":1151},{"type":46,"value":1189}," 是一個用於創建本地單一集群 k8s 簡單的工具，是一個在 VM上創建一個單一節點 node 的 cluster。這是目前最常見用於在本地上模擬一個 k8s cluster 的工具。\n因為是在本地上創建的 k8s，所以效能還是受限於自己電腦的處理器及內存大小，但作為學習用工具，在大多數情況下都是足夠的。\n",{"type":41,"tag":242,"props":1191,"children":1193},{"className":1192},[],[1194],{"type":46,"value":1151},{"type":46,"value":1196},"  的安裝有許多種辦法，可以",{"type":41,"tag":204,"props":1198,"children":1201},{"href":1199,"rel":1200},"https://minikube.sigs.k8s.io/docs/start/?ref=blog.ewocker.com",[208],[1202],{"type":46,"value":1203},"根據官方文檔來安裝",{"type":46,"value":1205},"。我個人喜歡使用 ",{"type":41,"tag":242,"props":1207,"children":1209},{"className":1208},[],[1210],{"type":46,"value":1058},{"type":46,"value":1212}," 來安裝這類工具，上面是一段用 ",{"type":41,"tag":242,"props":1214,"children":1216},{"className":1215},[],[1217],{"type":46,"value":1151},{"type":46,"value":1219}," 創建 cluster 的簡單 ",{"type":41,"tag":242,"props":1221,"children":1223},{"className":1222},[],[1224],{"type":46,"value":1075},{"type":46,"value":1120},{"type":41,"tag":1166,"props":1227,"children":1228},{},[1229,1238,1242,1247,1249,1254,1256,1261,1263,1268,1270,1275,1277,1283,1284,1289,1290,1295,1296,1301],{"type":41,"tag":1170,"props":1230,"children":1231},{"id":1159},[1232],{"type":41,"tag":204,"props":1233,"children":1236},{"href":1234,"rel":1235},"https://kind.sigs.k8s.io/docs/user/quick-start/?ref=blog.ewocker.com",[208],[1237],{"type":46,"value":1159},{"type":41,"tag":1075,"props":1239,"children":1241},{"id":1240},"389002",[],{"type":41,"tag":242,"props":1243,"children":1245},{"className":1244},[],[1246],{"type":46,"value":1159},{"type":46,"value":1248}," 是 ",{"type":41,"tag":154,"props":1250,"children":1251},{},[1252],{"type":46,"value":1253},"K",{"type":46,"value":1255},"ubernetes ",{"type":41,"tag":154,"props":1257,"children":1258},{},[1259],{"type":46,"value":1260},"in D",{"type":46,"value":1262},"ocker 的簡寫，是使用 docker 為節點來創建 k8s 的工具。開發 ",{"type":41,"tag":242,"props":1264,"children":1266},{"className":1265},[],[1267],{"type":46,"value":1159},{"type":46,"value":1269}," 的初衷是為了測試 k8s 本身，但因為其輕便及簡單的特信，近來慢慢被使用於各種簡單的 local k8s service 測試等等。\n",{"type":41,"tag":242,"props":1271,"children":1273},{"className":1272},[],[1274],{"type":46,"value":1159},{"type":46,"value":1276}," 的安裝有許多種辦法，可以",{"type":41,"tag":204,"props":1278,"children":1281},{"href":1279,"rel":1280},"https://kind.sigs.k8s.io/docs/user/quick-start/?ref=blog.ewocker.com#installation",[208],[1282],{"type":46,"value":1203},{"type":46,"value":1205},{"type":41,"tag":242,"props":1285,"children":1287},{"className":1286},[],[1288],{"type":46,"value":1058},{"type":46,"value":1212},{"type":41,"tag":242,"props":1291,"children":1293},{"className":1292},[],[1294],{"type":46,"value":1159},{"type":46,"value":1219},{"type":41,"tag":242,"props":1297,"children":1299},{"className":1298},[],[1300],{"type":46,"value":1075},{"type":46,"value":1120},{"type":41,"tag":91,"props":1303,"children":1305},{"id":1304},"cloud-managed",[1306],{"type":46,"value":1307},"Cloud Managed",{"type":41,"tag":42,"props":1309,"children":1310},{},[1311],{"type":41,"tag":270,"props":1312,"children":1314},{"alt":20,"src":1313},"k8s.png",[],{"type":41,"tag":42,"props":1316,"children":1317},{},[1318,1320,1327,1329,1336,1337,1344,1346,1349,1351,1354,1356,1363,1365,1372],{"type":46,"value":1319},"因為 Kubernetes 的快速普及，市面上幾乎所有的雲供應商都有自己的 Managed Kubernetes 服務。像是 ",{"type":41,"tag":204,"props":1321,"children":1324},{"href":1322,"rel":1323},"https://cloud.google.com/kubernetes-engine?ref=blog.ewocker.com",[208],[1325],{"type":46,"value":1326},"GCP 的 Google Kubernetes Engine (GKE)",{"type":46,"value":1328},"、",{"type":41,"tag":204,"props":1330,"children":1333},{"href":1331,"rel":1332},"https://aws.amazon.com/eks/?ref=blog.ewocker.com",[208],[1334],{"type":46,"value":1335},"AWS 的 Elastic Kubernetes Service (EKS)",{"type":46,"value":1328},{"type":41,"tag":204,"props":1338,"children":1341},{"href":1339,"rel":1340},"https://azure.microsoft.com/en-us/topic/what-is-kubernetes/?amp%3Bef_id=Cj0KCQiA0-6ABhDMARIsAFVdQv8GPBiBmtEtu_vx4GGIlWMn8amElgUiNIZ5pT1Rh_OWFYmL6bbOU0oaApghEALw_wcB%3AG%3As&%3BOCID=AID2100365_SEM_Cj0KCQiA0-6ABhDMARIsAFVdQv8GPBiBmtEtu_vx4GGIlWMn8amElgUiNIZ5pT1Rh_OWFYmL6bbOU0oaApghEALw_wcB%3AG%3As&ref=blog.ewocker.com",[208],[1342],{"type":46,"value":1343},"Azure 的 Azure Kubernetes Service (AKS)",{"type":46,"value":1345},"，以至於 Digital Ocean、Linode、阿里巴巴、IBM、RedHat 等等，真的是一大堆而且競爭激烈！",{"type":41,"tag":731,"props":1347,"children":1348},{},[],{"type":46,"value":1350},"\nManaged k8s 和一般自己創建和維護的 k8s 主要的差別就是，k8s 中的 master nodes 是由雲供應商管理的。簡單來說就是各種 control plane 的維護和運行都由廠商承包了，所以可以省下許多維護和升級所需的時間。",{"type":41,"tag":731,"props":1352,"children":1353},{},[],{"type":46,"value":1355},"\n創建這些 managed k8s 的方法主要是透過各個雲供應商的使用者頁面 (UI/Console) 來完成的。但因為 GitOps 以及 Infrastructure as Code 概念的衍生，愈來愈多科技大廠開始使用 ",{"type":41,"tag":204,"props":1357,"children":1360},{"href":1358,"rel":1359},"https://www.terraform.io/?ref=blog.ewocker.com",[208],[1361],{"type":46,"value":1362},"terraform",{"type":46,"value":1364}," 或是 ",{"type":41,"tag":204,"props":1366,"children":1369},{"href":1367,"rel":1368},"https://www.pulumi.com/?ref=blog.ewocker.com",[208],[1370],{"type":46,"value":1371},"pulumi",{"type":46,"value":1373}," 來在幾大雲供應商創建 k8s 了。",{"type":41,"tag":91,"props":1375,"children":1377},{"id":1376},"self-managed",[1378],{"type":46,"value":1379},"Self-Managed",{"type":41,"tag":42,"props":1381,"children":1382},{},[1383,1385,1391,1393,1399,1400,1406],{"type":46,"value":1384},"有許多公司因為資安原因或是各種客製化原因，會組建一個團對來管理自己的 k8s clusters (像是我目前就職的公司)。像這種時候就會使用像是 ",{"type":41,"tag":242,"props":1386,"children":1388},{"className":1387},[],[1389],{"type":46,"value":1390},"kops",{"type":46,"value":1392}," 、 ",{"type":41,"tag":242,"props":1394,"children":1396},{"className":1395},[],[1397],{"type":46,"value":1398},"kube-spray",{"type":46,"value":1392},{"type":41,"tag":242,"props":1401,"children":1403},{"className":1402},[],[1404],{"type":46,"value":1405},"kubeadm",{"type":46,"value":1407}," 來創建 cluster。這些工具主要用途也是在各大雲供應商或 bare metal 上創建 k8s，但是不像 EKS、GKE、AKS 等等由雲供應商管理控制組件 Control Plane Component，所有創建的 k8s 都是由自己全權管理的。",{"type":41,"tag":42,"props":1409,"children":1410},{},[1411],{"type":41,"tag":270,"props":1412,"children":1414},{"alt":1405,"src":1413},"kubeadm.png",[],{"type":41,"tag":42,"props":1416,"children":1417},{},[1418,1428,1430,1436,1438,1444,1446,1451,1453,1458,1459,1464,1466,1471,1472,1477,1479,1484],{"type":41,"tag":204,"props":1419,"children":1422},{"href":1420,"rel":1421},"https://kubernetes.io/docs/reference/setup-tools/kubeadm/?ref=blog.ewocker.com",[208],[1423],{"type":41,"tag":242,"props":1424,"children":1426},{"className":1425},[],[1427],{"type":46,"value":1405},{"type":46,"value":1429}," 是一個由 Kubernetes 官方推出的工具，其主要功能包括 ",{"type":41,"tag":242,"props":1431,"children":1433},{"className":1432},[],[1434],{"type":46,"value":1435},"kubeadm init",{"type":46,"value":1437}," 以及 ",{"type":41,"tag":242,"props":1439,"children":1441},{"className":1440},[],[1442],{"type":46,"value":1443},"kubeadm join",{"type":46,"value":1445}," 。簡單來說，就是簡化了",{"type":41,"tag":154,"props":1447,"children":1448},{},[1449],{"type":46,"value":1450},"初始化 k8s 的步驟",{"type":46,"value":1452},"和",{"type":41,"tag":154,"props":1454,"children":1455},{},[1456],{"type":46,"value":1457},"創建新節點 Node 的步驟",{"type":46,"value":336},{"type":41,"tag":242,"props":1460,"children":1462},{"className":1461},[],[1463],{"type":46,"value":1405},{"type":46,"value":1465}," 比較適用於在 bare metal 時使用，因為如果是使用雲供應商的話 ",{"type":41,"tag":242,"props":1467,"children":1469},{"className":1468},[],[1470],{"type":46,"value":1390},{"type":46,"value":1153},{"type":41,"tag":242,"props":1473,"children":1475},{"className":1474},[],[1476],{"type":46,"value":1398},{"type":46,"value":1478}," 都想叫簡單。我個人認為 ",{"type":41,"tag":242,"props":1480,"children":1482},{"className":1481},[],[1483],{"type":46,"value":1405},{"type":46,"value":1485}," 也很適合用於學習了解 k8s cluster 的創建步驟以及細節。",{"type":41,"tag":42,"props":1487,"children":1488},{},[1489],{"type":41,"tag":270,"props":1490,"children":1492},{"alt":1390,"src":1491},"kops.png",[],{"type":41,"tag":42,"props":1494,"children":1495},{},[1496,1506,1507,1511,1512,1517,1519,1524],{"type":41,"tag":204,"props":1497,"children":1500},{"href":1498,"rel":1499},"https://github.com/kubernetes/kops?ref=blog.ewocker.com",[208],[1501],{"type":41,"tag":242,"props":1502,"children":1504},{"className":1503},[],[1505],{"type":46,"value":1390},{"type":46,"value":1248},{"type":41,"tag":154,"props":1508,"children":1509},{},[1510],{"type":46,"value":1253},{"type":46,"value":1255},{"type":41,"tag":154,"props":1513,"children":1514},{},[1515],{"type":46,"value":1516},"Op",{"type":46,"value":1518},"eration",{"type":41,"tag":154,"props":1520,"children":1521},{},[1522],{"type":46,"value":1523},"s",{"type":46,"value":1525}," 的英文縮寫，是一個非常好用的 k8s 管理工具。其有許多的 configuration 選項讓管理 k8s 變得非常的簡單，並且每一個新的版本都都有許多資安方面的考量，而且背後開源團隊的成員真的都非常強 (因為其中有我們公司的一個大神)！",{"type":41,"tag":42,"props":1527,"children":1528},{},[1529],{"type":41,"tag":270,"props":1530,"children":1533},{"alt":1531,"src":1532},"kubespray","kubespray.png",[],{"type":41,"tag":42,"props":1535,"children":1536},{},[1537,1547,1549,1554,1556,1561,1563,1568,1570,1575],{"type":41,"tag":204,"props":1538,"children":1541},{"href":1539,"rel":1540},"https://github.com/kubernetes-sigs/kubespray?ref=blog.ewocker.com",[208],[1542],{"type":41,"tag":242,"props":1543,"children":1545},{"className":1544},[],[1546],{"type":46,"value":1398},{"type":46,"value":1548}," 是一個 Kubernetes Incubator 中的項目，主要是透過 Ansible Playbook 來完成定義系統及 k8s 的部署任務。與 ",{"type":41,"tag":242,"props":1550,"children":1552},{"className":1551},[],[1553],{"type":46,"value":1390},{"type":46,"value":1555}," 不同的是，",{"type":41,"tag":242,"props":1557,"children":1559},{"className":1558},[],[1560],{"type":46,"value":1390},{"type":46,"value":1562}," 和雲供應商有有較大的綁定，但 ",{"type":41,"tag":242,"props":1564,"children":1566},{"className":1565},[],[1567],{"type":46,"value":1398},{"type":46,"value":1569}," 因為是使用 Ansible 來完成各項部署工作，所有在運行平台上有較多的選擇和客製化選擇。但使用難度確實是比 ",{"type":41,"tag":242,"props":1571,"children":1573},{"className":1572},[],[1574],{"type":46,"value":1390},{"type":46,"value":1576}," 要高上一些的。",{"type":41,"tag":125,"props":1578,"children":1579},{},[],{"type":41,"tag":73,"props":1581,"children":1583},{"id":1582},"其他的-k8s-練習管道",[1584],{"type":46,"value":1585},"其他的 k8s 練習管道",{"type":41,"tag":42,"props":1587,"children":1588},{},[1589,1591,1598,1600,1607],{"type":46,"value":1590},"除了自己創建自己的 k8s 來起步之外，也可以選擇透過一些類似於模擬的網站來練習。像是由 O'Reilly 提供的 ",{"type":41,"tag":204,"props":1592,"children":1595},{"href":1593,"rel":1594},"https://www.katacoda.com/courses/kubernetes?ref=blog.ewocker.com",[208],[1596],{"type":46,"value":1597},"Katacoda 的 k8s playground",{"type":46,"value":1599},"，有各種不同的情境讓人練習各種簡單的狀況，或是 ",{"type":41,"tag":204,"props":1601,"children":1604},{"href":1602,"rel":1603},"https://labs.play-with-k8s.com/?ref=blog.ewocker.com",[208],[1605],{"type":46,"value":1606},"Play With Kubernetes",{"type":46,"value":1608},"，一個從零開始練習創建 k8s 的網站。",{"type":41,"tag":125,"props":1610,"children":1611},{},[],{"type":41,"tag":73,"props":1613,"children":1615},{"id":1614},"總結",[1616],{"type":46,"value":1614},{"type":41,"tag":42,"props":1618,"children":1619},{},[1620,1622,1627,1628,1633,1635,1638,1640,1645],{"type":46,"value":1621},"上面提供各種常見開始使用 k8s 的方式。雖然直接在雲供應商上創建一個 k8s cluster 是最貼近業界需求的方法，但一般來說如果是純屬練習用途並不推薦這樣做，因為除了要對各個雲供應商有基本的瞭解之外還要考量到價格。我個人最推薦的就是使用 ",{"type":41,"tag":242,"props":1623,"children":1625},{"className":1624},[],[1626],{"type":46,"value":1151},{"type":46,"value":1364},{"type":41,"tag":242,"props":1629,"children":1631},{"className":1630},[],[1632],{"type":46,"value":1159},{"type":46,"value":1634}," 在本地創建，首先是難度較低且沒有太多的門檻，再來就是相較使用 katacoda 這類網站比較有真實感，而且因為是自己的 cluster，所以想怎麼嘗試都沒問題。",{"type":41,"tag":731,"props":1636,"children":1637},{},[],{"type":46,"value":1639},"\n推薦想要開始學習 k8s 的讀者可以自己試著使用 ",{"type":41,"tag":242,"props":1641,"children":1643},{"className":1642},[],[1644],{"type":46,"value":1151},{"type":46,"value":1646}," 來在本地創建一個 cluster，以便於後續教學文章中的實作內容。",{"type":41,"tag":1040,"props":1648,"children":1649},{},[1650],{"type":41,"tag":42,"props":1651,"children":1652},{},[1653,1655,1660,1662,1667,1669,1674],{"type":46,"value":1654},"💡使用 ",{"type":41,"tag":242,"props":1656,"children":1658},{"className":1657},[],[1659],{"type":46,"value":1159},{"type":46,"value":1661}," 也可以，這裡推薦 ",{"type":41,"tag":242,"props":1663,"children":1665},{"className":1664},[],[1666],{"type":46,"value":1151},{"type":46,"value":1668}," 是因為撰寫的當下 ",{"type":41,"tag":242,"props":1670,"children":1672},{"className":1671},[],[1673],{"type":46,"value":1159},{"type":46,"value":1675}," 還沒有 GA。",{"type":41,"tag":125,"props":1677,"children":1678},{},[],{"title":8,"searchDepth":981,"depth":981,"links":1680},[1681,1682,1687,1688],{"id":1071,"depth":981,"text":1071},{"id":1126,"depth":981,"text":1129,"children":1683},[1684,1685,1686],{"id":1137,"depth":986,"text":1140},{"id":1304,"depth":986,"text":1307},{"id":1376,"depth":986,"text":1379},{"id":1582,"depth":981,"text":1585},{"id":1614,"depth":981,"text":1614},"content:1.blog:015.k8s-intro:01.md","1.blog/015.k8s-intro/01.md","1.blog/015.k8s-intro/01",{"_path":1693,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":1694,"description":1695,"layout":11,"series":12,"image":1696,"keywords":1697,"head":1698,"body":1706,"_type":1017,"_id":2522,"_source":1019,"_file":2523,"_stem":2524,"_extension":1022},"/blog/k8s-intro/02","開始使用 Kubernetes (下)","Kubernetes 的官方文檔雖然包括了很多重要的內容，但其實有許多對剛上手的使用者來說都是不需要馬上接觸的資訊，本篇文章將會以日常實作的角度來切入如何開始使用 Kubernetes。",{"src":14,"alt":15,"width":16,"height":17},[19,20,21,22],{"meta":1699},[1700,1701,1703,1705],{"name":26,"content":27},{"name":29,"content":1702},"8 min read",{"property":32,"content":1704},"2021-02-20T00:00:00.000Z",{"property":35,"content":36},{"type":38,"children":1707,"toc":2515},[1708,1730,1738,1741,1747,1772,1821,1833,1838,1880,1922,1929,1941,1963,2003,2008,2011,2015,2022,2042,2102,2109,2126,2203,2231,2234,2240,2247,2258,2294,2327,2375,2387,2402,2405,2409,2414,2420,2432,2455,2460,2472,2495,2498,2502,2512],{"type":41,"tag":42,"props":1709,"children":1710},{},[1711,1713,1720,1722,1728],{"type":46,"value":1712},"在",{"type":41,"tag":204,"props":1714,"children":1717},{"href":1715,"rel":1716},"https://blog.ewocker.com/blog/k8s-intro/01",[208],[1718],{"type":46,"value":1719},"上篇",{"type":46,"value":1721},"中，大至介紹了一下創建 k8s cluster 的各種方式。這篇則是動手來做一些簡單的操作，以此來了解一些 k8s 的基本概念。這篇的內容將會使用到許多 ",{"type":41,"tag":204,"props":1723,"children":1726},{"href":1724,"rel":1725},"https://blog.ewocker.com/intro-to-k8s/TODOLink",[208],[1727],{"type":46,"value":9},{"type":46,"value":1729},"的內容，如果有任何專有名詞不太了解可以參照該文章。",{"type":41,"tag":1040,"props":1731,"children":1732},{},[1733],{"type":41,"tag":42,"props":1734,"children":1735},{},[1736],{"type":46,"value":1737},"💡 Kubernetes 中 99.99% 的 Configuration 都是 YAML Syntax，如果對 YAML 的句法不太認識的話，推薦先自行了解一下。簡單來說就是 YAML is a superset of JSON。",{"type":41,"tag":125,"props":1739,"children":1740},{},[],{"type":41,"tag":73,"props":1742,"children":1744},{"id":1743},"使用-minikube-創建本底-k8s-cluster",[1745],{"type":46,"value":1746},"使用 Minikube 創建本底 k8s cluster",{"type":41,"tag":42,"props":1748,"children":1749},{},[1750,1752,1757,1758,1763,1765,1770],{"type":46,"value":1751},"::\n💡 有關 ",{"type":41,"tag":242,"props":1753,"children":1755},{"className":1754},[],[1756],{"type":46,"value":1151},{"type":46,"value":1153},{"type":41,"tag":242,"props":1759,"children":1761},{"className":1760},[],[1762],{"type":46,"value":1071},{"type":46,"value":1764}," 的安裝請參照",{"type":41,"tag":204,"props":1766,"children":1768},{"href":1715,"rel":1767},[208],[1769],{"type":46,"value":1719},{"type":46,"value":1771},"\n::",{"type":41,"tag":42,"props":1773,"children":1774},{},[1775,1777,1782,1784,1789,1790,1795,1796,1799,1801,1807,1809,1812,1813,1819],{"type":46,"value":1776},"首先必須在本地創建一個 k8s cluster，這裡我們使用 ",{"type":41,"tag":242,"props":1778,"children":1780},{"className":1779},[],[1781],{"type":46,"value":1151},{"type":46,"value":1783}," 來創建。（有關 ",{"type":41,"tag":242,"props":1785,"children":1787},{"className":1786},[],[1788],{"type":46,"value":1151},{"type":46,"value":1764},{"type":41,"tag":204,"props":1791,"children":1793},{"href":1715,"rel":1792},[208],[1794],{"type":46,"value":1719},{"type":46,"value":222},{"type":41,"tag":731,"props":1797,"children":1798},{},[],{"type":46,"value":1800},"\n➤ ",{"type":41,"tag":242,"props":1802,"children":1804},{"className":1803},[],[1805],{"type":46,"value":1806},"minikube start",{"type":46,"value":1808}," - 安裝好 minikube 後，創建本地 cluster。",{"type":41,"tag":731,"props":1810,"children":1811},{},[],{"type":46,"value":1800},{"type":41,"tag":242,"props":1814,"children":1816},{"className":1815},[],[1817],{"type":46,"value":1818},"kubectl cluster-info",{"type":46,"value":1820}," - 創建好 k8s 後，取得 cluster 的基本信息。",{"type":41,"tag":568,"props":1822,"children":1823},{},[1824],{"type":41,"tag":42,"props":1825,"children":1826},{},[1827,1831],{"type":41,"tag":270,"props":1828,"children":1830},{"alt":1806,"src":1829},"minikube.png",[],{"type":46,"value":1832},"\nminikube start",{"type":41,"tag":42,"props":1834,"children":1835},{},[1836],{"type":46,"value":1837},"這裡倒底發生了什麼事情呢？",{"type":41,"tag":42,"props":1839,"children":1840},{},[1841,1843,1848,1850,1856,1858,1864,1865,1868,1870,1879],{"type":46,"value":1842},"首先 ",{"type":41,"tag":242,"props":1844,"children":1846},{"className":1845},[],[1847],{"type":46,"value":1151},{"type":46,"value":1849}," 使用 environment variable ",{"type":41,"tag":242,"props":1851,"children":1853},{"className":1852},[],[1854],{"type":46,"value":1855},"KUBECONFIG",{"type":46,"value":1857}," 找到了我的 ",{"type":41,"tag":242,"props":1859,"children":1861},{"className":1860},[],[1862],{"type":46,"value":1863},"kubeconfig",{"type":46,"value":336},{"type":41,"tag":731,"props":1866,"children":1867},{},[],{"type":46,"value":1869},"\n並且在本地創建了一個 virtual machine 作為 k8s node，並在上面運行了基本的 control plane 組件。這裡可以看到 master endpoint 是在本機上的 ",{"type":41,"tag":165,"props":1871,"children":1872},{},[1873],{"type":41,"tag":242,"props":1874,"children":1876},{"className":1875},[],[1877],{"type":46,"value":1878},"127.0.0.1:55008",{"type":46,"value":336},{"type":41,"tag":42,"props":1881,"children":1882},{},[1883,1885,1890,1892,1898,1900,1905,1907,1913,1915,1920],{"type":46,"value":1884},"一般來說 ",{"type":41,"tag":242,"props":1886,"children":1888},{"className":1887},[],[1889],{"type":46,"value":1863},{"type":46,"value":1891}," 的預設路徑是 ",{"type":41,"tag":242,"props":1893,"children":1895},{"className":1894},[],[1896],{"type":46,"value":1897},"$HOME/.kube/config",{"type":46,"value":1899}," ，這是一個用於和所有 k8s 溝通的檔案。 ",{"type":41,"tag":242,"props":1901,"children":1903},{"className":1902},[],[1904],{"type":46,"value":1863},{"type":46,"value":1906},"包括三項主要信息 clusters、users、contexts (使用指令 ",{"type":41,"tag":242,"props":1908,"children":1910},{"className":1909},[],[1911],{"type":46,"value":1912},"kubectl config view --minify",{"type":46,"value":1914}," 來看 ",{"type":41,"tag":242,"props":1916,"children":1918},{"className":1917},[],[1919],{"type":46,"value":1863},{"type":46,"value":1921}," 的簡化內容)。",{"type":41,"tag":42,"props":1923,"children":1924},{},[1925],{"type":41,"tag":270,"props":1926,"children":1928},{"alt":8,"src":1927},"config.png",[],{"type":41,"tag":42,"props":1930,"children":1931},{},[1932,1934,1939],{"type":46,"value":1933},"這裡介紹一下 ",{"type":41,"tag":242,"props":1935,"children":1937},{"className":1936},[],[1938],{"type":46,"value":1863},{"type":46,"value":1940}," 的基本，",{"type":41,"tag":1040,"props":1942,"children":1943},{},[1944],{"type":41,"tag":42,"props":1945,"children":1946},{},[1947,1949,1954,1956,1962],{"type":46,"value":1948},"💡 ",{"type":41,"tag":242,"props":1950,"children":1952},{"className":1951},[],[1953],{"type":46,"value":1863},{"type":46,"value":1955}," 的例子和內容了解在這裡可以選擇性略過，不會影響本篇後續內容的學習，也可以直接參照稍微複雜一點的",{"type":41,"tag":204,"props":1957,"children":1960},{"href":1958,"rel":1959},"https://kubernetes.io/zh/docs/tasks/access-application-cluster/configure-access-multiple-clusters/?ref=blog.ewocker.com",[208],[1961],{"type":46,"value":1104},{"type":46,"value":336},{"type":41,"tag":42,"props":1964,"children":1965},{},[1966,1971,1973,1976,1981,1983,1986,1991,1993,1996,2001],{"type":41,"tag":154,"props":1967,"children":1968},{},[1969],{"type":46,"value":1970},"cluster",{"type":46,"value":1972}," - 包含了所有 cluster 的基本信息，像是 name、kube-apiserver endpoint、certificate-authority。",{"type":41,"tag":731,"props":1974,"children":1975},{},[],{"type":41,"tag":154,"props":1977,"children":1978},{},[1979],{"type":46,"value":1980},"user",{"type":46,"value":1982}," - 包含了所有的 user 的基本信息，像是 name 和 credentials (Ex. token、cert、username/password)。",{"type":41,"tag":731,"props":1984,"children":1985},{},[],{"type":41,"tag":154,"props":1987,"children":1988},{},[1989],{"type":46,"value":1990},"context",{"type":46,"value":1992}," - 是使用 kubectl 時用於確認是使用哪個 user 溝通哪個 cluster ，每一個 context 是 user+cluster+namespace 的組合。",{"type":41,"tag":731,"props":1994,"children":1995},{},[],{"type":41,"tag":154,"props":1997,"children":1998},{},[1999],{"type":46,"value":2000},"current-context",{"type":46,"value":2002}," - 則是目前所使用的 context。",{"type":41,"tag":42,"props":2004,"children":2005},{},[2006],{"type":46,"value":2007},"一般來說使用者會和許多 clusters 溝通，每個 cluster 可能擁有多個不同的 user accounts 也可能共享同一個 user account。",{"type":41,"tag":125,"props":2009,"children":2010},{},[],{"type":41,"tag":73,"props":2012,"children":2013},{"id":1071},[2014],{"type":46,"value":1071},{"type":41,"tag":42,"props":2016,"children":2017},{},[2018],{"type":41,"tag":270,"props":2019,"children":2021},{"alt":8,"src":2020},"kubectl.png",[],{"type":41,"tag":42,"props":2023,"children":2024},{},[2025,2027,2033,2035,2041],{"type":46,"value":2026},"上圖中的 verbose log (flag -v6) 就顯示出指令 ",{"type":41,"tag":242,"props":2028,"children":2030},{"className":2029},[],[2031],{"type":46,"value":2032},"kubectl get pod",{"type":46,"value":2034}," 就是一個 HTTP GET Request 到 kube-apiserver (127.0.0.1) 的路徑 ",{"type":41,"tag":242,"props":2036,"children":2038},{"className":2037},[],[2039],{"type":46,"value":2040},"/api/v1/namespaces/default/pods",{"type":46,"value":336},{"type":41,"tag":42,"props":2043,"children":2044},{},[2045,2047,2052,2054,2059,2061,2066,2068,2073,2075,2080,2082,2088,2090,2093,2095,2100],{"type":46,"value":2046},"在開始之前先說說 ",{"type":41,"tag":242,"props":2048,"children":2050},{"className":2049},[],[2051],{"type":46,"value":1071},{"type":46,"value":2053}," 吧！",{"type":41,"tag":242,"props":2055,"children":2057},{"className":2056},[],[2058],{"type":46,"value":1071},{"type":46,"value":2060}," 是和 k8s 溝通的最基本工具，",{"type":41,"tag":242,"props":2062,"children":2064},{"className":2063},[],[2065],{"type":46,"value":1071},{"type":46,"value":2067}," 會使用 ",{"type":41,"tag":242,"props":2069,"children":2071},{"className":2070},[],[2072],{"type":46,"value":1863},{"type":46,"value":2074}," 中的設定和資訊來和 cluster 溝通，上面說到 ",{"type":41,"tag":242,"props":2076,"children":2078},{"className":2077},[],[2079],{"type":46,"value":1863},{"type":46,"value":2081}," 中得 cluster 部分包含 ",{"type":41,"tag":204,"props":2083,"children":2086},{"href":2084,"rel":2085},"https://blog.ewocker.com/blog/k8s-intro/01/#kube-apiserver",[208],[2087],{"type":46,"value":339},{"type":46,"value":2089}," 的位置。這裡快速的介紹一下 kube-apiserver。",{"type":41,"tag":731,"props":2091,"children":2092},{},[],{"type":46,"value":2094},"\n每個 k8s cluster 都會有一個 kube-apiserver，kube-apiserver 類似於一個開放的端口，是以個 REST Endpoint。而 ",{"type":41,"tag":242,"props":2096,"children":2098},{"className":2097},[],[2099],{"type":46,"value":1071},{"type":46,"value":2101}," 則是一個包裝好的客戶端，讓使用者能輕鬆的和 k8s cluster 互動，其實說到底也就是 HTTP Request 。",{"type":41,"tag":42,"props":2103,"children":2104},{},[2105],{"type":41,"tag":270,"props":2106,"children":2108},{"alt":8,"src":2107},"kubectl2.png",[],{"type":41,"tag":42,"props":2110,"children":2111},{},[2112,2117,2119,2124],{"type":41,"tag":242,"props":2113,"children":2115},{"className":2114},[],[2116],{"type":46,"value":1071},{"type":46,"value":2118}," 的使用方式挺容易上手的，就是 1) ",{"type":41,"tag":242,"props":2120,"children":2122},{"className":2121},[],[2123],{"type":46,"value":1071},{"type":46,"value":2125}," 2) 動作 3) 資源 4) 名稱 [Optional]。",{"type":41,"tag":1162,"props":2127,"children":2128},{},[2129,2171],{"type":41,"tag":1166,"props":2130,"children":2131},{},[2132,2134,2139,2141,2147,2149,2154,2156,2162,2164,2170],{"type":46,"value":2133},"舉例來說使用者想要刪除名為 test 的 Pod 那就是 1) ",{"type":41,"tag":242,"props":2135,"children":2137},{"className":2136},[],[2138],{"type":46,"value":1071},{"type":46,"value":2140}," 2) 動作 ",{"type":41,"tag":242,"props":2142,"children":2144},{"className":2143},[],[2145],{"type":46,"value":2146},"delete",{"type":46,"value":2148}," 3) 資源 ",{"type":41,"tag":242,"props":2150,"children":2152},{"className":2151},[],[2153],{"type":46,"value":563},{"type":46,"value":2155}," 4) 名稱 ",{"type":41,"tag":242,"props":2157,"children":2159},{"className":2158},[],[2160],{"type":46,"value":2161},"test",{"type":46,"value":2163}," → ",{"type":41,"tag":242,"props":2165,"children":2167},{"className":2166},[],[2168],{"type":46,"value":2169},"kubectl delete pod test",{"type":46,"value":1120},{"type":41,"tag":1166,"props":2172,"children":2173},{},[2174,2176,2182,2183,2189,2190,2195,2197,2202],{"type":46,"value":2175},"想要取得所有的 Pod 則是 1) ",{"type":41,"tag":242,"props":2177,"children":2179},{"className":2178},[],[2180],{"type":46,"value":2181},"kubeclt",{"type":46,"value":2140},{"type":41,"tag":242,"props":2184,"children":2186},{"className":2185},[],[2187],{"type":46,"value":2188},"get",{"type":46,"value":2148},{"type":41,"tag":242,"props":2191,"children":2193},{"className":2192},[],[2194],{"type":46,"value":563},{"type":46,"value":2196}," => ",{"type":41,"tag":242,"props":2198,"children":2200},{"className":2199},[],[2201],{"type":46,"value":2032},{"type":46,"value":336},{"type":41,"tag":42,"props":2204,"children":2205},{},[2206,2208,2213,2215,2221,2223,2229],{"type":46,"value":2207},"當然並非所有指令都完全是這樣的結構，但大多數都是如此。使用 ",{"type":41,"tag":242,"props":2209,"children":2211},{"className":2210},[],[2212],{"type":46,"value":1071},{"type":46,"value":2214}," 時如果有不了解或不熟悉的指令時可以直接加上 ",{"type":41,"tag":242,"props":2216,"children":2218},{"className":2217},[],[2219],{"type":46,"value":2220},"--help",{"type":46,"value":2222}," 來觀看簡易的使用方式，如果有不理解的資源時也可以使用 ",{"type":41,"tag":242,"props":2224,"children":2226},{"className":2225},[],[2227],{"type":46,"value":2228},"kubectl explain",{"type":46,"value":2230}," 來觀看資源文檔。",{"type":41,"tag":125,"props":2232,"children":2233},{},[],{"type":41,"tag":73,"props":2235,"children":2237},{"id":2236},"namespace",[2238],{"type":46,"value":2239},"Namespace",{"type":41,"tag":42,"props":2241,"children":2242},{},[2243],{"type":41,"tag":270,"props":2244,"children":2246},{"alt":8,"src":2245},"namespace.png",[],{"type":41,"tag":42,"props":2248,"children":2249},{},[2250,2252,2257],{"type":46,"value":2251},"在創建好 cluster 後，首先要知道什麼是 Namespace。Namespace 是一個用於更好管理的 k8s 中資源的抽象的概念，k8s 中幾乎所有資源都有其所屬的 Naemespace。用英文來解釋可能更容易一些，簡單來說 Namespace 就是 ",{"type":41,"tag":154,"props":2253,"children":2254},{},[2255],{"type":46,"value":2256},"Logical Grouping",{"type":46,"value":336},{"type":41,"tag":42,"props":2259,"children":2260},{},[2261,2263,2269,2271,2277,2279,2285,2287,2292],{"type":46,"value":2262},"以上圖為例，在一個 k8s cluster 中有許多 ",{"type":41,"tag":204,"props":2264,"children":2267},{"href":2265,"rel":2266},"https://blog.ewocker.com/blog/k8s-intro/00/#pod",[208],[2268],{"type":46,"value":566},{"type":46,"value":2270}," (k8s 的最小運行單位)，每個 Pod 會被 ",{"type":41,"tag":204,"props":2272,"children":2275},{"href":2273,"rel":2274},"https://blog.ewocker.com/blog/k8s-intro/00/#kube-scheduler",[208],[2276],{"type":46,"value":368},{"type":46,"value":2278}," 根據各種條件分配到不同的 ",{"type":41,"tag":204,"props":2280,"children":2283},{"href":2281,"rel":2282},"https://blog.ewocker.com/blog/k8s-intro/00/#node",[208],[2284],{"type":46,"value":197},{"type":46,"value":2286}," 上運行，但使用者要如合使用 ",{"type":41,"tag":242,"props":2288,"children":2290},{"className":2289},[],[2291],{"type":46,"value":1071},{"type":46,"value":2293}," 來檢視這些 Pod 呢？這時 Namespace 的重要性就體現出來了，假設 Pod A、C、E 是屬於同一個組的軟體，這時使用 Namespace 將他們邏輯性的圈起來竟可以更方便的管理和檢視了。",{"type":41,"tag":42,"props":2295,"children":2296},{},[2297,2299,2305,2306,2312,2313,2319,2320,2326],{"type":46,"value":2298},"剛創建好的 cluster 目前有四個預設的 Namespace，分別是 ",{"type":41,"tag":242,"props":2300,"children":2302},{"className":2301},[],[2303],{"type":46,"value":2304},"default",{"type":46,"value":1328},{"type":41,"tag":242,"props":2307,"children":2309},{"className":2308},[],[2310],{"type":46,"value":2311},"kube-node-lease",{"type":46,"value":1328},{"type":41,"tag":242,"props":2314,"children":2316},{"className":2315},[],[2317],{"type":46,"value":2318},"kube-public",{"type":46,"value":1328},{"type":41,"tag":242,"props":2321,"children":2323},{"className":2322},[],[2324],{"type":46,"value":2325},"kube-system",{"type":46,"value":1120},{"type":41,"tag":42,"props":2328,"children":2329},{},[2330,2335,2337,2343,2345,2348,2353,2355,2358,2363,2365,2368,2373],{"type":41,"tag":242,"props":2331,"children":2333},{"className":2332},[],[2334],{"type":46,"value":2304},{"type":46,"value":2336}," 是 k8s 的預設 namespace，其中包含 k8s 的 ",{"type":41,"tag":204,"props":2338,"children":2341},{"href":2339,"rel":2340},"https://blog.ewocker.com/blog/k8s-intro/00/#kube-apiserver",[208],[2342],{"type":46,"value":339},{"type":46,"value":2344}," Endpoint。",{"type":41,"tag":731,"props":2346,"children":2347},{},[],{"type":41,"tag":242,"props":2349,"children":2351},{"className":2350},[],[2352],{"type":46,"value":2325},{"type":46,"value":2354}," 是 k8s 運行所有內部運行所需的資源的 namespace，其中包括幾乎所有的主組建 Master Components。",{"type":41,"tag":731,"props":2356,"children":2357},{},[],{"type":41,"tag":242,"props":2359,"children":2361},{"className":2360},[],[2362],{"type":46,"value":2318},{"type":46,"value":2364}," 是 k8s 中無需 authentication 的 namespace，這個 namespace 的存在只是 k8s 中的創建慣例，實際上可有可無。",{"type":41,"tag":731,"props":2366,"children":2367},{},[],{"type":41,"tag":242,"props":2369,"children":2371},{"className":2370},[],[2372],{"type":46,"value":2311},{"type":46,"value":2374}," （可以不需要理解這個 Namespace 的用途）是用於與各個節點相關的租期（Lease）對象； 此對象的設計使得集群規模很大時節點心跳檢測性能得到提升。",{"type":41,"tag":42,"props":2376,"children":2377},{},[2378,2380,2385],{"type":46,"value":2379},"下面用一段 ",{"type":41,"tag":242,"props":2381,"children":2383},{"className":2382},[],[2384],{"type":46,"value":1075},{"type":46,"value":2386}," 來簡單演示一下 Namespace 有關的 operations。",{"type":41,"tag":1040,"props":2388,"children":2389},{},[2390],{"type":41,"tag":42,"props":2391,"children":2392},{},[2393,2395,2400],{"type":46,"value":2394},"💡 如果不理解下面所有的 ",{"type":41,"tag":242,"props":2396,"children":2398},{"className":2397},[],[2399],{"type":46,"value":1071},{"type":46,"value":2401}," 指令也沒關係，後續問文章會慢慢說明。",{"type":41,"tag":125,"props":2403,"children":2404},{},[],{"type":41,"tag":73,"props":2406,"children":2407},{"id":563},[2408],{"type":46,"value":566},{"type":41,"tag":42,"props":2410,"children":2411},{},[2412],{"type":46,"value":2413},"在上面的影片中我們在 Namespace 中快速的創建了幾個以水果和肉類命名的 Pod，那 Pod 是什麼呢？",{"type":41,"tag":42,"props":2415,"children":2416},{},[2417],{"type":41,"tag":270,"props":2418,"children":2419},{"alt":8,"src":576},[],{"type":41,"tag":42,"props":2421,"children":2422},{},[2423,2425,2430],{"type":46,"value":2424},"簡單的說 ",{"type":41,"tag":154,"props":2426,"children":2427},{},[2428],{"type":46,"value":2429},"Pod 是 k8s 中可以部署的最小單位",{"type":46,"value":2431},"。要細說的話 Pod 可可能會講不完，但一般使用 k8s 不需要知道所有的內容，這裡列出幾個簡單且常見的重點：",{"type":41,"tag":1162,"props":2433,"children":2434},{},[2435,2440,2445,2450],{"type":41,"tag":1166,"props":2436,"children":2437},{},[2438],{"type":46,"value":2439},"Pod 是 k8s 中可部署的最小單位",{"type":41,"tag":1166,"props":2441,"children":2442},{},[2443],{"type":46,"value":2444},"Pod 是一或多個 Container 的集合體",{"type":41,"tag":1166,"props":2446,"children":2447},{},[2448],{"type":46,"value":2449},"Pod 中的 Container 共用同一個 Pod IP",{"type":41,"tag":1166,"props":2451,"children":2452},{},[2453],{"type":46,"value":2454},"Pod 中的 Container 可以使用同樣的 Volume",{"type":41,"tag":42,"props":2456,"children":2457},{},[2458],{"type":46,"value":2459},"可能會有人不太理解為何需要運行多的 Container ，常見的使用方式是將 Pod 分為Main Container 和 Sidecar Containers。Main Container 主要包含 Service 的主邏輯，而 Sidecar Container 則是用於輔助 Main Container。雖然被分做 Main 和 Sidecar，但實質上在 Pod 中他們並沒有區別，都是 Container。 常見的 sidecar 有 log watcher，用於將 log 發送至 centralized log service (ElasticSearch 或是 Splunk 等等)。",{"type":41,"tag":42,"props":2461,"children":2462},{},[2463,2465,2470],{"type":46,"value":2464},"上面說到 k8s 中所有 resource 都是用 YAML 來定義的，這裡用最簡單的 Pod Spec內容來介紹如何創建一個 Pod。以下是一些 ",{"type":41,"tag":242,"props":2466,"children":2468},{"className":2467},[],[2469],{"type":46,"value":1071},{"type":46,"value":2471}," 常見的與 Pod 相關的指令。",{"type":41,"tag":1040,"props":2473,"children":2474},{},[2475],{"type":41,"tag":42,"props":2476,"children":2477},{},[2478,2480,2486,2488,2493],{"type":46,"value":2479},"💡 可能會有人好奇如果 Pod 需要用 YAML來定義才能創建，那之前的影片中為什麼沒有使用 YAML 也可以創建。之前用的是 ",{"type":41,"tag":242,"props":2481,"children":2483},{"className":2482},[],[2484],{"type":46,"value":2485},"kubectl run",{"type":46,"value":2487}," 指令，是 ",{"type":41,"tag":242,"props":2489,"children":2491},{"className":2490},[],[2492],{"type":46,"value":1071},{"type":46,"value":2494}," 的快捷指令，其實只是用一個預設的模板快速創建一個簡易的 Pod 而已。",{"type":41,"tag":125,"props":2496,"children":2497},{},[],{"type":41,"tag":73,"props":2499,"children":2500},{"id":1614},[2501],{"type":46,"value":1614},{"type":41,"tag":42,"props":2503,"children":2504},{},[2505,2507,2510],{"type":46,"value":2506},"上面是在創建 k8s 後一些熟悉簡單操作的教程。相較於 k8s 高含量卻複雜的官方文檔，本文盡量摘取我認為一般使用者所需的內容，但可能也因此而省略了一些重要的內容，不過這對於沒影經驗的讀者來說這樣的起步相較起來會更平易近人一些。",{"type":41,"tag":731,"props":2508,"children":2509},{},[],{"type":46,"value":2511},"\n我會在後續的文章中將 k8s 中許多重要的內容慢慢補齊。如果有任何疑問歡迎在facebook 上留言或者私訊我。",{"type":41,"tag":125,"props":2513,"children":2514},{},[],{"title":8,"searchDepth":981,"depth":981,"links":2516},[2517,2518,2519,2520,2521],{"id":1743,"depth":981,"text":1746},{"id":1071,"depth":981,"text":1071},{"id":2236,"depth":981,"text":2239},{"id":563,"depth":981,"text":566},{"id":1614,"depth":981,"text":1614},"content:1.blog:015.k8s-intro:02.md","1.blog/015.k8s-intro/02.md","1.blog/015.k8s-intro/02",{"_path":2526,"_dir":6,"_draft":7,"_partial":7,"_locale":8,"title":2527,"description":2528,"layout":11,"series":12,"image":2529,"keywords":2530,"head":2531,"body":2538,"_type":1017,"_id":3208,"_source":1019,"_file":3209,"_stem":3210,"_extension":1022},"/blog/k8s-intro/03","Kubernetes Workload Basics","本篇文章將會介紹 k8s 中 PodSpec 最常見的幾個與 container 本身有關的設定，特別是 Resources 以及 Probes。",{"src":14,"alt":15,"width":16,"height":17},[19,20,21,22],{"meta":2532},[2533,2534,2535,2537],{"name":26,"content":27},{"name":29,"content":1702},{"property":32,"content":2536},"2021-03-12T00:00:00.000Z",{"property":35,"content":36},{"type":38,"children":2539,"toc":3203},[2540,2554,2573,2578,2609,2622,2633,2678,2743,2757,2949,2952,2958,2963,2977,2982,3029,3048,3053,3089,3094,3119,3122,3127,3144,3167,3176,3181,3184,3188,3200],{"type":41,"tag":42,"props":2541,"children":2542},{},[2543,2545,2552],{"type":46,"value":2544},"本篇文章將會介紹 k8s 中 PodSpec 最常見的幾個與 container 本身有關的設定，特別是 Resources 以及 Probes。。在上一篇中最後提到 ",{"type":41,"tag":204,"props":2546,"children":2549},{"href":2547,"rel":2548},"https://blog.ewocker.com/blog/k8s-intro/02/#pod",[208],[2550],{"type":46,"value":2551},"Pod 的基本信息",{"type":46,"value":2553},"，快速地複習一下幾個重點：",{"type":41,"tag":1162,"props":2555,"children":2556},{},[2557,2561,2565,2569],{"type":41,"tag":1166,"props":2558,"children":2559},{},[2560],{"type":46,"value":2439},{"type":41,"tag":1166,"props":2562,"children":2563},{},[2564],{"type":46,"value":2444},{"type":41,"tag":1166,"props":2566,"children":2567},{},[2568],{"type":46,"value":2449},{"type":41,"tag":1166,"props":2570,"children":2571},{},[2572],{"type":46,"value":2454},{"type":41,"tag":42,"props":2574,"children":2575},{},[2576],{"type":46,"value":2577},"這裡我們來簡單的看看 Pod 的常用設定：",{"type":41,"tag":1040,"props":2579,"children":2580},{},[2581],{"type":41,"tag":42,"props":2582,"children":2583},{},[2584],{"type":41,"tag":154,"props":2585,"children":2586},{},[2587],{"type":41,"tag":165,"props":2588,"children":2589},{},[2590,2592,2598,2600,2607],{"type":46,"value":2591},"這裡只會提到最常見的幾個設定，並以 ",{"type":41,"tag":242,"props":2593,"children":2595},{"className":2594},[],[2596],{"type":46,"value":2597},"k8s@1.17",{"type":46,"value":2599}," 為主，可以參考 ",{"type":41,"tag":204,"props":2601,"children":2604},{"href":2602,"rel":2603},"https://v1-17.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/?ref=blog.ewocker.com#pod-v1-core",[208],[2605],{"type":46,"value":2606},"Pod API Reference",{"type":46,"value":2608}," 來看設定細項。",{"type":41,"tag":2610,"props":2611,"children":2617},"pre",{"className":2612,"code":2614,"filename":2615,"language":2616,"meta":8},[2613],"language-vue","\u003Ctemplate>\n  \u003Cdiv>\n    Some default layout shared across all pages\n    \u003Cslot />\n  \u003C/div>\n\u003C/template>\n","layouts/default.vue","vue",[2618],{"type":41,"tag":242,"props":2619,"children":2620},{"__ignoreMap":8},[2621],{"type":46,"value":2614},{"type":41,"tag":2610,"props":2623,"children":2628},{"className":2624,"code":2626,"language":2627,"meta":8},[2625],"language-yaml","apiVersion: v1\nkind: Pod\nmetadata:\n  labels:\n    app: echoserver\n  name: echoserver\nspec:\n  initContainers:\n    - name: init\n      image: busybox:1.28\n      command:\n        - \"sh\"\n        - \"-c\"\n        - 'echo \"preparing application\"'\n  containers:\n    - name: server\n      image: ewocker/slim-echoserver:1.0.0\n      imagePullPolicy: IfNotPresent\n      resources:\n        limits:\n          cpu: \"100m\"\n          memory: \"50Mi\"\n        requests:\n          cpu: \"100m\"\n          memory: \"50Mi\"\n      ports:\n        - name: service-port\n          containerPort: 8080\n      readinessProbe:\n        httpGet:\n          path: /healthy\n          port: service-port\n        initialDelaySeconds: 5\n        failureThreshold: 2\n        periodSeconds: 10\n      livenessProbe:\n        httpGet:\n          path: /ready\n          port: service-port\n        initialDelaySeconds: 5\n        failureThreshold: 2\n        periodSeconds: 10\n  restartPolicy: Always\n  terminationGracePeriodSeconds: 5\n","yaml",[2629],{"type":41,"tag":242,"props":2630,"children":2631},{"__ignoreMap":8},[2632],{"type":46,"value":2626},{"type":41,"tag":42,"props":2634,"children":2635},{},[2636,2638,2644,2645,2651,2653,2658,2659,2665,2667,2677],{"type":46,"value":2637},"首先是 ",{"type":41,"tag":242,"props":2639,"children":2641},{"className":2640},[],[2642],{"type":46,"value":2643},"containers",{"type":46,"value":1153},{"type":41,"tag":242,"props":2646,"children":2648},{"className":2647},[],[2649],{"type":46,"value":2650},"initContainers",{"type":46,"value":2652},"，一個 Pod 可以包含多個容器，而在 k8s 中還將其分為兩種，分別是 ",{"type":41,"tag":154,"props":2654,"children":2655},{},[2656],{"type":46,"value":2657},"主容器運行前先運行的",{"type":46,"value":856},{"type":41,"tag":242,"props":2660,"children":2662},{"className":2661},[],[2663],{"type":46,"value":2664},"**initContainers**",{"type":46,"value":2666}," 和 包含",{"type":41,"tag":154,"props":2668,"children":2669},{},[2670,2672],{"type":46,"value":2671},"主容器的 ",{"type":41,"tag":242,"props":2673,"children":2675},{"className":2674},[],[2676],{"type":46,"value":2643},{"type":46,"value":336},{"type":41,"tag":1162,"props":2679,"children":2680},{},[2681,2713],{"type":41,"tag":1166,"props":2682,"children":2683},{},[2684,2689,2691,2696,2698,2703,2705,2711],{"type":41,"tag":154,"props":2685,"children":2686},{},[2687],{"type":46,"value":2688},"initContainer",{"type":46,"value":2690}," 顧名思義就是用於 initialization。如果有多個 ",{"type":41,"tag":242,"props":2692,"children":2694},{"className":2693},[],[2695],{"type":46,"value":2650},{"type":46,"value":2697}," 時，會依序逐個運行。常見的 ",{"type":41,"tag":242,"props":2699,"children":2701},{"className":2700},[],[2702],{"type":46,"value":2688},{"type":46,"value":2704}," 有像是用 ",{"type":41,"tag":242,"props":2706,"children":2708},{"className":2707},[],[2709],{"type":46,"value":2710},"nslookup",{"type":46,"value":2712}," 確保 DNS reachability，或是預先將 configuration 處理成所需的格式等等。‌‌（這裡因為演示需要，就隨便 echo 一串字）",{"type":41,"tag":1166,"props":2714,"children":2715},{},[2716,2720,2722,2727,2729,2734,2736,2741],{"type":41,"tag":154,"props":2717,"children":2718},{},[2719],{"type":46,"value":19},{"type":46,"value":2721}," 則是在所有 ",{"type":41,"tag":242,"props":2723,"children":2725},{"className":2724},[],[2726],{"type":46,"value":2688},{"type":46,"value":2728}," 運行結束後才開始的，如果有多個 ",{"type":41,"tag":242,"props":2730,"children":2732},{"className":2731},[],[2733],{"type":46,"value":2643},{"type":46,"value":2735}," 時，所有 ",{"type":41,"tag":242,"props":2737,"children":2739},{"className":2738},[],[2740],{"type":46,"value":2643},{"type":46,"value":2742}," 會同時運行。",{"type":41,"tag":42,"props":2744,"children":2745},{},[2746,2748,2755],{"type":46,"value":2747},"接著來看看 ",{"type":41,"tag":204,"props":2749,"children":2752},{"href":2750,"rel":2751},"https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#container-v1-core",[208],[2753],{"type":46,"value":2754},"ContainerSpec",{"type":46,"value":2756},"，這裡使用的幾個常見的 field 是：",{"type":41,"tag":1162,"props":2758,"children":2759},{},[2760,2770,2780,2824,2834,2904],{"type":41,"tag":1166,"props":2761,"children":2762},{},[2763,2768],{"type":41,"tag":154,"props":2764,"children":2765},{},[2766],{"type":46,"value":2767},"name",{"type":46,"value":2769}," - 容器的名字，主要是使除錯或指檢查日誌時更容易分別 Pod 中的多個容器。",{"type":41,"tag":1166,"props":2771,"children":2772},{},[2773,2778],{"type":41,"tag":154,"props":2774,"children":2775},{},[2776],{"type":46,"value":2777},"image",{"type":46,"value":2779}," - 映像檔，該 container 所使用的映像檔。",{"type":41,"tag":1166,"props":2781,"children":2782},{},[2783,2788,2790,2796,2798,2807,2809,2815,2817,2822],{"type":41,"tag":154,"props":2784,"children":2785},{},[2786],{"type":46,"value":2787},"resources",{"type":46,"value":2789}," -  資源，該容器所需使用的 cpu 和 memory 資源，細分為 request 和 limit：‌‌",{"type":41,"tag":242,"props":2791,"children":2793},{"className":2792},[],[2794],{"type":46,"value":2795},"request",{"type":46,"value":2797}," - 是容器所請求的資源，",{"type":41,"tag":204,"props":2799,"children":2801},{"href":2800},"/blog/k8s-intro/00#kube-scheduler",[2802],{"type":41,"tag":242,"props":2803,"children":2805},{"className":2804},[],[2806],{"type":46,"value":368},{"type":46,"value":2808}," 會在創建 Pod 時會根據所有 container request 的資源來決定該 Pod 將發派到哪一個 Node 上，被發配到的 Node 必須有足夠的資源。‌‌",{"type":41,"tag":242,"props":2810,"children":2812},{"className":2811},[],[2813],{"type":46,"value":2814},"limit",{"type":46,"value":2816}," - 是限制容器不能超過的資源用量，如果 cpu 超過 limit 的話 container 會被 throttle (每當超過時會被壓抑回限制的用量)。如果 memory 超標的話則是會被 OOMKill (Out of Memory Kill，該容器會因為內存不足而被刪掉)，這種狀況下在 k8s 中 container 等於是被重啟了。‌‌resources 的設定非常重要，它會被用於確保 Pod 至少保有屬於自己 request 的資源。Application owner 必須要了解怎麼樣的資源配置對自己的 app 是最有效率的，並且與以後會提到的",{"type":41,"tag":154,"props":2818,"children":2819},{},[2820],{"type":46,"value":2821},"自適應擴縮 autoscaling",{"type":46,"value":2823}," 有關。（下面有更多信息）",{"type":41,"tag":1166,"props":2825,"children":2826},{},[2827,2832],{"type":41,"tag":154,"props":2828,"children":2829},{},[2830],{"type":46,"value":2831},"ports",{"type":46,"value":2833}," - 是 container 的端口，如果加上了 name 來命名的話，則可以在其他設定中直接用名稱來代替端口。",{"type":41,"tag":1166,"props":2835,"children":2836},{},[2837,2842,2844,2853,2855,2860,2862,2870,2872,2878,2880,2886,2888,2893,2895,2902],{"type":41,"tag":154,"props":2838,"children":2839},{},[2840],{"type":46,"value":2841},"livenessProbe",{"type":46,"value":2843}," - ",{"type":41,"tag":204,"props":2845,"children":2847},{"href":2846},"/blog/k8s-intro/00#kubelet",[2848],{"type":41,"tag":242,"props":2849,"children":2851},{"className":2850},[],[2852],{"type":46,"value":472},{"type":46,"value":2854}," 會根據 livenessProbe 的定義來檢查 container 是否健康的在運行，如果 livenessProbe 發生錯誤則 container 會被是於 ",{"type":41,"tag":154,"props":2856,"children":2857},{},[2858],{"type":46,"value":2859},"不健康 (Unhealthy)",{"type":46,"value":2861},"，",{"type":41,"tag":204,"props":2863,"children":2864},{"href":2846},[2865],{"type":41,"tag":242,"props":2866,"children":2868},{"className":2867},[],[2869],{"type":46,"value":472},{"type":46,"value":2871}," 會重啟該 container。‌‌上面是以最常見的 ",{"type":41,"tag":242,"props":2873,"children":2875},{"className":2874},[],[2876],{"type":46,"value":2877},"httpGet",{"type":46,"value":2879}," 為例子，如果 container 沒辦法準時回應 ",{"type":41,"tag":242,"props":2881,"children":2883},{"className":2882},[],[2884],{"type":46,"value":2885},"/healthy",{"type":46,"value":2887}," HTTP GET 的要求或發生錯誤等等，則會被視為 Unhealthy 並且被重啟。（除了 ",{"type":41,"tag":242,"props":2889,"children":2891},{"className":2890},[],[2892],{"type":46,"value":2877},{"type":46,"value":2894}," 以外還有其他方法，請參考 ",{"type":41,"tag":204,"props":2896,"children":2899},{"href":2897,"rel":2898},"https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#probe-v1-core",[208],[2900],{"type":46,"value":2901},"Probe",{"type":46,"value":2903},"）",{"type":41,"tag":1166,"props":2905,"children":2906},{},[2907,2912,2913,2921,2923,2928,2930,2935,2937,2947],{"type":41,"tag":154,"props":2908,"children":2909},{},[2910],{"type":46,"value":2911},"readinessProbe",{"type":46,"value":2843},{"type":41,"tag":204,"props":2914,"children":2915},{"href":2846},[2916],{"type":41,"tag":242,"props":2917,"children":2919},{"className":2918},[],[2920],{"type":46,"value":472},{"type":46,"value":2922}," 會根據 readinessProbe 的定義來檢查 container 是否處於準備好的狀態，當readinessProbe 發生錯誤時 container 並不會像 livenessProbe Failure 一樣被重啟，但 container 會被當作處於 ",{"type":41,"tag":154,"props":2924,"children":2925},{},[2926],{"type":46,"value":2927},"未就緒 (Unready)",{"type":46,"value":2929}," 的狀態，並且如果是 ",{"type":41,"tag":204,"props":2931,"children":2933},{"href":2932},"/blog/k8s-intro/00#service",[2934],{"type":46,"value":609},{"type":46,"value":2936}," 所選擇的 Pod 時則會被剔除於 Service 的 LoadBalancing 選擇中 。（以後說到 Service 時會在多加說明）‌‌舉個常見 readinessProbe 的用法，像是 container 需要構通一個 database，但是 database 卻因為某些原因而無法架設連結，這時候 ",{"type":41,"tag":154,"props":2938,"children":2939},{},[2940,2942],{"type":46,"value":2941},"container 雖然是_健康的狀態 (Healthy)_ 卻也是 ",{"type":41,"tag":165,"props":2943,"children":2944},{},[2945],{"type":46,"value":2946},"未就緒狀態 (Unready)",{"type":46,"value":2948},"。（下面有更多信息）",{"type":41,"tag":125,"props":2950,"children":2951},{},[],{"type":41,"tag":73,"props":2953,"children":2955},{"id":2954},"resources-qos",[2956],{"type":46,"value":2957},"Resources & QoS",{"type":41,"tag":42,"props":2959,"children":2960},{},[2961],{"type":46,"value":2962},"了解自己 container 所需的資源是非常重要的一件事，除了在自適應擴縮（autoscaling）上有極大的影響外， 在 k8s 中還有非常重要的意義，那就是 Pod 的 QoS 屬性。",{"type":41,"tag":1040,"props":2964,"children":2965},{},[2966],{"type":41,"tag":42,"props":2967,"children":2968},{},[2969],{"type":41,"tag":154,"props":2970,"children":2971},{},[2972],{"type":41,"tag":165,"props":2973,"children":2974},{},[2975],{"type":46,"value":2976},"💡 k8s 說到底就是多個 Node (機器/伺服器) 和再一起共同的集合體。在機器的資源不夠用的時候，k8s 會根據 Pod 的重要性來依次將 Pod 剔除 (eviction)，直到系統有足夠的資源使用。‌‌Pod 的重要性首先是看 PriorityClass，接著就是看 QoS。（以後會在提到 PriorityClass）",{"type":41,"tag":42,"props":2978,"children":2979},{},[2980],{"type":46,"value":2981},"首先要在細說下當 container 使用超過 Request 和 Limit 時會發生什麼事：",{"type":41,"tag":1162,"props":2983,"children":2984},{},[2985,2996,3007,3018],{"type":41,"tag":1166,"props":2986,"children":2987},{},[2988,2994],{"type":41,"tag":242,"props":2989,"children":2991},{"className":2990},[],[2992],{"type":46,"value":2993},"CPU exceeds request",{"type":46,"value":2995},"，當 CPU 使用超過要求的資源時，無論是否有設置 CPU limit Pod 可以使用系統中多餘的 CPU。",{"type":41,"tag":1166,"props":2997,"children":2998},{},[2999,3005],{"type":41,"tag":242,"props":3000,"children":3002},{"className":3001},[],[3003],{"type":46,"value":3004},"CPU exceeds limit",{"type":46,"value":3006},"，當 CPU 使用超過限制的資源時， Pod 中的 container 會被壓抑 (throttling)。",{"type":41,"tag":1166,"props":3008,"children":3009},{},[3010,3016],{"type":41,"tag":242,"props":3011,"children":3013},{"className":3012},[],[3014],{"type":46,"value":3015},"Memory exceeds request",{"type":46,"value":3017},"，當 Memory 使用超過要求時，‌‌- 如果 Pod 有設置 Memory limit，Pod 中的 container 可以使用系統中多餘的  Memory。‌‌但如果 Pod 沒有設置 Memory limit，在系統需要內存資源時 Pod 中的 container 可能會被刪除 (OOM Killed，Out of Memory Kill)。",{"type":41,"tag":1166,"props":3019,"children":3020},{},[3021,3027],{"type":41,"tag":242,"props":3022,"children":3024},{"className":3023},[],[3025],{"type":46,"value":3026},"Memory exceeds limit",{"type":46,"value":3028},"，當 Memory 使用超過限制時 Pod 中的 container 會被刪除 (OOM Killed，Out of Memory Kill)。",{"type":41,"tag":1040,"props":3030,"children":3031},{},[3032],{"type":41,"tag":42,"props":3033,"children":3034},{},[3035],{"type":41,"tag":154,"props":3036,"children":3037},{},[3038],{"type":41,"tag":165,"props":3039,"children":3040},{},[3041,3043,3046],{"type":46,"value":3042},"💡 CPU - Compressible （可壓縮）",{"type":41,"tag":731,"props":3044,"children":3045},{},[],{"type":46,"value":3047},"\n💡 Memory - Incompressible （不可壓縮）",{"type":41,"tag":42,"props":3049,"children":3050},{},[3051],{"type":46,"value":3052},"QoS (Quality of Service) 中文直翻服務質量，用於表示 Pod 的可變動性。QoS 有三個值，分別是：",{"type":41,"tag":1162,"props":3054,"children":3055},{},[3056,3067,3078],{"type":41,"tag":1166,"props":3057,"children":3058},{},[3059,3065],{"type":41,"tag":242,"props":3060,"children":3062},{"className":3061},[],[3063],{"type":46,"value":3064},"Guaranteed - High Priority",{"type":46,"value":3066}," (高重要性，不容易被刪除的 Pod)‌‌ 當所有 container 中 resource 的 request 和 limit 相同時，Pod 的 QoS 將會是 Guaranteed。簡單來說就是使用者保證自己的 Pod 不會使用超過 resource 的定義。",{"type":41,"tag":1166,"props":3068,"children":3069},{},[3070,3076],{"type":41,"tag":242,"props":3071,"children":3073},{"className":3072},[],[3074],{"type":46,"value":3075},"Burstable - Medium Priority",{"type":46,"value":3077}," (中等重要性，有可能被刪除的 Pod) ‌‌當條件不符合 Guaranteed 時，並且 Pod 中有任一 container 有設置 resource request 時，Pod 的 QoS 將會是 Burstable。",{"type":41,"tag":1166,"props":3079,"children":3080},{},[3081,3087],{"type":41,"tag":242,"props":3082,"children":3084},{"className":3083},[],[3085],{"type":46,"value":3086},"BestEffort - Low Priority",{"type":46,"value":3088}," (低重要性，容易被刪除的 Pod)‌‌ 當 Pod 中沒有任一 container 有設置 resource request 時，Pod 的 QoS 將會是 Burstable。",{"type":41,"tag":42,"props":3090,"children":3091},{},[3092],{"type":46,"value":3093},"所以 QoS 究竟代表什麼呢？簡單來說如果今天有兩個正在運行的 Pod，分別有 QoS Guaranteed 和 Burstable，在系統資源不夠用時，k8s 會首先剔除 QoS 為 Burstable 的 Pod 來緩解系統的壓力。",{"type":41,"tag":1040,"props":3095,"children":3096},{},[3097,3108],{"type":41,"tag":42,"props":3098,"children":3099},{},[3100],{"type":41,"tag":154,"props":3101,"children":3102},{},[3103],{"type":41,"tag":165,"props":3104,"children":3105},{},[3106],{"type":46,"value":3107},"❗️ 創建新的 Pod 時，當 k8s cluster 中資源不夠用時，即便有較低的 QoS Pod 存在，k8s 也不會因為新要創建的 Pod 有較高的 QoS 而剔除較低 QoS 的 Pod。‌‌這種為了 High Priority 而剔除 Low Priority 的型態叫做 Preemption，是屬於 PriorityClass 相關的內容，和 QoS 並無關連。",{"type":41,"tag":42,"props":3109,"children":3110},{},[3111],{"type":41,"tag":154,"props":3112,"children":3113},{},[3114],{"type":41,"tag":165,"props":3115,"children":3116},{},[3117],{"type":46,"value":3118},"QoS 只有在系統資源不足時必須剔除 Pod 時才會被考慮進去，如果你使用的 cluster 有高手在後面細心關照，並且有設置 kubelet reservation 及 system reservation，則這種事情將會很少發生。",{"type":41,"tag":125,"props":3120,"children":3121},{},[],{"type":41,"tag":73,"props":3123,"children":3125},{"id":3124},"probe",[3126],{"type":46,"value":2901},{"type":41,"tag":42,"props":3128,"children":3129},{},[3130,3132,3136,3138,3142],{"type":46,"value":3131},"因為 ",{"type":41,"tag":154,"props":3133,"children":3134},{},[3135],{"type":46,"value":2841},{"type":46,"value":3137}," 及 ",{"type":41,"tag":154,"props":3139,"children":3140},{},[3141],{"type":46,"value":2911},{"type":46,"value":3143}," 是非常重要的概念，所以這裡細說一下例子中的幾個設定 initialDelaySeconds、periodSeconds、failureThreshold：",{"type":41,"tag":1162,"props":3145,"children":3146},{},[3147,3152,3157,3162],{"type":41,"tag":1166,"props":3148,"children":3149},{},[3150],{"type":46,"value":3151},"initialDelaySeconds 是初始延遲時間，在 container 啟動之後可能需要數秒甚至幾分鐘來維持狀態。一般來說 readinessProbe 的 initialDelaySeconds 會比 livenessProbe 要長一些。（先確保處於健康的可執行狀態，在確定是否就緒）",{"type":41,"tag":1166,"props":3153,"children":3154},{},[3155],{"type":46,"value":3156},"periodSeconds 是每次確認的間隔秒數",{"type":41,"tag":1166,"props":3158,"children":3159},{},[3160],{"type":46,"value":3161},"failureThreshold 是指失敗多少次才將其歸類於不健康或未就緒狀態。相反的，也有 successThreshold 的設定。",{"type":41,"tag":1166,"props":3163,"children":3164},{},[3165],{"type":46,"value":3166},"其他設定還有 timeoutSeconds，這裡因為非常顧名思義所以就不多做說明。",{"type":41,"tag":2610,"props":3168,"children":3171},{"className":3169,"code":3170,"language":2627,"meta":8},[2625],"initialDelaySeconds: 5\nperiodSeconds: 10\nfailureThreshold: 2\n",[3172],{"type":41,"tag":242,"props":3173,"children":3174},{"__ignoreMap":8},[3175],{"type":46,"value":3170},{"type":41,"tag":42,"props":3177,"children":3178},{},[3179],{"type":46,"value":3180},"以上面的設定來說就是，container 創建好 5 秒後開始 liveness/readiness Probe，每 10 秒一次，不能連續失敗兩次。",{"type":41,"tag":125,"props":3182,"children":3183},{},[],{"type":41,"tag":73,"props":3185,"children":3186},{"id":1614},[3187],{"type":46,"value":1614},{"type":41,"tag":42,"props":3189,"children":3190},{},[3191,3193,3198],{"type":46,"value":3192},"除了上面的設定以外，Pod 還有許多其他的設定，這裡只介紹了幾個創建 Pod 時必須要知道的設定，特別是 livenessProbe/readinessProbe 以及 resource。‌‌一般來說使用者不會自己創建 Pod，而是會在其它 ",{"type":41,"tag":242,"props":3194,"children":3196},{"className":3195},[],[3197],{"type":46,"value":20},{"type":46,"value":3199}," 工作附載資源 (Workload Resource) 中透過定義 PodTemplate 來創建 Pod。接下來幾個章節會慢慢介紹幾個常見的 Workloads。",{"type":41,"tag":125,"props":3201,"children":3202},{},[],{"title":8,"searchDepth":981,"depth":981,"links":3204},[3205,3206,3207],{"id":2954,"depth":981,"text":2957},{"id":3124,"depth":981,"text":2901},{"id":1614,"depth":981,"text":1614},"content:1.blog:015.k8s-intro:03.md","1.blog/015.k8s-intro/03.md","1.blog/015.k8s-intro/03",1775365448599]