Secret 基本使用方法

介绍

Secret 是 Kubernetes 中的一种资源对象,用于存储敏感的配置数据,例如密码、密钥、证书等。与 ConfigMap 类似,Secret 也提供了一种将敏感数据与应用程序解耦的方式,使得应用程序可以更安全地部署和管理。

注意:
默认情况下,Kubernetes Secret 未加密地存储在 API 服务器的底层数据存储(etcd)中。 任何拥有 API 访问权限的人都可以检索或修改 Secret,任何有权访问 etcd 的人也可以。 此外,任何有权限在命名空间中创建 Pod 的人都可以使用该访问权限读取该命名空间中的任何 Secret; 这包括间接访问,例如创建 Deployment 的能力。

创建 Secret

Secret 大小限制:
每个 Secret 的尺寸最多为 1MiB。施加这一限制是为了避免用户创建非常大的 Secret, 进而导致 API 服务器和 kubelet 内存耗尽。不过创建很多小的 Secret 也可能耗尽内存。 可以使用资源配额来约束每个名字空间中 Secret(或其他资源)的个数。

使用原始数据创建

创建:

kubectl create secret generic db-user-pass --from-literal=username=admin --from-literal=password='S!B\*d$zDsb='

查看:

kubectl get secrets
NAME           TYPE     DATA   AGE
db-user-pass   Opaque   2      6s

查看yaml文件

kubectl get secrets db-user-pass -oyaml
apiVersion: v1
data:   # 下面这两个是加密过的账号和密码
  password: UyFCXCpkJHpEc2I9
  username: YWRtaW4=
kind: Secret
metadata:
  name: db-user-pass
type: Opaque

Secrets 解密

在 Kubernetes 中,Secret 中的数据被存储为 Base64 编码的形式,通过Base64 加密的内容也可以通过Base64 解密 例如:

echo 'YWRtaW4='|base64 -d

使用源文件创建

将凭据保存到文件:

echo -n 'admin' > ./username.txt
echo -n 'S!B\*d$zDsb=' > ./password.txt

使用文件创建

kubectl create secret generic db-user-pass \
    --from-file=username=./username.txt \
    --from-file=password=./password.txt

创建完成以后查看方法和上面的一样

创建 Secret 时提供未编码的数据

使用 stringData 字段。 这个字段可以将一个非 base64 编码的字符串直接放入 Secret 中, 当创建或更新该 Secret 时,此字段将被编码。

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
stringData:   # 下面的数据都是明文添加的,如果不使用这个字段是需要base64编码的
  config.yaml: |
    apiUrl: "https://my.api.com/api/v1"
    username: <user>
    password: <password>  

同时指定 data 和 stringData

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=      # 这个是 base64 编码过的
stringData:
  username: administrator # 这个是明文数据

修改 Secret

## 基本所有类型的资源都可以用这个方式去修改,除非设置禁止修改了
kubectl edit secrets db-user-pass
apiVersion: v1
data:
  password: UyFCXCpkJHpEc2I9
  username: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: "2024-04-07T08:42:14Z"
  name: db-user-pass
  namespace: default     # 不指定namespace 默认就是 default 
  resourceVersion: "7809921"
  uid: 1843c576-cea8-4bbe-a482-3cfd23f66d29
type: Opaque

Secret的类型

Secret 资源的 type 字段常用的类型:

内置类型用法
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启动引导令牌数据

通过为 Secret 对象的 type 字段设置一个非空的字符串值,你也可以定义并使用自己 Secret 类型(如果 type 值为空字符串,则被视为 Opaque 类型)。

例如使用 ServiceAccount 令牌 Secret

apiVersion: v1
kind: Secret
metadata:
  name: secret-sa-sample
  annotations:
    kubernetes.io/service-account.name: "sa-name"
type: kubernetes.io/service-account-token           # 需要修改为相应类型的字段
data:
  extra: YmFyCg==

Secret 具体应用

可选的 Secret

这个参数基本和ConfigMap里的一样

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret   # secret 文件的名字
      optional: true         # 如果 secret 不存在就忽略他

以挂载的方式使用 Secret

apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
spec:
  containers:
    - name: test-container
      image: nginx
      volumeMounts:
        
        - name: secret-volume            # name 必须与下面的卷名匹配
          mountPath: /etc/secret-volume
          readOnly: true                 # 以只读方式挂在 Secret
  # Secret 数据通过一个卷暴露给该 Pod 中的容器
  volumes:
    - name: secret-volume                # 名字一致
      secret:
        secretName: test-secret

