日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【体系】Kubernetes容器管理

發布時間:2024/3/26 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【体系】Kubernetes容器管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 1. 基本概念
  • 2. 搭建集群
  • 3. 核心技術(上)
  • 4. 核心技術(下)
  • 5. 日志管理
  • 6. 監控平臺
  • 7. 搭建高可用集群
  • 8. 集群項目部署實操

1. 基本概念

概述與特性:k8s是谷歌在2014年開源的容器化集群管理系統,主要用于容器應用部署,具有易于應用擴展的特點,讓容器化應用部署更加簡潔高效。傳統的應用部署方式是通過插件或腳本來安裝應用。這樣做的缺點是應用的運行、配 置、管理、所有生存周期將與當前操作系統綁定,這樣做并不利于應用的升級更新/回滾等 操作,當然也可以通過創建虛擬機的方式來實現某些功能,但是虛擬機非常重,并不利于可移植性;新的方式是通過部署容器方式實現,每個容器之間互相隔離,每個容器有自己的文件 系統 ,容器之間進程不會相互影響,能區分計算資源。相對于虛擬機,容器能快速部署, 由于容器與底層設施、機器文件系統解耦的,所以它能在不同云、不同版本操作系統間進行遷移。

架構組件:k8s具有自動裝箱、自我修復(自愈能力)、水平擴展、服務發現、滾動更新、版本回退、密鑰和配置管理、存儲編排和批處理等功能特點

  • Master Node:k8s 集群控制節點,對集群進行調度管理,接受集群外用戶去集群操作請求; Master Node 由 API Server、Scheduler、ClusterState Store(ETCD 數據庫)和 Controller MangerServer 所組成
    • apiserver:集群統一入口,以restfull方式,交給etcd存儲
    • scheduler:節點調度,選擇node節點應用部署
    • controller-manager:處理集群中常規后臺任務,一個資源對應一個控制器
    • etcd:存儲系統,保存集群相關的數據
  • Worker Node:集群工作節點,運行用戶業務應用容器,包含 kubelet、kube proxy 和 ContainerRuntime
    • kubelet:master排到node節點代表,管理本機容器
    • kube-proxy:提供網絡代理,負載均衡等操作

核心概念:pod、controller、service

  • pod:最小部署單元;一組容器的集合;共享網絡;生命周期是短暫的
  • controller:確保預期的pod副本數量;無狀態應用部署;有狀態應用部署;確保所有的node運行同一個pod;一次性任務和定時任務
  • service:定義一組pod訪問規則

2. 搭建集群

k8s硬件要求:測試環境中master(2核 4G內存 20G硬盤)和node(4核 8G內存 40G硬盤);生產環境中master和node均有更高要求
搭建集群方式:kubeadm方式(Kubeadm 是一個 K8s 部署工具,提供 kubeadm init 和 kubeadm join,用于快速部 署 Kubernetes 集群。官方地址,見鏈接)和二進制包方式(從 github 下載發行版的二進制包,手動部署每個組件,組成 Kubernetes 集群)
k8s平臺規劃:環境平臺規劃分為單master集群和多master集群(常用,避免單master故障導致系統崩潰)

#mermaid-svg-Wu83BuDU1V5YH4ki .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .label text{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .node rect,#mermaid-svg-Wu83BuDU1V5YH4ki .node circle,#mermaid-svg-Wu83BuDU1V5YH4ki .node ellipse,#mermaid-svg-Wu83BuDU1V5YH4ki .node polygon,#mermaid-svg-Wu83BuDU1V5YH4ki .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-Wu83BuDU1V5YH4ki .node .label{text-align:center;fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .node.clickable{cursor:pointer}#mermaid-svg-Wu83BuDU1V5YH4ki .arrowheadPath{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-Wu83BuDU1V5YH4ki .flowchart-link{stroke:#333;fill:none}#mermaid-svg-Wu83BuDU1V5YH4ki .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-Wu83BuDU1V5YH4ki .edgeLabel rect{opacity:0.9}#mermaid-svg-Wu83BuDU1V5YH4ki .edgeLabel span{color:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-Wu83BuDU1V5YH4ki .cluster text{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-Wu83BuDU1V5YH4ki .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-Wu83BuDU1V5YH4ki text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-Wu83BuDU1V5YH4ki .actor-line{stroke:grey}#mermaid-svg-Wu83BuDU1V5YH4ki .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-Wu83BuDU1V5YH4ki #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .sequenceNumber{fill:#fff}#mermaid-svg-Wu83BuDU1V5YH4ki #sequencenumber{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki #crosshead path{fill:#333;stroke:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .messageText{fill:#333;stroke:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-Wu83BuDU1V5YH4ki .labelText,#mermaid-svg-Wu83BuDU1V5YH4ki .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-Wu83BuDU1V5YH4ki .loopText,#mermaid-svg-Wu83BuDU1V5YH4ki .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-Wu83BuDU1V5YH4ki .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-Wu83BuDU1V5YH4ki .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-Wu83BuDU1V5YH4ki .noteText,#mermaid-svg-Wu83BuDU1V5YH4ki .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-Wu83BuDU1V5YH4ki .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-Wu83BuDU1V5YH4ki .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-Wu83BuDU1V5YH4ki .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-Wu83BuDU1V5YH4ki .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki .section{stroke:none;opacity:0.2}#mermaid-svg-Wu83BuDU1V5YH4ki .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-Wu83BuDU1V5YH4ki .section2{fill:#fff400}#mermaid-svg-Wu83BuDU1V5YH4ki .section1,#mermaid-svg-Wu83BuDU1V5YH4ki .section3{fill:#fff;opacity:0.2}#mermaid-svg-Wu83BuDU1V5YH4ki .sectionTitle0{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .sectionTitle1{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .sectionTitle2{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .sectionTitle3{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-Wu83BuDU1V5YH4ki .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki .grid path{stroke-width:0}#mermaid-svg-Wu83BuDU1V5YH4ki .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-Wu83BuDU1V5YH4ki .task{stroke-width:2}#mermaid-svg-Wu83BuDU1V5YH4ki .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki .taskText:not([font-size]){font-size:11px}#mermaid-svg-Wu83BuDU1V5YH4ki .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-Wu83BuDU1V5YH4ki .task.clickable{cursor:pointer}#mermaid-svg-Wu83BuDU1V5YH4ki .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Wu83BuDU1V5YH4ki .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Wu83BuDU1V5YH4ki .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Wu83BuDU1V5YH4ki .taskText0,#mermaid-svg-Wu83BuDU1V5YH4ki .taskText1,#mermaid-svg-Wu83BuDU1V5YH4ki .taskText2,#mermaid-svg-Wu83BuDU1V5YH4ki .taskText3{fill:#fff}#mermaid-svg-Wu83BuDU1V5YH4ki .task0,#mermaid-svg-Wu83BuDU1V5YH4ki .task1,#mermaid-svg-Wu83BuDU1V5YH4ki .task2,#mermaid-svg-Wu83BuDU1V5YH4ki .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-Wu83BuDU1V5YH4ki .taskTextOutside0,#mermaid-svg-Wu83BuDU1V5YH4ki .taskTextOutside2{fill:#000}#mermaid-svg-Wu83BuDU1V5YH4ki .taskTextOutside1,#mermaid-svg-Wu83BuDU1V5YH4ki .taskTextOutside3{fill:#000}#mermaid-svg-Wu83BuDU1V5YH4ki .active0,#mermaid-svg-Wu83BuDU1V5YH4ki .active1,#mermaid-svg-Wu83BuDU1V5YH4ki .active2,#mermaid-svg-Wu83BuDU1V5YH4ki .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-Wu83BuDU1V5YH4ki .activeText0,#mermaid-svg-Wu83BuDU1V5YH4ki .activeText1,#mermaid-svg-Wu83BuDU1V5YH4ki .activeText2,#mermaid-svg-Wu83BuDU1V5YH4ki .activeText3{fill:#000 !important}#mermaid-svg-Wu83BuDU1V5YH4ki .done0,#mermaid-svg-Wu83BuDU1V5YH4ki .done1,#mermaid-svg-Wu83BuDU1V5YH4ki .done2,#mermaid-svg-Wu83BuDU1V5YH4ki .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-Wu83BuDU1V5YH4ki .doneText0,#mermaid-svg-Wu83BuDU1V5YH4ki .doneText1,#mermaid-svg-Wu83BuDU1V5YH4ki .doneText2,#mermaid-svg-Wu83BuDU1V5YH4ki .doneText3{fill:#000 !important}#mermaid-svg-Wu83BuDU1V5YH4ki .crit0,#mermaid-svg-Wu83BuDU1V5YH4ki .crit1,#mermaid-svg-Wu83BuDU1V5YH4ki .crit2,#mermaid-svg-Wu83BuDU1V5YH4ki .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-Wu83BuDU1V5YH4ki .activeCrit0,#mermaid-svg-Wu83BuDU1V5YH4ki .activeCrit1,#mermaid-svg-Wu83BuDU1V5YH4ki .activeCrit2,#mermaid-svg-Wu83BuDU1V5YH4ki .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-Wu83BuDU1V5YH4ki .doneCrit0,#mermaid-svg-Wu83BuDU1V5YH4ki .doneCrit1,#mermaid-svg-Wu83BuDU1V5YH4ki .doneCrit2,#mermaid-svg-Wu83BuDU1V5YH4ki .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-Wu83BuDU1V5YH4ki .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-Wu83BuDU1V5YH4ki .milestoneText{font-style:italic}#mermaid-svg-Wu83BuDU1V5YH4ki .doneCritText0,#mermaid-svg-Wu83BuDU1V5YH4ki .doneCritText1,#mermaid-svg-Wu83BuDU1V5YH4ki .doneCritText2,#mermaid-svg-Wu83BuDU1V5YH4ki .doneCritText3{fill:#000 !important}#mermaid-svg-Wu83BuDU1V5YH4ki .activeCritText0,#mermaid-svg-Wu83BuDU1V5YH4ki .activeCritText1,#mermaid-svg-Wu83BuDU1V5YH4ki .activeCritText2,#mermaid-svg-Wu83BuDU1V5YH4ki .activeCritText3{fill:#000 !important}#mermaid-svg-Wu83BuDU1V5YH4ki .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-Wu83BuDU1V5YH4ki g.classGroup text .title{font-weight:bolder}#mermaid-svg-Wu83BuDU1V5YH4ki g.clickable{cursor:pointer}#mermaid-svg-Wu83BuDU1V5YH4ki g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-Wu83BuDU1V5YH4ki g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-Wu83BuDU1V5YH4ki .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-Wu83BuDU1V5YH4ki .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-Wu83BuDU1V5YH4ki .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-Wu83BuDU1V5YH4ki .dashed-line{stroke-dasharray:3}#mermaid-svg-Wu83BuDU1V5YH4ki #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Wu83BuDU1V5YH4ki #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Wu83BuDU1V5YH4ki #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-Wu83BuDU1V5YH4ki #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-Wu83BuDU1V5YH4ki #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Wu83BuDU1V5YH4ki #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Wu83BuDU1V5YH4ki #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Wu83BuDU1V5YH4ki #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Wu83BuDU1V5YH4ki .commit-id,#mermaid-svg-Wu83BuDU1V5YH4ki .commit-msg,#mermaid-svg-Wu83BuDU1V5YH4ki .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-Wu83BuDU1V5YH4ki g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-Wu83BuDU1V5YH4ki g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-Wu83BuDU1V5YH4ki g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-Wu83BuDU1V5YH4ki .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-Wu83BuDU1V5YH4ki .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-Wu83BuDU1V5YH4ki .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-Wu83BuDU1V5YH4ki .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-Wu83BuDU1V5YH4ki .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-Wu83BuDU1V5YH4ki .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-Wu83BuDU1V5YH4ki .edgeLabel text{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Wu83BuDU1V5YH4ki .node circle.state-start{fill:black;stroke:black}#mermaid-svg-Wu83BuDU1V5YH4ki .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-Wu83BuDU1V5YH4ki #statediagram-barbEnd{fill:#9370db}#mermaid-svg-Wu83BuDU1V5YH4ki .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-Wu83BuDU1V5YH4ki .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-Wu83BuDU1V5YH4ki .statediagram-state .divider{stroke:#9370db}#mermaid-svg-Wu83BuDU1V5YH4ki .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-Wu83BuDU1V5YH4ki .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-Wu83BuDU1V5YH4ki .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-Wu83BuDU1V5YH4ki .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-Wu83BuDU1V5YH4ki .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-Wu83BuDU1V5YH4ki .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-Wu83BuDU1V5YH4ki .note-edge{stroke-dasharray:5}#mermaid-svg-Wu83BuDU1V5YH4ki .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-Wu83BuDU1V5YH4ki .error-icon{fill:#522}#mermaid-svg-Wu83BuDU1V5YH4ki .error-text{fill:#522;stroke:#522}#mermaid-svg-Wu83BuDU1V5YH4ki .edge-thickness-normal{stroke-width:2px}#mermaid-svg-Wu83BuDU1V5YH4ki .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-Wu83BuDU1V5YH4ki .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-Wu83BuDU1V5YH4ki .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-Wu83BuDU1V5YH4ki .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-Wu83BuDU1V5YH4ki .marker{fill:#333}#mermaid-svg-Wu83BuDU1V5YH4ki .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-Wu83BuDU1V5YH4ki {color: rgba(0, 0, 0, 0.75);font: ;}masternode1node2node3 #mermaid-svg-WTCevQQ7IE2JpDnM .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .label text{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .node rect,#mermaid-svg-WTCevQQ7IE2JpDnM .node circle,#mermaid-svg-WTCevQQ7IE2JpDnM .node ellipse,#mermaid-svg-WTCevQQ7IE2JpDnM .node polygon,#mermaid-svg-WTCevQQ7IE2JpDnM .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-WTCevQQ7IE2JpDnM .node .label{text-align:center;fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .node.clickable{cursor:pointer}#mermaid-svg-WTCevQQ7IE2JpDnM .arrowheadPath{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-WTCevQQ7IE2JpDnM .flowchart-link{stroke:#333;fill:none}#mermaid-svg-WTCevQQ7IE2JpDnM .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-WTCevQQ7IE2JpDnM .edgeLabel rect{opacity:0.9}#mermaid-svg-WTCevQQ7IE2JpDnM .edgeLabel span{color:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-WTCevQQ7IE2JpDnM .cluster text{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-WTCevQQ7IE2JpDnM .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-WTCevQQ7IE2JpDnM text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-WTCevQQ7IE2JpDnM .actor-line{stroke:grey}#mermaid-svg-WTCevQQ7IE2JpDnM .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-WTCevQQ7IE2JpDnM #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .sequenceNumber{fill:#fff}#mermaid-svg-WTCevQQ7IE2JpDnM #sequencenumber{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM #crosshead path{fill:#333;stroke:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .messageText{fill:#333;stroke:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-WTCevQQ7IE2JpDnM .labelText,#mermaid-svg-WTCevQQ7IE2JpDnM .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-WTCevQQ7IE2JpDnM .loopText,#mermaid-svg-WTCevQQ7IE2JpDnM .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-WTCevQQ7IE2JpDnM .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-WTCevQQ7IE2JpDnM .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-WTCevQQ7IE2JpDnM .noteText,#mermaid-svg-WTCevQQ7IE2JpDnM .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-WTCevQQ7IE2JpDnM .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-WTCevQQ7IE2JpDnM .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-WTCevQQ7IE2JpDnM .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-WTCevQQ7IE2JpDnM .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM .section{stroke:none;opacity:0.2}#mermaid-svg-WTCevQQ7IE2JpDnM .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-WTCevQQ7IE2JpDnM .section2{fill:#fff400}#mermaid-svg-WTCevQQ7IE2JpDnM .section1,#mermaid-svg-WTCevQQ7IE2JpDnM .section3{fill:#fff;opacity:0.2}#mermaid-svg-WTCevQQ7IE2JpDnM .sectionTitle0{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .sectionTitle1{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .sectionTitle2{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .sectionTitle3{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-WTCevQQ7IE2JpDnM .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM .grid path{stroke-width:0}#mermaid-svg-WTCevQQ7IE2JpDnM .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-WTCevQQ7IE2JpDnM .task{stroke-width:2}#mermaid-svg-WTCevQQ7IE2JpDnM .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM .taskText:not([font-size]){font-size:11px}#mermaid-svg-WTCevQQ7IE2JpDnM .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-WTCevQQ7IE2JpDnM .task.clickable{cursor:pointer}#mermaid-svg-WTCevQQ7IE2JpDnM .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WTCevQQ7IE2JpDnM .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WTCevQQ7IE2JpDnM .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-WTCevQQ7IE2JpDnM .taskText0,#mermaid-svg-WTCevQQ7IE2JpDnM .taskText1,#mermaid-svg-WTCevQQ7IE2JpDnM .taskText2,#mermaid-svg-WTCevQQ7IE2JpDnM .taskText3{fill:#fff}#mermaid-svg-WTCevQQ7IE2JpDnM .task0,#mermaid-svg-WTCevQQ7IE2JpDnM .task1,#mermaid-svg-WTCevQQ7IE2JpDnM .task2,#mermaid-svg-WTCevQQ7IE2JpDnM .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-WTCevQQ7IE2JpDnM .taskTextOutside0,#mermaid-svg-WTCevQQ7IE2JpDnM .taskTextOutside2{fill:#000}#mermaid-svg-WTCevQQ7IE2JpDnM .taskTextOutside1,#mermaid-svg-WTCevQQ7IE2JpDnM .taskTextOutside3{fill:#000}#mermaid-svg-WTCevQQ7IE2JpDnM .active0,#mermaid-svg-WTCevQQ7IE2JpDnM .active1,#mermaid-svg-WTCevQQ7IE2JpDnM .active2,#mermaid-svg-WTCevQQ7IE2JpDnM .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-WTCevQQ7IE2JpDnM .activeText0,#mermaid-svg-WTCevQQ7IE2JpDnM .activeText1,#mermaid-svg-WTCevQQ7IE2JpDnM .activeText2,#mermaid-svg-WTCevQQ7IE2JpDnM .activeText3{fill:#000 !important}#mermaid-svg-WTCevQQ7IE2JpDnM .done0,#mermaid-svg-WTCevQQ7IE2JpDnM .done1,#mermaid-svg-WTCevQQ7IE2JpDnM .done2,#mermaid-svg-WTCevQQ7IE2JpDnM .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-WTCevQQ7IE2JpDnM .doneText0,#mermaid-svg-WTCevQQ7IE2JpDnM .doneText1,#mermaid-svg-WTCevQQ7IE2JpDnM .doneText2,#mermaid-svg-WTCevQQ7IE2JpDnM .doneText3{fill:#000 !important}#mermaid-svg-WTCevQQ7IE2JpDnM .crit0,#mermaid-svg-WTCevQQ7IE2JpDnM .crit1,#mermaid-svg-WTCevQQ7IE2JpDnM .crit2,#mermaid-svg-WTCevQQ7IE2JpDnM .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-WTCevQQ7IE2JpDnM .activeCrit0,#mermaid-svg-WTCevQQ7IE2JpDnM .activeCrit1,#mermaid-svg-WTCevQQ7IE2JpDnM .activeCrit2,#mermaid-svg-WTCevQQ7IE2JpDnM .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-WTCevQQ7IE2JpDnM .doneCrit0,#mermaid-svg-WTCevQQ7IE2JpDnM .doneCrit1,#mermaid-svg-WTCevQQ7IE2JpDnM .doneCrit2,#mermaid-svg-WTCevQQ7IE2JpDnM .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-WTCevQQ7IE2JpDnM .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-WTCevQQ7IE2JpDnM .milestoneText{font-style:italic}#mermaid-svg-WTCevQQ7IE2JpDnM .doneCritText0,#mermaid-svg-WTCevQQ7IE2JpDnM .doneCritText1,#mermaid-svg-WTCevQQ7IE2JpDnM .doneCritText2,#mermaid-svg-WTCevQQ7IE2JpDnM .doneCritText3{fill:#000 !important}#mermaid-svg-WTCevQQ7IE2JpDnM .activeCritText0,#mermaid-svg-WTCevQQ7IE2JpDnM .activeCritText1,#mermaid-svg-WTCevQQ7IE2JpDnM .activeCritText2,#mermaid-svg-WTCevQQ7IE2JpDnM .activeCritText3{fill:#000 !important}#mermaid-svg-WTCevQQ7IE2JpDnM .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-WTCevQQ7IE2JpDnM g.classGroup text .title{font-weight:bolder}#mermaid-svg-WTCevQQ7IE2JpDnM g.clickable{cursor:pointer}#mermaid-svg-WTCevQQ7IE2JpDnM g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-WTCevQQ7IE2JpDnM g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-WTCevQQ7IE2JpDnM .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-WTCevQQ7IE2JpDnM .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-WTCevQQ7IE2JpDnM .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-WTCevQQ7IE2JpDnM .dashed-line{stroke-dasharray:3}#mermaid-svg-WTCevQQ7IE2JpDnM #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WTCevQQ7IE2JpDnM #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WTCevQQ7IE2JpDnM #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-WTCevQQ7IE2JpDnM #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-WTCevQQ7IE2JpDnM #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WTCevQQ7IE2JpDnM #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WTCevQQ7IE2JpDnM #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WTCevQQ7IE2JpDnM #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-WTCevQQ7IE2JpDnM .commit-id,#mermaid-svg-WTCevQQ7IE2JpDnM .commit-msg,#mermaid-svg-WTCevQQ7IE2JpDnM .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-WTCevQQ7IE2JpDnM g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-WTCevQQ7IE2JpDnM g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-WTCevQQ7IE2JpDnM g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-WTCevQQ7IE2JpDnM .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-WTCevQQ7IE2JpDnM .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-WTCevQQ7IE2JpDnM .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-WTCevQQ7IE2JpDnM .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-WTCevQQ7IE2JpDnM .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-WTCevQQ7IE2JpDnM .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-WTCevQQ7IE2JpDnM .edgeLabel text{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-WTCevQQ7IE2JpDnM .node circle.state-start{fill:black;stroke:black}#mermaid-svg-WTCevQQ7IE2JpDnM .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-WTCevQQ7IE2JpDnM #statediagram-barbEnd{fill:#9370db}#mermaid-svg-WTCevQQ7IE2JpDnM .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-WTCevQQ7IE2JpDnM .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-WTCevQQ7IE2JpDnM .statediagram-state .divider{stroke:#9370db}#mermaid-svg-WTCevQQ7IE2JpDnM .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-WTCevQQ7IE2JpDnM .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-WTCevQQ7IE2JpDnM .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-WTCevQQ7IE2JpDnM .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-WTCevQQ7IE2JpDnM .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-WTCevQQ7IE2JpDnM .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-WTCevQQ7IE2JpDnM .note-edge{stroke-dasharray:5}#mermaid-svg-WTCevQQ7IE2JpDnM .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-WTCevQQ7IE2JpDnM .error-icon{fill:#522}#mermaid-svg-WTCevQQ7IE2JpDnM .error-text{fill:#522;stroke:#522}#mermaid-svg-WTCevQQ7IE2JpDnM .edge-thickness-normal{stroke-width:2px}#mermaid-svg-WTCevQQ7IE2JpDnM .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-WTCevQQ7IE2JpDnM .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-WTCevQQ7IE2JpDnM .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-WTCevQQ7IE2JpDnM .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-WTCevQQ7IE2JpDnM .marker{fill:#333}#mermaid-svg-WTCevQQ7IE2JpDnM .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-WTCevQQ7IE2JpDnM {color: rgba(0, 0, 0, 0.75);font: ;}master1負載均衡master2master3node1node2node3

