15 | 深入解析Pod对象(二):使用进阶 笔记
15 | 深入解析Pod对象(二):使用进阶 笔记
- 1.Kubernetes 支持的 Projected Volume(Kubernetes v1.11 之后)
- 2.容器健康检查和恢复机制
1.Kubernetes 支持的 Projected Volume(Kubernetes v1.11 之后)
- Secret;
它的作用,是帮你把 Pod 想要访问的加密数据,存放到 Etcd 中。然后,你就可以通过在 Pod 的容器里挂载 Volume 的方式,访问到这些 Secret 里保存的信息了。
apiVersion: v1
kind: Pod
metadata:name: test-projected-volume
spec:containers:- name: test-secret-volumeimage: busyboxargs:- sleep- "86400"volumeMounts:- name: mysql-credmountPath: "/projected-volume"readOnly: truevolumes:- name: mysql-credprojected:sources:- secret:name: user- secret:name: pass
在这个 Pod 中,我定义了一个简单的容器。它声明挂载的 Volume,并不是常见的 emptyDir 或者 hostPath 类型,而是 projected 类型。而这个 Volume 的数据来源(sources),则是名为 user 和 pass 的 Secret 对象,分别对应的是数据库的用户名和密码。
这里用到的数据库的用户名、密码,正是以 Secret 对象的方式交给 Kubernetes 保存的。完成这个操作的指令,如下所示:
$ cat ./username.txt
admin
$ cat ./password.txt
c1oudc0w!$ kubectl create secret generic user --from-file=./username.txt
$ kubectl create secret generic pass --from-file=./password.txt
其中,username.txt 和 password.txt 文件里,存放的就是用户名和密码;而 user 和 pass,则是我为 Secret 对象指定的名字。而我想要查看这些 Secret 对象的话,只要执行一条 kubectl get 命令就可以了:
$ kubectl get secrets
NAME TYPE DATA AGE
user Opaque 1 51s
pass Opaque 1 51s
yaml文件创建Secret
apiVersion: v1
kind: Secret
metadata:name: mysecret
type: Opaque
data:user: YWRtaW4=pass: MWYyZDFlMmU2N2Rm
注:数据必须是经过 Base64 转码
$ echo -n 'admin' | base64
YWRtaW4=
$ echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
注:通过挂载方式进入到容器里的 Secret,一旦其对应的 Etcd 里的数据被更新,需要注意的是,这个更新可能会有一定的延时。所以在编写应用程序时,在发起数据库连接的代码处写好重试和超时的逻辑,绝对是个好习惯。
- ConfigMap
与Secret类似,只是一个加密,一个不加密
# .properties文件的内容
$ cat example/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice# 从.properties文件创建ConfigMap
$ kubectl create configmap ui-config --from-file=example/ui.properties# 查看这个ConfigMap里保存的信息(data)
# .properties文件的内容
$ cat example/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice# 从.properties文件创建ConfigMap
$ kubectl create configmap ui-config --from-file=example/ui.properties# 查看这个ConfigMap里保存的信息(data)
$ kubectl get configmaps ui-config -o yaml
apiVersion: v1
data:ui.properties: |color.good=purplecolor.bad=yellowallow.textmode=truehow.nice.to.look=fairlyNice
kind: ConfigMap
metadata:name: ui-config...
- Downward API
让 Pod 里的容器能够直接获取到这个 Pod API 对象本身的信息。
例子:
apiVersion: v1
kind: Pod
metadata:name: test-downwardapi-volumelabels:zone: us-est-coastcluster: test-cluster1rack: rack-22
spec:containers:- name: client-containerimage: k8s.gcr.io/busyboxcommand: ["sh", "-c"]args:- while true; doif [[ -e /etc/podinfo/labels ]]; thenecho -en '\n\n'; cat /etc/podinfo/labels; fi;sleep 5;done;volumeMounts:- name: podinfomountPath: /etc/podinforeadOnly: falsevolumes:- name: podinfoprojected:sources:- downwardAPI:items:- path: "labels"fieldRef:fieldPath: metadata.labels
目前,Downward API 支持的字段已经非常丰富了,比如:
1. 使用fieldRef可以声明使用:
spec.nodeName - 宿主机名字
status.hostIP - 宿主机IP
metadata.name - Pod的名字
metadata.namespace - Pod的Namespace
status.podIP - Pod的IP
spec.serviceAccountName - Pod的Service Account的名字
metadata.uid - Pod的UID
metadata.labels['<KEY>'] - 指定<KEY>的Label值
metadata.annotations['<KEY>'] - 指定<KEY>的Annotation值
metadata.labels - Pod的所有Label
metadata.annotations - Pod的所有Annotation2. 使用resourceFieldRef可以声明使用:
容器的CPU limit
容器的CPU request
容器的memory limit
容器的memory request
注:Downward API 能够获取到的信息,一定是 Pod 里的容器进程启动之前就能够确定下来的信息。而如果你想要获取 Pod 容器运行后才会出现的信息,比如,容器进程的 PID,那就肯定不能使用 Downward API 了,而应该考虑在 Pod 里定义一个 sidecar 容器。
其实,Secret、ConfigMap,以及 Downward API 这三种 Projected Volume 定义的信息,大多还可以通过环境变量的方式出现在容器里。但是,通过环境变量获取这些信息的方式,不具备自动更新的能力。所以,一般情况下,我都建议你使用 Volume 文件的方式获取这些信息。
- ServiceAccountToken
Service Account 对象的作用,就是 Kubernetes 系统内置的一种“服务账户”,它是 Kubernetes 进行权限分配的对象。比如,Service Account A,可以只被允许对 Kubernetes API 进行 GET 操作,而 Service Account B,则可以有 Kubernetes API 的所有操作权限。
如下面这个例子:
[root@k8smaster ~]# kubectl describe pod nacos-0
Name: nacos-0
Namespace: default
Priority: 0
Node: k8snode1/10.10.220.102
Start Time: Tue, 15 Feb 2022 09:17:00 +0800
Labels: app=nacoscontroller-revision-hash=nacos-56d49bb69fstatefulset.kubernetes.io/pod-name=nacos-0
Annotations: pod.alpha.kubernetes.io/initialized: true
Status: Running
IP: 10.244.1.214
IPs:IP: 10.244.1.214
Controlled By: StatefulSet/nacos
Init Containers:peer-finder-plugin-install:Container ID: docker://2fa1c7b1777d85e6ff4cc869fd2d1081151ed409c72fe206cd0db4c652129fb0Image: nacos/nacos-peer-finder-plugin:1.0Image ID: docker-pullable://nacos/nacos-peer-finder-plugin@sha256:61f2a8911a999b60fb1382a14429bf884fee782c23d4c3c3cdcfae1bf41e9ac0Port: <none>Host Port: <none>State: TerminatedReason: CompletedExit Code: 0Started: Mon, 28 Mar 2022 14:45:21 +0800Finished: Mon, 28 Mar 2022 14:45:21 +0800Ready: TrueRestart Count: 1Environment: <none>Mounts:/home/nacos/plugins/peer-finder from plguindir (rw)/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-k6h5v (ro)
Containers:nacos:Container ID: docker://10c90e52b23d6823c9a3ed1c84a10c1087131a22d383d67d1bda3f61277a713bImage: nacos/nacos-server:1.4.1Image ID: docker-pullable://nacos/nacos-server@sha256:fe6e5688cdf324c8043f2b77046411c983020161d1bd4c2fa8e3e25f60a62bc0Port: 8848/TCPHost Port: 0/TCPState: RunningStarted: Mon, 28 Mar 2022 14:46:17 +0800Last State: TerminatedReason: ErrorExit Code: 137Started: Sun, 27 Feb 2022 09:21:17 +0800Finished: Mon, 28 Mar 2022 14:43:56 +0800Ready: TrueRestart Count: 2Requests:cpu: 500mmemory: 2GiEnvironment:NACOS_REPLICAS: 2SERVICE_NAME: nacos-headlessDOMAIN_NAME: cluster.localPOD_NAMESPACE: default (v1:metadata.namespace)MYSQL_SERVICE_HOST: <set to the key 'mysql.db.host' of config map 'nacos-cm'> Optional: falseMYSQL_SERVICE_DB_NAME: <set to the key 'mysql.db.name' of config map 'nacos-cm'> Optional: falseMYSQL_SERVICE_PORT: <set to the key 'mysql.port' of config map 'nacos-cm'> Optional: falseMYSQL_SERVICE_USER: <set to the key 'mysql.user' of config map 'nacos-cm'> Optional: falseMYSQL_SERVICE_PASSWORD: <set to the key 'mysql.password' of config map 'nacos-cm'> Optional: falseNACOS_SERVER_PORT: 8848PREFER_HOST_MODE: hostnameMounts:/home/nacos/data from datadir (rw)/home/nacos/logs from logdir (rw)/home/nacos/plugins/peer-finder from plguindir (rw)/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-k6h5v (ro)
Conditions:Type StatusInitialized True Ready True ContainersReady True PodScheduled True
Volumes:plguindir:Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)ClaimName: plguindir-nacos-0ReadOnly: falsedatadir:Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)ClaimName: datadir-nacos-0ReadOnly: falselogdir:Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)ClaimName: logdir-nacos-0ReadOnly: falsekube-api-access-k6h5v:Type: Projected (a volume that contains injected data from multiple sources)TokenExpirationSeconds: 3607ConfigMapName: kube-root-ca.crtConfigMapOptional: <nil>DownwardAPI: true
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300snode.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
/run/secrets/kubernetes.io/serviceaccount # ls
ca.crt namespace token
应用程序只要直接加载这些授权文件,就可以访问并操作 Kubernetes API 了
这种把 Kubernetes 客户端以容器的方式运行在集群里,然后使用 default Service Account 自动授权的方式,被称作“InClusterConfig”,也是我最推荐的进行 Kubernetes API 编程的授权方式。
2.容器健康检查和恢复机制
apiVersion: v1
kind: Pod
metadata:labels:test: livenessname: test-liveness-exec
spec:containers:- name: livenessimage: busyboxargs:- /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600livenessProbe:exec:command:- cat- /tmp/healthyinitialDelaySeconds: 5periodSeconds: 5
在这个 Pod 中,它在启动之后做的第一件事,就是在 /tmp 目录下创建了一个 healthy 文件,以此作为自己已经正常运行的标志。而 30 s 过后,它会把这个文件删除掉。与此同时,我们定义了一个这样的 livenessProbe(健康检查)。它的类型是 exec,这意味着,它会在容器启动后,在容器里面执行一条我们指定的命令,比如:“cat /tmp/healthy”。这时,如果这个文件存在,这条命令的返回值就是 0,Pod 就会认为这个容器不仅已经启动,而且是健康的。这个健康检查,在容器启动 5 s 后开始执行(initialDelaySeconds: 5),每 5 s 执行一次(periodSeconds: 5)。
需要注意的是:Kubernetes 中并没有 Docker 的 Stop 语义。所以虽然是 Restart(重启),但实际却是重新创建了容器。这个功能就是 Kubernetes 里的 Pod 恢复机制,也叫 restartPolicy。它是 Pod 的 Spec 部分的一个标准字段(pod.spec.restartPolicy),默认值是 Always,即:任何时候这个容器发生了异常,它一定会被重新创建。
但一定要强调的是,Pod 的恢复过程,永远都是发生在当前节点上,而不会跑到别的节点上去。事实上,一旦一个 Pod 与一个节点(Node)绑定,除非这个绑定发生了变化(pod.spec.node 字段被修改),否则它永远都不会离开这个节点。这也就意味着,如果这个宿主机宕机了,这个 Pod 也不会主动迁移到其他节点上去。
而如果你想让 Pod 出现在其他的可用节点上,就必须使用 Deployment 这样的“控制器”来管理 Pod,哪怕你只需要一个 Pod 副本。这就是我在第 12 篇文章《牛刀小试:我的第一个容器化应用》最后给你留的思考题的答案,即一个单 Pod 的 Deployment 与一个 Pod 最主要的区别。
1.只要 Pod 的 restartPolicy 指定的策略允许重启异常的容器(比如:Always),那么这个 Pod 就会保持 Running 状态,并进行容器重启。否则,Pod 就会进入 Failed 状态 。
2.对于包含多个容器的 Pod,只有它里面所有的容器都进入异常状态后,Pod 才会进入 Failed 状态。在此之前,Pod 都是 Running 状态。此时,Pod 的 READY 字段会显示正常容器的个数
livenessProbe 也可以定义为发起 HTTP 或者 TCP 请求的方式,定义格式如下:
livenessProbe:httpGet:path: /healthzport: 8080httpHeaders:- name: X-Custom-Headervalue: AwesomeinitialDelaySeconds: 3periodSeconds: 3livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 15periodSeconds: 20
参考:https://time.geekbang.org/column/article/40466?utm_source=related_read&utm_medium=article&utm_term=related_read
15 | 深入解析Pod对象(二):使用进阶 笔记相关推荐
- 15. 深入解析Pod对象(二):使用进阶
15. 深入解析Pod对象(二):使用进阶 15.1 Projected Volume,投射数据卷 备注:Projected Volume 是 Kubernetes v1.11 之后的新特性 在 Ku ...
- 14 | 深入解析Pod对象(一):基本概念
今天我和你分享的主题是:深入解析 Pod 对象之基本概念. 在上一篇文章中,我详细介绍了 Pod 这个 Kubernetes 项目中最重要的概念.而在今天这篇文章中,我会和你分享 Pod 对象的更多细 ...
- 14. 深入解析Pod对象(一)
14. 深入解析Pod对象(一) """ 通过前面的讲解,大家应该都知道: Pod,而不是容器,它是 Kubernetes 项目中的最小编排单位.将这个设计落实到 API ...
- Linux 进阶笔记(二)
这几篇博文主要记录博主的Linux 学习之路,用作以后回顾和参考.大家可以选择略过也可以作参考. (一)Linux 初步笔记 (二)Linux 进阶笔记(一) (三)Linux 进阶笔记(二) (四) ...
- Shell 编程进阶笔记
这几篇博文主要记录博主的Linux 学习之路,用作以后回顾和参考.大家可以选择略过也可以作参考. (一)Linux 初步笔记 (二)Linux 进阶笔记(一) (三)Linux 进阶笔记(二) (四) ...
- Linux 进阶笔记(一)
这几篇博文主要记录博主的Linux 学习之路,用作以后回顾和参考.大家可以选择略过也可以作参考. (一)Linux 初步笔记 (二)Linux 进阶笔记(一) (三)Linux 进阶笔记(二) (四) ...
- Pod资源管理进阶-Pod对象的生命周期
目录 Pod的生命周期 1.存活性探测行为属性 (Liveness probe) 2.Pod就绪性探测 3.Pod对象的相位 4.Pod的创建过程 5.Pod生命周期中的重要阶段 6.容器的重启策略 ...
- 第一百一十四节,JavaScript文档对象,DOM进阶
JavaScript文档对象,DOM进阶 学习要点: 1.DOM类型 2.DOM扩展 3.DOM操作内容 DOM自身存在很多类型,在DOM基础课程中大部分都有所接触,比如Element类型:表示的是元 ...
- amazeui学习笔记二(进阶开发4)--JavaScript规范Rules
amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...
最新文章
- idea中刷新项目快捷键_解决 IDEA 使用过程中让你觉得不爽的一些问题
- 神经网络波动方程∂f(x)/ ∂x=f(-x)f(x)的另一组玻色子解
- 安卓程序开发——创建安卓虚拟机
- 大厂架构师经验分享!成功跳槽字节跳动
- linux 权限测试,linux下检测root权限的shell脚本
- delphi listview1添加指定列_对表格的列进行批量处理的函数详解
- kafka内部消费偏移
- 【每日算法Day 93】不用额外空间,你会旋转一个矩阵吗?
- 如何在 iPhone、iPad 和 Mac 上更改日历颜色?
- 3D控件Aspose.3D 8月新版V17.8发布 | 支持6面多维地图
- Android源码下载编译(高通)
- 豪赌激光电视,海信算是赢了吗?
- 每周论文精读04——A Survey on 3D Hand Pose Estimation: Cameras, Methods, and Datasets
- 怎样利用计算机打出开方,在电脑上,平方与开方怎么打?
- 自下而上分析方法-算符优先,LR(0),SLR,LR(1),LALR大全
- Python爬虫——Scrapy 的基本使用
- 人生苦短,饕餮docker
- 马蜂窝陈罡:用户、内容、商业化3C矩阵,是新一代旅游市场密码
- 解决STC8G1K08程序不能运行的问题和端口配置
- 网上报名上传电子照片时,要求大于30K小于200K,该怎么修改?...
热门文章
- 斯蒂夫乔布斯传札记:第四波
- 不朽凡人 第五百二十九章 你的游戏别找我
- 计算机网络作业评价,计算机网络作业-20210412094502.docx-原创力文档
- quartus虚价破戒的一种解决办法
- 【RepVGG】《RepVGG:Making VGG-style ConvNets Great Again》
- python抽样不同花色纸牌_Python 十几行代码实现你对一副扑克牌的所有幻想
- 我所体验到的中国电信网上营业厅
- 打靶归来 - 详解upload-labs靶场(下)
- 企业云盘在企业数字存储巩助
- 在元宇宙里进行「全域营销」这还是第一次听说! #omgland