天天看點

Kubernetes 核心對象概覽詳解

之前說了k8s對象共性的部分,包括typemeta定義了這個對象是什麼,metadata定義了對象是誰,以及spec是使用者的期望,往往都是使用者輸入的,status是對象的狀态,一般是由控制器去更新。

typemeta和metadata是所有對象共性共有的,spec每個對象長的不一樣。

Node

Node是Pod真正運作的主機,可以實體機,也可以是虛拟機。

為了管理Pod,每個Node節點上至少要運作container runtime ·

(比如 Docker 或者 Rkt)、Kubelet和 Kube-proxy服務。

node就是計算節點,k8s第一個層面的能力就是叢集管理能力,将一堆的計算節點放到叢集裡面,那麼每一個計算節點就代表一個node對象。

這部分是typemeta,這裡v1前面其實是有group的資訊的,但是node是core group,是以這裡可以省略。

有些項目比如calico,是叢集的cni插件,它想寫一些屬性到這個節點上面,但是又沒有地方寫,是以它将資訊寫到了annotation裡面,是以annotation就是這個對象的擴充屬性。

[root@master ~]# kubectl get node master -o yaml
apiVersion: v1
kind: Node
metadata:
  annotations:
    kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
    node.alpha.kubernetes.io/ttl: "0"
    projectcalico.org/IPv4Address: 192.168.111.6/24
    projectcalico.org/IPv4IPIPTunnelAddr: 10.244.219.64
    volumes.kubernetes.io/controller-managed-attach-detach: "true"
  creationTimestamp: "2022-04-18T09:00:46Z"
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: master
    kubernetes.io/os: linux
    node-role.kubernetes.io/master: ""      

spec對于節點來說資訊非常少,也就是節點需要配置的屬性非常少,也就是配置這個節點pod的cidr,其實也就是配置了這個節點的sybnet,也就是這個節點的pod能夠使用哪個子網去配置設定ip。

spec:
  podCIDR: 10.244.0.0/24
  podCIDRs:
  - 10.244.0.0/24
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master      

最後就是status,當我們要去關心節點的,要去關心它的健康狀況,它的近十年來等等這些資訊,其實都是它的狀态上報。

address:ip和主機名是什麼

 allocatable:節點能夠配置設定的資源是多少,包括cpu memory,資源并不是可以全部使用資源的,能夠使用多少,這裡面定義了

  capacity:這個節點最大的能力是多少,也就是有多少硬體資源

status:
  addresses:
  - address: 192.168.111.6
    type: InternalIP
  - address: master
    type: Hostname
  allocatable:
    cpu: "1"
    ephemeral-storage: "16871797528"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 1538360Ki
    pods: "110"
  capacity:
    cpu: "1"
    ephemeral-storage: 17878Mi
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 1640760Ki
    pods: "110"      

conditions包含了節點的健康狀态,比如kernel有沒有deadlock,比如你的cni插件是不是ready的,比如是否有足夠的記憶體。硬碟是不是承壓,比如pid是不是足夠。

所有這些conditation最後決定了這個節點的健康狀況。

如果不健康了,k8s就會去做一些事情來確定這個節點不會壓垮。

conditions:
  - lastHeartbeatTime: "2022-06-21T23:40:17Z"
    lastTransitionTime: "2022-06-21T23:40:17Z"
    message: Calico is running on this node
    reason: CalicoIsUp
    status: "False"
    type: NetworkUnavailable
  - lastHeartbeatTime: "2022-06-25T01:12:44Z"
    lastTransitionTime: "2022-06-23T20:05:46Z"
    message: kubelet has sufficient memory available
    reason: KubeletHasSufficientMemory
    status: "False"
    type: MemoryPressure
  - lastHeartbeatTime: "2022-06-25T01:12:44Z"
    lastTransitionTime: "2022-06-23T20:05:46Z"
    message: kubelet has no disk pressure
    reason: KubeletHasNoDiskPressure
    status: "False"
    type: DiskPressure
  - lastHeartbeatTime: "2022-06-25T01:12:44Z"
    lastTransitionTime: "2022-06-23T20:05:46Z"
    message: kubelet has sufficient PID available
    reason: KubeletHasSufficientPID
    status: "False"
    type: PIDPressure
  - lastHeartbeatTime: "2022-06-25T01:12:44Z"
    lastTransitionTime: "2022-06-23T20:05:46Z"
    message: kubelet is posting ready status
    reason: KubeletReady
    status: "True"
    type: Ready
  daemonEndpoints:
    kubeletEndpoint:
      Port: 10250      

