15 | 深入解析Pod对象(二):使用进阶 笔记

  • 1.Kubernetes 支持的 Projected Volume(Kubernetes v1.11 之后)
  • 2.容器健康检查和恢复机制

1.Kubernetes 支持的 Projected Volume(Kubernetes v1.11 之后)

  1. 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 里的数据被更新,需要注意的是,这个更新可能会有一定的延时。所以在编写应用程序时,在发起数据库连接的代码处写好重试和超时的逻辑,绝对是个好习惯。

  1. 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...
  1. 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 文件的方式获取这些信息。

  1. 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对象(二):使用进阶 笔记相关推荐

  1. 15. 深入解析Pod对象(二):使用进阶

    15. 深入解析Pod对象(二):使用进阶 15.1 Projected Volume,投射数据卷 备注:Projected Volume 是 Kubernetes v1.11 之后的新特性 在 Ku ...

  2. 14 | 深入解析Pod对象(一):基本概念

    今天我和你分享的主题是:深入解析 Pod 对象之基本概念. 在上一篇文章中,我详细介绍了 Pod 这个 Kubernetes 项目中最重要的概念.而在今天这篇文章中,我会和你分享 Pod 对象的更多细 ...

  3. 14. 深入解析Pod对象(一)

    14. 深入解析Pod对象(一) """ 通过前面的讲解,大家应该都知道: Pod,而不是容器,它是 Kubernetes 项目中的最小编排单位.将这个设计落实到 API ...

  4. Linux 进阶笔记(二)

    这几篇博文主要记录博主的Linux 学习之路,用作以后回顾和参考.大家可以选择略过也可以作参考. (一)Linux 初步笔记 (二)Linux 进阶笔记(一) (三)Linux 进阶笔记(二) (四) ...

  5. Shell 编程进阶笔记

    这几篇博文主要记录博主的Linux 学习之路,用作以后回顾和参考.大家可以选择略过也可以作参考. (一)Linux 初步笔记 (二)Linux 进阶笔记(一) (三)Linux 进阶笔记(二) (四) ...

  6. Linux 进阶笔记(一)

    这几篇博文主要记录博主的Linux 学习之路,用作以后回顾和参考.大家可以选择略过也可以作参考. (一)Linux 初步笔记 (二)Linux 进阶笔记(一) (三)Linux 进阶笔记(二) (四) ...

  7. Pod资源管理进阶-Pod对象的生命周期

    目录 Pod的生命周期 1.存活性探测行为属性 (Liveness probe) 2.Pod就绪性探测 3.Pod对象的相位 4.Pod的创建过程 5.Pod生命周期中的重要阶段 6.容器的重启策略 ...

  8. 第一百一十四节,JavaScript文档对象,DOM进阶

    JavaScript文档对象,DOM进阶 学习要点: 1.DOM类型 2.DOM扩展 3.DOM操作内容 DOM自身存在很多类型,在DOM基础课程中大部分都有所接触,比如Element类型:表示的是元 ...

  9. amazeui学习笔记二(进阶开发4)--JavaScript规范Rules

    amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...

最新文章

  1. idea中刷新项目快捷键_解决 IDEA 使用过程中让你觉得不爽的一些问题
  2. 神经网络波动方程∂f(x)/ ∂x=f(-x)f(x)的另一组玻色子解
  3. 安卓程序开发——创建安卓虚拟机
  4. 大厂架构师经验分享!成功跳槽字节跳动
  5. linux 权限测试,linux下检测root权限的shell脚本
  6. delphi listview1添加指定列_对表格的列进行批量处理的函数详解
  7. kafka内部消费偏移
  8. 【每日算法Day 93】不用额外空间,你会旋转一个矩阵吗?
  9. 如何在 iPhone、iPad 和 Mac 上更改日历颜色?
  10. 3D控件Aspose.3D 8月新版V17.8发布 | 支持6面多维地图
  11. Android源码下载编译(高通)
  12. 豪赌激光电视,海信算是赢了吗?
  13. 每周论文精读04——A Survey on 3D Hand Pose Estimation: Cameras, Methods, and Datasets
  14. 怎样利用计算机打出开方,在电脑上,平方与开方怎么打?
  15. 自下而上分析方法-算符优先,LR(0),SLR,LR(1),LALR大全
  16. Python爬虫——Scrapy 的基本使用
  17. 人生苦短,饕餮docker
  18. 马蜂窝陈罡:用户、内容、商业化3C矩阵,是新一代旅游市场密码
  19. 解决STC8G1K08程序不能运行的问题和端口配置
  20. 网上报名上传电子照片时,要求大于30K小于200K,该怎么修改?...

热门文章

  1. 斯蒂夫乔布斯传札记:第四波
  2. 不朽凡人 第五百二十九章 你的游戏别找我
  3. 计算机网络作业评价,计算机网络作业-20210412094502.docx-原创力文档
  4. quartus虚价破戒的一种解决办法
  5. 【RepVGG】《RepVGG:Making VGG-style ConvNets Great Again》
  6. python抽样不同花色纸牌_Python 十几行代码实现你对一副扑克牌的所有幻想
  7. 我所体验到的中国电信网上营业厅
  8. 打靶归来 - 详解upload-labs靶场(下)
  9. 企业云盘在企业数字存储巩助
  10. 在元宇宙里进行「全域营销」这还是第一次听说! #omgland