k8s里的资源对象
在k8s里,yaml用来声明API对象的,那么API对象都有哪些?
可以这样查看资源对象
kubectl api-resources
yaml
- 使用缩进表示层次,缩进不允许使用tab,只能用空格,缩进空格数多少不要求,只要保证同一层级空格数一样多即可
- 使用 # 书写注释
- 数组(列表)是使用 - 开头的清单形式
- 对象(字典)的格式与JSON基本相同,但Key不需要使用双引号。
- 表示对象的 : 和表示数组的 - 后面都必须要有空格。
- 可以使用 --- 在一个文件里分隔多个YAML对象
![[yaml基本介绍.png]]
yaml简单使用
01、运行一个pod
可以使用kubectl命令快速启动一个pod
kubectl run pod-demo --image=busybox
说明:Pod名字为pod-demo,镜像为busybox
然后从已知的pod到处yaml文件:
kubectl get pod pod-demo -o yaml > pod-demo.yaml
以下为一个pod的yaml文件示例内容:
apiVersion: v1
kind: Pod
metadata:
name: ngx-pod
namespace: aming
labels: ## labels字段非常关键,它可以添加任意数量的Key-Value,目的是为了让pod的信息更加详细
env: dev
spec: ##用来定义该pod更多的资源信息,比如containers, volume, storage
containers: ##定义容器属性
- image: nginx:1.23.2
imagePullPolicy: IfNotPresent ##镜像拉取策略,三种:Always/Never/IfNotPresent,一般默认是IfNotPresent,也就是说只有本地不存在才会远程拉取镜像,可以减少网络消耗。
name: ngx
env: ##定义变量,类似于Dockerfile里面的ENV指令
- name: os
value: "Rocky Linux"
ports:
- containerPort: 80
这个yaml文件,可以创建一个临时pod导出一个模板yaml文件
然后基于模板yaml去修改即可
03、基于yaml文件创建和删除pod
工作中创建pod,更多的是基于yaml来创建。而非使用bukectl命令
创建:
kubectl apply -f ngx-pod.yaml
删除:
kubectl delete -f ngx-pod.yaml
04、查看pod信息
常见的观察和管理pod方法
列出pod:
列出默认命名空间的pod
`kubectl get pod`
列出kube-system命名空间的pod
kubectl get pod -n kube-system
查看pod的详细信息:
kubectl describe pod ngx-pod
可以看到pod的相关信息,比如镜像是什么、IP是什么、pod的创建日志等
查看pod日志:
kubectl logs ngx-pod
##动态查看日志,类似于tail -f
kubectl logs -f ngx-pod
##查看最后100行日志
kubectl logs --tail=100 ngx-pod
一、API资源对象Pod
Pod原理和生命周期
Pod为k8s里最小、最简单的资源对象。它和docker容器还是有一定区别的,它比容器单元更大一些,也就是说在Pod里面会包含容器,一个pod里面可以有多个容器。
![[pod对象01.png]]
1.pod原理
Pod 是在 K8s集群中运行部署应用或服务的最小单元。
在同一个Pod中其实可以同时运行多个容器,这些容器能够共享网络、存储以及 CPU/内存等资源。
每个Pod都有一个特殊的被称为 “根容器” 的Pause容器。Pause容器的主要作用是为Pod中的其他容器提供一些基本的功能,比如网络和PID命名空间的共享、 负责管理Pod内其他容器的生命周期。
网络命名空间共享:pause容器为整个Pod创建一个网络命名空间,Pod内的其他容器都将加入这个网络命名空间。这样,Pod中的所有容器都可以共享同一个IP地址和端口空间,从而实现容器间的紧密通信。
PID命名空间共享:pause容器充当Pod内其他容器的父容器,它们共享同一个PID命名空间。这使得Pod内的容器可以通过进程ID直接发现和相互通信,同时也使得Pod具有一个统一的生命周期。
生命周期管理:pause容器作为Pod中其他容器的父容器,负责协调和管理它们的生命周期。当pause容器启动时,它会成为Pod中其他容器的根容器。当pause容器终止时,所有其他容器也会被自动终止,确保了整个Pod的生命周期的一致性。
保持Pod状态:pause容器保持运行状态,即使Pod中的其他容器暂时停止或崩溃,也可以确保
Pod保持活跃。这有助于Kubernetes更准确地监视和管理Pod的状态。
2.pod生命周期
Pod生命周期包括以下几个阶段:
-
Pending:在此阶段,Pod已被创建,但尚未调度到运行节点上。此时,Pod可能还在等待被调度,或者因为某些限制(如资源不足)而无法立即调度。
-
Running:在此阶段,Pod已被调度到一个节点,并创建了所有的容器。至少有一个容器正在运行,或者正在启动或重启。
-
Succeeded:在此阶段,Pod中的所有容器都已成功终止,并且不会再次重启。
-
Failed:在此阶段,Pod中的至少一个容器已经失败(退出码非零)。这意味着容器已经崩溃或以其他方式出错。
-
Unknown:在此阶段,Pod的状态无法由Kubernetes确定。这通常是因为与Pod所在节点的通信出现问题。
除了这些基本的生命周期阶段之外,还有一些更详细的容器状态,用于描述容器在Pod生命周期中的不同阶段:
- ContainerCreating:容器正在创建,但尚未启动。
- Terminating:容器正在终止,但尚未完成。
- Terminated:容器已终止。
- Waiting:容器处于等待状态,可能是因为它正在等待其他容器启动,或者因为它正在等待资源可用。
- Completed:有一种Pod是一次性的,不需要一直运行,只要执行完就会是此状态。
Pod创建
Pod删除
pod资源限制
01、Resource Quota
资源配额Resource Quotas(简称quato)是对namespace进行资源配额,限制资源使用的一种策略。
k8s是一个多用户架构,当多用户或者团队共享一个k8s系统时,SA使用quota防止用户(基于namespace的)的资源抢占,定义好资源分配策略。
Quota应用在namespace上,默认情况下,没有resource quota 的,需要另外创建quota,并且每个namespace最多只能有一个quota对象。
resource quota可限定资源类型,主要有三大类:计算资源、存储资源以及资源个数。
计算资源:
主要针对CPU和内存的限制
limit.cpu | requests.cpu | limits.memory | requests.memory
存储资源:
包括存储资源的总量以及指定storage class的总量
request.storage:存储资源总量,如500Gi
persistentvolumeclaims:pvc的个数
对象数:
即可创建的对象个数
pods,replicationcontrollers,configmaps,secrets,
persistentvolueclaims,services,
services.loadbalancers,service.nodeports
resource quota 依赖于资源管理器,可以使用资源对象limits或者在创建资源对象时为pod设置资源限制(resources),如果不设置,资源对象无法创建。
当该namespace中的任意个额度达到预设Quota时,将无法创建资源对象。
resource quota示例
cat > quota.yaml <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:
namespace: aming
name: aming-quota
spec:
hard:
pods: 50 ## 该命名空间里最多支持启动50个Pods
requests.cpu: 0.5 ##最低保证0.5个CPU资源
requests.memory: 512Mi ##最低保证512M内存
limits.cpu: 5 ##最多使用5核CPU
limits.memory: 16Gi ##最多使用16G内存
configmaps: 20 ##最多支持20个configMaps
persistentvolumeclaims: 20 ##最多支持20个pvc
replicationcontrollers: 20 ##最多支持20个replicationControllers
secrets: 20 ##最多支持20个secrets
services: 50 ##最多支持50个services
EOF
##############################
## 生效
kubectl apply -f quota.yaml
## 查看
kubectl get quota -n aming
测试
为了显示限额效果,修改quota.yaml,将pod限制数改为5,其它先删除掉
命令行创建deployment,指定Pod副本为7
kubectl create deployment testdp --image=nginx:1.23.2 -n aming --replicas=7
查看deployment和pod
kubectl get deploy,po -n aming
02、pod 的 limits 和 requests
resources quota 是针对namespace下面所有的pod的限制,而pod本身也有限制。
eg:
cat > quota-pod.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: quota-pod
namespace: aming
spec:
containers:
- image: nginx:1.23.2
name: ngx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources:
limits:
cpu: 0.5 ##限制Pod CPU资源最多使用500m,这里的0.5=500m,1=1000m
memory: 2Gi ##限制内存资源最多使用2G
requests:
cpu: 200m ##K8s要保证Pod使用的最小cpu资源为200m,如果node上资源满足不了,则不会调度到该node上
memory: 512Mi ##K8s要保证Pod使用最小内存为512M,如果node上资源满足不了,则不会调度到该node上
EOF
limits重在限制,意思为不允许超过这么多
requests重在保障,意思是至少要给到这么多
二、Deployment
deployment YAML示例
vim ng-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ng-deploy
labels:
app: myng
spec:
replicas: 2 # 副本数
selector:
matchLabels:
app: myng
template:
metadata:
labels:
app: myng
spec:
containers:
- name: myng
image: nginx:1.23.2
ports:
- name: myng-port
containerPort: 80
## 使用YAML創建deploy
kubectl apply -f ng-deploy.yaml
## 查看
kubectl get deploy
kubectl get po
## 查看pod分配到哪个节点上
kubectl get po -o wide
三、Service
Service(简称:svc)YAML示例
vim ng-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: ngx-svc
spec:
selector:
app: myng
ports:
- protocol: TCP
port: 8080 # Service 的端口号,服务访问的端口
targetPort: 80 # Pod 的端口号,实际容器监听的端口
## 使用yaml創建service
kubectl apply -f ng-svc.yaml
## 查看
kubectl get svc
SVC三种类型
1.ClusterIP
该方式为默认类型,即不定义type字段时,(如上面展示的service的示例),就是该类型
spec:
selector:
app: myng
type: ClusterIP
ports:
- protocol: TCP
port: 8080 ## service的port
targetPort: 80 ##pod的port
2.NodePort
如果想通过k8s节点的IP直接访问到service对应的资源,可以使用nodeport,NodePort对应的端口范围为:30000-32767
spec:
selector:
app: myng
type: NodePort
ports:
- protocol: TCP
port: 8080 # Service 的端口,外部访问的端口
targetPort: 80 # Pod 的端口,容器内部监听的端口
nodePort: 30009 # NodePort 服务的节点端口,可以自定义或自动获取
3.LoadBlancer
这种方式需要配合公有云资源(阿里云、亚马逊云等)来实现,这里需要一个公网IP作为入口,然后负载均衡所有pod
spec:
selector:
app: myng
type: LoadBalancer # 确保类型拼写正确
ports:
- protocol: TCP
port: 8080 # Service 的端口,即服务暴露的端口
targetPort: 80 # Pod 的端口,即后端 Pod 监听的端口
四、DaemonSet
有些场景西药在每一个node上运行pod,(比如,网络插件calico、监控、日志收集),Deploment无法做到,而Daemonset(简称ds)可以。
Deamonset的目标是在集群的每一个节点上运行且只允许一个pod。
Daemonset不支持使用 kubectl create 获取 YAML 模板,所以只能参考Delopment的YAML编写,
其实Daemonset 和 Delopment 的差异很小,除了Kind不一样,还需要去掉replica配置。
Daemonset(简称ds)YAML示例
vim ds-demo.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-demo
labels:
app: ds-demo
spec:
selector:
matchLabels:
app: ds-demo
template:
metadata:
labels:
app: ds-demo
spec:
containers:
- name: ds-demo
image: nginx:1.23.2
ports:
- name: mysql-port # 注意:这里端口的名称是 mysql-port,但实际容器使用的是 nginx镜像
containerPort: 80
## 使用yaml创建ds
kubectl apply -f ds-demo.yaml
## 查看
kubectl get ds
kubectl get po
## 默认master上有限制,只在两个node节点上启动pod,master上没有启动
kubectl describe node k8s01 |grep -i 'taint'
Taints: node-role.kubernetes.io/control-plane:NoSchedule
说明:Taint叫做污点,如果某一个节点上有污点,则不会被调度运行pod
但是这个还得取决于pod自己的一个属性:toleration(容忍),即这个Pod是否能够容忍目标节点是否有污点。
为了解决此问题,我们可以在Pod上增加toleration属性。
增加toleration属性的ds.YAML示例
修改后的YAML配置:
vim ds-demo.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-demo
labels:
app: ds-demo
spec:
selector:
matchLabels:
app: ds-demo
template:
metadata:
labels:
app: ds-demo
spec:
tolerations:
- key: "node-role.kubernetes.io/control-plane"
effect: "NoSchedule"
containers:
- name: ds-demo
image: nginx:1.23.2
ports:
- name: mysql-port # 注意端口名称与服务的实际用途应保持一致
containerPort: 80
## 再次使用此YAML
kubectl apply -f ds-demo.yaml
五、StatefulSet
Pod根据是否有数据存储分为有状态和无状态:
- 无状态:指的Pod运行期间不会产生重要数据,即使有数据产生,这些数据丢失了也不影响整个应用。比如nginx、Tomcat等应用适合无状态。
- 有状态:指的是Pod运行期间会产生重要的数据,这些数据必须要做持久化,比如MySQL、Redis、RabbitMQ等。
Deploment 和 Daemonset 适合做无状态,而有状态也有一个对应的资源,那就是 Statefulset(简称sts)。
说明:由于StatefulSet涉及到数据持久化,用到了StorageClass,需要先创建一个基于NFS 的StorageClass
额外建立一台虚拟机,搭建NFS服务(待完善)
假设NFS服务器IP地址为192.168.31.30,共享目录为 /data/nfs
另外,想要使用NFS的sc,还需要装一个NFS provisioner,它的作用是自动创建NFS的pv
GitHub地址:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
源码下载:
git clone https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
cd nfs-subdir-external-provisioner/deploy
## 修改命名空间为 kube-system
sed -i 's/namespace:default/namespace:kube-system/' rbac.yaml
## 创建rbac授权
kubectl apply -f rbac.yaml
修改deploment.yaml
sed -i 's/namespace: default/namespace: kube-system/' deployment.yaml ##修改命
名空间为kube-system
##你需要修改标红的部分
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: chronolaw/nfs-subdir-external-provisioner:v4.0.2 ##改为
dockerhub地址
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 192.168.222.128 ##nfs服务器地址
- name: NFS_PATH
value: /data/nfs ##nfs共享目录
volumes:
- name: nfs-client-root
nfs:
server: 192.168.222.128 ##nfs服务器地址
path: /data/nfs ##nfs共享目录
标签:容器,04,kubectl,##,介绍,yaml,组件,Pod,pod
From: https://www.cnblogs.com/wangand/p/18302441