[K8S系列四] K8S核心組件與核心概念(Pod、Deployment、Service)

1. 核心組件與核心概念

K8S集群分為Master節(jié)點(diǎn)和Node節(jié)點(diǎn),Master節(jié)點(diǎn)負(fù)責(zé)調(diào)度分配任務(wù),Node節(jié)點(diǎn)接受Master調(diào)度進(jìn)行工作。

1.1 Master節(jié)點(diǎn)組件

1. API Server

集群的統(tǒng)一入口,各組件協(xié)調(diào)者,以RESTful API方式提供接口服務(wù),所有對象資源的增刪查改和監(jiān)聽操作都交給API Server處理后再提交給Etcd存儲。

2. Controller Manager
負(fù)責(zé)維護(hù)集群的狀態(tài),比如故障檢測、自動擴(kuò)展、滾動更新等。一個資源對應(yīng)一個控制器,而Controller Manager就是負(fù)責(zé)管理這些控制器的。

3. Scheduler
負(fù)責(zé)資源的調(diào)度,按照預(yù)定的調(diào)度策略將Pod調(diào)度到相應(yīng)的機(jī)器上。

4.etcd
分布式鍵值存儲系統(tǒng),用于保存群集狀態(tài)數(shù)據(jù),比如Pod、Service等對象信息。

1.2 Node組件

1. kubelet
kubelet是Master在Node節(jié)點(diǎn)上的Agent,管理本機(jī)運(yùn)行容器的生命周期,比如創(chuàng)建容器、Pod掛載數(shù)據(jù)卷、下載secret、獲取容器和節(jié)點(diǎn)狀態(tài)等工作。kubelet將每個Pod轉(zhuǎn)換成一組容器。

2. kube-proxy
責(zé)為Service提供cluster內(nèi)部的服務(wù)發(fā)現(xiàn)和負(fù)載均衡。

2. 核心概念

2.1 Pod

Pod是一個邏輯概念,是一組共享了某些資源的容器。Pod在K8S中是調(diào)度的最基本單位,以便容器互相依賴時,可以同時調(diào)度。
Pod 里的所有容器,共享的是同一個 Network Namespace,并且可以聲明共享同一個 Volume。每個Pod中都有一個Pause(Infra)容器,Pause容器是Kubernetes基礎(chǔ)設(shè)施的一部分,Kubernetes管理的所有pod里,pause容器是第一個啟動的,而其他用戶定義的容器,則通過 Join Network Namespace 的方式,與 pause容器關(guān)聯(lián)在一起。

對于 Pod 里的容器 A 和容器 B 來說:

  • 它們可以直接使用 localhost 進(jìn)行通信;
  • 它們看到的網(wǎng)絡(luò)設(shè)備跟 Pause容器看到的完全一樣;
  • 一個 Pod 只有一個 IP 地址,也就是這個 Pod 的 Network Namespace 對應(yīng)的 IP 地址;
  • 當(dāng)然,其他的所有網(wǎng)絡(luò)資源,都是一個 Pod 一份,并且被該 Pod 中的所有容器共享;
  • Pod 的生命周期只跟 Infra 容器一致,而與容器 A 和 B 無關(guān)。
image.png
2.2 Controller

1.ReplicaSet
確保預(yù)期的Pod副本數(shù)量,很少直接使用,需要被Deployment管理。

2.Deployment
作用于一組Pod的創(chuàng)建和運(yùn)行,控制pod應(yīng)用的升級、回滾,當(dāng)然也能控制pod的數(shù)量。

3.Service
在K8S中,一方面Pod有伸縮與重新部署的需求,Pod的IP大多數(shù)情況是不固定的,另一方面,同一組Pod之間也有負(fù)載均衡的需要。因此,一組Pod被抽象成一個Service統(tǒng)一向外暴露。Service與其后端Pod副本集群之間則是通過Label Selector實(shí)現(xiàn)關(guān)聯(lián)。

