一、 pod简介
1. pod概览
Pod是kubernetes中你可以创建和部署的最小也是最简单位。一个Pod代表着集群中运行的一个进程。
Pod中封装着应用的容器(有的情况下是好几个容器),存储、独立的网络IP,管理容器如何运行的策略选项。Pod代表着部署的一个单位:kubernetes中应用的一个实例,可能由一个或者多个容器组合在一起共享资源
在Kubrenetes集群中Pod有如下两种使用方式:
- 一个Pod中运行一个容器。“每个Pod中一个容器”的模式是最常见的用法:在这种使用方式中,你可以把Pod想象成是单个容器的封装,kuberentes管理的是Pod而不是直接管理容器。
- 在一个Pod中同时运行多个容器。一个Pod中也可以同时封装几个需要紧密耦合互相协作的容器,它们之间共享资源。这些在同一个Pod中的容器可以互相协作成为一个service单位——一个容器共享文件,另一个“sidecar”容器来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理。
2. pod网络
由于一个pod中的容器运行于相同的Network命名空间中,因此它们共享相同的IP地址和端口空间。当两个pod彼此之间发送网络数据包时,它们都会将对方的实际IP地址看作数据包中的源IP。
![afbdbf2b10f0dd8cae813d64aadadaff.png](https://i-blog.csdnimg.cn/blog_migrate/f2b4950d763e5556766d6854779f473f.jpeg)
pod 是逻辑主机,其行为与非容器世界中的物理主机或虚拟机非常相似。此外,运行在同一个pod中的进程与运行在同一物理机或虚拟机上的进程相似,只是每个进程都封装在一个容器之中。
二、创建pod的两种方式
1. 命令方式
[root@master ~]# kubectl run kubia --image=luksa/kubia --replicas=3 kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.deployment.apps/kubia created
kubia指定deployment名字(本文pod的创建不论命令还是文件方式都使用Controller deployment),--image=luksa/kubia显示的是指定要运行的镜像,--replicas=3指定副本数为3
![9c1684ead684ce4b725418cba8652112.png](https://i-blog.csdnimg.cn/blog_migrate/652663c515387c6253a5b47585d41841.jpeg)
先创建deployment:nginx-deployment,再创建replicasets:kubia-66c8b6d4fc,最后创建三个pod:kubia-66c8b6d4fc-cdzzg、kubia-66c8b6d4fc-ff9f8和kubia-66c8b6d4fc-xtcmm,3个pod分别位于3个node节点上。
2. 文件方式
[root@master ~]# more nginx-master.yamlapiVersion: extensions/v1beta1 #描述文件遵循extensions/v1beta1版本的Kubernetes APIkind: Deployment #创建资源类型为Deploymentmetadata: #该资源元数据 name: nginx-master #Deployment名称spec: #Deployment的规格说明 replicas: 3 #指定副本数为3 template: #定义Pod的模板 metadata: #定义Pod的元数据 labels: #定义label(标签) app: nginx #label的key和value分别为app和nginx spec: #Pod的规格说明 containers: - name: nginx #容器的名称 image: nginx:latest #创建容器所使用的镜像
执行创建命令
[root@master ~]# kubectl create -f nginx-master.yaml deployment.extensions/nginx-master created
查看创建的资源
![02d790cfdef138aaa60f8ce433333ad0.png](https://i-blog.csdnimg.cn/blog_migrate/511ff5e533cece0bd6e98ce91265611d.jpeg)
3. 进入pod
进入pod kubia-66c8b6d4fc-cdzzg
[root@master ~]# kubectl exec -it kubia-66c8b6d4fc-cdzzg bash
类似docker,使用kubectl exec命令进入容器
![4d88c77b0d3a61b8f0e01e6767d196e0.png](https://i-blog.csdnimg.cn/blog_migrate/fe99f4ba8787fae54d1b8d87ce96d869.jpeg)
容器的ip和主机名同pod
三、标签
标签其实就一对 key/value,可以附加到资源的任意键值对,标签可以用来划分特定组的对象,用以选择具有该确切标签的资源。
1. pod使用标签
pod指定标签
[root@master ~]# kubectl run http-label --image=httpd --labels="app=web,env=prod"kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.deployment.apps/http-label created
指定pod的标签为'app=web和env=prod'
查看pod的标签
[root@master ~]# kubectl get pod --show-labels
![5e558a8152df78b465b55a0caade1cba.png](https://i-blog.csdnimg.cn/blog_migrate/3e65b175c114f1d1047f5a393ed7666c.jpeg)
通过--show-labels参数可查看pod的标签
通过标签筛选pod
[root@master ~]# kubectl get pod -l app --show-labels NAME READY STATUS RESTARTS AGE LABELShttp-label-7cf498876f-rhqxf 1/1 Running 0 107s app=web,env=prod,pod-template-hash=7cf498876fnginx-master-9d4cf4f77-cg47g 1/1 Running 1 46h app=nginx,pod-template-hash=9d4cf4f77nginx-master-9d4cf4f77-lflck 1/1 Running 1 46h app=nginx,pod-template-hash=9d4cf4f77nginx-master-9d4cf4f77-w4xgb 1/1 Running 1 46h app=nginx,pod-template-hash=9d4cf4f77
通过-l app参数可筛选所有标签为app的pod
修改现有标签
[root@master ~]# kubectl label pod http-label-7cf498876f-rhqxf env=debug --overwrite pod/http-label-7cf498876f-rhqxf labeled
![040e17cf5be78f2520a6399164bf680a.png](https://i-blog.csdnimg.cn/blog_migrate/050c24d382525ad1cb2d330f4c207de5.jpeg)
将pod http-label-7cf498876f-rhqxf的标签env由prod更改为debug
删除标签
[root@master ~]# kubectl label pod http-label-7cf498876f-rhqxf env-pod/http-label-7cf498876f-rhqxf labeled
![e68deae96174d22d34aac4bd951a80a3.png](https://i-blog.csdnimg.cn/blog_migrate/bc064ae123f889b655b1c7cf1fc852d7.jpeg)
将pod http-label-7cf498876f-rhqxf的标签env删除
2. 通过标签指定pod创建的节点
给node节点打标签
![a2ea4c40b7a758783dfd8814d5f31292.png](https://i-blog.csdnimg.cn/blog_migrate/1f9c215b1c85194eda55b921534b27d9.jpeg)
分别给节点打上标签node=master、node=node01、node=node02
指定node创建pod
[root@master ~]# more httpd-node.yaml apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: httpd-nodespec: template: metadata: labels: env: prod spec: containers: - name: httpd-node image: httpd:latest nodeSelector: node: master[root@master ~]# kubectl apply -f httpd-node.yaml
指定pod的label为env:prod,node节点为master
![e9e90588960bf1a35abdc8413c501c43.png](https://i-blog.csdnimg.cn/blog_migrate/38f4c2f15b64f23c2a2fa1742cc96142.jpeg)
四、命名空间
Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的pods, services, replication controllers和deployments等都是属于某一个namespace的(默认是default)
1. 查看命名空间
[root@master ~]# kubectl get nsNAME STATUS AGEdefault Active 37dkube-node-lease Active 46hkube-public Active 37dkube-system Active 37d
其中命名空间kube-node-lease发布于1.14的beta版本,被kubelet用作确定节点运行状况。
2. 查看指定命名空间的pod
[root@master ~]# kubectl get po -n kube-system NAME READY STATUS RESTARTS AGEbusybox03-5b4cb76f96-jg8f8 1/1 Running 4 5d22hcoredns-fb8b8dccf-bxvrz 1/1 Running 24 37dcoredns-fb8b8dccf-mqvd8 1/1 Running 24 37detcd-master 1/1 Running 26 37dfluentd-elasticsearch-928nt 1/1 Running 21 29dfluentd-elasticsearch-gw5tx 1/1 Running 30 29dfluentd-elasticsearch-n4mc6 1/1 Running 26 29dkube-apiserver-master 1/1 Running 26 37dkube-controller-manager-master 1/1 Running 31 37dkube-flannel-ds-amd64-lkh5n 1/1 Running 30 35dkube-flannel-ds-amd64-pv5ll 1/1 Running 24 36dkube-flannel-ds-amd64-wnn5g 1/1 Running 36 36dkube-proxy-42vb5 1/1 Running 26 37dkube-proxy-7nrfk 1/1 Running 30 35dkube-proxy-x7dmk 1/1 Running 35 36dkube-scheduler-master 1/1 Running 32 37dkubernetes-dashboard-7b87f5bdd6-7d5s8 1/1 Running 4 5d18h
该命令也可写作为:'kubectl get pod --namespace=kube-system'
3. 创建命名空间
文件方式
创建test01-namespace
[root@master ~]# more test01-namespace.yaml apiVersion: v1kind: Namespacemetadata: name: test01-namespace[root@master ~]# kubectl apply -f test01-namespace.yaml namespace/test01-namespace created
kubectl apply和kubectl create命令类似,都可以根据文件创建相关资源。
命令方式
创建test02-namespace
[root@master ~]# kubectl create ns test02-namespacenamespace/test02-namespace created
![830432203500a6532dde0b6da60c918f.png](https://i-blog.csdnimg.cn/blog_migrate/2873f87d6914d3679c37e1949f03be3f.jpeg)
4. pod指定命名空间
[root@master ~]# kubectl run httpd --image=httpd -n test01-namespace kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.deployment.apps/httpd created[root@master ~]# kubectl get pod -o wide -n test01-namespace NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATEShttpd-6b77d6648-zqnv4 0/1 ContainerCreating 0 27s node01
指定创建pod的命名空间为test01-namespace,查询pod是需带上命名空间。
命名空间切换
[root@master ~]# alias kcd='kubectl config set-context $(kubectl config current-context) --namespace'[root@master ~]# kcd test01-namespaceContext "kubernetes-admin@kubernetes" modified.[root@master ~]# kubectl get podNAME READY STATUS RESTARTS AGEhttpd-6b77d6648-zqnv4 1/1 Running 0 5m6s
配置kcd,通过kcd namespace可切换命名空间。
五、扩容/缩容
创建文件nginx-scale.yaml并新建资源
![f20d5d61797bb7b38d0c74f1faf8fae2.png](https://i-blog.csdnimg.cn/blog_migrate/3efd48935061973d70d49d3954b119f7.jpeg)
新建deployment nginx-scale,pod副本数为3
文件方式
![e2366077cc5429aaa9e3539bbd1da4ae.png](https://i-blog.csdnimg.cn/blog_migrate/d32034f8ccc51829a1239b87e42f140b.jpeg)
通过修改文件中参数replicas的值并重新执行kubectl apply命令即可实现pod的扩缩容
命令方式
[root@master ~]# kubectl scale deployment nginx-scale --replicas=1deployment.extensions/nginx-scale scaled
![cb608170ac8b2192bf1fafcddd7412aa.png](https://i-blog.csdnimg.cn/blog_migrate/d32c4e36c481dc3fd5d3f71f47c54bd8.jpeg)
通过命令将pod副本数缩容为1
六、failover
1. pod节点分布查看
![a2993767506c87440f2749188e557f78.png](https://i-blog.csdnimg.cn/blog_migrate/50f9258a13ab28c1506f76d7a0ef0d79.jpeg)
2. failover测试
节点node02关机
[root@node02 ~]# init 0
查看node状态和pod分布
![779cc2f1d68be39a6978222789052e34.png](https://i-blog.csdnimg.cn/blog_migrate/aa4b0e2eed746c42d30553c781573b16.jpeg)
node02状态为NotReady且之前在该节点的pod被迁移至master或者node01
当node02恢复后,运行在该节点的Pod会被删除,且迁移至master和node01的Pod不会重新调度回到node02
注意,本节有个前提:所有pod需绑定到replication controller上,'裸奔的 pod'(没有绑定到任何replication controller)不会被重新调度
七、升级及回滚
1. 创建deployment
[root@master ~]# more nginx-roll.yaml apiVersion: apps/v1kind: Deploymentmetadata: name: nginx-roll namespace: test02-namespacespec: selector: matchLabels: env: prod replicas: 3 template: metadata: labels: env: prod spec: containers: - name: nginx-roll image: nginx:1.16[root@master ~]# kubectl apply -f nginx-roll.yaml --record deployment.apps/nginx-roll created
创建deployment nginx-roll,副本数为3,namespace为test02-namespace,nginx版本为1.16,--record参数会记录历史版本号
Deployment apiVersion版本说明:
- 1.6版本之前 apiVsersion:extensions/v1beta1
- 1.6版本到1.9版本之间:apps/v1beta1
- 1.9版本之后:apps/v1
查看部署状态
[root@master ~]# kubectl rollout status deployment -n test02-namespace nginx-rollWaiting for deployment "nginx-roll" rollout to finish: 0 of 3 updated replicas are available...Waiting for deployment "nginx-roll" rollout to finish: 1 of 3 updated replicas are available...Waiting for deployment "nginx-roll" rollout to finish: 2 of 3 updated replicas are available...deployment "nginx-roll" successfully rolled out
![b05509610084f748c3fab2256ff131ac.png](https://i-blog.csdnimg.cn/blog_migrate/de21eac667ea877fd2fc7f1901b71b27.jpeg)
查看pod
![98c72acb141ab336571b1c662315bd87.png](https://i-blog.csdnimg.cn/blog_migrate/2eca65381f5c987ff3c52240c3deac52.jpeg)
分别查看deployment、replicaset、pod
2. 升级
升级方式有多种,比如'kubectl edit deployments -n test02-namespace nginx-roll'方式、直接修改nginx-roll.yaml文件方式、kubectl set image方式等
修改文件方式
[root@master ~]# sed -i 's/image: nginx:1.16/image: nginx:1.17/g' nginx-roll.yaml[root@master ~]# kubectl apply -f nginx-roll.yaml --record deployment.apps/nginx-roll configured
将nginx-roll.yaml中nginx镜像版本修改为1.17并重新执行kubectl apply命令
![c64e8f0f972d9855fa2a34b8f95f2541.png](https://i-blog.csdnimg.cn/blog_migrate/cde75eac792353116043f6fef03ee8f6.jpeg)
nginx升级为1.17
kubectl set image方式
[root@master ~]# kubectl set image deployment -n test02-namespace nginx-roll nginx-roll=nginx:1.17.1deployment.extensions/nginx-roll image updated
将nginx升级至1.17.1
![cef7a12c07c3df0ef1a861df496bc179.png](https://i-blog.csdnimg.cn/blog_migrate/3668a334702951ef9f68d805cd797bc4.jpeg)
3. 回滚
查看deployments版本
[root@master ~]# kubectl rollout history deployments -n test02-namespace nginx-rolldeployment.extensions/nginx-roll REVISION CHANGE-CAUSE1 kubectl apply --filename=nginx-roll.yaml --record=true2 kubectl apply --filename=nginx-roll.yaml --record=true3 kubectl apply --filename=nginx-roll.yaml --record=true
查看deployment具体版本信息
![f4cd455048ad1ab70ffded4a8254cda4.png](https://i-blog.csdnimg.cn/blog_migrate/068379b1b129e2991d36692aebff671b.jpeg)
回滚至上一个版本
[root@master ~]# kubectl rollout undo deployment -n test02-namespace nginx-roll deployment.extensions/nginx-roll rolled back
![85d6206d9fd21f57a282ac17534e72a3.png](https://i-blog.csdnimg.cn/blog_migrate/3973cf1f12e676fa1fddf418fb90e70d.jpeg)
回滚至指定版本
[root@master ~]# kubectl rollout undo deployment -n test02-namespace nginx-roll --to-revision=1deployment.extensions/nginx-roll rolled back
![0c0912551fda62c80211895f7eaa004d.png](https://i-blog.csdnimg.cn/blog_migrate/f9476dc7f268c522b3ea5974ffbbc54c.jpeg)
--to-revision=1指定回滚至1.16版本的nginx
查看ReplicasSet
![dd997e6a1f4a7a40ee141059ed337a4c.png](https://i-blog.csdnimg.cn/blog_migrate/4d9adc73800ad877082b57eb628da2b9.jpeg)
可以看到在升级过程中replicaset保留了修改的历史版本信息
八、内外网访问
1. 创建pod
[root@master ~]# more web-svc.yaml apiVersion: apps/v1kind: Deploymentmetadata: name: web-svc namespace: test02-namespacespec: selector: matchLabels: app: web-svc replicas: 3 template: metadata: labels: app: web-svc spec: containers: - name: web-svc image: httpd:latest[root@master ~]# kubectl apply -f web-svc.yamldeployment.apps/web-svc created
创建pod,namespace为test02,副本数为3
![2f900cb0b2415a02220d8b0c2cbdf2e6.png](https://i-blog.csdnimg.cn/blog_migrate/d0db2538105afe558d3d1d65ffa1f4dd.jpeg)
2. 内网访问
创建servcie
内网通过pod ip访问没什么太大意义,因为pod会随时重建,每次ip会随机分配
[root@master ~]# cat >> web-svc.yaml << EOF---apiVersion: v1kind: Servicemetadata: name: web-svc namespace: test02-namespacespec: selector: app: web-svc ports: - protocol: TCP port: 8080 targetPort: 80> EOF[root@master ~]# kubectl apply -f web-svc.yamldeployment.apps/web-svc unchangedservice/web-svc created
查看创建的service
[root@master ~]# kubectl get service -n test02-namespaceNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEweb-svc ClusterIP 10.106.53.114 8080/TCP 5m12s
修改index.html
[root@master ~]# kubectl get po -o wide -n test02-namespaceNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATESnginx-roll-8fd7f679-9h9ng 1/1 Running 2 2d17h 10.244.1.52 node01 nginx-roll-8fd7f679-b5clj 1/1 Running 2 2d17h 10.244.0.180 master nginx-roll-8fd7f679-pwkbw 1/1 Running 2 2d17h 10.244.2.6 node02 web-svc-58956c55fc-7vnw5 1/1 Running 0 3m35s 10.244.1.59 node01 web-svc-58956c55fc-8wbst 1/1 Running 0 3m35s 10.244.2.14 node02 web-svc-58956c55fc-nxt4r 1/1 Running 0 3m35s 10.244.2.13 node02 [root@master ~]# kubectl exec -it web-svc-58956c55fc-7vnw5 -n test02-namespace bash root@web-svc-58956c55fc-7vnw5:/usr/local/apache2# cat > /usr/local/apache2/htdocs/index.html << EOF> web-svc-58956c55fc-7vnw5> EOFroot@web-svc-58956c55fc-7vnw5:/usr/local/apache2# exitexit[root@master ~]# kubectl exec -it web-svc-58956c55fc-8wbst -n test02-namespace bash root@web-svc-58956c55fc-8wbst:/usr/local/apache2# cat > /usr/local/apache2/htdocs/index.html << EOF> web-svc-58956c55fc-8wbst> EOFroot@web-svc-58956c55fc-8wbst:/usr/local/apache2# exitexit[root@master ~]# kubectl exec -it web-svc-58956c55fc-nxt4r -n test02-namespace bash root@web-svc-58956c55fc-nxt4r:/usr/local/apache2# cat > /usr/local/apache2/htdocs/index.html << EOF> web-svc-58956c55fc-nxt4r> EOFroot@web-svc-58956c55fc-nxt4r:/usr/local/apache2# exit
分别进入pod,将访问的主页修改为pod名
内网访问pod
[root@master ~]# for i in {1..10};do sleep 1;curl 10.98.103.41:8080;doneweb-svc-58956c55fc-8wbstweb-svc-58956c55fc-7vnw5web-svc-58956c55fc-7vnw5 web-svc-58956c55fc-nxt4r web-svc-58956c55fc-nxt4rweb-svc-58956c55fc-7vnw5web-svc-58956c55fc-7vnw5 web-svc-58956c55fc-nxt4rweb-svc-58956c55fc-8wbstweb-svc-58956c55fc-8wbst
通过service内容访问pod
![f11872ae5237face6beb0c9568895977.png](https://i-blog.csdnimg.cn/blog_migrate/6fec2a90379696cd655febe128f9595d.jpeg)
3. 外网访问
修改servcie
apiVersion: v1kind: Servicemetadata: name: web-svc namespace: test02-namespacespec: type: NodePort selector: app: web-svc ports: - protocol: TCP nodePort: 30002 port: 8080 targetPort: 80
新增'type: NodePort'和'nodePort: 30002',通过NodePort方式外网访问pod,映射端口为30002,重新kubectl apply
外网访问pod
[root@master ~]# for i in {1..10};do sleep 1;curl 172.27.9.131:30002;doneweb-svc-58956c55fc-7vnw5web-svc-58956c55fc-8wbst web-svc-58956c55fc-nxt4rweb-svc-58956c55fc-7vnw5web-svc-58956c55fc-7vnw5 web-svc-58956c55fc-nxt4rweb-svc-58956c55fc-8wbstweb-svc-58956c55fc-7vnw5 web-svc-58956c55fc-nxt4rweb-svc-58956c55fc-7vnw5
通过node ip + nodePort方式外网访问pod
![2519834e95231409a023a3bcfd3bb528.png](https://i-blog.csdnimg.cn/blog_migrate/11cc08fdff1e14e2c5b400f9f687cc78.jpeg)
九、日志查看
使用kubectl logs命令可获取pod日志
1. 查看最近的日志
[root@master ~]# kubectl logs kubernetes-dashboard-7b87f5bdd6-m62r6 -n kube-system --tail=20
'--tail=20':查看命名空间kube-system下kubernetes-dashboard-7b87f5bdd6-m62r6最近20行的日志,
![17667007d10cda4b34e8f4460fb65f60.png](https://i-blog.csdnimg.cn/blog_migrate/621b14ef8fa790ec1fbfdb4f158ee7e6.jpeg)
2. 查看前一个容器的日志
[root@master ~]# kubectl logs kubernetes-dashboard-7b87f5bdd6-m62r6 -n kube-system --previous
'--previous':当容器重启时,该参数可以查看前一个容器的日志。
![5f0d81b26075de0608e43cebacc7d891.png](https://i-blog.csdnimg.cn/blog_migrate/aa223584dc6f3d63397215be18ad4e99.jpeg)
3. 通过标签查看日志
[root@master ~]# kubectl logs -lapp=web
查看标签为'app=web'的日志
![ed99bf1b17d8a7068b59e6d2737f13f7.png](https://i-blog.csdnimg.cn/blog_migrate/87d283ffe36f9449afbc736b2963d511.jpeg)
'-lapp=web'该日志是标签为'app=web'的合集
十、删除pod
1. 通过删除deployment删除pod
通过deployment创建的pod可以直接删除deployment
[root@master ~]# kubectl delete deployments kubia deployment.extensions "kubia" deleted
![581d7f550b9995a0161f4a7771fd8f23.png](https://i-blog.csdnimg.cn/blog_migrate/66faf096c8b61cb6e95b9ee8b47d3266.jpeg)
2. 通过删除namespace删除pod
删除namespace中所有资源
[root@master ~]# kubectl delete all --all -n test02-namespace
![87b6b6a7a5a4062b6791664c91fd9a8c.png](https://i-blog.csdnimg.cn/blog_migrate/a61b34fc35271d9da229d376d82992bc.jpeg)
直接删除namespace
[root@master ~]# kubectl delete ns test01-namespace
![a207f49733809620ece5a3d1f215795b.png](https://i-blog.csdnimg.cn/blog_migrate/c132a765ae71e4b0b8786d014f9039c4.jpeg)
总结:
- 直接删除pod会重建一个新的不同名的pod;
- 直接删除replicasets会重建同名replicasets,其下所有pod则会删除重建且名字不同;
- 直接删除deployments则其下的replicasets和pod将一起被删除;
本文所有脚本和配置文件已上传github:https://github.com/loong576/k8s-in-action-for-pods.git