ConfigMap是用来存储一些非安全的配置信息,如果涉及到一些安全相关的数据的话用ConfigMap就非常不妥了, 因为ConfigMap明文存储的,这个时候j就应该使用Secret
Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 ssh key。
敏感信息放在 secret 中比放在 Pod 的定义或者容器镜像中来说更加安全和灵活。
Pod 可以用两种方式使用 secret:
作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里。当 kubelet 为 pod 拉取镜像时使用(仓库认证信息)。Secret的类型:
Service Account:Kubernetes 自动创建包含访问 API 凭据的 secret,并自动修改pod 以使用此类型的 secret。Opaque:使用base64编码存储信息,可以通过base64 --decode解码获得原始数据,因此安全性弱。kubernetes.io/dockerconfigjson:用于存储docker registry的认证信息。运行在pod里的进程需要调用Kubernetes API以及非Kubernetes API的其它服务。Service Account它并不是给kubernetes集群的用户使用的,而是给pod里面的进程使用的,它为pod提供必要的身份认证,让它可以通过apiserver获取信息。
每个namespace下有一个名为default的默认的ServiceAccount对象: [root@server2 manifest]# kubectl get sa --all-namespaces NAMESPACE NAME SECRETS AGE default default 1 12d ingress-nginx default 1 29h ingress-nginx ingress-nginx 1 29h ingress-nginx ingress-nginx-admission 1 29h kube-node-lease default 1 12d kube-public default 1 12d kube-system attachdetach-controller 1 12d [root@server2 manifest]# kubectl describe sa default Name: default Namespace: default Labels: <none> Annotations: <none> Image pull secrets: <none> Mountable secrets: default-token-j7pl7 /可以挂载的secret Tokens: default-token-j7pl7 /token就是一个secret Events: <none> serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。对应的 secret 会自动挂载到Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。 # 进入pod中查看secret的挂载信息。 [root@server2 manifest]# kubectl exec my-nginx-7f45d597d5-n7jft -- ls /var/run/secrets/kubernetes.io/serviceaccount ca.crt namespace token /里面有证书,命名空间和token等信息。 ServiceAccount里有一个名为Tokens的可以作为Volume一样被Mount到Pod里的Secret,当Pod启动时这个Secret会被自动Mount到Pod的指定目录下,用来协助完成Pod中的进程访问API Server时的身份鉴权过程。 [root@server2 manifest]# kubectl describe pod my-nginx-7f45d597d5-n7jft Mounts: /etc/nginx/conf.d from config-volume (rw) /var/run/secrets/kubernetes.io/serviceaccount from default-token-j7pl7 (ro) //secret挂载到了这里 default-token-j7pl7: //secret 就是 sa 里面的一个token Type: Secret (a volume populated by a Secret) SecretName: default-token-j7pl7 Optional: false QoS Class: BestEffort Node-Selectors: <none>Opaque使用base64编码存储信息,其value为base64编码后的值。我们需要自行创建。
我们在做ingress的 basic-auth 其实就是一个opaque 类型的secret:
[root@server2 manifest]# kubectl get secrets NAME TYPE DATA AGE basic-auth Opaque 1 7h52m //这个 default-token-j7pl7 kubernetes.io/service-account-token 3 12d tls-secret kubernetes.io/tls 2 26h命令行创建secret:
[root@server2 ~]# kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password=S\!B\\*d\$zDsb secret/dev-db-secret created [root@server2 ~]# kubectl get secrets NAME TYPE DATA AGE dev-db-secret Opaque 2 2s注意如果密码具有特殊字符,则需要使用 \ 字符对其进行转义 在文件中创建secret:
[root@server2 ~]# echo -n 'admin' > ./username.txt [root@server2 ~]# echo -n 'westos' > ./password.txt [root@server2 ~]# kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt kubesecret/db-user-pass created [root@server2 ~]# kubectl get secrets NAME TYPE DATA AGE db-user-pass Opaque 2 4s默认情况下 kubectl get和kubectl describe 为了安全是不会显示密码的内容,可以通过以下方式查看:
[root@server2 ~]# kubectl get secrets dev-db-secret -o yaml apiVersion: v1 data: password: UyFCXCpkJHpEc2I= username: ZGV2dXNlcg== kind: Secret metadata: creationTimestamp: "2020-07-01T09:12:14Z" managedFields: - apiVersion: v1 fieldsType: FieldsV1 fieldsV1: f:data: .: {} f:password: {} f:username: {} f:type: {} manager: kubectl operation: Update time: "2020-07-01T09:12:14Z" name: dev-db-secret namespace: default resourceVersion: "478900" selfLink: /api/v1/namespaces/default/secrets/dev-db-secret uid: e08f8d85-c4ac-4e82-a177-ab70a0e55c1e type: Opaque [root@server2 ~]# echo UyFCXCpkJHpEc2I= |base64 -d S!B\*d$zDsb [root@server2 ~]# echo ZGV2dXNlcg== |base64 -d devuser //进行转换就出来了yaml清单secret
[root@server2 ~]# echo admin |base64 YWRtaW4K [root@server2 ~]# echo caoaoyuan |base64 Y2FvYW95dWFuCg== [root@server2 ~]# vim mysecret.yaml apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: Y2FvYW95dWFuCg== [root@server2 cm]# kubectl apply -f mysecret.yaml kubec gsecret/mysecret created [root@server2 cm]# kubectl get secrets NAME TYPE DATA AGE basic-auth Opaque 1 8h db-user-pass Opaque 2 10m default-token-j7pl7 kubernetes.io/service-account-token 3 12d dev-db-secret Opaque 2 9m10s mysecret Opaque 2 6s //这个将Secret挂载到Volume中:
[root@server2 cm]# vim mysecret.yaml apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: Y2FvYW95dWFuCg== --- apiVersion: v1 kind: Pod metadata: name: mysecret spec: containers: - name: nginx image: nginx volumeMounts: - name: secrets mountPath: "/secret" /挂接到这个位置,pod会自动创建 readOnly: true volumes: - name: secrets secret: secretName: mysecret [root@server2 cm]# kubectl apply -f mysecret.yaml secret/mysecret unchanged pod/mysecret created [root@server2 cm]# kubectl exec mysecret -- ls /secret password username [root@server2 cm]# kubectl exec mysecret -- cat /secret/password caoaoyuan [root@server2 cm]# kubectl exec mysecret -- cat /secret/username admin就挂接进去了。 向指定路径映射 secret 密钥:
[root@server2 cm]# vim mysecret.yaml apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: Y2FvYW95dWFuCg== --- apiVersion: v1 kind: Pod metadata: name: mysecret spec: containers: - name: nginx image: nginx volumeMounts: - name: secrets mountPath: "/secret" readOnly: true volumes: - name: secrets secret: secretName: mysecret items: - key: username /选择mysecret中的username这个key path: my-group/my-username /将它挂载道这个位置 [root@server2 cm]# kubectl apply -f mysecret.yaml secret/mysecret created pod/mysecret created [root@server2 cm]# kubectl exec mysecret -- ls /secret/ my-group [root@server2 cm]# kubectl exec mysecret -- ls /secret/my-group my-username [root@server2 cm]# kubectl exec mysecret -- cat /secret/my-group/my-username admin 可以看出值有指定的数据挂接到了这里。将Secret设置为环境变量:
[root@server2 cm]# vim mysecret.yaml apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: username: YWRtaW4= password: Y2FvYW95dWFuCg== --- apiVersion: v1 kind: Pod metadata: name: secret-env spec: containers: - name: nginx image: nginx env: - name: SECRET_USERNAME /自己定义名称 valueFrom: secretKeyRef: name: mysecret /调用secret的值 key: username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password [root@server2 cm]# kubectl apply -f mysecret.yaml secret/mysecret unchanged pod/secret-env created [root@server2 cm]# kubectl exec secret-env -- env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=secret-env SECRET_PASSWORD=caoaoyuan SECRET_USERNAME=admin KUBERNETES_SERVICE_PORT_HTTPS=443 HOME=/root环境变量读取Secret很方便,但是无法支撑Secret动态更新。
kubernetes.io/dockerconfigjson 类型的secret 用于存储 docker registry 的认证信息. 我们目前用的私有仓库是harbor仓库,我们现在有一个未公开的仓库,里面又一个镜像:
现在我们去拉取:
[root@server3 ~]# docker pull reg.caoaoyuan.org/caoaoyuan/game2048 Using default tag: latest Error response from daemon: pull access denied for reg.caoaoyuan.org/caoaoyuan/game2048, r是被拒绝的我们值有登陆进去才能拉取:
[root@server3 ~]# docker login reg.caoaoyuan.org Username: admin Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded [root@server3 ~]# docker pull reg.caoaoyuan.org/caoaoyuan/game2048 Using default tag: latest latest: Pulling from caoaoyuan/game2048 534e72e7cedc: Pull complete f62e2f6dfeef: Pull complete fe7db6293242: Pull complete 3f120f6a2bf8: Pull complete 4ba4e6930ea5: Pull complete Digest: sha256:8a34fb9cb168c420604b6e5d32ca6d412cb0d533a826b313b190535c03fe9390 Status: Downloaded newer image for reg.caoaoyuan.org/caoaoyuan/game2048:latest reg.caoaoyuan.org/caoaoyuan/game2048:latest而我们登陆的信息保存在用户主目录下的 .docker 下:
[root@server3 ~]# cd .docker/ [root@server3 .docker]# cat config.json { "auths": { "reg.caoaoyuan.org": { "auth": "YWRtaW46Y2FvYW95dWFu" } }, "HttpHeaders": { "User-Agent": "Docker-Client/19.03.11 (linux)" } [root@server3 .docker]# docker rmi reg.caoaoyuan.org/caoaoyuan/game2048:latest // 先删除镜像 [root@server3 .docker]# docker logout //退出 [root@server3 .docker]# cat config.json { "auths": {}, "HttpHeaders": { "User-Agent": "Docker-Client/19.03.11 (linux)" }这种方式是一种不安全且不够灵活的方式,我们可以通过kubernetes.io/dockerconfigjson 类型的secret 来实现简化
手动创建:
[root@server2 cm]# kubectl create secret docker-registry myregistrykey \ /secret 名称 --docker-server=reg.caoaoyuan.org \ /仓库地址 --docker-username=admin --docker-password=caoaoyuan \ /仓库的用户密码 --docker-email=413026125@qq.com /用户邮箱 secret/myregistrykey created [root@server2 cm]# kubectl get secrets NAME TYPE DATA AGE basic-auth Opaque 1 9h db-user-pass Opaque 2 98m default-token-j7pl7 kubernetes.io/service-account-token 3 13d dev-db-secret Opaque 2 97m myregistrykey kubernetes.io/dockerconfigjson 1 94s使用:
[root@server2 cm]# cat pod.yml apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: game2048 image: reg.caoaoyuan.org/caoaoyuan/game2048 imagePullSecrets: - name: myregistrykey secret/myregistrykey created [root@server2 cm]# kubectl apply -f pod.yml pod/mypod created [root@server2 cm]# kubectl get pod NAME READY STATUS RESTARTS AGE my-nginx-7f45d597d5-n7jft 1/1 Running 0 4h19m mypod 1/1 Running 0 9s /注意这时我们并没有docker login。