- Pod是可以創建和管理Kubernetes計算的最小可部署單元,一個Pod代表着集羣
中運行的一個進程,每個pod都有一個唯一的ip。 - 一個pod類似一個豌豆莢,包含一個或多個容器(通常是docker),多個容器間共享IPC、Network和UTC namespace。
pod運行管理
自主式pod
[kubeadm@server2 ~]$ kubectl run demo --image=nginx
pod/demo created
[kubeadm@server2 ~]$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 8s
[kubeadm@server2 ~]$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo 1/1 Running 0 14s 10.244.1.5 server3 <none> <none>
[kubeadm@server2 ~]$ kubectl delete pod demo
pod "demo" deleted
[kubeadm@server2 ~]$ kubectl get pods -o wide
No resources found in default namespace.
自主式pod 刪除後就沒有了,生命週期就結束了。
deployment控制器
[kubeadm@server2 ~]$ kubectl create deployment myapp --image=nginx
deployment.apps/myapp created
[kubeadm@server2 ~]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-687598b8b4-678wm 1/1 Running 0 4s
生成的pod名稱是控制器名稱myapp + rs名 +容器名
,而且我們還可以再後面加參數,指定副本數等。
[kubeadm@server2 ~]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-687598b8b4-678wm 1/1 Running 0 4s
[root@server3 ~]# ip a
5: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default qlen 1000
link/ether c6:c8:cf:99:c7:2d brd ff:ff:ff:ff:ff:ff
inet 10.244.1.1/24 scope global cni0 # pod再結點上運行會創建cni0網卡,分配ip。
valid_lft forever preferred_lft forever
inet6 fe80::c4c8:cfff:fe99:c72d/64 scope link
valid_lft forever preferred_lft forever
[kubeadm@server2 ~]$ kubectl delete pod myapp-687598b8b4-678wm
pod "myapp-687598b8b4-678wm" deleted
[kubeadm@server2 ~]$ get pod
NAME READY STATUS RESTARTS AGE
myapp-687598b8b4-bt8mv 1/1 Running 0 10s
我們刪除了之前的,但是deploy控制器直接再相同的rs
底下拉取了一個副本.
[kubeadm@server2 ~]$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/myapp-687598b8b4-bt8mv 1/1 Running 0 97s # pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/myapp 1/1 1 1 4m42s #deployment控制器
NAME DESIRED CURRENT READY AGE
replicaset.apps/myapp-687598b8b4 1 1 1 4m41s #rs控制器
#pod出現故障的時候,rs 控制器會進行修復。
那我們想刪除它的話,就需要刪除調度器纔可以:
[kubeadm@server2 ~]$ kubectl delete deployments.apps myapp
deployment.apps "myapp" deleted
[kubeadm@server2 ~]$ kubectl get pod
No resources found in default namespace.
pod的擴容縮容:
[kubeadm@server2 ~]$ kubectl create deployment myapp --image=nginx
deployment.apps/myapp created
[kubeadm@server2 ~]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-687598b8b4-mjhdc 1/1 Running 0 9s
[kubeadm@server2 ~]$ kubectl scale deployment myapp --replicas=2
deployment.apps/myapp scaled # 拉伸到2個
[kubeadm@server2 ~]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-687598b8b4-c6s7h 0/1 ContainerCreating 0 1s
myapp-687598b8b4-mjhdc 1/1 Running 0 33s
[kubeadm@server2 ~]$ kubectl scale deployment myapp --replicas=10
deployment.apps/myapp scaled # 拉伸到10個
[kubeadm@server2 ~]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-687598b8b4-2wttr 0/1 ContainerCreating 0 1s
myapp-687598b8b4-84k69 0/1 Pending 0 1s
myapp-687598b8b4-b2w99 0/1 ContainerCreating 0 1s
myapp-687598b8b4-c6s7h 1/1 Running 0 5s
myapp-687598b8b4-h6lph 0/1 Pending 0 1s
myapp-687598b8b4-mjhdc 1/1 Running 0 37s
myapp-687598b8b4-whld2 0/1 Pending 0 1s
myapp-687598b8b4-wtpkn 0/1 Pending 0 1s
myapp-687598b8b4-xx8qr 0/1 Pending 0 1s
myapp-687598b8b4-zkwc9 0/1 ContainerCreating 0 1s
[kubeadm@server2 ~]$ kubectl scale deployment myapp --replicas=2
deployment.apps/myapp scaled
[kubeadm@server2 ~]$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-687598b8b4-hb7zv 1/1 Running 0 11s
myapp-687598b8b4-s2ncv 1/1 Running 0 18s
[kubeadm@server2 ~]$ kubectl delete deployments.apps myapp
deployment.apps "myapp" deleted
[kubeadm@server2 ~]$ kubectl get pod
No resources found in default namespace. # 可以這樣刪除
這就是我們手動的擴容。其實可以做到再需求比較大的時候自動擴容,再需求小的時候再自動縮容。
service微服務
[kubeadm@server2 ~]$ curl 10.244.1.15
<!DOCTYPE html>
<html>
<head>
當前我們是可以通過內網來訪問開啓的容器的
service是一個抽象概念,定義了一個服務的多個pod邏輯合集和訪問pod的策略,一般把service稱爲微服務。
service 就是來暴露我們的訪問接口的,它就是從外部訪問內部pod的一個端口port,並且可以實現負載均衡。
- 創建service
[root@server2 ~]# kubectl expose deployment myapp --port=80 --target-port=80
service/myapp exposed # 相當於端口映射
[root@server2 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19h
myapp ClusterIP 10.109.116.35 <none> 80/TCP 9s
默認獲得一個clusterIP 類型,這是一個僅集羣內部可以訪問的虛擬IP.
[root@server2 ~]# kubectl describe svc myapp
Name: myapp
Namespace: default
Labels: app=myapp
Annotations: <none>
Selector: app=myapp
Type: ClusterIP
IP: 10.109.116.35 # service 分到的IP
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.15:80,10.244.2.6:80 # 這裏的兩個ip地址和pod的ip相同,是虛擬ip
Session Affinity: None
Events: <none>
[root@server2 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
myapp-687598b8b4-hb7zv 1/1 Running 0 53m 10.244.2.6 server4 <none> <none>
myapp-687598b8b4-s2ncv 1/1 Running 0 54m 10.244.1.15 server3 <none> <none>
它是怎麼識別pod的那?
[root@server2 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myapp-687598b8b4-hb7zv 1/1 Running 0 56m app=myapp,pod-template-hash=687598b8b4
myapp-687598b8b4-s2ncv 1/1 Running 0 56m app=myapp,pod-template-hash=687598b8b4
#是通過後面的標籤識別的,有這個標籤,就可以加進來
比如:
[root@server2 ~]# kubectl scale deployment myapp --replicas=4 # 我們擴增到四個
deployment.apps/myapp scaled
[root@server2 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
myapp-687598b8b4-hb7zv 1/1 Running 0 58m app=myapp,pod-template-hash=687598b8b4
myapp-687598b8b4-px6nq 1/1 Running 0 9s app=myapp,pod-template-hash=687598b8b4
myapp-687598b8b4-s2ncv 1/1 Running 0 58m app=myapp,pod-template-hash=687598b8b4
myapp-687598b8b4-tkhv5 1/1 Running 0 9s app=myapp,pod-template-hash=687598b8b4
# 每個都有標籤
[root@server2 ~]# kubectl describe svc myapp
Name: myapp
Namespace: default
Labels: app=myapp
Annotations: <none>
Selector: app=myapp
Type: ClusterIP
IP: 10.109.116.35
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.15:80,10.244.1.19:80,10.244.2.6:80 + 1 more... # ip 動態加進來了。
Session Affinity: None
Events: <none>
由於後端由多個,我們就可以通過service的 虛擬IP
地址進行訪問,並可以實現負載均衡
。
但是現在還不能使用VIP 進行訪問,我們還沒有配置好,我們可以去容器內部訪問一下;
[root@server2 ~]# kubectl run demo --image=busyboxplus -it --restart=never
If you don't see a command prompt, try pressing enter.
/ # curl 10.109.116.35
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title> #這裏做負載均衡效果不明顯,我們在版本更新處展示
滾動更新
- 更新
[root@server2 ~]# kubectl get pod # 這是我們現在運行的容器
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 1 8m58s
myapp-687598b8b4-hb7zv 1/1 Running 0 92m
myapp-687598b8b4-px6nq 1/1 Running 0 34m
myapp-687598b8b4-s2ncv 1/1 Running 0 92m
myapp-687598b8b4-tkhv5 1/1 Running 0 34m
[root@server2 ~]# kubectl describe pod myapp-687598b8b4-hb7zv
Containers:
nginx: # 裏面運行的容器名字叫做nginx
Container ID: docker://fef76a437c55b9ea9c9c089bdcddd21b0eb0e737c88125c237f56188e8c74104
Image: nginx # 鏡像是nginx
[root@server2 ~]# kubectl set image deployments myapp nginx=myapp:v1 --record # 更新
deployment.apps/myapp image updated # record 是記錄,用於回滾
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 1 19m
myapp-76df559f68-bjwwx 1/1 Running 0 3m52s
myapp-76df559f68-cdr7m 1/1 Running 0 3m51s
myapp-76df559f68-fxjxv 1/1 Running 0 3m59s
myapp-76df559f68-xzrrr 1/1 Running 0 3m58s
# 我額門發現容器名全變了,而且連 rs 都變了
[root@server2 ~]# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/demo 1/1 Running 1 20m
pod/myapp-76df559f68-bjwwx 1/1 Running 0 5m3s
pod/myapp-76df559f68-cdr7m 1/1 Running 0 5m2s
pod/myapp-76df559f68-fxjxv 1/1 Running 0 5m10s
pod/myapp-76df559f68-xzrrr 1/1 Running 0 5m9s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20h
service/myapp ClusterIP 10.109.116.35 <none> 80/TCP 53m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/myapp 4/4 4 4 104m
NAME DESIRED CURRENT READY AGE
replicaset.apps/myapp-687598b8b4 0 0 0 104m # 原來的 rs 還在,用於回滾
replicaset.apps/myapp-76df559f68 4 4 4 5m10s # 創建了新的rs來維護現在這個版本
# 負載均衡
[root@server2 ~]# kubectl attach demo -it #連接這個pod
/ # curl 10.109.116.35 # 訪問service的VIP
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
# 加上這個可以顯示pod ip
/ # curl 10.109.116.35/hostname.html
myapp-76df559f68-bjwwx
/ # curl 10.109.116.35/hostname.html
myapp-76df559f68-cdr7m
/ # curl 10.109.116.35/hostname.html
myapp-76df559f68-fxjxv
/ # curl 10.109.116.35/hostname.html
myapp-76df559f68-cdr7m
# 這就是負載均衡的功能
- 回滾
[root@server2 ~]# kubectl set image deployments myapp nginx=myapp:v2 --record
deployment.apps/myapp image updated
[root@server2 ~]# kubectl rollout history deployment myapp # 查看歷史版本
deployment.apps/myapp
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deployments myapp nginx=myapp:v1 --record=true
3 kubectl set image deployments myapp nginx=myapp:v2 --record=true
[root@server2 ~]# kubectl attach demo -it
/ # curl 10.109.116.35
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
/ # curl 10.109.116.35/hostname.html
myapp-bf4d57f8f-8b82j # 又是新的pod
/ # curl 10.109.116.35/hostname.html
myapp-bf4d57f8f-svq28
[root@server2 ~]# kubectl rollout history deployment myapp
deployment.apps/myapp
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deployments myapp nginx=myapp:v1 --record=true
3 kubectl set image deployments myapp nginx=myapp:v2 --record=true
# 當前有三個版本
[root@server2 ~]# kubectl rollout undo deployment myapp --to-revision=2 #回退到第二個
deployment.apps/myapp rolled back
[root@server2 ~]# kubectl attach demo -it
Defaulting container name to demo.
Use 'kubectl describe pod/demo -n default' to see all of the containers in this pod.
If you don't see a command prompt, try pressing enter.
/ # curl 10.109.116.35
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> # 回滾了
通過外部結點訪問service
[root@server2 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 21h
myapp ClusterIP 10.109.116.35 <none> 80/TCP 80m
[root@server2 ~]# kubectl edit svc myapp
service/myapp edited
[root@server2 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 21h
myapp NodePort 10.109.116.35 <none> 80:31470/TCP 82m
修改svc
的類型爲nodeport
.
此時又爲我們分配了一個31470端口,端口是隨機分配的,在工作結點上
[root@server4 ~]# netstat -tnlp |grep 31470
tcp 0 0 0.0.0.0:31470 0.0.0.0:* LISTEN 26106/kube-proxy
[root@server3 ~]# netstat -tnlp |grep 31470
tcp 0 0 0.0.0.0:31470 0.0.0.0:* LISTEN 26106/kube-proxy
我們就可以通過外部訪問了,這次就不用去訪問service的 VIP, 而是直接訪問主機的ip:
[root@rhel7host yum.repos.d]# curl 172.25.254.3:31470
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@rhel7host yum.repos.d]# curl 172.25.254.4:31470
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@rhel7host yum.repos.d]# curl 172.25.254.4:31470/hostname.html
myapp-76df559f68-vbclz
[root@rhel7host yum.repos.d]# curl 172.25.254.4:31470/hostname.html
myapp-76df559f68-fwqqw
[root@rhel7host yum.repos.d]# curl 172.25.254.4:31470/hostname.html
myapp-76df559f68-gqz7p