1. Namespace的使用
Namespace
(命名空间)用来隔离集群内不同环境下的资源。仅同一 namespace 下的资源命名需要唯一,它的作用域仅针对带有名字空间的对象,例如Deployment
、Service
等。
前面的教程中,默认使用的 namespace
是 default
。以下是创建多个 namespace
:
# namespaces.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Namespace
metadata:
name: test
使用:
$ kk apply -f namespaces.yaml
# namespace/dev created
# namespace/test created
$ kk get namespaces
# NAME STATUS AGE
# default Active 215d
# dev Active 2m44s
# ingress-nginx Active 110d
# kube-node-lease Active 215d
# kube-public Active 215d
# kube-system Active 215d
# test Active 2m44s
# 获取指定namespace下的资源
$ kk get pods -n dev
需要注意的是,删除 namespace 时,会默认删除该空间下的所有资源,需要谨慎操作。
2. 使用 ConfigMap 和 Secret
ConfigMap
和 Secret
都是用来保存配置数据的,在模板定义和使用上没有大太差别。唯一的区别就是 Secret
是用来保存敏感型的配置数据,比如证书密钥
、token
之类的。
2.1 ConfigMap
K8s
使用 ConfigMap
来将你的配置数据和应用程序代码分开,它推荐我们将一般性的配置数据保存到 ConfigMap 资源清单中。
![NOTE]
在 ConfigMap 中保存的数据不可超过 1 MiB,所以不要在 ConfigMap
中存储大量配置数据,对于占用空间较大的配置建议使用 [存储卷][存储卷] 或专门的配置服务。
如果配置数据不常修改,可以随应用程序直接打包到镜像。
部署 ConfigMap 资源后,我们可以用四种方式使用它:
- 在容器命令和参数内
- 容器的环境变量(常见)
- 在只读卷里面添加一个文件,让应用来读取(常见)
- 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap(不常见)
下面使用 ConfigMap
来保存应用Podhellok8s
的配置信息:
# configmap-hellok8s.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: hellok8s-configmap
data: # 用来保存UTF8字符串
DB_URL: "http://mydb.example123.com"
binaryData: # 用来保存二进制数据作为 base64 编码的字串。
app-config.json: eyJkYl91cmwiOiJteXNxbC5leGFtcGxlLmNvbSJ9Cg== # echo '{"db_url":"mysql.example.com"}' |base64
# 对于一个大量使用 configmap 的集群,禁用 configmap 修改会带来以下好处
# 1. 保护应用,使之免受意外(不想要的)更新所带来的负面影响。
# 2. 通过大幅降低对 kube-apiserver 的压力提升集群性能, 这是因为系统会关闭对已标记为不可变更的 configmap 的监视操作。
# 一旦标记为不可更改,这个操作就不可逆,再想要修改就只能删除并重建 configmap
immutable: true
然后修改 deployment
以读取 configmap,具体看 [deployment-use-configmap.yaml
]:
# 此模板演示了两种使用configmap的方式
# - 1. 环境变量方式
# - 2. 挂载volume方式
apiVersion: apps/v1
kind: Deployment
metadata:
name: hellok8s-go-http
spec:
replicas: 1 # 当使用 hostPort 时,每个节点只能运行一个 pod
strategy:
type: Recreate # 因为下面使用hostPort进行测试,所以更新时只能先销毁再创建
selector:
matchLabels:
app: hellok8s
template:
metadata:
labels:
app: hellok8s
spec:
containers:
- image: leigg/hellok8s:v4_configmap
name: hellok8s
ports:
- containerPort: 3000
hostPort: 3000
env: # 以环境变量的方式读取data
- name: DB_URL
valueFrom:
configMapKeyRef:
name: hellok8s-configmap
key: DB_URL
volumeMounts: # 以挂载卷的方式读取二进制数据
- name: configmap-volume
mountPath: "/etc/configmap_vol"
volumes:
- name: configmap-volume
configMap:
name: hellok8s-configmap
然后再修改 main.go 为 [main_read_configmap.go
],接着重新构建并推送镜像:
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
readFile := func(f string) string {
nbytes, err := os.ReadFile("/etc/configmap_vol/" + f)
if err != nil {
panic(err)
}
return string(nbytes)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
host, _ := os.Hostname()
dbURL := os.Getenv("DB_URL")
io.WriteString(w, fmt.Sprintf("[v4] Hello, Kubernetes! From host: %s\n"+
"Get Database Connect URL: %s\n"+
"app-config.json:%s", host, dbURL, readFile("app-config.json")))
})
http.ListenAndServe(":3000", nil)
}
重新构建并推送镜像:
# 先删除所有资源
$ kk delete pod,deployment,service,ingress --all
docker build . -t leigg/hellok8s:v4_configmap
docker push leigg/hellok8s:v4_configmap
kk apply -f deployment-use-configmap.yaml
$ kk get pod
NAME READY STATUS RESTARTS AGE
hellok8s-go-http-684ff55564-qf2x9 1/1 Running 0 3m47s
hellok8s-go-http-684ff55564-s5bfl 1/1 Running 0 3m47s
# pod直接映射到节点端口
$ curl 10.0.2.3:3000/hello
[v4] Hello, Kubernetes! From host: hellok8s-go-http-c548c88b5-25sl9
Get Database Connect URL: http://mydb.example123.com
app-config.json:{"db_url":"mysql.example.com"}
可以看到 app 已经拿到了 configmap 中定义的配置信息。若要更新,直接更改 configmap 的 yaml 文件然后应用,然后重启业务 pod
即可(使用kk rollout restart deployment <deployment-name>
)。
若 configmap 配置了immutable: true
,则无法再进行修改:
$ kk apply -f configmap-hellok8s.yaml
The ConfigMap "hellok8s-configmap" is invalid: data: Forbidden: field is immutable when `immutable` is set
最后需要注意的是,在上面提到的四种使用 configmap 的方式中,只有挂载 volume 和调用 k8s API 的方式会接收到 configmap 的更新(具有一定延迟),其余两种则需要重启 Pod 才能看到更新。
2.1 Secret
Secret
用于存储敏感信息,例如密码、Token
、(证书)密钥等,在使用上与 ConfigMap 不会有太大差别,但需要注意下面两点。
data
的 value 部分必须是 base64 编码后的字符串(创建时会执行 base64 解码检查),但 Pod 中获取到的仍然是明文;- 模板语法上稍有不同
- Secret 支持的是
stringData
而不是binaryData
,它的 value 可以是任何 UTF8 字符 - 额外支持
type
字段,用来在创建时检查资源合法性
- Secret 支持的是
2.1.1 Secret 的类型
创建 Secret 时,还可以使用 Secret 资源的 type 字段(可选),它用来告诉 k8s 我要创建何种类型的 secret,并根据类型对其进行基础的合法性检查。
当前支持的类型如下:
类型 | 描述 |
---|---|
Opaque | 用户定义的任意数据(默认) |
kubernetes.io/service-account-token | 服务账号令牌 |
kubernetes.io/dockercfg | ~/.dockercfg 文件的序列化形式 |
kubernetes.io/dockerconfigjson | ~/.docker/config.json 文件的序列化形式 |
kubernetes.io/basic-auth | 用于基本身份认证的凭据 |
kubernetes.io/ssh-auth | 用于 SSH 身份认证的凭据 |
kubernetes.io/tls | 用于 TLS 客户端或者服务器端的数据 |
bootstrap.kubernetes.io/token | 启动引导令牌数据 |
比如 type 为kubernetes.io/tls
时,k8s 要求 secret 中必须包含tls.crt
和tls.key
两个字段(data 或 stringData 都可),
但这里不会对值进行任何检查,并且这个类型也限制了创建后再修改,只能删除重建。[secret-hellok8s-cert.yaml
]是一个合法的kubernetes.io/tls
类型的Secret。其他类型的要求查看官方文档。
apiVersion: v1
kind: Secret
metadata:
name: hellok8s-tls
namespace: default
type: kubernetes.io/tls
# data 只接收base64编码
data:
# 这里的示例数据是随意填写的,在新版本中会警告:Warning: tls: private key does not match public key
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNVakNDQWJ1Z0F3SUJBZ0lKQUs5RU9hb1BQcFdkTUEwR0NTcUdTSWIzRFFFQkN3VUFNRUl4Q3pBSkJnTlYKQkFZVEFsaFlNUlV3RXdZRFZRUUhEQXhFWldaaGRXeDBJRU5wZEhreEhEQWFCZ05WQkFvTUUwUmxabUYxYkhRZwpRMjl0Y0dGdWVTQk1kR1F3SGhjTk1qTXhNRE14TWpFd016QTJXaGNOTWpNeE1UTXdNakV3TXpBMldqQkNNUXN3CkNRWURWUVFHRXdKWVdERVZNQk1HQTFVRUJ3d01SR1ZtWVhWc2RDQkRhWFI1TVJ3d0dnWURWUVFLREJORVpXWmgKZFd4MElFTnZiWEJoYm5rZ1RIUmtNSUdmTUEwR0NTcUdTSWIzRFFFQkFRVUFBNEdOQURDQmlRS0JnUUROclRnZwp6a2JHUTVTQVV5T3BCVVFtYktnMHI1bEhpNG1QeTBtQWM5bnlIbTUvaXUwKzFpaEFNYlUybGtSUFM1Q3U0eWIyCldUZ1lHR3NvOXo4VGJOU0JFZXBTWHoxZFpVTllxVTNnSEpHOHh4RW05UW9oZlFKcERZZVJ5dm1Od2xhdzVseksKcDN0bjVuV3c5cEhxSEwySXZ6eEJ3QnVDbzVyUEZQbC9kTnFuSVFJREFRQUJvMUF3VGpBZEJnTlZIUTRFRmdRVQorYzhGRE5jOTJsNFdQTzBKZG5NWldVdUhtTXd3SHdZRFZSMGpCQmd3Rm9BVStjOEZETmM5Mmw0V1BPMEpkbk1aCldVdUhtTXd3REFZRFZSMFRCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQmdRQVpCWmlSdzQ5SGFJUG0KcW5RWm0zc1RNVFh1MEZCOENlVFFGU0s3L21MQi9sbXlxVk1DMnVScmhwSFdrMk43SlRyb1VkZzU2UFZhcUM4eQp5R2UvSkcvdG5aZXRtRkFvTG5KaVlzaHYvWm5wblJSZ0t2UFhkaEtyelVKa2NqSGYrYmdxOU1aYW1pQkFQY2lKCi9qdUx0MnRQblFvajlIMWxaaWhqRno3WUxiZ0JQUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUNkUUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQWw4d2dnSmJBZ0VBQW9HQkFMSng2NWlCTjdoMGZLRHcKalFTWFRKeUIyYnZ1b2t4cUdrckRMc01nWEdIdUlUakNBNWt3TDNqZHkvbUQ0RVZjZ1Y4a1BJK2tjTnJJd0pWbQp3NmF4TzFseExqaVpYRjdGWUZrZGdzcEZVRjNQQW50SVhMeDl6bndtek5jeWxhV0RyaEdJVGVTT0JGNi9qTklDClpJcHFaN1dSSGIzS0w3SE41eFp3VWw0UlNOTWhBZ01CQUFFQ2dZQUY2MTJEVzVYN21uR2Y3UnJnY2h4cWZLdzYKWGJvb2lzU0FnbVVFdUFnWWY0dStsRUVHVGVEbFE0WkdxcWMvNWNlczNramNBdnB6WjRGcjgxSytMdGJuSEcrbQpNRXBVcWQyUTNmV0s3WFByUkZjbjZlUEx2YUZKWlhJSGVKZnAxRUltbXdKNmdRR1FJalBBRC92YTl5WVNBUmhqCmZqR0NNZFdxN2NwS1VXSXlnUUpCQU9acjNsdkJBMVBSeW5qZHB1RXIxZm9ybG55bzRFOTh2NlFSNnVXWWtnQjAKeUJQQzJlczhEZ2RoVDlNY0xsVGdHb281SGJrWE5vS1B3cExoSUp5S0RSa0NRUURHUVB2TzJ4RjRYQkpaZUEwaQp6bndHZTN4WFpRSHVJN0RpYWtWQUc2U1JId3NrMEJwNXk3YTVJQ3hCTU82d1g2c2owSW1mN3NBa0J1MjNuZmx1Cmo2OUpBa0JiNURqUkxyQTlCVFZSN2xOWENUeFVnSDJMU1czclJUeklHYjByd3lTMnVkdnd4WXhTbTZpY21OcFUKdnJCYmVPUWNxNXFHN2hMM0RvM3lOWVhqNThwQkFrQllwTCt5YXdNeHRNRkRuY2tKMGhka2NweFRHMGUwcWVLeQpLZUFTM1FsRkZnTk9qM24zRVYzL0FtS25OM0RTRGNTZ3UrSjlUeXc4TDVqa3E4N1dYNHA1QWtCR2VEK0E2YmFECnNzaXRtWmRydEo2ekxHYkZHRmtXazM0bVJxOGNzSWN4bndoelZnSXBKRjZvUG5yZUU2RmdUaDNHd0J6Z3VOc3kKVm5yOTZyd2tmMzQ1Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
# 也可以换成 stringData 存明文证书,在kk get secret hellok8s-tls -o json 时看到的都一样
#stringData:
# tls.crt: |-
# -----BEGIN CERTIFICATE-----
# ...
# qnQZm3sTMTXu0FB8CeTQFSK7/mLB/lmyqVMC2uRrhpHWk2N7JTroUdg56PVaqC8y
# yGe/JG/tnZetmFAoLnJiYshv/ZnpnRRgKvPXdhKrzUJkcjHf+bgq9MZamiBAPciJ
# /juLt2tPnQoj9H1lZihjFz7YLbgBPQ==
# -----END CERTIFICATE-----
# tls.key: |-
# -----BEGIN PRIVATE KEY-----
# ...
# vrBbeOQcq5qG7hL3Do3yNYXj58pBAkBYpL+yawMxtMFDnckJ0hdkcpxTG0e0qeKy
# KeAS3QlFFgNOj3n3EV3/AmKnN3DSDcSgu+J9Tyw8L5jkq87WX4p5AkBGeD+A6baD
# ssitmZdrtJ6zLGbFGFkWk34mRq8csIcxnwhzVgIpJF6oPnreE6FgTh3GwBzguNsy
# Vnr96rwkf345
# -----END PRIVATE KEY-----
2.1.2 引用时设置可选 key
正常情况下,如果引用 Secret 的某个字段不存在,则启动 Pod 时会报错,比如:
# 在env处引用
...
- name: LOG_LEVEL
valueFrom:
secretKeyRef:
name: hellok8s-secret # name必须是有效且存在的
key: not_found_key
# optional: true
k8s 允许在引用 Secret 时添加optional: true
属性,以确保 Secret 中的字段不存在时不会影响 Pod 启动(但 Secret 对象本身必须存在)。
2.1.3 拉取私有镜像使用 Secret
如果你尝试从私有仓库拉取容器镜像,你需要一种方式让每个节点上的 kubelet 能够完成与镜像库的身份认证。
你可以配置 imagePullSecrets
字段来实现这点。 Secret 是在 Pod 层面来配置的。
有两种方式来配置 imagePullSecrets
:
第一种方式需要对使用私有仓库的每个 Pod 执行以上操作,如果 App 较多,可能比较麻烦。
第二种方式是推荐的方式,因为 ServiceAccount 是一个集群范围内的概念,所以只需要在 ServiceAccount 上添加 Secret,
所有引用该 ServiceAccount 的 Pod 都会自动使用该 Secret。
完整演示这一步需要私有镜像仓库,此节测试略过。
2.1.4 在 Pod 内测试
这里提供测试通过的模板和代码供读者自行测试:
- [
secret-hellok8s-misc.yaml
]
apiVersion: v1
kind: Secret
metadata:
name: hellok8s-secret
data:
DB_PASSWD: cGFzczEyMwo= # echo pass123 |base64
stringData:
some.txt: "hello world"
cert.key: |-
-----BEGIN OPENSSH PRIVATE KEY-----
J1a9V50zOAl0k2Fpmy+RDvCy/2LeCZHyWY9MR248Ah2Ko3VywDrevdPIz8bxg9zxqy0+xy
jbu09sNix9b0IZuZQbbGkw4C4RcAN5HZ4UnWWRfzv2KgtXSdJCPp38hsWH2j9hmlNXLZz0
EqqtXGJpxjV67NAAAACkxlaWdnQEx1eWk=
-----END OPENSSH PRIVATE KEY-----
config.yaml: |-
username: hellok8s
password: pass123
# 对于一个大量使用 secret 的集群,禁用修改会带来以下好处
# 1. 保护应用,使之免受意外(不想要的)更新所带来的负面影响。
# 2. 通过大幅降低对 kube-apiserver 的压力提升集群性能, 这是因为系统会关闭对已标记为不可变更的 secret 的监视操作。
# 一旦标记为不可更改,这个操作就不可逆,再想要修改就只能删除并重建 secret
immutable: true
- [
deployment-use-secret.yaml
]
apiVersion: apps/v1
kind: Deployment
metadata:
name: hellok8s-go-http
spec:
strategy:
type: Recreate # 因为下面使用hostPort进行测试,所以更新时只能先销毁再创建
replicas: 1
selector:
matchLabels:
app: hellok8s
template:
metadata:
labels:
app: hellok8s
spec:
containers:
- image: leigg/hellok8s:v4_secret
name: hellok8s
ports:
- containerPort: 3000
hostPort: 3000
env:
- name: DB_PASSWD
valueFrom:
secretKeyRef:
name: hellok8s-secret
key: DB_PASSWD
- name: LOG_LEVEL
valueFrom:
secretKeyRef:
name: hellok8s-secret # name必须是有效且存在的
key: not_found_key
optional: true # 允许key不存在,这样在key找不到时不会影响Pod启动
volumeMounts:
- name: secret-volume
mountPath: "/etc/secret_vol"
volumes:
- name: secret-volume
secret:
secretName: hellok8s-secret
- [
main_read_secret.go
]
package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
readFile := func(f string) string {
nbytes, err := os.ReadFile("/etc/secret_vol/" + f)
if err != nil {
panic(err)
}
return string(nbytes)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
host, _ := os.Hostname()
io.WriteString(w, fmt.Sprintf("[v4] Hello, Kubernetes! From host: %s, Get Database Passwd: %s\n"+
"some.txt:%s\ncert.key:%s\nconfig.yaml:%s",
host, os.Getenv("DB_PASSWD"), readFile("some.txt"), readFile("cert.key"), readFile("config.yaml")))
})
http.ListenAndServe(":3000", nil)
}
测试结果:
$ curl 10.0.2.3:3000/hello
[v4] Hello, Kubernetes! From host: hellok8s-go-http-869d4548dc-vtmcr, Get Database Passwd: pass123
some.txt:hello world
cert.key:-----BEGIN OPENSSH PRIVATE KEY-----
J1a9V50zOAl0k2Fpmy+RDvCy/2LeCZHyWY9MR248Ah2Ko3VywDrevdPIz8bxg9zxqy0+xy
jbu09sNix9b0IZuZQbbGkw4C4RcAN5HZ4UnWWRfzv2KgtXSdJCPp38hsWH2j9hmlNXLZz0
EqqtXGJpxjV67NAAAACkxlaWdnQEx1eWk=
-----END OPENSSH PRIVATE KEY-----
config.yaml:username: hellok8s
password: pass123
2.1.5 使用命令创建 secret
除了通过模板方式创建 Secret,我们还可以通过 kubectl 命令直接创建 Secret:
# generic表示常规类型,通过 kubectl create secret -h 查看参数说明
$ kubectl create secret generic db-user-pass \
--from-literal=username=admin \
--from-literal=password='S!B\*d$zDsb='
secret/db-user-pass created
# 或者通过文件创建
$ kubectl create secret generic db-user-pass \
--from-file=./username.txt \
--from-file=./password.txt
创建后直接查看 Secret 明文:
$ kk describe secret db-user-pass
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 12 bytes
username: 5 bytes
$ kk get secret db-user-pass -o jsonpath='{.data}'
{"password":"UyFCXCpkJHpEc2I9","username":"YWRtaW4="} # value是base64编码
$ echo UyFCXCpkJHpEc2I9 |base64 --decode
S!B\*d$zDsb=
$ kk get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode
S!B\*d$zDsb=#
$ kk get secret db-user-pass -o jsonpath='{.data.username}' | base64 --decode
admin
删除 Secret:
$ kk delete secret db-user-pass
secret "db-user-pass" deleted
3. Downward API
有时候,容器需要获得关于自身的信息,但不能与 k8s 过于耦合,Downward API 就是用来解决这个问题的。 Downward API 允许容器在不使用
Kubernetes 客户端或 API 服务器的情况下获得自己或集群的信息,具体通过下面两种方式实现:
- 作为环境变量
- 作为
downwardAPI
卷中的文件
这两种暴露 Pod 和容器字段的方式统称为 Downward API。
可用字段
只有部分 Kubernetes API 字段可以通过 Downward API 使用。本节列出了你可以使用的字段。
你可以使用 fieldRef
传递来自可用的 Pod 级字段的信息。
- metadata.name:Pod 名称
- metadata.namespace:Pod 的命名空间
- metadata.uid:Pod 的唯一 ID
- metadata.annotations[‘’]:Pod 的注解 的值
- metadata.labels[‘’]:Pod 的标签 的值
以下信息可以通过环境变量获得,但不能作为 downwardAPI
卷fieldRef
获得:
- spec.serviceAccountName:Pod 的服务账号名称
- spec.nodeName:Pod 运行时所处的节点名称
- status.hostIP:Pod 所在节点的主 IP 地址
- status.hostIPs:这组 IP 地址是 status.hostIP 的双协议栈版本,第一个 IP 始终与 status.hostIP 相同。 该字段在启用了
PodHostIPs 特性门控后可用。 - status.podIP:Pod 的主 IP 地址(通常是其 IPv4 地址)
以下信息可以通过 downwardAPI 卷fieldRef
获得,但不能作为环境变量获得:
- metadata.labels:Pod 的所有标签,格式为 标签键名=“转义后的标签值”,每行一个标签
- metadata.annotations:Pod 的全部注解,格式为 注解键名=“转义后的注解值”,每行一个注解
可通过 resourceFieldRef 获得的信息:
- limits.cpu:容器的 CPU 限制值
- requests.cpu:容器的 CPU 请求值
- limits.memory:容器的内存限制值
- requests.memory:容器的内存请求值
- limits.hugepages-*:容器的巨页限制值
- requests.hugepages-*:容器的巨页请求值
- limits.ephemeral-storage:容器的临时存储的限制值
- requests.ephemeral-storage:容器的临时存储的请求值
如果没有为容器指定 CPU
和内存限制时尝试使用 Downward API
暴露该信息,那么 kubelet默认会根据 节点可分配资源 计算并暴露 CPU 和内存的最大可分配值。
下面使用 [pod_use_downwardAPI.yaml
] 进行测试:
# 此模板演示了如何使用 环境变量和存储卷 方式注入Pod信息到Pod内部
apiVersion: v1
kind: Pod
metadata:
name: busybox-use-downwardapi
labels:
app: busybox
label_test: some_value
spec:
containers:
- name: write
image: busybox
command: [ "sh", "-c" ]
# 通过命令行可以读取环境变量
args: [ 'echo "hellok8s, downwardAPI! PodName=${POD_NAME} LIMITS_CPU=${LIMITS_CPU} POD_IP=${POD_IP}"; sleep infinity' ]
resources:
limits:
cpu: "0.1"
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: LIMITS_CPU
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
volumeMounts:
- mountPath: /config/downward_api_info
name: volume-downward
volumes:
- name: volume-downward
downwardAPI:
items:
- path: "POD_NAME"
fieldRef:
fieldPath: metadata.name
- path: "LABELS"
fieldRef:
fieldPath: metadata.labels
$ kk apply -f pod_use_downwardAPI.yaml
pod/busybox-use-downwardapi created
$ kk get pod
NAME READY STATUS RESTARTS AGE
busybox-use-downwardapi 1/1 Running 0 59s
$ kk logs busybox-use-downwardapi
hellok8s, downwardAPI! PodName=busybox-use-downwardapi LIMITS_CPU=1 POD_IP=20.2.36.86
$ kk exec -it busybox-use-downwardapi -- sh
/ # ls /config/downward_api_info/
LABELS POD_NAME
/ # cat /config/downward_api_info/LABELS
app="busybox"
label_test="some_value"
/ # cat /config/downward_api_info/POD_NAME
busybox-use-downwardapi
4. 结语
恭喜🎉🎉🎉!!!到这里,你已经看完了本篇 K8s 基础教程学习。如果你完成了教程中的大部分练习,那你已经能够使用 Kubernetes 进行日常开发工作了。
如果你的工作需要深度使用 K8s(比如运维人员)亦或你想要深度掌握 K8s的使用,那请允许我向你推荐[Kubernetes 进阶教程][Kubernetes 进阶教程],预祝下一旅途愉快!