secret介绍
1、configmap都是明文存数据的,所以我们不能用它来访问,所以我们使用secret,但它比configmap要麻烦一点,只有敏感数据采用secrt来存放,比如你的私钥和证书,这个时候私钥和证书要放在secret中,其它内容应该放在configmap中,另外还有,比如我们连接mysql是我们打算把密码写在配置文件中,这个时候我们要把密码写成secret,而不能定义成configmap,所以他和configmap一样也是键值存储,只是它的值在看的时候不显示给你,或者就算显示给你的也是base64的编码格式,但除此之外我们secret还有一个特定就是它有多种类型。
a、generic(通用的):保存密码数据等用它就可以
b、tls:保存私钥和证书
c、docker-registry:保存docker-registry的认证信息,我们每一个node运行pod之前会把pod依赖的镜像要先检查本地有没有,如果没有就回去仓库服务器上拖,如果我们用的是私有仓库的话,必须要输入账号和密码才能访问,账号密码放哪儿呢?也就意味着当前node要自动去通过认证然后去拖镜像否则pod就会运行失败,也就意味着拉取的时候要现在节点上使用docker login然后docker pull。因此很多时候我们k8s节点要运行pod获取镜像,而若镜像若托管在在必须要认证才能获取到的私有镜像仓库中时,kubelet要能自动完成,因此拖镜像和认证是通过kubelet指挥着docker去做的,那我们怎么去提供这个私有数据呢。第一种方式是我们使用secret,使用我们pods.spec.imagePullSecrets字段,表示pod创建时,它如果要连到私有镜像仓库服务器,需要认证那么这里我们应该放个secret,这个secret包含了让我们kubelet或我们docker去链接私有仓库服务器时的账号和密码,这个账号密码就是由secret提供的,这个对象必须是专用的对象,就是我们这个docker-registry
创建一个generic类型的secret
kubectl create secret generic mysql-root-password --from-literal=password=MyP@ss123
获取secret信息:
kubectl get secret mysql-root-password -o yaml
反编译查看secret内容:
echo TXlQQHNzMTIz | base64 -d
pod应用secre两种方式
引用到env
apiVersion: v1 kind: Pod metadata: name: pod-secret-1 namespace: default labels: #也可以在此处写上{app:myapp,tier:frontend}代替下面两行 app: myapp #应用层级标签 tier: frontend #架构层级标签,在分层架构中属于frontend层 annotations: created-by: "cluster admin" spec: containers: #是一个列表,具体定义方式如下 - name: myapp image: ikubernetes/myapp:v1 ports: #不暴露端口其实也可以被访问,目的是为了说明启动的端口有哪些 - name: http #service 中可以通过名称来引用端口 containerPort: 80 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-root-password key: password
实际效果:
方式二:挂载为存储卷
apiVersion: v1 kind: Pod metadata: name: pod-secret-2 namespace: default labels: #也可以在此处写上{app:myapp,tier:frontend}代替下面两行 app: myapp #应用层级标签 tier: frontend #架构层级标签,在分层架构中属于frontend层 annotations: created-by: "cluster admin" spec: containers: #是一个列表,具体定义方式如下 - name: myapp image: ikubernetes/myapp:v1 ports: #不暴露端口其实也可以被访问,目的是为了说明启动的端口有哪些 - name: http #service 中可以通过名称来引用端口 containerPort: 80 volumeMounts: #在容器中使用pod定义的volumes - name: secretconfig mountPath: /tmp/ readOnly: true volumes: #在pod中定义volumes - name: secretconfig secret: secretName: mysql-root-password
效果如下:
向特性路径映射 secret 密钥
首先edit secret 增加一个key,value:
echo admin|base64 kubectl edit secret mysql-root-password kubectl get secret mysql-root-password -o yaml
效果如下:增加了一个username
我们还可以控制 Secret key 映射在 volume 中的路径。您可以使用 spec.volumes[].secret.items
字段修改每个 key 的目标路径:
apiVersion: v1 kind: Pod metadata: name: pod-secret-3 namespace: default labels: #也可以在此处写上{app:myapp,tier:frontend}代替下面两行 app: myapp #应用层级标签 tier: frontend #架构层级标签,在分层架构中属于frontend层 annotations: created-by: "cluster admin" spec: containers: #是一个列表,具体定义方式如下 - name: myapp image: ikubernetes/myapp:v1 ports: #不暴露端口其实也可以被访问,目的是为了说明启动的端口有哪些 - name: http #service 中可以通过名称来引用端口 containerPort: 80 volumeMounts: #在容器中使用pod定义的volumes - name: secretconfig mountPath: /tmp/ readOnly: true volumes: #在pod中定义volumes - name: secretconfig secret: secretName: mysql-root-password items: - key: password path: mypath/my-password
将会发生什么呢:
- password secret 存储在 /tmp/mypath/my-password 文件中而不是 /tmp/password 中。
username
secret 没有被映射
挂载的 secret 被自动更新
上面的测试,secret都是一个,现在对secret中password值进行更新,然后观察
echo MyP@ss1234 | base64
kubectl edit secret mysql-root-password
结果:
env方式: 未进行更新,应该是需要重启才会生效
方式二:挂载为存储卷 : 自动更新了,图贴错了,实验过,会更新
向特性路径映射 secret 密钥:自动更新了
重启第一个pod,看是否生效:
kubectl delete pod pod-secret-1 kubectl get pod kubectl apply -f pod-secret-1.yaml kubectl exec -it pod-secret-1 printenv| grep PASS
更新了
使用 imagePullSecret
用于拉去镜像时的认证
参考:https://blog.51cto.com/lvnian/2314456?source=dra
不做测试,只贴一个案例:
apiVersion: v1 kind: Pod metadata: name: foo namespace: awesomeapps spec: containers: - name: foo image: janedoe/awesomeapp:v1 imagePullSecrets: - name: myregistrykey
参考:
https://www.cnblogs.com/Presley-lpc/p/11044991.html
https://kubernetes.io/zh/docs/concepts/configuration/secret/