Kubernetes之secrets使用

和谦
2023-12-01

系列文章

1. mac上安装docker并运行kubernetes

2. Docker上部署并运行SpringBoot项目

3. 利用kubernetes部署docker的镜像文件

4. Kubernetes之secrets使用

背景

Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在 PodSpecification中或者container image中。 使用 Secret 意味着你不需要在应用程序代码中包含机密数据。

由于创建 Secret 可以独立于使用它们的 Pod, 因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。 Kubernetes 和在集群中运行的应用程序也可以对 Secret 采取额外的预防措施, 例如避免将机密数据写入非易失性存储。

Secret 类似于 ConfigMap 但专门用于保存机密数据。

1. 创建secret

1.1. 通过kubectl command 方式

一个 Secret 可以包含 Pod 访问数据库所需的用户凭证。 例如,由用户名和密码组成的数据库连接字符串。 你可以在本地计算机上,将用户名存储在文件 ./username.txt 中,将密码存储在文件 ./password.txt 中。

echo -n 'system' > ./username.txt
echo -n 'system123' > ./password.txt

在这些命令中,-n 标志确保生成的文件在文本末尾不包含额外的换行符。 这一点很重要,因为当 kubectl 读取文件并将内容编码为 base64 字符串时,多余的换行符也会被编码。

kubectl create secret 命令将这些文件打包成一个 Secret 并在 API 服务器上创建对象。

kubectl create secret generic testsecretbyfile \
  --from-file=./username.txt \
  --from-file=./password.txt

默认密钥名称是文件名。 你可以选择使用 --from-file=[key=]source 来设置密钥名称。例如:

kubectl create secret generic testsecretbyfile \
  --from-file=username=./username.txt \
  --from-file=password=./password.txt

1.2. 通过配置文件的方式

你可以先用 JSON 或 YAML 格式在一个清单文件中定义 Secret 对象,然后创建该对象。 Secret 资源包含 2 个键值对:data 和 stringData。 data 字段用来存储 base64 编码的任意数据。 提供 stringData 字段是为了方便,它允许 Secret 使用未编码的字符串。

$ echo -n "system" | base64
c3lzdGVt
$ echo -n "system123" | base64
c3lzdGVtMTIz

my_secret.yml, 

apiVersion: v1
kind: Secret
metadata:
  name: testsecret
type: Opaque
data:
  password: c3lzdGVtMTIz
  username: c3lzdGVt

通过下面命令创建

kubectl apply -f my_secret.yml

用stringData的方式

apiVersion: v1
kind: Secret
metadata:
  name: testsecret
type: Opaque
stringData:
  password: system123
  username: system

1.3. 通过kustomize方式

你可以在 kustomization.yaml 中定义 secreteGenerator 字段,并在定义中引用其它本地文件生成 Secret。 例如:下面的 kustomization 文件 引用了 ./username.txt 和 ./password.txt 文件:

secretGenerator:
- name: testsecret
  files:
  - username.txt
  - password.txt

你也可以在 kustomization.yaml 文件中指定一些字面量定义 secretGenerator 字段。 例如:下面的 kustomization.yaml 文件中包含了 username 和 password 两个字面量:

secretGenerator:
- name: testsecret
  literals:
  - username=system
  - password=system123

你也可以使用 .env 文件在 kustomization.yaml 中定义 secretGenerator。 例如:下面的 kustomization.yaml 文件从 .env.secret 文件获取数据。

secretGenerator:
- name: testsecret
  envs:
  - .env.secret

2. 验证 Secret

检查 secret 是否已创建:

kubectl get secrets

输出类似于:

NAME                  TYPE                                  DATA      AGE
testsecret            Opaque                                2         51s

你可以查看 Secret 的描述:

kubectl describe secrets/testsecret

3. 删除Secret

删除创建的 Secret:

kubectl delete secret testsecret

4. Opaque Secret的使用

创建好secret之后,有两种方式来使用它:

  • 以Volume方式
  • 以环境变量方式

4.1. 以Volume方式

