寫在前面
- 學習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
|
---|
1、Master角色
Kubernetes裡的Master指的是
叢集控制節點
,每個Kubernetes叢集裡需要有一個Master節點來負責整個叢集的管理和控制,基本上Kubernetes的所有控制指令都發給它,它來負責具體的執行過程,我們後面執行的所有指令基本都是在Master節點上運作的。
Master節點通常會占據一個獨立的伺服器
(高可用部署建議用3台伺服器),其主要原因是它太重要了,是整個叢集的“
首腦
”,如果當機或者不可用,那麼對叢集内容器應用的管理都将失效。
Master節點上運作着以下一組關鍵程序。
Master節點上關鍵程序 | -- |
---|---|
| 提供了HTTP Rest接口的關鍵服務程序,是Kubernetes裡所有資源的增、删、改、查等操作的唯一入口,也是叢集控制的入口程序。 |
| Kubernetes裡所有資源對象的自動化控制中心,可以了解為資源對象的“大總管”。 |
| 負責資源排程(Pod排程)的程序,相當于公交公司的“排程室”。 |
| 在Master節點上還需要啟動一個 服務,因為 裡的所有資源對象的資料全部是儲存在 中的。 |
除了Master, Kubernetes叢集中的其他機器被稱為Node節點
2、Node角色
在較早的版本中也被稱為
Miniono
與
Master
一樣,
Node
節點可以是一台實體主機,也可以是一台虛拟機。 Node節點才是Kubermetes叢集中的工作負載節點,每個Node都會被Master配置設定一些工作負載(Docker容器),當某個Node當機時,其上的工作負載會被Master自動轉移到其他節點上去。
每個Node節點上都運作着以下一組關鍵程序。
每個Node節點上都運作關鍵程序 | |
---|---|
| 負責Pod對應的容器的建立、啟停等任務,同時與Master節點密切協作,實作叢集管理的基本功能。 |
| 實作 的 的重要元件。) |
| (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容器
為什麼 會設計出一個全新的 的概念并且 有這樣特殊的組成結構? |
---|
原因之一:在 的情況下,我們難以對“整體”簡單地進行判斷及有效地進行行動。 ,就簡單、巧妙地解決了這個難題。 |
原因之二: 裡的 ,共享 挂接的 ,這樣既簡化了 問題,也很好地解決了它們之間的 問題。 |
Pod IP
Kubernetes
為每個
Pod
都配置設定了
唯一的IP位址
,稱之為
Pod IP
,一個Pod裡的多個容器共享
Pod IP
位址。 Kuberetes要求底層網絡支援叢集内任意兩個Pod之間的TCP/P直接通信,這通常采用
虛拟二層網絡技術來實作
(鍊路層網橋),
在裡,一個
Kubernetes
裡的容器與另外主機上的
Pod
容器能夠直接通信。
Pod
普通的Pod
及 靜态Pod (Static Pod)
普通的Pod
靜态Pod (Static Pod)
Pod其實有兩種類型:
普通的Pod
靜态Pod (Static Pod)
,如果使用kubeadm的方式部署,靜态pod在node節點和master節點建立略有不同
Pod兩種類型 | 描述 |
---|---|
| 并 不存放在Kubernetes的etcd存儲 裡,而是存放在某個具體的Node上的一個具體檔案中,并且隻在此Node上啟動運作。 |
| 一旦被建立,就會被放入到 中存儲,随後會被 排程到某個具體的 上并進行綁定(Binding), |
正常情況下,
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 周邊對象的示意圖
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的定義 |
---|
期待的副本數(replicas) |
用于篩選目标 |
當 的副本數量小于預期數量時,用于建立新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的情形。
在運作時,我們可以通過 修改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
對上述輸出中涉及的數量解釋如下。
數量 | 解釋 |
---|---|
| Pod副本數量的期望值,即Deployment裡定義的Replica. |
| 目前Replica的值,實際上是Deployment所建立的Replica Set裡的Replica值,這個值不斷增加,直到達到DESIRED為止,表明整個部署過程完成。 |
| 最新版本的Pod的副本數量,用于訓示在滾動更新的過程中,有多少個Pod副本已經成功更新。 |
| 目前叢集中可用的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确定唯一不變的ID,
Pod的IP位址也是在運作期才确定且可能有變動的
為了能夠在其他節點上恢複某個失敗的節點,這種叢集中的Pod需要挂接某種共享存儲,為了解決這個問題, Kubernetes從v1.4版本開始引入了
PetSet這個新的資源對象
,并且在v1.5版本時更名為
StatefulSet
StatefulSet從本質上來說,可以看作DeploymentRC的一個特殊變種,它有如下一些特性。)
特性 |
---|
裡的每個Pod都有 ,可以用來發現叢集内的其他成員。假設 的名字叫kafka,那麼第1個Pod 叫 kafka-0,第2個叫kafk-1,以此類推。) |
,操作第n個Pod時,前n-1個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的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位址,它是 根據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的負載均衡 |
---|
元件獨立于 之外,通常是一個 ,或者是以 的,例如 或者 。對于每個Service,我們通常需要配置一個對應的Load balancer執行個體來轉發流量到後端的Node上 |
提供了 ,如果我們的叢集運作在 上,那麼隻要我們把 ,此時 會自動建立一個對應的 執行個體并傳回它的 |
10、 Volume (存儲卷)
Volume是Pod中能夠被多個容器通路的共享目錄。
Kuberetes的Volume概念、用途和目的與Docker的Volume比較類似,但兩者不能等價
Volume (存儲卷) |
---|
Kubernetes中的 ,然後被一個Pod裡的多個容器挂載到具體的檔案目錄下; |
,但與 |
Kubernetes支援 ,例如 等先進的 |
的使用也比較簡單,在大多數情況下,我們先在
Volume
上聲明一個
Pod
,然後在容器裡引用該
Volume
并
Volume
到容器裡的某個目錄上。舉例來說,我們要給之前的
Mount
增加一個名字為
Tomcat Pod
datavol
,并且
Volume
到容器的
Mount
目錄上,則隻要對Pod的定義檔案做如下修正即可(注意黑體字部分):
/mydata-data
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位址等。 |
日志庫、監控庫、分析庫等資源庫的位址資訊。 |
程式調試工具資訊,例如工具名稱、版本号等。 |
團隊的聯系資訊,例如電話号碼、負責人名稱、網址等。 |