目录

ConfigMap

向容器传递命令行参数

在 Docker 中定义命令与参数

下面是 Dockerfile 中的指令 ENTRYPOINT 和 CMD。

指令 解释
ENTRYPOINT 容器启动时调用的命令
CMD 传递给 ENTRYPOINT 指定命令的参数

构建带参数的程序(date:args)

编写脚本 date.sh

#!/bin/sh
INTERVAL=$1
while :
do
  echo $(date)
  sleep $INTERVAL
done

编写 Dockerfile

FROM busybox
ADD date.sh /date.sh
RUN chmod +x /date.sh
ENTRYPOINT ["/date.sh"]
CMD ["1"]

参数默认值为 1,在运行容器可以设置参数覆盖默认值。

构建镜像

docker build -t wangjunjian/date:args .

在 Docker 中覆盖命令和参数

使用 Docker 运行镜像来设置命令和参数

docker run [--entrypoint=] <image> [arg1, arg2, arg3]

启动镜像

$ docker run wangjunjian/date:args
Tue Aug 3 13:08:04 UTC 2021
Tue Aug 3 13:08:05 UTC 2021

设置参数覆盖默认睡眠时间

$ docker run wangjunjian/date:args 3
Tue Aug 3 13:08:46 UTC 2021
Tue Aug 3 13:08:49 UTC 2021

覆盖默认的命令

$ docker run --entrypoint=/bin/sh wangjunjian/date:args
/ # 

在 Kubernetes 中覆盖命令和参数

在定义 Pod 时设置命令和参数

kind: Pod
spec:
  containers:
  - image: image
    command: ["/bin/command"]
    args: ["arg1", "arg2", "arg3"]

少量参数的设置可以使用上面的数组表示,当参数过多时可以使用下面的方式,如果参数是数值型需要使用引号。

    args:
    - str
    - "3"

在 Docker 和 Kubernetes 中指定命令和参数

Docker Kubernetes 描述
ENTRYPOINT command 容器中运行的命令
CMD args 传给命令的参数

使用自定义睡眠时间运行 date

编写 date.yaml

apiVersion: v1
kind: Pod
metadata:
  name: date
spec:
  containers:
  - image: wangjunjian/date:args
    name: date
    args: ["3"]

部署 Pod

kubectl apply -f date.yaml

查看运行日志

$ kubectl logs date
Tue Aug 3 13:51:22 UTC 2021
Tue Aug 3 13:51:25 UTC 2021

为容器设置环境变量

构建通过环境变量配置的程序(date:env)

编写脚本 date.sh

#!/bin/sh
while :
do
  echo $(date)
  sleep $INTERVAL
done
编程语言 访问环境变量
Shell $ENV_VAR
Python os.environ[“ENV_VAR”]
Go os.Getenv(“ENV_VAR”)
C/C++ getenv(“ENV_VAR”)
Java System.getenv(“ENV_VAR”)
Node.JS process.env.ENV_VAR

编写 Dockerfile

FROM busybox
ADD date.sh /date.sh
RUN chmod +x /date.sh
ENV INTERVAL=1
ENTRYPOINT ["/date.sh"]

参数默认值为 1,在运行容器可以设置参数覆盖默认值。

构建镜像

docker build -t wangjunjian/date:env .

在 Docker 中设置环境变量

运行 Docker 镜像时设置环境变量

docker run [--env var1=value] <image>

启动镜像

$ docker run wangjunjian/date:env
Tue Aug 3 14:24:33 UTC 2021
Tue Aug 3 14:24:34 UTC 2021

设置环境变量覆盖默认睡眠时间

$ docker run -e INTERVAL=3 wangjunjian/date:env
Tue Aug 3 14:25:50 UTC 2021
Tue Aug 3 14:25:53 UTC 2021

在 Kubernetes 中设置环境变量

在定义 Pod 时设置环境变量

kind: Pod
spec:
  containers:
  - image: image
    env:
    - name: var1
      value: "value"

使用环境变量设置睡眠时间运行 date

编写 date.yaml

