《云原生入門級開發者認證》學習筆記之云原生基礎設施K8s(三) 【與云原生的故事】

      網友投稿 848 2025-03-31

      寫在前面

      嗯,報了考試,整理課堂筆記記憶

      學習的原因:

      雖然考了CKA,了解了一些K8s相關的知識

      但是對云原生整個體系一直都很模糊

      希望對云原生有一個基本的認識

      通過學習實現云原生相關入門

      寫在前面

      嗯,報了考試,整理課堂筆記記憶

      學習的原因:

      雖然考了CKA,了解了一些K8s相關的知識

      但是對云原生整個體系一直都很模糊

      希望對云原生有一個基本的認識

      通過學習實現云原生相關入門

      雖然考了CKA,了解了一些K8s相關的知識

      但是對云原生整個體系一直都很模糊

      希望對云原生有一個基本的認識

      通過學習實現云原生相關入門

      博文主要內容涉及:

      關于云原生基礎設施的簡述,主要為K8s,適合溫習,初學

      都是理論,很淺,對K8s做一個整體的簡介

      關于云原生基礎設施的簡述,主要為K8s,適合溫習,初學

      都是理論,很淺,對K8s做一個整體的簡介

      【與云原生的故事】有獎征文火熱進行中:https://bbs.huaweicloud.com/blogs/345260

      「 傍晚時分,你坐在屋檐下,看著天慢慢地黑下去,心里寂寞而凄涼,感到自己的生命被剝奪了。當時我是個年輕人,但我害怕這樣生活下去,衰老下去。在我看來,這是比死亡更可怕的事。--------王小波」

      云原生基礎設施

      容器集群管理概述

      容器(如Docker)以及周邊生態系統提供了很多工具來實現容器生命周期管理,能夠滿足在單臺宿主機管理容器的需求。但越來越多企業開始使用容器,對容器技術的進一步發展提出了以下新的訴求:·

      高效的容器管理及編排。

      容器的跨主機部署及調度。

      容器的存儲、網絡、運維、安全等能力的拓展。

      容器編排技術可實現跨主機集群的容器調度,并管理各種不同的底層容器。k8s通過管理底層的容器節點,自動化應用容器的部署、擴展和操作,提供以容器為中心的基礎架構。

      容器編排是指自動化容器的部署、管理、擴展和聯網

      容器編排管理平臺用于管理云平臺中多個主機上的容器化應用,其目標是讓部署容器化的應用簡單并且高效。

      容器編排管理平臺用于管理云平臺中多個主機上的容器化應用,其目標是讓部署容器化的應用簡單并且高效。

      容器編排平臺提供了應用部署、規劃、更新、維護的一種機制。

      容器編排平臺提供了應用部署、規劃、更新、維護的一種機制。

      對應用開發者而言,容器編排平臺是一個集群操作系統,提供服務發現、伸縮、負載均衡、自愈甚至選舉等功能,讓開發者從基礎設施相關配置等解脫出來。

      對應用開發者而言,容器編排平臺是一個集群操作系統,提供服務發現、伸縮、負載均衡、自愈甚至選舉等功能,讓開發者從基礎設施相關配置等解脫出來。

      Kubernetes起源于Google內部的Borg項目,它對計算資源進行了更高層次的抽象,通過將容器進行細致的組合,將最終的應用服務交給用戶。它的目標是管理大規模的容器,提供基本的部署、維護以及應用伸縮等功能,其主要實現語言為Go語言。

      Kubernetes作為容器集群管理工具,于2015年7月22日迭代到v1.0并正式對外公布。與此同時,谷歌聯合Linux基金會及其他合作伙伴共同成立了CNCF基金會(Cloud Native Computing Foundation),并將Kuberentes作為首個編入CNCF管理體系的開源項目,助力容器技術生態的發展進步。

      在整個容器編排生態中,過去多國混戰,包括:mesos+Marathon、docker swarm、kubernetes等等。

      Kubernetes架構與核心概念

      一個基礎的Kubernetes集群(Cluster)通常包含一個Master節點和多個Node節點。每個節點可以是一臺物理機,也可以是一臺虛擬機。

      Master節點是集群的控制節點,由API Server、Scheduler、Controller Manager和ETCD四個組件構成。

      Kube-apiserver:kube-apiserver對外暴露了KubernetesAPl。它是的Kubernetes前端控制層。被設計為水平擴展架構,即通過部署更多實例來承載業務。各組件互相通訊的中轉站,接受外部請求,并將信息寫到ETCD中。

      etcd:etcd用于Kubernetes的后端存儲,存儲集群數據,提供數據備份。一個分布式數據存儲組件,負責存儲集群的配置信息。

      Kube-controller-manager:控制器,負責策略控制,針對不同的工作負載執行不同的策略,如無狀態應用,有狀態應用等。執行集群級功能,例如復制組件,跟蹤Node節點,處理節點故障等等。

      Kube-scheduler:負責任務調度工作,監控沒有分配節點的新創建的Pod,選擇一個節點供Pods運行。負責應用調度的組件,根據各種條件(如可用的資源、節點的親和性等)將容器調度到Node上運行。

      在生產環境中,為了保障集群的高可用,通常會部署多個master,如CCE的集群高可用模式就是3個master節點

      Node節點是集群的計算節點,即運行容器化應用的節點。

      Kubelet:在集群內每個節點中運行的一個代理,用于保證Pod的運行,接收Master的指令,負責管理節點容器(Pod)。kubelet主要負責同Container Runtime打交道

      Kube-proxy:負責做負載均衡工作,在多個Pod/Service之間做負載均衡。用于管理Service的訪問入口,包括集群內Pod到Service的訪問和集群外訪問Service。應用組件間的訪問代理

      Add-ons:插件,用于擴展Kubernetes的功能。

      Container runtime:通常使用Docker來運行容器,也可使用rkt或者podman等做為替代方案。

      Kubernetes作為云原生應用的的基礎調度平臺,相當于云原生的操作系統,為了便于系統的擴展,Kubernetes中開放的以下接口,可以分別對接不同的后端,來實現自己的業務邏輯:

      Kubernetes作為云原生應用的的基礎調度平臺,相當于云原生的操作系統,為了便于系統的擴展,Kubernetes中開放的以下接口,可以分別對接不同的后端,來實現自己的業務邏輯:

      CRI(Container Runtime Interface):容器運行時接口,提供計算能力,是定義了容器和鏡像的服務的接口,常見的CRI后端有Docker、rkt、kata-containers等。

      CRI(Container Runtime Interface):容器運行時接口,提供計算能力,是定義了容器和鏡像的服務的接口,常見的CRI后端有Docker、rkt、kata-containers等。

      CNI(Container Network Interface):容器網絡接口,提供網絡能力,由一組用于配置Linux容器的網絡接口的規范和庫組成,同時還包含了一些插件,它僅關心容器創建時的網絡分配,和當容器被刪除時釋放網絡資源。

      CNI(Container Network Interface):容器網絡接口,提供網絡能力,由一組用于配置Linux容器的網絡接口的規范和庫組成,同時還包含了一些插件,它僅關心容器創建時的網絡分配,和當容器被刪除時釋放網絡資源。

      CSI(Container Storage Interface):容器存儲接口,提供存儲能力,通過它,Kubernetes可以將任意存儲系統暴露給自己的容器工作負載。

      CSI(Container Storage Interface):容器存儲接口,提供存儲能力,通過它,Kubernetes可以將任意存儲系統暴露給自己的容器工作負載。

      用戶可以通過UI或者kubectl提交一個Pod創建的請求給Kubernetes集群的控制面,

      這個請求首先會由Kube API Server接收,API Server會把這個信息寫入到集群的存儲系統etcd。

      之后Scheduler會通過API Server的watch,或者叫做notification的機制得到這個信息。接收到Pod創建請求后,Scheduler會根據集群各節點的內存狀態進行一次調度決策,在完成這次調度之后,它會向API Server返回可調度的節點的信息。API Server接收到這次操作之后,會把調度決策的結果再次寫到etcd,然后通知相應的節點去真正的執行Pod的啟動。

      相應節點的kubelet接收到創建Pod的請求后就會去調用Container runtime來真正的去動配置容器和這個容器的運行環境,并調度Storage Plugin進行容器存儲的配置,調度network Plugin進行容器網絡的配置。

      Pod是Kubernetes中最重要最基本的概念,Pod是Kubernetes最小工作單元。每一個Pod包含一個或多個相關容器,Kubernetes將Pod看做一個整體進行調度。

      將聯系緊密的容器封裝在一個Pod單元內,以Pod整體進行調度、擴展和實現生命周期管理。

      Pod內所有容器使用相同的網絡Namespace和共享存儲。即Pod內容器擁有相同IP地址和Port空間,容器間直接使用localhost通信。當掛載volume到Pod,即可實現將volume掛載到Pod中的每個容器。

      Pod中運行一個容器。這是Kubernetes最常見的用法,您可以將Pod視為單個封裝的容器,但是Kubernetes是直接管理Pod而不是容器。

      Pod中運行多個需要耦合在一起工作、需要共享資源的容器(比如初始化容器)。通常這種場景下應用包含一個主容器和幾個輔助容器(SideCar Container),例如主容器為一個web服務器,從一個固定目錄下對外提供文件服務,而輔助容器周期性的從外部下載文件存到這個固定目錄下。

      當資源變得非常多的時候,如何分類管理就非常重要了,Kubernetes提供了一種機制來為資源分類,那就是Label(標簽)。類似HTML中的標簽屬性,Label非常簡單,但是卻很強大,Kubernetes中幾乎所有資源都可以用Label來組織。Label的具體形式是key-value的標記對,可以在創建資源的時候設置,也可以在后期添加和修改。

      對已存在的Pod,可以直接使用kubectl label命令直接添加Label。

      Pod有了Label后,在查詢Pod的時候帶上--show-labels就可以看到Pod的Label。

      命名空間(Namespace)是對一組資源和對象的抽象整合。在同一個集群內可創建不同的命名空間,不同命名空間中的數據彼此隔離。使得它們既可以共享同一個集群的服務,也能夠互不干擾。一般用于租戶隔離。或者生產開發隔離

      將包含很多組件的系統分成不同的組,每個資源僅屬于一個Namespace。

      實現多租戶劃分,這樣多個團隊可以共用一個集群,使用的資源用Namespace進行劃分

      不同的Namespace下面的資源可以擁有相同的名字

      Namespace可使用的資源量可通過ResourceQuota進行限制

      default:所有未指定Namespace的對象都會被分配在default命名空間。

      kube-public:此命名空間下的資源可以被所有人訪問(包括未認證用戶),用來部署公共插件、容器模板等。

      kube-system:所有由Kubernetes系統創建的資源都處于這個命名空間(通過kubeadm的方式部署)。

      kube-node-lease:每個節點在該命名空間中都有一個關聯的“Lease”對象,該對象由節點定期更新,被用來記錄節點的心跳信號。(這個第一次聽說)

      Kubernetes中大部分資源可以用Namespace劃分,不過有些資源不行,它們屬于全局資源,不屬于某一個Namespace,如Node、PV等。

      Namespace只能做到組織上劃分,對運行的對象來說,它不能做到真正的隔離。舉例來說,如果兩個Namespace下的Pod知道對方的IP,而Kubernetes依賴的底層網絡沒有提供Namespace之間的網絡隔離的話,那這兩個Pod就可以互相訪問。

      工作負載是在Pod之上的一層抽象,我們可以通過控制器(controller)實現一系列基于Pod的高級特性,比如節點故障時Pod的自動遷移,Pod多副本橫向擴展,應用滾動升級等。我們通常使用controller來做應用的真正的管理,而Pod是組成工作負載最小的單元。

      工作負載按不同業務類型,在Kubernetes中分為以下四類:

      Deployment和ReplicaSet

      StatefulSet

      DaemonSet

      《云原生入門級開發者認證》學習筆記之云原生基礎設施K8s(三) 【與云原生的故事】

      Job、CronJob

      Controller負責整個Kubernetes的管理工作,保證集群中各種資源的狀態處于期望狀態,當監控到集群中某個資源狀態不正常時,管理控制器會觸發對應的調度操作。一個Controller至少追蹤一種類型的Kubernetes資源。這些對象有一個代表期望狀態的spec字段。該資源的Controller負責確保其當前狀態接近期望狀態。

      在Kubernetes中,Pod副本發生遷移或者伸縮的時候會發生變化,IP也是變化的。

      Kubernetes中的Service是一種抽象概念,它定義了一個Pod邏輯集合以及訪問它們的策略。Service定義了外界訪問一組特定Pod的方式。Service有自己的IP和端口,Service為Pod提供了負載均衡(kube-proxy)。

      Service有一個固定lP地址(在創建集群時有一個服務網段的設置,這個網段專門用于給Service分配IP地址),Service將訪問它的流量轉發給Pod,具體轉發給哪些Pod通過Label來選擇,而且Service可以給這些Pod做負載均衡。

      Volume用來管理Kubernetes存儲,是用來聲明在Pod中的容器可以訪問的文件目錄,含義如下:

      聲明在Pod中的容器可以訪問的文件目錄

      可以被掛載在Pod中一個或多個容器的指定路徑下。

      支持多種后端存儲(本地存儲、分布式存儲、云存儲等)。

      Pod中的所有容器都可以訪問Volume,但必須要掛載,且可以掛載到容器中任何目錄。

      Kubernetes應用編排與管理

      Pod:最小調度單位。

      Workload:Kuberntes中承載工作負載的對象,實現Pod的編排與調度。

      Routing:Kubernetes網絡,解決Pod的訪問問題。

      Nucleus:Kubernetes存儲及配置管理。

      Policy Enforcement:各類實現Kubernetes高級特性的插件。

      Kubectl是Kubernetes的命令行工具。通過kubectl,用戶能對集群進行管理,并在集群上進行容器化應用的安裝部署。

      Kubectl支持以下對象管理方式:

      指令式:通過kubectl內置的驅動命令,如:kubectl'+create/scale/delete/..+參數的形式,直接快速創建、更新和刪除Kubernetes對象。

      聲明式:使用kubectl apply創建指定目錄中配置文件所定義的所有對象。通常,此配置文件采用yaml進行描述。

      K8s中所有的配置都是通過API對象的spec去設置的,也就是用戶通過配置系統的理想狀態來改變系統,這是k8s重要設計理念之一,即所有的操作都是聲明式(Declarative)的而不是命令式(Imperative)的。

      聲明式操作在分布式系統中的好處是穩定,不怕丟操作或運行多次。例如,設置副本數為3的操作運行多次也還是一個結果,而給副本數加1的操作就不是聲明式的,運行多次結果就錯了。

      因此,在容器編排體系中,我們可以執行一個應用實例副本數保持在3個,而不用明確的去擴容Pod或是刪除已有的Pod來保證副本數。

      在Kubernetes中的很多操作都是用kubectl來完成,通過其命令可以管理Deployment、Replicaset、ReplicationController、Pod等,進行操作、擴容、刪除等全生命周期操作,同時可以對管理對象進行查看或者監控資源使用情況。

      kubectl的語法:kubectl[command][TYPE][NAME][flags]

      Command:指定你希望進行的操作,如create,get,describe,delete等。

      TYPE:指定操作對象的類型,如deployment,pod,service等。

      NAME:指定對象的名字。

      flags:可選的標志位。

      創建Kubernetes對象時,必須提供對象的規約,用來描述該對象的期望狀態,以及關于對象的一些基本信息(例如名稱)。在同一個yaml配置文件內可以同時定義多個資源

      在編輯Kubernetes對象對應的yaml文件時,至少需要配置如下的字段:

      apiVersion:建該對象所使用的KubernetesAPl的版本。

      kind:創建的對象的類別,如Pod/Deploymen/Service等。

      Metadata:描述對象的唯一性標識,可以是一個name字符串,可選的namespace,label項指定標簽等。

      Spec:該對象的期望狀態,其中replicas指定Pod副本數量。

      apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: pod-svc name: pod-svc spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: pod-svc resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {}

      無狀態工作負載:管理的Pod集合是相互等價的,需要的時候可以被替換。

      Deployment

      ReplicaSet

      有狀態工作負載:為每個Pod維護了一個唯一的ID,能夠保證Pod的順序性和唯一性,每個Pod是不可替代的。可使用持久存儲來保存服務產生的狀態。

      StatefulSet

      守護進程工作負載:保證每個節點上運行著這樣一個守護進程。

      DaemonSet

      批處理工作負載:一次性的任務。

      Job

      Cronjob

      無狀態工作負載的“無狀態”指的是請求無論經由哪一個實例進行處理,其返回的處理結果應是一致的,也就是說任何一個請求都可以被任意一個Pod處理;Pod不存儲狀態數據,相互等價,可以水平拓展,可被替換。web應用就是一類典型的無狀態應用,對于這類應用,可采用Deployment或ReplicaSet進行部署。

      Deployment是一組不具有唯一標識的多個Pod的集合,具備以下功能:

      確保集群中有期望數量的Pod運行

      提供多種升級策略以及一鍵回滾能力。

      提供暫停/恢復的能力。

      典型使用場景:

      Web Server等無狀態應用。

      從大到小的管理邏輯為:Deployment>ReplicaSet>Pod>容器,多個ReplicaSet場景:滾動更新

      kubectl create deployment web1 --image=nginx

      apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: web1 name: web1 spec: replicas: 3 selector: matchLabels: app: web1 strategy: {} template: metadata: creationTimestamp: null labels: app: web1 spec: containers: - image: nginx name: nginx ports: - containerPort: 80 resources: {} status: {}

      用戶希望應用程序始終可用,而開發人員則需要每天多次部署它們的新版本。在Kubernetes中,這些是通過滾動更新(Rolling Updates)完成的。滾動更新允許通過使用新的實例逐步更新Pod實例,零停機進行工作負載的更新。新的Pod將在具有可用資源的節點上進行調度。

      滾動更新允許以下操作:

      將應用程序從一個環境提升到另一個環境(通過容器鏡像更新)。

      回滾到以前的版本。

      持續集成和持續交付應用程序,無需停機。

      在某些分布式的場景,比如分布式數據庫,要求每個Pod都有自己單獨的狀態時,這時Deployment就不能滿足需求了。

      此類應用依靠StatefulSet進行部署。StatefulSet具備的以下特征:

      Pod有穩定的網絡標識符,Pod重新調度后PodName和HostName不變。

      每個Pod有單獨存儲,保證Pod重新調度后還是能訪問到相同的數據。

      StatefulSet給每個Pod提供固定名稱,Pod名稱增加從0-N的固定后綴,Pod重新調度后Pod名稱和HostName不變。

      StatefulSet通過Headless Service給每個Pod提供固定的訪問域名,Service的概念會在后面章節中詳細介紹。

      StatefulSet通過創建固定標識的PVC保證Pod重新調度后還是能訪問到相同的持久化數據。

      DaemonSet(守護進程集)部署的副本Pod會分布在各個Node上。它具備以下特點:

      確保每一個節點或者期望的節點(通過nodeSelector實現)上運行一個Pod。DaemonSet跟節點相關,如果節點異常,也不會在其他節點重新創建。

      新增節點時自動部署一個Pod。

      移除節點時自動刪除Pod。

      DaemonSet典型場景:

      在集群的每個節點上運行存儲Daemon,如glusterd,ceph。

      在每個節點上運行日志收集Daemon,如fluentd或logstash。

      在每個節點上運行監控Daemon,如Prometheus Node Exporter。

      若需要在特定Node節點創建Pod,可在Pod模板中定義nodeSelector加以區分。

      apiVersion: apps/v1 kind: DaemonSet metadata: creationTimestamp: null labels: app: myds1 name: myds1 spec: #replicas: 1 selector: matchLabels: app: myds1 #strategy: {} template: metadata: creationTimestamp: null labels: app: myds1 spec: containers: - image: nginx name: nginx resources: {} #status: {}

      Job:是Kubernetes用來控制批處理型任務的資源對象。批處理業務與長期伺服業務(Deployment、Statefulset)的主要區別是批處理業務的運行有頭有尾,而長期伺服業務在用戶不停止的情況下永遠運行。Job管理的Pod根據用戶的設置把任務成功完成就自動退出(Pod自動刪除)。

      Jobs主要處理一些短暫的一次性任務,并具備以下特點保證指定數量Pod成功運行結束。

      支持并發執行。

      支持錯誤自動重試。

      支持暫停/恢復Jobs。

      典型使用場景:

      計算以及訓練任務,如批量計算,Al訓練任務等。

      計算圓周率2000位

      apiVersion: batch/v1 kind: Job metadata: creationTimestamp: null name: job3 spec: template: metadata: creationTimestamp: null spec: containers: - command: - perl - -Mbignum=bpi - -wle - print bpi(500) image: perl name: job3 resources: {} restartPolicy: Never status: {}

      CronJob:是基于時間的Job,就類似于Linux系統的crontab文件中的一行,在指定的時間周期運行指定的Job。

      CronJob主要處理周期性或者重復性的任務:

      基于Crontab格式的時間調度。

      可以暫停/恢復CronJob。 ·典型的使用場景:

      周期性的數據分析服務。

      周期性的資源回收服務。

      ·相對于Deployment和DaemonSet通常提供持續的服務,Jobs執行一次性任務:

      Kind選擇Job。

      Completions當前的任務需要執行的Pod數量。

      Parallelism表示最多有多少個并發執行的任務。

      RestartPolicy只能選擇Never或OnFailure。

      BackoffLimit參數指定job失敗后進行重試的次數。

      apiVersion: batch/v1 kind: Job metadata: creationTimestamp: null name: my-job spec: backoffLimit: 6 #重試次數 completions: 6 # 運行幾次 parallelism: 2 # 一次運行幾個 template: metadata: creationTimestamp: null spec: containers: - command: - sh - -c - echo "hello jobs" - sleep 15 image: busybox name: my-job resources: {} restartPolicy: Never status: {}

      CronJob是一種特殊的Job,它能夠按照時間對任務進行調度,與我們熟悉的crontab非常相似。我們可以使用Cron格式快速指定任務的調度時間:

      在給定時間點只運行一次。

      在給定時間點周期性地運行。

      ```yaml apiVersion: batch/v1 kind: CronJob metadata: creationTimestamp: null name: test-job spec: jobTemplate: metadata: creationTimestamp: null name: test-job spec: template: metadata: creationTimestamp: null spec: containers: - command: - /bin/sh - -c - date image: busybox name: test-job resources: {} restartPolicy: OnFailure schedule: '*/1 * * * *' status: {}

      Kubernetes服務發布

      Pod有自己獨立的IP。

      Pod可以被創建,銷毀。

      當擴縮容時,Pod的數量會發生變更。

      當Pod故障時,ReplicaSet會創建新的Pod。

      「如何保證在pod進行如此多變化時,業務都能被訪問?」

      Pod創建完成后,如何訪問Pod呢?直接訪問Pod會有如下幾個問題:

      Pod會隨時被Deployment這樣的控制器刪除重建,那訪問Pod的結果就會變得不可預知。

      Pod的IP地址是在Pod啟動后才被分配,在啟動前并不知道Pod的IP地址。

      應用往往都是由多個運行相同鏡像的一組Pod組成,逐個訪問Pod也變得不現實。

      Kubernetes Service定義了這樣一種抽象:邏輯上的一組Pod,一種可以訪問它們的策略,通常稱為微服務。這一組Pod能夠被Service訪問到,通常是通過Label Selector實現的。

      Kubernetes支持以下Service類型:

      ClusterIP:提供一個集群內部的虛擬IP地址以供Pod訪問(默認模式)。

      NodePort:在Node上打開一個端口以供外部訪問。

      LoadBalancer:通過外部的負載均衡器來訪問。

      ClusterIP是Service的默認模式,LoadBalancer需要額外的模組來提供負載均衡。

      創建一個deployment,特別注意其中的幾個選項要和service匹配。

      template選項必須配置labels,該配置和service匹配。

      apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: web1 name: web1 spec: replicas: 3 selector: matchLabels: app: web1 strategy: {} template: metadata: creationTimestamp: null labels: app: web1 spec: containers: - image: nginx name: nginx resources: {} status: {}

      Pod的屬性中ports選項指定pod對外提供服務的容器端口,該端口需要和Service匹配。

      apiVersion: v1 kind: Service metadata: creationTimestamp: "2021-12-21T15:31:19Z" labels: run: dbpod name: dbsvc namespace: liruilong-svc-create resourceVersion: "310763" uid: 05ccb22d-19c4-443a-ba86-f17d63159144 spec: clusterIP: 10.102.137.59 clusterIPs: - 10.102.137.59 internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - port: 3306 protocol: TCP targetPort: 3306 selector: run: dbpod sessionAffinity: None type: ClusterIP status: loadBalancer: {}

      集群內訪問(ClusterlP)表示工作負載暴露給同一集群內其他工作負載訪問的方式,可以通過集群內部域名訪問。

      示例創建一個名為httpd-svc的Service,通過selector選擇到標簽app:httpd的Pod,目標Pod的端口為80,Service對外暴露的端口為8080。

      集群內Pod訪問該服務只需要通過“服務名稱:對外暴露的端口”接口,對應本例即 httpd-svc:8080。

      如果需要Service可供外部進行訪問,可以使用NodePort的方式。

      編輯yaml文件時,添加type參數。

      可以在使用nodePort字段指定對外服務端口,如果不進行指定,系統會自動分配空閑端口。

      訪問時通過訪問“節點IP地址:端口”進行服務使用。

      nodePort: 30000 為節點端口,取值范圍為30000-32767。

      負載均衡(LoadBalancer):可以通過彈性負載均衡從公網訪問到工作負載,與NodePort加公網IP的方式相比提供了高可靠的保障。

      LoadBalancer此功能由集群外部負載均衡器提供商提供。

      負載均衡(LoadBalancer)一般用于系統中需要暴露到公網的服務。

      負載均衡訪問方式由公網彈性負載均衡服務地址以及設置的訪問端口組成,例如

      ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create/metalld] └─$kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dbsvc ClusterIP 10.102.137.59 3306/TCP 101m ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create/metalld] └─$kubectl expose --name=blogsvc pod blog --port=80 --type=LoadBalancer service/blogsvc exposed ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create/metalld] └─$kubectl get svc -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR blogsvc LoadBalancer 10.108.117.197 192.168.26.240 80:30230/TCP 9s run=blog dbsvc ClusterIP 10.102.137.59 3306/TCP 101m run=dbpod

      在訪問時從ELB過來的流量會先訪問到節點,然后通過Service轉發到Pod。而如果創建一個LoadBalancer,系統則會創建一個NodePort,NodePort則會創建ClusterlP。

      Service是基于四層TCP和UDP協議轉發的,而在實際使用場景中,四層Service無法滿足應用層存在的大量HTTP/HTTPS訪問需求,因此需要使用七層負載均衡(Ingress)來暴露服務。

      Ingress可基于七層的HTTP和HTTPS協議進行轉發,它是Kubernetes集群中一種獨立的資源,制定了集群外部訪問流量的轉發規則。這些轉發規則可根據域名和路徑進行自定義,Ingress Controller根據這些規則將流量分配到一個或多個Service,完成對訪問流量的細粒度劃分。

      ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create] └─$kubectl get svc -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR pod-svc-1-svc ClusterIP 10.99.80.121 80/TCP 94s run=pod-svc-1 pod-svc-2-svc ClusterIP 10.110.40.30 80/TCP 107s run=pod-svc-2 pod-svc-svc ClusterIP 10.96.152.5 80/TCP 85s run=pod-svc ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create] └─$

      Ingress資源:一組基于域名或URL把請求轉發到指定Service實例的訪問規則,是Kubernetes的一種資源對象,通過接口服務實現增、刪、改、查的操作。

      apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: kubernetes.io/ingress.class: "nginx" #必須要加 spec: rules: - host: liruilongs.nginx1 http: paths: - path: / pathType: Prefix backend: service: name: pod-svc-svc port: number: 80 - host: liruilongs.nginx2 http: paths: - path: / pathType: Prefix backend: service: name: pod-svc-1-svc port: number: 80 - host: liruilongs.nginx3 http: paths: - path: / pathType: Prefix backend: service: name: pod-svc-2-svc port: number: 80

      Ingress Controller:請求轉發的執行器,用以實時監控資源對象Ingress、Service、End-point、Secret(主要是TLS證書和Key)、Node、ConfigMap的變化,解析Ingress定義的規則并負責捋請求轉發到相應的后端Service。

      Ingress Controller在不同廠商之間的實現方式不同,根據負載均衡器種類的不同,可以將其分成ELB型和Nginx型。

      Kubernetes存儲管理

      Volume的核心是一個目錄,其中可能存有數據,Pod中的容器可以訪問該目錄中的數據。 用戶創建Volume時選擇的卷類型將決定該目錄如何形成,使用何種介質保存數據,以及規定目錄中存放的內容。

      Volume的生命周期與掛載它的Pod相同,但是Volume里面的文件可能在Volume消失后仍然存在,這取決于卷的類型。如當Pod不再存在時,Kubernetes也會銷毀臨時卷,但并不會銷毀持久卷。

      ·Kubernetes支持多種卷類型,常用的類型有:

      emptyDir:一種簡單的空目錄,主要用于臨時存儲。

      hostPath:將主機(節點)某個目錄掛載到容器中,適用于讀取主機上的數據。

      ConfigMap:特殊類型,將Kubernetes特定的對象類型掛載到容器。

      Secret:特殊類型,將Kubernetes特定的對象類型掛載到容器。

      PVC:PersistentVolumeClaim,用來掛載PersistentVolume(持久化卷),提供可靠的存儲來保存應用的持久化數據。

      Kubernetes的Volume是Pod的一部分,并不是單獨的對象,不能獨立創建,只能在Pod中定義。

      template: metadata: labels: app: app-demo tier: frontend spec: volumes: - name: datavol emptyDir: {} containers: - name: tomcat-demo image: tomcat volumeMounts: - mountPath: /myddata-data name: datavol imagePullPolicy: IfNotPresent

      EmptyDir是最簡單的一種Volume類型,根據名字就能看出,這個Volume掛載后就是一個空目錄,應用程序可以在里面讀寫文件,emptyDir Volume的生命周期與Pod相同,Pod刪除后Volume的數據也同時刪除掉。

      emptyDir的一些用途:

      緩存空間,例如基于磁盤的歸并排序。

      為耗時較長的計算任務提供檢查點,以便任務能從崩潰前狀態恢復執行。

      apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podvolume name: podvolume spec: volumes: - name: volume1 emptyDir: {} - name: volume2 emptyDir: {} containers: - image: busybox imagePullPolicy: IfNotPresent command: ['sh','-c','sleep 5000'] resources: {} name: podvolume1 volumeMounts: - mountPath: /liruilong name: volume1 - image: busybox imagePullPolicy: IfNotPresent name: podvolume2 volumeMounts: - mountPath: /liruilong name: volume2 command: ['sh','-c','sleep 5000'] dnsPolicy: ClusterFirst restartPolicy: Always status: {}

      「emptyDir實際是將Volume的內容寫在Pod所在節點的磁盤上,另外emptyDir也可以設置存儲介質為內存」

      hostPath卷能將主機節點文件系統上的文件或目錄掛載到Pod中。

      使用場景:

      運行需要訪問Docker內部文件的容器:使用/var/lib/docker的hostPath。

      在容器中運行cAdvisor:使用/sys/fs/cgroup的hostPath。

      其他使用到宿主機文件的場景。

      HostPath是一種持久存儲,emptyDir里面的內容會隨著Pod的刪除而消失,但HostPath不會,如果對應的Pod刪除,HostPath Volume里面的內容依然存在于節點的目錄中,如果后續重新創建Pod并調度到同一個節點,掛載后依然可以讀取到之前Pod寫的內容。

      apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podvolumehostpath name: podvolumehostpath spec: volumes: - name: volumes1 hostPath: path: /data containers: - image: busybox name: podvolumehostpath command: ['sh','-c','sleep 5000'] resources: {} volumeMounts: - mountPath: /liruilong name: volumes1 dnsPolicy: ClusterFirst restartPolicy: Always status: {}

      「HostPath存儲的內容與節點相關,所以它不適合像數據庫這類的應用,想象下如果數據庫的Pod被調度到別的節點了,那讀取的內容就完全不一樣了。」

      記住永遠不要使用HostPath存儲跨Pod的數據,一定要把HostPath的使用范圍限制在讀取節點文件上,這是因為Pod被重建后不確定會調度哪個節點上,寫文件可能會導致前后不一致。

      不管是emptyDir還是hostPath,數據都是存放到宿主機,但是如某個pod出現了問題,通過控制器重啟時,會通過調度生產一個新的Pod,如果調度的節點不是原來的節點,那么數據就會丟失。這里的話,使用網路存儲就很方便。

      apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podvolumehostpath name: podvolumehostpath spec: volumes: - name: volumes1 nfs: server: vms81.liruilongs.github.io path: /liruilong containers: - image: busybox name: podvolumehostpath command: ['sh','-c','sleep 5000'] resources: {} volumeMounts: - mountPath: /liruilong name: volumes1 dnsPolicy: ClusterFirst restartPolicy: Always status: {}

      ConfigMap用于容器的配置文件管理,在被Pod引用前需單獨定義。它作為多個properties文件的應用,類似一個專門存儲配置文件的目錄,里面存放著各種配置文件。

      應用場景:ConfigMap最為常見的使用方式就是在環境變量和Volume中引用,能夠實現image和應用程序的配置文件、命令行參數和環境變量等信息解耦。

      ConfigMap是一種用于存儲應用所需配置信息的資源類型,用于保存配置數據的鍵值對,可以用來保存單個屬性,也可以用來保存配置文件。通過ConfigMap可以方便的做到配置解耦,使得不同環境有不同的配置。

      ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-secret-create] └─$kubectl create configmap myconfig2 --from-file=./application.properties configmap/myconfig2 created

      在Volume中引用ConfigMap:就是通過文件的方式直接捋ConfigMap的每條數據填入Volume,每條數據是一個文件,鍵就是文件名,鍵值就是文件內容。

      apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: nginxsecret name: nginxsecret spec: volumes: - name: config configMap: name: myconfig2 containers: - image: nginx imagePullPolicy: IfNotPresent name: nginxsecret resources: {} volumeMounts: - name: config mountPath: /app/java readOnly: true dnsPolicy: ClusterFirst restartPolicy: Always status: {}

      Secret是一種包含少量敏感信息例如密碼、token或key的對象。

      特征:

      在創建、查看和編輯Pod的流程中Secret暴露風險較小。

      系統會對Secret對象采取額外的預防措施,例如避免將其寫入磁盤。

      只有Pod請求的Secret在其容器中才是可見的,一個Pod不能訪問另一個Pod的Secret。

      應用場景:

      Secret和ConfigMap類似,都是以key-value的形式存儲信息,使用方式也相同,也就是作為環境變量或者volume被引用。但它更方便處理含敏感信息的字符串,比如密碼、token密鑰等,而不需要把這些敏感數據暴露到鏡像或者Pod Spec中,以此降低敏感數據暴露的風險。Secret中的信息僅在Pod成功請求Secret后才對其中的容器可見,一個Pod不能訪問另一個Pod的Secret。另外,系統會對Secret對象采取額外的預防措施,例如避免將其寫入磁盤等。

      ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-secret-create] └─$kubectl create secret generic mysecl --from-literal=mysqlpassword=liruilong --from-literal=rqpassword=rq secret/mysecl created ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-secret-create] └─$kubectl get secrets NAME TYPE DATA AGE default-token-7q2qj kubernetes.io/service-account-token 3 49m mysecl Opaque 2 9s ┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-secret-create] └─$

      apiVersion: v1 data: mysqlpassword: bGlydWlsb25n rqpassword: cnE= kind: Secret metadata: creationTimestamp: "2021-12-12T02:45:20Z" name: mysecl namespace: liruilong-secret-create resourceVersion: "1594980" selfLink: /api/v1/namespaces/liruilong-secret-create/secrets/mysecl uid: 05a99a7c-c7f0-48ac-9f67-32eb52ed1558 type: Opaque

      以變量的方式使用secret和卷的方式使用secret

      apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: mysqlpod name: mysqlpod spec: containers: - image: hub.c.163.com/library/mysql:latest imagePullPolicy: IfNotPresent name: mysqlpod resources: {} env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysecl key: mysqlpassword dnsPolicy: ClusterFirst restartPolicy: Always status: {} ----------- apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: nginxsecret name: nginxsecret spec: volumes: - name: v1 secret: secretName: mysecl containers: - image: nginx imagePullPolicy: IfNotPresent name: nginxsecret resources: {} volumeMounts: - name: v1 mountPath: /data dnsPolicy: ClusterFirst restartPolicy: Always status: {}

      PV/PVC/SC概念介紹

      持久化存儲,簡稱PV,是Kubernetes對存儲資源的抽象,屬于集群資源,可以由管理員事先創建,或者使用存儲類(Storage Class)實現動態供應。PV可以理解成 Kubernetes集群中的某個網絡存儲中對應的一塊存儲,它與Volume很類似,這里也可以結合物理盤區和邏輯卷來理解,PV可以理解為物理卷,PVC可以理解為劃分的邏輯卷。

      apiVersion: v1 kind: PersistentVolume metadata: name: pv0003 spec: capacity: storage: 5Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle #storageClassName: slow mountOptions: - hard - nfsvers=4.1 nfs: path: /tmp server: vms81.liruilongs.github.io

      持久化存儲聲明,簡稱PVC,是用戶對存儲卷(PV)的申請,屬于Namespace中的資源。

      PVC是基于命名空間相互隔離的,不同命名空間的PVC相互隔離PVC通過accessModes和storage的約束關系來匹配PV,不需要顯示定義,accessModes必須相同,storage必須小于等于。

      apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc01 spec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 4Gi #storageClassName: slow

      storageClassName 用于控制那個PVC能和PV綁定,只有在storageClassName相同的情況下才去匹配storage和accessModes

      apiVersion: v1 kind: PersistentVolume metadata: name: pv0003 spec: capacity: storage: 5Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle storageClassName: slow mountOptions: - hard - nfsvers=4.1 nfs: path: /tmp server: vms81.liruilongs.github.io ----- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mypvc01 spec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 4Gi storageClassName: slow

      存儲類,簡稱SC,為管理員提供了描述存儲“類”的方法,通過相應的存儲插件(CSl)實現,可根據用戶提出的PVC動態提供不同性質的PV。

      通過storageClass來動態處理PV的創建,管理員只需要創建好storageClass就可以了,用戶創建PVC時會自動的創建PV和PVC。當創建 pvc 的時候,系統會通知 storageClass,storageClass 會從它所關聯的分配器來獲取后端存儲類型,然后動態的創建一個 pv 出來和此 pvc 進行關聯

      apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: managed-nfs-storage provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME' parameters: archiveOnDelete: "false" ------ kind: PersistentVolumeClaim apiVersion: v1 metadata: name: pvc-nfs spec: accessModes: - ReadWriteMany resources: requests: storage: 20Mi storageClassName: "managed-nfs-storage"

      apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podvolumepvc name: podvolumepvc spec: volumes: - name: volumes1 persistentVolumeClaim: claimName: mypvc01 containers: - image: nginx name: podvolumehostpath resources: {} volumeMounts: - mountPath: /liruilong name: volumes1 imagePullPolicy: IfNotPresent dnsPolicy: ClusterFirst restartPolicy: Always status: {}

      Kubernetes 云原生 云端實踐

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:git命令
      下一篇:excel表格設置橫豎打印的教程(excel表格怎么設置橫向打印)
      相關文章
      亚洲精品国产精品国自产网站| 中文字幕亚洲精品资源网| 亚洲一本之道高清乱码| 亚洲美女免费视频| 久久青青草原亚洲av无码app| 亚洲av永久无码精品秋霞电影影院| 伊人久久大香线蕉亚洲五月天| 亚洲午夜精品第一区二区8050| 亚洲高清最新av网站| 亚洲一区二区三区免费| 亚洲五月午夜免费在线视频| 亚洲一本大道无码av天堂| 亚洲午夜精品一级在线播放放| 亚洲无线一二三四区手机| 中文字幕第13亚洲另类| 亚洲免费人成在线视频观看| 亚洲色欲一区二区三区在线观看| 亚洲永久精品ww47| 亚洲国产精品VA在线观看麻豆| 久久夜色精品国产嚕嚕亚洲av| 亚洲AV无码久久寂寞少妇| 亚洲AV成人精品网站在线播放| 亚洲精品线在线观看| 亚洲精品日韩中文字幕久久久| 亚洲欧洲日产国码www| 亚洲一级在线观看| 亚洲欧美不卡高清在线| 亚洲av无码片vr一区二区三区| 亚洲AV永久无码精品一区二区国产 | 亚洲另类无码专区丝袜| 日韩色视频一区二区三区亚洲 | 亚洲AV无码第一区二区三区| 91天堂素人精品系列全集亚洲| 亚洲美女在线观看播放| 97se亚洲国产综合自在线| 亚洲av最新在线观看网址| 国产乱辈通伦影片在线播放亚洲 | 处破女第一次亚洲18分钟| 亚洲一区二区三区无码影院| 亚洲成A∨人片在线观看不卡| 久久亚洲精品人成综合网|