国产精品chinese,色综合天天综合精品网国产在线,成午夜免费视频在线观看,清纯女学生被强行糟蹋小说

    <td id="ojr13"><tr id="ojr13"><label id="ojr13"></label></tr></td>
        • <source id="ojr13"></source>
            <td id="ojr13"><ins id="ojr13"><label id="ojr13"></label></ins></td>

            Article / 文章中心

            關(guān)于 Kubernetes中一些基本概念和術(shù)語筆記

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

            一、簡述

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

            K8s中相關(guān)資源:隨版本變化

            ┌──[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é)點來負(fù)責(zé)整個集群的管理和控制,基本上Kubernetes的所有控制命令都發(fā)給它,它來負(fù)責(zé)具體的執(zhí)行過程,我們后面執(zhí)行的所有命令基本都是在Master節(jié)點上運(yùn)行的。

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

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

            2、Node角色

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

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

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

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

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

            ┌──[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基本信息:名稱、標(biāo)簽、創(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當(dāng)前的運(yùn)行狀態(tài), Node啟動以后會做一系列的自檢工作: # 比如磁盤是否滿了,如果滿了就標(biāo)注OutODisk=True # 否則繼續(xù)檢查內(nèi)存是否不足(如果內(nèi)存不足,就標(biāo)注MemoryPressure=True) # 最后一切正常,就設(shè)置為Ready狀態(tài)(Ready=True) # 該狀態(tài)表示Node處于健康狀態(tài), Master將可以在其上調(diào)度新的任務(wù)了(如啟動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的主機(jī)地址與主機(jī)名。  Addresses:
              InternalIP:  192.168.26.82
              Hostname:    vms82.liruilongs.github.io # Node上的資源總量:描述Node可用的系統(tǒng)資源,包括CPU、內(nèi)存數(shù)量、最大可調(diào)度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當(dāng)前可用于分配的資源量。 Allocatable:
              cpu:                2
              ephemeral-storage:  144884367121
              hugepages-1Gi:      0
              hugepages-2Mi:      0
              memory:             3927772Ki
              pods:               110 # 主機(jī)系統(tǒng)信息:包括主機(jī)的唯一標(biāo)識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 # 當(dāng)前正在運(yùn)行的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相關(guān)的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]-[~]
            └─$

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

            3、 Pod資源對象

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

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

            Pause容器

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

            Pod IP

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

            在Kubernetes里,一個Pod里的容器與另外主機(jī)上的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上啟動運(yùn)行。
            普通的Pod 一旦被創(chuàng)建,就會被放入到etcd中存儲,隨后會被Kubernetes Masten調(diào)度到某個具體的Node上并進(jìn)行綁定(Binding),隨后該P(yáng)od被對應(yīng)的Node上的kubelet進(jìn)程實例化成一組相關(guān)的Docker容器并啟動起來。

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

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

            在默認(rèn)情況下,當(dāng)Pod里的某個容器停止時,Kubernetes會自動檢測到這個問題并且重新啟動這個Pod (重啟Pod里的所有容器),如果Pod所在的Node宕機(jī),則會將這個Node上的所有Pod重新調(diào)度到其他節(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是一個事件的記錄,記錄了事件的最早產(chǎn)生時間、最后重現(xiàn)時間、重復(fù)次數(shù)、發(fā)起者、類型,以及導(dǎo)致此事件的原因等眾多信息。Event通常會關(guān)聯(lián)到某個具體的資源對象上,是排查故障的重要參考信息,

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

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

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

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

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

            在這里插入圖片描述

            4 、Lable 標(biāo)簽

            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)多維度的資源分組管理功能,以便于靈活、方便地進(jìn)行資源分配、調(diào)度、配置、部署等管理工作。

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

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

            name=標(biāo)簽名
            env != 標(biāo)簽名
            name in (標(biāo)簽1,標(biāo)簽2)
            name not in(標(biāo)簽1)
            name in (redis-master, redis-slave):匹配所有具有標(biāo)簽`name=redis-master`或者`name=redis-slave`的資源對象。
            name not in (phn-frontend):匹配所有不具有標(biāo)簽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 進(jìn)行關(guān)聯(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用于定義一組基于集合的篩選條件,可用的條件運(yùn)算符包括: In, NotIn, Exists和DoesNotExist.

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

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

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

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

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

            apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: podnodea name: podnodea spec: containers: - image: nginx imagePullPolicy: IfNotPresent name: podnodea resources: {} affinity: nodeAffinity: #主機(jī)親和性 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ù)量在任意時刻都符合某個預(yù)期值,所以RC的定義包括如下幾個部分。

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

            下面是一個完整的RC定義的例子,即確保擁有tier-frontend標(biāo)簽的這個Pod (運(yùn)行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

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

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

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

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

            kubectl scale rc redsi-slave --replicas=3

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

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

            6、 Deployment

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

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

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

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

            kubectl create -f tomcat-deploment.yaml

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

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

            運(yùn)行下述命令查看對應(yīng)的Replica Set,我們看到它的命名與Deployment的名字有關(guān)系:

            ┌──[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控制的所有目標(biāo)Pod的負(fù)載變化情況,來確定是否需要針對性地調(diào)整目標(biāo)Pod的副本數(shù),這是HPA的實現(xiàn)原理 。當(dāng)前, HPA可以有以下兩種方式作為Pod負(fù)載的度量指標(biāo)。

            Horizontal Pod Autoscaler
            CPUUtilizationPercentage.
            應(yīng)用程序自定義的度量指標(biāo),比如服務(wù)在每秒內(nèi)的相應(yīng)的請求數(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是一個算術(shù)平均值,即目標(biāo)Pod所有副本自身的CPU利用率的平均值。一個Pod自身的CPU利用率是該P(yáng)od當(dāng)前CPU的使用量除以它的Pod Request的值,比,如我們定義一個Pod的Pod Request為0.4,而當(dāng)前Pod的CPU使用量為0.2,則它的CPU使用率為50%

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

            除了可以通過直接定義yaml文件并且調(diào)用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)的服務(wù)。 但現(xiàn)實中有很多服務(wù)是有狀態(tài)的,特別是一些復(fù)雜的中間件集群,例如MysQL集·群、MongoDB集群、ZooKeeper集群等,這些應(yīng)用集群有以下一些共同點:

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

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

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

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

            $(podname).$(headless service name)

            9、 Service (服務(wù))

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

            在這里插入圖片描述

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

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

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

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

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

            我們知道, Pod的Endpoint地址會隨著Pod的銷毀和重新創(chuàng)建而發(fā)生改變,因為新Pod的IP地址與之前舊Pod的不同。而 Service一旦被創(chuàng)建, Kubernetes就會自動為它分配一個可用的Cluster IP,而且在Service的整個生命周期內(nèi),它的Cluster IP不會發(fā)生改變。于是,服務(wù)發(fā)現(xiàn)這個棘手的問題在Kubernetes的架構(gòu)里也得以輕松解決:只要用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的服務(wù)發(fā)現(xiàn)機(jī)制了

            Kubernetes 的服務(wù)發(fā)現(xiàn)機(jī)制

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

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

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

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

            Service 負(fù)載均衡問題

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

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

            10、 Volume (存儲卷)

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

            Volume (存儲卷)
            Kubernetes中的Volume定義在Pod上,然后被一個Pod里的多個容器掛載到具體的文件目錄下;
            Kubernetes中的Volume與Pod的生命周期相同,但與容器的生命周期不相關(guān),當(dāng)容器終止或者重啟時, Volume中的數(shù)據(jù)也不會丟失。
            Kubernetes支持多種類型的Volume,例如GlusterFS, Ceph等先進(jìn)的分布式文件系統(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ù)寫到宿主機(jī)的磁盤上或者寫文件到網(wǎng)絡(luò)存儲中, Kubernetes的Volume還擴(kuò)展出了一種非常有實用價值的功能,即

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

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

            1. emptyDir

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

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

            2. hostPath

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

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

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

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

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

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

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

            3. gcePersistentDisk

            使用這種類型的Volume表示使用谷歌公有云提供的永久磁盤(PersistentDisk, PD)存放Volume的數(shù)據(jù),它與emptyDir不同, PD上的內(nèi)容會被永久存,當(dāng)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)絡(luò)文件系統(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)絡(luò)存儲”是相對獨立于“計算資源”而存在的一種實體資源。比如在使用虛擬機(jī)的情況下,我們通常會先定義一個網(wǎng)絡(luò)存儲,然后從中劃出一個“網(wǎng)盤”并掛接到虛擬機(jī)上

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

            Persistent Volume與Volume的區(qū)別
            PV只能是網(wǎng)絡(luò)存儲,不屬于任何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 (僅供單機(jī)測試)。
            apiversion: v1 kind: PersistentVolume metadata: name: pv0003 spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce nfs: path: /somepath server: 172.17.0.2

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

            • ReadWriteOnce:讀寫權(quán)限、并且只能被單個Node掛載。
            • ReadOnlyMany:只讀權(quán)限、允許被多個Node掛載。
            • ReadWriteMany:讀寫權(quán)限、允許被多個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:對應(yīng)的PVC已經(jīng)刪除,但資源還沒有被集群收回。|
            |Failed: PV自動回收失敗。|

            12、 Namespace (命名空間)

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

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

            kub-system 本身的各種 pod,是kubamd默認(rèn)的空間。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: {}

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

            13、 Annotation (注解)

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

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

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

            ┌──[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)控庫、分析庫等資源庫的地址信息。
            程序調(diào)試工具信息,例如工具名稱、版本號等。
            團(tuán)隊的聯(lián)系信息,例如電話號碼、負(fù)責(zé)人名稱、網(wǎng)址等。