Pod是可以建立和管理Kubernetes計算的最小可部署單元。pod可以了解為容器的外殼,給容器做了一層抽象封裝。一個Pod代表着叢集中運作的一個程序,每個pod都有一個唯一的ip。
一個pod類似一個豌豆莢,包含一個或多個容器(通常是docker),這多個容器間共享IPC、Network和UTC,和存儲卷,存儲卷不再屬于容器,而屬于pod。
Pod分為兩類:
- 自主式Pod
- 控制器管理的Pod 使pod成為有生命周期的對象
- ReplicationController
- ReplicaSet replicaset不直接使用,它有一個聲明式更新的控制器--deployment來負責管理,但是deployment隻能管理無狀态的
- Deployment 管理無狀态的,使用最多的
- StatefulSet 管理有狀态的
- DaemonSet
- Job, Ctonjob
Deployment為Pod和ReplicaSet提供了一個聲明式定義(declarative)方法,用來替代以前的ReplicationController來友善的管理應用。典型的應用場景包括:
- 定義Deployment來建立Pod和ReplicaSet
- 滾動更新和復原應用
- 擴容和縮容
- 暫停和繼續Deployment
使用deployment建立一個pod應用
kubectl run -h 檢視run指令的用法
master01 # kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1 --record
控制器名稱 容器鏡像 容器的端口 pod的數量 在Deployment revision中可以檢視到執行的曆史指令
檢視
# kubectl get deployment -o wide #檢視deployment控制器
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deploy 1/1 1 1 2m38s nginx-deploy nginx:1.14-alpine run=nginx-deploy
[master01 ]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-55d8d67cf-kckf9 1/1 Running 0 2m55s 10.244.1.2 node01 <none> <none>
可以看到pod已經運作在一個工作節點上, 這裡的ip是cni0橋的ip
[node01] # ifconfig
cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1450
inet 10.244.1.1 netmask 255.255.255.0 broadcast 0.0.0.0
# curl 10.244.1.2 可以通路到nginx。在叢集中間的任意一個節點都可以通路到pod
在叢集内部任意的節點可以通路pod 。叢集外部無法直接通路pod
删除pods 檢視會看到自動起來另一個,因為 replicas個數為1,控制器會另外再啟動一個pod
# kubectl delete pod nginx-deploy-55d8d67cf-kckf9
pod "nginx-deploy-55d8d67cf-kckf9" deleted
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-55d8d67cf-lf5xb 1/1 Running 0 2m55s 10.244.1.3 node01 <none> <none>
會看到容器已經被重建了,且pod的ip發生變化了。
service
service是一個抽象概念,定義了一個服務的多個pod邏輯合集和通路pod的政策,一般把service稱為微服務。
舉個例子:a服務運作3個pod,b服務怎麼通路a服務的pod,pod的ip都不是持久化的重新開機之後就會有變化。
這時候b服務可以通路跟a服務綁定的service,service資訊是固定的提前告訴b就行了,service通過Label Selector跟a服務的pod綁定,無論a的pod如何變化對b來說都是透明的。
用戶端的請求到service,由service代理至後端的pod。service并不是一個具體的應用程式,而是相當于一條ipvs或iptables規則。
kubectl expose -h 檢視指令的用法
kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type] [options]
建立service
# kubectl expose deployment nginx-deploy --name=nginx80 --port=80 --target-port=80 --protocol=TCP
service_name service_port pod_port
service/nginx exposed
檢視service
# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26d <none>
nginx80 ClusterIP 10.105.125.134 <none> 80/TCP 118s run=nginx-deploy
# curl 10.105.125.134:80 在叢集内部節點上可以通路到pod
在叢集節點可以使用 service_ip:service_port 通路pod。 node通路 -> service_ip:service_port -> pod_ip:pod:port。
在pod用戶端可以通過 service_name:service_port 通路到pod,這依賴于coredns解析
[master01 ] # cat /etc/resolv.conf
nameserver 114.114.114.114 # 節點上的dns伺服器不是指向的coredns的位址,是以無法直接通過server_name:service_port 通路pod
# kubectl get svc -n kube-system #可以看到coredns的位址
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 6d3h
在pod用戶端通路
# kubectl run client --image=busybox --replicas=1 -it --restart=Never
/ # cat /etc/resolv.conf
nameserver 10.96.0.10
search default.svc.cluster.local svc.cluster.local cluster.local
/ # wget -O - -q http://nginx80 可以通路到 # pod用戶端可以通過 server_name:server_ip 通路到pod
在node可以通過dig解析
# dig nginx80.default.svc.cluster.local. @10.96.0.10
svc的域名 coredns的clusterip
kubectl describe svc nginx80 檢視service詳細資訊
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLxIjNzUzM3AzNx0yM1ETMwkzM0EjMyATM5EDMy0iM1EDN2MTMvwFMxkTMwIzLcJTNxQjNzEzLcd2bsJ2Lc12bj5ycn9Gbi52YugTMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
- selector 标簽選擇器
- endpoints可以看到後端pod資源
pod被删除掉之後會建立一個新pod,通路nginx:80依然能通路到,因為service通過selector标簽選擇器跟pod建立了綁定,service可以為pod提供固定通路端點。
# kubectl get pods --show-labels # 檢視标簽
NAME READY STATUS RESTARTS AGE LABELS
client 1/1 Running 0 19m run=client
nginx-deploy-54d6d94f75-b2kxf 1/1 Running 0 165m pod-template-hash=54d6d94f75,run=nginx-deploy
實踐:
建立兩個pod
# kubectl run myapp --image=ikubernetes/myapp:v1 --replicas=2
# kubectl get deployment -w # -w 監控deployment狀态
# kubectl get pods -o wide
建立一個service
# kubectl expose deployment myapp --port=8000 --target-port=80
檢視svc
# kubectl describe svc myapp
Name: myapp
Namespace: default
Labels: run=myapp
Annotations: <none>
Selector: run=myapp
Type: ClusterIP
IP: 10.99.71.37
Port: <unset> 8000/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.35:80,10.244.1.36:80 #service後端的兩個pod
Session Affinity: None
Events: <none>
建立一個pod用戶端通路 service_name:service_port,可以看到service是随機的将請求分發到後端的兩個pod的
# kubectl run client --image=busybox -it
/ # wget -O - -q http://myapp:8000/hostname.html
動态擴容縮容
kubectl scale --replicas=5 deployment nginx-deploy # replicas指定pod數即可擴容縮容
更新鏡像
将鏡像更新為1.16-alpine:
# kubectl set image deployment nginx-deploy nginx-deploy=nginx:1.16-alpine --record
deployment.extensions/nginx-deploy image updated
另開一個視窗監控更新過程:
# kubectl get pod -w
更新完成後檢視:
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deploy-56457775df-ptx9f 1/1 Running 0 2m25s
# kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deploy 1/1 1 1 23d nginx-deploy nginx:1.16-alpine run=nginx-deploy
# kubectl describe pod nginx-deploy-56457775df-ptx9f
復原操作
# kubectl rollout undo deployment/nginx-deploy
deployment.extensions/nginx-deploy rolled back
--to-revision 參數可以指定回退的版本
# kubectl rollout undo deploy/nginx-deploy --to-revision=1
# kubectl rollout history deployment/nginx-deploy #檢視曆史版本
這裡CHANGE-CAUSE顯示為空是因為操作deployment的時候沒有加--record。如果加上應該顯示:
外部用戶端通路pod
k8s中的三種網絡:
Node Network: 與外部網絡接口
Service Network:又叫叢集網絡,與pod不在一個網段,隻存在于iptables或ipvs規則中,是虛拟的
Pod Network: 節點當中pod的内部網絡
如果端口暴露類型為NodePort,那麼外部用戶端可以通過叢集内任意一台主機ip加暴露的端口進行通路
1. # kubectl edit svc myapp 修改service的type為NodePort
ClusterIP: 預設類型,自動配置設定一個僅叢集内部可以通路的虛拟IP
NodePort: 在ClusterIP基礎上為Service在每台機器上綁定一個端口,這樣就可以通過 NodeIP:NodePort 來通路該服務
2. 也可以在建立service時指定type
kubectl expose deployment nginx-deploy --name=nginx --port=80 --target-port=80 --
type
=NodePort
# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 26d <none>
nginx80 NodePort 10.105.125.134 <none> 80:32441/TCP 35m run=nginx-deploy
使用叢集外用戶端通路,需要使用叢集任意一個節點的IP位址加上暴露的端口号