apiVersion: v1
kind: Pod
metadata:
  name: date
spec:
  containers:
  - image: wangjunjian/date:env
    name: date
    env:
    - name: INTERVAL
      value: "3"

部署 Pod

kubectl apply -f date.yaml

查看运行日志

$ kubectl logs date
Tue Aug 3 14:44:32 UTC 2021
Tue Aug 3 14:44:35 UTC 2021

在环境变量中引用环境变量

env:
- name: VAR1
  value: "value1"
- name: VAR2
  value: "$(VAR1) value2"

commandargs 也可以这样用。

利用 ConfigMap 解耦配置

在 Pod 定义中进行硬编码,导致部署在不同环境(开发、测试、生产)需要分别定义不同的 Pod。

ConfigMap 本质就是键/值对。

ConfigMap 操作

创建

字面量

kubectl create configmap date-config --from-literal=sleep-interval=3
# 创建多项
kubectl create configmap date-config --from-literal=one=1 --from-literal=two=2

文件

# 默认文件名就是键名
kubectl create configmap date-config --from-file=requests-pod.yaml
# 设置键名
kubectl create configmap date-config --from-file=customkey=requests-pod.yaml

目录

# 文件夹下的每个文件单独创建一项
kubectl create configmap date-config --from-file=dir/

混合

kubectl create configmap date-config --from-literal=sleep-interval=3 \
  --from-file=requests-pod.yaml \
  --from-file=hello/

使用 Kubernetes API创建。 定义 ConfigMap YAML 文件(date-config.yaml)

apiVersion: v1
kind: ConfigMap
data:
  sleep-interval: "3"
metadata:
  name: date-config
kubectl apply -f date-config.yaml

查看

get

$ kubectl get configmap date-config -o yaml
apiVersion: v1
data:
  sleep-interval: "3"
kind: ConfigMap
metadata:
  creationTimestamp: "2021-08-11T01:08:53Z"
  name: date-config
  namespace: default
  resourceVersion: "1383722"
  uid: 887229e7-4934-483f-9890-9cd33cbf7237

describe

$ kubectl describe configmap date-config
Name:         date-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
sleep-interval:
----
3
Events:  <none>

修改

kubectl edit configmap date-config

删除

kubectl delete configmap date-config

给容器传递 ConfigMap 条目作为环境变量

