kubernetes官网https://kubernetes.io/
存储卷相关的资源有StorageClass、pv、pvc、configMap、secret等(configMap和secret也是存储卷的一种)。
PV的创建方式分为静态供给(Static Provisioning)和动态供给(Dynamic Provisioning)两种。静态创建时,PV是运维人员来创建的,需要规划挂载的路径、存储块的大小等,但是大规模集群中可能会有很多PV,如果这些PV都需要运维手动来处理这也是一件很繁琐的事情,所以就有了动态供给概念,也就是Dynamic Provisioning。动态创建时只需要创建pvc就可以自动创建pv。kubernetes支持部分存储的动态PV创建,但不包括nfs,所以需要使用额外插件实现。nfs动态供给插件参考external-storage/nfs-client at master · kubernetes-retired/external-storage · GitHub
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs
spec:
storageClassName: my-storage-class
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
server: 10.244.1.4
path: "/"
accessModes:读写有三种类型,nfs、glusterfs等存储方式三种都支持,hostpath只支持ReadWriteOnce
ReadWriteMany 多路读写,存储卷能被集群多个节点挂载并读写
ReadWriteOnce 单路读写,存储卷只能被单一集群节点挂载读写
ReadOnlyMany 多路只读,存储卷能被多个集群节点挂载且只能读
persistentVolumeReclaimPolicy:存储卷的回收策略,即对应的PVC被删除后,PV的回收策略
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: hello-test
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: my-storage-class
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
readme.txt: "this is a text."
server.xml:
zhangsan
18
使用kubectl create configmap --help命令查看更多快捷的创建configmap的方式,可以直接读取配置文件的内容来创建configmap
apiVersion: v1
kind: Secret
metadata:
name: my-secret
type: Opaque
data:
passwd: cm9vdA=
username: cm9vdA=
Secret类似configmap,不过Secret的key是经过了base64加密的。但是该加密方式轻松就能解密了,使用以下命令即可将上面编排文件中的cm9vdA=解密出来:
[root@k8s-master1 lck]# echo cm9vdA= | base64 -d
root
[root@k8s-master1 lck]# echo root | base64
cm9vdA=
apiVersion: apps/v1
kind: Deployment
metadata:
name: sftp
spec:
replicas: 1
selector:
matchLabels:
app: my-deployment
template:
metadata:
labels:
app: sftp
spec:
terminationGracePeriodSeconds: 60 # pod停止时的优雅退出时间
initContainers:
- image: harbor.k8s/test/initHello:alpine
name: initHello
command: ["cp", "-r", "/workspace", "/workdir"]
volumeMounts:
- name: workspace
mountPath: /workdir
containers:
- image: harbor.k8s/test/hello:alpine
command: ["/entrypoint", "$(user):$(passwd):::$(path)"] #command中引用环境变量
name: hello
env:
- name: TZ
value: "CST-8"
- name: user
valueFrom: # 用于引用secret、configMap、metadata等的key
secretKeyRef:
name: my-secret
key: user
- name: passwd
valueFrom:
secretKeyRef:
name: my-secret
key: passwd
- name: path
value: "file"
readinessProbe: # 就绪探针
exec:
command: ["sh", "/root/webapp/bin/readiness.sh"]
initialDelaySeconds: 20
livenessProbe: # 存活探针
tcpSocket:
port: 8081
httpGet:
port: 8080
path: /heath
initialDelaySeconds: 20
lifecycle: # 生命周期
preStop:
exec:
command: ["sh", "/root/webapp/bin/shutdown.sh"]
resources:
limits:
cpu: "1"
memory: 200Mi
requests:
cpu: "0.5"
memory: 100Mi
volumeMounts:
- name: workspace
mountPath: /root/webapp/workspace
- name: data
mountPath: /home/data
- name: server
mountPath: /home/readme.md #挂载在容器中的路径
subPath: readme.txt #存储卷中的路径,此处是configMap中的readme.txt
- name: server
mountPath: /home/server.xml
subPath: server.xml #存储卷中的路径,此处是configMap中的server.xml
volumes:
- name: workspace
emptyDir: {} # pod生命周期中的临时目录
- name: data
persistentVolumeClaim:
claimName: my-pvc
- name: server
configMap:
name: my-configmap
readinessProbe: 就绪探针,用于检测container是否已就绪,默认连续检测3次失败则重启container。支持exec、http、tcp等
livenessProbe: 存活探针,用于检测container是否存活,默认连续检测失败则重启container。支持exec、http、tcp等
mountPath: 挂载在容器中的路径(Path within the container at which the volume should be mounted.)
subPath: 存储卷中的路径(Path within the volume from which the container's volume should be mounted.)
emptyDir: pod生命周期中的临时目录(EmptyDir represents a temporary directory that shares a pod's lifetime.)
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 10
containers:
- name: nginx
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: my-storage-class
resources:
requests:
storage: 1Gi
PodPreSet不是控制器的一种,在 pod 创建时,用户可以使用 podpreset 对象将特定信息注入 pod 中,这些信息可以包括 secret、 卷、 卷挂载和环境变量。
kind: PodPreset
apiVersion: settings.k8s.io/v1alpha1
metadata:
name: allow-database
namespace: myns
spec:
selector:
matchLabels:
role: frontend
env:
- name: DB_PORT
value: "6379"
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
为了在集群中使用 Pod Preset,必须确保以下内容
另外,Pod Preset 与原 Pod 存在冲突时,Pod spec 不会被修改。
每个命名空间下都有一个名称是default的serviceaccount
待续......
apiVersion: v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000 # 值越大,优先级越高。可以是小于或者等于10亿的32位任意整数值
globalDefault: false # 整个系统只能存在一个globalDefault设置为 true的PriorityClass
description: "This priority class should be used for XYZ service pods only."
为了启用该功能,需要在 API server 和 scheduler 的启动参数中设置:
--feature-gates=PodPriority=true
在 API server 中还需要设置如下启动参数:
--runtime-config=scheduling.k8s.io/v1alpha1=true
创建PriorityClass后,在pod里配置spec.priorityClassName字段即可。
设置了优先级的pod,在Pod 生成后,会进入一个队列等待调度。scheduler 从队列中选择一个 Pod,然后尝试将其调度到某个节点上。如果没有任何节点能够满足 Pod 指定的所有要求,对于这个挂起的 Pod,抢占逻辑就会被触发。当前假设我们把挂起的 Pod 称之为 P。抢占逻辑会尝试查找一个节点,在该节点上移除一个或多个比 P 优先级低的 Pod 后, P 能够调度到这个节点上。如果节点找到了,部分优先级低的 Pod 就会从该节点删除。Pod 消失后,P 就能被调度到这个节点上了。