亚洲一区精品自拍_2021年国内精品久久_男同十八禁gv在线观看_免费观看a级性爱黄片

Article / 文章中心

關于 Kubernetes中一些基本概念和術語筆記

發(fā)布時間:2021-11-24 點擊數(shù):1272

一、簡述

Kubernetes中的大部分概念如Node, Pod,Replication Controller, Service等都可以看作一種“資源對象”,幾乎所有的資源對象都可以通過Kubernetes提供的kubect工具(或者API編程調用)執(zhí)行增、刪、改、查等操作并將其保存在etcd中持久化存儲。從這個角度來看, Kubernetes其實是一個高度自動化的資源控制系統(tǒng),它通過`跟蹤對比etcd庫里保存的“資源期望狀態(tài)”與當前環(huán)境中的“實際資源狀態(tài)”的差異來實現(xiàn)自動控制和自動糾錯的高級功能。

K8s中相關資源:隨版本變化

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl api-resources
NAME(名字) SHORTNAMES(簡稱) APIVERSION(版本) NAMESPACED(命名空間隔離) KIND(種類)
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Podpodtemplates
replicationcontrollers rc v1 true ReplicationController
resourcequotas quota v1 true ResourceQuota
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition
apiservices apiregistration.k8s.io/v1 false APIService
controllerrevisions apps/v1 true ControllerRevision
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
tokenreviews authentication.k8s.io/v1 false TokenReview
localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview
selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview
horizontalpodautoscalers hpa autoscaling/v1 true HorizontalPodAutoscaler
cronjobs cj batch/v1 true CronJob
jobs batch/v1 true Jobcertificatesigningrequests
leases coordination.k8s.io/v1 true Lease
bgpconfigurations crd.projectcalico.org/v1 false BGPConfiguration
bgppeers crd.projectcalico.org/v1 false BGPPeer
blockaffinities crd.projectcalico.org/v1 false BlockAffinity
clusterinformations crd.projectcalico.org/v1 false ClusterInformation
felixconfigurations crd.projectcalico.org/v1 false FelixConfiguration
globalnetworkpolicies crd.projectcalico.org/v1 false GlobalNetworkPolicy
globalnetworksets crd.projectcalico.org/v1 false GlobalNetworkSet
hostendpoints crd.projectcalico.org/v1 false HostEndpoint
ipamblocks crd.projectcalico.org/v1 false IPAMBlock
ipamconfigs crd.projectcalico.org/v1 false IPAMConfig
ipamhandles crd.projectcalico.org/v1 false IPAMHandle
ippools crd.projectcalico.org/v1 false IPPool
kubecontrollersconfigurations crd.projectcalico.org/v1 false KubeControllersConfiguration
networkpolicies crd.projectcalico.org/v1 true NetworkPolicy
networksets crd.projectcalico.org/v1 true NetworkSet
endpointslices discovery.k8s.io/v1 true EndpointSlice
events ev events.k8s.io/v1 true Event
flowschemas flowcontrol.apiserver.k8s.io/v1beta1 false FlowSchema
prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1beta1 false PriorityLevelConfiguration
nodes metrics.k8s.io/v1beta1 false NodeMetrics
pods metrics.k8s.io/v1beta1 true PodMetrics
ingressclasses networking.k8s.io/v1 false IngressClass
ingresses ing networking.k8s.io/v1 true Ingress
networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy
runtimeclasses node.k8s.io/v1 false RuntimeClass
poddisruptionbudgets pdb policy/v1 true PodDisruptionBudget
podsecuritypolicies psp policy/v1beta1 false PodSecurityPolicy
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role
priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
csidrivers storage.k8s.io/v1 false CSIDriver
csinodes storage.k8s.io/v1 false CSINode
csistoragecapacities storage.k8s.io/v1beta1 true CSIStorageCapacity
storageclasses sc storage.k8s.io/v1 false StorageClass
volumeattachments storage.k8s.io/v1 false VolumeAttachment

二、Kubernetes集群的兩種管理角色: Master和Node

Master和Node
在這里插入圖片描述

1、Master角色

Kubernetes里的Master指的是 集群控制節(jié)點,每個Kubernetes集群里需要有一個Master節(jié)點來負責整個集群的管理和控制,基本上Kubernetes的所有控制命令都發(fā)給它,它來負責具體的執(zhí)行過程,我們后面執(zhí)行的所有命令基本都是在Master節(jié)點上運行的。

Master節(jié)點通常會占據(jù)一個獨立的服務器(高可用部署建議用3臺服務器),其主要原因是它太重要了,是整個集群的“首腦”,如果宕機或者不可用,那么對集群內容器應用的管理都將失效。Master節(jié)點上運行著以下一組關鍵進程。

Master節(jié)點上關鍵進程 --
Kubernetes API Server (kube-apiserver) 提供了HTTP Rest接口的關鍵服務進程,是Kubernetes里所有資源的增、刪、改、查等操作的唯一入口,也是集群控制的入口進程。
Kubernetes Controller Manager (kube-controller-manager) Kubernetes里所有資源對象的自動化控制中心,可以理解為資源對象的“大總管”。
Kubernetes Scheduler (kube-scheduler) 負責資源調度(Pod調度)的進程,相當于公交公司的“調度室”。
etcd 在Master節(jié)點上還需要啟動一個etcd服務,因為Kubernetes里的所有資源對象的數(shù)據(jù)全部是保存在etcd中的。
除了Master, Kubernetes集群中的其他機器被稱為Node節(jié)點

2、Node角色

在較早的版本中也被稱為Miniono與Master一樣, Node節(jié)點可以是一臺物理主機,也可以是一臺虛擬機。 Node節(jié)點才是Kubermetes集群中的工作負載節(jié)點,每個Node都會被Master分配一些工作負載(Docker容器),當某個Node宕機時,其上的工作負載會被Master自動轉移到其他節(jié)點上去。

每個Node節(jié)點上都運行著以下一組關鍵進程。
每個Node節(jié)點上都運行關鍵進程 --
kubelet 負責Pod對應的容器的創(chuàng)建、啟停等任務,同時與Master節(jié)點密切協(xié)作,實現(xiàn)集群管理的基本功能。
kube-proxy 實現(xiàn)Kubernetes Service的通信與負載均衡機制的重要組件。)
Docker Engine (docker): Docker引擎,負責本機的容器創(chuàng)建和管理工作。

Node節(jié)點可以在運行期間動態(tài)增加到Kubernetes集群中,前提是這個節(jié)點上已經(jīng)正確安裝、配置和啟動了上述關鍵進程,在默認情況下kubelet會向Master注冊自己,這也是Kubernetes推薦的Node管理方式。

一旦Node被納入集群管理范圍, kubelet進程就會定時向Master節(jié)點匯報自身的情報,例如操作系統(tǒng)、Docker版本、機器的CPU和內存情況,以及當前有哪些Pod在運行等,這樣Master可以獲知每個Node的資源使用情況,并實現(xiàn)高效均衡的資源調度策略。而某個Node超過指定時間不上報信息時,會被Master判定為“失聯(lián)", Node的狀態(tài)被標記為不可用(Not Ready),隨后Master會觸發(fā)“工作負載大轉移”的自動流程。

查看集群中的Node節(jié)點和節(jié)點的詳細信息

┌──[root@vms81.liruilongs.github.io]-[~]
└─$kubectl get nodes
NAME                         STATUS     ROLES                  AGE   VERSION
vms81.liruilongs.github.io   Ready      control-plane,master   47d   v1.22.2
vms82.liruilongs.github.io   Ready      worker1                47d   v1.22.2
vms83.liruilongs.github.io   NotReady   worker2                47d   v1.22.2
┌──[root@vms81.liruilongs.github.io]-[~]
└─$kubectl describe  node vms82.liruilongs.github.io # Node基本信息:名稱、標簽、創(chuàng)建時間等。 Name:               vms82.liruilongs.github.io
Roles:              worker1
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    disktype=node1
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=vms82.liruilongs.github.io
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/worker1=
Annotations:        dest: 這是一個工作節(jié)點
                    kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
                    projectcalico.org/IPv4Address: 192.168.26.82/24
                    projectcalico.org/IPv4IPIPTunnelAddr: 10.244.171.128
                    volumes.kubernetes.io/controller-managed-attach-detach: true CreationTimestamp:  Thu, 07 Oct 2021 01:15:45 +0800
Taints:             <none>
Unschedulable: false Lease:
  HolderIdentity:  vms82.liruilongs.github.io
  AcquireTime:     <unset>
  RenewTime:       Tue, 23 Nov 2021 23:08:16 +0800 # Node當前的運行狀態(tài), Node啟動以后會做一系列的自檢工作: # 比如磁盤是否滿了,如果滿了就標注OutODisk=True # 否則繼續(xù)檢查內存是否不足(如果內存不足,就標注MemoryPressure=True) # 最后一切正常,就設置為Ready狀態(tài)(Ready=True) # 該狀態(tài)表示Node處于健康狀態(tài), Master將可以在其上調度新的任務了(如啟動Pod)  Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason
        Message
  ----                 ------  -----------------                 ------------------                ------
        -------
  NetworkUnavailable   False   Tue, 23 Nov 2021 23:02:52 +0800   Tue, 23 Nov 2021 23:02:52 +0800   CalicoIsUp
        Calico is running on this node
  MemoryPressure       False   Tue, 23 Nov 2021 23:05:32 +0800   Tue, 23 Nov 2021 22:45:03 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Tue, 23 Nov 2021 23:05:32 +0800   Tue, 23 Nov 2021 22:45:03 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Tue, 23 Nov 2021 23:05:32 +0800   Tue, 23 Nov 2021 22:45:03 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Tue, 23 Nov 2021 23:05:32 +0800   Tue, 23 Nov 2021 22:45:03 +0800   KubeletReady
        kubelet is posting ready status # Node的主機地址與主機名。  Addresses:
  InternalIP:  192.168.26.82
  Hostname:    vms82.liruilongs.github.io # Node上的資源總量:描述Node可用的系統(tǒng)資源,包括CPU、內存數(shù)量、最大可調度Pod數(shù)量等,注意到目前Kubernetes已經(jīng)實驗性地支持GPU資源分配了(alpha.kubernetes.io/nvidia-gpu=0) Capacity:
  cpu:                2
  ephemeral-storage:  153525Mi
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             4030172Ki
  pods:               110 # Node可分配資源量:描述Node當前可用于分配的資源量。 Allocatable:
  cpu:                2
  ephemeral-storage:  144884367121
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             3927772Ki
  pods:               110 # 主機系統(tǒng)信息:包括主機的唯一標識UUID, Linux kernel版本號、操作系統(tǒng)類型與版本、Kubernetes版本號、kubelet與kube-proxy的版本號等。  System Info:
  Machine ID:                 1ee67b1c4230405a851cf0107d6e89f5
  System UUID:                C0EA4D56-ED9A-39CF-6942-5B66704F6E6F
  Boot ID:                    b0e42864-9778-4ded-af4c-a88a64f988db
  Kernel Version:             3.10.0-693.el7.x86_64
  OS Image:                   CentOS Linux 7 (Core)
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  docker://20.10.9
  Kubelet Version:            v1.22.2
  Kube-Proxy Version:         v1.22.2
PodCIDR:                      10.244.1.0/24
PodCIDRs:                     10.244.1.0/24 # 當前正在運行的Pod列表概要信息 Non-terminated Pods:          (3 in total)
  Namespace                   Name                              CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                              ------------  ----------  ---------------  -------------  ---
  kube-system                 calico-node-ntm7v                 250m (12%)    0 (0%)      0 (0%)           0 (0%)         47d
  kube-system                 kube-proxy-nzm24                  0 (0%)        0 (0%)      0 (0%)           0 (0%)         35d
  kube-system                 metrics-server-bcfb98c76-wxv5l    0 (0%)        0 (0%)      0 (0%)           0 (0%)         27m # 已分配的資源使用概要信息,例如資源申請的最低、最大允許使用量占系統(tǒng)總量的百分比。  Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                250m (12%)  0 (0%)
  memory             0 (0%)      0 (0%)
  ephemeral-storage  0 (0%)      0 (0%)
  hugepages-1Gi      0 (0%)      0 (0%)
  hugepages-2Mi      0 (0%)      0 (0%) # Node相關的Event信息。 Events:
  Type    Reason                   Age                 From     Message
  ----    ------                   ----                ----     -------
  Normal  NodeHasSufficientMemory  23m (x3 over 3d4h)  kubelet  Node vms82.liruilongs.github.io status is now: NodeHasSufficientMemory
  Normal  NodeHasNoDiskPressure    23m (x3 over 3d4h)  kubelet  Node vms82.liruilongs.github.io status is now: NodeHasNoDiskPressure
  Normal  NodeHasSufficientPID     23m (x3 over 3d4h)  kubelet  Node vms82.liruilongs.github.io status is now: NodeHasSufficientPID
  Normal  NodeReady                23m (x2 over 3d4h)  kubelet  Node vms82.liruilongs.github.io status is now: NodeReady
┌──[root@vms81.liruilongs.github.io]-[~]
└─$

總結一下,我們要操作k8s,在管理節(jié)點那我們怎么操作,我們通過kube-apiserver來接受用戶的請求,通過kubu-scheduler來負責資源的調度,是使用work1計算節(jié)點來處理還是使用work2計算節(jié)點來處理,然后在每個節(jié)點上要運行一個代理服務kubelet,用來控制每個節(jié)點的操作,但是每個節(jié)點的狀態(tài),是否健康我們不知道,這里我們需要kube-controller-manager

3、 Pod資源對象

Pod是Kubernetes的最重要也最基本的概念,

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

Pause容器

為什么Kubernetes會設計出一個全新的Pod的概念并且Pod有這樣特殊的組成結構?
原因之一:在一組容器作為一個單元的情況下,我們難以對“整體”簡單地進行判斷及有效地進行行動。引入業(yè)務無關并且不易死亡的Pause容器作為Pod的根容器,以它的狀態(tài)代表整個容器組的狀態(tài),就簡單、巧妙地解決了這個難題。
原因之二: Pod里的多個業(yè)務容器共享Pause容器的IP,共享Pause容器掛接的Volume,這樣既簡化了密切關聯(lián)的業(yè)務容器之間的通信問題,也很好地解決了它們之間的文件共享問題。

Pod IP

Kubernetes 為每個Pod都分配了唯一的IP地址,稱之為Pod IP,一個Pod里的多個容器共享Pod IP地址。 Kuberetes要求底層網(wǎng)絡支持集群內任意兩個Pod之間的TCP/P直接通信,這通常采用虛擬二層網(wǎng)絡技術來實現(xiàn)(鏈路層網(wǎng)橋),

在Kubernetes里,一個Pod里的容器與另外主機上的Pod容器能夠直接通信。

普通的Pod及靜態(tài)Pod (Static Pod)

Pod其實有兩種類型:普通的Pod及靜態(tài)Pod (Static Pod),如果使用kubeadm的方式部署,靜態(tài)pod在node節(jié)點和master節(jié)點創(chuàng)建略有不同

Pod兩種類型 描述
靜態(tài)Pod (Static Pod) 并 不存放在Kubernetes的etcd存儲 里,而是存放在某個具體的Node上的一個具體文件中,并且只在此Node上啟動運行。
普通的Pod 一旦被創(chuàng)建,就會被放入到etcd中存儲,隨后會被Kubernetes Masten調度到某個具體的Node上并進行綁定(Binding),隨后該Pod被對應的Node上的kubelet進程實例化成一組相關的Docker容器并啟動起來。

正常情況下,pod是在master上統(tǒng)一管理的,所謂靜態(tài)pod就是,即不是由master上創(chuàng)建調度的,是屬于node自身特的pod,在node上只要啟動kubelet之后,就會自動的創(chuàng)建的pod。這里理解的話,結合java靜態(tài)熟悉,靜態(tài)方法理解,即的node節(jié)點初始化的時候需要創(chuàng)建的一些pod

比如 kubeadm的安裝k8s的話,所以的服務都是通過容器的方式運行的。相比較二進制的方式方便很多,這里的話,那么涉及到master節(jié)點的相關組件在沒有k8s環(huán)境時是如何運行,構建master節(jié)點的,這里就涉及到靜態(tài)pod的問題。

在默認情況下,當Pod里的某個容器停止時,Kubernetes會自動檢測到這個問題并且重新啟動這個Pod (重啟Pod里的所有容器),如果Pod所在的Node宕機,則會將這個Node上的所有Pod重新調度到其他節(jié)點上.

Kubernetes里的所有資源對象都可以采用yaml或者JSON格式的文件來定義或描述,下面是我們在之前Hello World例子里用到的myweb這個Pod的資源定義文件:

apiVersion: v1 kind: Pod # Pod 定義 metadata: name: myweb # Pod 名字 lables: name: myweb spec: # 包含的容器組 containers: - name: myweb image: kubeguide/tomcat-app:v1 ports: - containerPort: 8080 env: - name: MYSQL_SERVICE_HOST value: 'mysql' - name: MYSQL_SERVICE_PORT value: '3306' 

Kubernetes的Event概念, Event是一個事件的記錄,記錄了事件的最早產生時間、最后重現(xiàn)時間、重復次數(shù)、發(fā)起者、類型,以及導致此事件的原因等眾多信息。Event通常會關聯(lián)到某個具體的資源對象上,是排查故障的重要參考信息,

Pod同樣有Event記錄,當我們發(fā)現(xiàn)某個Pod遲遲無法創(chuàng)建時,可以用kubectl describe pod xxxx來查看它的描述信息,用來定位問題的原因

在Kubernetes里,一個計算資源進行配額限定需要設定以下兩個參數(shù)。

計算資源進行配額限定
Requests:該資源的最小申請量,系統(tǒng)必須滿足要求。
Limits:該資源最大允許使用的量,不能被突破,當容器試圖使用超過這個量的資源時,可能會被Kubernetes Kill并重啟。

通常我們會把Request設置為一個比較小的數(shù)值,符合容器平時的工作負載情況下的資源需求,而把Limit設置為峰值負載情況下資源占用的最大量。

比如下面這段定義,表明MysQL容器申請最少0.25個CPU及64MiB內存,在運行過程中MySQL容器所能使用的資源配額為0.5個CPU及128MiB內存:
.... resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" ...
Pod Pod 周邊對象的示意圖

在這里插入圖片描述

4 、Lable 標簽

Label是Kubernetes系統(tǒng)中另外一個核心概念。一個Label是一個key-value的鍵值對。其中key與value由用戶自己指定。

Label可以附加到各種資源對象上,例如Node、Pod、Service、RC等,一個資源對象可以定義任意數(shù)量的Label,同一個Label也可以被添加到任意數(shù)量的資源對象上去, Label通常在資源對象定義時確定,也可以在對象創(chuàng)建后動態(tài)添加,或者刪除。

可以通過給指定的資源對象捆綁一個或多個不同的Label來實現(xiàn)多維度的資源分組管理功能,以便于靈活、方便地進行資源分配、調度、配置、部署等管理工作。

例如:部署不同版本的應用到不同的環(huán)境中;或者監(jiān)控和分析應用(日志記錄、監(jiān)控、告警)等。一些常用的Label示例如下。
版本標簽: "release" : "stable", "release":"canary"....
環(huán)境標簽: "environment":"dev", "environment":"ga","environment":"production"·
架構標簽: "ier":"frontend," "tier":"backend", "tier":"midleware" 分區(qū)標簽: "artition":"customerA", "partition": "customerB".
質量管控標簽: "track": "daily","track":"weeky" 

可以通過多個Label Selector表達式的組合實現(xiàn)復雜的條件選擇,多個表達式之間用“,”進行分隔即可,幾個條件之間是“AND"的關系,即同時滿足多個條件,比如下面的例子:

name=標簽名
env != 標簽名
name in (標簽1,標簽2)
name not in(標簽1)
name in (redis-master, redis-slave):匹配所有具有標簽`name=redis-master`或者`name=redis-slave`的資源對象。
name not in (phn-frontend):匹配所有不具有標簽name=php-frontend的資源對象。
name=redis-slave, env!=production
name notin (php-frontend),env!=production
apiVersion: v1 kind: Pod metadata: name: myweb lables: app: myweb # 管理對象RC和Service 在 spec 中定義Selector 與 Pod 進行關聯(lián)。 apiVersion: v1 kind: ReplicationController metadata: name: myweb spec: replicas: 1 selector: app: myweb template: ...略... apiVersion" v1 kind: Service metadata: name: myweb spec: selector: app: myweb ports: port: 8080 

新出現(xiàn)的管理對象如Deployment, ReplicaSet, DaemonSet和Job則可以在Selector中使用基于集合的篩選條件定義,例如:

selector: matchLabels: app: myweb matchExpressions: - {key: tire,operator: In,values: [frontend]} - {key: environment, operator: NotIn, values: [dev]} 

matchLabels用于定義一組Label,與直接寫在Selector中作用相同; matchExpressions用于定義一組基于集合的篩選條件,可用的條件運算符包括: In, NotIn, Exists和DoesNotExist.

如果同時設置了matchLabels和matchExpressions,則兩組條件為"AND"關系,即所有條件需要同時滿足才能完成Selector的篩選。

Label Selector在Kubernetes中的重要使用場景有以下幾處:

kube-controller進程通過資源對象RC上定義的Label Selector來篩選要監(jiān)控的Pod副本的數(shù)量,從而實現(xiàn)Pod副本的數(shù)量始終符合預期設定的全自動控制流程

kube-proxy進程通過Service的Label Selector來選擇對應的Pod, 自動建立起每個Service到對應Pod的請求轉發(fā)路由表,從而實現(xiàn)Service的智能負載均衡機制

通過對某些Node定義特定的Label,并且在Pod定義文件中使用NodeSelector這種標簽調度策略, kube-scheduler進程可以實現(xiàn)Pod “定向調度”的特性。

apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podnodea name: podnodea spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: podnodea resources: {} affinity: nodeAffinity: #主機親和性 requiredDuringSchedulingIgnoredDuringExecution: #硬策略 nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - vms85.liruilongs.github.io - vms84.liruilongs.github.io dnsPolicy: ClusterFirst restartPolicy: Always status: {}

5、 Replication Controller

RC是Kubernetes系統(tǒng)中的核心概念之一,簡單來說,它其實是定義了一個期望的場景,即聲明某種Pod的副本數(shù)量在任意時刻都符合某個預期值,所以RC的定義包括如下幾個部分。

RC的定義
Pod 期待的副本數(shù)(replicas)
用于篩選目標 Pod 的Label Selector
當 Pod 的副本數(shù)量小于預期數(shù)量時,用于創(chuàng)建新Pod的Pod模板(template)。

下面是一個完整的RC定義的例子,即確保擁有tier-frontend標簽的這個Pod (運行Tomcat容器)在整個Kubernetes集群中始終只有一個副本:

apiVersion: v1 kind: ReplicationController metadata: name: frontend spec: replicas: 1 selector: tier: frontend template: metadata: labels: app: app-demo tier: frontend spec: containers: - name: tomcat-demo image: tomcat imagePullPolicy: IfNotPresent env: - name: GET_HOSTS_FROM value: dns ports: - containerPort: 80

當我們定義了一個RC并提交到Kubernetes集群中以后, Master節(jié)點上的Controller Manager組件就得到通知,定期巡檢系統(tǒng)中當前存活的目標Pod,并確保目標Pod實例的數(shù)量剛好等于此RC的期望值,如果有過多的Pod副本在運行,系統(tǒng)就會停掉一些Pod,否則系統(tǒng)就會再自動創(chuàng)建一些Pod

通過RC, Kubernetes實現(xiàn)了用戶應用集群的高可用性,并且大大減少了系統(tǒng)管理員在傳統(tǒng)IT環(huán)境中需要完成的許多手工運維工作(如主機監(jiān)控腳本、應用監(jiān)控腳本、故障恢復腳本等)

下面我們以3個Node節(jié)點的集群為例,說明Kubernetes如何通過RC來實現(xiàn)Pod副本數(shù)量自動控制的機制。假如我們的RC里定義redis-slave這個Pod需要保持3個副本,系統(tǒng)將可能在其中的兩個Node上創(chuàng)建Pod,圖1.9描述了在兩個Node上創(chuàng)建redis-slave Pod的情形。
在這里插入圖片描述

在運行時,我們可以通過 修改RC的副本數(shù)量,來實現(xiàn)Pod的動態(tài)縮放(Scaling)功能,這可以通過執(zhí)行kubectl scale命令來一鍵完成:

kubectl scale rc redsi-slave --replicas=3

需要注意的是,刪除RC并不會影響通過該RC已創(chuàng)建好的Pod,為了刪除所有Pod,可以設置replicas的值為0,然后更新該RC。另外, kubectl提供了stop和delete命令來一次性刪除RC和RC控制的全部Pod。

應用升級時,通常會通過Build一個新的Docker鏡像,并用新的鏡像版本來替代舊的版本的方式達到目的。在系統(tǒng)升級的過程中,我們希望是平滑的方式,比如當前系統(tǒng)中10個對應的舊版本的Pod,最佳的方式是舊版本的Pod每次停止一個,同時創(chuàng)建一個新版本的Pod,在整個升級過程中,此消彼長,而運行中的Pod數(shù)量始終是10個,通過RC的機制, Kubernetes很容易就實現(xiàn)了這種高級實用的特性,被稱為“滾動升級” (Rolling Update)

6、 Deployment

Deployment是Kubernetes v1.2引入的新概念,引入的目的是為了更好地解決Pod的編排問題。

Deployment相對于RC的一個最大升級是我們可以隨時知道當前Pod “部署”的進度。實際上由于一個Pod的創(chuàng)建、調度、綁定節(jié)點及在目標Node上啟動對應的容器這一完整過程需要一定的時間,所以我們期待系統(tǒng)啟動N個Pod副本的目標狀態(tài),實際上是一個連續(xù)變化的“部署過程"導致的最終狀態(tài)。

Deployment的典型使用場景有以下幾個。
Deployment的典型使用場景
創(chuàng)建一個Deployment對象來生成對應的Replica Set并完成Pod副本的創(chuàng)建過程。
檢查Deployment的狀態(tài)來看部署動作是否完成(Pod副本的數(shù)量是否達到預期的值)
更新Deployment以創(chuàng)建新的Pod (比如鏡像升級)。
如果當前Deployment不穩(wěn)定,則回滾到一個早先的Deployment版本。
暫停Deployment以便于一次性修改多個PodTemplateSpec的配置項,之后再恢復Deployment,進行新的發(fā)布。
擴展Deployment以應對高負載。
查看Deployment的狀態(tài),以此作為發(fā)布是否成功的指標。
清理不再需要的舊版本ReplicaSets。

Deployment的定義與Replica Set的定義很類似,除了API聲明與Kind類型等有所區(qū)別:

apiversion: extensions/vlbetal       apiversion: v1 kind: Deployment                     kind: ReplicaSet metadata:                            metadata: name: nginx-deployment               name: nginx-repset

創(chuàng)建一個 tomcat-deployment.yaml Deployment 描述文件:

apiVersion: extensions/v1betal kind: Deployment metadata: name: frontend spec: replicas: 1 selector: matchLabels: tier: frontend matchExpressions: - {key: tier, operator: In,value: [frontend]} template: metadata: labels: app: app-demo tier: frontend spec: containers: - name: tomcat-demo images: tomcat imagePullPolicy: IfNotPresent ports: - containerPort: 8080 

運行如下命令創(chuàng)建 Deployment:

kubectl create -f tomcat-deploment.yaml

對上述輸出中涉及的數(shù)量解釋如下。

數(shù)量 解釋
DESIRED Pod副本數(shù)量的期望值,即Deployment里定義的Replica.
CURRENT 當前Replica的值,實際上是Deployment所創(chuàng)建的Replica Set里的Replica值,這個值不斷增加,直到達到DESIRED為止,表明整個部署過程完成。
UP-TO-DATE 最新版本的Pod的副本數(shù)量,用于指示在滾動升級的過程中,有多少個Pod副本已經(jīng)成功升級。
AVAILABLE 當前集群中可用的Pod副本數(shù)量,即集群中當前存活的Pod數(shù)量。

運行下述命令查看對應的Replica Set,我們看到它的命名與Deployment的名字有關系:

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl get rs -A
NAMESPACE     NAME                                 DESIRED   CURRENT   READY   AGE
kube-system   calico-kube-controllers-78d6f96c7b   1         1         1       47d
kube-system   coredns-545d6fc579                   0         0         0       47d
kube-system   coredns-7f6cbbb7b8                   2         2         2       36d
kube-system   kuboard-78dccb7d9f                   1         1         1       11d
kube-system   metrics-server-bcfb98c76

7、 Horizontal Pod Autoscaler

HPA與之前的RC、 Deployment一樣,也屬于一種Kubernetes資源對象。通過 追蹤分析RC控制的所有目標Pod的負載變化情況,來確定是否需要針對性地調整目標Pod的副本數(shù),這是HPA的實現(xiàn)原理 。當前, HPA可以有以下兩種方式作為Pod負載的度量指標。

Horizontal Pod Autoscaler
CPUUtilizationPercentage.
應用程序自定義的度量指標,比如服務在每秒內的相應的請求數(shù)(TPS或QPS)
apiversion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: php-apache namespace: default spec maxReplicas: 10 minReplicas: 1 scaleTargetRef: kind: Deployment name: php-apache targetcpuutilizationPercentage: 90

CPUUtilizationPercentage是一個算術平均值,即目標Pod所有副本自身的CPU利用率的平均值。一個Pod自身的CPU利用率是該Pod當前CPU的使用量除以它的Pod Request的值,比,如我們定義一個Pod的Pod Request為0.4,而當前Pod的CPU使用量為0.2,則它的CPU使用率為50%

根據(jù)上面的定義,我們可以知道這個HPA控制的目標對象為一個名叫php-apache Deployment里的Pod副本,當這些Pod副本的CPUUtilizationPercentage的值超過90%時會觸發(fā)自動動態(tài)擴容行為,擴容或縮容時必須滿足的一個約束條件是Pod的副本數(shù)要介于1與10之間。

除了可以通過直接定義yaml文件并且調用kubectrl create的命令來創(chuàng)建一個HPA資源對象的方式,我們還能通過下面的簡單命令行直接創(chuàng)建等價的HPA對象:

kubectl autoscale deployment php-apache --cpu-percent=90--min-1 --max=10

8、 StatefulSet

在Kubernetes系統(tǒng)中, Pod的管理對象RC, Deployment, DaemonSet和Job都是面向無狀態(tài)的服務。 但現(xiàn)實中有很多服務是有狀態(tài)的,特別是一些復雜的中間件集群,例如MysQL集·群、MongoDB集群、ZooKeeper集群等,這些應用集群有以下一些共同點:

共同點
每個節(jié)點都有固定的身份ID,通過這個ID,集群中的成員可以相互發(fā)現(xiàn)并且通信。
集群的規(guī)模是比較固定的,集群規(guī)模不能隨意變動。
集群里的每個節(jié)點都是有狀態(tài)的,通常會持久化數(shù)據(jù)到永久存儲中。
如果磁盤損壞,則集群里的某個節(jié)點無法正常運行,集群功能受損
如果用RC/Deployment控制Pod副本數(shù)的方式來實現(xiàn)上述有狀態(tài)的集群,則我們會發(fā)現(xiàn)第1點是無法滿足的,因為Pod的名字是隨機產生的, Pod的IP地址也是在運行期才確定且可能有變動的,我們事先無法為每個Pod確定唯一不變的ID,

為了能夠在其他節(jié)點上恢復某個失敗的節(jié)點,這種集群中的Pod需要掛接某種共享存儲,為了解決這個問題, Kubernetes從v1.4版本開始引入了PetSet這個新的資源對象,并且在v1.5版本時更名為StatefulSet, StatefulSet從本質上來說,可以看作DeploymentRC的一個特殊變種,它有如下一些特性。)

特性
StatefulSet里的每個Pod都有穩(wěn)定、唯一的網(wǎng)絡標識,可以用來發(fā)現(xiàn)集群內的其他成員。假設StatefulSet的名字叫kafka,那么第1個Pod 叫 kafka-0,第2個叫kafk-1,以此類推。)
StatefulSet控制的Pod副本的啟停順序是受控的,操作第n個Pod時,前n-1個Pod已經(jīng)是運行且準備好的狀態(tài))
StatefulSet里的Pod采用穩(wěn)定的持久化存儲卷,通過PV/PVC來實現(xiàn),刪除Pod時默認不會刪除與StatefulSet相關的存儲卷(為了保證數(shù)據(jù)的安全)。

statefulSet除了要與PV卷捆綁使用以存儲Pod的狀態(tài)數(shù)據(jù),還要與Headless Service配合使用,即在每個StatefulSet的定義中要聲明它屬于哪個Headless ServiceHeadless Service與普通Service的關鍵區(qū)別在于,它沒有Cluster IP,如果解析Headless Service的DNS域名,則返回的是該Service對應的全部Pod的Endpoint列表。StatefulSet在Headless Service的基礎上又為StatefulSet控制的每個Pod實例創(chuàng)建了一個DNS域名,這個域名的格式為:

$(podname).$(headless service name)

9、 Service (服務)

Service也是Kubernetes里的最核心的資源對象之一, Kubernetes里的每個Service其實就是我們經(jīng)常提起的微服務架構中的一個“微服務”,之前我們所說的Pod, RC等資源對象其實都是為這節(jié)所說的“服務”-Kubernetes Service作“嫁衣”的Pod,RC與Service的邏輯關系。

在這里插入圖片描述

Kubernetes的Service定義了一個服務的訪問入口地址,前端的應用(Pod)通過這個入口地址訪問其背后的一組由Pod副本組成的集群實例, Service與其后端Pod副本集群之間則是通過Label Selector來實現(xiàn)“無縫對接”的。而RC的作用實際上是保證Service的服務能力和服務質量始終處干預期的標準。

每個Pod都會被分配一個單獨的IP地址,而且每個Pod都提供了一個獨立的Endpoint(Pod IP+ContainerPort)以被客戶端訪問,現(xiàn)在多個Pod副本組成了一個集群來提供服務.客戶端如何來訪問它們呢?一般的做法是部署一個負載均衡器(軟件或硬件),

Kubernetes中運行在每個Node上的kube-proxy進程其實就是一個智能的軟件負載均衡器,它負責把對Service的請求轉發(fā)到后端的某個Pod實例上,并在內部實現(xiàn)服務的負載均衡與會話保持機制。

Kubernetes發(fā)明了一種很巧妙又影響深遠的設計:

Service不是共用一個負載均衡器的IP地址,而是每個Service分配了一個全局唯一的虛擬IP地址,這個虛擬IP被稱為Cluster IP,這樣一來,每個服務就變成了具備唯一IP地址的“通信節(jié)點”,服務調用就變成了最基礎的TCP網(wǎng)絡通信問題。

我們知道, Pod的Endpoint地址會隨著Pod的銷毀和重新創(chuàng)建而發(fā)生改變,因為新Pod的IP地址與之前舊Pod的不同。而 Service一旦被創(chuàng)建, Kubernetes就會自動為它分配一個可用的Cluster IP,而且在Service的整個生命周期內,它的Cluster IP不會發(fā)生改變。于是,服務發(fā)現(xiàn)這個棘手的問題在Kubernetes的架構里也得以輕松解決:只要用Service的Name與Service的Cluster IP地址做一個DNS域名映射即可完美解決問題。

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl get svc myweb -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2021-10-16T14:25:08Z" name: myweb
  namespace: liruilong-pod-create
  resourceVersion: "339816" uid: 695aa461-166c-4937-89ed-7b16ac49c96b
spec:
  clusterIP: 10.109.233.35
  clusterIPs:
  - 10.109.233.35
  externalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 30001
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: myweb
  sessionAffinity: None type: NodePort
status:
  loadBalancer: {}

Kubernetes Service支持多個Endpoint(端口),在存在多個Endpoint的情況下,要求每個Endpoint定義一個名字來區(qū)分。下面是Tomcat多端口的Service定義樣例:

spec: ports: - port: 8080 name: service-port - port: 8005 name: shutdown-port
多端口為什么需要給每個端口命名呢?這就涉及Kubernetes的服務發(fā)現(xiàn)機制了

Kubernetes 的服務發(fā)現(xiàn)機制

Kubernetes 的服務發(fā)現(xiàn)機制
最早時Kubernetes采用了Linux環(huán)境變量的方式解決這個問題,即每個Service生成一些對應的Linux環(huán)境變量(ENV),并在每個Pod的容器在啟動時,自動注入這些環(huán)境變量
后來Kubernetes通過Add-On增值包的方式引入了DNS系統(tǒng),把服務名作為DNS域名,這樣一來,程序就可以直接使用服務名來建立通信連接了。目前Kubernetes上的大部分應用都已經(jīng)采用了DNS這些新興的服務發(fā)現(xiàn)機制

外部系統(tǒng)訪問 Service 的問題

Kubernetes里的“三種IP" 描述
Node IP Node 節(jié)點的IP地址,Node IP是Kubernetes集群中每個節(jié)點的物理網(wǎng)卡的IP地址,這是一個真實存在的物理網(wǎng)絡,所有屬于這個網(wǎng)絡的服務器之間都能通過這個網(wǎng)絡直接通信,不管它們中是否有部分節(jié)點不屬于這個Kubernetes集群。這也表明了Kubernetes集群之外的節(jié)點訪問Kubernetes集群之內的某個節(jié)點或者TCP/IP服務時,必須要通過Node IP進行通信。
Pod IP Pod 的 IP 地址:Pod IP是每個Pod的IP地址,它是Docker Engine根據(jù)dockero網(wǎng)橋的IP地址段進行分配的,通常是一個虛擬的二層網(wǎng)絡,前面我們說過, Kubernetes要求位于不同Node上的Pod能夠彼此直接通信,所以Kubernetes里一個Pod里的容器訪問另外一個Pod里的容器,就是通過Pod IP所在的虛擬二層網(wǎng)絡進行通信的,而真實的TCP/IP流量則是通過Node IP所在的物理網(wǎng)卡流出的。
Cluster IP Service 的IP地址,Cluster IP僅僅作用于Kubernetes Service這個對象,并由Kubernetes管理和分配IP地址(來源于Cluster IP地址池)。Cluster IP無法被Ping,因為沒有一個“實體網(wǎng)絡對象”來響應。Cluster IP只能結合Service Port組成一個具體的通信端口,單獨的Cluster IP不具備TCPIP通信的基礎,并且它們屬于Kubernetes集群這樣一個封閉的空間,集群之外的節(jié)點如果要訪問這個通信端口,則需要做一些額外的工作。在Kubernetes集群之內, Node IP網(wǎng)、Pod IP網(wǎng)與Cluster IP網(wǎng)之間的通信,采用的是Kubermetes自己設計的一種編程方式的特殊的路由規(guī)則,與我們所熟知的IP路由有很大的不同。
外部系統(tǒng)訪問 Service,采用NodePort是解決上述問題的最直接、最有效、最常用的做法。具體做法如下,以tomcat-service為例,我們在Service的定義里做如下擴展即可:
... spec: type: NodePort posts: - port: 8080 nodePort: 31002 selector: tier: frontend ...

即這里我們可以通過nodePort:31002 來訪問Service,NodePort的實現(xiàn)方式是在Kubernetes集群里的每個Node上為需要外部訪問的Service開啟個對應的TCP監(jiān)聽端口,外部系統(tǒng)只要用任意一個Node的IP地址+具體的NodePort端口即可訪問此服務,在任意Node上運行netstat命令,我們就可以看到有NodePort端口被監(jiān)聽:

Service 負載均衡問題

但NodePort還沒有完全解決外部訪問Service的所有問題,比如負載均衡問題,假如我們的集群中有10個Node,則此時最好有一個負載均衡器,外部的請求只需訪問此負載均衡器的IP地址,由負載均衡器負責轉發(fā)流量到后面某個Node的NodePort上。如圖

NodePort的負載均衡
在這里插入圖片描述
Load balancer組件獨立于Kubernetes集群之外,通常是一個硬件的負載均衡器,或者是以軟件方式實現(xiàn)的,例如HAProxy或者Nginx。對于每個Service,我們通常需要配置一個對應的Load balancer實例來轉發(fā)流量到后端的Node上
Kubernetes提供了自動化的解決方案,如果我們的集群運行在谷歌的GCE公有云上,那么只要我們把Service的type-NodePort改為type-LoadBalancer,此時Kubernetes會自動創(chuàng)建一個對應的Load balancer實例并返回它的IP地址供外部客戶端使用。

10、 Volume (存儲卷)

Volume是Pod中能夠被多個容器訪問的共享目錄。Kuberetes的Volume概念、用途和目的與Docker的Volume比較類似,但兩者不能等價。

Volume (存儲卷)
Kubernetes中的Volume定義在Pod上,然后被一個Pod里的多個容器掛載到具體的文件目錄下;
Kubernetes中的Volume與Pod的生命周期相同,但與容器的生命周期不相關,當容器終止或者重啟時, Volume中的數(shù)據(jù)也不會丟失。
Kubernetes支持多種類型的Volume,例如GlusterFS, Ceph等先進的分布式文件系統(tǒng)。
Volume的使用也比較簡單,在大多數(shù)情況下,我們先在Pod上聲明一個Volume,然后在容器里引用該Volume并Mount到容器里的某個目錄上。舉例來說,我們要給之前的Tomcat Pod增加一個名字為datavol的Volume,并且Mount到容器的/mydata-data目錄上,則只要對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
除了可以讓一個Pod里的多個容器共享文件、讓容器的數(shù)據(jù)寫到宿主機的磁盤上或者寫文件到網(wǎng)絡存儲中, Kubernetes的Volume還擴展出了一種非常有實用價值的功能,即

容器配置文件集中化定義與管理,這是通過ConfigMap這個新的資源對象來實現(xiàn)的.

Kubernetes提供了非常豐富的Volume類型,下面逐一進行說明。

1. emptyDir

一個emptyDir Volume是在Pod分配到Node時創(chuàng)建的。從它的名稱就可以看出,它的初始內容為空,并且無須指定宿主機上對應的目錄文件,因為這是 Kubernetes自動分配的一個目錄,當Pod從Node上移除時, emptyDir中的數(shù)據(jù)也會被永久刪除。emptyDir的一些用途如下。

emptyDir的一些用途
臨時空間,例如用于某些應用程序運行時所需的臨時目錄,且無須永久保留。
長時間任務的中間過程CheckPoint的臨時保存目錄。
一個容器需要從另一個容器中獲取數(shù)據(jù)的目錄(多容器共享目錄)

2. hostPath

hostPath為在Pod上掛載宿主機上的文件或目錄,它通??梢杂糜谝韵聨追矫?。

|容器應用程序生成的日志文件需要永久保存時,可以使用宿主機的高速文件系統(tǒng)進行存儲。|

需要訪問宿主機上Docker引擎內部數(shù)據(jù)結構的容器應用時,可以通過定義hostPath為宿主機/var/lib/docker目錄,使容器內部應用可以直接訪問Docker的文件系統(tǒng)。

在使用這種類型的Volume時,需要注意以下幾點。

在不同的Node上具有相同配置的Pod可能會因為宿主機上的目錄和文件不同而導致對Volume上目錄和文件的訪問結果不一致。)

如果使用了資源配額管理,則Kubernetes無法將hostPath在宿主機上使用的資源納入管理。在下面的例子中使用宿主機的/data目錄定義了一個hostPath類型的Volume:

volumes: - name: "persistent-storage" hostPath: path: "/data"

3. gcePersistentDisk

使用這種類型的Volume表示使用谷歌公有云提供的永久磁盤(PersistentDisk, PD)存放Volume的數(shù)據(jù),它與emptyDir不同, PD上的內容會被永久存,當Pod被刪除時, PD只是被卸載(Unmount),但不會被刪除。需要注意是,你需要先創(chuàng)建一個永久磁盤(PD),才能使用gcePersistentDisk.

4. awsElasticBlockStore

與GCE類似,該類型的Volume使用亞馬遜公有云提供的EBS Volume存儲數(shù)據(jù),需要先創(chuàng)建一個EBS Volume才能使用awsElasticBlockStore.

5. NFS

使用NFS網(wǎng)絡文件系統(tǒng)提供的共享目錄存儲數(shù)據(jù)時,我們需要在系統(tǒng)中部署一個NFSServer,定義NES類型的Volume的示例如下
yum -y install nfs-utils

... volumes: - name: test-volume nfs: server: nfs.server.locathost path: "/" .... 

11、 Persistent Volume

Volume是定義在Pod上的,屬于“計算資源”的一部分,而實際上, “網(wǎng)絡存儲”是相對獨立于“計算資源”而存在的一種實體資源。比如在使用虛擬機的情況下,我們通常會先定義一個網(wǎng)絡存儲,然后從中劃出一個“網(wǎng)盤”并掛接到虛擬機上

Persistent Volume(簡稱PV)和與之相關聯(lián)的Persistent Volume Claim (簡稱PVC)也起到了類似的作用。PV可以理解成 Kubernetes集群中的某個網(wǎng)絡存儲中對應的一塊存儲,它與Volume很類似,但有以下區(qū)別。

Persistent Volume與Volume的區(qū)別
PV只能是網(wǎng)絡存儲,不屬于任何Node,但可以在每個Node上訪問。
PV并不是定義在Pod上的,而是獨立于Pod之外定義。
PV目前支持的類型包括: gcePersistentDisk、 AWSElasticBlockStore, AzureFileAzureDisk, FC (Fibre Channel). Flocker, NFS, isCSI, RBD (Rados Block Device)CephFS. Cinder, GlusterFS. VsphereVolume. Quobyte Volumes, VMware Photon.PortworxVolumes, ScalelO Volumes和HostPath (僅供單機測試)。
apiversion: v1 kind: PersistentVolume metadata: name: pv0003 spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce nfs: path: /somepath server: 172.17.0.2

PV的accessModes屬性, 目前有以下類型:

  • ReadWriteOnce:讀寫權限、并且只能被單個Node掛載。
  • ReadOnlyMany:只讀權限、允許被多個Node掛載。
  • ReadWriteMany:讀寫權限、允許被多個Node掛載。

如果某個Pod想申請某種類型的PV,則首先需要定義一個PersistentVolumeClaim (PVC)對象:

kind: Persistentvolumeclaim apiversion: v1 metadata: name: myclaim spec: accessModes: - Readwriteonce resources: requests: storage: BGi 

引用PVC

volumes: - name: mypd persistentvolumeclaim: claimName: myclaim

|PV是有狀態(tài)的對象,它有以下幾種狀態(tài)。|
|:--|
|Available:空閑狀態(tài)。|
|Bound:已經(jīng)綁定到某個Pvc上。|
|Released:對應的PVC已經(jīng)刪除,但資源還沒有被集群收回。|
|Failed: PV自動回收失敗。|

12、 Namespace (命名空間)

Namespace (命名空間)是Kubernetes系統(tǒng)中非常重要的概念, Namespace在很多情況下用于實現(xiàn) 多租戶的資源隔離。Namespace通過將集群內部的資源對象“分配”到不同的Namespace 中,形成邏輯上分組的不同項目、小組或用戶組,便于不同的分組在共享使用整個集群的資源的同時還能被分別管理。Kubernetes集群在啟動后,會創(chuàng)建一個名為"default"的Namespace,通過kubectl可以查看到:

不同的namespace之間互相隔離
查看所有命名空間 kubectl get ns
查看當前命名空間 kubectl config get-contexts
設置命名空間 kubectl config set-context 集群名 --namespace=命名空間

kub-system 本身的各種 pod,是kubamd默認的空間。pod使用命名空間相互隔離

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl get namespaces
NAME              STATUS   AGE
default           Active   13h
kube-node-lease   Active   13h
kube-public       Active   13h
kube-system       Active   13h
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl get ns
NAME              STATUS   AGE
default           Active   13h
kube-node-lease   Active   13h
kube-public       Active   13h
kube-system       Active   13h
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$

命名空間基本命令

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl create ns liruilong
namespace/liruilong created
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl get ns
NAME              STATUS   AGE
default           Active   13h
kube-node-lease   Active   13h
kube-public       Active   13h
kube-system       Active   13h
liruilong         Active   4s
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl create ns k8s-demo
namespace/k8s-demo created
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl get ns
NAME              STATUS   AGE
default           Active   13h
k8s-demo          Active   3s
kube-node-lease   Active   13h
kube-public       Active   13h
kube-system       Active   13h
liruilong         Active   20s
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl delete ns  k8s-demo
namespace "k8s-demo" deleted
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl get ns
NAME              STATUS   AGE
default           Active   13h
kube-node-lease   Active   13h
kube-public       Active   13h
kube-system       Active   13h
liruilong         Active   54s
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$

命名空間切換

┌──[root@vms81.liruilongs.github.io]-[~/.kube]
└─$vim config
┌──[root@vms81.liruilongs.github.io]-[~/.kube]
└─$kubectl config get-contexts
CURRENT   NAME       CLUSTER    AUTHINFO            NAMESPACE
*         context1   cluster1   kubernetes-admin1
          context2   cluster2   kubernetes-admin2
┌──[root@vms81.liruilongs.github.io]-[~/.kube]
└─$kubectl config set-context context2 --namespace=kube-system
Context "context2" modified.
┌──[root@vms81.liruilongs.github.io]-[~/.kube]
└─$kubectl config get-contexts
CURRENT   NAME       CLUSTER    AUTHINFO            NAMESPACE
*         context1   cluster1   kubernetes-admin1
          context2   cluster2   kubernetes-admin2   kube-system
┌──[root@vms81.liruilongs.github.io]-[~/.kube]
└─$kubectl config set-context context1 --namespace=kube-public
Context "context1" modified.

或者可以這樣切換名稱空間

kubectl config set-context $(kubectl config current-context) --namespace=<namespace>
kubectl config view | grep namespace
kubectl get pods

創(chuàng)建pod時指定命名空間

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

當我們給每個租戶創(chuàng)建一個Namespace來實現(xiàn)多租戶的資源隔離時,還能結合Kubernetes"的資源配額管理,限定不同租戶能占用的資源,例如CPU使用量、內存使用量等。

13、 Annotation (注解)

Annotation與Label類似,也使用key/value鍵值對的形式進行定義。

不同的是Label具有嚴格的命名規(guī)則,它定義的是Kubernetes對象的元數(shù)據(jù)(Metadata),并且用于Label Selector.

Annotation則是用戶任意定義的“附加”信息,以便于外部工具進行查找, Kubernetes的模塊自身會通過Annotation的方式標記資源對象的一些特殊信息。

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl annotate nodes vms82.liruilongs.github.io "dest=這是一個工作節(jié)點" node/vms82.liruilongs.github.io annotated
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-pod-create]
└─$kubectl describe nodes vms82.liruilongs.github.io
Name:               vms82.liruilongs.github.io
Roles:              worker1
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    disktype=node1
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=vms82.liruilongs.github.io
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/worker1=
Annotations:        dest: 這是一個工作節(jié)點
                    kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
                    node.alpha.kubernetes.io/ttl: 0
                    projectcalico.org/IPv4Address: 192.168.26.82/24
                    projectcalico.org/IPv4IPIPTunnelAddr: 10.244.171.128
                    volumes.kubernetes.io/controller-managed-attach-detach: true .....................
通常來說,用Annotation來記錄的信息如下
build信息、 release信息、Docker鏡像信息等,例如時間戳、release id號、PR號、鏡像hash值、 docker registry地址等。
日志庫、監(jiān)控庫、分析庫等資源庫的地址信息。
程序調試工具信息,例如工具名稱、版本號等。
團隊的聯(lián)系信息,例如電話號碼、負責人名稱、網(wǎng)址等。