定义 Pod YAML (date-config.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: date
spec:
  containers:
  - image: wangjunjian/date:env
    name: date
    env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: date-config
          key: sleep-interval

创建 Pod 对象

kubectl apply -f date-config.yaml

在 Pod 中引用不存在的 ConfigMap

创建 Pod 对象时,没有引用的 ConfigMap 对象。可以看到在调度时出现的错误信息。

$ kubectl describe pod date
Name:         date
...
Containers:
  date:
    Image:          wangjunjian/date:env
...
    State:          Waiting
      Reason:       CreateContainerConfigError
    Environment:
      INTERVAL:  <set to the key 'sleep-interval' of config map 'date-config'>  Optional: false
...
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  28s                default-scheduler  Successfully assigned default/date to minikube
  Normal   Pulled     12s (x3 over 27s)  kubelet            Container image "wangjunjian/date:env" already present on machine
  Warning  Failed     12s (x3 over 27s)  kubelet            Error: configmap "date-config" not found

可以设置对 ConfigMap 的引用是可选的,configMapKeyRef.optional: true。没有引用的 ConfigMap 对象,也可以调度成功。

一次性传递 ConfigMap 的所有条目作为环境变量

上面的 Pod 定义,需要一个条目一个条目的描述,当条目太多时比较麻烦,可以一次性传递多个条目。

定义 Pod YAML (test.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
  - image: busybox
    name: test
    command: ["/bin/sh", "-c", "sleep 86400"]
    envFrom:
    - prefix: CONFIG_
      configMapRef:
        name: test-config
  • prefix 是可选的

创建 ConfigMap 对象

kubectl create configmap test-config --from-literal=sleep-interval=3 --from-literal=one=1 --from-literal=two=2

创建 Pod 对象

kubectl apply -f test.yaml

查看容器中的环境变量

$ kubectl exec -it test -- env
HOSTNAME=test
CONFIG_one=1
CONFIG_sleep-interval=3
CONFIG_two=2

使用 configMap 卷将条目暴露为文件

Nginx 默认配置文件 /etc/nginx/nginx.conf,默认配置文件会自动嵌入子文件夹 /etc/nginx/conf.d/ 下所有的 .conf 文件。

通过 Nginx 的配置文件开启压缩功能,让服务器使用压缩传递给客户端响应。 这里编写我们的配置文件(nginx-config-gzip-on.conf)挂载到 /etc/nginx/conf.d/ 文件夹。

server {
    listen       80;
    server_name  localhost;

    gzip  on;
    gzip_types text/plain application/xml;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

创建 ConfigMap 对象

kubectl create configmap nginx-config --from-file=nginx-config-gzip-on.conf --from-literal=sleep-interval=3

查看 nginx-config

$ kubectl get configmap nginx-config -o yaml
apiVersion: v1
data:
  nginx-config-gzip-on.conf: |
    server {
        listen       80;
        server_name  localhost;

        gzip  on;
        gzip_types text/plain application/xml;

        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
    }
  sleep-interval: "3"
kind: ConfigMap
metadata:
  creationTimestamp: "2021-08-11T07:12:28Z"
  name: nginx-config
  namespace: default
  resourceVersion: "1399157"
  uid: 7f350db5-536d-40fd-b553-43e8a9575f29

编写 Pod YAML 文件(nginx-pod-configmap-volume.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod-configmap-volume
spec:
  containers:
  - image: nginx:alpine
    name: nginx
    volumeMounts:
    - name: config
      mountPath: /etc/nginx/conf.d
      readOnly: true
  volumes:
  - name: config
    configMap:
      name: nginx-config

创建 Pod 对象

kubectl apply -f nginx-pod-configmap-volume.yaml

通过端口转发连接 Pod

$ kubectl port-forward nginx-pod-configmap-volume 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

利用 curl 检查服务器响应来验证配置是否生效。

$ curl -H "Accept-Encoding: gzip" -I localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.21.1
Date: Wed, 11 Aug 2021 07:33:37 GMT
Content-Type: text/html
Last-Modified: Tue, 06 Jul 2021 15:21:03 GMT
Connection: keep-alive
ETag: W/"60e474df-264"
Content-Encoding: gzip

检查被挂载的 configMap 卷的内容。如果 ConfigMap 有多个条目会出现多个文件。

$ kubectl exec nginx-pod-configmap-volume -c nginx -- ls /etc/nginx/conf.d
nginx-config-gzip-on.conf
sleep-interval

卷内暴露指定的 ConfigMap 条目

对于上面的 sleep-interval 项,Nginx 服务器并不需要。

编写 Pod YAML 文件(nginx-pod-configmap-volume-with-items.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod-configmap-volume-with-items
spec:
  containers:
  - image: nginx:alpine
    name: nginx
    volumeMounts:
    - name: config
      mountPath: /etc/nginx/conf.d
      readOnly: true
  volumes:
  - name: config
    configMap:
      name: nginx-config
      items:
      - key: nginx-config-gzip-on.conf
        path: gzip-on.conf
  • path 必须指定。

创建 Pod 对象

kubectl apply -f nginx-pod-configmap-volume-with-items.yaml

检查被挂载的 configMap 卷的内容。

$ kubectl exec nginx-pod-configmap-volume-with-items -c nginx -- ls /etc/nginx/conf.d
gzip-on.conf

ConfigMap 独立条目作为文件被挂载且不隐藏文件夹中的其它文件

通过运行 nginx:alpine 容器可以看到在 /etc/nginx/conf.d 目录下有个 default.conf 文件。挂载我们的配置文件不想隐藏掉这个配置文件。

$ docker run --rm nginx:alpine ls /etc/nginx/conf.d
default.conf

编写 Pod YAML 文件(nginx-pod-configmap-volume-with-items-no-hide-files.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod-configmap-volume-with-items-no-hide-files
spec:
  containers:
  - image: nginx:alpine
    name: nginx
    volumeMounts:
    - name: config
      mountPath: /etc/nginx/conf.d/nginx-config-gzip-on.conf
      subPath: nginx-config-gzip-on.conf
      readOnly: true
  volumes:
  - name: config
    configMap:
      name: nginx-config
      defaultMode: 0660
  • mountPath 挂载的是文件路径
  • subPath 指定条目 nginx-config-gzip-on.conf
  • defaultMode 设置文件权限。默认是 644(-rw-r–r–),这里设置文件拥有者的用户和组可读写 660(-rw-rw—-)。

创建 Pod 对象

kubectl apply -f nginx-pod-configmap-volume-with-items-no-hide-files.yaml

检查被挂载的 configMap 卷的内容。

$ kubectl exec nginx-pod-configmap-volume-with-items-no-hide-files -c nginx -- ls -l /etc/nginx/conf.d
-rw-r--r--    1 root     root          1093 Aug 11 09:19 default.conf
-rw-rw----    1 root     root           217 Aug 11 09:19 nginx-config-gzip-on.conf

配置热更新(更新应用配置且不重启应用程序)

修改 ConfigMap

kubectl edit configmap nginx-config

打开编辑器,修改 gzip on 为 gzip off,保存退出。等待一会,修改的配置会自动更新卷中对应的文件。

验证

kubectl exec -it nginx-pod-configmap-volume -- cat /etc/nginx/conf.d/nginx-config-gzip-on.conf

可以看到配置文件更新了,但 Nginx 并没有什么影响,这是因为 Nginx 没有监控文件的更新并重启。

手动重启

kubectl exec -it nginx-pod-configmap-volume -- nginx -s reload

需要应用支持重载配置

文件被自动更新的过程

修改 ConfigMap 前

$ kubectl exec -it nginx-pod-configmap-volume -- ls -lA /etc/nginx/conf.d
total 0
drwxr-xr-x    2 root     root            61 Aug 12 01:39 ..2021_08_12_01_39_48.726754238
lrwxrwxrwx    1 root     root            31 Aug 12 01:39 ..data -> ..2021_08_12_01_39_48.726754238
lrwxrwxrwx    1 root     root            32 Aug 12 01:39 nginx-config-gzip-on.conf -> ..data/nginx-config-gzip-on.conf
lrwxrwxrwx    1 root     root            21 Aug 12 01:39 sleep-interval -> ..data/sleep-interval

修改 ConfigMap 后

$ kubectl exec -it nginx-pod-configmap-volume -- ls -lA /etc/nginx/conf.d
drwxr-xr-x    2 root     root            61 Aug 12 01:42 ..2021_08_12_01_42_24.017381129
lrwxrwxrwx    1 root     root            31 Aug 12 01:42 ..data -> ..2021_08_12_01_42_24.017381129
lrwxrwxrwx    1 root     root            32 Aug 12 01:39 nginx-config-gzip-on.conf -> ..data/nginx-config-gzip-on.conf
lrwxrwxrwx    1 root     root            21 Aug 12 01:39 sleep-interval -> ..data/sleep-interval

可以看到文件都链接当前文件夹 data 下的文件,文件夹 data 链接到另一个文件夹 yyyy_mm_dd_hh_mm_ss.f,修改 ConfigMap 后,只需要重新生成文件夹 yyyy_mm_dd_hh_mm_ss.f,把修改后的文件放到这个文件夹中,然后 data 重新链接到新的文件夹 yyyy_mm_dd_hh_mm_ss.f。

挂载到已存在文件夹的文件不会被更新

通过查看,文件并没有链接的存在,所以不能动态更新。

$ kubectl exec -it nginx-pod-configmap-volume-with-items-no-hide-files -- ls -lA /etc/nginx/conf.d
total 8
-rw-r--r--    1 root     root          1093 Aug 12 01:52 default.conf
-rw-rw----    1 root     root           217 Aug 12 01:52 nginx-config-gzip-on.conf

Secret

存储配置的敏感数据,如:证书和私钥。Secret 只会存储在节点的内存中。

如果一个配置文件同时包含敏感与非敏感数据,该文件应该被存储在 Secret 中。

默认令牌 Secret

默认被挂载到所有容器中的 Secret,通过 kubectl describe pods 命令可以查看到下面的信息。每个 Pod 都会自动挂载一个 secret 卷。

$ kubectl describe pods
Containers:
  kubia:
    Image:          wangjunjian/kubia:latest
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-d98km (ro)
Volumes:
  default-token-d98km:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-d98km

secret 卷会被挂载到容器的 /var/run/secrets/kubernetes.io/serviceaccount 目录。

查看描述信息,可以看到 Secret 包含三个条目:ca.crt, namespace, token。包含了从 Pod 内部安全访问 Kubernetes API 服务器所需的全部信息。

$ kubectl describe secrets default-token-d98km
Name:         default-token-d98km
Namespace:    kubia
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: 1aa99b7d-20a9-461e-b79a-c6bcd712f832

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  5 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IkZmZkdQXzBoMkNRLXpNVDA4UWxNcmlyNzYxTzVHYnVJZE5xZXN3T1lzazgifQ...

default-token Secret 默认会被挂载到每个容器。可以通过设置 Pod 定义中的 spec.automountServiceAccountToken 为 false,或者设置 Pod 使用的 ServiceAccount 中相同的字段为 false 来关闭这种默认行为。

查看 secret 卷挂载到容器文件夹包含的三个文件。

$ kubectl exec kubia-manual -- ls /var/run/secrets/kubernetes.io/serviceaccount
ca.crt
namespace
token

创建 Secret

生成证书和私钥

openssl genrsa -out https.key 2048
openssl req -new -x509 -key https.key -out https.cert -days 3650 -subj /CN=www.wangjunjian.com

创建 generic Secret

kubectl create secret generic nginx-https --from-file=https.key --from-file=https.cert --from-literal=sleep-interval=3

查看 Secret YAML

$ kubectl get secret nginx-https -o yaml
apiVersion: v1
data:
  https.cert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURIVENDQWdXZ0F3SUJBZ0lVZjlJekoxSnl6cEp0...
  https.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBcDlNU0xrWkNzN0RHZ...
  sleep-interval: Mw==
kind: Secret
...

可以看到 Secret 条目的值被以 Base64 格式编码。

Secret 可以用来存储非敏感二进制数据。Secret 的大小限于 1MB。

查看 Secret 条目的原值

$ kubectl get secret nginx-https -o jsonpath='{.data.sleep-interval}' | base64 -d
3

在 Pod 中使用 Secret 条目

通过 secret 卷将 Secret 暴露给容器之后,Secret 条目的值会被解码并以真实形式写入对应的文件。

编写 Nginx 配置,开发 HTTPS

编写 Nginx 配置文件(nginx-config-https.conf)。

server {
    listen       80;
    listen       443 ssl;
    server_name  www.kubia-example.com;

    ssl_certificate     certs/https.cert;
    ssl_certificate_key certs/https.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}

配置了服务器从 /etc/nginx/certs 中读取证书和私钥文件。

创建 ConfigMap 对象

kubectl create configmap date-html-config --from-file=nginx-config-https.conf --from-literal=sleep-interval=3

创建 Secret 对象

kubectl create secret generic date-html-https --from-file=https.key --from-file=https.cert

挂载 ConfigMap 和 Secret 到 Pod

定义 Pod YAML(date-html.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: date-html
spec:
  containers:
  - name: date-html-generator
    image: wangjunjian/date-html-generator
    env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: date-html-config
          key: sleep-interval
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - name: web-server
    image: nginx:alpine
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    - name: config
      mountPath: /etc/nginx/conf.d
      readOnly: true
    - name: https
      mountPath: /etc/nginx/certs
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP 
  volumes:
  - name: html
    emptyDir:
      medium: Memory
  - name: config
    configMap:
      name: date-html-config
      items:
      - key: nginx-config-https.conf
        path: https.conf
  - name: https
    secret:
      secretName: date-html-https

创建 Pod 对象

kubectl apply -f date-html.yaml

测试 Nginx 是否正确使用了 Secret 中的证书和密钥

通过 port-forward 访问 Pod

kubectl port-forward date-html 8443:443 &

发送请求,检查响应中服务器证书是否与之前生成的证书匹配。

$ curl https://localhost:8443 -k
2021-08-13 02:02:25

可以通过选项 -v 查看详细日志

$ curl https://localhost:8443 -k -v
*   Trying 127.0.0.1:8443...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8443 (#0)
Handling connection for 8443
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: CN=www.wangjunjian.com
*  start date: Aug 12 07:38:18 2021 GMT
*  expire date: Aug 10 07:38:18 2031 GMT
*  issuer: CN=www.wangjunjian.com
*  SSL certificate verify result: self signed certificate (18), continuing anyway.
> GET / HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/7.68.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.21.1
< Date: Fri, 13 Aug 2021 02:03:15 GMT
< Content-Type: text/html
< Content-Length: 20
< Last-Modified: Fri, 13 Aug 2021 02:03:13 GMT
< Connection: keep-alive
< ETag: "6115d2e1-14"
< Accept-Ranges: bytes
< 
2021-08-13 02:03:13

可以看到 Server certificate 字段显示的证书信息。

secret 卷存储于内存

$ kubectl exec date-html -c web-server -- mount | grep certs
tmpfs on /etc/nginx/certs type tmpfs (ro,relatime)

使用的是 tmpfs。

通过环境变量暴露 Secret 条目

创建 Secret 对象

kubectl create secret generic date-config --from-literal=sleep-interval=3

查看 Secret 对象

$ kubectl get secret date-config -o yaml
apiVersion: v1
data:
  sleep-interval: Mw==
kind: Secret

定义 Pod YAML (date-secret.yaml)

apiVersion: v1
kind: Pod
metadata:
  name: date
spec:
  containers:
  - image: wangjunjian/date:env
    name: date
    env:
    - name: INTERVAL
      valueFrom:
        secretKeyRef:
          name: date-config
          key: sleep-interval

创建 Pod 对象

kubectl apply -f date-secret.yaml

查看环境变量

$ kubectl exec date -- env
INTERVAL=3

查看日志

$ kubectl logs date
Fri Aug 13 00:42:00 UTC 2021
Fri Aug 13 00:42:03 UTC 2021

通过环境变量传递 Secret 给容器可能会暴露敏感数据,请始终采用 secret 卷的方式暴露 Secret。

镜像拉取 Secret(imagePullSecrets)

可以在自己的 Docker Hub 上找到一个仓库,通过 Settings -> Visibility Settings -> Make Private 进行设置为私有。

创建 docker-registry Secret

kubectl create secret docker-registry mydockerhubsecret \
  --docker-username=myusername \
  --docker-password=mypassword \
  --docker-email=myemail

查看 Secret 对象,可以看到仅有一个条目 .dockerconfigjson

$ kubectl get secrets mydockerhubsecret -o yaml
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsidXNlcm5hbWUiOiJ3Y...
kind: Secret

在 Pod 定义中使用 docker-registry Secret

通过在 Pod 定义中配置 imagePullSecrets 字段引用 docker-registry Secret。

apiVersion: v1
kind: Pod
metadata:
  name: private
spec:
  imagePullSecrets:
  - name: mydockerhubsecret
  containers:
  - image: wangjunjian/private:latest
    name: private

创建 Pod 对象

kubectl apply -f private.yaml

查看日志

$ kubectl logs private 
Hello World

如果没有配置 docker-registry Secret,将会出现下面的错误:

Failed to pull image "wangjunjian/private:latest": rpc error: code = Unknown desc = Error response from daemon: pull access denied for wangjunjian/private, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

参考资料