- 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