kubernets之secret资源
一 对于一些保密度比较高的文件,k8s又是如何存储的呢?
针对那些保密度比较高的配置文件,例如证书以及一些认证配置不能直接存储在configmap中,而是需要存储在另外一种资源中,需要对存储在里面的数据进行加密,并且只会调度到需要的pod上面,在pod上面所在的节点上,secret卷并不会存储在硬盘等设备上,而是需要存储在node上面的内存中,这样就不需要擦拭来提高保密性,同样的secrets和configmap类似,支持两种数据渲染到pod中的容器
- 通过将配置渲染到容器的环境变量中
- 通过将secerts暴露为卷中的文件
另外一点需要注意的是,对于主节点本身,secerts是按照明文的形式进行存储,这就需要保障主节点安全从而确保存储在secerts的数据安全性,同样需要保障的一点是禁止未被授权的用户访问主节点服务器,因为在没有确实授权之前,任何用户都可以通过pod拉去secerts数据并可能造成数据暴露因此是将数据存储到configmap或者secert是需要认真考虑的一件事情
- 采用configmap存储非敏感的数据文件
- 采用secerts存储敏感的数据文件
- 当存储的数据里面同时包含敏感数据或者非敏感数据,也得将数据存储在secerts中
二 secrets的相关应用和创建
2.1 来看一个pod中默认的令牌
[root@node01 ~]# k get secrets NAME TYPE DATA AGE default-token-tzwwt kubernetes.io/service-account-token 3 15d [root@node01 ~]# k describe secrets Name: default-token-tzwwt Namespace: default Labels: <none> Annotations: kubernetes.io/service-account.name: default kubernetes.io/service-account.uid: 61b7be2c-433e-11eb-90ae-5254002a5691 Type: kubernetes.io/service-account-token Data ==== namespace: 7 bytes token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tdHp3d3QiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjYxYjdiZTJjLTQzM2UtMTFlYi05MGFlLTUyNTQwMDJhNTY5MSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.zwEvc13whMJW7MaCcDpXkpLmQsi2qfih-OUiNAVt8gwqZ9KWmFOj7Qye_vtzeYhc1m3YyM6YkCTjCtKqTUX28P0Y50-_Pl_0fQKrm2BTb7fGIskRwB4egFiwMZmcgzqUr4CHuvINdb339mYp8eYqpf1Io51fFKmLRwE3U1zWLRFod_QP-eBxlSCq5O76BtPjkH0egWvEgScao5tYJLw-tFMdkhyeFpJCoVdjf4plxi5yFYdxP86kc0jjtW9x9Z6LBKVhTC18_cQawG24UgOAjwZW4TF4v5y25Me4G3itTTVx_IKx8M6ndK5MrerFGCZoppFeSJdFr_TFyuWgcznuTw ca.crt: 1025 bytes
- 系统中每个pod都会挂载一个secrets卷,存储的内容是可以直接于kubernets的api服务器进行通信的相关认证,这里也可以通过设置pod中的automountServiceAccountToken字段为false来关闭这种默认行为
- 通过describe命令可以看到更过的关于这个secrets的信息,可以发现这个secrets数据包含了ca.crt,token以及namespace等访问kubernets的api服务器的全部信息
- 再者通过describe pod可以看到该secrets挂载在pod上面的相关信息地址为/var/run/secrets/kubernetes.io/serviceaccount
2.2 查看该默认的secrets挂载pod中的位置
[root@node01 ~]# k exec test-for-all-env-from-configmap -- ls -Alrt /var/run/secrets/kubernetes.io/serviceaccount total 0 lrwxrwxrwx. 1 root root 12 Jan 4 13:51 token -> ..data/token lrwxrwxrwx. 1 root root 16 Jan 4 13:51 namespace -> ..data/namespace lrwxrwxrwx. 1 root root 13 Jan 4 13:51 ca.crt -> ..data/ca.crt lrwxrwxrwx. 1 root root 31 Jan 4 13:51 ..data -> ..2021_01_04_13_51_29.048076121 drwxr-xr-x. 2 root root 100 Jan 4 13:51 ..2021_01_04_13_51_29.048076121
- 可以看出secrets也是和configmap一样,通过创建data的软连接到指定的目录,然后data也是其中一个挂载的目录,通过对整个文件进行替换使得文件来更新
- 该文件夹下面包含了访问kubernetsapi服务器的所有的必要文件
2.3 创建一个secrets
[root@node01 Chapter07]# openssl genrsa -out https.key 2048 Generating RSA private key, 2048 bit long modulus [root@node01 Chapter07]# openssl req -new -x509 -key https.key -out https.cert -days 3650 -subj /CN=www.kubia-example.com [root@node01 Chapter07]# echo wxm-test>wxm-test [root@node01 Chapter07]# k create secret generic fortune-https --from-file=https.cert --from-file=https.key --from-file=wxm-test secret/fortune-https created [root@node01 Chapter07]# k get secret NAME TYPE DATA AGE default-token-tzwwt kubernetes.io/service-account-token 3 15d fortune-https Opaque 3 24s
- 我们首先使用openssl等相关命令创建了证书以及认证以及一个附加的文件
- 之后用这个三个文件创建了一个secret
- 至此secret创建完成,但是有点奇怪的是,type类型内容为opaque不知道什么意思?
2.4 对比configmap以及secret
2.4.1 通过yaml的形式查看刚才创建的secret
[root@node01 Chapter07]# k get secret fortune-https -o yaml apiVersion: v1 data: https.cert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFekNDQWZ1Z0F3SUJBZ0lKQU5jQk83ZW0wYk5pTUEwR0NTcUdTSWIzRFFFQkN3VUFNQ0F4SGpBY0JnTlYKQkFNTUZYZDNkeTVyZFdKcFlTMWxlR0Z0Y0d4bExtTnZiVEFlRncweU1UQXhNRFV3TkRBMk1EUmFGdzB6TVRBeApNRE13TkRBMk1EUmFNQ0F4SGpBY0JnTlZCQU1NRlhkM2R5NXJkV0pwWVMxbGVHRnRjR3hsTG1OdmJUQ0NBU0l3CkRRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFLdkNkUFFHRWlJaElwZ0ZDRkU2U21oZFJ5ODMKaldoRDZPZUtLcndNcms1cWMweWUrSmg5N3lqRHY4Q3NtbGFpZWJPZjZXTUN0L1Z2ajhPWVhsZUR2K2xFclNPVgo0Y0NnR3Qvd1B3SmJQSS9WcUhoR1ZPUGVHM0RTcFpGaUpPSWJOUTkyK1N5SWZyWUVUeDRYSGlNKzRQcWVVeGh2CmtqaGxUZXFqZ0wrOVJHQlFZa1ROZDBlUlJ1cnRGbkRUYnFZOFVSbmdieVVGVkVVcnM5ODB5OGtxK1pucmZIQ1cKS2Y2VjQwRUVxNlh0eXd0RElaQnlUMGJGZWlMbi9iTVF3Z1hFOEUwRzNvZmU3NFFUWjZicmFYNFNLVVovaUIxSgpiV1pQSkJVS3B3ZmdNN2Rlamo4ZGsvRW9WaXE3VnZqQTdxYTdGQkJqSURSZ2txKzNPSnQvNndCWmc0VUNBd0VBCkFhTlFNRTR3SFFZRFZSME9CQllFRkQ1Rld5VUtDZHA2SVpGaWlSQnpTclprbnpqVU1COEdBMVVkSXdRWU1CYUEKRkQ1Rld5VUtDZHA2SVpGaWlSQnpTclprbnpqVU1Bd0dBMVVkRXdRRk1BTUJBZjh3RFFZSktvWklodmNOQVFFTApCUUFEZ2dFQkFHV1pKQjZwcXZ6cmRzcDZya0dBbWVYUFpUN0tNZ3NqUktvWkdKcXhQYWw1Tnk3QXY2YlFyWEJUCnZDQ3ZtM1lUcU0vOE9RVU5WTlpUdE1kNjRiUEpBOUZwNVo4QXNHYXlFdFJ6Q3JyaDFSdzVraXdlZkhkZC9WcFQKaDNIUThnejBuclBhV1UzVEVQbzhZQ0Y5V251MUdrblZxQTFSZ2NtZExzNjROTEhQaTN6T0cvWmtJYVZzRWVVRgp6RFJyUCs3NlNIMTBMRFpoaEZGWm1HSVNDT25zYWcyTytGUGhnTWVKa1hTb2kvZ1NOdTdpVGpvVXF6dWwyc0tsCm1Tc3UvNUYwdEEyU2hYaVFrWkMzRjJXbTBZUnlUNzZOWmdXWnZTR1U2YmQ3a0o5WmNRSHAxZDRoMnNPVHdzSm8KbEp2TXVUN090emg4aFlpU283cUVhTXdkTTdGbkVGbz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= https.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBcThKMDlBWVNJaUVpbUFVSVVUcEthRjFITHplTmFFUG81NG9xdkF5dVRtcHpUSjc0Cm1IM3ZLTU8vd0t5YVZxSjVzNS9wWXdLMzlXK1B3NWhlVjRPLzZVU3RJNVhod0tBYTMvQS9BbHM4ajlXb2VFWlUKNDk0YmNOS2xrV0lrNGhzMUQzYjVMSWgrdGdSUEhoY2VJejdnK3A1VEdHK1NPR1ZONnFPQXY3MUVZRkJpUk0xMwpSNUZHNnUwV2NOTnVwanhSR2VCdkpRVlVSU3V6M3pUTHlTcjVtZXQ4Y0pZcC9wWGpRUVNycGUzTEMwTWhrSEpQClJzVjZJdWY5c3hEQ0JjVHdUUWJlaDk3dmhCTm5wdXRwZmhJcFJuK0lIVWx0Wms4a0ZRcW5CK0F6dDE2T1B4MlQKOFNoV0tydFcrTUR1cHJzVUVHTWdOR0NTcjdjNG0zL3JBRm1EaFFJREFRQUJBb0lCQUZJSFRabVpLS0hhRjA1bwo0TjhDS3JVTEQwc1NpZHNveTV1QTFnWDNQR3ZBMVEzYndqZjV0UFZQLzAwQ1liZE1ZemtRL3dKRk14dnBTc3lNCkFVcGtab3YrTzM0S1A4V2g4UlBRQmhlWEFTWmtVTkFZTHNTZ3Q1UTdWYzFJQlB0aktRVVl1Y20xNm1YOVN0ZkIKREtpaWlBbkpBVUJqVUg3VWl0Q3JnM3FPNW8va0s2OHVZLzlDNWNpVHB2aXBGYjd1UUpITVJzak9lOTRNWGc1YQp6M0tsaVB2cldKT1AvUjFPeTl6T0dzNksxZDhoOXdiVWFxZTJoZmQ2b09wRU9Edlk1RC9XLzNJeDFDY2FSSnNsCk9KT1pvbWptMkZaUUFEaEFsZ0V6Tlc1UjVLcVp0dGNpN1pPZjZ4a1lnYUdTbzVnYVkvV0xRbms3YXJoMXF4V3gKT3FNWmRBVUNnWUVBMHN3TFlmZ25LY1QvRjM0cHhvUElwOVpvWjcwNHlwcktrakRLMHZWT01iQ2g5V3EwamQ2VgpMdTB4ak5rVGs5V1ZDeklXR1FRbEFZN2hzWEdLOEFhSUg0bUZqVXdMdHFLR1VSWXRKdEJoTTM0T3IvQXVxUW1RClR4RUZOTEwwYWVYWmJLUUtiYktHYjYveHlaUU5ZM2dSYlJHTm9QZzRuMmIrOXZBbytlOEplSU1DZ1lFQTBKZG4KcHgrSzY0L25WM3dqU1RUNlJ6UDRlRTFMMTFLTXJUaGwwWTQ5emlnTkw0UEZRVnU0T2pNQ2xsVmo2cmZpdWl5egpaL3I3NW9PMTRJTTFaZ2dIZGtGUXNKVytvL3JRS3Y1Y3B3ZStBNU9zdzF2ZzVTQkEvRFpKNnVGWXZrWUpsdU5mClZ6dS8wbTZ2ZEc0TVJSOGZWWE1aWWs4MHpObmpoUmh3WnBkdEJWY0NnWUFiclhqdEl5VVpRZWx3anpzeStvaTEKS056S2lqalR1V0ZSc3FCZTlLQ1F1NjE0U010dU9VU0RSZGVVczhmelNEN3FtbWYyWHVudysyNjgycml3YlZzZwpNUEZkTFJmNG9meGExenVVZGhYZEtmY0p1TktYbFU3aVlzeTVMNm9SNFlFYjE2b2EzeTd4cVR0cENVeDh1LzRsCndRRkVtbkxzMHh3MUZqRjdKNXlwdXdLQmdRQ1NOVjRaUGJuUlRjZjVnWEQyVW1VUDNiVFBGbGNQc2JRYmdzbVQKcm1GU0RLN1pYRUs2Z2tES3dwQ1FzWC9jdVZINTczVTljQ1o3T0YwVzVzRmFLRXlhcmtPUjB4U1N1aTZKeEV0TApaTmppaHZOMDZBVG1kY28zUHhKbXlkZTdYem8vZ2xhRXZjUENDNFYrVmRqUjVuTy9JSE50Zmxsak1XTVNHc1JHCmxPTjg5d0tCZ1FDMk5YTG9KeGk4OWt4aUg1Q05ENjJ5dzEwMGNvallsVEVvNVZoU1dMeFRqc1VzcUg1T0RGUTYKZ0NORVBRcHFJNWtNa1NsMUtHdVloSnY5L1ZyckpvMi9QalJ0RGMyaXdMdzFlaU5sQmZ1dDdXOHZWeHhrY21EaApNb21GRjdBUklqQ1VHc1ZnVmJWRElNZkE5VmpMSTNhTitGWGhsdVI1U1dtUWZydzloQ2Q4dWc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo= wxm-test: d3htLXRlc3QK kind: Secret metadata: creationTimestamp: "2021-01-05T04:08:43Z" name: fortune-https namespace: default resourceVersion: "2145910" selfLink: /api/v1/namespaces/default/secrets/fortune-https uid: b3435209-4f0b-11eb-ae9a-5254002a5691 type: Opaque
- 对比之前创建的configmap可以发现secret里面的数据都是通过采用base64格式编码
- 这么做的好处很明显,可以对数据起到很好的保护
- 但是对于开发者而言,就会多了一个编解码的步骤,但是不需要应用自己去编解码
2.4.2 StringData字段介绍
由于并非所有的敏感数据都是以二进制的,k8s允许Secret通过StringData设置纯文本值为条目,StringData是只写的而非只读,可以被设置为条目值,通过k get po -o yaml命令不会显示stringData字段,相反stringdata所有的条目会被Base64解析到data字段下
2.5 在pod中使用Secret
2.5.1 创建一个包含之前创建的emptyDir,configmap以及secret卷
[root@node01 Chapter07]# cat fortune-https.yml apiVersion: v1 kind: Pod metadata: name: fortune-https spec: containers: - image: luksa/fortune:env name: html-generator env: - name: INTERVAL valueFrom: configMapKeyRef: name: fortune-config key: sleep-interval volumeMounts: - name: html mountPath: /var/htdocs - image: nginx:alpine name: web-server volumeMounts: - name: html mountPath: /usr/share/nginx/html readOnly: true - name: config mountPath: /etc/nginx/conf.d readOnly: true - name: certs mountPath: /etc/nginx/certs/ readOnly: true ports: - containerPort: 80 - containerPort: 443 volumes: - name: html emptyDir: {} - name: config configMap: name: fortune-config items: - key: my-nginx-config.conf path: https.conf - name: certs secret: secretName: fortune-https
2.5.2 我们用一张更为直观的图来展示我们创建这个pod内部对应的关系
- 可以很直观的看出这个pod里面有2个容器web-server和html-generator
- web-server上面挂载了三个卷分别是emptyDir卷html这个卷同样也挂载html-genreator,作用也是很明显,用来接受html-generator产生的html文件,同时还挂载了config的configmap用来让容器里面nginx的应用来读取配置文件,也挂载了一个certs的secret卷,用来作为https的认证
- 这便是一种通过文件的形式将secret卷挂载到pod容器的方式下面我们来介绍与认识另一种将secret卷挂载到容器的方式
2.6 通过环境变量的形式secret的条目
2.6.1 通过环境变量的形式暴露secret的一个例子如下所示
env: - name:FOO_SECRET valurFrom: secretKeyRef: name: fortune-http key: foo
- secretKeyRef参数标志这该环境变量的值是通过secret的条目
- 渲染到环境变量往往会导致在出错的时候会转存环境变量,导致私密信息泄漏
- 另外子进程会继承父进程,你也无法知晓会拿这个私密文件来干嘛