资源管理介绍
-
在kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理kubernetes。
-
kubernetes的本质上就是一个集群系统,用户可以在集群中部署各种服务
-
所谓的部署服务,其实就是在kubernetes集群中运行一个个的容器,并将指定的程序跑在容器中。
-
kubernetes的最小管理单元是pod而不是容器,只能将容器放在
Pod
中, -
kubernetes一般也不会直接管理Pod,而是通过
Pod控制器
来管理Pod的。 -
Pod中服务服务的访问是由kubernetes提供的
Service
资源来实现。 -
Pod中程序的数据需要持久化是由kubernetes提供的各种
存储
系统来实现
# 查看所有pod
kubectl get pod
# 查看某个pod
kubectl get pod pod_name
# 查看某个pod,以yaml格式展示结果
kubectl get pod pod_name -o yaml
#查看某个pod的详细信息
kubectl get pod_name -o wide
查看版本
[root@k8s-master ~]# kubectl version
查看私有节点状态
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-1 Ready <none> 3d20h v1.30.5
k8s-2 Ready <none> 3d20h v1.30.5
k8s-master Ready control-plane 3d21h v1.30.5
常用资源类型
常见的命令操作
一切的示例演示的前提是你的hub仓库有这些镜像
基本命令
创建一个类型为deployment,名字为web的控制器,并指定有3个
[root@k8s-master ~]# kubectl create deployment web --image nginx/nginx --replicas 3
查看控制器
[root@k8s-master ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
web 3/3 3 3 5s
查看pod
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-78bcbff-pssd6 1/1 Running 0 49s
web-78bcbff-qlq2v 1/1 Running 0 49s
web-78bcbff-w6dqt 1/1 Running 0 49s
查看某个pod的详细信息显示
[root@k8s-master ~]# kubectl get pod web-78bcbff-pssd6 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-78bcbff-pssd6 1/1 Running 0 86s 10.244.1.4 k8s-1 <none> <none>
编辑控制器的配置,如把数量该为一个
[root@k8s-master ~]# kubectl edit deployments.apps web
此时在查看pod就会发现只有一个了
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-78bcbff-qlq2v 1/1 Running 0 5m36s
或者查看控制器
[root@k8s-master ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
web 1/1 1 1 6m45s
也可以用命令修改,此时该为6个
[root@k8s-master ~]# kubectl scale deployment web --replicas 6
查看
如果删除pod,控制器会再自动创建新的pod
如果要删除,删除资源,
[root@k8s-master ~]# kubectl delete deployments.apps web
此时在查看就会提示没有了
[root@k8s-master ~]# kubectl get pod
No resources found in default namespace.
运行和调试
运行一个pod
[root@k8s-master ~]# kubectl run web --image nginx/nginx
查看
[root@k8s-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web 1/1 Running 0 12s
端口暴露(即创建一个微服务),把微服务80端口映射到容器内的80端口
[root@k8s-master ~]# kubectl expose pod web --port 80 --target-port 80
查看
此时就可以进行访问
可以查看pod的web的详细信息,要指定pod名称
可以查看日志,指定pod的名称
删除微服务
[root@k8s-master ~]# kubectl delete service web
运行一个交互的pod
[root@k8s-master ~]# kubectl run -it test --image busybox/busybox
If you don't see a command prompt, try pressing enter.
/ #
/ #
当同时安装下CTRL和pq时会退出pod,但不会停止运行
重新进入
[root@k8s-master ~]# kubectl attach pods/test -it
如果删除交互示的pod较慢时可以加--force
[root@k8s-master ~]# kubectl delete pod test --force
在已经运行的pod中运行指定命令,此时就会在名为web的pod中运行了一个一个 bash shell 会话
[root@k8s-master ~]# kubectl exec pods/web -- /bin/bash
也可以加-it进入交互查看
把文件复制到pod里
[root@k8s-master ~]# mkdir mqw
[root@k8s-master ~]# kubectl cp mqw web:/
此时进入容器查看,就会看到在/下多出一个mqw的文件
可以把pod里的文件复制到本机中
[root@k8s-master mnt]# kubectl cp web:/home home
此时就会在mnt的目录下有home的目录
高级命令演示
生成yml模板
[root@k8s-master ~]# kubectl create deployment --image nginx/nginx web --dry-run=client -o yaml > web.yml
此时可以查看,vim web.yml
启用
[root@k8s-master ~]# kubectl apply -f web.yml
查看
因为控制器的原因,即使你删了pod,控制器会自动再开启新的pod
收回资源
[root@k8s-master ~]# kubectl delete -f web.yml
版本更新
用控制器创建pod,并暴露端口,
访问,此时是v1版本的
查看历史版本
命令修改
[root@k8s-master ~]# kubectl set image deployments/test myapp=myapp:v2
查看版本
此时再次访问,就会变成v2版本
版本回滚
[root@k8s-master ~]# kubectl rollout undo deployment test --to-revision 1
此时就会变为v1版本了
利用yaml文件部署
资源参数介绍
参数名称 | 类型 | 参数说明 |
---|---|---|
version | String | 这里是指的是K8S API的版本,目前基本上是v1,可以用kubectl api-versions命令查询 |
kind | String | 这里指的是yaml文件定义的资源类型和角色,比如:Pod |
metadata | Object | 元数据对象,固定值就写metadata |
metadata.name | String | 元数据对象的名字,这里由我们编写,比如命名Pod的名字 |
metadata.namespace | String | 元数据对象的命名空间,由我们自身定义 |
Spec | Object | 详细定义对象,固定值就写Spec |
spec.containers[] | list | 这里是Spec对象的容器列表定义,是个列表 |
spec.containers[].name | String | 这里定义容器的名字 |
spec.containers[].image | string | 这里定义要用到的镜像名称 |
spec.containers[].imagePullPolicy | String | 定义镜像拉取策略,有三个值可选: (1) Always: 每次都尝试重新拉取镜像 (2) IfNotPresent:如果本地有镜像就使用本地镜像 (3) )Never:表示仅使用本地镜像 |
spec.containers[].command[] | list | 指定容器运行时启动的命令,若未指定则运行容器打包时指定的命令 |
spec.containers[].args[] | list | 指定容器运行参数,可以指定多个 |
spec.containers[].workingDir | String | 指定容器工作目录 |
spec.containers[].volumeMounts[] | list | 指定容器内部的存储卷配置 |
spec.containers[].volumeMounts[].name | String | 指定可以被容器挂载的存储卷的名称 |
spec.containers[].volumeMounts[].mountPath | String | 指定可以被容器挂载的存储卷的路径 |
spec.containers[].volumeMounts[].readOnly | String | 设置存储卷路径的读写模式,ture或false,默认为读写模式 |
spec.containers[].ports[] | list | 指定容器需要用到的端口列表 |
spec.containers[].ports[].name | String | 指定端口名称 |
spec.containers[].ports[].containerPort | String | 指定容器需要监听的端口号 |
spec.containers[] ports[].hostPort | String | 指定容器所在主机需要监听的端口号,默认跟上面containerPort相同,注意设置了hostPort同一台主机无法启动该容器的相同副本(因为主机的端口号不能相同,这样会冲突) |
spec.containers[].ports[].protocol | String | 指定端口协议,支持TCP和UDP,默认值为 TCP |
spec.containers[].env[] | list | 指定容器运行前需设置的环境变量列表 |
spec.containers[].env[].name | String | 指定环境变量名称 |
spec.containers[].env[].value | String | 指定环境变量值 |
spec.containers[].resources | Object | 指定资源限制和资源请求的值(这里开始就是设置容器的资源上限) |
spec.containers[].resources.limits | Object | 指定设置容器运行时资源的运行上限 |
spec.containers[].resources.limits.cpu | String | 指定CPU的限制,单位为核心数,1=1000m |
spec.containers[].resources.limits.memory | String | 指定MEM内存的限制,单位为MIB、GiB |
spec.containers[].resources.requests | Object | 指定容器启动和调度时的限制设置 |
spec.containers[].resources.requests.cpu | String | CPU请求,单位为core数,容器启动时初始化可用数量 |
spec.containers[].resources.requests.memory | String | 内存请求,单位为MIB、GIB,容器启动的初始化可用数量 |
spec.restartPolicy | string | 定义Pod的重启策略,默认值为Always. (1)Always: Pod-旦终止运行,无论容器是如何 终止的,kubelet服务都将重启它 (2)OnFailure: 只有Pod以非零退出码终止时,kubelet才会重启该容器。如果容器正常结束(退出码为0),则kubelet将不会重启它 (3) Never: Pod终止后,kubelet将退出码报告给Master,不会重启该 |
spec.nodeSelector | Object | 定义Node的Label过滤标签,以key:value格式指定 |
spec.imagePullSecrets | Object | 定义pull镜像时使用secret名称,以name:secretkey格式指定 |
spec.hostNetwork | Boolean | 定义是否使用主机网络模式,默认值为false。设置true表示使用宿主机网络,不使用docker网桥,同时设置了true将无法在同一台宿主机 上启动第二个副本 |
示例
获取yaml模板
[root@k8s-master ~]# cd mqw/
[root@k8s-master mqw]# ls
[root@k8s-master mqw]# kubectl run test --image myapp:v1 --dry-run=client -o yaml > pod.yml
查看文件
[root@k8s-master mqw]# vim pod.yml
运行
资源回收
[root@k8s-master mqw]# kubectl delete -f pod.yml
注意如果多个容器运行在一个pod中,资源共享的同时在使用相同资源时也会干扰,比如端口
示例
[root@k8s-master mqw]# vim pod.yml
启动之后查看,此时有一个会启动不了
在一个pod中开启多个容器时一定要确保容器彼此不能互相干扰
示例
[root@k8s-master mqw]# vim pod1.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: timing
name: timinglee
spec:
containers:
- image: nginx/nginx:latest
name: web1
- image: busybox/busybox:latest
name: busybox
command: ["/bin/sh","-c","sleep 1000000"]
~
此时两个容器都运行了
同在一个pod中的容器公用一个网络
示例
[root@k8s-master mqw]# vim pod2.yml
运行
在同一pod下的容器进行测试
可以看到查看到了另一个容器的内容
端口映射
示例
[root@k8s-master mqw]# vim pod3.yml
运行
此时就可以访问了
设定环境变量
示例
[root@k8s-master mqw]# vim pod4.yml
运行,并测试
资源限制
示例
[root@k8s-master mqw]# vim pod5.yml
limits是设置pod使用资源的最高限制
requests是设置pod期望使用资源量,不能大于limits
查看
容器启动管理
示例
[root@k8s-master mqw]# vim pod6.yml
选择节点管理
示例
[root@k8s-master mqw]# vim pod7.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: timinglee
name: test
spec:
nodeSelector:
kubernetes.io/hostname: k8s-2 #选择在节点2上运行
restartPolicy: Always
containers:
- image: myapp:v1
name: myapp
~
运行,可以看到在节点2上运行了
共享宿主机网络
示例
[root@k8s-master mqw]# vim pod8.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: timinglee
name: test
spec:
hostNetwork: true #打开
restartPolicy: Always
containers:
- image: busybox/busybox:latest
name: busybox
command: ["/bin/sh","-c","sleep 100000"]
~
运行,测试
[root@k8s-master mqw]# kubectl apply -f pod8.yml
[root@k8s-master mqw]# kubectl exec -it pods/test -c busybox -- /bin/s
pod的生命周期
-
Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。
-
Init 容器与普通的容器非常像,除了如下两点:
-
它们总是运行到完成
-
init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成,每个 Init 容器必须运行成功,下一个才能够运行。
-
-
如果Pod的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。但是,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新启动
INIT 容器的功能
-
Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。
-
Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
-
应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
-
Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。
-
由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。
示例
[root@k8s-master mqw]# vim pod9.yml
启动之后容器并没有运行,因为没有满足在容器内有mqw这个文件
此时在容器内创建mqw的文件后,就可以运行了
探针
探针是由 kubelet 对容器执行的定期诊断:
-
ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
-
TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
-
HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
每次探测都将获得以下三种结果之一:
-
成功:容器通过了诊断。
-
失败:容器未通过诊断。
-
未知:诊断失败,因此不会采取任何行动。
Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应:
-
livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success。
-
readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。
-
startupProbe: 指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。
ReadinessProbe 与 LivenessProbe 的区别
-
ReadinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。
-
LivenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施
StartupProbe 与 ReadinessProbe、LivenessProbe 的区别
-
如果三个探针同时存在,先执行 StartupProbe 探针,其他两个探针将会被暂时禁用,直到 pod 满足 StartupProbe 探针配置的条件,其他 2 个探针启动,如果不满足按照规则重启容器。
-
另外两种探针在容器启动后,会按照配置,直到容器消亡才停止探测,而 StartupProbe 探针只是在容器启动后按照配置满足一次后,不在进行后续的探
存活探针演示
[root@k8s-master mqw]# vim pod10.yml
解释
tcpSocket作用:检测端口存在性
initialDelaySeconds: 3 #容器启动后要等待多少秒后就探针开始工作,默认是 0
periodSeconds: 1 #执行探测的时间间隔,默认为 10s
timeoutSeconds: 1 #探针执行检测请求后,等待响应的超时时间,默认为 1s
运行
就绪探针
[root@k8s-master mqw]# vim pod11.yml
此时启动后,但还是处于准备状态
端口启动微服务
[root@k8s-master mqw]# kubectl expose pod readiness --port 80 --target-port 80
此时查看详细信息,但端口没暴露,不满足条件
添加
[root@k8s-master mqw]# kubectl exec pods/readiness -c myapp -- /bin/sh -c "echo test > /usr/share/nginx/html/test.html"