加下面配置在spec.volumes和spec.containers.volumeMounts这两个标签里。

    spec:
      volumes:
        - name: secrets
          secret:
            secretName: testsecret
      containers:
        - name: test123
          image: test-demo1:v1.0
          volumeMounts:
            - name: secrets
              mountPath: /etc/secrets  
              readOnly: true

利用下面命令重新部署你的项目

#kubectl apply -f yourapp.yaml

进入你的pod , 注:test123-5595d9fdf9-bsdj6是我pod名字

#Kubectl exec -ti test123-5595d9fdf9-bsdj6 -- /bin/sh

在/etc/secrets/目录里查看password文件

root@test123-5595d9fdf9-bsdj6:/# cd etc/secrets/
root@test123-5595d9fdf9-bsdj6:/etc/secrets# cat password 
system123

注意:如果你重新编辑secret的password,每个pod里的password也会改变。

完整的yourapp.yaml文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test123
  labels:
    app: test123
spec:
  replicas: 1
  template:
    metadata:
      name: test123
      labels:
        app: test123
    spec:
      volumes:
        - name: secrets
          secret:
            secretName: testsecret
      containers:
        - name: test123
          image: test-demo1:v1.0
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: secrets
              mountPath: /etc/secrets  
              readOnly: true
          ports:
            - containerPort: 8080
          resources: 
            requests: 
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 250m
              memory: 256Mi
      restartPolicy: Always
  selector:
    matchLabels:
      app: test123
---
apiVersion: v1
kind: Service
metadata:
  name: test123-service
  labels:
    app: test123-service
spec:
  selector:
    app: test123
  ports:
    - port: 8087
      targetPort: 8089
      nodePort: 30082
  type: NodePort

4.2. 以环境变量方式

在Container的env里配置下面环境参数

    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: testsecret
            key: username
            optional: false # same as default; "mysecret" must exist
                            # and include a key named "username"
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: testsecret
            key: password
            optional: false # same as default; "mysecret" must exist
                            # and include a key named "password"

利用下面命令重新部署你的项目

#kubectl apply -f yourapp.yaml

进入你的pod , 注:test123-675b6f7c8-psh6w是我pod名字

#Kubectl exec -ti test123-675b6f7c8-psh6w -- /bin/sh

输出环境变量


root@test123-675b6f7c8-psh6w:/# echo SECRET_USERNAME
SECRET_USERNAME
root@test123-675b6f7c8-psh6w:/# echo $SECRET_PASSWORD
system123

完整的yaml 文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test123
  labels:
    app: test123
spec:
  replicas: 1
  template:
    metadata:
      name: test123
      labels:
        app: test123
    spec:
      containers:
        - name: test123
          image: test-demo1:v1.0
          env:
            - name: SECRET_USERNAME
              valueFrom:
                secretKeyRef:
                  name: testsecret
                  key: username
                  optional: false # same as default; "mysecret" must exist
                            # and include a key named "username"
            - name: SECRET_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: testsecret
                  key: password
                  optional: false # same as default; "mysecret" must exist
                            # and include a key named "password"
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
          resources: 
            requests: 
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 250m
              memory: 256Mi
      restartPolicy: Always
  selector:
    matchLabels:
      app: test123
---
apiVersion: v1
kind: Service
metadata:
  name: test123-service
  labels:
    app: test123-service
spec:
  selector:
    app: test123
  ports:
    - port: 8087
      targetPort: 8089
      nodePort: 30082
  type: NodePort

5. 所有的secret类型

Built-in TypeUsage
Opaquearbitrary user-defined data
kubernetes.io/service-account-tokenServiceAccount token
kubernetes.io/dockercfgserialized ~/.dockercfg file
kubernetes.io/dockerconfigjsonserialized ~/.docker/config.json file
kubernetes.io/basic-authcredentials for basic authentication
kubernetes.io/ssh-authcredentials for SSH authentication
kubernetes.io/tlsdata for a TLS client or server
bootstrap.kubernetes.io/tokenbootstrap token data

参考资料

Secrets | Kubernetes

 类似资料: