3-10-2-ConfigMap、Secret资源

熊 0 阅读 容器

1. 基础概念

在说configmap和secret资源之前 , 我们先来回顾下在docker环境下怎么给容器提供配置信息 ; 在docker容器里我们要给容器里的应用提供配置的方式有两种 ,

  • 一种是通过环境变量的方式 , 把对应容器里跑的程序的某些属性通过一个环境变量传递给容器运行时的环境中去 , 这样容器启动时 , 读取对应的环境变量 , 对应容器里的应用程序就会根据我们传递的环境变量来启动对应的程序 , 从而实现配置容器里应用程序的目的 ; 这种能够通过环境变量向容器里的应用传递配置的前提是对应应用程序支持

  • 第二种方式就是通过存储卷的方式 , 把外部的配置文件直接通过存储卷的方式挂载到容器里的应用程序对应位置 , 对应程序在启动时 , 通过读取挂载的配置文件 , 从而实现配置容器里的应用程序的目的 ;

这两种方式都有一个特点 , 只能在初始化容器时做 , 一旦一个容器初始化完成以后 , 修改对应的配置 , 必须要重新初始化容器 , 对应配置才能生效 ; 对于k8s上的pod来说 , 也是类似的逻辑 ; 第一通过环境变量的方式 , 第二通过存储卷的方式 ; 不同于docker容器 , 在k8s上一切皆对象 , 我们需要把对应的配置信息通过对应资源初始化为一个对象 , 然后通过pod调用对应的对象 , 从而实现向pod里的容器提供配置 , 这种能够把配置信息初始化为一个对象并被pod所调用的资源有两个 , 分别是configmap和secret ; configmap和secret资源都是用来向pod提供配置信息的资源 , 两者用法都很相似 , 唯一不同的是configmap主要用于提供非敏感配置的资源 , secret主要用来提供敏感配置的资源 ; 简单讲就是configmap不加密 , secret要对敏感配置做加密处理(严格上不叫加密 ,它是把对应敏感数据做base64编码处理)

configmap资源对象的创建和使用

configmap是k8s上的一个标准资源 , 我们可以通过命令的方式来创建 , 也可以通过定义资源清单的方式来创建 ;

configmap通过create命令来创建的语法格式

Usage:
kubectl create configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run=server|client|none] [options]

configmap对象的创建主要指定对应configmap对象的名称 , 以及把对应配置信息传递给对应对象 ; configmap对象支持从命令行直接获取用户给定的kv配置信息 , 也支持通过读取一个配置文件的内容来获取对应配置 ; --from-file选项表示 , 对应配置信息从文件获取 , 默认我们直接指定一个配置文件的文件名称 , 它会把文件的基名(不包含路径名称)当作对应配置信息的key , 把文件内容当作对应key的值 ; --from-literal选项表示 , 对应配置信息从用户在命令给定的key和value获取 ;

2. configmap配置

2.1 命令行传递kv

示例 : 通过命令的方式创建configmap资源对象 , 并在命令行向其传递kv配置 ;

root@k8s-master01:~# kubectl create cm configmap-demo --from-literal=key1=value1 --from-literal=key2=value2
configmap/configmap-demo created
root@k8s-master01:~# kubectl get cm 
NAME               DATA   AGE
configmap-demo     2      5s
kube-root-ca.crt   1      7d18h
root@k8s-master01:~# kubectl describe cm configmap-demo
Name:         configmap-demo
Namespace:    default
Labels:       <none>
Annotations:  <none>
​
Data
====
key1:
----
value1
key2:
----
value2
​
BinaryData
====
​
Events:  <none>
​

configmap可以简写为cm ; --from-literal选项可以多次使用 , 每次指定一个配置项 ; 从上面的显示看 , 对应configmap-demo这个对象保存了两个配置 , 分别是key1=value1、key2=value2 ;

定义pod应用configmap对象

root@k8s-master01:/opt/k8s-data/yaml/configmap# cat nginx-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-demo
  namespace: default
  labels:
    app: nginx
    rel: stable
spec:
  containers:
  - name: nginx-demo
    image: nginx:1.14-alpine
    env:
    - name: FIRST_KEY
      valueFrom:
        configMapKeyRef:
          name: configmap-demo
          key: key1
    - name: SECOND_KEY
      valueFrom:
        configMapKeyRef:
          name: configmap-demo
          key: key2

以上配置清单主要在nginx-demo容器里通过configmap向对应容器的运行环境传递两个环境变量 ; FIRST_KEY这个环境变量的值对应configmap对象里保存的key1这个键的值 ; SECOND_KEY这个环境变量的值对应configmap对象里的key2这个键的值 ;

应用资源清单

root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl apply -f ./
pod/nginx-demo created
root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl get pods 
NAME         READY   STATUS    RESTARTS   AGE
nginx-demo   1/1     Running   0          52s
root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl describe pod nginx-demo
Name:             nginx-demo
Namespace:        default
Priority:         0
Service Account:  default
Node:             k8s-node02.cbear.top/192.168.71.36
Start Time:       Tue, 04 Jun 2024 06:13:49 +0000
Labels:           app=nginx
                  rel=stable
Annotations:      <none>
Status:           Running
IP:               172.20.4.54
IPs:
  IP:  172.20.4.54
