Kubernetes Secret存储敏感数据

Secret 存在意义


K8s configmap可以注入pod之内成为环境变量或者是配置文件,这些都是以明文方式保存,如果碰到密码这种的以明文方式保存就不行了,Secret更加倾向于保存要加密的文件。 

Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec中。Secret 可以以 Volume 或者环境变量的方式使用。密码这种可以先存储到secret里面,然后挂载到Pod里面即可。

Secret 有三种类型:

  • Service Account:用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的/run/secrets/kubernetes.io/serviceaccount目录中
  • Opaque:base64编码格式的Secret,用来存储密码、密钥等
  • kubernetes.io/dockerconfigjson:用来存储私有 docker registry 的认证信息

Service Account:对于有些pod来说需要和apiserver进行交互,比如flanned,coredns这些需要和api进行交互,kube api不是谁都可以过来访问的,因为它是一切访问的入口。所以pod的访问方式就是挂载Service Account

Opaque:这种方式就是加密的方式存储,加密程度并不高,很容易就进行解密

kubernetes.io/dockerconfigjson: 如果有私有仓库那么下载的时候需要认证,这些认证方案是由docker仓库去完成的,这个可以保存私有

 

Secret


与ConfigMap类似,区别在于Secret主要存储敏感数据,所有的数据要经过base64编码。

应用场景:凭据
kubectl create secret 支持三种数据类型:
  • docker-registry(kubernetes.io/dockerconfigjson):存储镜像仓库认证信息
  •  generic(Opaque):存储密码、密钥等
  • tls(kubernetes.io/tls):存储TLS证书
[root@k8s-master ~]# kubectl create secret --help
Create a secret using specified subcommand.

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

 

存储TLS证书场景


[root@k8s-master SSL]# kubectl create secret tls blog-ctnrs-com --cert=blog.ctnrs.com.pem --key=blog.ctnrs.com-key.pem
secret/blog-ctnrs-com created
 
[root@k8s-master SSL]# kubectl get secret
NAME                  TYPE                                  DATA   AGE
blog-ctnrs-com        kubernetes.io/tls                     2      34s
default-token-j9294   kubernetes.io/service-account-token   3      50d
 
[root@k8s-master SSL]# kubectl describe secret blog-ctnrs-com 
Name:         blog-ctnrs-com
Namespace:    default
Labels:       <none>
Annotations:  <none>
 
Type:  kubernetes.io/tls
 
Data
====
tls.crt:  1314 bytes
tls.key:  1675 bytes
[root@k8s-master ~]# cat ingress-https.yml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: blog
spec:
  tls:
  - hosts: 
    - blog.ctnrs.com #要和证书的域名对应上
    secretName: blog-ctnrs-com
  rules:
  - host: blog.ctnrs.com  #和域名证书里面的域名保持一致
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web1
            port:
              number: 80

 

存储镜像仓库认证信息场景


$ kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL

secret "myregistrykey" created.

在创建 Pod 的时候,通过imagePullSecrets来引用刚创建的 `myregistrykey`

apiVersion: v1
kind: Pod
metadata:  
  name: foo
spec:  
  containers:    
  - name: foo      
    image: centos:v1  
    imagePullSecrets:    
    - name: myregistrykey

 

存储密码、密钥等场景


[root@k8s-master ~]# cat secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: db-user-pass
type: Opaque                   #存储类型
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm


[root@k8s-master ~]# kubectl describe secret db-user-pass
Name:         db-user-pass
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  12 bytes
username:  5 bytes

数据这里也是使用了键值方式存储,可以以变量的方式去注入,也可以使用数据卷挂载在某个目录下面。和configmap不一样是变量的值来自于secretKeyRef:

这里变量存储了数据库名和密码供数据库使用,mysql可以通过该引用设置密码

[root@k8s-master ~]# cat secret-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: secret-demo-pod
spec:
  containers:
    - name: demo
      image: nginx 
      env:
        - name: USER
          valueFrom:
            secretKeyRef:
              name: db-user-pass 
              key: username
        - name: PASS 
          valueFrom:
            secretKeyRef:
              name: db-user-pass 
              key: password
      volumeMounts:
      - name: config
        mountPath: "/config"
        readOnly: true
  volumes:
    - name: config
      secret:
        secretName: db-user-pass 
        items:
        - key: username 
          path: my-username.config
[root@k8s-master ~]# kubectl exec -it secret-demo-pod -- bash
root@secret-demo-pod:/# ls /config/
my-username.config
root@secret-demo-pod:/# cat /config/my-username.config 
admin
root@secret-demo-pod:/# echo $USER
admin
root@secret-demo-pod:/# echo $PASS
1f2d1e2e67df

Configmap主要是应用于配置文件,存储一些kv值和具体配置文件内容,你都可以放在里面,也即是程序用到的配置文件首选configmap

