天天看點

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

寫在前面

  • 學習K8s,是以整理記憶
  • 大部分部分内容來源于

    《Kubernetes權威指南:從Docker到Kubernetes實踐全接觸》

    第一章,感興趣小夥伴可以支援作者一波

一個不欣賞自己的人,是難以快樂的。-------三毛

一、簡述

Kubernetes

中的大部分概念如

Node

,

Pod

Replication Controller

Service

等都可以看作一種“

資源對象

”,幾乎所有的資源對象都可以通過

Kubernetes

提供的

kubect

工具(或者

API

程式設計調用)執行增、删、改、查等操作并将其儲存在

etcd

中持久化存儲。從這個角度來看,

Kubernetes

其實是一個

高度自動化的資源控制系統

,它通過`跟蹤對比etcd庫裡儲存的“資源期望狀态”與目前環境中的“實際資源狀态”的差異來實作自動控制和自動糾錯的進階功能。

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

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

二、Kubernetes叢集的兩種管理角色:

Master

Node

Master

Node

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

1、Master角色

Kubernetes裡的Master指的是

叢集控制節點

,每個Kubernetes叢集裡需要有一個Master節點來負責整個叢集的管理和控制,基本上Kubernetes的所有控制指令都發給它,它來負責具體的執行過程,我們後面執行的所有指令基本都是在Master節點上運作的。

Master節點通常會占據一個獨立的伺服器

(高可用部署建議用3台伺服器),其主要原因是它太重要了,是整個叢集的“

首腦

”,如果當機或者不可用,那麼對叢集内容器應用的管理都将失效。

Master節點上運作着以下一組關鍵程序。

Master節點上關鍵程序 --

Kubernetes API Server (kube-apiserver)

提供了HTTP Rest接口的關鍵服務程序,是Kubernetes裡所有資源的增、删、改、查等操作的唯一入口,也是叢集控制的入口程序。

Kubernetes Controller Manager (kube-controller-manager)

Kubernetes裡所有資源對象的自動化控制中心,可以了解為資源對象的“大總管”。

Kubernetes Scheduler (kube-scheduler)

負責資源排程(Pod排程)的程序,相當于公交公司的“排程室”。

etcd

在Master節點上還需要啟動一個

etcd

服務,因為

Kubernetes

裡的所有資源對象的資料全部是儲存在

etcd

中的。
除了Master, Kubernetes叢集中的其他機器被稱為Node節點

2、Node角色

在較早的版本中也被稱為

Miniono

Master

一樣,

Node

節點可以是一台實體主機,也可以是一台虛拟機。 Node節點才是Kubermetes叢集中的工作負載節點,每個Node都會被Master配置設定一些工作負載(Docker容器),當某個Node當機時,其上的工作負載會被Master自動轉移到其他節點上去。

每個Node節點上都運作着以下一組關鍵程序。
每個Node節點上都運作關鍵程序

kubelet

負責Pod對應的容器的建立、啟停等任務,同時與Master節點密切協作,實作叢集管理的基本功能。

kube-proxy

實作

Kubernetes Service

通信與負載均衡機制

的重要元件。)

Docker Engine

(docker):

Docker引擎

,負責本機的容器建立和管理工作。

Node節點可以在運作期間動态增加到Kubernetes叢集中

,前提是這個節點上已經正确安裝、配置和啟動了上述關鍵程序,在預設情況下kubelet會向Master注冊自己,這也是Kubernetes推薦的Node管理方式。

一旦Node被納入叢集管理範圍, kubelet程序就會定時向Master節點彙報自身的情報,例如作業系統、Docker版本、機器的CPU和記憶體情況,以及目前有哪些Pod在運作等,這樣Master可以獲知每個Node的資源使用情況,并實作高效均衡的資源排程政策。而某個Node超過指定時間不上報資訊時,會被Master判定為“失聯", Node的狀态被标記為不可用(Not Ready),随後Master會觸發“工作負載大轉移”的自動流程。

檢視叢集中的Node節點和節點的詳細資訊

┌──[[email protected]]-[~]
└─$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           
┌──[[email protected]]-[~]
└─$kubectl describe  node vms82.liruilongs.github.io
# Node基本資訊:名稱、标簽、建立時間等。
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: 這是一個工作節點
                    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目前的運作狀态, Node啟動以後會做一系列的自檢工作:
# 比如磁盤是否滿了,如果滿了就标注OutODisk=True
# 否則繼續檢查記憶體是否不足(如果記憶體不足,就标注MemoryPressure=True)
# 最後一切正常,就設定為Ready狀态(Ready=True)
# 該狀态表示Node處于健康狀态, 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可用的系統資源,包括CPU、記憶體數量、最大可排程Pod數量等,注意到目前Kubernetes已經實驗性地支援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
# 主機系統資訊:包括主機的唯一辨別UUID, Linux kernel版本号、作業系統類型與版本、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
# 已配置設定的資源使用概要資訊,例如資源申請的最低、最大允許使用量占系統總量的百分比。  
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
┌──[[email protected]]-[~]
└─$           

總結一下,我們要操作

k8s

,在管理節點那我們怎麼操作,我們通過

kube-apiserver

來接受使用者的請求,通過

kubu-scheduler

來負責資源的排程,是使用work1計算節點來處理還是使用work2計算節點來處理,然後在每個節點上要運作一個代理服務kubelet,用來控制每個節點的操作,但是每個節點的狀态,是否健康我們不知道,這裡我們需要

kube-controller-manager

3、 Pod資源對象

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

每個Pod都有一個特殊的被稱為“根容器”的

Pause容器

Pause容器

對應的鏡像屬于Kubernetes平台的一部分,除了

Pause容器

,每個Pod還包含一個或多個緊密相關的使用者業務容器。

Pause容器

為什麼

Kubernetes

會設計出一個全新的

Pod

的概念并且

Pod

有這樣特殊的組成結構?
原因之一:在

一組容器作為一個單元

的情況下,我們難以對“整體”簡單地進行判斷及有效地進行行動。

引入業務無關并且不易死亡的Pause容器作為Pod的根容器

以它的狀态代表整個容器組的狀态

,就簡單、巧妙地解決了這個難題。
原因之二:

Pod

裡的

多個業務容器共享Pause容器的IP

,共享

Pause容器

挂接的

Volume

,這樣既簡化了

密切關聯

業務容器之間的通信

問題,也很好地解決了它們之間的

檔案共享

問題。

Pod IP

Kubernetes

為每個

Pod

都配置設定了

唯一的IP位址

,稱之為

Pod IP

,一個Pod裡的多個容器共享

Pod IP

位址。 Kuberetes要求底層網絡支援叢集内任意兩個Pod之間的TCP/P直接通信,這通常采用

虛拟二層網絡技術來實作

(鍊路層網橋),

Kubernetes

裡,一個

Pod

裡的容器與另外主機上的

Pod

容器能夠直接通信。

普通的Pod

靜态Pod (Static Pod)

Pod其實有兩種類型:

普通的Pod

靜态Pod (Static Pod)

,如果使用kubeadm的方式部署,靜态pod在node節點和master節點建立略有不同

Pod兩種類型 描述

靜态Pod (Static Pod)

并 不存放在Kubernetes的etcd存儲 裡,而是存放在某個具體的Node上的一個具體檔案中,并且隻在此Node上啟動運作。

普通的Pod

一旦被建立,就會被放入到

etcd

中存儲,随後會被

Kubernetes Masten

排程到某個具體的

Node

上并進行綁定(Binding),

随後該Pod被對應的Node上的kubelet程序執行個體化成一組相關的Docker容器并啟動起來

正常情況下,

pod

是在

master

上統一管理的,所謂

靜态pod

就是,即不是由master上建立排程的,是屬于node自身特的pod,在node上隻要啟動kubelet之後,就會自動的建立的pod。這裡了解的話,結合java靜态熟悉,靜态方法了解,即的node節點初始化的時候需要建立的一些pod

比如 kubeadm的安裝k8s的話,是以的服務都是通過容器的方式運作的。相比較二進制的方式友善很多,這裡的話,那麼涉及到master節點的相關元件在沒有k8s環境時是如何運作,建構master節點的,這裡就涉及到靜态pod的問題。

在預設情況下,當

Pod

裡的某個容器停止時,

Kubernetes

會自動檢測到這個問題并且重新啟動這個

Pod

(重新開機Pod裡的所有容器),如果Pod所在的

Node

當機,則會将這個Node上的所有Pod重新排程到其他節點上.

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

是一個事件的記錄,

記錄了事件的最早産生時間、最後重制時間、重複次數、發起者、類型,以及導緻此事件的原因等衆多資訊。

Event通常會關聯到某個具體的資源對象上,是排查故障的重要參考資訊,

Pod同樣有Event記錄,當我們發現某個Pod遲遲無法建立時,可以用

kubectl describe pod xxxx

來檢視它的描述資訊,用來定位問題的原因

Kubernetes

裡,一個計算資源進行配額限定需要設定以下兩個參數。

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

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

比如下面這段定義,表明MysQL容器申請最少0.25個CPU及64MiB記憶體,在運作過程中MySQL容器所能使用的資源配額為0.5個CPU及128MiB記憶體:
....
resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"  
...           
Pod Pod 周邊對象的示意圖
關于 Kubernetes中一些基本概念和術語筆記

4 、Lable 标簽

Label是Kubernetes系統中另外一個核心概念。

一個Label是一個key-value的鍵值對

。其中key與value由使用者自己指定。

Label可以附加到各種資源對象上,例如Node、Pod、Service、RC等

,一個資源對象可以定義任意數量的Label,同一個Label也可以被添加到任意數量的資源對象上去, Label通常在資源對象定義時确定,也可以在對象建立後動态添加,或者删除。

可以通過

給指定的資源對象捆綁一個或多個不同的Label

來實作多元度的資源分組管理功能,以便于靈活、友善地進行資源配置設定、排程、配置、部署等管理工作。

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

可以通過多個

Label Selector

表達式的組合實作複雜的條件選擇,

多個表達式之間用“,”進行分隔即可

,幾個條件之間是“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 進行關聯。
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
           

新出現的管理對象如

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

篩選要監控的Pod副本的數量

,進而實作Pod副本的數量始終符合預期設定的全自動控制流程

kube-proxy

程序

通過Service的Label Selector來選擇對應的Pod

, 自動建立起

每個Service到對應Pod的請求轉發路由表

,進而實作

Service的智能負載均衡機制

通過對某些

Node定義特定的Label

,并且在

Pod定義檔案中使用NodeSelector這種标簽排程政策

kube-scheduler

程序可以實作

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系統中的核心概念之一

,簡單來說,它其實是

定義了一個期望的場景,即聲明某種Pod的副本數量在任意時刻都符合某個預期值

,是以RC的定義包括如下幾個部分。

RC的定義

Pod

期待的副本數(replicas)
用于篩選目标

Pod

Label Selector

Pod

的副本數量小于預期數量時,用于建立新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節點上的Controller Manager元件

就得到通知,定期巡檢系統中目前

存活的目标Pod

,并確定

目标Pod執行個體的數量剛好等于此RC的期望值

,如果有過多的Pod副本在運作,系統就會停掉一些Pod,否則系統就會再自動建立一些Pod

通過RC, Kubernetes實作了使用者應用叢集的高可用性,并且大大減少了系統管理者在傳統IT環境中需要完成的許多手工運維工作(如主機監控腳本、應用監控腳本、故障恢複腳本等)

下面我們以

3個Node節點的叢集

為例,說明

Kubernetes如何通過RC來實作Pod副本數量自動控制的機制

。假如我們的RC裡定義redis-slave這個Pod需要保持3個副本,系統将可能在其中的兩個Node上建立Pod,圖1.9描述了在兩個Node上建立redis-slave Pod的情形。

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

在運作時,我們可以通過 修改RC的副本數量,來實作Pod的動态縮放(Scaling)功能,這可以通過執行

kubectl scale

指令來一鍵完成:

kubectl scale rc redsi-slave --replicas=3           

需要注意的是,删除RC并不會影響通過該RC已建立好的Pod,為了删除所有Pod,可以設定

replicas的值為0

,然後更新該RC。另外, kubectl提供了

stop和delete

指令來一次性删除RC和RC控制的全部Pod。

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

6、 Deployment

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

Deployment相對于RC的一個最大更新是我們可以随時知道目前Pod “部署”的進度。實際上由于一個Pod的建立、排程、綁定節點及在目标Node上啟動對應的容器這一完整過程需要一定的時間,是以我們期待系統啟動N個Pod副本的目标狀态,實際上是一個連續變化的“部署過程"導緻的最終狀态。

Deployment的典型使用場景有以下幾個。
Deployment的典型使用場景
建立一個Deployment對象來生成對應的Replica Set并完成Pod副本的建立過程。
檢查Deployment的狀态來看部署動作是否完成(Pod副本的數量是否達到預期的值)
更新Deployment以建立新的Pod (比如鏡像更新)。
如果目前Deployment不穩定,則復原到一個早先的Deployment版本。
暫停Deployment以便于一次性修改多個PodTemplateSpec的配置項,之後再恢複Deployment,進行新的釋出。
擴充Deployment以應對高負載。
檢視Deployment的狀态,以此作為釋出是否成功的名額。
清理不再需要的舊版本ReplicaSets。

Deployment的定義與Replica Set的定義很類似,除了API聲明與Kind類型等有所差別:

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

建立一個

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             

運作如下指令建立 Deployment:

kubectl create -f tomcat-deploment.yaml           

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

數量 解釋

DESIRED

Pod副本數量的期望值,即Deployment裡定義的Replica.

CURRENT

目前Replica的值,實際上是Deployment所建立的Replica Set裡的Replica值,這個值不斷增加,直到達到DESIRED為止,表明整個部署過程完成。

UP-TO-DATE

最新版本的Pod的副本數量,用于訓示在滾動更新的過程中,有多少個Pod副本已經成功更新。

AVAILABLE

目前叢集中可用的Pod副本數量,即叢集中目前存活的Pod數量。

運作下述指令檢視對應的

Replica Set

,我們看到它的命名與

Deployment

的名字有關系:

┌──[[email protected]]-[~/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的副本數,這是HPA的實作原理 。目前, HPA可以有以下兩種方式作為Pod負載的度量名額。

Horizontal Pod Autoscaler
CPUUtilizationPercentage.
應用程式自定義的度量名額,比如服務在每秒内的相應的請求數(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%

根據上面的定義,我們可以知道這個

HPA控制的目标對象為一個名叫php-apache Deployment裡的Pod副本,當這些Pod副本的CPUUtilizationPercentage的值超過90%時會觸發自動動态擴容行為,擴容或縮容時必須滿足的一個限制條件是Pod的副本數要介于1與10之間

除了可以通過直接定義yaml檔案并且調用

kubectrl create

的指令來建立一個HPA資源對象的方式,我們還能通過下面的簡單指令行直接建立等價的

HPA對象

:

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

8、 StatefulSet

在Kubernetes系統中, Pod的管理對象RC, Deployment, DaemonSet和Job都是面向無狀态的服務。 但現實中有很多服務是有狀态的,特别是一些複雜的中間件叢集,例如MysQL集·群、MongoDB叢集、ZooKeeper叢集等,這些應用叢集有以下一些共同點:

共同點
每個節點都有固定的身份ID,通過這個ID,叢集中的成員可以互相發現并且通信。
叢集的規模是比較固定的,叢集規模不能随意變動。
叢集裡的每個節點都是有狀态的,通常會持久化資料到永久存儲中。
如果磁盤損壞,則叢集裡的某個節點無法正常運作,叢集功能受損
如果用

RC/Deployment控制Pod副本數

的方式來實作上述

有狀态的叢集

,則我們會發現第1點是無法滿足的,因為Pod的名字是随機産生的,

Pod的IP位址也是在運作期才确定且可能有變動的

,我們事先無法為每個Pod确定唯一不變的ID,

為了能夠在其他節點上恢複某個失敗的節點,這種叢集中的Pod需要挂接某種共享存儲,為了解決這個問題, Kubernetes從v1.4版本開始引入了

PetSet這個新的資源對象

,并且在v1.5版本時更名為

StatefulSet

StatefulSet從本質上來說,可以看作DeploymentRC的一個特殊變種,它有如下一些特性。)

特性

StatefulSet

裡的每個Pod都有

穩定、唯一的網絡辨別

,可以用來發現叢集内的其他成員。假設

StatefulSet

的名字叫kafka,那麼第1個Pod 叫 kafka-0,第2個叫kafk-1,以此類推。)

StatefulSet控制的Pod副本的啟停順序是受控的

,操作第n個Pod時,前n-1個Pod已經是運作且準備好的狀态)

StatefulSet裡的Pod采用穩定的持久化存儲卷

,通過PV/PVC來實作,删除Pod時預設不會删除與StatefulSet相關的存儲卷(為了保證資料的安全)。

statefulSet除了要與PV卷捆綁使用以存儲Pod的狀态資料

,還要與

Headless Service

配合使用,即在每個

StatefulSet

的定義中要聲明它屬于哪個Headless Service. Headless Service與普通Service的關鍵差別在于,它沒有Cluster IP,如果解析Headless Service的DNS域名,則傳回的是該Service對應的全部Pod的Endpoint清單。StatefulSet在Headless

Service的基礎上又為StatefulSet控制的每個Pod執行個體建立了一個DNS域名

,這個域名的格式為:

$(podname).$(headless service name)            

9、 Service (服務)

Service也是Kubernetes裡的最核心的資源對象之一

, Kubernetes裡的每個Service其實就是我們經常提起的微服務架構中的一個“微服務”,之前我們所說的Pod, RC等資源對象其實都是為這節所說的“服務”-Kubernetes Service作“嫁衣”的。Pod,RC與Service的邏輯關系。

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

Kubernetes的Service定義了一個服務的通路入口位址

前端的應用(Pod)

通過這個入口位址通路其背後的一組由Pod副本組成的叢集執行個體, Service與其後端Pod副本叢集之間則是通過Label Selector來實作“無縫對接”的。而RC的作用實際上是保證Service的服務能力和服務品質始終處幹預期的标準。

每個Pod都會被配置設定一個單獨的IP位址,而且每個Pod都提供了一個獨立的

Endpoint(Pod IP+ContainerPort)

以被用戶端通路,現在多個Pod副本組成了一個叢集來提供服務.用戶端如何來通路它們呢?一般的做法是部署一個負載均衡器(軟體或硬體),

Kubernetes

中運作在每個

Node

上的

kube-proxy

程序其實就是一個

智能的軟體負載均衡器

,它負責把對Service的請求轉發到後端的某個Pod執行個體上,并在内部實作服務的負載均衡與會話保持機制。

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

Service不是共用一個負載均衡器的IP位址,而是每個

Service

配置設定了一個全局唯一的虛拟IP位址,這個虛拟IP被稱為

Cluster IP

,這樣一來,

每個服務就變成了具備唯一IP位址的“通信節點”

服務調用就變成了最基礎的TCP網絡通信問題

我們知道, Pod的Endpoint位址會随着Pod的銷毀和重新建立而發生改變,因為新Pod的IP位址與之前舊Pod的不同。而 Service一旦被建立, Kubernetes就會自動為它配置設定一個可用的Cluster IP,而且在Service的整個生命周期内,它的Cluster IP不會發生改變。于是,服務發現這個棘手的問題在Kubernetes的架構裡也得以輕松解決:隻要用Service的Name與Service的Cluster IP位址做一個DNS域名映射即可完美解決問題。

┌──[[email protected]]-[~/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定義一個名字來區分。下面是Tomcat多端口的Service定義樣例:

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

Kubernetes 的服務發現機制

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

外部系統通路 Service 的問題

Kubernetes裡的“三種IP"
Node IP Node 節點的IP位址,Node IP是Kubernetes叢集中每個節點的實體網卡的IP位址,這是一個真實存在的實體網絡,所有屬于這個網絡的伺服器之間都能通過這個網絡直接通信,不管它們中是否有部分節點不屬于這個Kubernetes叢集。這也表明了Kubernetes叢集之外的節點通路Kubernetes叢集之内的某個節點或者TCP/IP服務時,必須要通過Node IP進行通信。
Pod 的 IP 位址:Pod IP是每個Pod的IP位址,它是

Docker Engine

根據dockero網橋的IP位址段進行配置設定的,通常是一個虛拟的二層網絡,前面我們說過, Kubernetes要求位于不同Node上的Pod能夠彼此直接通信,是以Kubernetes裡一個Pod裡的容器通路另外一個Pod裡的容器,就是通過Pod IP所在的虛拟二層網絡進行通信的,而真實的TCP/IP流量則是通過Node IP所在的實體網卡流出的。
Cluster IP Service 的IP位址,Cluster IP僅僅作用于Kubernetes Service這個對象,并由Kubernetes管理和配置設定IP位址(來源于Cluster IP位址池)。Cluster IP無法被Ping,因為沒有一個“實體網絡對象”來響應。Cluster IP隻能結合Service Port組成一個具體的通信端口,單獨的Cluster IP不具備TCPIP通信的基礎,并且它們屬于Kubernetes叢集這樣一個封閉的空間,叢集之外的節點如果要通路這個通信端口,則需要做一些額外的工作。在Kubernetes叢集之内, Node IP網、Pod IP網與Cluster IP網之間的通信,采用的是Kubermetes自己設計的一種程式設計方式的特殊的路由規則,與我們所熟知的IP路由有很大的不同。
外部系統通路 Service,采用NodePort是解決上述問題的最直接、最有效、最常用的做法。具體做法如下,以tomcat-service為例,我們在Service的定義裡做如下擴充即可:
...
spec:
  type: NodePort
  posts:
   - port: 8080
     nodePort: 31002
  selector:
    tier: frontend   
...           

即這裡我們可以通過nodePort:31002 來通路Service,NodePort的實作方式是在Kubernetes叢集裡的每個Node上為需要外部通路的Service開啟個對應的TCP監聽端口,外部系統隻要用任意一個Node的IP位址+具體的NodePort端口即可通路此服務,在任意Node上運作netstat指令,我們就可以看到有NodePort端口被監聽:

Service 負載均衡問題

NodePort

還沒有完全解決外部通路

Service

的所有問題,比如

負載均衡

問題,假如我們的

叢集中有10個Node

,則此時最好有一個

負載均衡器

,外部的請求隻需通路此

負載均衡器的IP位址

,由負載均衡器負責轉發流量到後面某個Node的NodePort上。如圖

NodePort的負載均衡
關于 Kubernetes中一些基本概念和術語筆記

Load balancer

元件獨立于

Kubernetes叢集

之外,通常是一個

硬體的負載均衡器

,或者是以

軟體方式實作

的,例如

HAProxy

或者

Nginx

。對于每個Service,我們通常需要配置一個對應的Load balancer執行個體來轉發流量到後端的Node上

Kubernetes

提供了

自動化的解決方案

,如果我們的叢集運作在

谷歌的GCE公有雲

上,那麼隻要我們把

Service的type-NodePort改為type-LoadBalancer

,此時

Kubernetes

會自動建立一個對應的

Load balancer

執行個體并傳回它的

IP位址供外部用戶端使用

10、 Volume (存儲卷)

Volume是Pod中能夠被多個容器通路的共享目錄。

Kuberetes的Volume概念、用途和目的與Docker的Volume比較類似,但兩者不能等價

Volume (存儲卷)
Kubernetes中的

Volume定義在Pod上

,然後被一個Pod裡的多個容器挂載到具體的檔案目錄下;

Volume與Pod的生命周期相同

,但與

容器的生命周期不相關

當容器終止或者重新開機時, Volume中的資料也不會丢失。

Kubernetes支援

多種類型的Volume

,例如

GlusterFS, Ceph

等先進的

分布式檔案系統

Volume

的使用也比較簡單,在大多數情況下,我們先在

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

多個容器共享檔案、讓容器的資料寫到主控端的磁盤上或者寫檔案到網絡存儲中

Kubernetes的Volume

還擴充出了一種非常有實用價值的功能,即

容器配置檔案集中化定義與管理,這是通過

ConfigMap

這個新的資源對象來實作的.

Kubernetes提供了非常豐富的

Volume類型

,下面逐一進行說明。

1. emptyDir

一個emptyDir Volume是在Pod配置設定到Node時建立的。從它的名稱就可以看出,它的

初始内容為空

,并且無須指定主控端上對應的目錄檔案,因為這是 Kubernetes自動配置設定的一個目錄,

當Pod從Node上移除時, emptyDir中的資料也會被永久删除

。emptyDir的一些用途如下。

emptyDir的一些用途
臨時空間,例如用于某些應用程式運作時所需的臨時目錄,且無須永久保留。
長時間任務的中間過程CheckPoint的臨時儲存目錄。
一個容器需要從另一個容器中擷取資料的目錄(多容器共享目錄)

2. hostPath

hostPath為在Pod上挂載主控端上的檔案或目錄

,它通常可以用于以下幾方面。

|容器應用程式生成的日志檔案需要永久儲存時,可以使用主控端的高速檔案系統進行存儲。|

需要通路主控端上

Docker

引擎内部資料結構的容器應用時,可以通過定義

hostPath

為主控端

/var/lib/docker

目錄,使容器内部應用可以直接通路

Docker

的檔案系統。

在使用這種類型的

Volume

時,需要注意以下幾點。

在不同的Node上具有相同配置的

Pod

可能會因為主控端上的目錄和檔案不同而導緻對

Volume

上目錄和檔案的通路結果不一緻。)

如果使用了資源配額管理,則Kubernetes無法将hostPath在主控端上使用的資源納入管理。在下面的例子中使用主控端的/data目錄定義了一個

hostPath

類型的

Volume

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

3. gcePersistentDisk

使用這種類型的Volume表示使用谷歌公有雲提供的永久磁盤(PersistentDisk, PD)存放Volume的資料,它與emptyDir不同, PD上的内容會被永久存,當Pod被删除時, PD隻是被解除安裝(Unmount),但不會被删除。需要注意是,你需要先建立一個永久磁盤(PD),才能使用gcePersistentDisk.

4. awsElasticBlockStore

與GCE類似,該類型的Volume使用亞馬遜公有雲提供的EBS Volume存儲資料,需要先建立一個EBS Volume才能使用awsElasticBlockStore.

5. NFS

使用NFS網絡檔案系統提供的共享目錄存儲資料時,我們需要在系統中部署一個NFSServer,定義NES類型的Volume的示例如下

yum -y install nfs-utils

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

11、 Persistent Volume

Volume

是定義在

Pod

上的,屬于“

計算資源

”的一部分,而實際上, “

網絡存儲

”是相對獨立于“

計算資源

”而存在的一種

實體資源

。比如在使用

虛拟機

的情況下,我們通常會先定義一個網絡存儲,然後從中劃出一個“網盤”并挂接到

虛拟機

Persistent Volume(簡稱PV)

和與之相關聯的

Persistent Volume Claim (簡稱PVC)

也起到了類似的作用。

PV

可以了解成 Kubernetes叢集中的某個網絡存儲中對應的一塊存儲,它與Volume很類似,但有以下差別。

Persistent Volume與Volume的差別
PV隻能是網絡存儲,不屬于任何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

是有狀态的對象,它有以下幾種狀态。|

|:--|

Available

:空閑狀态。|

Bound

:已經綁定到某個Pvc上。|

Released

:對應的PVC已經删除,但資源還沒有被叢集收回。|

Failed

: PV自動回收失敗。|

12、 Namespace (命名空間)

Namespace (命名空間)是Kubernetes系統中非常重要的概念, Namespace在很多情況下用于實作 多租戶的資源隔離。Namespace通過将叢集内部的資源對象“配置設定”到不同的Namespace 中,形成邏輯上分組的不同項目、小組或使用者組,便于不同的分組在共享使用整個叢集的資源的同時還能被分别管理。Kubernetes叢集在啟動後,會建立一個名為

"default"

Namespace

,通過

kubectl

可以檢視到:

不同的namespace之間互相隔離
檢視所有命名空間 kubectl get ns
檢視目前命名空間 kubectl config get-contexts
設定命名空間 kubectl config set-context 叢集名 --namespace=命名空間

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

┌──[[email protected]]-[~/ansible]
└─$kubectl get namespaces
NAME              STATUS   AGE
default           Active   13h
kube-node-lease   Active   13h
kube-public       Active   13h
kube-system       Active   13h
┌──[[email protected]]-[~/ansible]
└─$kubectl get ns
NAME              STATUS   AGE
default           Active   13h
kube-node-lease   Active   13h
kube-public       Active   13h
kube-system       Active   13h
┌──[[email protected]]-[~/ansible]
└─$           

命名空間基本指令

┌──[[email protected]]-[~/ansible]
└─$kubectl create ns liruilong
namespace/liruilong created
┌──[[email protected]]-[~/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
┌──[[email protected]]-[~/ansible]
└─$kubectl create ns k8s-demo
namespace/k8s-demo created
┌──[[email protected]]-[~/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
┌──[[email protected]]-[~/ansible]
└─$kubectl delete ns  k8s-demo
namespace "k8s-demo" deleted
┌──[[email protected]]-[~/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
┌──[[email protected]]-[~/ansible]
└─$           

命名空間切換

┌──[[email protected]]-[~/.kube]
└─$vim config
┌──[[email protected]]-[~/.kube]
└─$kubectl config get-contexts
CURRENT   NAME       CLUSTER    AUTHINFO            NAMESPACE
*         context1   cluster1   kubernetes-admin1
          context2   cluster2   kubernetes-admin2
┌──[[email protected]]-[~/.kube]
└─$kubectl config set-context context2 --namespace=kube-system
Context "context2" modified.
┌──[[email protected]]-[~/.kube]
└─$kubectl config get-contexts
CURRENT   NAME       CLUSTER    AUTHINFO            NAMESPACE
*         context1   cluster1   kubernetes-admin1
          context2   cluster2   kubernetes-admin2   kube-system
┌──[[email protected]]-[~/.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           

建立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: {}           

當我們給每個租戶建立一個Namespace來實作多租戶的資源隔離時,還能

結合Kubernetes"的資源配額管理,限定不同租戶能占用的資源,例如CPU使用量、記憶體使用量

等。

13、 Annotation (注解)

Annotation與Label類似,也使用

key/value鍵值

對的形式進行定義。

不同的是Label具有嚴格的命名規則,它定義的是Kubernetes對象的中繼資料(Metadata),并且用于Label Selector.

Annotation則是使用者任意定義的“附加”資訊,以便于外部工具進行查找, Kubernetes的子產品自身會通過Annotation的方式标記資源對象的一些特殊資訊。

┌──[[email protected]]-[~/ansible/k8s-pod-create]
└─$kubectl annotate nodes vms82.liruilongs.github.io "dest=這是一個工作節點"
node/vms82.liruilongs.github.io annotated
┌──[[email protected]]-[~/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: 這是一個工作節點
                    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位址等。
日志庫、監控庫、分析庫等資源庫的位址資訊。
程式調試工具資訊,例如工具名稱、版本号等。
團隊的聯系資訊,例如電話号碼、負責人名稱、網址等。
上一篇: ECS使用體驗
下一篇: ECS使用體驗