环境说明:
主机名
操作系统版本
ip
docker version
kubelet version
备注
master
Centos 7.6.1810
172.27.9.131
Docker 18.09.6
V1.14.2
master主机
node01
Centos 7.6.1810
172.27.9.135
Docker 18.09.6
V1.14.2
node节点
node02
Centos 7.6.1810
172.27.9.136
Docker 18.09.6
V1.14.2
node节点
一、 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。
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
先创建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.yaml
apiVersion: extensions/v1beta1 #描述文件遵循extensions/v1beta1版本的Kubernetes API
kind: Deployment #创建资源类型为Deployment
metadata: #该资源元数据
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
查看创建的资源
3. 进入pod
进入pod kubia-66c8b6d4fc-cdzzg
[root@master ~]# kubectl exec -it kubia-66c8b6d4fc-cdzzg bash
类似docker,使用kubectl exec命令进入容器
容器的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
通过--show-labels参数可查看pod的标签
通过标签筛选pod
[root@master ~]# kubectl get pod -l app --show-labels
NAME READY STATUS RESTARTS AGE LABELS
http-label-7cf498876f-rhqxf 1/1 Running 0 107s app=web,env=prod,pod-template-hash=7cf498876f
nginx-master-9d4cf4f77-cg47g 1/1 Running 1 46h app=nginx,pod-template-hash=9d4cf4f77
nginx-master-9d4cf4f77-lflck 1/1 Running 1 46h app=nginx,pod-template-hash=9d4cf4f77
nginx-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
将pod http-label-7cf498876f-rhqxf的标签env由prod更改为debug
删除标签
[root@master ~]# kubectl label pod http-label-7cf498876f-rhqxf env-
pod/http-label-7cf498876f-rhqxf labeled
将pod http-label-7cf498876f-rhqxf的标签env删除
2. 通过标签指定pod创建的节点
给node节点打标签
分别给节点打上标签node=master、node=node01、node=node02
指定node创建pod
[root@master ~]# more httpd-node.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: httpd-node
spec:
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
四、命名空间
Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的pods, services, replication controllers和deployments等都是属于某一个namespace的(默认是default)
1. 查看命名空间
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 37d
kube-node-lease Active 46h
kube-public Active 37d
kube-system Active 37d
其中命名空间kube-node-lease发布于1.14的beta版本,被kubelet用作确定节点运行状况。
2. 查看指定命名空间的pod
[root@master ~]# kubectl get po -n kube-system
NAME READY STATUS RESTARTS AGE
busybox03-5b4cb76f96-jg8f8 1/1 Running 4 5d22h
coredns-fb8b8dccf-bxvrz 1/1 Running 24 37d
coredns-fb8b8dccf-mqvd8 1/1 Running 24 37d
etcd-master 1/1 Running 26 37d
fluentd-elasticsearch-928nt 1/1 Running 21 29d
fluentd-elasticsearch-gw5tx 1/1 Running 30 29d
fluentd-elasticsearch-n4mc6 1/1 Running 26 29d
kube-apiserver-master 1/1 Running 26 37d
kube-controller-manager-master 1/1 Running 31 37d
kube-flannel-ds-amd64-lkh5n 1/1 Running 30 35d
kube-flannel-ds-amd64-pv5ll 1/1 Running 24 36d
kube-flannel-ds-amd64-wnn5g 1/1 Running 36 36d
kube-proxy-42vb5 1/1 Running 26 37d
kube-proxy-7nrfk 1/1 Running 30 35d
kube-proxy-x7dmk 1/1 Running 35 36d
kube-scheduler-master 1/1 Running 32 37d
kubernetes-dashboard-7b87f5bdd6-7d5s8 1/1 Running 4 5d18h
该命令也可写作为:'kubectl get pod --namespace=kube-system'
3. 创建命名空间
文件方式
创建test01-namespace
[root@master ~]# more test01-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
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-namespace
namespace/test02-namespace created
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 GATES
httpd-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-namespace
Context "kubernetes-admin@kubernetes" modified.
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
httpd-6b77d6648-zqnv4 1/1 Running 0 5m6s
配置kcd,通过kcd namespace可切换命名空间。
五、扩容/缩容
创建文件nginx-scale.yaml并新建资源
新建deployment nginx-scale,pod副本数为3
文件方式
通过修改文件中参数replicas的值并重新执行kubectl apply命令即可实现pod的扩缩容
命令方式
[root@master ~]# kubectl scale deployment nginx-scale --replicas=1
deployment.extensions/nginx-scale scaled
通过命令将pod副本数缩容为1
六、failover
1. pod节点分布查看
2. failover测试
节点node02关机
[root@node02 ~]# init 0
查看node状态和pod分布
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/v1
kind: Deployment
metadata:
name: nginx-roll
namespace: test02-namespace
spec:
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-roll
Waiting 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
查看pod
分别查看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命令
nginx升级为1.17
kubectl set image方式
[root@master ~]# kubectl set image deployment -n test02-namespace nginx-roll nginx-roll=nginx:1.17.1
deployment.extensions/nginx-roll image updated
将nginx升级至1.17.1
3. 回滚
查看deployments版本
[root@master ~]# kubectl rollout history deployments -n test02-namespace nginx-roll
deployment.extensions/nginx-roll
REVISION CHANGE-CAUSE
1 kubectl apply --filename=nginx-roll.yaml --record=true
2 kubectl apply --filename=nginx-roll.yaml --record=true
3 kubectl apply --filename=nginx-roll.yaml --record=true
查看deployment具体版本信息
回滚至上一个版本
[root@master ~]# kubectl rollout undo deployment -n test02-namespace nginx-roll
deployment.extensions/nginx-roll rolled back
回滚至指定版本
[root@master ~]# kubectl rollout undo deployment -n test02-namespace nginx-roll --to-revision=1
deployment.extensions/nginx-roll rolled back
--to-revision=1指定回滚至1.16版本的nginx
查看ReplicasSet
可以看到在升级过程中replicaset保留了修改的历史版本信息
八、内外网访问
1. 创建pod
[root@master ~]# more web-svc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-svc
namespace: test02-namespace
spec:
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.yaml
deployment.apps/web-svc created
创建pod,namespace为test02,副本数为3
2. 内网访问
创建servcie
内网通过pod ip访问没什么太大意义,因为pod会随时重建,每次ip会随机分配
[root@master ~]# cat >> web-svc.yaml << EOF
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
namespace: test02-namespace
spec:
selector:
app: web-svc
ports:
- protocol: TCP
port: 8080
targetPort: 80
> EOF
[root@master ~]# kubectl apply -f web-svc.yaml
deployment.apps/web-svc unchanged
service/web-svc created
查看创建的service
[root@master ~]# kubectl get service -n test02-namespace
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web-svc ClusterIP 10.98.103.41 8080/TCP 5m12s
修改index.html
[root@master ~]# kubectl get po -o wide -n test02-namespace
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-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
> EOF
root@web-svc-58956c55fc-7vnw5:/usr/local/apache2# exit
exit
[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
> EOF
root@web-svc-58956c55fc-8wbst:/usr/local/apache2# exit
exit
[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
> EOF
root@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;done
web-svc-58956c55fc-8wbst
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-8wbst
web-svc-58956c55fc-8wbst
通过service内容访问pod
3. 外网访问
修改servcie
apiVersion: v1
kind: Service
metadata:
name: web-svc
namespace: test02-namespace
spec:
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;done
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-8wbst
web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-8wbst
web-svc-58956c55fc-7vnw5
web-svc-58956c55fc-nxt4r
web-svc-58956c55fc-7vnw5
通过node ip + nodePort方式外网访问pod
九、日志查看
使用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行的日志,
2. 查看前一个容器的日志
[root@master ~]# kubectl logs kubernetes-dashboard-7b87f5bdd6-m62r6 -n kube-system --previous
'--previous':当容器重启时,该参数可以查看前一个容器的日志。
3. 通过标签查看日志
[root@master ~]# kubectl logs -lapp=web
查看标签为'app=web'的日志
'-lapp=web'该日志是标签为'app=web'的合集
十、删除pod
1. 通过删除deployment删除pod
通过deployment创建的pod可以直接删除deployment
[root@master ~]# kubectl delete deployments kubia
deployment.extensions "kubia" deleted
2. 通过删除namespace删除pod
删除namespace中所有资源
[root@master ~]# kubectl delete all --all -n test02-namespace
直接删除namespace
[root@master ~]# kubectl delete ns test01-namespace
总结:
直接删除pod会重建一个新的不同名的pod;
直接删除replicasets会重建同名replicasets,其下所有pod则会删除重建且名字不同;
直接删除deployments则其下的replicasets和pod将一起被删除;