引子
kubernetes的资源对象是kubernetes体系中的重要组成部分,简单理解就是生成的kubernetes的系统应用,用来调度、编排我们的业务应用。是我们的业务应用与kubernetes的kube-controller组件,如:apiserver、kube-controller、kube-scheduler等之间的中间层,起到承上启下的作用。
将kubernetes的资源对象简单的分类为以下几种资源对象:
类别 | 名称 |
---|---|
资源对象 | Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaling、Node、Namespace、Service、Ingress、Label、CustomResourceDefinition |
存储对象 | Volume、PersistentVolume、Secret、ConfigMap |
策略对象 | SecurityContext、ResourceQuota、LimitRange |
身份对象 | ServiceAccount、Role、ClusterRole |
学习kubernetes的资源对象对入门kubernetes是十分重要的,但kubernetes的资源对象比较多,概念繁杂,容易让人困惑。
单单从理论出发,也容易让人无法留下较深的印象,故本系列直接从各种小练习出发,以练促学,在实践中加深对kubernetes资源对象的理解。同时也在实践找那个插入响应的理论讲解,理论与实践相辅相成,相符促进。
关于kubernetes的简单入门,以及搭建一个简单的kubernetes集群,百度或者其他资讯平台都有很好的教程。关注作者,私信留言(kubernetes)直接赠送。
存储
存储
1. 创建含有初始化容器的pod,满足如下要求。
1) pod名为pod1,镜像为nginx。
2) 创建一个名字为v1的卷,这个卷的数据不能永久存储数据。
3) 初始化容器名字为initc1,镜像使用busybox,挂载此卷v1到目录/data。
4) 在初始化容器里,创建文件/data/aa.txt。
5) 普通容器名字为c1,镜像为nginx。
6) 把卷v1挂载到/data里。
7) 当次pod运行起来之后,在pod1的c1容器里,查看是不是存在/data/aa.txt。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
terminationGracePeriodSeconds: 0 #terminationGracePeriodSeconds 可以定义优雅关闭的宽限期,即在收到停止请求后,有多少时间来进行资源释放或者做其它操作,如果到了最大时间还没有停止,会被强制结束。默认值:30。
volumes:
- name: v1
emptyDir: {}#只写一个位置对应的容器的位置,物理机上随便找一个位置,删除后物理机上的数据也会消失
containers:
- name: initc1
image: busybox
imagePullPolicy: IfNotPresent
command: ["sh","-c","touch /data/aa.txt && sleep 1000"]
volumeMounts:
- name: v1
mountPath: /data
- name: c1
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: v1
mountPath: /data
#readOnly: false
resources: {}#resources可以用于限制容器对资源的使用,具体设置如下
dnsPolicy: ClusterFirst#dns策略,ClusterFirst 表示集群 DNS 优先
restartPolicy: Always
status: {}
###############################################################
测试在pod1的c1容器里,查看是不是存在/data/aa.txt
[root@vms31 10-test]# kubectl exec -it pod1 -c c1 -- ls /data
aa.txt
requests未设置时,默认与limits相同。
limits未设置时,默认值与集群配置相关。
可以使用requests来设置各容器需要的最小资源
limits用于限制运行时容器占用的资源,用来限制容器的最大CPU、内存的使用率。
当容器申请内存超过limits时会被终止,并根据重启策略进行重启。.
resources:
limits:
cpu: "1"
memory: 2048Mi
requests:
cpu: "0.6"
memory: 1024Mi
2. 创建一个持久性存储,满足如下要求。
1) 持久性存储的名字为pv10。
2) 容量大小设置为2G。
3) 访问模式为ReadWriteOnce。
4) 存储类型为hostPath,对应目录/pv10。
5) storageClassName设置为cka。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv10
spec:
capacity:
storage: 2Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain #持久卷回收策略,Retain就是保留,还有”Recycle” 和 “Delete”
storageClassName: cka #
hostPath: #hostPath存储删除容器,物理机上的文件还会保存,但不会同步到重建的pod上
path: /data
###############################################################################
PersistentVolumes 可以有多种回收策略,包括 “Retain”、”Recycle” 和 “Delete”。
对于动态配置的 PersistentVolumes 来说,默认回收策略为 “Delete”。这表示当用户删除对应的
PersistentVolumeClaim 时,动态配置的 volume 将被自动删除。如果 volume 包含重要数据时,
这种自动行为可能是不合适的。那种情况下,更适合使用 “Retain” 策略。使用 “Retain” 时,
如果用户删除 PersistentVolumeClaim,对应的 PersistentVolume 不会被删除。
相反,它将变为 Released 状态,表示所有的数据可以被手动恢复。
###############################################################################
PV是对底层网络共享存储的抽象,将共享存储定义为一种“资源”,比如Node也是容器应用可以消费的资源。
PV由管理员创建和配置,与共享存储的具体实现直接相关。
PVC则是用户对存储资源的一个“申请”,就像Pod消费Node资源一样,PVC能够消费PV资源。
PVC可以申请特定的存储空间和访问模式。
StorageClass,用于标记存储资源的特性和性能,管理员可以将存储资源定义为某种类别,
正如存储设备对于自身的配置描述(Profile)。根据StorageClass的描述可以直观的
得知各种存储资源的特性,就可以根据应用对存储资源的需求去申请存储资源了。存储卷可以按需创建。
3. 创建pvc,满足如下要求。
1) 名字为pvc10。
2) 让此pvc和pv10进行关联。
3) 所在命名空间为default。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc10
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi #pvc的容量和pv的大小是否要求一致,我觉得是不需要的
storageClassName: cka
4. 创建pod,满足如下要求。
1) 名字为pod-pvc。
2) 创建名字为v1的卷,让其使用pvc10作为后端存储。
3) 容器所使用的镜像为nginx。
4) 把卷v1挂载到/data目录。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod-pvc
name: pod-pvc
spec:
nodeName: vm3
terminationGracePeriodSeconds: 0
volumes:
- name: v1
persistentVolumeClaim:
claimName: pvc10
containers:
- image: nginx
name: pod-pvc
imagePullPolicy: IfNotPresent
volumeMounts:
- name: v1
mountPath: /data
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
Secret
创建含有初始化容器的pod,满足如下要求:
1.创建secret,名字为s1,键值对为name1/tom1
1)创建一个名字为nginx的pod,镜像为nginx。
2.)此pod里定义一个名字为MYENV的变量,此变量的值为s1里name1对应的值。
3)当pod运行起来之后,进入pod里查看变量MYENV的值。
[root@vms31 10-test]# kubectl create secret --help
Create a secret using specified subcommand.
Available Commands:
docker-registry 创建一个给 Docker registry 使用的 secret
generic 从本地 file, directory 或者 literal value 创建一个 secret
tls 创建一个 TLS secret
Usage:
kubectl create secret [flags] [options]
Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).
[root@vms31 10-test]# kubectl create secret generic s1 --from-literal=name1=tom1
#generic子命令可以通过本地文件、目录或者literal(键值对)
[root@vms31 10-test]# kubectl nginx --image=nginx --image-pull-policy=IfNotPresent --dry-run=client -o yaml > test.yaml
修改生成的yaml文件
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
terminationGracePeriodSeconds: 0
containers:
- env:
- name: MYENV
valueFrom:
secretKeyRef:
name: s1
key: name1
image: nginx
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
验证容器内的变量值
[root@vms31 10-test]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 2m49s
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl exec -it nginx -- bash
root@nginx:/# echo $MYENV
tom1
2.创建configmap,名字cm1,键值对为name2/tom2
1)创建一个名字为nginx2的pod,镜像为nginx。
2)此pod里把cm1挂载到/also/data目录里。
创建configmap并生成yaml文件
[root@vms31 10-test]# kubectl create cm cm1 --from-literal=name2=tom2
configmap/cm1 created
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl run nginx2 --image=nginx --image-pull-policy=IfNotPresent --dry-run=client -o yaml > test2.yaml
配置的yaml文件
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx2
name: nginx2
spec:
volumes:
- name: v1
configMap:
name: cm1
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: nginx2
resources: {}
volumeMounts:
- name: v1
mountPath: /also/data
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
验证pod的configmap
[root@vms31 10-test]# kubectl exec -it nginx2 -- cat /also/data/name2
tom2[root@vms31 10-test]#
deploy
1.创建一个deployment,满足如下要求:
1)名字为web1,镜像为nginx:1.9。
2)此web1要有2个副本。
3)pod的标签为app-name=web1。
deploy的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web1
name: web1
spec:
replicas: 2
selector:
matchLabels:
app: web1
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web1
spec:
containers:
- image: nginx:1.9
name: nginx
resources: {}
status: {}
可以看到通过deploy创建的pod是在deploy和pod上都能查找到的,但删除的时候是要删除deploy,删除pod会再次自动创建的
设置的标签可以看到deploy上有。pod上是没有的
2.更新此deployment,把maxSurge和maxUnavailable的值都设置为1。
服务在滚动更新时,deployment控制器的目的是:给旧版本(old_rs)副本数减少至0、给新版本(new_rs)副本数量增至期望值(replicas)。大家在使用时,通常容易忽视控制速率的特性,以下是kubernetes提供的两个参数:
- maxUnavailable:和期望ready的副本数比,不可用副本数最大比例(或最大值),这个值越小,越能保证服务稳定,更新越平滑;
- maxSurge:和期望ready的副本数比,超过期望副本数最大比例(或最大值),这个值调的越大,副本更新速度越快。
通过kubectl edit deployments.apps web1
来修改不太靠谱,修改原来的yaml文件再次生成,如果成功显示是deployment.apps/web1 configured
,标明是修改生成的
[root@vms31 10-test]# kubectl apply -f deploy.yaml
deployment.apps/web1 configured
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
web1 2/2 2 2 18h
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web1-6f8f6976b5-t4j7l 1/1 Running 1 18h
web1-6f8f6976b5-vc8pl 1/1 Running 1 17h
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# cat deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web1
name: web1
spec:
replicas: 2
selector:
matchLabels:
app: web1
strategy: #修改的是标红
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
creationTimestamp: null
labels:
app: web1
spec:
containers:
- image: nginx:1.9
name: nginx
resources: {}
status: {}
修改之后edit deploy发现更新策略写在下图位置
3.修改此deployment的副本数为6。
[root@vms31 10-test]# kubectl scale deployment web1 --replicas=6
deployment.apps/web1 scaled
[root@vms31 10-test]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
web1 5/6 6 5 18h
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web1-6f8f6976b5-2d8r4 0/1 ContainerCreating 0 29s
web1-6f8f6976b5-bxbkj 1/1 Running 0 29s
web1-6f8f6976b5-jprw9 1/1 Running 0 29s
web1-6f8f6976b5-t4j7l 1/1 Running 1 18h
web1-6f8f6976b5-t9drk 1/1 Running 0 29s
web1-6f8f6976b5-vc8pl 1/1 Running 1 17h
4.更新此deployment,让其使用镜像nginx,并记录此次更新。
[root@vms31 10-test]# kubectl get deployments.apps -o wide#可以看到此时nginx版本为1.9
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
web1 6/6 6 6 18h nginx nginx:1.9 app=web1
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl set image deploy web1 nginx=nginx --record#更新操作命令
deployment.apps/web1 image updated
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl get deployments.apps -o wide#此时nginx版本发生了变化
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
web1 6/6 6 6 18h nginx nginx app=web1
[root@vms31 10-test]# kubectl rollout history deployment web1#可以查询到更新的版本
deployment.apps/web1
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deploy web1 nginx=nginx --record=true
kubectl rollout
对资源进行管理
可用资源包括:
deployments
daemonsets
子命令
history(查看历史版本)
pause(暂停资源)
resume(恢复暂停资源)
status(查看资源状态)
undo(回滚版本)
5.回滚此次更新 至升级之前的镜像版本nginx:1.9。
[root@vms31 10-test]# kubectl get deployments.apps -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
web1 6/6 6 6 18h nginx nginx app=web1
[root@vms31 10-test]# kubectl rollout history deployment web1
deployment.apps/web1
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deploy web1 nginx=nginx --record=true
[root@vms31 10-test]# kubectl rollout undo deployment web1 --to-revision=1#把deploy回滚的命令,版本根据前面查到的
deployment.apps/web1 rolled back
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# #kubectl rollout undo deployment web1#这个命令是回滚到上一个版本
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
web1 6/6 6 6 18h
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl get deployments.apps -o wide#nginx版本又回到了1.9
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
web1 6/6 6 6 18h nginx nginx:1.9 app=web1
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl rollout history deployment web1
deployment.apps/web1
REVISION CHANGE-CAUSE
2 kubectl set image deploy web1 nginx=nginx --record=true
3 <none>
6.删除此deployment。
kubectl delete deployments.apps web1 --force
Daemon Set
1.创建一个daemonset,满足如下要求:
1)名字为ds-test1。
2)使用的镜像为nginx。
daemon set的yaml文件
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
labels:
app: ds-test1
name: ds-test1
spec:
selector:
matchLabels:
app: ds-test1
template:
metadata:
creationTimestamp: null
labels:
app: ds-test1
spec:
containers:
- image: nginx
name: nginx
resources: {}
daemonset创建成功后查询daemonset
[root@vms31 10-test]# kubectl get daemonsets.apps -o wide
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
ds-test1 2 2 2 2 2 <none> 2m45s nginx nginx app=ds-test1
[root@vms31 10-test]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ds-test1-bzhct 1/1 Running 0 2m46s 10.244.252.17 vms33 <none> <none>
ds-test1-zb9c8 1/1 Running 0 2m46s 10.244.29.99 vms32 <none> <none>
2.解释,此daemonset为什么没有在master创建pod。
因为master节点设置了误点(Taints)
查看所有节点是否设置了污点
kubectl describenodes |grep -E "Taints|Name"
[root@vms31 10-test]# kubectl describe nodes | grep -E "Taints|Name"#-E表示可以使用正则表达式,该表达式表示Taints或Name
Name: vms31
Taints: node-role.kubernetes.io/master:NoSchedule
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
Name: vms32
Taints: <none>
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
Name: vms33
Taints: <none>
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
设置和取消污点
kubectl taint node [node] key=value[effect]
其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]
NoSchedule: 一定不能被调度
PreferNoSchedule: 尽量不要调度
NoExecute: 不仅不会调度, 还会驱逐Node上已有的Pod
[root@vms31 10-test]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
vms31 Ready control-plane,master 97d v1.20.1
vms32 Ready node1 97d v1.20.1
vms33 Ready node2 97d v1.20.1
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl taint node vms32 node-role.kubernetes.io/worker1=:NoSchedule
node/vms32 tainted
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl describe nodes | grep -E "Taints|Name"
Name: vms31
Taints: node-role.kubernetes.io/master:NoSchedule
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
Name: vms32
Taints: node-role.kubernetes.io/worker1:NoSchedule
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
Name: vms33
Taints: <none>
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
删除污点
[root@vms31 10-test]# kubectl taint node vms32 node-role.kubernetes.io/worker1-
node/vms32 untainted
[root@vms31 10-test]# kubectl describe nodes | grep -E "Taints|Name"
Name: vms31
Taints: node-role.kubernetes.io/master:NoSchedule
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
Name: vms32
Taints: <none>
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
Name: vms33
Taints: <none>
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
3.创建一个daemonset,
满足如下要求:
1)名字为ds-test2。
2)使用的镜像为nginx。
3)此daemonset所创建的pod只在含有标签为disktype=ssd的worker上运行。
4.)删除这两个daemonset。
先给一个节点设置对应标签
[root@vms31 10-test]# kubectl get nodes --show-labels | grep vm32
[root@vms31 10-test]# kubectl get nodes --show-labels | grep vms32
vms32 Ready node1 97d v1.20.1 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=vms32,kubernetes.io/os=linux,node-role.kubernetes.io/node1=
daemonset的yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
labels:
app: ds-test2
name: ds-test2
spec:
selector:
matchLabels:
app: ds-test2
template:
metadata:
creationTimestamp: null
labels:
app: ds-test2
spec:
nodeSelector:
disktype: ssd
containers:
- image: nginx
name: nginx
resources: {}
运行后可以查到只在对应标签的node上运行
[root@vms31 10-test]# kubectl get daemonsets.apps
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
ds-test2 1 1 0 1 0 disktype=ssd 7s
[root@vms31 10-test]#
[root@vms31 10-test]#
[root@vms31 10-test]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ds-test2-4zjfc 0/1 ContainerCreating 0 23s <none> vms32 <none> <none>
后续继续更新有关云原生及kubernetes的干货文章,欢迎点赞关注,多多分享。
评论区