最後可以看到節點上有哪些鏡像,鏡像有哪些版本,大小是多少

images:
  - names:
    - calico/node@sha256:b386769a293d180cb6ee208c8594030128a0810b286a93ae897a231ef247afa8
    - calico/node:v3.15.1
    sizeBytes: 262367223
  - names:
    - registry.aliyuncs.com/google_containers/etcd@sha256:735f090b15d5efc576da1602d8c678bf39a7605c0718ed915daec8f2297db2ff
    - registry.aliyuncs.com/google_containers/etcd:3.4.9-1
    sizeBytes: 253331281
  - names:
    - calico/cni@sha256:b86711626e68a5298542efc52e2bd3c64e212a635359b3a017ee0a8cd47b0c1e
    - calico/cni:v3.15.1
    sizeBytes: 217115249      

nodeInfo:展示k8s版本和kernel的版本是什麼,作業系統的版本是什麼,如果要看k8s更新成功沒,那麼從這裡面就可以看到 

nodeInfo:
    architecture: amd64
    bootID: fb5e2f05-00af-4556-9305-a4cb32193d9b
    containerRuntimeVersion: docker://20.10.14
    kernelVersion: 3.10.0-1160.62.1.el7.x86_64
    kubeProxyVersion: v1.19.0
    kubeletVersion: v1.19.0
    machineID: 13872de9684d45898ae6f3614b134670
    operatingSystem: linux
    osImage: CentOS Linux 7 (Core)
    systemUUID: 45F34D56-0606-8E7E-69C8-41C8CB0E1ABF      

Namespace

Namespace 是對一組資源和對象的抽象集合,比如可以用來将系統内部的對象劃分為不同的項目組或使用者組。

常見的pods,services,replication controllers和 deployments等都是屬于某一個Namespace 的(預設是 default),而 Node,persistentVolumes 等則不屬于任何 Namespace。

有了namespace就能夠很好的将對象組織起來,通過權限控制和namespace隔離,就可以使得多個使用者在同一叢集裡面,但是互不幹擾。

當一個對象沒有namespace屬性,那麼意味着它是none-namespace的對象,它是一個全局範圍的,這個對象是屬于整個叢集的。

[root@master ~]# kubectl get ns default -o yaml
spec:
  finalizers:
  - kubernetes      

這個finalizers意義是什麼呢?當namespace對象被删除的時候,這個對象不會立刻消失,它依然是一個邏輯删除的狀态,正是有個這個finalizers的屬性,當去删除namespace對象的時候,首先它有一個namespace controller,它會去掃描目前這個namspace裡面所有的歸屬對象,如果發現還有任何的子對象沒有删除,它會先去删除這些子對象,當所有的子對象被删除,清理趕緊之後,它才會将namspace删除掉。

是以finalizers依然是鎖對象的。

什麼是pod

Kubernetes 核心對象概覽詳解
[root@master ~]# kubectl run --image=nginx nginx
pod/nginx created      

 如何通過pod對象定義支撐應用運作

Kubernetes 核心對象概覽詳解

12要素:代碼和配置是要分離的,當我們建構容器鏡像的時候,我們隻是将源碼建構為二進制的可執行檔案,然後再去打包為容器鏡像,但是應用的配置我們希望通過外部注入的方式,通過voume mount方式或者環境變量的方式傳進去,讓這個應用來讀取。

這樣的好處是,當生産系統要去做配置變更的時候,我就不需要重新去打鏡像,重新打鏡像意味着要釋出版本,整個ci/cd流水線要走一遍,是以這個整個過程是非常重的。有些參數動态調整,沒必要走流水線,這些可以通過外部的環境變量,或者以卷的方式mount到這個pod裡面。

Kubernetes 核心對象概覽詳解

這個來源是一個filed,是metadata.name,也就是這個環境變量希望擷取這個pod的name,并且把它作為環境變量傳進去。

configmap裡面定義了鍵值對,希望從configmap的鍵值對裡面去擷取某個環境變量。