Containers:
  nginx-demo:
    Container ID:   containerd://7b704b23d6857a87a17ace4f1d39f26b3cb34da3de5a0673de89b23fb9ca97dc
    Image:          nginx:1.14-alpine
    Image ID:       docker.io/library/nginx@sha256:485b610fefec7ff6c463ced9623314a04ed67e3945b9c08d7e53a47f6d108dc7
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 04 Jun 2024 06:13:50 +0000
    Ready:          True
    Restart Count:  0
    Environment:
      FIRST_KEY:   <set to the key 'key1' of config map 'configmap-demo'>  Optional: false
      SECOND_KEY:  <set to the key 'key2' of config map 'configmap-demo'>  Optional: false
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pf2t6 (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  kube-api-access-pf2t6:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  96s   default-scheduler  Successfully assigned default/nginx-demo to k8s-node02.cbear.top
  Normal  Pulled     96s   kubelet            Container image "nginx:1.14-alpine" already present on machine
  Normal  Created    96s   kubelet            Created container nginx-demo
  Normal  Started    96s   kubelet            Started container nginx-demo
​

从上面pod的详细信息可以看到在对应Environment字段下多了两个环境变量 , 分别是FIRST_KEY和SECOND_KEY ;

验证 : 进入对应pod , 看看环境变量是否有FIRST_KEY和SECOND_KEY , 对应值是否是configmap对象中的值

root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl exec -it nginx-demo -- printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=nginx-demo
NGINX_VERSION=1.14.2
FIRST_KEY=value1
SECOND_KEY=value2
KUBERNETES_PORT_443_TCP_ADDR=10.68.0.1
KUBERNETES_SERVICE_HOST=10.68.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.68.0.1:443
KUBERNETES_PORT_443_TCP=tcp://10.68.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
TERM=xterm
HOME=/root
​

可以看到在对应pod的环境变量中有我们传递的两个环境变量 , 对应的值也是我们在configmap对象中定义的值 ;

2.2. 命令行传递配置信息

示例 : 通过命令的方式创建configmap资源对象 , 并通过配置文件向其传递配置信息 ;

准备配置文件

root@k8s-master01:/opt/k8s-data/yaml/configmap# cat www-cbear-top.conf 
server {
        server_name www.cbear.top;
        listen 80;
        location / {
            root "/www/html";
        }
}
root@k8s-master01:/opt/k8s-data/yaml/configmap# cat bbs-cbear-top.conf 
server {
        server_name bbs.cbear.top;
        listen 80;
        location / {
            root "/bbs/html";
        }
}
​

创建configmap对象 , 并把上面两个配置文件信息传递给configmap对象

root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl create cm nginx-conf --from-file=./www-cbear-top.conf --from-file=bbs-conf=./bbs-cbear-top.conf 
configmap/nginx-conf created
root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl describe cm nginx-conf 
Name:         nginx-conf
Namespace:    default
Labels:       <none>
Annotations:  <none>
​
Data
====
bbs-conf:
----
server {
        server_name bbs.cbear.top;
        listen 80;
        location / {
            root "/bbs/html";
        }
}
​
www-cbear-top.conf:
----
server {
        server_name www.cbear.top;
        listen 80;
        location / {
            root "/www/html";
        }
}
​
​
BinaryData
====
​
Events:  <none>
​

可以看到cm对象创建成功 , 并且成功把对应的配置文件内容当作对应key传递给cm对象了 ; 在创建cm对象时 , 要使用--from-file选项来指定从文件加载配置信息 , 如果只指定了文件名 , 则以文件基名作为对应key , 其文件内容作为对应key的值 ;

定义pod挂载configmap对象中的配置文件信息

​
root@k8s-master01:/opt/k8s-data/yaml/configmap# cat nginx-demo2.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-demo2
  namespace: default
  labels:
    app: nginx
    rel: stable
spec:
  containers:
  - name: nginx-demo
    image: nginx:1.14-alpine
    volumeMounts:
    - name: website-conf
      mountPath: /etc/nginx/conf.d/
  volumes:
  - name: website-conf
    configMap:
      name: nginx-conf
      items:
      - key: www-cbear-top.conf
        path: www-cbear-top.conf
        mode: 0644
      - key: bbs-conf
        path: bbs-cbear-top.conf
        mode: 0644
​
root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl apply -f nginx-demo2.yaml 
pod/nginx-demo2 created
root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl get pods 
NAME          READY   STATUS    RESTARTS   AGE
nginx-demo    1/1     Running   0          38m
nginx-demo2   1/1     Running   0          42s

以上配置信息表示把configmap对象中的两个配置信息 , 都以文件的方式挂载到/etc/nginx/conf.d/目录下 ; configmap类型存储卷它会把configmap中的对象以文件的形式挂载到对应pod ; 其中spec.volumes.configMap.items.key字段用于指定configmap对象中的key ; path用于指定把对应的key映射的文件名称 ; mode是用于指定对应文件的权限信息 ;

应用配置清单

root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl apply -f nginx-demo2.yaml 
pod/nginx-demo2 created
root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl get pods 
NAME          READY   STATUS    RESTARTS   AGE
nginx-demo    1/1     Running   0          38m
nginx-demo2   1/1     Running   0          42s


root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl describe pods nginx-demo2
Name:             nginx-demo2
Namespace:        default
Priority:         0
Service Account:  default
Node:             k8s-node03.cbear.top/192.168.71.37
Start Time:       Tue, 04 Jun 2024 06:51:18 +0000
Labels:           app=nginx
                  rel=stable
Annotations:      <none>
Status:           Running
IP:               172.20.5.44
IPs:
  IP:  172.20.5.44
Containers:
  nginx-demo:
    Container ID:   containerd://950c061c4f32636ccdc9c22ee5434081fa8f9cc0e56abb00a55dd69d989c657a
    Image:          nginx:1.14-alpine
    Image ID:       docker.io/library/nginx@sha256:485b610fefec7ff6c463ced9623314a04ed67e3945b9c08d7e53a47f6d108dc7
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 04 Jun 2024 06:51:33 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /etc/nginx/conf.d/ from website-conf (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-wzqft (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  website-conf:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      nginx-conf
    Optional:  false
  kube-api-access-wzqft:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m50s  default-scheduler  Successfully assigned default/nginx-demo2 to k8s-node03.cbear.top
  Normal  Pulling    2m49s  kubelet            Pulling image "nginx:1.14-alpine"
  Normal  Pulled     2m35s  kubelet            Successfully pulled image "nginx:1.14-alpine" in 14.504s (14.504s including waiting)
  Normal  Created    2m35s  kubelet            Created container nginx-demo
  Normal  Started    2m35s  kubelet            Started container nginx-demo

进入nginx-demo2容器 , 看看对应/etc/nginx/conf.d/目录下是否有两个我们指定的配置文件 , 对应文件内容是否是cm对象中对应key的内容。

root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl exec -it nginx-demo2 -- /bin/sh
/ # cat /etc/nginx/conf.d/
..2024_06_04_06_51_18.3463816011/  ..data/                            bbs-cbear-top.conf                 www-cbear-top.conf
/ # cat /etc/nginx/conf.d/bbs-cbear-top.conf 
server {
        server_name bbs.cbear.top;
        listen 80;
        location / {
            root "/bbs/html";
        }
}
/ # cat /etc/nginx/conf.d/www-cbear-top.conf 
server {
        server_name www.cbear.top;
        listen 80;
        location / {
            root "/www/html";
        }
}

可以看到在对应pod容器里 , 在/etc/nginx/conf.d/目录下有两个配置文件 , 这两个配置文件就是我们定义pod时挂载configmap存储卷定义的文件名称 ; 对应文件内容也是cm对象中保存的文件内容 ;

测试 : 修改对应cm资源的配置信息 , 看看对应引用了该cm资源对象的pod是否会更新配置信息

root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl edit cm nginx-conf
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  bbs-conf: |
    server {
            server_name bbs.cbear.top;
            listen 80;
            location / {
                root "/bbs/html";
            }
    }
  www-cbear-top.conf: |
    server {
            server_name www.cbear.top;
            listen 80;
            location / {
                root "/www/html";
            }
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2024-06-04T06:42:03Z"
  name: nginx-conf
  namespace: default
  resourceVersion: "1583525"
  uid: 8462729d-add4-4d2a-b840-65966a26cf91

在线修改cm对象配置信息 , 可以使用edit命令来修改指定cm对象即可 ; 修改完成后保存退出对应配置就会立即更新到cm对象 ; 以上主要修改了bbs-conf键中的listen 80修改为8080 ;

验证:查看对应cm对象 , 看看配置信息是否更新

root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl describe  cm nginx-conf
Name:         nginx-conf
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
bbs-conf:
----
server {
        server_name bbs.cbear.top;
        listen 8080;
        location / {
            root "/bbs/html";
        }
}

www-cbear-top.conf:
----
server {
        server_name www.cbear.top;
        listen 80;
        location / {
            root "/www/html";
        }
}


BinaryData
====

Events:  <none>

image-20240604150810119

可以看到对应cm对象中的配置信息已经被更新 ;

验证 : 看看对应引用该cm对象中的配置信息的pod是否更新了配置?是否重载了对应配置?

root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl exec -it nginx-demo2 -- /bin/sh
/ # cat /etc/nginx/conf.d/www-cbear-top.conf 
server {
        server_name www.cbear.top;
        listen 80;
        location / {
            root "/www/html";
        }
}
/ # cat /etc/nginx/conf.d/
..2024_06_04_07_07_44.2989162812/  ..data/                            bbs-cbear-top.conf                 www-cbear-top.conf
/ # cat /etc/nginx/conf.d/bbs-cbear-top.conf 
server {
        server_name bbs.cbear.top;
        listen 8080;
        location / {
            root "/bbs/html";
        }
}
/ # 

对应pod配置文件信息已经更新 , 但是并没有应用新配置 ; 像这种情况我们还得自己手动进入到对应的容器里重载配置 ;

2.3. 配置清单创建configmap

示例 : 使用配置清单创建cm对象

root@k8s-master01:/opt/k8s-data/yaml/configmap# cat configmap-demo.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-cm-demo
  namespace: default
data:
  website-conf: |
    server {
        server_name bbs.cbear.top;
        listen 80;
        location / {
            root "/bbs/html";
        }
    }

cm对象在没有spec字段 , 取而代之的是data字段 , 该字段主要用来定义对应kv配置信息 ; key可以是任意合法名称 , 对应的值可以是一个文件内容 ; 如果对应内容需要多行来书写 , 需要在对应的key后面加上 “|” ;

应用配置清单

root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl apply  -f configmap-demo.yaml 
configmap/test-cm-demo created
root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl get cm
NAME               DATA   AGE
configmap-demo     2      86m
kube-root-ca.crt   1      7d19h
nginx-conf         2      50m
test-cm-demo       1      6s
root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl describe cm test-cm-demo
Name:         test-cm-demo
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
website-conf:
----
server {
    server_name bbs.cbear.top;
    listen 80;
    location / {
        root "/bbs/html";
    }
}


BinaryData
====

Events:  <none>

可以看到对应的cm对象已经成功被创建 , 并且里面保存了我们在定义cm时的配置信息;

3. Secret资源的创建和使用

secret资源和configmap资源的用法都很类似 , 可以在命令行中通过create命令来创建 , 也可以通过定义资源清单来创建 , 其使用方式和configmap也很类似 ;

secret资源通过create命令来创建的语法格式

root@k8s-master01:/opt/k8s-data/yaml/configmap# kubectl create secret
Create a secret with specified type.

 A docker-registry type secret is for accessing a container registry.

 A generic type secret indicate an Opaque secret type.

 A tls type secret holds TLS certificate and its associated key.

Available Commands:
  docker-registry   Create a secret for use with a Docker registry
  generic           Create a secret from a local file, directory, or literal value
  tls               Create a TLS secret

Usage:
  kubectl create secret (docker-registry | generic | tls) [options]

Use "kubectl create secret <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

secret资源有三种类型 , 分别是docker-registry、generis、tls ;

  • docker-registry类型主要用来创建保存私有镜像仓库中需要用到的认证信息 , 比如用户名称 , 用户密码 , 仓库地址 , 用户邮件信息等等 ;

  • generis类型是比较通用的一种类型 , 它可以从一个文件中加载信息 , 也可以从命令行中获取对应的kv配置信息 ;

  • tls类型主要用来保存证书相关的证书 , 私钥 ;

在前边我们使用ingress资源时 , 在应用对应的证书和私钥时 , 就是通过tls类型的secret资源对象来向其ingress资源对象传递证书和私钥文件信息 ;

3.1 命令行创建Secret

3.1.1 docker-registry

创建docker-registry类型的secret资源的语法格式

Usage:
  kubectl create secret docker-registry NAME --docker-username=user --docker-password=password --docker-email=email
[--docker-server=string] [--from-literal=key1=value1] [--dry-run=server|client|none] [options]

示例 : 使用create命令来创建一个docker-registry类型的secret资源对象

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl create secret docker-registry harbor.cbear.top --docker-username=admin --docker-password=Harbor12345 --docker-server=harbor.cbear.top
secret/harbor.cbear.top created
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get secret
NAME               TYPE                             DATA   AGE
harbor.cbear.top   kubernetes.io/dockerconfigjson   1      28s
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl describe secret harbor.cbear.top
Name:         harbor.cbear.top
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/dockerconfigjson

Data
====
.dockerconfigjson:  110 bytes
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get secret harbor.cbear.top -o yaml
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyJoYXJib3IuY2JlYXIudG9wIjp7InVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IkhhcmJvcjEyMzQ1IiwiYXV0aCI6IllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSJ9fX0=
kind: Secret
metadata:
  creationTimestamp: "2024-06-04T07:51:10Z"
  name: harbor.cbear.top
  namespace: default
  resourceVersion: "1592960"
  uid: 7f8478ce-9e23-4f43-9cdb-cf61263f9844
type: kubernetes.io/dockerconfigjson

从上面对应secret资源对象中输出为yaml格式的配置中可以看到 , 对应data字段输出的是一个base64编码后的字符串 ; 其实里面的内容就是我们创建secret资源对象时指定的内容 ; 如下

root@k8s-master01:/opt/k8s-data/yaml/secret# echo "eyJhdXRocyI6eyJoYXJib3IuY2JlYXIudG9wIjp7InVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IkhhcmJvcjEyMzQ1IiwiYXV0aCI6IllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSJ9fX0=" | base64 -d
{"auths":{"harbor.cbear.top":{"username":"admin","password":"Harbor12345","auth":"YWRtaW46SGFyYm9yMTIzNDU="}}}root@k8s-master01:/opt/k8s-data/yaml/secret# 

root@k8s-master01:/opt/k8s-data/yaml/secret# echo YWRtaW46SGFyYm9yMTIzNDU= | base64 -d
admin:Harbor12345root@k8s-master01:/opt/k8s-data/yaml/secret# 

可以看到所有把对应字符串交给base64解密后 , 拿到的就是我们在创建docker-registry类型的secret资源对象传递的选项 ;

定义pod资源引用docker-registry类型的secret资源对象

root@k8s-master01:/opt/k8s-data/yaml/secret# cat test-pod-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-nginx
  namespace: default
  labels:
    app: nginx
spec:
  imagePullSecrets:
  - name: harbor.cbear.top
  containers:
  - name: nginx
    image: harbor.cbear.top/test/nginx:latest

在定义pod时 , 如果要从对应私有镜像仓库中拉去镜像 , 需要用到认证信息 , 可以使用imagePullSecrets字段来应用对应的secret资源对象来传递仓库的认证信息 ; 在应用配置清单之前 , 需要将所有节点的/etc/hosts文件和/etc/docker/daemon.json文件更新下 ; 如果是私钥镜像仓库默认docker会认为不安全 , 需要我们手动指定出来 ; 如果对应域名在互联网上无法正常解析 , 还需要借助对应的hosts文件将其解析到对应仓库服务器的地址上 ; 如下

[root@master01 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.99 time.test.org time-node
192.168.0.41  master01 master01.k8s.org
192.168.0.42  master02 master02.k8s.org
192.168.0.43  master03 master03.k8s.org
192.168.0.44  node01 node01.k8s.org
192.168.0.45  node02 node02.k8s.org
192.168.0.46  node03 node03.k8s.org
192.168.0.47  node04 node04.k8s.org
199.232.28.133 raw.githubusercontent.com
192.168.0.99 docker-registry.io registry
[root@master01 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://cyr1uljt.mirror.aliyuncs.com"],
"insecure-registries": ["docker-registry.io"]
}
[root@master01 ~]# scp /etc/docker/daemon.json node01:/etc/docker/
daemon.json                                                                                                100%  112    39.4KB/s   00:00   
[root@master01 ~]# scp /etc/docker/daemon.json node02:/etc/docker/
daemon.json                                                                                                100%  112    67.3KB/s   00:00   
[root@master01 ~]# scp /etc/docker/daemon.json node03:/etc/docker/
daemon.json                                                                                                100%  112     8.9KB/s   00:00   
[root@master01 ~]# scp /etc/docker/daemon.json node04:/etc/docker/
daemon.json                                                                                                100%  112    69.8KB/s   00:00   
[root@master01 ~]# scp /etc/hosts node01:/etc/
hosts                                                                                                      100%  541   477.4KB/s   00:00   
[root@master01 ~]# scp /etc/hosts node02:/etc/
hosts                                                                                                      100%  541   225.7KB/s   00:00   
[root@master01 ~]# scp /etc/hosts node03:/etc/
hosts                                                                                                      100%  541   217.3KB/s   00:00   
[root@master01 ~]# scp /etc/hosts node04:/etc/
hosts                                                                                                      100%  541   149.4KB/s   00:00   
[root@master01 ~]# ssh node01 'systemctl restart docker'
[root@master01 ~]# ssh node02 'systemctl restart docker'
[root@master01 ~]# ssh node03 'systemctl restart docker'
[root@master01 ~]# ssh node04 'systemctl restart docker'

应用配置清单 , 看看对应的pod是否能够启动成功

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl apply -f test-pod-demo.yaml
pod/test-nginx created

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get pods -o wide
NAME          READY   STATUS    RESTARTS   AGE    IP            NODE                   NOMINATED NODE   READINESS GATES

test-nginx    1/1     Running   0          6s     172.20.3.74   k8s-node01.cbear.top   <none>           <none>

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl describe pod test-nginx
Name:             test-nginx
Namespace:        default
Priority:         0
Service Account:  default
Node:             k8s-node01.cbear.top/192.168.71.35
Start Time:       Tue, 04 Jun 2024 08:31:12 +0000
Labels:           app=nginx
Annotations:      <none>
Status:           Running
IP:               172.20.3.75
IPs:
  IP:  172.20.3.75
Containers:
  nginx:
    Container ID:   containerd://61fd344b042153a2d0273aee731e717b8c01b73fcfabd0ef9079ab36e614ba15
    Image:          harbor.cbear.top/test/nginx:latest
    Image ID:       harbor.cbear.top/test/nginx@sha256:658aa991c82d64867ecbe34a1c5b8573358fe7c1fac5a16b8dc500ea7e73d1b7
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 04 Jun 2024 08:31:13 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-kjj9b (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  kube-api-access-kjj9b:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m22s  default-scheduler  Successfully assigned default/test-nginx to k8s-node01.cbear.top
  Normal  Pulling    2m23s  kubelet            Pulling image "harbor.cbear.top/test/nginx:latest"
  Normal  Pulled     2m22s  kubelet            Successfully pulled image "harbor.cbear.top/test/nginx:latest" in 251ms (251ms including waiting)
  Normal  Created    2m22s  kubelet            Created container nginx
  Normal  Started    2m22s  kubelet            Started container nginx

可以看到对应pod能够正常到指定的私钥仓库中把镜像托下来 , 并启动成功 ;

这里直接切换到对应节点k8s-node01.cbear.top上面删除对应镜像直接测试下载镜像 ,会发现如果没有登录仓库。会直接提示下载失败

root@k8s-node01:~# nerdctl pull harbor.cbear.top/test/nginx
WARN[0000] skipping verifying HTTPS certs for "harbor.cbear.top" 
FATA[0000] failed to resolve reference "harbor.cbear.top/test/nginx:latest": unexpected status from HEAD request to https://harbor.cbear.top/v2/test/nginx/manifests/latest: 401 Unauthorized 

3.1.2 generic

使用create命令创建generic类型的secret资源对象语法格式

Usage:
  kubectl create secret generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1]
[--dry-run=server|client|none] [options]

示例 : 使用create命令创建generic类型的secret资源对象

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl create secret generic mysql-auth --from-literal=username=root --from-literal=passwd=admin
secret/mysql-auth created

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get secret 
NAME               TYPE                             DATA   AGE
harbor.cbear.top   kubernetes.io/dockerconfigjson   1      50m
mysql-auth         Opaque                           2      25s

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl describe secret mysql-auth
Name:         mysql-auth
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
passwd:    5 bytes
username:  4 bytes

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get  secret mysql-auth -o yaml
apiVersion: v1
data:
  passwd: YWRtaW4=
  username: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: "2024-06-04T08:40:48Z"
  name: mysql-auth
  namespace: default
  resourceVersion: "1599757"
  uid: aa52ba0e-b3c5-44f6-a75e-62926ec3ab22
type: Opaque

generic类型的secret资源的创建和configmap很类似 , 它可以接受从命令行中用户手动传递对应的配置信息 , 也支持从配置文件中获取对应的配置信息 ;

创建pod资源 , 引用generic类型的secret类型的资源

root@k8s-master01:/opt/k8s-data/yaml/secret# cat mysql-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mysql-demo
  namespace: default
  labels:
    app: mysql
spec:
  containers:
  - name: mysql-demo
    image: mysql:5.6
    env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysql-auth
          key: passwd

上述清单定义了运行一个pod , 其内部跑一个mysql:5.6的容器 ; 对应使用环境变量的方式向mysql-demo容器传递了一个MYSQL_ROOT_PASSWORD的环境变量 , 对应环境变量的值为generic类型的secret资源对象中的passwd这个键的值 ;

应用配置清单

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl apply -f mysql-demo.yaml 
pod/mysql-demo created

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get pods -o wide
NAME          READY   STATUS    RESTARTS   AGE    IP            NODE                   NOMINATED NODE   READINESS GATES
mysql-demo    1/1     Running   0          85s    172.20.4.55   k8s-node02.cbear.top   <none>           <none>

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl describe pod mysql-demo
Name:             mysql-demo
Namespace:        default
Priority:         0
Service Account:  default
Node:             k8s-node02.cbear.top/192.168.71.36
Start Time:       Tue, 04 Jun 2024 08:51:31 +0000
Labels:           app=mysql
Annotations:      <none>
Status:           Running
IP:               172.20.4.55
IPs:
  IP:  172.20.4.55
Containers:
  mysql-demo:
    Container ID:   containerd://cfb7673bf46398144eef98ac279050c9be19a77784ff7950088e792c3445c806
    Image:          mysql:5.6
    Image ID:       docker.io/library/mysql@sha256:20575ecebe6216036d25dab5903808211f1e9ba63dc7825ac20cb975e34cfcae
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 04 Jun 2024 08:52:27 +0000
    Ready:          True
    Restart Count:  0
    Environment:
      MYSQL_ROOT_PASSWORD:  <set to the key 'passwd' in secret 'mysql-auth'>  Optional: false
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-brvk6 (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  kube-api-access-brvk6:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m30s  default-scheduler  Successfully assigned default/mysql-demo to k8s-node02.cbear.top
  Normal  Pulling    2m30s  kubelet            Pulling image "mysql:5.6"
  Normal  Pulled     95s    kubelet            Successfully pulled image "mysql:5.6" in 54.84s (54.84s including waiting)
  Normal  Created    95s    kubelet            Created container mysql-demo
  Normal  Started    95s    kubelet            Started container mysql-demo

可以看到对应容器已经正常处于running状态 , 并在其详细信息中看到对应环境变量MYSQL_ROOT_PASSWORD引用secret中的passwd键 ;

测试:进入mysql-demo的交互式接口 , 看看使用创建secret时使用的passwd键传递的密码是否可以正常登录到mysql系统

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl exec -it mysql-demo -- /bin/sh
# mysql
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
# mysql -padmin  
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.51 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)

mysql> exit
Bye

可以看到直接在容器交互式接口直接不使用密码是不能正常登录到mysql数据库 ; 使用正确的密码后能够正常进入mysql ; 其实我们在交互式接口上查看环境变量也能查看到对应的环境变量的信息 ; 如下

# printenv   
KUBERNETES_PORT=tcp://10.68.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=mysql-demo
MYSQL_MAJOR=5.6
HOME=/root
MYSQL_ROOT_PASSWORD=admin
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.68.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MYSQL_VERSION=5.6.51-1debian9
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.68.0.1:443
GOSU_VERSION=1.12
KUBERNETES_SERVICE_HOST=10.68.0.1
PWD=/

3.1.3 tls

使用create命令创建tls类型的secret资源对象语法格式

Usage:
  kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file
[--dry-run=server|client|none] [options]

示例 : 使用create命令创建tls类型的secret资源对象

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl create secret tls test-tls --cert=./server.crt --key=./server.key 
secret/test-tls created
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get secret
NAME               TYPE                             DATA   AGE
harbor.cbear.top   kubernetes.io/dockerconfigjson   1      94m
mysql-auth         Opaque                           2      44m
test-tls           kubernetes.io/tls                2      3s


root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl describe secret test-tls
Name:         test-tls
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/tls

Data
====
tls.crt:  1915 bytes
tls.key:  3268 bytes

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get secret test-tls -o yaml
apiVersion: v1
data:
  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZXakNDQTBLZ0F3SUJBZ0lVR21QQmtzRHNjODJwMTN4a0wzbjN5UVI3WUVVd0RRWUpLb1pJaHZjTkFRRU4KQlFBd0d6RVpNQmNHQTFVRUF3d1FhR0Z5WW05eUxtTmlaV0Z5TG5SdmNEQWVGdzB5TkRBMU1qQXhNVEU0TVRsYQpGdzB6TkRBMU1UZ3hNVEU0TVRsYU1Cc3hHVEFYQmdOVkJBTU1FR2hoY21KdmNpNWpZbVZoY2k1MGIzQXdnZ0lpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ3hDR2VVdVpEWDdNNlRBK0FSTkFvS2wzZ3QKVXoweTR0WUZIYk5FME1qeWwvcUdMR1BKTkZiZWZCSnNSdHg4bWw0bE9aL05wa0ZIRUtvQ1d1dG1BNTJHZS8xcgpRejFUVitwRlJkQThaM2VDOFJjOXhzaXVHS1k1SEZZbmtNTzlLMkp4ZmFOdUNRYitIQWNGUVBLT3J3ZDNZMXNLCm1ua2c1aXVZM1BOek4xeTZhb2NXM0RId1pSWEtBNVl3Sm11WWMrR3ZjTDVCZm1QbWZ6OFBXK2NDRHY4VzZTakIKM05leENabVRIclZYem54WjQ5MUxxME40RWRxWTVoSURadS9SZXlEeWplNWJQS3M5Q2ZlRUZvT1g3TCtScTNoSQpSaUR2RlJ5Y3E3TVBYb2U1ZjYxYTl6Q1QrbnFmU3RqZnlKazZpbnlNdXE4ZWNtWUpRYXZaVGoza01VckVBWFpGCnB5WFZuSzVYdVFGWkNzWkVma25hbVZlSjBvREY0R1g2TkRTbnQvZUZvdmZ2M3drUmszVHRDQzNRbzZmWDJweHYKYk1GcEhoK2x5cy94ZTU5bFRQczFSR1VLSzdtMmhaUXlqdnUzQ2hCTitsOVlON2FLY25aOGFpVmx5U0J0a09JbQpwbzIwUW0vNnU1SDBONDlMUEM2MjVIZEhJcXpQSWdMbnJIcmlrSjdGSlFtUk9mQUFsQ1plcFZubTRvcFQ5OTJJClV1N1hrMThnSjhsZjRyNEYvaDVGWmdnSzlES0duWFNyYlFjRkJWa2gwNnlLMHI5cUhpYldBN1Y1T3lKanB5UkwKU01pN3JLNDJyTlJiMHo3TnI0TnRjV1RLVDFENnI0a05uckZkSGNEUXlBNG1PSmFVQVB0QnNJQWxvUnUvWXVaYQpRQm5HcW5TRUpJS0lCNm5kVXdJREFRQUJvNEdWTUlHU01COEdBMVVkSXdRWU1CYUFGRFE4dkNMTzUvejlDcUlJCkJUQnRCN0J4K2Uzb01Ba0dBMVVkRXdRQ01BQXdDd1lEVlIwUEJBUURBZ1R3TUJNR0ExVWRKUVFNTUFvR0NDc0cKQVFVRkJ3TUJNQ01HQTFVZEVRUWNNQnFDRUdoaGNtSnZjaTVqWW1WaGNpNTBiM0NDQm1oaGNtSnZjakFkQmdOVgpIUTRFRmdRVXdGYXRHL2RQTFpaSDhFZE5BNEhsTmxaSTBpTXdEUVlKS29aSWh2Y05BUUVOQlFBRGdnSUJBSE44CnYrenZoTTZhYVZCVVVydWpEU3FRSlhqeURCOGpSaHlYRUpFQVpRTlhMeXFGTUpacEw4WEE1SWR4ZFFCMy9tUk4Kb3k3MDZMS2Fvd1JzOWVwQVZZRkgzN1Z5b2ZtM3BTSnFZMVBRMjhaTGJhbnYzblhzc0wxT2c4MjhVZzllTmtSZApXeXJjaXA0ek05NTFVRHRpQTNpam5RU3NLbGdHR0pja1ZRYmJVeks1Y1JXVHhxZWNRWXQzNW9CUW5mVXVFWm1zCjMyd1ROS2FFL00zNzNWbWJPRFJWZXpsbnpTUlhNL2NSaThjNHBwNU16NXo3L3poaGorMDFtMWNkbTYvcFN5WjIKNVFzMS83RlpQM3VhRi9BRTFEckFxQm1UU3lWMzhpVXhmUWx4RUYvRzdYRkdFQnNVc3VGMzU0cXpzenpEWFVoNgp6dnA3S0FDZndpOTZndlpzSkZaMUZwZUNHKytXay83cm9jSFdUQ1hoSjQzRHEyb2dZNGJGYldwVkZ1NndWNVlkCnhaY2VsWHVOM3BtUDdkSlhoVDRjendEVjNIRittdEMvN0tDZS9DRUJ3cEo4VCtXNWZUY0dYWm1RZGNXNDN2c1MKd0dIa2puVU5sdzBtY0VSTmxyVmZiVmJIZDlUdDhqTFpYMndjcUd0NURac29PWUxPYk8wd1prVFRWYkJYSTlOVwpBaWg5RUNxUy90TzhMZnV3QlNPUndvYlRQRzl6cWNiQTB1RWgvUEZqd0F1N3p0alJ2SlF6S1JDeE1sTjNndks5Cmo1Q0VKZnpmRkhlRG4rMjk2WGY4T0JvNzZTR3J0U3I1ajVsdkVSTy8zRFN3Z0lMemlvb3JIMmNhaW9Ja3QyQVIKdEhROEYxMXdveEl2QjNoRm1TTEdxQS9VcDZSeU52TjNUZXFHTmtJTgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
  tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRUUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Nzd2dna25BZ0VBQW9JQ0FRQ3hDR2VVdVpEWDdNNlQKQStBUk5Bb0tsM2d0VXoweTR0WUZIYk5FME1qeWwvcUdMR1BKTkZiZWZCSnNSdHg4bWw0bE9aL05wa0ZIRUtvQwpXdXRtQTUyR2UvMXJRejFUVitwRlJkQThaM2VDOFJjOXhzaXVHS1k1SEZZbmtNTzlLMkp4ZmFOdUNRYitIQWNGClFQS09yd2QzWTFzS21ua2c1aXVZM1BOek4xeTZhb2NXM0RId1pSWEtBNVl3Sm11WWMrR3ZjTDVCZm1QbWZ6OFAKVytjQ0R2OFc2U2pCM05leENabVRIclZYem54WjQ5MUxxME40RWRxWTVoSURadS9SZXlEeWplNWJQS3M5Q2ZlRQpGb09YN0wrUnEzaElSaUR2RlJ5Y3E3TVBYb2U1ZjYxYTl6Q1QrbnFmU3RqZnlKazZpbnlNdXE4ZWNtWUpRYXZaClRqM2tNVXJFQVhaRnB5WFZuSzVYdVFGWkNzWkVma25hbVZlSjBvREY0R1g2TkRTbnQvZUZvdmZ2M3drUmszVHQKQ0MzUW82ZlgycHh2Yk1GcEhoK2x5cy94ZTU5bFRQczFSR1VLSzdtMmhaUXlqdnUzQ2hCTitsOVlON2FLY25aOAphaVZseVNCdGtPSW1wbzIwUW0vNnU1SDBONDlMUEM2MjVIZEhJcXpQSWdMbnJIcmlrSjdGSlFtUk9mQUFsQ1plCnBWbm00b3BUOTkySVV1N1hrMThnSjhsZjRyNEYvaDVGWmdnSzlES0duWFNyYlFjRkJWa2gwNnlLMHI5cUhpYlcKQTdWNU95SmpweVJMU01pN3JLNDJyTlJiMHo3TnI0TnRjV1RLVDFENnI0a05uckZkSGNEUXlBNG1PSmFVQVB0QgpzSUFsb1J1L1l1WmFRQm5HcW5TRUpJS0lCNm5kVXdJREFRQUJBb0lDQUJ2ckErUVA1RGd4RFBOaFRwSXRTZWR1CnMxSGozbkwvdm03ekcrOXp4T1RXWG5pUFY5M2JSbGNkYTQydUduSlVxUmtuYVJIMk1JclkrcjZXcTZoeHFkaSsKQlVmSG1hRzRRUkVvbDlUQmRReERkMU5UaUcxRmVqS1NkZXhxWjN2ckhoZGd1ckppYzdzRXgzOVJiK1JjS2pURAozZVVpV1l6Uno0NmRTdVUyRmdaWWxnZUp0UjhWM3pyMW1DeVlEOVZzY2tCZEZYRTFwemZWTHYxOTZabkpBZnNSCklrOTVtTkxwL1NhVzFxbExhUS9jbit4TUloUGdMa0FqaVlsYmVvd1NFSzdxVkJjSStSdU4rVk10ZG11SE56OXQKTWtiNk51ZTM4Qm10b3N0L01GbnF1U0laem1HS2J1WmZyWURwQjhVVUlZZlRTWm84YkpGSmQ4K0pYUTJoK2w5WQppVkIzQWp3UC94ay9zbDFxaVVJZkhiQXdCM3lLV0ZMb05JUnBCUm5waERqTVEzUkY4U0NKQkZ4Um92QVNWRW1RCm51WUdNTFhHbWVQVGRyN283dm5RTG5Iei9xMGVFa2d3L2pwOURUeE1KOU1JZlZuTTUyT0FrdGI1TFB5R1RzbG4KVDRJZzFHY25Vdk9FZmdjc0dWOGlxWlZlQVhYbVN5NlFURlh3eFIwc0VQckE1QXZOVm9PVldNTG1UWFJBKy9aZAp3R3ZxY0RaMDBDMVVYeVhxbkhkb0ZDSGxqaks4bm1jTHBxQ0VzYVZMR25vRjZWdFF6ejFrTFBtd1R5M2t1SURDCmk5b0x2MFdwdVZMNmluSHBweTVlb1RuNWhJQXhkR1YrS3V1UVZMeEVCc0lPVUplVFFIUGNvVHljYnRpZndNZUIKRDlzOHd1bG1sQmdBUGhueGZwTk5Bb0lCQVFETnloQzVJRngxRCt1MGMrNk95VGpHc3FYTkhqS2RGNkFyMUVnVQplMWsrNWorV2VOa2U0ZUhFZC8xaGlwQnJkUXNMNjVoOFlyZ2F6WktrYVhxZXUxMDZ2REZHdFhtbkFkcDlHMnNICnlSNVJjVW5xbTN4eHNtS0pQL1F4TEZ5Wk1LeHBlem5WeUJoYUV2c2kydThpbG1IMWdyc1BEdXFha2cyWS9jSXEKc0ZkdTVuVzhXSWlIZW51eTJzd0p5TXdVODVsNG15MW5qd3N0ZGRycm1ibkVUMkloNnlJVmpsMHhLank3WWd2QgplNkgyblVYNnFZRndaOFVOL1BZWjNadEZIUDRiRzJZRXNDOUNxbG5FdVdvdmlLMEVqNnBQdEdaTnFhVHhUZ3EwCkF5WGZjYU85aHp3OUtUZWtjYjZRcFdkUVhlT3ZvVDY0TnJXRWx3K2RJcXEvR0JLRkFvSUJBUURjT2ltVjRKS2YKOFVFYjh1UVJ3Q2RRVnB5SldvV3ZZVzNyeFQ5RkFxZmRQTUw0dGlXb0JZRW9RY0F0LzVBUC94VlR6d2ZJWk5YUQpMTlRDTFAwMnhFUXpQK2g1STYvSzNFb1VHRTQ5YjVaeDd2S013SkcrSGtVTXFacHFZN2tETSt5TVZrZ0JZdENwClptVHNSVVRMZ2hTZ1lmSXhIQmJlV2RjSEZJb0dPK1E2ZFFUczNUQ0t6WlBnbzNaVHhuSHZ2cjl4RHhraFUvSE8KMzhKcWxKeVowVTFIeEFtcUtoWU9OSXhVdFEwMThSRTVielNiNGdxeWEvZXhjbmxqYVp5VVdSdFBpajI5dy9sbgp6R3RBK0FMcC9ETm9ITllURHhhd1NuaGFhUTZOWTlxK0N0dmFKL3Q2UkwxWWQrVVkzK1BXMU1ubUd1dlpvK0FOCjdlZU5LZmdObWJQM0FvSUJBQzJjd2dRbWRoZkVSWndqcmhhYjV5ZXpaU2lIcnZRK3psT29vNmxXaGJ0NVVWTEsKeW1VYjcreWFJK0ZBMHkzZUxXcWc5NVZxVkNBc3ZIb1Fud3Nid0ZoS2FpbWdBNnpPcmx6WWZPcW0yejkxK3NvegpXR3ZpL0JBcnlyWXpmUHEvWFJlc0ptK0tBRXZHdFQ5T2czNkpFb0ZXVHB2UjFKSWFHVVYxeVZtbzZGZytZSTQwCm1WNWQrWmoxQWhDUkh4cnR1M0NPQkl4Vm1rYWpQcmpGdy9VTkcxVWxSdEs4VVUrYWF3ZWxmYkdPODZFenp0VDIKU1NoZTk4Qlg5enhZY0Jmcml5NzY3YXZRV1VsUGRNSXp6cU5taWVMZTdRTHBtMXRQWkszUGZIUFYxc2tsNlFNVApQSGpaNytsVkJNWU93MDErNGY2Rm9OODMwUmZvVzUrYWxYbnhuZmtDZ2dFQVdLK3pmMy9vakRDRG45VzRzczFICkI3dFpYcGJ0cnlyMU1UVkZ2V3pNWFBQVE1JVnB0TGhDd3d0M2NRNngzVDlFUDNQb0ZuTkZCNGlHUll3SWpMMk4KR1hackVCMm05WEt4QWxhbmEyWThsN1U2U0NSa2pNTnoyeDJSNmJZdkUzTWRsNFpIaVFkYU1GM2oxcUl1aWlYZwpXSllaQ2wzZGQ3MkdNbnU2K2JlMHVUWFd2ZXgxVi9CaDFOei9FYzJncElPVVpOdEhxM3c2ckt5L2hseENsRThOCmFCRXlNeXl2cFJqVVNtaCs0WElyRlk0TENadUY0MFJIZzFZdVBES1RzOG9PallHR1M1MVlHc3pmaEZKY0dnNU8KUldjWGJxVnM1YUdYeGhENG8wZkxGeTBZVEVvOW80ZDdHTjF2alF6Y20rOGxQMTBvRFlWSS9WTUpKSGY2UkwvWgpFUUtDQVFCeVBCNFI1Qm9XZEhhbk1pcG5kTXBLdFpwMHZFTzJWTVpoVFBMU2Nkbkh2R2YxWVBIME1nZ2xLdkk0CjRKZ2JqRnlkRGtsN001T1lLVzZKcEt3b2pZQ3Q2bTQzV25ZNGgyUGhLc0JJYXdIelRrUEZvUDRhdFZUYkNJMDIKSkEwS2FVL2E2Ulg1a2Fya3hpeFI0Z2xFelZyNWVvdWlIVFpOT29OemY0OGpjbGJMYThmaWdkTmFiR2lORXF2TApBRTlyOEJQaUR3TVo5bjJIc2dRN2dTSjJHOTQzSzRLVmhkVGNaeCt4K3FpNnkwVTB1SDB2cnZSSWJRa1owTTFnCkZod0tGVXZvalk3dXh3NklmUDFNblJMdXArTVBybUdtVXhFdFM1U3FjbHpLUEJydzZRc2ozU3FMSmlLMGpFVnEKWkloRWxidVVqM1hMUkhCRHY1Qk5qekk0ZlZsVQotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg==
kind: Secret
metadata:
  creationTimestamp: "2024-06-04T09:26:09Z"
  name: test-tls
  namespace: default
  resourceVersion: "1605953"
  uid: bf045e3f-ea32-40d7-b80c-74e4a6f5e8c3
type: kubernetes.io/tls

创建tls类型的secret资源对象时 , 只需要指定其名称和对应的证书和私钥文件即可 ; 这里需要注意一点 , 不管外部证书和私钥是什么名字 , 在tls类型的secret资源对象中都叫tls.crt和tls.key ; 它会自动映射为这两个名字 ;

示例 : 定义pod挂载secret存储卷

root@k8s-master01:/opt/k8s-data/yaml/secret# cat mount-secretvolume.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  namespace: default
spec:
  containers:
  - name: nginx
    image: nginx:1.14-alpine
    volumeMounts:
    - name: test-tls-secret
      mountPath: /etc/nginx/cert/
  volumes:
  - name: test-tls-secret
    secret:
      secretName: test-tls
      items:
      - key: tls.crt
        path: test.crt
        mode: 0400
      - key: tls.key
        path: test.key
        mode: 0400

应用资源清单

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl apply -f mount-secretvolume.yaml 
pod/test-pod created
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get pods -o wide
NAME          READY   STATUS    RESTARTS   AGE     IP            NODE                   NOMINATED NODE   READINESS GATES
test-pod      1/1     Running   0          20s     172.20.3.76   k8s-node01.cbear.top   <none>           <none>
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl describe pods test-pod
Name:             test-pod
Namespace:        default
Priority:         0
Service Account:  default
Node:             k8s-node01.cbear.top/192.168.71.35
Start Time:       Tue, 04 Jun 2024 09:32:45 +0000
Labels:           <none>
Annotations:      <none>
Status:           Running
IP:               172.20.3.76
IPs:
  IP:  172.20.3.76
Containers:
  nginx:
    Container ID:   containerd://83cf9030d66927600ff015adafa29b05b582eb2b64fe9e1a34c623e390a0f32e
    Image:          nginx:1.14-alpine
    Image ID:       docker.io/library/nginx@sha256:485b610fefec7ff6c463ced9623314a04ed67e3945b9c08d7e53a47f6d108dc7
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 04 Jun 2024 09:32:46 +0000
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /etc/nginx/cert/ from test-tls-secret (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-cddc6 (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  test-tls-secret:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  test-tls
    Optional:    false
  kube-api-access-cddc6:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  59s   default-scheduler  Successfully assigned default/test-pod to k8s-node01.cbear.top
  Normal  Pulled     59s   kubelet            Container image "nginx:1.14-alpine" already present on machine
  Normal  Created    59s   kubelet            Created container nginx
  Normal  Started    59s   kubelet            Started container nginx

可以看到对应容器已经将对应secret存储卷以读写方式挂载至/etc/nginx/cert/目录 ;

验证 : 进入test-pod交互式接口 , 看看对应目录下是否有对应的文件

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl exec -it test-pod -- /bin/sh
/ # ls /etc/nginx/cert/
test.crt  test.key

可以看到在test-pod容器对应的/etc/nginx/目录下自动创建了一个cert目录 , 并在其目录下看到有两个证书文件 , 一个名为test.crt , 一个名为test.key ; 这两个名字都是我们在pod资源清单中指定的名称 ;

3.2 通过资源清单创建secret

示例:使用资源清单创建secret资源

root@k8s-master01:/opt/k8s-data/yaml/secret# cat test-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: test-secret-demo
  namespace: default
data:
  name: cWl1aG9tCg==
  passwd: YWRtaW4xMjMuY29tCg==
type: Opaque

使用资源清单方式创建secret时 , data字段是定义对应的kv配置信息 , 需要事先将其对应的值转换为base64编码 ; type是用来指定对应secret的类型 , 这个字段有四个值 , 分别是Opaque 、kubernetes.io/dockerconfigjson、kubernetes.io/tls、kubernetes.io/service-account-token ;

应用资源清单

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl apply -f test-secret.yaml
secret/test-secret-demo created
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get secret
NAME               TYPE                             DATA   AGE
harbor.cbear.top   kubernetes.io/dockerconfigjson   1      120m
mysql-auth         Opaque                           2      70m
test-secret-demo   Opaque                           2      11s
test-tls           kubernetes.io/tls                2      25m

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl describe secret  test-secret-demo
Name:         test-secret-demo
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
name:    7 bytes
passwd:  13 bytes

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get  secret  test-secret-demo -o yaml
apiVersion: v1
data:
  name: cWl1aG9tCg==
  passwd: YWRtaW4xMjMuY29tCg==
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"name":"cWl1aG9tCg==","passwd":"YWRtaW4xMjMuY29tCg=="},"kind":"Secret","metadata":{"annotations":{},"name":"test-secret-demo","namespace":"default"},"type":"Opaque"}
  creationTimestamp: "2024-06-04T09:51:33Z"
  name: test-secret-demo
  namespace: default
  resourceVersion: "1609434"
  uid: 689862c3-6992-4e2f-b3eb-c3b451c86243
type: Opaque

示例 : 使用stringData字段来指定数据

root@k8s-master01:/opt/k8s-data/yaml/secret# cat test1-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: test-secret-demo1
  namespace: default
stringData:
  name: qiuhom
  passwd: admin123.com
type: Opaque

使用stringData字段来指定kv配置信息 , 可以不用将对应数据编码为base64格式 ; 它会在创建secret时 , 自动将其转化为base64编码格式 , 存放在data字段中 ;

应用配置清单

root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl apply -f test1-secret.yaml 
secret/test-secret-demo1 created
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get secret 
NAME                TYPE                             DATA   AGE
harbor.cbear.top    kubernetes.io/dockerconfigjson   1      128m
mysql-auth          Opaque                           2      78m
test-secret-demo    Opaque                           2      7m46s
test-secret-demo1   Opaque                           2      11s
test-tls            kubernetes.io/tls                2      33m
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get secret test1-secret.yaml
Error from server (NotFound): secrets "test1-secret.yaml" not found
root@k8s-master01:/opt/k8s-data/yaml/secret# cat test1-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: test-secret-demo1
  namespace: default
stringData:
  name: qiuhom
  passwd: admin123.com
type: Opaque
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl get secret test-secret-demo1 -o yaml
apiVersion: v1
data:
  name: cWl1aG9t
  passwd: YWRtaW4xMjMuY29t
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"test-secret-demo1","namespace":"default"},"stringData":{"name":"qiuhom","passwd":"admin123.com"},"type":"Opaque"}
  creationTimestamp: "2024-06-04T09:59:08Z"
  name: test-secret-demo1
  namespace: default
  resourceVersion: "1610465"
  uid: a20e0175-3ea6-4d0c-b3c0-027fc1cd1b39
type: Opaque
root@k8s-master01:/opt/k8s-data/yaml/secret# kubectl describe secret test-secret-demo1 
Name:         test-secret-demo1
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
name:    6 bytes
passwd:  12 bytes

stringData字段不会被apiserver输出,它将stringData字段信息以base64编码格式存储在data字段中给予显示 ; 但是将对应secret输出为yaml格式时,在对应的注解信息中能够看到对应stringData的信息 ;


参考链接

容器编排系统K8s之ConfigMap、Secret资源 - Linux-1874 - 博客园 (cnblogs.com)