Service有以下三種類型:
ClusterIP:提供一個集群內(nèi)部的虛擬IP(clusterIP),以便在集群內(nèi)部通過clutserIP:port訪問;
NodePort:在每個節(jié)點(diǎn)上打開一個端口,在集群外部可以通過nodeIP:nodePort訪問,在內(nèi)部依然可以通過clutserIP:port 訪問;
LoadBalancer:通過外部的負(fù)載均衡器來訪問,多用于公有云上。

ClusterIP
NodePort

Service vs Deployment

  • Service是從網(wǎng)絡(luò)角度的抽象概念,類似于Nginx做負(fù)載均衡提供的統(tǒng)一網(wǎng)絡(luò)入口;
  • Pod是最終的應(yīng)用部署實(shí)體;
  • Deoplyment 負(fù)責(zé)創(chuàng)建和保持pod運(yùn)行狀態(tài)。

3. 示例

3.1 deployment
#  whomai-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami-deployment
  labels:
    app: whoami
spec:
  replicas: 3
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
      - name: whoami
        image: jwilder/whoami
        ports:
        - containerPort: 8000
# kubectl get pods -o wide
whoami-deployment-8886867c8-67d4f   1/1     Running   0              45m   10.244.80.206   w2     <none>           <none>
whoami-deployment-8886867c8-hgvmb   1/1     Running   0              45m   10.244.80.205   w2     <none>           <none>
whoami-deployment-8886867c8-pc67z   1/1     Running   0              45m   10.244.190.88   w1     <none>           <none>

# curl 10.244.80.206:8000
I'm whoami-deployment-8886867c8-67d4f
# curl 10.244.80.205:8000
I'm whoami-deployment-8886867c8-hgvmb
# curl 10.244.190.88:8000
I'm whoami-deployment-8886867c8-pc67z
3.2 Service

1. ClusterIP
whoami-clusterip.yaml

apiVersion: v1
kind: Service
metadata:
  name: whoami-clusterip
spec:
  type: ClusterIP
  selector:
    app: whoami
  ports:
    - protocol: TCP
      port: 8080 # 集群的8080端口
      targetPort: 8000 # Pod的8000端口
# kubectl apply -f whoami-clusterip.yaml
# kubectl get svc -o wide
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE   SELECTOR
kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP    34d   <none>
whoami-clusterip   ClusterIP   10.98.191.167   <none>        8080/TCP   8s    app=whoami

# curl 10.98.191.167:8080
I'm whoami-deployment-8886867c8-hgvmb
# curl 10.98.191.167:8080
I'm whoami-deployment-8886867c8-67d4f
# curl 10.98.191.167:8080
I'm whoami-deployment-8886867c8-67d4f
# curl 10.98.191.167:8080
I'm whoami-deployment-8886867c8-hgvmb
# curl 10.98.191.167:8080
I'm whoami-deployment-8886867c8-pc67z

#  kubectl describe  svc whoami-clusterip
Name:              whoami-clusterip
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=whoami
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.98.191.167
IPs:               10.98.191.167
Port:              <unset>  8080/TCP
TargetPort:        8000/TCP
Endpoints:         10.244.190.88:8000,10.244.80.205:8000,10.244.80.206:8000
Session Affinity:  None
Events:            <none>

這種Service在集群外部是無法訪問的,因為它是基于每個集群節(jié)點(diǎn)上配置的iptables中的虛擬IP地址實(shí)現(xiàn)的,并沒有真實(shí)的網(wǎng)絡(luò)設(shè)備存在。 通過 iptables-save可以看到如下規(guī)則,這條 iptables 規(guī)則的含義是:凡是目的地址是 10.98.191.167、目的端口是 8080 的 IP 包,都應(yīng)該跳轉(zhuǎn)到另外一條名叫 KUBE-SVC-XYYCMFLZLJQGYLMQ 的 iptables 鏈進(jìn)行處理。