Secret主要是用于存储敏感数据,也就是上面三种类型

 

Secret 与 SA 的关系


Service Account 用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod的/run/secrets/kubernetes.io/serviceaccount目录中 

Kubernetes 设计了一种资源对象叫做 Secret,分为两类,一种是用于 ServiceAccount 的 service-account-token,另一种是用于保存用户自定义保密信息的 Opaque。ServiceAccount 中用到包含三个部分:Token、ca.crt、namespace

  • token是使用 API Server 私钥签名的 JWT。用于访问API Server时,Server端认证
  • ca.crt,根证书。用于Client端验证API Server发送的证书
  • namespace, 标识这个service-account-token的作用域名空间

Json web token(JWT),是为了在网络应用环境间传递声明而执行的一种基于 Json 的开放标准((Rrc 7519】)该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(sso)场景。jwt的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声面明德患,该 token 也可直接被用于认证,也可被加密

默认情况下,每个 namespace 都会有一个 ServiceAccount,如果 Pod 在创建时没有指定 ServiceAccount,就会使用 Pod 所属的 namespace 的 ServiceAccount,默认挂载目录/run/secrets/kubernetes.io/serviceaccount

这个serviceaccount会生成一个token保存在secret里面,serviceaccount和secret是有关联的,用sercert保存token的 (Kubernetes 自身也有一些内置的 Secret,主要用来保存访问 APIServer 的 service account token)

[root@k8s-master ~]# kubectl get serviceaccount
NAME      SECRETS   AGE
default   1         65d

[root@k8s-master ~]# kubectl describe sa default
Name:                default
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   default-token-j9294
Tokens:              default-token-j9294
Events:              <none>

[root@k8s-master ~]#  kubectl  get secret default-token-j9294
NAME                  TYPE                                  DATA   AGE
default-token-j9294   kubernetes.io/service-account-token   3      65d

#这里保存的是token信息
[root@k8s-master ~]#  kubectl  describe secret default-token-j9294
Name:         default-token-j9294
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: 3b6f6ac8-fb89-42e0-9a45-d14680ee6157

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1066 bytes
namespace:  7 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6InR0cTRHNDNQUGFMeUZ5Rnp1azZnSUEyRVU0WEY1dWdEMEYwd056ZnNkWWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tajkyOTQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjNiNmY2YWM4LWZiODktNDJlMC05YTQ1LWQxNDY4MGVlNjE1NyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.cbHTMxahgVgImt2ll-cN4pJIbtN_gMks9Wg-Aqc3hvntktpmPFN0TRk9eT362HoYFpf6RB5pJvH4Xg-eACoZ9IfOcIqDK8ky14jk1z5TolgXrLv1OqacxI8PlRJBDvmjIEX8iLIxcFE63gJQpBoDscCOHMMs-i1cuygdRr2vEq47XX_ykxPg49pw1hRaG4DSLjfCTA7kAG3R-9NnhGCpexruryDd4ftqaKKf12BTmT8xgydcvNWzzkgnYMnoF-o8cfaLqd9c_-TOr3h1VGyoop925CCrTXqHxBU6VPEnSRozegIfDbLwbyhp4Wq3CTDyBAc4YSm8WbqRPyikNRa-ow


[root@k8s-master ~]# kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-wp9kx   1/1     Running   0          50m


#指定了sa,也就是k8s在创建pod的时候会将创建的sa会注入到pod当中,里面程序带着
[root@k8s-master ~]# kubectl exec -it nginx-6799fc88d8-wp9kx sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# cd /run/secrets/kubernetes.io/
# ls
serviceaccount
# cd serviceaccount
# ls
ca.crt	namespace  token
# cat token
eyJhbGciOiJSUzI1NiIsImtpZCI6InR0cTRHNDNQUGFMeUZ5Rnp1azZnSUEyRVU0WEY1dWdEMEYwd056ZnNkWWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tajkyOTQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjNiNmY2YWM4LWZiODktNDJlMC05YTQ1LWQxNDY4MGVlNjE1NyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.cbHTMxahgVgImt2ll-cN4pJIbtN_gMks9Wg-Aqc3hvntktpmPFN0TRk9eT362HoYFpf6RB5pJvH4Xg-eACoZ9IfOcIqDK8ky14jk1z5TolgXrLv1OqacxI8PlRJBDvmjIEX8iLIxcFE63gJQpBoDscCOHMMs-i1cuygdRr2vEq47XX_ykxPg49pw1hRaG4DSLjfCTA7kAG3R-9NnhGCpexruryDd4ftqaKKf12BTmT8xgydcvNWzzkgnYMnoF-o8cfaLqd9c_-TOr3h1VGyoop925CCrTXqHxBU6VPEnSRozegIfDbLwbyhp4Wq3CTDyBAc4YSm8WbqRPyikNRa-ow

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值