Kubernetes 基础:Namespace、ConfigMap和Secret的使用

在这里插入图片描述

1. Namespace的使用

Namespace(命名空间)用来隔离集群内不同环境下的资源。仅同一 namespace 下的资源命名需要唯一,它的作用域仅针对带有名字空间的对象,例如DeploymentService 等。

前面的教程中,默认使用的 namespacedefault。以下是创建多个 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

在这里插入图片描述

ConfigMapSecret 都是用来保存配置数据的,在模板定义和使用上没有大太差别。唯一的区别就是 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字段,用来在创建时检查资源合法性
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.crttls.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

  1. 直接在 Pod 上指定 ImagePullSecrets
  2. 向 ServiceAccount 添加 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 的标签 的值

以下信息可以通过环境变量获得,但不能作为 downwardAPIfieldRef 获得:

  • 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 进阶教程],预祝下一旅途愉快!

5. 本教程参考资料

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码踏云端

你的打赏是我精心创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值