平臺搭建1:單master集群的kubeadm方式安裝

  • 準備虛擬主機(記得做好快照,以便環境快速恢復)。網絡要求:集群機器之間能夠互通,且能夠上外網(操作系統此例為CentOS7)
  • 三個虛擬機的初始化(記得做好快照,以便環境快速恢復)# 1.三臺虛擬機均關閉防火墻: systemctl stop firewalld #臨時 systemctl disable firewalld #永久# 2.三臺虛擬機均關閉selinux setenforce 0 #臨時 sed -i 's/enforcing/disabled/' /etc/selinux/config #永久# 3.三臺虛擬機均關閉swap分區 swapoff -a #臨時 sed -ri 's/.*swap.*/#&/' /etc/fstab #永久# 4.三臺虛擬機分別設置主機名 hostnamectl set-hostname k8s-master# 5.在master添加 hosts [root@k8s-master ~]# cat >> /etc/hosts << EOF > 172.16.90.146 k8s-master > 172.16.90.145 k8s-node1 > 172.16.90.144 k8s-node2 > EOF# 6. 將三臺虛擬機橋接的IPv4流量傳遞到iptables的鏈,并使之生效 [root@k8s-master ~]# cat > /etc/sysctl.d/k8s.conf << EOF > net.bridge.bridge-nf-call-ip6tables = 1 > net.bridge.bridge-nf-call-iptables = 1 > EOF [root@k8s-master ~]# sysctl --system# 7. 三臺虛擬機均設置時間同步 yum install ntpdate -y ntpdate time.windows.com
  • 所有節點安裝 Docker/kubeadm/kubelet# 安裝wget [root@k8s-master ~]# yum install wget# 下載docker源文件 [root@k8s-master ~]# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo# 安裝docker [root@k8s-master ~]# yum -y install docker-ce-18.06.1.ce-3.el7# 啟動docker [root@k8s-master ~]# systemctl enable docker && systemctl start docker# 檢查是否安裝成功 [root@k8s-master ~]# docker --version# 添加阿里云YUM軟件源 # 設置倉庫地址 [root@k8s-master ~]# cat > /etc/docker/daemon.json << EOF > { > "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"] > } > EOF# 添加yum源 [root@k8s-master ~]# cat > /etc/yum.repos.d/kubernetes.repo << EOF > [kubernetes] > name=Kubernetes > baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 > enabled=1 > gpgcheck=0 > repo_gpgcheck=0 > gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg > https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg > EOF# 安裝 kubeadm,kubelet 和 kubectl [root@k8s-master ~]# yum install -y kubelet kubeadm kubectl# 設置開機啟動 [root@k8s-master ~]# systemctl enable kubelet
  • 在master節點執行kubeadm init命令進行初始化# 在master節點機部署Kubernetes Master,并執行一下目錄 # 由于默認拉取鏡像地址 k8s.gcr.io 國內無法訪問,這里指定阿里云鏡像倉庫地址。 [root@k8s-master ~]# kubeadm init --apiserver-advertise-address=172.16.90.146 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.21.0 --service-cidr=10.96.0.0/12 --pod-network-cidr=10.244.0.0/16 ... error execution phase preflight: [preflight] Some fatal errors occurred:[ERROR ImagePull]: failed to pull image registry.aliyuncs.com/google_containers/coredns:v1.8.0: output: Error response from daemon: manifest for registry.aliyuncs.com/google_containers/coredns:v1.8.0 not found , error: exit status 1 ...# 檢查發現缺少鏡像coredns [root@k8s-master ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry.aliyuncs.com/google_containers/kube-apiserver v1.21.0 4d217480042e 3 months ago 126MB registry.aliyuncs.com/google_containers/kube-proxy v1.21.0 38ddd85fe90e 3 months ago 122MB registry.aliyuncs.com/google_containers/kube-controller-manager v1.21.0 09708983cc37 3 months ago 120MB registry.aliyuncs.com/google_containers/kube-scheduler v1.21.0 62ad3129eca8 3 months ago 50.6MB registry.aliyuncs.com/google_containers/pause 3.4.1 0f8457a4c2ec 6 months ago 683kB registry.aliyuncs.com/google_containers/etcd 3.4.13-0 0369cf4303ff 11 months ago 253MB# 解決該問題:Kubernetes 需要的是 registry.aliyuncs.com/google_containers/coredns:v1.8.0 這個鏡像,使用 docker tag 命令重命名 # 拉取鏡像 [root@k8s-master ~]# docker pull registry.aliyuncs.com/google_containers/coredns:1.8.0 # 重命名 [root@k8s-master ~]# docker tag registry.aliyuncs.com/google_containers/coredns:1.8.0 registry.aliyuncs.com/google_containers/coredns:v1.8.0 # 刪除原有鏡像 [root@k8s-master ~]# docker rmi registry.aliyuncs.com/google_containers/coredns:1.8.0# 檢查 [root@k8s-master ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry.aliyuncs.com/google_containers/kube-apiserver v1.21.0 4d217480042e 3 months ago 126MB registry.aliyuncs.com/google_containers/kube-proxy v1.21.0 38ddd85fe90e 3 months ago 122MB registry.aliyuncs.com/google_containers/kube-controller-manager v1.21.0 09708983cc37 3 months ago 120MB registry.aliyuncs.com/google_containers/kube-scheduler v1.21.0 62ad3129eca8 3 months ago 50.6MB registry.aliyuncs.com/google_containers/pause 3.4.1 0f8457a4c2ec 6 months ago 683kB registry.aliyuncs.com/google_containers/coredns v1.8.0 296a6d5035e2 9 months ago 42.5MB registry.aliyuncs.com/google_containers/etcd 3.4.13-0 0369cf4303ff 11 months ago 253MB# 再次執行kubeadm init ... Your Kubernetes control-plane has initialized successfully!To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config ... kubeadm join 172.16.90.146:6443 --token y761gh.vxrkrulwu0tt74sw \--discovery-token-ca-cert-hash sha256:b611e2e88052ec60ac4716b0a9a48a9fa45d99a4b457563593dc29805214bbc5 # 使用 kubectl 工具: [root@k8s-master ~]# mkdir -p $HOME/.kube [root@k8s-master ~]# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config [root@k8s-master ~]# chown $(id -u):$(id -g) $HOME/.kube/config [root@k8s-master ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master NotReady control-plane,master 3m25s v1.21.3
  • 在node節點上執行kubeadm join命令把node節點添加到當前集群里面[root@k8s-node1 ~]# kubeadm join 172.16.90.146:6443 --token y761gh.vxrkrulwu0tt74sw --discovery-token-ca-cert-hash sha256:b611e2e88052ec60ac4716b0a9a48a9fa45d99a4b457563593dc29805214bbc5 [root@k8s-node2 ~]# kubeadm join 172.16.90.146:6443 --token y761gh.vxrkrulwu0tt74sw --discovery-token-ca-cert-hash sha256:b611e2e88052ec60ac4716b0a9a48a9fa45d99a4b457563593dc29805214bbc5# 檢查是否添加成功 [root@k8s-master ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master NotReady control-plane,master 11m v1.21.3 k8s-node1 NotReady <none> 2m6s v1.21.3 k8s-node2 NotReady <none> 60s v1.21.3
  • 配置網絡插件[root@k8s-master ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml# 查看是否有運行 [root@k8s-master ~]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE coredns-59d64cd4d4-dqx8m 1/1 Running 0 31m coredns-59d64cd4d4-z8pdq 1/1 Running 0 31m etcd-k8s-master 1/1 Running 0 31m kube-apiserver-k8s-master 1/1 Running 0 31m kube-controller-manager-k8s-master 1/1 Running 0 31m kube-flannel-ds-h7v2g 1/1 Running 0 2m46s kube-flannel-ds-xmzfh 1/1 Running 0 2m46s kube-flannel-ds-z9nbj 1/1 Running 0 2m46s kube-proxy-6c9cd 1/1 Running 0 20m kube-proxy-cnvfg 1/1 Running 0 31m kube-proxy-p4nx4 1/1 Running 0 22m kube-scheduler-k8s-master 1/1 Running 0 31m# 驗證是否啟動 [root@k8s-master ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane,master 32m v1.21.3 k8s-node1 Ready <none> 23m v1.21.3 k8s-node2 Ready <none> 22m v1.21.3
  • 測試 kubernetes 集群# 在 Kubernetes 集群中創建一個 pod,驗證是否正常運行 # 聯網下載nginx鏡像 [root@k8s-master ~]# kubectl create deployment nginx --image=nginx deployment.apps/nginx created # 查看pod狀態 [root@k8s-master ~]# kubectl get pod NAME READY STATUS RESTARTS AGE nginx-6799fc88d8-lj24f 1/1 Running 0 62s # 對外暴露80端口 [root@k8s-master ~]# kubectl expose deployment nginx --port=80 --type=NodePort service/nginx exposed # 查看對外端口 [root@k8s-master ~]# kubectl get pod,svc NAME READY STATUS RESTARTS AGE pod/nginx-6799fc88d8-lj24f 1/1 Running 0 3m4sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 39m service/nginx NodePort 10.105.227.129 <none> 80:30640/TCP 20s# 訪問地址:http://NodeIP:Port(NodeIP為任意節點ip,port為暴露出來的端口號)

平臺搭建2:單master集群的二進制方式安裝

  • 準備虛擬主機(記得做好快照,以便環境快速恢復)。網絡要求:集群機器之間能夠互通,且能夠上外網(操作系統此例為CentOS7) 角色IP組件
    k8s-master172.16.90.147kube-apiserver,kube-controller-manager,kube -scheduler,etcd
    k8s-node1172.16.90.148kubelet,kube-proxy,docker etcd
  • 兩個虛擬機的初始化(記得做好快照,以便環境快速恢復)# 關閉防火墻 systemctl stop firewalld systemctl disable firewalld# 關閉 selinux sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久 setenforce 0 # 臨時# 關閉 swap swapoff -a # 臨時 sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久# 根據規劃設置主機名 hostnamectl set-hostname <hostname># 在 master 添加 hosts cat >> /etc/hosts << EOF 172.16.90.147 m1 172.16.90.148 n1 EOF# 將橋接的 IPv4 流量傳遞到 iptables 的鏈 cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF# 生效 sysctl --system # 時間同步 yum install ntpdate -y ntpdate time.windows.com
  • 為etcd自簽證書# 準備 cfssl 證書生成工具 # cfssl 是一個開源的證書管理工具,使用 json 文件生成證書,相比 openssl 更方便使用。 找任意一臺服務器操作,這里用 Master 節點 # 下載 wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64 mv cfssl_linux-amd64 /usr/local/bin/cfssl mv cfssljson_linux-amd64 /usr/local/bin/cfssljson mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo# 生成 Etcd 證書 # 自簽證書頒發機構(CA) # 創建工作目錄 [root@m1 TSL]# mkdir -p ~/TLS/{etcd,k8s} [root@m1 TSL]# cd TLS/etcd# 自簽CA [root@m1 TSL]# cat > ca-config.json<< EOF {"signing": { "default": { "expiry": "87600h" },"profiles": { "www": { "expiry": "87600h", "usages": ["signing", "key encipherment", "server auth", "client auth"] } } } } EOF [root@m1 TSL]# cat > ca-csr.json<< EOF { "CN": "etcd CA", "key": { "algo": "rsa", "size": 2048 },"names": [{ "C": "CN", "L": "Beijing", "ST": "Beijing"}] } EOF# 生成證書 [root@m1 etcd]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca - [root@m1 etcd]# ls *pem ca-key.pem ca.pem# 使用自簽 CA 簽發 Etcd HTTPS 證書 # 創建證書申請文件 [root@m1 etcd]# cat > server-csr.json<< EOF {"CN": "etcd","hosts": ["172.16.90.147","172.16.90.148"],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "BeiJing","ST": "BeiJing"}] } EOF # 注意:上述文件 hosts 字段中 IP 為所有 etcd 節點的集群內部通信 IP,一個都不能少!為了 方便后期擴容可以多寫幾個預留的 IP。# 生成證書 [root@m1 etcd]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server#查看結果 [root@m1 etcd]# ls server*pem server-key.pem server.pem
  • 部署etcd集群# 以下在節點 1 上操作,為簡化操作,待會將節點 1 生成的所有文件拷貝到節點 2 和節點 3. # 創建工作目錄并解壓二進制包 [root@m1 ~]# mkdir -p /opt/etcd/{bin,cfg,ssl} [root@m1 ~]# tar zxvf etcd-v3.4.9-linux-amd64.tar.gz [root@m1 ~]# mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/ [root@m1 opt]# tree etcd etcd ├── bin │ ├── etcd │ └── etcdctl ├── cfg └── ssl# 創建etcd配置文件 [root@m1 ~]# cat > /opt/etcd/cfg/etcd.conf << EOF #[Member] #ETCD_NAME:節點名稱,集群中唯一 ETCD_NAME="etcd-1" #ETCD_DATA_DIR:數據目錄 ETCD_DATA_DIR="/var/lib/etcd/default.etcd" #ETCD_LISTEN_PEER_URLS:集群通信監聽地址 ETCD_LISTEN_PEER_URLS="https://172.16.90.147:2380" #ETCD_LISTEN_CLIENT_URLS:客戶端訪問監聽地址 ETCD_LISTEN_CLIENT_URLS="https://172.16.90.147:2379" #[Clustering] #ETCD_INITIAL_ADVERTISE_PEER_URLS:集群通告地址 ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.16.90.147:2380" #ETCD_ADVERTISE_CLIENT_URLS:客戶端通告地址 ETCD_ADVERTISE_CLIENT_URLS="https://172.16.90.147:2379" #ETCD_INITIAL_CLUSTER:集群節點地址 ETCD_INITIAL_CLUSTER="etcd-1=https://172.16.90.147:2380,etcd-2=https://172.16.90.148:2380" #ETCD_INITIAL_CLUSTER_TOKEN:集群 Token ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" #ETCD_INITIAL_CLUSTER_STATE:加入集群的當前狀態,new 是新集群,existing 表示加入 已有集群 ETCD_INITIAL_CLUSTER_STATE="new"#systemd 管理 etcd [root@m1 /]# cat > /usr/lib/systemd/system/etcd.service << EOF [Unit] Description=Etcd Server After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify EnvironmentFile=/opt/etcd/cfg/etcd.conf ExecStart=/opt/etcd/bin/etcd \ --cert-file=/opt/etcd/ssl/server.pem \ --key-file=/opt/etcd/ssl/server-key.pem \ --peer-cert-file=/opt/etcd/ssl/server.pem \ --peer-key-file=/opt/etcd/ssl/server-key.pem \ --trusted-ca-file=/opt/etcd/ssl/ca.pem \ --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \ --logger=zap Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF# 筆者再啟動etcd服務時報錯,經排查因為 \ 引發,改后可行 [Unit] Description=Etcd Server After=network.target After=network-online.target Wants=network-online.target [Service] Type=notify EnvironmentFile=/opt/etcd/cfg/etcd.conf ExecStart=/opt/etcd/bin/etcd --cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem --peer-cert-file=/opt/etcd/ssl/server.pem --peer-key-file=/opt/etcd/ssl/server-key.pem --trusted-ca-file=/opt/etcd/ssl/ca.pem --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem --logger=zap Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target# 拷貝剛才生成的證書 [root@m1 ssl]# cp ~/TLS/etcd/ca*pem ~/TLS/etcd/server*pem /opt/etcd/ssl/ [root@m1 ssl]# ls ca-key.pem ca.pem server-key.pem server.pem# 將上面mastert所有生成的文件拷貝到從節點 [root@m1 system]# scp -r /opt/etcd/ root@172.16.90.148:/opt/ [root@m1 system]# scp /usr/lib/systemd/system/etcd.service root@172.16.90.148:/usr/lib/systemd/system/# 到從節點點修改配置文件 [root@n1 ~]# vim /opt/etcd/cfg/etcd.conf #[Member] ETCD_NAME="etcd-2" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://172.16.90.148:2380" ETCD_LISTEN_CLIENT_URLS="https://172.16.90.148:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://172.16.90.148:2380" ETCD_ADVERTISE_CLIENT_URLS="https://172.16.90.148:2379" ETCD_INITIAL_CLUSTER="etcd-1=https://172.16.90.147:2380,etcd-2=https://172.16.90.148:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new"# 啟動并設置開機啟動 # 重新服務的配置文件 [root@m1 system]# systemctl daemon-reload #啟動etcd服務 [root@m1 system]# systemctl start etcd #有錯誤可用此命令查看日志;也可檢查是否啟動 [root@m1 system]# systemctl status etcd.service #將etcd服務設置為開機啟動 [root@m1 system]# systemctl enable etcd# 在master節點執行以下命令,檢查是否啟動成功 [root@m1 ~]# ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://172.16.90.147:2379,https://172.16.90.148:2379" endpoint health https://172.16.90.147:2379 is healthy: successfully committed proposal: took = 23.120604ms https://172.16.90.148:2379 is healthy: successfully committed proposal: took = 24.304144ms #如果輸出上面信息,就說明集群部署成功。如果有問題第一步先看日志: /var/log/message 或 journalctl -u etcd
  • 安裝docker# 以下在所有節點操作。這里采用二進制安裝,用 yum 安裝也一樣。 # 解壓二進制包 [root@m1 ~]# tar zxvf docker-19.03.9.tgz [root@m1 ~]# mv docker/* /usr/bin# systemd 管理 docker [root@m1 ~]# vim /usr/lib/systemd/system/docker.service [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com After=network-online.target firewalld.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/bin/dockerd ExecReload=/bin/kill -s HUP $MAINPID LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TimeoutStartSec=0 Delegate=yes KillMode=process Restart=on-failure StartLimitBurst=3 StartLimitInterval=60s [Install] WantedBy=multi-user.target# 創建配置文件 # registry-mirrors 阿里云鏡像加速器 [root@m1 ~]# cat > /etc/docker/daemon.json << EOF > { > "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"] > } > EOF
  • 為apiserver自簽證書# 主從節點間的訪問:添加可信任的ip列表 或者 寫到CA證書發送 # 下列以 添加可信任的ip列表 為例進行演示# 創建CA配置json文件 # 自簽證書頒發機構(CA) [root@m1 k8s]# vim ca-config.json {"signing": {"default": {"expiry": "87600h"},"profiles": {"kubernetes": {"expiry": "87600h","usages": ["signing","key encipherment","server auth","client auth"]}}} }[root@m1 k8s]# vim ca-csr.json {"CN": "kubernetes","key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "HuBei","ST": "WuHan","O": "k8s","OU": "System"}] }# 使用自簽 CA 簽發 kube-apiserver HTTPS 證書 # 創建apiserver證書的所需配置文件 [root@m1 k8s]# vim kube-proxy-csr.json {"CN": "system:kube-proxy","hosts": [],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "HuBei","ST": "WuHan","O": "k8s","OU": "System"}] }# 創建證書申請文件: [root@m1 k8s]# vim server-csr.json {"CN": "kubernetes","hosts": ["10.0.0.1","127.0.0.1","kubernetes","kubernetes.default","kubernetes.default.svc","kubernetes.default.svc.cluster","kubernetes.default.svc.cluster.local","172.16.90.147","172.16.90.148","172.16.90.149","172.16.90.150","172.16.90.151"],"key": {"algo": "rsa","size": 2048},"names": [{"C": "CN","L": "HuBei","ST": "WuHan","O": "k8s","OU": "System"}] } # 注:host中的最后幾個IP為需要連接apiserver的IP,一般為master集群的所有IP,和負載均衡LB的所有IP和VIP,本文中的IP # "10.16.8.150", master01 # "10.16.8.151", master02 # "10.16.8.156", LB # "10.16.8.155", 備用IP # "10.16.8.164" 備用IP # 其中10.16.8.168即可信任的IP列表 # 原配置: # ... # "10.0.0.1", # "127.0.0.1", # "kubernetes", # "kubernetes.default", # "kubernetes.default.svc", # "kubernetes.default.svc.cluster", # "kubernetes.default.svc.cluster.local", # "10.16.8.150", # "10.16.8.151", # "10.16.8.156", # "10.16.8.155", # "10.16.8.164" # ...# 自建CA,生成證書 [root@m1 k8s]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -# 生成證書 [root@k8s-master01 k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server [root@k8s-master01 k8s]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy# 檢查證書生成情況 [root@m1 k8s]# ll *.pem [root@m1 k8s]# ll *.pem -rw-------. 1 root root 1679 728 19:14 ca-key.pem -rw-r--r--. 1 root root 1346 728 19:14 ca.pem -rw-------. 1 root root 1675 728 19:24 kube-proxy-key.pem -rw-r--r--. 1 root root 1391 728 19:24 kube-proxy.pem -rw-------. 1 root root 1675 728 19:22 server-key.pem -rw-r--r--. 1 root root 1635 728 19:22 server.pem# 啟動并設置開機啟動 systemctl daemon-reload systemctl start docker systemctl enable docker
  • 部署master組件(由于未知錯誤,筆者CentOS7無法識別 “”,此處有*.conf 和 *.server文件集合,驗證碼:nht1)# 注:打開鏈接你會發現里面有很多包,下載一個 server 包就夠了,包含了 Master 和 Worker Node 二進制文件。# 解壓二進制包 [root@m1 ~]# mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} [root@m1 kubernetes]# tar -xzvf kubernetes-server-linux-amd64.tar.gz [root@m1 ~]# cd kubernetes/server/bin [root@m1 bin]# cp kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin [root@m1 bin]# cp kubectl /usr/bin/# 部署 kube-apiserver # 創建配置文件[root@m1 bin]# vim /opt/kubernetes/cfg/kube-apiserver.conf KUBE_APISERVER_OPTS="--logtostderr=false \ --v=2 \ --log-dir=/opt/kubernetes/logs \ --etcd-servers=https://172.16.90.147:2379,https://172.16.90.148:2379 \ --bind-address=172.16.90.147 \ --secure-port=6443 \ --advertise-address=172.16.90.147 \ --allow-privileged=true \ --service-cluster-ip-range=10.0.0.0/24 \ --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \ --authorization-mode=RBAC,Node \ --enable-bootstrap-token-auth=true \ --token-auth-file=/opt/kubernetes/cfg/token.csv \ --service-node-port-range=30000-32767 \ --kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \ --kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \ --tls-cert-file=/opt/kubernetes/ssl/server.pem \ --tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \ --client-ca-file=/opt/kubernetes/ssl/ca.pem \ --service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \ --etcd-cafile=/opt/etcd/ssl/ca.pem \ --etcd-certfile=/opt/etcd/ssl/server.pem \ --etcd-keyfile=/opt/etcd/ssl/server-key.pem \ --audit-log-maxage=30 \ --audit-log-maxbackup=3 \ --audit-log-maxsize=100 \ --audit-log-path=/opt/kubernetes/logs/k8s-audit.log" # 配置詳解 # –logtostderr:啟用日志 # —v:日志等級 # –log-dir:日志目錄 # –etcd-servers:etcd 集群地址 # –bind-address:監聽地址 # –secure-port:https 安全端口 # –advertise-address:集群通告地址 # –allow-privileged:啟用授權 # –service-cluster-ip-range:Service 虛擬 IP 地址段 # –enable-admission-plugins:準入控制模塊 # –authorization-mode:認證授權,啟用 RBAC 授權和節點自管理 # –enable-bootstrap-token-auth:啟用 TLS bootstrap 機制 # –token-auth-file:bootstrap token 文件 # –service-node-port-range:Service nodeport 類型默認分配端口范圍 # –kubelet-client-xxx:apiserver 訪問 kubelet 客戶端證書 # –tls-xxx-file:apiserver https 證書 # –etcd-xxxfile:連接 Etcd 集群證書 # –audit-log-xxx:審計日志# 拷貝剛才生成的證書,把剛才生成的證書拷貝到配置文件中的路徑 [root@m1 bin]# cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/# 啟用 TLS Bootstrapping 機制 # TLS Bootstraping:Master apiserver 啟用 TLS 認證后,Node 節點 kubelet 和 kube- proxy 要與 kube-apiserver 進行通信,必須使用 CA 簽發的有效證書才可以,當 Node 節點很多時,這種客戶端證書頒發需要大量工作,同樣也會增加集群擴展復雜度。為了 簡化流程,Kubernetes 引入了 TLS bootstraping 機制來自動頒發客戶端證書,kubelet 會以一個低權限用戶自動向 apiserver 申請證書,kubelet 的證書由 apiserver 動態簽署。 # 所以強烈建議在 Node 上使用這種方式,目前主要用于 kubelet,kube-proxy 還是由我 們統一頒發一個證書。 # 創建上述配置文件中 token 文件: [root@m1 bin]# vim /opt/kubernetes/cfg/token.csv c47ffb939f5ca36231d9e3121a252940,kubelet-bootstrap,10001,"system:node-bootstrapper" # 格式:token,用戶名,UID,用戶組。token 也可自行生成替換: # head -c 16 /dev/urandom | od -An -t x | tr -d ' '# systemd 管理 apiserver [root@m1 bin]# vim /usr/lib/systemd/system/kube-apiserver.service [Unit] Description=Kubernetes API Server Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target# 啟動并設置開機啟動 [root@m1 ~]# systemctl daemon-reload [root@m1 ~]# systemctl start kube-apiserver [root@m1 ~]# systemctl enable kube-apiserver# 授權 kubelet-bootstrap 用戶允許請求證書 [root@m1 k8s]# kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap# 部署 kube-controller-manager [root@m1 k8s]# vim /opt/kubernetes/cfg/kube-controller-manager.conf KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \ --v=2 \ --log-dir=/opt/kubernetes/logs \ --leader-elect=true \ --master=127.0.0.1:8080 \ --bind-address=127.0.0.1 \ --allocate-node-cidrs=true \ --cluster-cidr=10.244.0.0/16 \ --service-cluster-ip-range=10.0.0.0/24 \ --cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \ --cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \ --root-ca-file=/opt/kubernetes/ssl/ca.pem \ --service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \ --experimental-cluster-signing-duration=87600h0m0s" # -master:通過本地非安全本地端口 8080 連接 apiserver # -leader-elect:當該組件啟動多個時,自動選舉(HA) # -cluster-signing-cert-file/–cluster-signing-key-file:自動為 kubelet 頒發證書 的 CA,與 apiserver 保持一致# systemd 管理 controller-manager [root@m1 k8s]# vim /usr/lib/systemd/system/kube-controller-manager.service [Unit] Description=Kubernetes Controller Manager Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=/opt/kubernetes/cfg/kube-controller-manager.conf ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target# 啟動并設置開機啟動 [root@m1 k8s]# systemctl daemon-reload [root@m1 k8s]# systemctl start kube-controller-manager [root@m1 k8s]# systemctl enable kube-controller-manager# 部署 kube-scheduler [root@m1 k8s]# vim /opt/kubernetes/cfg/kube-scheduler.conf KUBE_SCHEDULER_OPTS="--logtostderr=false \ --v=2 \ --log-dir=/opt/kubernetes/logs \ --leader-elect \ --master=127.0.0.1:8080 \ --bind-address=127.0.0.1" # –master:通過本地非安全本地端口 8080 連接 apiserver。 # –leader-elect:當該組件啟動多個時,自動選舉(HA)# systemd 管理 scheduler [root@m1 k8s]# vim /usr/lib/systemd/system/kube-scheduler.service [Unit] Description=Kubernetes Scheduler Documentation=https://github.com/kubernetes/kubernetes[Service] EnvironmentFile=/opt/kubernetes/cfg/kube-scheduler.conf ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS Restart=on-failure[Install] WantedBy=multi-user.target# 啟動并設置開機啟動 [root@m1 k8s]# systemctl daemon-reload [root@m1 k8s]# systemctl start kube-scheduler [root@m1 k8s]# systemctl enable kube-scheduler# 查看集群狀態 # 所有組件都已經啟動成功,通過 kubectl 工具查看當前集群組件狀態: Warning: v1 ComponentStatus is deprecated in v1.19+ NAME STATUS MESSAGE ERROR controller-manager Healthy ok scheduler Healthy ok etcd-0 Healthy {"health":"true"} etcd-1 Healthy {"health":"true"} # 如上輸出說明 Master 節點組件運行正常。
  • 部署node組件(由于未知錯誤,筆者CentOS7無法識別 “”,此處有*.conf 和 *.server文件集合,驗證碼:nht1)# 創建工作目錄并拷貝二進制文件 # 在所有 worker node 創建工作目錄 [root@n1 ~]# mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}# 將m1上證書文件拷貝到n1 [root@m1 k8s]# scp ~/TLS/k8s/ca*pem ~/TLS/k8s/kube-proxy*pem root@172.16.90.148:/opt/kubernetes/ssl/# 解壓文件并拷貝配置 [root@n1 ~]# tar -xzvf kubernetes-node-linux-amd64.tar.gz [root@n1 ~]# cd kubernetes/node/bin/ [root@n1 bin]# ls kubeadm kubectl kubelet kube-proxy [root@n1 bin]# cp kubelet kube-proxy /opt/kubernetes/bin [root@n1 bin]# cp kubectl /usr/bin/# 部署 kubelet # 創建配置文件 [root@n1 bin]# vim /opt/kubernetes/cfg/kubelet.conf KUBELET_OPTS="--logtostderr=false \ --v=2 \ --log-dir=/opt/kubernetes/logs \ --hostname-override=m1 \ --network-plugin=cni \ --kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \ --bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \ --config=/opt/kubernetes/cfg/kubelet-config.yml \ --cert-dir=/opt/kubernetes/ssl \ --pod-infra-container-image=lizhenliang/pause-amd64:3.0" # –hostname-override:顯示名稱,集群中唯一 # –network-plugin:啟用 CNI # –kubeconfig:空路徑,會自動生成,后面用于連接 apiserver # –bootstrap-kubeconfig:首次啟動向 apiserver 申請證書 # –config:配置參數文件 # –cert-dir:kubelet 證書生成目錄 # –pod-infra-container-image:管理 Pod 網絡容器的鏡像# 配置參數文件 [root@n1 bin]# vim /opt/kubernetes/cfg/kubelet-config.yml kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 0.0.0.0 port: 10250 readOnlyPort: 10255 cgroupDriver: cgroupfs clusterDNS: - 10.0.0.2 clusterDomain: cluster.local failSwapOn: false authentication:anonymous:enabled: falsewebhook:cacheTTL: 2m0senabled: truex509:clientCAFile: /opt/kubernetes/ssl/ca.pem authorization:mode: Webhookwebhook:cacheAuthorizedTTL: 5m0scacheUnauthorizedTTL: 30s evictionHard: imagefs.available: 15% memory.available: 100Mi nodefs.available: 10% nodefs.inodesFree: 5% maxOpenFiles: 1000000 maxPods: 110# 生成 bootstrap.kubeconfig 文件 # 指定apiserver地址 [root@n1 kubernetes]# export KUBE_APISERVER="https://172.16.90.147:6443" # apiserver IP:PORT # 指定TOKEN值 [root@n1 kubernetes]# export TOKEN="c47ffb939f5ca36231d9e3121a252940" # 與 token.csv 里保持一致 # 設置集群參數 [root@n1 kubernetes]# kubectl config set-cluster kubernetes \ > --certificate-authority=/opt/kubernetes/ssl/ca.pem \ > --embed-certs=true \ > --server=${KUBE_APISERVER} \ > --kubeconfig=bootstrap.kubeconfig Cluster "kubernetes" set. # 設置客戶端認證參數 [root@n1 kubernetes]# kubectl config set-credentials "kubelet-bootstrap" \ > --token=${TOKEN} \ > --kubeconfig=bootstrap.kubeconfig User "kubelet-bootstrap" set. # 設置上下文參數 [root@n1 kubernetes]# kubectl config set-context default \ > --cluster=kubernetes \ > --user="kubelet-bootstrap" \ > --kubeconfig=bootstrap.kubeconfig Context "default" created. # 設置默認上下文 [root@n1 kubernetes]# kubectl config use-context default --kubeconfig=bootstrap.kubeconfig Switched to context "default". # –embed-certs 為 true 時表示將 certificate-authority 證書寫入到生成的 bootstrap.kubeconfig 文件中 # 拷貝到配置文件路徑 [root@n1 kubernetes]# cp bootstrap.kubeconfig /opt/kubernetes/cfg# systemd 管理 kubelet [root@n1 kubernetes]# vim /usr/lib/systemd/system/kubelet.service [Unit] Description=Kubernetes Kubelet After=docker.service [Service] EnvironmentFile=/opt/kubernetes/cfg/kubelet.conf ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target# 啟動并設置開機啟動 [root@n1 kubernetes]# systemctl daemon-reload [root@n1 kubernetes]# systemctl start kubelet [root@n1 kubernetes]# systemctl enable kubelet# 批準 kubelet 證書申請并加入集群 # 查看 kubelet 證書請求 [root@m1 ~]# kubectl get csr NAME AGE SIGNERNAME REQUESTOR CONDITION node-csr-j8VQGozwmrCDsJfBXTtA7MYwlmSMULb8WacDPTSniDY 61s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending# 批準申請 [root@m1 ~]# kubectl certificate approve node-csr-j8VQGozwmrCDsJfBXTtA7MYwlmSMULb8WacDPTSniDY certificatesigningrequest.certificates.k8s.io/node-csr-j8VQGozwmrCDsJfBXTtA7MYwlmSMULb8WacDPTSniDY approved# 查看節點 [root@m1 ~]# kubectl get node NAME STATUS ROLES AGE VERSION m1 NotReady <none> 28s v1.19.13 # 注:由于網絡插件還沒有部署,節點會沒有準備就緒 NotReady# 部署 kube-proxy # 創建配置文件 [root@n1 kubernetes]# vim /opt/kubernetes/cfg/kube-proxy.conf KUBE_PROXY_OPTS="--logtostderr=false \ --v=2 \ --log-dir=/opt/kubernetes/logs \ --config=/opt/kubernetes/cfg/kube-proxy-config.yml"# 配置參數文件 [root@n1 kubernetes]# vim /opt/kubernetes/cfg/kube-proxy-config.yml kind: KubeProxyConfiguration apiVersion: kubeproxy.config.k8s.io/v1alpha1 bindAddress: 0.0.0.0 metricsBindAddress: 0.0.0.0:10249 clientConnection:kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig hostnameOverride: n1 clusterCIDR: 10.0.0.0/24# 生成 kubeconfig 文件 # m1已經設置集群參數KUBE_APISERVER,這里不再設置 # 設置集群參數 [root@n1 kubernetes]# kubectl config set-cluster kubernetes \ > --certificate-authority=/opt/kubernetes/ssl/ca.pem \ > --embed-certs=true \ > --server=${KUBE_APISERVER} \ > --kubeconfig=kube-proxy.kubeconfig Cluster "kubernetes" set. # 設置客戶端認證參數 [root@n1 kubernetes]# kubectl config set-credentials kube-proxy \ > --client-certificate=/opt/kubernetes/ssl/kube-proxy.pem \ > --client-key=/opt/kubernetes/ssl/kube-proxy-key.pem \ > --embed-certs=true \ > --kubeconfig=kube-proxy.kubeconfig User "kube-proxy" set. # 設置上下文參數 [root@n1 kubernetes]# kubectl config set-context default \ > --cluster=kubernetes \ > --user=kube-proxy \ > --kubeconfig=kube-proxy.kubeconfig Context "default" created. # 設置默認上下文 [root@n1 kubernetes]# kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig Switched to context "default". # 設置集群參數和客戶端認證參數時 –embed-certs 都為 true,這會將 certificate-authority、client-certificate 和 client-key 指向的證書文件內容寫入到生成的 kube-proxy.kubeconfig 文件中 # 新增節點時只需,將bootstrap.kubeconfig和kube-proxy.kubeconfig文件分發到各node節點上# 拷貝到配置文件指定路徑 [root@n1 kubernetes]# cp kube-proxy.kubeconfig /opt/kubernetes/cfg/# systemd 管理 kube-proxy [root@n1 kubernetes]# vim /usr/lib/systemd/system/kube-proxy.service [Unit] Description=Kubernetes Proxy After=network.target [Service] EnvironmentFile=/opt/kubernetes/cfg/kube-proxy.conf ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target# 啟動并設置開機啟動 [root@n1 kubernetes]# systemctl daemon-reload [root@n1 kubernetes]# systemctl start kube-proxy [root@n1 kubernetes]# systemctl status kube-proxy ● kube-proxy.service - Kubernetes ProxyLoaded: loaded (/usr/lib/systemd/system/kube-proxy.service; disabled; vendor preset: disabled)Active: active (running) since 六 2021-07-31 19:03:13 CST; 2s ago ... [root@n1 kubernetes]# systemctl enable kube-proxy
  • 部署集群(CNI)網絡# 解壓二進制包并移動到默認工作目錄 [root@n1 ~]# mkdir -p /opt/cni/bin [root@n1 ~]# tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin# 部署CNI網絡 [root@m1 ~]# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml [root@m1 ~]# sed -i -r "s#quay.io/coreos/flannel:.*-amd64#lizhenliang/flannel:v0.12.0- amd64#g" kube-flannel.yml# 默認鏡像地址無法訪問,修改為 docker hub 鏡像倉庫 [root@m1 ~]# kubectl apply -f kube-flannel.yml [root@m1 ~]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE kube-flannel-ds-2kqmz 1/1 Running 0 6m26s [root@m1 ~]# kubectl get node NAME STATUS ROLES AGE VERSION m1 Ready <none> 81m v1.19.13 # 部署好網絡插件,Node準備就緒# 授權 apiserver 訪問 kubelet [root@m1 ~]# vim apiserver-to-kubelet-rbac.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:annotations:rbac.authorization.kubernetes.io/autoupdate: "true"labels:kubernetes.io/bootstrapping: rbac-defaultsname: system:kube-apiserver-to-kubelet rules:- apiGroups:- ""resources:- nodes/proxy- nodes/stats- nodes/log- nodes/spec- nodes/metrics- pods/logverbs: - "*" --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:name: system:kube-apiservernamespace: "" roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: system:kube-apiserver-to-kubelet subjects:- apiGroup: rbac.authorization.k8s.iokind: Username: kubernetes [root@m1 ~]# kubectl apply -f apiserver-to-kubelet-rbac.yaml
  • 新增加 Worker Node# 拷貝已部署好的 Node 相關文件到新節點 # 在n1(172.16.90.148)節點將Worker Node涉及文件拷貝到新節點172.16.90.149 [root@n1 ~]# scp -r /opt/kubernetes root@172.16.90.149:/opt/ [root@n1 ~]# scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service root@172.16.90.149:/usr/lib/systemd/system [root@n1 ~]# scp -r /opt/cni/ root@172.16.90.149:/opt/ [root@n1 ~]# scp /opt/kubernetes/ssl/ca.pem root@172.16.90.149:/opt/kubernetes/ssl# 刪除kubelet證書和kubeconfig文件 [root@n2 ~]# rm /opt/kubernetes/cfg/kubelet.kubeconfig [root@n2 ~]# rm -f /opt/kubernetes/ssl/kubelet* # 注:這幾個文件是證書申請審批后自動生成的,每個Node不同,必須刪除重新生成# 修改主機名 [root@n2 ~]# vim /opt/kubernetes/cfg/kubelet.conf ... --hostname-override=n2 ... [root@n2 ~]# vim /opt/kubernetes/cfg/kube-proxy-config.yml ... hostnameOverride: n2 ...# 啟動并設置開機啟動 [root@n2 ~]# systemctl daemon-reload [root@n2 ~]# systemctl start kubelet [root@n2 ~]# systemctl enable kubelet [root@n2 ~]# systemctl start kube-proxy [root@n2 ~]# systemctl enable kube-proxy# 在Master上批準新Node kubelet證書申請 # 與n1相同,此處略過# 查看 Node 狀態 [root@m1 ~]# Kubectl get node
  • 測試集群[root@m1 ~]# kubectl create deployment nginx --image=nginx deployment.apps/nginx created [root@m1 ~]# kubectl expose deployment nginx --port=80 --type=NodePort service/nginx exposed [root@m1 ~]# kubectl get pod,svc NAME READY STATUS RESTARTS AGE pod/nginx-6799fc88d8-j5fn2 0/1 ContainerCreating 0 20sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 3d23h service/nginx NodePort 10.0.0.70 <none> 80:30465/TCP 7s # 瀏覽器訪問地址:http://NodeIP:Port(例如:http://172.16.90.148:30465)

兩種搭建方式對比:對兩種搭建方式的總結

  • kubeadm搭建k8s集群
    • 安裝linux系統虛擬機,并對系統進行初始化操作
    • 在所有節點(master、node)安裝docker(包括下載、修改倉庫地址和yum源成阿里地址)、kubeadm(kubeadm join <Master 節點的 IP 和端口 >)、kubelet和kubectl
    • 在master節點執行初始化命令操作(kubeadm init \,指定鏡像源,使用阿里云鏡像)
    • 部署網絡CNI插件(kubectl apply -f kube-flannel.yml)
    • 在所有node節點上使用join命令把node節點添加到master
  • 二進制方式搭建k8s集群
    • 安裝linux系統虛擬機,并對系統進行初始化操作
    • 生成cfssl自簽證書(ca-key.pem、ca.pem、server-key.pem、server.pem)
    • 部署ectd集群(本質是把etcd服務,交給systemd管理。把證書復制過來,啟動并設置開機啟動)
    • 為apiserver自簽證書(生成過程和etcd類似)
    • 部署master組件(apiserver、controller-manager、scheduler下載二進制文件進行安裝,交給systemd管理組件啟動并設置開機啟動)
    • 部署node組件(docker、kubelet、kube-proxy下載二進制文件進行安裝,交給systemd管理組件啟動并設置開機啟動,最后批準kubelet證書申請并加入集群)
    • 部署CNI網絡插件

3. 核心技術(上)

kubernetes 集群命令行工具 kubectl:kubectl 是 Kubernetes 集群的命令行工具,通過 kubectl 能夠對集群本身進行管理,并能 夠在集群上進行容器化應用的安裝部署。kubectl命令語法:kubectl [command] [TYPE] [NAME] [flags](command指定要對資源執行的操作,例如create、get、describe和delete;TYPE指定資源類型,資源類型是大小寫敏感的,開發者能夠以單數、復數和縮略的形式,例如kubectl get pod pod1;NAME指定資源名稱,名稱大小寫敏感,如果省略名稱,則會顯示所有的資源例如:kubectl get pods);flags指定可選的參數,例如可用-s或者-server參數指定kubernetes API server的地址和端口。獲取kubectl幫助的方法:kubectl --help,具體看某個操作kubectl get --help。kubectl 子命令使用分類:

  • 基礎命令
  • 部署和集群管理命令
  • 故障和調試命令
  • 其他命令

    kubernetes集群YAML文件詳解:k8s集群中對資源管理和資源對象編排部署都可以通過聲明樣式(YAML)文件來解決,我們把這種文件叫做資源清單文件,通過 kubectl 命令直接使用資源清單文件就可以實現對大量的資源對象進行編排部署了。語法格式:通過縮進表示層級關系;不能用tab進行縮進,只能用空格;一般開通縮進兩個空格;字符后縮進一個空格,比如冒號,逗號等后面;使用—表示新的yaml文件開始;使用#表示注釋。yaml文件有控制器定義和被控制對象組成:

快速編寫yaml文件:使用kubectl create命令生成yaml文件,命令:kubectl create deployment web --image=nginx -o yaml --dry-run > web.yaml(用于還未真正部署);使用kubectl get命令導出yaml文件kubectl get deploy nginx -o=yaml --export > web.yaml(用于已經部署好的情況)

Pod簡介:Pod 是 k8s 系統中可以創建和管理的最小單元,是資源對象模型中由用戶創建或部署的最 小資源對象模型,也是在 k8s 上運行容器化應用的資源對象,其他的資源對象都是用來支 撐或者擴展 Pod 對象功能的。k8s 不會直接處理容器,而是 Pod,Pod 是由一個或多個container組成

Pod 是 Kubernetes 的最重要概念,每一個 Pod 都有一個特殊的被稱為”根容器“的 Pause 容器。Pause 容器對應的鏡 像屬于 Kubernetes 平臺的一部分,除了 Pause 容器,每個 Pod 還包含一個或多個緊密相關的用戶業務容器(加入到Pause容器中)

pod基本概念:最小部署單元、包含多個容器(一組容器的集合)、各個pod中容器共享網絡命名空間、pod是短暫的

pod存在意義:創建容器使用docker,一個docker對應一個容器(便于管理),一個容器對應一個進程,一個容器運行一個應用程序;pod是多進程設計,運行多個應用程序(一個pod有多個容器,一個容器里面運行一個應用程序);pod存在為了親密性應用(兩個應用之間進行交互、網絡之間調用、兩個應用需要頻繁調用)

pod與應用、容器、節點、pos差別:每個pod都是應用的一個實例,有專用的IP;一個pod可以有多個容器,彼此之間共享網絡和存儲資源,每個pod中有一個pause容器保存所有的容器狀態,通過管理pause容器,達到管理pod中所有容器的效果;同一個pod中的容器總會被調度到相同node節點,不同節點間pod的通信基于虛擬二層網絡技術實現;普通的pod和靜態pod

pod特性:共享網絡,pod中容器之間通過linux的namespace和group機制進行隔離,所以要想實現網絡共享其前提是pod中所有容器都在一個namespace里面,其實現原理是先創建pause容器(也稱作info容器),然后將其他業務容器加入到pause容器中,使得所有業務容器處于同一namespace中,對外則暴露info容器的ip、mac、port等信息;共享存儲,采用docker的Volumn數據卷進行持久化存儲到某一特定區間,所有node都可以訪問該區間;生命周期短暫,當pod所在節點發生故障,那么該節點的pod會被調度到其他節點,而且被重新調度的pod是一個全新的pod;網絡平坦,K8S集群中的所有Pod都在同一個共享網絡地址空間中,也就是說每個Pod都可以通過其他Pod的IP地址來實現訪問

pod常見配置:拉取策略、資源限制、重啟機制和健康檢查

  • 鏡像拉取策略
  • 資源限制
  • 重啟策略
  • 健康檢查

pod調度策略:主要包括創建pod流程和pod調度影響因素兩部分

  • 創建pod流程:首先在master通過apiserver創建pod節點,隨后相關信息持久化到etcd中,此時scheduler是實時監控apiserver當檢查到有pod創建時,它會通過apiserver讀取到該pod存放在etcd的信息,并通過自身調度算法將該pod調度到某個node節點上;被調度的node節點通過kubelet訪問apiserver,并讀取到etcd中存放的信息,隨后通知docker創建該容器。
  • 影響pod調度的因素:主要有資源限制(前面所講的request、limit)、節點選擇器、節點親和性、污點和污點容忍這幾個方面


controller簡介:在集群上管理和運行容器的對象,Pod是通過Controller實現應用的運維(比如伸縮、滾動升級等等),Pod和Controller之間通過label標簽建立關系,其圖示如下:

常用控制器deployment:用于部署無狀態應用(例如web應用、之前部署的nginx,都是無狀態應用)、管理Pod和ReplicaSet、部署和滾動升級等功能。常用于web服務和微服務的場景,以下是使用deploy部署應用的過程:

  • 導出yaml文件kubectl create deployment web --image=nginx --dry-run -o yaml > web.yaml
  • 使用yaml部署應用 kubectl apply -f web.yaml
  • 查看應用的啟動情況 kubectl get pods
  • 對外發布(暴露端口)kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web1 -o yaml > web1.yaml,并執行該yaml文件kubectl apply -f web1.yaml
  • 查看運行情況kubectl get pods,svc
  • 應用升級 kubectl set image deployment web nginx=nignx:1.15,其升級過程,首先k8s下載1.15版本的nginx(期間1.1.4并不停止服務),下載完成后1.15版本的nginx會替換1.14版本的nginx,其升級過程中服務不中斷,最后查看升級狀態 kubectl rollout status deployment web
  • 彈性回滾,首先可通過 kubectl rollout history deployment web查看升級版本,通過 kubectl rollout undo deployment web回滾到上一個版本,也可以通過 kubectl rollout undo deployment web --to-revision=2回到指定版本,可通過 kubectl rollout status deployment web查看當前狀態。利用命令kubectl scale deployment web --relicas=10可彈性伸縮新增10個相同的pod
  • 常用控制器statefueset:pod分為無狀態pod(認為pod都是一樣的;沒有順序要求;不用考慮在哪個node運行;隨意進行伸縮和拓展)和有狀態pod(以上因素都需要考慮到;讓每個pod獨立的保持pod啟動順序和唯一性;唯一的網絡表示符,持久存儲;有序,比如mysql主從),而statefueset用于有狀態pod控制。其創建過程分為無頭service和有狀態應用:



    常用控制器DaemonSet:用于部署守護進程,在每個node上運行一個pod,新加入的node也同樣運行在一個pod里面(例如:在每個node節點安裝數據采集工具)


    常用控制器Job:一次性任務




    常用控制器cronJob:定時任務



    Service簡介:service用于定義一組pod訪問規則。作用:防止pod失聯、定義一組pod訪問策略(負載均衡)。起源如下圖:




    常用的Service類型:ClusterIP、NodePort、LoadBalancer

    • ClusterIP:集群內部使用(例如node1節點訪問啟動的pod,可利用 kubectl get svc查看分配的ip)
    • NodePort:對外訪問應用使用(例如:通過ip訪問系統,在瀏覽器訪問pod里面的nginx)
    • loadBalancer:對外訪問應用使用,公有云亦可

    4. 核心技術(下)

    配置管理:以是否加密來區分使用,分為Secret(常用作憑證,作用是將加密數據存在etcd里面,讓pod容器以掛載volume方式進行訪問)和ConfigMap(常用作配置文件,作用是存儲不加密數據到etcd,讓Pod以變量或者Volume掛載到容器中)

    • secret的使用




    • ConfigMap的使用





    集群安全機制:訪問k8s集群時候,需要經過以下三個步驟完成具體操作。而在進行訪問的時候,過程中都需要經過apiserver,apiserver作為統一協調(類比于門衛)。訪問過程中需要證書、token或者用戶名+密碼;如果訪問pod則需要serviceAccount

    • 認證:傳輸安全(對外不暴露8080端口,只能內部訪問,對外使用端口6443)、認證(客戶端認證常用方式有:https證書認證,基于ca證書;http tokens認證,通過token識別用戶;http基本認證,用戶名+密碼方式認證)
    • 鑒權(授權):基于RBAC進行鑒權操作;基于角色訪問控制
    • 準入控制:就是準入控制器的列表,如果列表有請求內容則通過,否則就拒絕
    #mermaid-svg-oSsf4ENcZdYTy5Py .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .label text{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .node rect,#mermaid-svg-oSsf4ENcZdYTy5Py .node circle,#mermaid-svg-oSsf4ENcZdYTy5Py .node ellipse,#mermaid-svg-oSsf4ENcZdYTy5Py .node polygon,#mermaid-svg-oSsf4ENcZdYTy5Py .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-oSsf4ENcZdYTy5Py .node .label{text-align:center;fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .node.clickable{cursor:pointer}#mermaid-svg-oSsf4ENcZdYTy5Py .arrowheadPath{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-oSsf4ENcZdYTy5Py .flowchart-link{stroke:#333;fill:none}#mermaid-svg-oSsf4ENcZdYTy5Py .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-oSsf4ENcZdYTy5Py .edgeLabel rect{opacity:0.9}#mermaid-svg-oSsf4ENcZdYTy5Py .edgeLabel span{color:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-oSsf4ENcZdYTy5Py .cluster text{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-oSsf4ENcZdYTy5Py .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-oSsf4ENcZdYTy5Py text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-oSsf4ENcZdYTy5Py .actor-line{stroke:grey}#mermaid-svg-oSsf4ENcZdYTy5Py .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-oSsf4ENcZdYTy5Py #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .sequenceNumber{fill:#fff}#mermaid-svg-oSsf4ENcZdYTy5Py #sequencenumber{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py #crosshead path{fill:#333;stroke:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .messageText{fill:#333;stroke:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-oSsf4ENcZdYTy5Py .labelText,#mermaid-svg-oSsf4ENcZdYTy5Py .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-oSsf4ENcZdYTy5Py .loopText,#mermaid-svg-oSsf4ENcZdYTy5Py .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-oSsf4ENcZdYTy5Py .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-oSsf4ENcZdYTy5Py .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-oSsf4ENcZdYTy5Py .noteText,#mermaid-svg-oSsf4ENcZdYTy5Py .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-oSsf4ENcZdYTy5Py .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-oSsf4ENcZdYTy5Py .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-oSsf4ENcZdYTy5Py .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-oSsf4ENcZdYTy5Py .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py .section{stroke:none;opacity:0.2}#mermaid-svg-oSsf4ENcZdYTy5Py .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-oSsf4ENcZdYTy5Py .section2{fill:#fff400}#mermaid-svg-oSsf4ENcZdYTy5Py .section1,#mermaid-svg-oSsf4ENcZdYTy5Py .section3{fill:#fff;opacity:0.2}#mermaid-svg-oSsf4ENcZdYTy5Py .sectionTitle0{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .sectionTitle1{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .sectionTitle2{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .sectionTitle3{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-oSsf4ENcZdYTy5Py .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py .grid path{stroke-width:0}#mermaid-svg-oSsf4ENcZdYTy5Py .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-oSsf4ENcZdYTy5Py .task{stroke-width:2}#mermaid-svg-oSsf4ENcZdYTy5Py .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py .taskText:not([font-size]){font-size:11px}#mermaid-svg-oSsf4ENcZdYTy5Py .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-oSsf4ENcZdYTy5Py .task.clickable{cursor:pointer}#mermaid-svg-oSsf4ENcZdYTy5Py .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-oSsf4ENcZdYTy5Py .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-oSsf4ENcZdYTy5Py .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-oSsf4ENcZdYTy5Py .taskText0,#mermaid-svg-oSsf4ENcZdYTy5Py .taskText1,#mermaid-svg-oSsf4ENcZdYTy5Py .taskText2,#mermaid-svg-oSsf4ENcZdYTy5Py .taskText3{fill:#fff}#mermaid-svg-oSsf4ENcZdYTy5Py .task0,#mermaid-svg-oSsf4ENcZdYTy5Py .task1,#mermaid-svg-oSsf4ENcZdYTy5Py .task2,#mermaid-svg-oSsf4ENcZdYTy5Py .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-oSsf4ENcZdYTy5Py .taskTextOutside0,#mermaid-svg-oSsf4ENcZdYTy5Py .taskTextOutside2{fill:#000}#mermaid-svg-oSsf4ENcZdYTy5Py .taskTextOutside1,#mermaid-svg-oSsf4ENcZdYTy5Py .taskTextOutside3{fill:#000}#mermaid-svg-oSsf4ENcZdYTy5Py .active0,#mermaid-svg-oSsf4ENcZdYTy5Py .active1,#mermaid-svg-oSsf4ENcZdYTy5Py .active2,#mermaid-svg-oSsf4ENcZdYTy5Py .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-oSsf4ENcZdYTy5Py .activeText0,#mermaid-svg-oSsf4ENcZdYTy5Py .activeText1,#mermaid-svg-oSsf4ENcZdYTy5Py .activeText2,#mermaid-svg-oSsf4ENcZdYTy5Py .activeText3{fill:#000 !important}#mermaid-svg-oSsf4ENcZdYTy5Py .done0,#mermaid-svg-oSsf4ENcZdYTy5Py .done1,#mermaid-svg-oSsf4ENcZdYTy5Py .done2,#mermaid-svg-oSsf4ENcZdYTy5Py .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-oSsf4ENcZdYTy5Py .doneText0,#mermaid-svg-oSsf4ENcZdYTy5Py .doneText1,#mermaid-svg-oSsf4ENcZdYTy5Py .doneText2,#mermaid-svg-oSsf4ENcZdYTy5Py .doneText3{fill:#000 !important}#mermaid-svg-oSsf4ENcZdYTy5Py .crit0,#mermaid-svg-oSsf4ENcZdYTy5Py .crit1,#mermaid-svg-oSsf4ENcZdYTy5Py .crit2,#mermaid-svg-oSsf4ENcZdYTy5Py .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-oSsf4ENcZdYTy5Py .activeCrit0,#mermaid-svg-oSsf4ENcZdYTy5Py .activeCrit1,#mermaid-svg-oSsf4ENcZdYTy5Py .activeCrit2,#mermaid-svg-oSsf4ENcZdYTy5Py .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-oSsf4ENcZdYTy5Py .doneCrit0,#mermaid-svg-oSsf4ENcZdYTy5Py .doneCrit1,#mermaid-svg-oSsf4ENcZdYTy5Py .doneCrit2,#mermaid-svg-oSsf4ENcZdYTy5Py .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-oSsf4ENcZdYTy5Py .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-oSsf4ENcZdYTy5Py .milestoneText{font-style:italic}#mermaid-svg-oSsf4ENcZdYTy5Py .doneCritText0,#mermaid-svg-oSsf4ENcZdYTy5Py .doneCritText1,#mermaid-svg-oSsf4ENcZdYTy5Py .doneCritText2,#mermaid-svg-oSsf4ENcZdYTy5Py .doneCritText3{fill:#000 !important}#mermaid-svg-oSsf4ENcZdYTy5Py .activeCritText0,#mermaid-svg-oSsf4ENcZdYTy5Py .activeCritText1,#mermaid-svg-oSsf4ENcZdYTy5Py .activeCritText2,#mermaid-svg-oSsf4ENcZdYTy5Py .activeCritText3{fill:#000 !important}#mermaid-svg-oSsf4ENcZdYTy5Py .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-oSsf4ENcZdYTy5Py g.classGroup text .title{font-weight:bolder}#mermaid-svg-oSsf4ENcZdYTy5Py g.clickable{cursor:pointer}#mermaid-svg-oSsf4ENcZdYTy5Py g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-oSsf4ENcZdYTy5Py g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-oSsf4ENcZdYTy5Py .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-oSsf4ENcZdYTy5Py .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-oSsf4ENcZdYTy5Py .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-oSsf4ENcZdYTy5Py .dashed-line{stroke-dasharray:3}#mermaid-svg-oSsf4ENcZdYTy5Py #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-oSsf4ENcZdYTy5Py #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-oSsf4ENcZdYTy5Py #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-oSsf4ENcZdYTy5Py #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-oSsf4ENcZdYTy5Py #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-oSsf4ENcZdYTy5Py #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-oSsf4ENcZdYTy5Py #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-oSsf4ENcZdYTy5Py #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-oSsf4ENcZdYTy5Py .commit-id,#mermaid-svg-oSsf4ENcZdYTy5Py .commit-msg,#mermaid-svg-oSsf4ENcZdYTy5Py .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-oSsf4ENcZdYTy5Py g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-oSsf4ENcZdYTy5Py g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-oSsf4ENcZdYTy5Py g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-oSsf4ENcZdYTy5Py .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-oSsf4ENcZdYTy5Py .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-oSsf4ENcZdYTy5Py .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-oSsf4ENcZdYTy5Py .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-oSsf4ENcZdYTy5Py .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-oSsf4ENcZdYTy5Py .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-oSsf4ENcZdYTy5Py .edgeLabel text{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-oSsf4ENcZdYTy5Py .node circle.state-start{fill:black;stroke:black}#mermaid-svg-oSsf4ENcZdYTy5Py .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-oSsf4ENcZdYTy5Py #statediagram-barbEnd{fill:#9370db}#mermaid-svg-oSsf4ENcZdYTy5Py .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-oSsf4ENcZdYTy5Py .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-oSsf4ENcZdYTy5Py .statediagram-state .divider{stroke:#9370db}#mermaid-svg-oSsf4ENcZdYTy5Py .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-oSsf4ENcZdYTy5Py .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-oSsf4ENcZdYTy5Py .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-oSsf4ENcZdYTy5Py .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-oSsf4ENcZdYTy5Py .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-oSsf4ENcZdYTy5Py .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-oSsf4ENcZdYTy5Py .note-edge{stroke-dasharray:5}#mermaid-svg-oSsf4ENcZdYTy5Py .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-oSsf4ENcZdYTy5Py .error-icon{fill:#522}#mermaid-svg-oSsf4ENcZdYTy5Py .error-text{fill:#522;stroke:#522}#mermaid-svg-oSsf4ENcZdYTy5Py .edge-thickness-normal{stroke-width:2px}#mermaid-svg-oSsf4ENcZdYTy5Py .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-oSsf4ENcZdYTy5Py .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-oSsf4ENcZdYTy5Py .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-oSsf4ENcZdYTy5Py .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-oSsf4ENcZdYTy5Py .marker{fill:#333}#mermaid-svg-oSsf4ENcZdYTy5Py .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-oSsf4ENcZdYTy5Py {color: rgba(0, 0, 0, 0.75);font: ;}訪問開始認證授權準入控制PodServiceController

    RBAC簡介:基于角色的訪問控制

    • 角色:role(特定命名空間訪問權限)和ClusterRole(所有命名空間訪問權限)
    • 角色綁定:roleBinding(角色綁定到主體)和ClusterRoleBinding(集群角色綁定到主體)
    • 主體:user(用戶)、group(用戶組)、serviceAccount(服務賬號)

    RBAC實現鑒權:以下用實例的方式表述其過程(以下TLS文件是以二進制安裝方式環境為例)










    引入Ingress控制器:在使用Service里面的NodePort(把端口對外暴露,通過ip:port方式進行訪問)時,其存在如下缺陷:在每個節點上都會起到端口,在訪問時候通過任何檢點,通過節點ip:port實現訪問;意味著每個端口只能使用一次,一個端口對應一個應用。但是實際訪問中都是用域名,根據不同域名跳轉到不同服務,Ingress正是為了解決此問題而提出的解決方案,它使得pod和ingress通過service關聯,ingress作為統一入口由service關聯一組pod,其原理如下圖所示:

    使用ingress控制器:這里選擇官方維護的nginx控制器進行部署,其步驟大致分為部署ingress controller和創建ingress規則,以下過程是使用Ingress對外暴露應用

    • 創建nginx應用,對外暴露端口使用NodePort

    • 部署ingress controller

      apiVersion: v1 kind: Namespace metadata:name: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx---kind: ConfigMap apiVersion: v1 metadata:name: nginx-configurationnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx--- kind: ConfigMap apiVersion: v1 metadata:name: tcp-servicesnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx--- kind: ConfigMap apiVersion: v1 metadata:name: udp-servicesnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx--- apiVersion: v1 kind: ServiceAccount metadata:name: nginx-ingress-serviceaccountnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx--- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata:name: nginx-ingress-clusterrolelabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx rules:- apiGroups:- ""resources:- configmaps- endpoints- nodes- pods- secretsverbs:- list- watch- apiGroups:- ""resources:- nodesverbs:- get- apiGroups:- ""resources:- servicesverbs:- get- list- watch- apiGroups:- ""resources:- eventsverbs:- create- patch- apiGroups:- "extensions"- "networking.k8s.io"resources:- ingressesverbs:- get- list- watch- apiGroups:- "extensions"- "networking.k8s.io"resources:- ingresses/statusverbs:- update--- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata:name: nginx-ingress-rolenamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx rules:- apiGroups:- ""resources:- configmaps- pods- secrets- namespacesverbs:- get- apiGroups:- ""resources:- configmapsresourceNames:# Defaults to "<election-id>-<ingress-class>"# Here: "<ingress-controller-leader>-<nginx>"# This has to be adapted if you change either parameter# when launching the nginx-ingress-controller.- "ingress-controller-leader-nginx"verbs:- get- update- apiGroups:- ""resources:- configmapsverbs:- create- apiGroups:- ""resources:- endpointsverbs:- get--- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: RoleBinding metadata:name: nginx-ingress-role-nisa-bindingnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: nginx-ingress-role subjects:- kind: ServiceAccountname: nginx-ingress-serviceaccountnamespace: ingress-nginx--- apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata:name: nginx-ingress-clusterrole-nisa-bindinglabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: nginx-ingress-clusterrole subjects:- kind: ServiceAccountname: nginx-ingress-serviceaccountnamespace: ingress-nginx---apiVersion: apps/v1 kind: Deployment metadata:name: nginx-ingress-controllernamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx spec:replicas: 1selector:matchLabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxtemplate:metadata:labels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginxannotations:prometheus.io/port: "10254"prometheus.io/scrape: "true"spec:hostNetwork: true# wait up to five minutes for the drain of connectionsterminationGracePeriodSeconds: 300serviceAccountName: nginx-ingress-serviceaccountnodeSelector:kubernetes.io/os: linuxcontainers:- name: nginx-ingress-controllerimage: lizhenliang/nginx-ingress-controller:0.30.0args:- /nginx-ingress-controller- --configmap=$(POD_NAMESPACE)/nginx-configuration- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services- --udp-services-configmap=$(POD_NAMESPACE)/udp-services- --publish-service=$(POD_NAMESPACE)/ingress-nginx- --annotations-prefix=nginx.ingress.kubernetes.iosecurityContext:allowPrivilegeEscalation: truecapabilities:drop:- ALLadd:- NET_BIND_SERVICE# www-data -> 101runAsUser: 101env:- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespaceports:- name: httpcontainerPort: 80protocol: TCP- name: httpscontainerPort: 443protocol: TCPlivenessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPinitialDelaySeconds: 10periodSeconds: 10successThreshold: 1timeoutSeconds: 10readinessProbe:failureThreshold: 3httpGet:path: /healthzport: 10254scheme: HTTPperiodSeconds: 10successThreshold: 1timeoutSeconds: 10lifecycle:preStop:exec:command:- /wait-shutdown---apiVersion: v1 kind: LimitRange metadata:name: ingress-nginxnamespace: ingress-nginxlabels:app.kubernetes.io/name: ingress-nginxapp.kubernetes.io/part-of: ingress-nginx spec:limits:- min:memory: 90Micpu: 100mtype: Container
    • 創建ingress規則

      apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata:name: example-ingress spec:rules:- host: example.ingredemo.comhttp:paths:- path: /backend:serviceName: webservicePort: 80
    • 在windows系統hosts文件中添加域名訪問規則

    • 驗證

    helm引入:之前部署應用的基本過程都是編寫yaml文件、deployment、service最后ingress,該方式是和部署單一的、少數服務的應用,但是如果部署微服務項目,則可能有幾十個服務,每個服務都有一套yaml文件,此時需要維護大量yaml文件,版本管理特別不方便。Helm就是為解決此問題而產生的解決方案。helm是一個Kubernetes的包管理工具,就像Linux下的包管理器,如yum/apt等,可以很方便的將之前打包好的yaml文件部署到kubernetes上。使用helm可以把所有yaml作為一個整體管理,以實現yaml高效復用。helm有三個重要概念分別是helm(一個命令行客戶端工具)、chart(把yaml打包,是yaml集合)和release(基礎chart部署實體,應用級別的版本管理)。helm在2019年發布V3版本,和之前版本相比有明顯變化:V3版本中刪除Tiller、release可以在不同命名空間重用、將chart推送到dorcker倉庫中。

    helm安裝使用:主要包括helm安裝、配置helm倉庫、使用helm快速部署應用

    # 安裝helm [root@k8s-master ~]# tar -xzvf helm-v3.0.0-linux-amd64.tar.gz [root@k8s-master ~]# cd linux-amd64/ [root@k8s-master linux-amd64]# ls helm LICENSE README.md [root@k8s-master linux-amd64]# mv helm /usr/bin# 配置helm倉庫 # 添加存儲庫 [root@k8s-master linux-amd64]# helm repo add stable http://mirror.azure.cn/kubernetes/charts #微軟倉庫,這個倉庫推薦,基本 上官網有的 chart 這里都有 [root@k8s-master linux-amd64]# helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts #阿里云倉庫 # 更新倉庫源 [root@k8s-master linux-amd64]# helm repo update # 查看配置的存儲庫 [root@k8s-master linux-amd64]# helm repo list # 刪除倉庫 [root@k8s-master linux-amd64]# helm repo remove stable# 使用helm快速部署應用 # 使用命令搜索應用,格式:helm search repo 名稱 [root@k8s-master ~]# helm search repo weave NAME CHART VERSION APP VERSION DESCRIPTION aliyun/weave-cloud 0.1.2 Weave Cloud is a add-on to Kubernetes which pro... aliyun/weave-scope 0.9.2 1.6.5 A Helm chart for the Weave Scope cluster visual... # 根據搜索內容選擇安裝,格式:helm install 安裝之后名稱 搜索之后應用名稱 [root@k8s-master ~]# helm install ui aliyun/weave-scope # 查看安裝之后狀態 [root@k8s-master ~]# helm list [root@k8s-master ~]# helm status ui# 查應用狀態發現,ui-weave-scope其TYPE為ClusterIP [root@k8s-master ~]# kubectl get svc # 修改其TYPE [root@k8s-master ~]# kubectl edit svc ui-weave-scope ...type: NodePort ... # 查看修改后狀態發現,ui-weave-scope其TYPE為NodePort [root@k8s-master ~]# kubectl get svc

    自定義chart部署:過程見以下命令

    # 使用命令創建chart,格式為:helm create chart 名稱 [root@k8s-master ~]# helm create mychart Creating mychart [root@k8s-master ~]# cd mychart/ #Chart.yaml:當前chart屬性配置信息 #templates:編寫yaml文件放在這個目錄 #values.yaml:yaml文件可以使用全局變量 [root@k8s-master mychart]# ls charts Chart.yaml templates values.yaml# 在templates文件夾中創建兩個yaml文件deployment.yaml和service.yaml [root@k8s-master mychart]# cd templates/ [root@k8s-master templates]# ls deployment.yaml _helpers.tpl ingress.yaml NOTES.txt serviceaccount.yaml service.yaml tests [root@k8s-master templates]# rm -rf ./* [root@k8s-master templates]# kubectl create deployment web1 --image=nginx --dry-run -o yaml > deployment.yaml W0817 20:20:53.148698 15888 helpers.go:557] --dry-run is deprecated and can be replaced with --dry-run=client. [root@k8s-master templates]# ls deployment.yaml [root@k8s-master templates]# kubectl expose deployment web1 --port=80 --target-port=80 --type=NodePort --dry-run -o yaml > service.yaml W0817 20:24:22.445043 21372 helpers.go:557] --dry-run is deprecated and can be replaced with --dry-run=client. Error from server (NotFound): deployments.apps "web1" not found [root@k8s-master templates]# ls deployment.yaml service.yaml # 此時打開service.yaml發現為空 [root@k8s-master templates]# kubectl create deployment web1 --image=nginx deployment.apps/web1 created [root@k8s-master templates]# kubectl expose deployment web1 --port=80 --target-port=80 --type=NodePort --dry-run -o yaml > service.yaml # 此時service.yaml里面就有內容 # 刪掉web1,以helm方式部署 [root@k8s-master templates]# kubectl delete deployment web1 deployment.apps "web1" deleted# 安裝mychart [root@k8s-master ~]# helm install web1 mychart/ # 檢查 [root@k8s-master ~]# kubectl get pods [root@k8s-master ~]# kubectl get svc# 應用升級 [root@k8s-master ~]# helm upgrade web1 mychart/

    chart模板使用:chart模板可實現yaml高效復用,其方式是通過chart的values.yaml文件定義全局變量傳遞參數(在values.yaml定義變量和值,在具體yaml文件中獲取定義變量值),動態渲染模板,yaml內容動態傳入參數生成(在yaml文件中大體只有image、tag、label、port和replicas這幾個地方不同而已),其實現過程如下

    # 在values.yaml定義變量和值 [root@k8s-master ~]# cd mychart/ [root@k8s-master mychart]# ls charts Chart.yaml templates values.yaml [root@k8s-master mychart]# vim values.yaml ... replicas: 1 image: nginx tag: 1.16 label: nginx port: 80 ...# 在templates的yaml文件使用values.yaml定義變量 # 通過表達式使用全局變量,其格式為:{{.Values.變量名稱}} # 也常用{{.Release.Name}}避免生成隨機名稱 [root@k8s-master mychart]# cd templates/ [root@k8s-master templates]# vim deployment.yaml apiVersion: apps/v1 kind: Deployment metadata:name: {{ .Release.Name}}-deploy spec:replicas: 1selector:matchLabels:app: {{ .Values.label}}strategy: {}template:metadata:creationTimestamp: nulllabels:app: {{ .Values.label}}spec:containers:- image: {{ .Values.image}}name: nginxresources: {} status: {} [root@k8s-master templates]# vim deployment.yaml apiVersion: v1 kind: Service metadata:name: {{ .Release.Name}}-svc spec:ports:- port: {{ .Values.port}}protocol: TCPtargetPort: 80selector:app: {{ .Values.label}}type: NodePort status:loadBalancer: {} [root@k8s-master ~]# helm install --dry-run web2 mychart/ #檢查 [root@k8s-master ~]# kubectl get pods [root@k8s-master ~]# kubectl get svc

    持久化存儲:數據卷emptydir是本地存儲,pod重啟后數據會丟失,為了解決這一問題就需要對數據進行持久化存儲。實現這一方案,k8s使用nfs網絡存儲實現pod重啟數據還在,以下是實現過程

    # 1. 準備環境:創建一臺服務器安裝nfs服務端(筆者這里ip設置為172.16.90.134)并關閉防火墻 [root@90143-k8s-nfs ~]# systemctl disable --now firewalld Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service. Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service. [root@90143-k8s-nfs ~]# firewall-cmd --list-all FirewallD is not running # 2. 安裝nfs [root@90143-k8s-nfs ~]# yum install -y nfs-utils # 3. 創建掛載路徑 [root@90143-k8s-nfs ~]# mkdir -p /data/nfs # 4. 設置掛載路徑 [root@90143-k8s-nfs ~]# vim /etc/exports /data/nfs *(rw,no_root_squash) # 5. 在k8s的node節點安裝nfs [root@k8s-node1 ~]# yum install -y nfs-utils [root@k8s-node2 ~]# yum install -y nfs-utils # 6. 在nfs服務器中啟動服務 [root@90143-k8s-nfs ~]# systemctl start nfs [root@90143-k8s-nfs ~]# ps -ef | grep nfs avahi 5936 1 0 14:52 ? 00:00:00 avahi-daemon: running [90143-k8s-nfs.local] root 27593 2 0 15:10 ? 00:00:00 [nfsd4_callbacks] root 27599 2 0 15:10 ? 00:00:00 [nfsd] root 27600 2 0 15:10 ? 00:00:00 [nfsd] root 27601 2 0 15:10 ? 00:00:00 [nfsd] root 27602 2 0 15:10 ? 00:00:00 [nfsd] root 27603 2 0 15:10 ? 00:00:00 [nfsd] root 27604 2 0 15:10 ? 00:00:00 [nfsd] root 27605 2 0 15:10 ? 00:00:00 [nfsd] root 27606 2 0 15:10 ? 00:00:00 [nfsd] root 28030 7550 0 15:10 pts/0 00:00:00 grep --color=auto nfs # 7. 在k8s集群部署應該用使用nfs持久網絡存儲 [root@k8s-master ~]# mkdir pv [root@k8s-master ~]# vim pv/nfs-nginx.yaml apiVersion: apps/v1 kind: Deployment metadata:name: nginx-dep1 spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxvolumeMounts:- name: wwwrootmountPath: /usr/share/nginx/htmlports:- containerPort: 80volumes:- name: wwwrootnfs:server: 172.16.90.143path: /data/nfs [root@k8s-master ~]# cd pv [root@k8s-master pv]# kubectl apply -f nfs-nginx.yaml deployment.apps/nginx-dep1 created [root@k8s-master pv]# kubectl describe pod nginx-dep1-776574d4d-hg647 [root@k8s-master pv]# kubectl exec -it nginx-dep1-776574d4d-mdtcd bash kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. root@nginx-dep1-776574d4d-mdtcd:/# ls /usr/share/nginx/html [root@90143-k8s-nfs ~]# cd /data/nfs/ hello nfs root@nginx-dep1-776574d4d-mdtcd:/# ls /usr/share/nginx/html index.html root@nginx-dep1-776574d4d-mdtcd:/# exit exit # 8. 驗證,通過NodeIP:Port可瀏覽器查看 [root@k8s-master pv]# kubectl expose deployment nginx-dep1 --port=80 --target-port=80 --type=NodePort service/nginx-dep1 exposed [root@k8s-master pv]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 22d nginx NodePort 10.105.227.129 <none> 80:30640/TCP 22d nginx-dep1 NodePort 10.96.151.113 <none> 80:31987/TCP 12s web1 NodePort 10.101.103.2 <none> 80:31093/TCP 2d5h

    PV與PVC:PV(持久化存儲,對存儲資源進行抽象,對外提供可以調用的地方,本質是生產者)與PVC(用于調用,不需要關心內部實現細節,本質是消費者)其實現流程如下圖所示:

    #mermaid-svg-Gt1zp0CZe0Bw8wuX .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .label text{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .node rect,#mermaid-svg-Gt1zp0CZe0Bw8wuX .node circle,#mermaid-svg-Gt1zp0CZe0Bw8wuX .node ellipse,#mermaid-svg-Gt1zp0CZe0Bw8wuX .node polygon,#mermaid-svg-Gt1zp0CZe0Bw8wuX .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .node .label{text-align:center;fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .node.clickable{cursor:pointer}#mermaid-svg-Gt1zp0CZe0Bw8wuX .arrowheadPath{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .flowchart-link{stroke:#333;fill:none}#mermaid-svg-Gt1zp0CZe0Bw8wuX .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-Gt1zp0CZe0Bw8wuX .edgeLabel rect{opacity:0.9}#mermaid-svg-Gt1zp0CZe0Bw8wuX .edgeLabel span{color:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .cluster text{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-Gt1zp0CZe0Bw8wuX .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-Gt1zp0CZe0Bw8wuX text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-Gt1zp0CZe0Bw8wuX .actor-line{stroke:grey}#mermaid-svg-Gt1zp0CZe0Bw8wuX .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .sequenceNumber{fill:#fff}#mermaid-svg-Gt1zp0CZe0Bw8wuX #sequencenumber{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX #crosshead path{fill:#333;stroke:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .messageText{fill:#333;stroke:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-Gt1zp0CZe0Bw8wuX .labelText,#mermaid-svg-Gt1zp0CZe0Bw8wuX .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-Gt1zp0CZe0Bw8wuX .loopText,#mermaid-svg-Gt1zp0CZe0Bw8wuX .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-Gt1zp0CZe0Bw8wuX .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-Gt1zp0CZe0Bw8wuX .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-Gt1zp0CZe0Bw8wuX .noteText,#mermaid-svg-Gt1zp0CZe0Bw8wuX .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-Gt1zp0CZe0Bw8wuX .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-Gt1zp0CZe0Bw8wuX .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-Gt1zp0CZe0Bw8wuX .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-Gt1zp0CZe0Bw8wuX .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX .section{stroke:none;opacity:0.2}#mermaid-svg-Gt1zp0CZe0Bw8wuX .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-Gt1zp0CZe0Bw8wuX .section2{fill:#fff400}#mermaid-svg-Gt1zp0CZe0Bw8wuX .section1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .section3{fill:#fff;opacity:0.2}#mermaid-svg-Gt1zp0CZe0Bw8wuX .sectionTitle0{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .sectionTitle1{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .sectionTitle2{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .sectionTitle3{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-Gt1zp0CZe0Bw8wuX .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX .grid path{stroke-width:0}#mermaid-svg-Gt1zp0CZe0Bw8wuX .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .task{stroke-width:2}#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskText:not([font-size]){font-size:11px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .task.clickable{cursor:pointer}#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskText0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskText1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskText2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskText3{fill:#fff}#mermaid-svg-Gt1zp0CZe0Bw8wuX .task0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .task1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .task2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskTextOutside0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskTextOutside2{fill:#000}#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskTextOutside1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .taskTextOutside3{fill:#000}#mermaid-svg-Gt1zp0CZe0Bw8wuX .active0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .active1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .active2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeText0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeText1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeText2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeText3{fill:#000 !important}#mermaid-svg-Gt1zp0CZe0Bw8wuX .done0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .done1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .done2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneText0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneText1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneText2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneText3{fill:#000 !important}#mermaid-svg-Gt1zp0CZe0Bw8wuX .crit0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .crit1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .crit2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeCrit0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeCrit1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeCrit2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneCrit0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneCrit1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneCrit2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-Gt1zp0CZe0Bw8wuX .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-Gt1zp0CZe0Bw8wuX .milestoneText{font-style:italic}#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneCritText0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneCritText1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneCritText2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .doneCritText3{fill:#000 !important}#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeCritText0,#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeCritText1,#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeCritText2,#mermaid-svg-Gt1zp0CZe0Bw8wuX .activeCritText3{fill:#000 !important}#mermaid-svg-Gt1zp0CZe0Bw8wuX .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.classGroup text .title{font-weight:bolder}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.clickable{cursor:pointer}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-Gt1zp0CZe0Bw8wuX .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-Gt1zp0CZe0Bw8wuX .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-Gt1zp0CZe0Bw8wuX .dashed-line{stroke-dasharray:3}#mermaid-svg-Gt1zp0CZe0Bw8wuX #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Gt1zp0CZe0Bw8wuX #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Gt1zp0CZe0Bw8wuX #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-Gt1zp0CZe0Bw8wuX #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-Gt1zp0CZe0Bw8wuX #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Gt1zp0CZe0Bw8wuX #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Gt1zp0CZe0Bw8wuX #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Gt1zp0CZe0Bw8wuX #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-Gt1zp0CZe0Bw8wuX .commit-id,#mermaid-svg-Gt1zp0CZe0Bw8wuX .commit-msg,#mermaid-svg-Gt1zp0CZe0Bw8wuX .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-Gt1zp0CZe0Bw8wuX g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-Gt1zp0CZe0Bw8wuX .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-Gt1zp0CZe0Bw8wuX .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-Gt1zp0CZe0Bw8wuX .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-Gt1zp0CZe0Bw8wuX .edgeLabel text{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-Gt1zp0CZe0Bw8wuX .node circle.state-start{fill:black;stroke:black}#mermaid-svg-Gt1zp0CZe0Bw8wuX .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-Gt1zp0CZe0Bw8wuX #statediagram-barbEnd{fill:#9370db}#mermaid-svg-Gt1zp0CZe0Bw8wuX .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .statediagram-state .divider{stroke:#9370db}#mermaid-svg-Gt1zp0CZe0Bw8wuX .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-Gt1zp0CZe0Bw8wuX .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-Gt1zp0CZe0Bw8wuX .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-Gt1zp0CZe0Bw8wuX .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-Gt1zp0CZe0Bw8wuX .note-edge{stroke-dasharray:5}#mermaid-svg-Gt1zp0CZe0Bw8wuX .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-Gt1zp0CZe0Bw8wuX .error-icon{fill:#522}#mermaid-svg-Gt1zp0CZe0Bw8wuX .error-text{fill:#522;stroke:#522}#mermaid-svg-Gt1zp0CZe0Bw8wuX .edge-thickness-normal{stroke-width:2px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-Gt1zp0CZe0Bw8wuX .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-Gt1zp0CZe0Bw8wuX .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-Gt1zp0CZe0Bw8wuX .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-Gt1zp0CZe0Bw8wuX .marker{fill:#333}#mermaid-svg-Gt1zp0CZe0Bw8wuX .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-Gt1zp0CZe0Bw8wuX {color: rgba(0, 0, 0, 0.75);font: ;}根據存儲容量匹配模式應用部署定義pvc:綁定pv定義pv:包括ip和路徑 # 避免影響刪除nfs-nginx.yaml [root@k8s-master pv]# kubectl delete -f nfs-nginx.yaml deployment.apps "nginx-dep1" deleted [root@k8s-master pv]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-6799fc88d8-lj24f 1/1 Running 0 22d web-7866dfdb9f-7zg68 0/1 ImagePullBackOff 0 2d5h web-96d5df5c8-br8md 1/1 Running 0 2d5h # 定義pvc [root@k8s-master pv]# vim pvc.yaml apiVersion: apps/v1 kind: Deployment metadata:name: nginx-dep1 spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxvolumeMounts:- name: wwwrootmountPath: /usr/share/nginx/htmlports:- containerPort: 80volumes:- name: wwwrootpersistentVolumeClaim:claimName: my-pvc---apiVersion: v1 kind: PersistentVolumeClaim metadata:name: my-pvc spec:accessModes:- ReadWriteManyresources:requests:storage: 5Gi [root@k8s-master pv]# kubectl apply -f pvc.yaml deployment.apps/nginx-dep1 created persistentvolumeclaim/my-pvc created [root@k8s-master pv]# vim pv.yaml apiVersion: v1 kind: PersistentVolume metadata:name: my-pv spec:capacity:storage: 5GiaccessModes:- ReadWriteManynfs:path: /data/nfsserver: 172.16.90.143 [root@k8s-master pv]# kubectl apply -f pv.yaml persistentvolume/my-pv created #檢查 [root@k8s-master pv]# kubectl get pv,pvc NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/my-pv 5Gi RWX Retain Bound default/my-pvc 43sNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/my-pvc Bound my-pv 5Gi RWX 3m13s [root@k8s-master pv]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-6799fc88d8-lj24f 1/1 Running 0 22d nginx-dep1-69f5bb95b-bwn2g 1/1 Running 0 4m11s nginx-dep1-69f5bb95b-gpn9f 1/1 Running 0 4m11s nginx-dep1-69f5bb95b-k9xhw 1/1 Running 0 4m11s web-7866dfdb9f-7zg68 0/1 ImagePullBackOff 0 2d5h web-96d5df5c8-br8md 1/1 Running 0 2d5h [root@k8s-master pv]# kubectl exec -it nginx-dep1-69f5bb95b-bwn2g bash kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. root@nginx-dep1-69f5bb95b-bwn2g:/# ls /usr/share/nginx/html/ index.html

    5. 日志管理


    6. 監控平臺

    集群資源監控:包括監控指標和監控平臺,其中

    • 監控指標
      • 集群監控:節點資源利用率、節點數、運行pods
      • Pod監控:容器指標、應用程序
    • 監控平臺搭建方案(prometheus+Grafana)
      • prometheus:開源的;監控、報警、數據庫;以HTTP協議周期性抓取被監控組件狀態;不需要復雜的集成過程,使用http接口接入就可以
      • Grafana:開源的數據分析和可視化工具;支持多種數據源
    #mermaid-svg-V2HeoPRqH6VcMr35 .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .label text{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .node rect,#mermaid-svg-V2HeoPRqH6VcMr35 .node circle,#mermaid-svg-V2HeoPRqH6VcMr35 .node ellipse,#mermaid-svg-V2HeoPRqH6VcMr35 .node polygon,#mermaid-svg-V2HeoPRqH6VcMr35 .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-V2HeoPRqH6VcMr35 .node .label{text-align:center;fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .node.clickable{cursor:pointer}#mermaid-svg-V2HeoPRqH6VcMr35 .arrowheadPath{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-V2HeoPRqH6VcMr35 .flowchart-link{stroke:#333;fill:none}#mermaid-svg-V2HeoPRqH6VcMr35 .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-V2HeoPRqH6VcMr35 .edgeLabel rect{opacity:0.9}#mermaid-svg-V2HeoPRqH6VcMr35 .edgeLabel span{color:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-V2HeoPRqH6VcMr35 .cluster text{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-V2HeoPRqH6VcMr35 .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-V2HeoPRqH6VcMr35 text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-V2HeoPRqH6VcMr35 .actor-line{stroke:grey}#mermaid-svg-V2HeoPRqH6VcMr35 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-V2HeoPRqH6VcMr35 #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .sequenceNumber{fill:#fff}#mermaid-svg-V2HeoPRqH6VcMr35 #sequencenumber{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 #crosshead path{fill:#333;stroke:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .messageText{fill:#333;stroke:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-V2HeoPRqH6VcMr35 .labelText,#mermaid-svg-V2HeoPRqH6VcMr35 .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-V2HeoPRqH6VcMr35 .loopText,#mermaid-svg-V2HeoPRqH6VcMr35 .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-V2HeoPRqH6VcMr35 .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-V2HeoPRqH6VcMr35 .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-V2HeoPRqH6VcMr35 .noteText,#mermaid-svg-V2HeoPRqH6VcMr35 .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-V2HeoPRqH6VcMr35 .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-V2HeoPRqH6VcMr35 .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-V2HeoPRqH6VcMr35 .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-V2HeoPRqH6VcMr35 .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 .section{stroke:none;opacity:0.2}#mermaid-svg-V2HeoPRqH6VcMr35 .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-V2HeoPRqH6VcMr35 .section2{fill:#fff400}#mermaid-svg-V2HeoPRqH6VcMr35 .section1,#mermaid-svg-V2HeoPRqH6VcMr35 .section3{fill:#fff;opacity:0.2}#mermaid-svg-V2HeoPRqH6VcMr35 .sectionTitle0{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .sectionTitle1{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .sectionTitle2{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .sectionTitle3{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-V2HeoPRqH6VcMr35 .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 .grid path{stroke-width:0}#mermaid-svg-V2HeoPRqH6VcMr35 .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-V2HeoPRqH6VcMr35 .task{stroke-width:2}#mermaid-svg-V2HeoPRqH6VcMr35 .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 .taskText:not([font-size]){font-size:11px}#mermaid-svg-V2HeoPRqH6VcMr35 .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-V2HeoPRqH6VcMr35 .task.clickable{cursor:pointer}#mermaid-svg-V2HeoPRqH6VcMr35 .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-V2HeoPRqH6VcMr35 .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-V2HeoPRqH6VcMr35 .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-V2HeoPRqH6VcMr35 .taskText0,#mermaid-svg-V2HeoPRqH6VcMr35 .taskText1,#mermaid-svg-V2HeoPRqH6VcMr35 .taskText2,#mermaid-svg-V2HeoPRqH6VcMr35 .taskText3{fill:#fff}#mermaid-svg-V2HeoPRqH6VcMr35 .task0,#mermaid-svg-V2HeoPRqH6VcMr35 .task1,#mermaid-svg-V2HeoPRqH6VcMr35 .task2,#mermaid-svg-V2HeoPRqH6VcMr35 .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-V2HeoPRqH6VcMr35 .taskTextOutside0,#mermaid-svg-V2HeoPRqH6VcMr35 .taskTextOutside2{fill:#000}#mermaid-svg-V2HeoPRqH6VcMr35 .taskTextOutside1,#mermaid-svg-V2HeoPRqH6VcMr35 .taskTextOutside3{fill:#000}#mermaid-svg-V2HeoPRqH6VcMr35 .active0,#mermaid-svg-V2HeoPRqH6VcMr35 .active1,#mermaid-svg-V2HeoPRqH6VcMr35 .active2,#mermaid-svg-V2HeoPRqH6VcMr35 .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-V2HeoPRqH6VcMr35 .activeText0,#mermaid-svg-V2HeoPRqH6VcMr35 .activeText1,#mermaid-svg-V2HeoPRqH6VcMr35 .activeText2,#mermaid-svg-V2HeoPRqH6VcMr35 .activeText3{fill:#000 !important}#mermaid-svg-V2HeoPRqH6VcMr35 .done0,#mermaid-svg-V2HeoPRqH6VcMr35 .done1,#mermaid-svg-V2HeoPRqH6VcMr35 .done2,#mermaid-svg-V2HeoPRqH6VcMr35 .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-V2HeoPRqH6VcMr35 .doneText0,#mermaid-svg-V2HeoPRqH6VcMr35 .doneText1,#mermaid-svg-V2HeoPRqH6VcMr35 .doneText2,#mermaid-svg-V2HeoPRqH6VcMr35 .doneText3{fill:#000 !important}#mermaid-svg-V2HeoPRqH6VcMr35 .crit0,#mermaid-svg-V2HeoPRqH6VcMr35 .crit1,#mermaid-svg-V2HeoPRqH6VcMr35 .crit2,#mermaid-svg-V2HeoPRqH6VcMr35 .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-V2HeoPRqH6VcMr35 .activeCrit0,#mermaid-svg-V2HeoPRqH6VcMr35 .activeCrit1,#mermaid-svg-V2HeoPRqH6VcMr35 .activeCrit2,#mermaid-svg-V2HeoPRqH6VcMr35 .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-V2HeoPRqH6VcMr35 .doneCrit0,#mermaid-svg-V2HeoPRqH6VcMr35 .doneCrit1,#mermaid-svg-V2HeoPRqH6VcMr35 .doneCrit2,#mermaid-svg-V2HeoPRqH6VcMr35 .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-V2HeoPRqH6VcMr35 .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-V2HeoPRqH6VcMr35 .milestoneText{font-style:italic}#mermaid-svg-V2HeoPRqH6VcMr35 .doneCritText0,#mermaid-svg-V2HeoPRqH6VcMr35 .doneCritText1,#mermaid-svg-V2HeoPRqH6VcMr35 .doneCritText2,#mermaid-svg-V2HeoPRqH6VcMr35 .doneCritText3{fill:#000 !important}#mermaid-svg-V2HeoPRqH6VcMr35 .activeCritText0,#mermaid-svg-V2HeoPRqH6VcMr35 .activeCritText1,#mermaid-svg-V2HeoPRqH6VcMr35 .activeCritText2,#mermaid-svg-V2HeoPRqH6VcMr35 .activeCritText3{fill:#000 !important}#mermaid-svg-V2HeoPRqH6VcMr35 .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-V2HeoPRqH6VcMr35 g.classGroup text .title{font-weight:bolder}#mermaid-svg-V2HeoPRqH6VcMr35 g.clickable{cursor:pointer}#mermaid-svg-V2HeoPRqH6VcMr35 g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-V2HeoPRqH6VcMr35 g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-V2HeoPRqH6VcMr35 .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-V2HeoPRqH6VcMr35 .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-V2HeoPRqH6VcMr35 .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-V2HeoPRqH6VcMr35 .dashed-line{stroke-dasharray:3}#mermaid-svg-V2HeoPRqH6VcMr35 #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-V2HeoPRqH6VcMr35 #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-V2HeoPRqH6VcMr35 #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-V2HeoPRqH6VcMr35 #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-V2HeoPRqH6VcMr35 #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-V2HeoPRqH6VcMr35 #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-V2HeoPRqH6VcMr35 #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-V2HeoPRqH6VcMr35 #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-V2HeoPRqH6VcMr35 .commit-id,#mermaid-svg-V2HeoPRqH6VcMr35 .commit-msg,#mermaid-svg-V2HeoPRqH6VcMr35 .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-V2HeoPRqH6VcMr35 g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-V2HeoPRqH6VcMr35 g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-V2HeoPRqH6VcMr35 g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-V2HeoPRqH6VcMr35 .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-V2HeoPRqH6VcMr35 .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-V2HeoPRqH6VcMr35 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-V2HeoPRqH6VcMr35 .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-V2HeoPRqH6VcMr35 .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-V2HeoPRqH6VcMr35 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-V2HeoPRqH6VcMr35 .edgeLabel text{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-V2HeoPRqH6VcMr35 .node circle.state-start{fill:black;stroke:black}#mermaid-svg-V2HeoPRqH6VcMr35 .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-V2HeoPRqH6VcMr35 #statediagram-barbEnd{fill:#9370db}#mermaid-svg-V2HeoPRqH6VcMr35 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-V2HeoPRqH6VcMr35 .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-V2HeoPRqH6VcMr35 .statediagram-state .divider{stroke:#9370db}#mermaid-svg-V2HeoPRqH6VcMr35 .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-V2HeoPRqH6VcMr35 .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-V2HeoPRqH6VcMr35 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-V2HeoPRqH6VcMr35 .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-V2HeoPRqH6VcMr35 .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-V2HeoPRqH6VcMr35 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-V2HeoPRqH6VcMr35 .note-edge{stroke-dasharray:5}#mermaid-svg-V2HeoPRqH6VcMr35 .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-V2HeoPRqH6VcMr35 .error-icon{fill:#522}#mermaid-svg-V2HeoPRqH6VcMr35 .error-text{fill:#522;stroke:#522}#mermaid-svg-V2HeoPRqH6VcMr35 .edge-thickness-normal{stroke-width:2px}#mermaid-svg-V2HeoPRqH6VcMr35 .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-V2HeoPRqH6VcMr35 .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-V2HeoPRqH6VcMr35 .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-V2HeoPRqH6VcMr35 .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-V2HeoPRqH6VcMr35 .marker{fill:#333}#mermaid-svg-V2HeoPRqH6VcMr35 .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-V2HeoPRqH6VcMr35 {color: rgba(0, 0, 0, 0.75);font: ;}被抓取被抓取node1prometheusnode2Grafana

    搭建過程:相關yaml文件地址(驗證碼:mzzv)

    • 啟動Prometheus和Grafana[root@k8s-master ~]# mkdir pgmonitor [root@k8s-master ~]# cd pgmonitor/ # 將yaml文件上傳到 [root@k8s-master pgmonitor]# ls grafana node-exporter.yaml prometheus[root@k8s-master pgmonitor]# vim node-exporter.yaml --- apiVersion: apps/v1 kind: DaemonSet metadata:name: node-exporternamespace: kube-systemlabels:k8s-app: node-exporter spec:selector:matchLabels:k8s-app: node-exporter ... # 部署守護進程 [root@k8s-master pgmonitor]# kubectl create -f node-exporter.yaml # 部署prometheus [root@k8s-master prometheus]# kubectl create -f rbac-setup.yaml [root@k8s-master prometheus]# kubectl create -f configmap.yaml [root@k8s-master prometheus]# vim prometheus.deploy.yml --- apiVersion: apps/v1 ... [root@k8s-master prometheus]# kubectl create -f prometheus.deploy.yml [root@k8s-master prometheus]# kubectl create -f prometheus.svc.yml # 檢查 [root@k8s-master prometheus]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE coredns-59d64cd4d4-dqx8m 1/1 Running 0 23d coredns-59d64cd4d4-z8pdq 1/1 Running 0 23d etcd-k8s-master 1/1 Running 0 23d kube-apiserver-k8s-master 1/1 Running 0 23d kube-controller-manager-k8s-master 1/1 Running 0 23d kube-flannel-ds-h7v2g 1/1 Running 0 23d kube-flannel-ds-xmzfh 1/1 Running 0 23d kube-flannel-ds-z9nbj 1/1 Running 0 23d kube-proxy-6c9cd 1/1 Running 0 23d kube-proxy-cnvfg 1/1 Running 0 23d kube-proxy-p4nx4 1/1 Running 0 23d kube-scheduler-k8s-master 1/1 Running 0 23d node-exporter-g68xs 1/1 Running 0 7m57s node-exporter-rk2rg 1/1 Running 0 7m57s prometheus-68546b8d9-xk7tx 1/1 Running 0 116s# 部署Grafana [root@k8s-master pgmonitor]# cd grafana/ [root@k8s-master grafana]# vim grafana-deploy.yaml apiVersion: apps/v1 kind: Deployment metadata:name: grafana-corenamespace: kube-systemlabels:app: grafanacomponent: core spec:replicas: 1selector:matchLabels:app: grafanacomponent: core ... [root@k8s-master grafana]# kubectl create -f grafana-deploy.yaml [root@k8s-master grafana]# kubectl create -f grafana-svc.yaml [root@k8s-master grafana]# kubectl create -f grafana-ing.yaml # 檢查 [root@k8s-master grafana]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE coredns-59d64cd4d4-dqx8m 1/1 Running 0 23d coredns-59d64cd4d4-z8pdq 1/1 Running 0 23d etcd-k8s-master 1/1 Running 0 23d grafana-core-85587c9c49-khvnk 1/1 Running 0 83s kube-apiserver-k8s-master 1/1 Running 0 23d kube-controller-manager-k8s-master 1/1 Running 0 23d kube-flannel-ds-h7v2g 1/1 Running 0 23d kube-flannel-ds-xmzfh 1/1 Running 0 23d kube-flannel-ds-z9nbj 1/1 Running 0 23d kube-proxy-6c9cd 1/1 Running 0 23d kube-proxy-cnvfg 1/1 Running 0 23d kube-proxy-p4nx4 1/1 Running 0 23d kube-scheduler-k8s-master 1/1 Running 0 23d node-exporter-g68xs 1/1 Running 0 17m node-exporter-rk2rg 1/1 Running 0 17m prometheus-68546b8d9-xk7tx 1/1 Running 0 11m# 查看打開的端口號 [root@k8s-master grafana]# kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana NodePort 10.111.191.90 <none> 3000:31708/TCP 4m32s kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 23d node-exporter NodePort 10.97.61.70 <none> 9100:31672/TCP 20m prometheus NodePort 10.111.182.252 <none> 9090:30003/TCP 14m [root@k8s-master grafana]# kubectl get svc -n kube-system -o wide
    • 打開Grafana,配置數據源,導入顯示模板,默認用戶名密碼都是admin。最后配置prometheus數據源







    7. 搭建高可用集群




    步驟文檔地址:驗證碼0x23


    8. 集群項目部署實操



    k8s集群部署java項目:以下將以java項目(驗證碼c78o)為例實現這一流程

  • 準備Java項目

  • 通過maven進行打包

    [root@15-package demo]# ls demojenkins [root@15-package demo]# cd demojenkins [root@15-package demojenkins]# mvn clean package [root@15-package demojenkins]# ls demojenkins.iml Dockerfile HELP.md mvnw mvnw.cmd pom.xml src target [root@15-package demojenkins]# cd target/ [root@15-package target]# ls classes demojenkins.jar demojenkins.jar.original generated-sources generated-test-sources maven-archiver maven-status surefire-reports test-classes
  • 制作鏡像

    [root@15-package demojenkins]# ls demojenkins.iml Dockerfile HELP.md mvnw mvnw.cmd pom.xml src target [root@15-package demojenkins]# docker build -t java-demo-01:latest . [root@15-package demojenkins]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE java-demo-01 latest 3563dd6e175a 3 minutes ago 122MB openjdk 8-jdk-alpine a3562aa0b991 2 years ago 105MB# 簡單測試鏡像 [root@62-cent demojenkins]# docker run -d -p 8111:8111 java-demo-01:latest -t

  • 上傳鏡像到鏡像服務器中(以阿里云為例)


    # 登錄阿里云倉庫 [root@62-cent demojenkins]# docker login --username=xxxx registry.cn-hangzhou.aliyuncs.com # 為鏡像添加版本號 [root@62-cent demojenkins]# docker tag 3563dd6e175a registry.cn-hangzhou.aliyuncs.com/my_demo_space/java-project-01:1.0.0 # 實現推送 [root@62-cent demojenkins]# docker push registry.cn-hangzhou.aliyuncs.com/my_demo_space/java-project-01:1.0.0

  • 部署鏡像暴露應用

    # 導出yaml [root@k8s-master ~]# kubectl create deployment javademo1 --image=registry.cn-hangzhou.aliyuncs.com/my_demo_space/java-project-01:1.0.0 --dry-run -o yaml > javademo1.yaml # 創建yaml [root@k8s-master ~]# kubectl apply -f javademo1.yaml deployment.apps/javademo1 created # 查看創建情況 [root@k8s-master ~]# kubectl get pods # 擴容 [root@k8s-master ~]# kubectl scale deployment javademo1 --replicas=3 # 暴露端口 [root@k8s-master ~]# kubectl expose deployment javademo1 --port=8111 --target-port=8111 --type=NodePort#通過NodeIp:port訪問即可
  • 總結

    以上是生活随笔為你收集整理的【体系】Kubernetes容器管理的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。