
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)。

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ù)載均衡器來訪問,多用于公有云上。


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