Kubernetes资源对象:pod
pod是一组紧密关联的容器集合,它们共享 IPC、Network 和 UTS namespace,是 Kubernetes 调度的基本单位。Pod 的设计理念是支持多个容器在一个 Pod *享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。
以下就是pod yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
根据yaml结构,pod对象的结构主要核心是pod.spec.containers, 每一个container 主要是由image(镜像),name(容器名),ports(端口组)组成,
根据yaml 的特殊符合 - ,代表着这个是数组中的一个,可以明确 pod 可以有多个容器,每个容器能开放多个端口;
pod.metadata.labels 对应结构类型为map,也就是说pod可以有多个label ,提供给其他资源筛选。
pod的资源使用限制
应用调度到哪些节点,节点资源是否占满,资源使用率是否低,这些都是需要考虑的东西,故需要添加对pod的资源使用限制,保证pod以合理的资源配额运行在节点上。
pod.spec.containers[].resources
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
spec.containers[].resources.limits.cpu:CPU 上限,可以短暂超过,容器也不会被停止
spec.containers[].resources.limits.memory:内存上限,不可以超过;如果超过,容器可能会被终止或调度到其他资源充足的机器上
spec.containers[].resources.requests.cpu:CPU 请求,也是调度 CPU 资源的依据,可以超过
spec.containers[].resources.requests.memory:内存请求,也是调度内存资源的依据,可以超过;但如果超过,容器可能会在 Node 内存不足时清理
关于pod的亲和性调度
服务往往因自身特性,可能会分为计算密集型(cpu),io密集型,网络密集型等,故可能需要划分节点,明确节点是否网络性能优先或io性能优先,故在服务调度的时候,需要考虑节点亲和;
若多个计算密集型资源服务调度到同一个节点,就可能会出现cpu紧缺,memory空余,导致资源浪费,故服务与服务之间的不亲和调度是在生产环境上必不可少的;
往往一个应用会有多个服务组成,某些服务之间调用十分频繁,那么这两个服务部署在同一个节点,性能提升将会十分明显。
pod.spec.affinity 下有着三种亲和性类型: nodeAffinity(节点亲和),podAffinity(pod亲和),podAntiAffinity(pod反亲和)
nodeAffinity demo
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: another-node-label-key
operator: In
values:
- another-node-label-value
requiredDuringSchedulingIgnoredDuringExecution :代表必须要满足条件
preferredDuringSchedulingIgnoredDuringExecution :代表优先条件,若条件不满足,在调度的时候也可以不考虑
preferredDuringSchedulingIgnoredDuringExecution.[].weight : 代表优先条件的权重,在条件冲突的时候,权重越高,优先支持
matchExpressions[].key : 代表node label 对应 key
matchExpressions[].operator : 代表 筛选label value 值的方式,有In, NotIn, Exists, DoesNotExist等方式
matchExpressions[].value : 代表 node label 对应 value
podAffinity / podAntiAffinity demo
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: failure-domain.beta.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: kubernetes.io/hostname
topologyKey: 代表筛选出node labels 的key中 有topologyKey value 的node
容器健康检查
容器运行起来,并不代表其能够提供正常服务,比如tomcat容器,往往需要一定时候启动,才能提供服务,故需要一种方式判定服务到底能否提供正常;
在容器一直运行,但处于无法提供服务的状态下,虽然健康检查可以使pod not ready,并使其不提供给其他服务调用,但其他实例负载就会变大,如何打破这种僵局,需要一种健康检查,判断无法提供服务,则重启容器的策略。
livenessProbe: 是根据规则检查pod状态,若检测结果为异常,则重启pod
readinessProbe: 是根据规则来不停止检测pod状态,若检测结果为异常,则将pod状态置为not rady,直到检测结果正常,将pod状态置为 ready
pod.spec.containers[].livenessProbe ,
pod.spec.containers[].readinessProbe
livenessProbe:
httpGet:
path: /
port: 80
httpHeaders:
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 15
timeoutSeconds: 1
readinessProbe:
exec:
command:
- cat
- /usr/share/nginx/html/index.html
initialDelaySeconds: 5
timeoutSeconds: 1
pod.spec.containers[].livenessProbe.httpGet: 代表使用http get 请求进行验证
pod.spec.containers[].livenessProbe.initialDelaySeconds: 代表容器正式启动后,多久后开始验证
pod.spec.containers[].livenessProbe.timeoutSeconds: 代表通过验证方式超时时间,超时代表着失败
pod.spec.containers[].readinessProbe.exec: 进入到容器内使用命令进行验证
- 在容器刚运行阶段,readiness 判定健康状态的初始值为 false,当readinessprobe 验证通过,才变为 true ,也就是pod 进入ready 状态 ;
- liveness 判定健康状态的初始值为 true ,当 livenessprobe验证失败,才变为fasle,则容器进行重启。
容器存储挂载
PV 与 PVC
PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 提供了方便的持久化卷:PV 提供网络存储资源,而 PVC 请求存储资源。
设置pv(持久化存储)包括置底层文件系统或者云数据卷、创建持久性数据卷,最后创建 PVC 来将 Pod 跟数据卷关联起来。
PV 和 PVC 可以将 pod 和数据卷解耦,pod 不需要知道确切的文件系统或者支持它的持久化引擎。
PersistentVolume(PV)是集群之中的一块网络存储。跟 Node 一样,也是集群的资源。PV 跟 Volume (卷) 类似,不过会有独立于 Pod 的生命周期。比如一个 NFS 的 PV 可以定义为
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
nfs:
path: /da/project/pvname
server: 172.17.0.2
PV 的访问模式(accessModes)有三种:
- ReadWriteOnce(RWO):是最基本的方式,可读可写,但只支持被单个 Pod 挂载。
- ReadOnlyMany(ROX):可以以只读的方式被多个 Pod 挂载。
- ReadWriteMany(RWX):这种存储可以以读写的方式被多个 Pod 共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是 NFS。在 PVC 绑定 PV 时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。
PV 的状态变化
- Available: 可用状态
- Bound: 已经分配给pvc
- Released: pvc解绑但未执行回收策略
- Failed: 发生错误
PV 的回收策略(persistentVolumeReclaimPolicy,即 PVC 释放卷的时候 PV 该如何操作)也有三种
- Retain,不清理, 保留 Volume(需要手动清理)
- Recycle,删除数据,即 rm -rf /thevolume/*(只有 NFS 和 HostPath 支持)
- Delete,删除存储资源,比如删除 AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)
PVC是存储资源的请求,而 PersistentVolumeClaim (PVC) 是对 PV 的请求。
PVC 跟 Pod 类似:Pod 消费 Node 资源,而 PVC 消费 PV 资源;Pod 能够请求 CPU 和内存资源,而 PVC 请求特定大小和访问模式的数据卷。
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
PVC 如何去寻找匹配pv,这通常通过pvc.spec.selector 查询到pv 列表,然后通过pvc.spec.accessModes 与 pvc.spec.resources 来判定pv.spec.accessModes 与 pv.spec.capaticy 是否满足条件,若满足则进行绑定操作,pv的状态变为bound
PVC 应用于pod 存储
kind: Pod
apiVersion: v1
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: dockerfile/nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
Configmap
在执行应用程式或是生产环境等等, 会有许多的情况需要做变更, 而我们不希望因应每一种需求就要准备一个镜像档, 这时就可以透过 ConfigMap 来帮我们做一个配置档或是命令参数的映射, 更加弹性化使用我们的服务或是应用程式。
ConfigMap 用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件
创建configmap
使用命令:kubectl create configmap special-config --from-file=config/
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
special.type: charm
configmap应用于pod 存储
apiVersion: v1
kind: Pod
metadata:
name: vol-test-pod
spec:
containers:
- name: test-container
image: gcr.io/google_containers/busybox
command: ["/bin/sh", "-c", "cat /etc/config/special.how"]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config
restartPolicy: Never
将config内的文件挂载到/etc/config目录下,
secret
Secret 解决了密码、token、**等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用。
Secret 有三种类型:
- Opaque:base64 编码格式的 Secret,用来存储密码、**等;但数据也通过 base64 --decode 解码得到原始数据,所以加密性很弱。
- kubernetes.io/dockerconfigjson:用来存储私有 docker registry 的认证信息。
- kubernetes.io/service-account-token: 用于被 serviceaccount 引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /var /run/secrets/kubernetes.io/serviceaccount目录中。
secret yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
secret应用pod存储
apiVersion: v1
kind: Pod
metadata:
labels:
name: db
name: db
spec:
volumes:
- name: secrets
secret:
secretName: mysecret
containers:
- image: gcr.io/my_project_id/pg:v1
name: db
volumeMounts:
- name: secrets
mountPath: "/etc/secrets"
readOnly: true
ports:
- name: cp
containerPort: 5432
hostPort: 5432
推荐阅读
-
[kubernetes]pod的存活探针
-
Kubernetes (一)Pod
-
Kubernetes 配置Pod和容器(十二)configmap的使用
-
Kubernetes强制删除一直处于Terminating状态的pod,namespace
-
Kubernetes Pod详解
-
Kubernetes:强制删除一直处于Terminating状态的pod,deployment,namespace,server
-
Kubernetes资源对象:pod
-
Kubernetes pod的yaml详解
-
kubernetes替换pod文件
-
Kubernetes如何使用ReplicationController、Replica Set、Deployment管理Pod