subPath 使用方法

使用 Secret 挂载配置文件时,默认情况下会覆盖容器中已存在的文件。如果在容器中已经存在相同路径下的文件,为避免这种情况,可以通过设置 subPath 字段来指定挂载的文件。这样可以确保只有指定的文件会被挂载,而不会影响相同路径下的其他的文件。

例如:挂载 nginx 配置文件,这个和ConfigMap用法基本一样

apiVersion: v1
data:
  nginx.conf.bak: c2VydmVyIHsKICAgIGxpc3RlbiAgICAgICA4MDsKICAgIGxpc3RlbiAgWzo6XTo4MDsKICAgIHNlcnZlcl9uYW1lICBsb2NhbGhvc3Q7CgogICAgI2FjY2Vzc19sb2cgIC92YXIvbG9nL25naW54L2hvc3QuYWNjZXNzLmxvZyAgbWFpbjsKCiAgICBsb2NhdGlvbiAvIHsKICAgICAgICByb290ICAgL3Vzci9zaGFyZS9uZ2lueC9odG1sOwogICAgICAgIGluZGV4ICBpbmRleC5odG1sIGluZGV4Lmh0bTsKICAgIH0KCiAgICAjZXJyb3JfcGFnZSAgNDA0ICAgICAgICAgICAgICAvNDA0Lmh0bWw7CgogICAgIyByZWRpcmVjdCBzZXJ2ZXIgZXJyb3IgcGFnZXMgdG8gdGhlIHN0YXRpYyBwYWdlIC81MHguaHRtbAogICAgIwogICAgZXJyb3JfcGFnZSAgIDUwMCA1MDIgNTAzIDUwNCAgLzUweC5odG1sOwogICAgbG9jYXRpb24gPSAvNTB4Lmh0bWwgewogICAgICAgIHJvb3QgICAvdXNyL3NoYXJlL25naW54L2h0bWw7CiAgICB9CgogICAgIyBwcm94eSB0aGUgUEhQIHNjcmlwdHMgdG8gQXBhY2hlIGxpc3RlbmluZyBvbiAxMjcuMC4wLjE6ODAKICAgICMKICAgICNsb2NhdGlvbiB+IFwucGhwJCB7CiAgICAjICAgIHByb3h5X3Bhc3MgICBodHRwOi8vMTI3LjAuMC4xOwogICAgI30KCiAgICAjIHBhc3MgdGhlIFBIUCBzY3JpcHRzIHRvIEZhc3RDR0kgc2VydmVyIGxpc3RlbmluZyBvbiAxMjcuMC4wLjE6OTAwMAogICAgIwogICAgI2xvY2F0aW9uIH4gXC5waHAkIHsKICAgICMgICAgcm9vdCAgICAgICAgICAgaHRtbDsKICAgICMgICAgZmFzdGNnaV9wYXNzICAgMTI3LjAuMC4xOjkwMDA7CiAgICAjICAgIGZhc3RjZ2lfaW5kZXggIGluZGV4LnBocDsKICAgICMgICAgZmFzdGNnaV9wYXJhbSAgU0NSSVBUX0ZJTEVOQU1FICAvc2NyaXB0cyRmYXN0Y2dpX3NjcmlwdF9uYW1lOwogICAgIyAgICBpbmNsdWRlICAgICAgICBmYXN0Y2dpX3BhcmFtczsKICAgICN9CgogICAgIyBkZW55IGFjY2VzcyB0byAuaHRhY2Nlc3MgZmlsZXMsIGlmIEFwYWNoZSdzIGRvY3VtZW50IHJvb3QKICAgICMgY29uY3VycyB3aXRoIG5naW54J3Mgb25lCiAgICAjCiAgICAjbG9jYXRpb24gfiAvXC5odCB7CiAgICAjICAgIGRlbnkgIGFsbDsKICAgICN9CjEzMjI0MTIzNDEyMzQxMjQxMjUyNDUyNDUyMzQyMzQ1NjIzNDYyMzQ2MjM0MjQ1MTM0Cn0K
kind: Secret
metadata:
  name: nginx-config
type: Opaque
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        command: ["bash","-c","sleep 3600"]
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-config-volume
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf.bak
      volumes:
      - name: nginx-config-volume
        secret:
          secretName: nginx-config