同理secret也一樣的。

通過上面可以将來自不同來源的剪紙通過環境變量的方式傳入到pod裡面。

進入pod之後可以使用env這條指令就能夠拿到所有的環境變量。

存儲卷

Kubernetes 核心對象概覽詳解

pod網絡

Kubernetes 核心對象概覽詳解

 資源限制

Kubernetes 核心對象概覽詳解

資源限制最後影響的就是排程器,它會去找一個滿足你需求的節點去做排程。

Kubernetes 核心對象概覽詳解

健康檢查

Kubernetes 核心對象概覽詳解

 一個pod啟動了之後,它有可能還在做初始化,這就意味着在初始化的應用程序還不能接受網絡流量,是以要去控制一下pod的狀态,也就是我還沒有就緒,我還不能夠接受流量。

有些應用跑着跑着沒有響應,出現大量的503,應用執行個體以及不能夠正常工作了,是否需要幫你重新開機。

tcp stocket  檢視某個端口,比如某個應用跑在80端口上面,你隻需要去看80端口是否是活着的,你就能夠知道它是否就緒了。

但是有時候80端口啟動了并不代表我業務正常了,可能應用已經死掉了,那麼可以通過HTTP,任何的微服務裡面都要開放healthz的健康檢查的uri,我們就可以針對uri去做健康檢查。

Kubernetes 核心對象概覽詳解

如果這個檔案存在,那麼會傳回code為0,這樣就認為健康檢查是通過的,如果這個檔案不存在,那麼這個return code為非0,也就是這次健康檢查會失敗。

Kubernetes 核心對象概覽詳解

ConfigMap

ConfigMap 用來将非機密性的資料儲存到鍵值對中。

使用時,Pods 可以将其用作環境變量、指令行參數或者存儲卷中的配置檔案。

ConfigMap 将環境配置資訊和 容器鏡像解耦,便于應用配置的修改。

需要遵循代碼和配置分離的原則,代碼進容器鏡像,配置通過外挂存儲,或者通過環境變量的方式注入給pod。

有時候挂載一個存儲并不是說要一塊很大的空間,并不是說我要寫很多的資料,更多的時候是希望将配置檔案放進去,這種通常可以使用configmap挂載進去。

Kubernetes 核心對象概覽詳解

可以通過指令,create config file讀取上面檔案,将上面檔案轉化為configmap。

Kubernetes 核心對象概覽詳解

将整個檔案讀取出來了,key為檔案名字,value就是檔案裡面所有的内容,這是最常用的一種方式,不管我配置檔案長的是什麼樣的,它裡面是不是key value,我們會将配置放在檔案裡面,比如yaml json xml,把它放到一個檔案裡面去,在正真去建立configmap的時候就會--from-file去讀取這個檔案,在config裡面就會以檔案名為key,檔案内容為value。

Kubernetes 核心對象概覽詳解

當我們加上env-fiile的時候,行為和上面就不一樣了,它會抛棄檔案名字,解析了檔案裡面的所有key value,也就是解析了所有有效的鍵值對,并且放到這個configmap裡面。

Kubernetes 核心對象概覽詳解

 除了configmap可以從檔案當中讀取,還可以給他一個輸入,輸入為key-value

Kubernetes 核心對象概覽詳解
Kubernetes 核心對象概覽詳解

上面是建立configmap,那麼怎麼使用呢?通過volume形式挂載

Kubernetes 核心對象概覽詳解
Kubernetes 核心對象概覽詳解

 當你應用程式啟動的時候可以去對應的路徑讀取這個檔案,完成應用配置和啟動。

密鑰對象(Secret)

  • Secret 是用來儲存和傳遞密碼、密鑰、認證憑證這些敏感資訊的對象。
  • 使用 Secret 的好處是可以避免把敏感資訊明文寫在配置檔案裡。
  • Kubernetes 叢集中配置和使用服務不可避免的要用到各種敏感資訊實作登入、認證等功能,例如通路 AWS存儲的使用者名密碼。
  • 為了避免将類似的敏感資訊明文寫在所有需要使用的配置檔案中,可以将這些資訊存入一個Secret 對象,而在配置檔案中通過 Secret 對象引用這些敏感資訊。
  • 這種方式的好處包括∶意圖明确,避免重複,減少暴漏機會。