目录
本次拉取一个简单镜像并对其进行部署应用,学习pod基本使用和命令,包括pod的创建,部署Deployment、扩容、更新、回滚等。
下载测试镜像
拉取镜像
[root@k8s1 docker]# docker pull yakexi007/myapp:v1
[root@k8s1 docker]# docker pull yakexi007/myapp:v2
修改标签
[root@k8s1 docker]# docker tag yakexi007/myapp:v1 reg.westos.org/library/myapp:v1
[root@k8s1 docker]# docker tag yakexi007/myapp:v2 reg.westos.org/library/myapp:v2
上传至仓库
[root@k8s1 docker]# docker push reg.westos.org/library/myapp:v1
[root@k8s1 docker]# docker push reg.westos.org/library/myapp:v2
什么是pod?
Pod是可以创建和管理Kubernetes计算的最小可部署单元,一个Pod代表着集群中运行的一个进程,每个pod都有一个唯一的ip。pod可以理解为是花生壳,一个pod中好几个花生豆(container),也可能一个pod中一个container,里面的container共享pod内的IP、Network和ns(namespace)等资源,这样就存在容器的多个副本不能直接放在一个pod里的问题,必须靠端口不同来区分一个pod中的不同容器。所有功能都是通过api接口实现。
创建自主式pod
生产中不推荐这样做
[root@k8s2 ~]# kubectl run demo --image=myapp:v1 #创建新的pod,叫demo
[root@k8s2 ~]# kubectl get pod -o wide #查看pod的ip和节点服务位置
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo 1/1 Running 0 35s 10.244.2.2 k8s4 <none> <none>
查看pod详情
[root@k8s2 ~]# kubectl describe pod demo #查看demo的详细信息
Name: demo
Namespace: default
Priority: 0
Node: k8s4/192.168.56.174
Start Time: Mon, 09 Jan 2023 15:40:49 +0800
Labels: run=demo
Annotations: <none>
Status: Running
IP: 10.244.2.2
IPs:
IP: 10.244.2.2
...
删除pod
删除名叫demo的pod
[root@k8s2 ~]# kubectl delete pod demo
创建控制器
实际环境推荐这样做,创建三个副本
[root@k8s2 ~]# kubectl create deployment myapp --image=myapp:v1 --replicas=3
控制器自动维护pod副本数在3个
[root@k8s2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-678fcbc488-gp6pr 1/1 Running 0 3s
myapp-678fcbc488-gqdgk 1/1 Running 0 3s
myapp-678fcbc488-qqkzx 1/1 Running 0 3s
[root@k8s2 ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
myapp 3/3 3 3 16s
我们删除一个副本
[root@k8s2 ~]# kubectl delete pod myapp-678fcbc488-gp6pr
pod "myapp-678fcbc488-gp6pr" deleted
查看发现,数量还是三个
[root@k8s2 ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
myapp 3/3 3 3 34s
不过号码换了。这是因为Deployment控制器的机制,他发现副本数量不足3时,他会自动创建,补足三个副本。
[root@k8s2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-678fcbc488-gqdgk 1/1 Running 0 39s
myapp-678fcbc488-qqkzx 1/1 Running 0 39s
myapp-678fcbc488-v7ftf 1/1 Running 0 8s
在远程pod中执行命令
[root@k8s2 ~]# kubectl exec myapp-678fcbc488-gqdgk -- ls /usr/share/nginx/html
50x.html
index.html
扩容pod数量
将副本数改为6个,发现新增了三个新的副本,并且时间为7s
[root@k8s2 ~]# kubectl scale deployment myapp --replicas=6
[root@k8s2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-678fcbc488-gqdgk 1/1 Running 0 11m
myapp-678fcbc488-jb5dw 1/1 Running 0 7s
myapp-678fcbc488-qqkzx 1/1 Running 0 11m
myapp-678fcbc488-tm55k 1/1 Running 0 7s
myapp-678fcbc488-v7ftf 1/1 Running 0 11m
myapp-678fcbc488-wrjt7 1/1 Running 0 7s
缩容
将副本数缩小为3个,多余的副本会被回收,优先回收新的副本
[root@k8s2 ~]# kubectl scale deployment myapp --replicas=3
deployment.apps/myapp scaled
[root@k8s2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-678fcbc488-gqdgk 1/1 Running 0 12m
myapp-678fcbc488-qqkzx 1/1 Running 0 12m
myapp-678fcbc488-v7ftf 1/1 Running 0 11m
通过service暴露pod
Service是Kubernetes里最核心的资源对象之一, 定义了一个服务的访问入口地址,前端的应用(Pod)通过这个入口地址访问其背后的一组由Pod副本组成的集群实力。
集群内部任意节点可以访问Pod,但集群外部无法直接访问内部节点,此时pod客户端可以通过service的名称或ip访问后端的两个Pod,设定可供集群外部访问的虚拟IP
[root@k8s2 ~]# kubectl expose deployment myapp --port=80 --target-port=80
[root@k8s2 ~]# kubectl describe svc myapp
Name: myapp
Namespace: default
Labels: app=myapp
Annotations: <none>
Selector: app=myapp
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.106.225.101
IPs: 10.106.225.101
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.2:80,10.244.1.3:80,10.244.2.4:80
Session Affinity: None
Events: <none>
访问该虚拟ip,可以看到负载均衡的落在不同后端上
[root@k8s2 ~]# curl 10.106.225.101
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s2 ~]# curl 10.106.225.101/hostname.html
myapp-678fcbc488-v7ftf
service自动发现pod扩容与缩容,自动更新endpoints,实现对应用的负载均衡
service默认使用clusterip类型,只能在集群中访问
nodeport类型,可以在集群外部访问
[root@k8s2 ~]# kubectl edit svc myapp
查看修改结果,类型改为nodeport
[root@k8s2 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 120m
myapp NodePort 10.106.225.101 <none> 80:30280/TCP 23m
访问集群任意节点+端口
[root@k8s1 docker]# curl 192.168.56.172:30280/hostname.html
myapp-678fcbc488-gkf4z
[root@k8s1 docker]# curl 192.168.56.173:30280/hostname.html
myapp-678fcbc488-gqdgk
[root@k8s1 docker]# curl 192.168.56.174:30280/hostname.html
myapp-678fcbc488-v7ftf
更新应用版本
镜像从myapp:v1更新为myapp:v2
[root@k8s2 ~]# kubectl set image deployment/myapp myapp=myapp:v2
[root@k8s1 docker]# curl 192.168.56.174:30280
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
开启的副本数量是6,可以看到678fxbc488的信息也保存着,但是开启的副本数量是0,为什么还要保存?这是因为回滚时的需要。
回滚
若新版本发布有问题,则可以回到旧版本
[root@k8s2 ~]# kubectl rollout undo deployment myapp --to-revision=1
[root@k8s1 docker]# curl 192.168.56.174:30280
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>