而我們前面已經(jīng)看到,10.98.191.167正是這個 Service 的 VIP。所以這一條規(guī)則,就為這個 Service 設(shè)置了一個固定的入口地址。并且,由于 10.98.191.167只是一條 iptables 規(guī)則上的配置,并沒有真正的網(wǎng)絡(luò)設(shè)備,所以你 ping 這個地址,是不會有任何響應(yīng)的。

KUBE-SVC-XYYCMFLZLJQGYLMQ 它是一組規(guī)則的集合,如下所示,這三條鏈指向的最終目的地,其實(shí)就是這個 Service 代理的三個 Pod。所以這一組規(guī)則,就是 Service 實(shí)現(xiàn)負(fù)載均衡的位置。

#  iptables-save
-A KUBE-SERVICES -d 10.98.191.167/32 -p tcp -m comment --comment "default/whoami-clusterip cluster IP" -m tcp --dport 8080 -j KUBE-SVC-XYYCMFLZLJQGYLMQ
-A KUBE-SVC-XYYCMFLZLJQGYLMQ -m comment --comment "default/whoami-clusterip" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-SZWRSKR7UEYM347Q
-A KUBE-SVC-XYYCMFLZLJQGYLMQ -m comment --comment "default/whoami-clusterip" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-GXJY2AW3O6IJVNJZ
-A KUBE-SVC-XYYCMFLZLJQGYLMQ -m comment --comment "default/whoami-clusterip" -j KUBE-SEP-3NPGKIHQFRDXBA2I

2. NodePort
whoami-nodeport.yaml

apiVersion: v1
kind: Service
metadata:
  name: whoami-nodeport
spec:
  type: NodePort
  selector:
    app: whoami
  ports:
    - protocol: TCP
      port: 8080. # service 端口
      targetPort: 8000 # Pod端口
      nodePort: 30000 # 可以指定對外暴露的隨機(jī)端口。一般30000-32627之間的一個端口就可以
# kubectl apply -f whoami-nodeport.yaml
service/whoami-nodeport created
# kubectl get svc -o wide
NAME              TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE   SELECTOR
whoami-nodeport   NodePort    10.111.44.34   <none>        8080:30000/TCP   8s    app=whoami

通過lsof可以發(fā)現(xiàn)在物理機(jī)上開辟30000端口

# lsof -i tcp:30000
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
kube-prox 3600 root   12u  IPv4 874479      0t0  TCP *:ndmps (LISTEN)

在集群內(nèi)通過clusterIP:port訪問service

# curl 10.111.44.34:8080
I'm whoami-deployment-8886867c8-pc67z
# curl 10.111.44.34:8080
I'm whoami-deployment-8886867c8-67d4f
# curl 10.111.44.34:8080
I'm whoami-deployment-8886867c8-hgvmb

在集群外通過nodeIP:nodePort 訪問, nodeIP就是集群物理機(jī)的IP,這里是92.168.0.51、92.168.0.61、92.168.0.62。

# curl 192.168.0.62:30000
I'm whoami-deployment-8886867c8-hgvmb
# curl 192.168.0.62:30000
I'm whoami-deployment-8886867c8-67d4f
# curl 192.168.0.62:30000
I'm whoami-deployment-8886867c8-pc67z
# curl 192.168.0.51:30000
I'm whoami-deployment-8886867c8-pc67z
# curl 192.168.0.51:30000
I'm whoami-deployment-8886867c8-67d4f

參考

  1. Kubernetes 架構(gòu)
  2. K8S-概念-service-deployment
  3. k8s中Pod、ReplicaSet、Deployment、Service的概念
  4. 深入k8s:Pod對象中重要概念及用法
  5. k8s 中Service、DNS與服務(wù)發(fā)現(xiàn)
  6. Kubernetes的三種外部訪問方式:NodePort、LoadBalancer 和 Ingress
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容