Kubernetes資源對象Pod、ReplicaSet、Deployment、Service之間的關係

Pod、ReplicaSet、Deployment、Service之間的關係如下圖

Pod:

Pod是一個或多個容器的組合,這些容器共享存儲、網絡和命名空間,以及如何運行的規範。Pod是Kubernetes的最小可部署單元。Pod的中文譯詞是豌豆莢,docker容器就像是豆子運行在豌豆莢內。

ReplicaSet:
先說下Replication Controller。Replication Controller的作用是確保Pod以指定的副本個數運行。
ReplicaSet是Replication Controller升級版。ReplicaSet和Replication Controller之間的唯一區別是對選擇器支持。Replication Controller只支持基於等式的selector(env=dev或environment!=qa),但ReplicaSet還支持新的,基於集合的selector(version in (v1.0,v2.0)或env notin (dev, qa))。
在yaml文件中通過spec.replicas聲明pod的副本數。

Deployment:
Deployment用於管理Pod、ReplicaSet,可實現滾動升級和回滾應用、擴容和縮容。

Service:
試想一個問題,ReplicaSet定義了pod的數量是2,當一個pod由於某種原因停止了,ReplicaSet會新建一個pod,以確保運行中的pod數量始終是2。但每個pod都有自己的ip,前端請求不知道這個新pod的ip是什麼,那前端的請求如何發送到新pod中呢?
答案是使用Service
k8s的Service定義了一個服務的訪問入口地址,前端的應用通過這個入口地址訪問其背後的一組由Pod副本組成的集羣實例,來自外部的訪問請求被負載均衡到後端的各個容器應用上。Service與其後端Pod副本集羣之間則是通過Label Selector實現關聯。
請說人話:前端請求不是直接發送給Pod,而是發送到Service,Service再將請求轉發給pod。

總結一下:Pod被ReplicaSet管理,ReplicaSet控制pod的數量;ReplicaSet被Deployment管理,Deployment控制pod應用的升級、回滾,當然也能控制pod的數量。Service提供一個統一固定入口,負責將前端請求轉發給Pod。

實踐環節

定義一個myapp.yaml文件

apiVersion: apps/v1
# 聲明一個Deployment資源對象
kind: Deployment
metadata:
  name: deployment-myapp
spec:
# 通過replicas聲明pod個數是2  
  replicas: 2
# 通過標籤選擇被控制的pod    
  selector:
    matchLabels:
      app: myapp
# 在template中定義pod      
  template:
    metadata:
# 給pod打上標籤app=myapp    
      labels:
        app: myapp
    spec:
      containers:
# 聲明容器名稱,注意不是pod名稱,pod名稱應該定義在metadata中
      - name: myapp
        image: ikubernetes/myapp:v1
        ports:
        - name: http
          containerPort: 80
# 在一個yaml文件中通過---分割多個資源對象          
---
apiVersion: v1
# 聲明一個Service資源對象
kind: Service
metadata:
  name: service-myapp
spec:
# service-myapp將選擇標籤包含app=myapp的pod
  selector:
    app: myapp
  ports:
  - name: http
# Service監聽端口  
    port: 80
# 轉發到後端Pod的端口號   
    targetPort: 80

部署這個資源清單 

kubectl apply -f myapp.yaml

先看一個很有意思的圖片

myapp.yaml文件聲明瞭deployment的名稱,沒聲明ReplicaSet、Pod的名稱。但kubernetes會自動給ReplicaSet、Pod起名稱。

Deployment名稱是deployment-myapp

ReplicaSet名稱是deployment-myapp-5fdb5f69f,實際上是Deployment名稱加上pod-template的hash值

Pod名稱是deployment-myapp-5fdb5f69f-njrb6、deployment-myapp-5fdb5f69f-whpwg,實際上是ReplicaSet的名稱加上一個hash值。

使用  kubectl describe svc service-myapp   命令看下service-myapp的詳細信息。

可以看到service-myapp的ip地址是10.97.41.88。發送到10.97.41.88:80的請求會被轉發給10.244.1.5:80或10.244.2.2:80

看下圖:

先直接請求pod,獲取pod的hostname

curl 10.244.1.5:80/hostname.html

curl 10.244.2.2:80/hostname.html

然後請求service-myapp,service-myapp會把請求負載給後端的pod

curl 10.97.41.88:80/hostname.html

 

還有一個很有意思的事情。pod能ping通,但是servic卻ping不通

這是爲什麼呢?

答案:因爲Service其實是iptables或ipvs的轉發規則,這規則不支持ICMP協議,所以就ping不通咯。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章