✨✨ 欢迎大家来到景天科技苑✨✨
🎈🎈 养成好习惯,先赞后看哦~🎈🎈
1.Secret概述
1.1 Secret是什么?
前面我们一起探讨了k8s的Configmap一般是用来存放明文数据的,如配置文件,
对于一些敏感数据,如密码、私钥等数据时,要用secret类型。
Secret解决了密码、token、秘钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。
Secret可以以Volume或者环境变量的方式使用。
要使用 secret,pod 需要引用 secret。Pod 可以用两种方式使用 secret:
作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里,
或者当 kubelet 为 pod 拉取镜像时使用。
secret可选参数有三种:
- generic: 通用类型,通常用于存储密码数据。
- tls:此类型仅用于存储私钥和证书。
- docker-registry: 若要保存docker仓库的认证信息的话,就必须使用此种类型来创建。
Secret类型有三种:
-
Service Account:用于被 serviceaccount 引用。
serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。
Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。 -
Opaque:base64编码格式的Secret,用来存储密码、秘钥等。可以通过base64 --decode解码获得原始数据,因此安全性弱
-
kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
1.2 使用Secret
1、通过环境变量引入Secret
#把mysql的root用户的password创建成secret
[root@master01 secret ]#kubectl create secret generic mysql-password --from-literal=password=Jxxxxxxx3x
secret/mysql-password created
[root@master01 secret ]#kubectl get secret
NAME TYPE DATA AGE
default-token-xc8dr kubernetes.io/service-account-token 3 12d
mysql-password Opaque 1 19s
nfs-provisioner-token-8mxt9 kubernetes.io/service-account-token 3 4d22h
[root@master01 secret ]#kubectl describe secret mysql-password
Name: mysql-password
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 14 bytes
#password的值是加密的,
#但secret的加密是一种伪加密,它仅仅是将数据做了base64的编码.
#创建pod,引用secret
[root@master01 secret ]#vim pod-secret.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-secret
labels:
app: myapp
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
env:
- name: MYSQL_ROOT_PASSWORD #它是Pod启动成功后,Pod中容器的环境变量名.
valueFrom:
secretKeyRef:
name: mysql-password #这是secret的对象名
key: password #它是secret中的key名
[root@master01 secret ]#kubectl apply -f pod-secret.yaml
pod/pod-secret created
[root@master01 secret ]#kubectl exec -it pod-secret -- /bin/sh
/ # printenv
MYAPP_SVC_PORT_80_TCP_ADDR=10.98.57.156
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://192.168.0.1:443
MYAPP_SVC_PORT_80_TCP_PORT=80
HOSTNAME=pod-secret
SHLVL=1
MYAPP_SVC_PORT_80_TCP_PROTO=tcp
HOME=/root
MYSQL_ROOT_PASSWORD=Jxxxxxxxx3x 这就是传递进来的变量
MYAPP_SVC_PORT_80_TCP=tcp://10.98.57.156:80
TERM=xterm
NGINX_VERSION=1.12.2
KUBERNETES_PORT_443_TCP_ADDR=192.168.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
MYAPP_SVC_SERVICE_HOST=10.98.57.156
KUBERNETES_PORT_443_TCP=tcp://192.168.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
KUBERNETES_SERVICE_HOST=192.168.0.1
MYAPP_SVC_SERVICE_PORT=80
MYAPP_SVC_PORT=tcp://10.98.57.156:80
传递到pod里面后,自动解密了
2、通过volume挂载Secret
1)创建Secret
手动加密,基于base64加密
[root@xianchaomaster1 ~]# echo -n 'admin' | base64
YWRtaW4=
echo -n 'jingtian123456f' | base64
解码:
echo amluZ3RpYW4xMjM0NTZm|base64 -d
2)创建yaml文件
[root@master01 secret ]#vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: amluZ3RpYW4xMjM0NTZm
[root@master01 secret ]#kubectl apply -f secret.yaml
secret/mysecret created
[root@master01 secret ]#
[root@master01 secret ]#kubectl get secret
NAME TYPE DATA AGE
default-token-xc8dr kubernetes.io/service-account-token 3 12d
mysecret Opaque 2 7s
mysql-password Opaque 1 14m
nfs-provisioner-token-8mxt9 kubernetes.io/service-account-token 3 4d23h
[root@master01 secret ]#kubectl describe secret mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 15 bytes
username: 5 bytes
3)将Secret挂载到Volume中
[root@master01 secret ]#vim pod_secret_volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-secret-volume
spec:
containers:
- name: myapp
image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
volumeMounts:
- name: secret-volume
mountPath: /etc/secret
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: mysecret
[root@master01 secret ]#kubectl apply -f pod_secret_volume.yaml
pod/pod-secret-volume created
[root@master01 secret ]#kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-pod 0/1 Completed 0 88m
mysql-pod-envfrom 0/1 Completed 0 76m
mysql-pod-volume 0/1 Completed 0 65m
nfs-provisioner-847fb5b8f5-lzvcf 1/1 Running 7 (6h38m ago) 3d7h
pod-pvc 1/1 Running 1 (7h38m ago) 3d5h
pod-secret 1/1 Running 0 11m
pod-secret-volume 1/1 Running 0 15s
test-hostpath 2/2 Running 6 (7h38m ago) 4d5h
test-nfs-volume 1/1 Running 3 (7h38m ago) 4d3h
web-0 1/1 Running 1 (7h38m ago) 2d22h
web-1 1/1 Running 1 (7h38m ago) 2d22h
web-2 1/1 Running 1 (7h38m ago) 2d22h
web-3 1/1 Running 1 (7h38m ago) 2d22h
进去容器查看
[root@master01 secret ]#kubectl exec -it pod-secret-volume -- /bin/sh
/ # ls /etc/secret/
password username
[root@master01 secret ]#kubectl exec -it pod-secret-volume -- /bin/sh
/ # cat /etc/sec
secret/ securetty
/ # cat /etc/secret/username
admin/ #
/ # cat /etc/secret/password
jingtian123456f/ #
#由上可见,以卷的方式挂载到pod ,在pod中的secret信息实际已经被解密。
Secret 的类型
创建 Secret 时,你可以使用 Secret 资源的 type 字段,或者与其等价的 kubectl 命令行参数(如果有的话)为其设置类型。
Secret 类型有助于对 Secret 数据进行编程处理。
Kubernetes 提供若干种内置的类型,用于一些常见的使用场景。
针对这些类型,Kubernetes 所执行的合法性检查操作以及对其所实施的限制各不相同。
内置类型 用法
Opaque 用户定义的任意数据
kubernetes.io/service-account-token 服务账号令牌
kubernetes.io/dockercfg ~/.dockercfg 文件的序列化形式
kubernetes.io/dockerconfigjson ~/.docker/config.json 文件的序列化形式
kubernetes.io/basic-auth 用于基本身份认证的凭据
kubernetes.io/ssh-auth 用于 SSH 身份认证的凭据
kubernetes.io/tls 用于 TLS 客户端或者服务器端的数据
bootstrap.kubernetes.io/token 启动引导令牌数据
docker私有仓库,加了https认证后拉取镜像:
imagePullSecret资源将Secret提供的密码传递给kubelet从而在拉取镜像前完成必要的认证过程,
简单说就是你的镜像仓库是私有的,每次拉取是需要认证的。
创建docker-registry类型的Secret对象,并在定义pod资源时明确通过"imagePullSecrets"字段来申明使用哪个私钥去认证;
创建docker-registry类型的Secret对象,然后把它添加到某个ServiceAccount对象中,
使用了这个ServiceAccount对象创建出来的pod就自然而然通过认证获取到镜像;
配置过程
这里创建Secret对象有两种方式,各有千秋。
方式一:通过命令行直接创建Secret
kubectl create secret docker-registry video-docker-redistry-key \
--docker-server=10.3.9.107:5000 \
--docker-username='gsafety' \
--docker-password='123456'
查看key
# kubectl get secret
NAME TYPE DATA AGE
default-token-d9phm kubernetes.io/service-account-token 3 19h
video-docker-redistry-key kubernetes.io/dockerconfigjson 1 2s
最后在yaml文件中使用这个创建出来的Secret:
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: awesomeapps
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: xxx-key
方式二:通过现存的docker认证文件来创建Secret,首先使用docker login 登录到某个仓库,会在本地保存认证信息
[root@master01 ~ ]#kubectl create secret generic harborsecret --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson
secret/harborsecret created
或者:
#Create a new secret named my-secret from ~/.docker/config.json
kubectl create secret docker-registry my-secret --from-file=.dockerconfigjson=path/to/.docker/config.json
[root@master01 ~ ]#kubectl create secret docker-registry my-secret --from-file=.dockerconfigjson=/root/.docker/config.json
secret/my-secret created
注意:config.json文件需要在主机上通过docker login 的方式登录后,才会生成。
这种方式有一个好处,就是如果有多个镜像仓库,都先存在于一个config.json文件中,然后通过命令打入Secret。
[root@master01 ~ ]#kubectl get secret harborsecret -oyaml
apiVersion: v1
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSJyZXBvc2l0b3J5Lmd1b2tpbmdoay5jb20iOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2VkdacGFHSXRjSEp2WkhWamRFQXlNREl5IgoJCX0KCX0KfQ==
kind: Secret
metadata:
creationTimestamp: "2022-11-07T05:52:41Z"
name: harborsecret
namespace: default
resourceVersion: "2355"
uid: 14503d3d-3992-4d31-9b1d-ff4049990d51
type: kubernetes.io/dockerconfigjson