应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名,密码或密钥,将这些信息直接保存在容器镜像中显然不妥,k8s提供的解决方案是 Serect。

        Serect 会以密文的方式存储数据,避免了直接再配置文件中把偶从你敏感信息。Serect会以Volume的形式被mount到Pod,容器可通过文件的方式使用Serect中的敏感数据;此外,容器也可以以环境变量的方式使用这些数据。

        Serect可通过命令行或YAML创建。

1. 创建Serect

(1)有四种方法创建 Serect ,这里我们选择yml的方式:

文件中的敏感数据必须是经过base64编码后的结果

zy@k8s-master:~$ echo -n zhangyin | base64
emhhbmd5aW4=

zy@k8s-master:~$ echo -n 123456 | base64
MTIzNDU2
apiVersion: v1
kind: Secret
metadata:
    name: myserect
data:
    username: emhhbmd5aW4=
    password: MTIzNDU2

(2)apply一下

zy@k8s-master:~$ kubectl apply -f mysecret.yml 
secret/myserect created

(3)查看secret

zy@k8s-master:~$ kubectl get secret myserect 
NAME       TYPE     DATA   AGE
myserect   Opaque   2      73s

(4)通过kubectl describe secret 查看条目key

zy@k8s-master:~$ kubectl describe secrets myserect 
Name:         myserect
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  6 bytes
username:  8 bytes

(5)kubectl edit secret myserect 查看value

apiVersion: v1
data:
  password: MTIzNDU2
  username: emhhbmd5aW4=
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"password":"MTIzNDU2","username":"emhhbmd5aW4="},"kind":"Secret","metadata":{"annotations":{},"name":"myserect","namespace":"default"}}
  creationTimestamp: "2023-03-19T08:53:26Z"
  name: myserect
  namespace: default
  resourceVersion: "381312"
  selfLink: /api/v1/namespaces/default/secrets/myserect
  uid: 25004a9d-415a-496e-a5d3-82ae73948caa
type: Opaque

2. 在Pod中使用Secret

pod可以通过volume或者环境变量的方式使用Secret。

(1)Volume方式

Pod的配置文件如下:

创建一个使用 BusyBox 镜像的 Pod,Pod 中包含一个名为 "mypod" 的容器,容器将执行 sleep 命令,并创建一个名为 "/tmp/healthy" 的文件。该文件将在 30000 秒后被删除。

此外,该文件还指定了一个名为 "foo" 的卷和一个名为 "mysecret" 的secret。在容器中,该卷将被装载到 "/etc/foo" 目录,并设置为只读模式。

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  volumes:                      #将volumes字段移动到这里
  - name: foo
    secret:
      secretName: myserect
  containers:
  - name: mypod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; touch /tmp/healthy; sleep 30000
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true

apply一下:

zy@k8s-master:~$ kubectl apply -f mypod.yml 
pod/mypod created

可以看到,k8s会在指定的路径 /etc/foo 下为每条敏感数据创建一个文件,文件名就是数据条目的Key,这里是 /etc/foo/username 和 /etc/foo/password, value则以明文存放在文件中。

zy@k8s-master:~$ kubectl exec -it mypod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # ls /etc/foo
password  username
/ # cat /etc/foo/username 
/ # cat /etc/foo/username 
zhangyin/ # 
/ # cat /etc/foo/password 
123456/ # 

以Volume方式使用的Secret支持动态更新,secret更新后,容器中的数据也会更新。

将password更新为 abcdef,base64编码为YWJjZGVm ,修改mysecret.yml:

apiVersion: v1
kind: Secret
metadata:
    name: myserect
data:
    username: emhhbmd5aW4=
    password: YWJjZGVm

重新apply一下密码文件:

zy@k8s-master:~$ kubectl apply -f mysecret.yml 
secret/myserect configured

几秒钟后就会同步过去,我们去对应文件夹查看:

/etc/foo # cat password 
abcdef/etc/foo # 

(2)环境变量方式

        通过Volume使用Secret,容器必须从文件中读取数据,稍嫌麻烦,k8s还支持通过环境变量使用Serect.

Pod 配置文件如下:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; touch /tmp/healthy; sleep 30000
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password

apply一下:

zy@k8s-master:~$ kubectl apply -f mypod-env.yml 
pod/mypod created

查看:

zy@k8s-master:~$ kubectl exec -it mypod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo $SECRET_USERNAME
zhangyin
/ # echo $SECRET_PASSWORD
abcdef

注意:虽然用环境变量查看更加方便,但不支持动态更新。

3. ConfigMap

        Serect可以为Pod提供密码、Token、私钥等敏感数据,对于一些非敏感数据,比如应用的配置信息,则可以用ConfigMap。

        ConfigMap的创建和使用方式与Serect非常类似,主要的不同是数据以明文的形式存放

        与secret一样,configMap也支持四种创建方式,这里以yml方式演示:

(1)Volume方式

zy@k8s-master:~$ cat configmap.yml 
apiVersion: v1
kind: ConfigMap
metadata:
    name: myconfigmap
data:
    config1: xxx
    config2: yyy
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  volumes:                      #将volumes字段移动到这里
  - name: foo
    configMap:
      name: myconfigmap
  containers:
  - name: mypod
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 10; touch /tmp/healthy; sleep 30000
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true

apply一下:

zy@k8s-master:~$ kubectl apply -f configmap.yml 
configmap/myconfigmap created
zy@k8s-master:~$ kubectl apply -f mypod-cfg.yml 
pod/mypod created

进入pod查看:

zy@k8s-master:~$ kubectl exec -it mypod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cd /etc/foo
/etc/foo # ls
config1  config2
/etc/foo # cat config1
xxx/etc/foo # 
/etc/foo # cat config2
yyy/etc/foo # 

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