注意: 对于以 subPath 形式挂载 Secret 卷的容器而言, 它们无法收到自动的 Secret 更新。

以环境变量的方式使用 Secret

如果容器已经使用了在环境变量中的 Secret,除非容器重新启动,否则容器将无法感知到 Secret 的更新。 有第三方解决方案可以在 Secret 改变时触发容器重启。

定义环境变量为 Secret 中的键值偶对:

kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'

在 Pod 规约中,将 Secret 中定义的值 backend-username 赋给 SECRET_USERNAME 环境变量。

apiVersion: v1
kind: Pod
metadata:
  name: env-single-secret
spec:
  containers:
  - name: envars-test-container
    image: nginx
    env:
    - name: SECRET_USERNAME
      valueFrom:
        secretKeyRef:
          name: backend-user
          key: backend-username

创建 Secret 访问私有镜像仓库

替换仓库进行身份验证的用户名、密码和客户端电子邮件地址,以及它的主机名即可。

kubectl create secret docker-registry secret-tiger-docker \
  --docker-email=tiger@acme.example \
  --docker-username=tiger \
  --docker-password=pass1234 \
  --docker-server=my-registry.example:5000

注意:Pod 只能引用位于自身所在名字空间中的 Secret,因此需要针对每个名字空间重复执行上述过程。

在Pod中使用上面创建的Secret

创建 Pod 时,可以在 Pod 定义中增加 imagePullSecrets 部分来引用该 Secret。imagePullSecrets 数组中的每一项只能引用同一名字空间中的 Secret。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx                # 填写私有镜像仓库的地址
  imagePullSecrets:
    - name: secret-tiger-docker   # Secret 名字要对应上

配置 imagePullSecrets 为自动挂载

kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "secret-tiger-docker"}]}'

配置好以后查看yaml文件

apiVersion: v1
kind: ServiceAccount
metadata:
  name: default
  namespace: default     # 这个根据需要更改
imagePullSecrets:
  - name: secret-tiger-docker

检查 imagePullSecrets 是否可以自动挂载

创建新 Pod 并使用默认 ServiceAccount 时, 新 Pod 的 spec.imagePullSecrets 会被自动设置。

kubectl run nginx --image=nginx --restart=Never
kubectl get pod nginx -o=jsonpath='{.spec.imagePullSecrets[0].name}{"\n"}'

使用 Secret 数据定义容器变量

定义环境变量为 Secret 中的键值偶对:

kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'

在 Pod 规约中,将 Secret 中定义的值 backend-username 赋给 SECRET_USERNAME 环境变量。

apiVersion: v1
kind: Pod
metadata:
  name: env-single-secret
spec:
  containers:
  - name: envars-test-container
    image: nginx
    env:
    - name: SECRET_USERNAME
      valueFrom:
        secretKeyRef:
          name: backend-user
          key: backend-username

也可以使用多个 Secret 的数据定义环境变量:

kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
kubectl create secret generic db-user --from-literal=db-username='db-admin'

在Pod 中使用

apiVersion: v1
kind: Pod
metadata:
  name: envvars-multiple-secrets
spec:
  containers:
  - name: envars-test-container
    image: nginx
    env:
    - name: BACKEND_USERNAME
      valueFrom:
        secretKeyRef:
          name: backend-user
          key: backend-username
    - name: DB_USERNAME
      valueFrom:
        secretKeyRef:
          name: db-user
          key: db-username

将 Secret 中的所有键值对定义为环境变量

创建包含多个键值偶对的 Secret:

kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'

使用 envFrom 来将 Secret 中的所有数据定义为环境变量。

apiVersion: v1
kind: Pod
metadata:
  name: envfrom-secret
spec:
  containers:
  - name: envars-test-container
    image: nginx
    envFrom:
    - secretRef:
        name: test-secret

不可修改Secret

你可以通过将 Secret 的 immutable 字段设置为 true 创建不可更改的 Secret。 例如:

apiVersion: v1
kind: Secret
metadata:
  ...
data:
  ...
immutable: true

Secret 设置 POSIX 权限

Secret 被挂载在 /etc/foo 目录下;所有由 Secret 卷挂载创建的文件的访问许可都是 0400,如果不指定任何权限,默认情况下使用 0644。

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      defaultMode: 0400
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值