Secret是什么?
在Kubernetes中,Secret是一种用于存储敏感信息的资源对象。它主要用于保存密码、API令牌、密钥和其他敏感数据,以供容器、Pod或集群中的其他资源使用。
Secret有以下特点:
安全存储:Secret对象被用于安全地存储敏感信息,这些信息通常不适合以明文形式出现在Pod的配置文件或环境变量中。
多种类型:Kubernetes支持不同类型的Secret,包括:
- Opaque:用于存储任意二进制数据,通常用于存储密码、证书等。
- Docker-registry:用于存储Docker镜像仓库的凭据。
- Service account token:用于自动创建与Service Account关联的Secret。
与Volume和环境变量结合使用:Secret可以将敏感信息挂载为Volume,以便Pod中的容器可以访问这些信息。也可以将Secret的内容注入到Pod的环境变量中。
自动编码/解码:Secret对象会对存储的数据进行Base64编码,但并不提供加密功能。因此,它并不是用于加密数据的最佳选择,而是用于基本的敏感信息存储。
不可修改:一旦创建,Secret对象的内容不能被修改。如果需要更新Secret,通常需要创建一个新的Secret,并重新部署使用它的Pod。
Secret是用于维护Kubernetes集群中应用程序的安全性和可配置性的关键工具之一。通过使用Secret,可以将敏感信息集中存储、管理和分发给需要访问这些信息的Pod和容器,同时避免了在配置文件或环境变量中硬编码敏感数据的风险。
使用 Secret 安全地分发凭证
参考文档:使用 Secret 安全地分发凭证 | Kubernetes
实验拓扑图:
 
1、创建 Secret:secret.yaml(这里是一个配置文件,可以用来创建存有用户名和密码的 Secret:)
apiVersion: v1
kind: Secret
metadata:name: test-secret
data:username: bXktYXBwpassword: Mzk1MjgkdmRnN0pi2、运行secret.yaml从而创建Pod
[root@master secrect]# kubectl apply -f secret.yaml
secret/test-secret created
3、查看 Secret 相关信息:
[root@master secrect]# kubectl get secret test-secret
NAME          TYPE     DATA   AGE
test-secret   Opaque   2      30s
[root@master secrect]# 
查看 Secret 相关的更多详细信息:
kubectl describe secret test-secret输出:
[root@master secrect]# kubectl describe secret test-secret
Name:         test-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>Type:  OpaqueData
====
password:  12 bytes
username:  6 bytes
[root@master secrect]# 
4、直接用 kubectl 创建 Secret(可以将之前的第一步和第二部浓缩在一起,十分常用)
使用 kubectl create secret 命令直接创建 Secret。例如:
kubectl create secret generic test-secret --from-literal='username=my-app' --from-literal='password=39528$vdg7Jb'代码解释:
这段`kubectl`命令用于在Kubernetes中创建一个叫做`test-secret`的通用(generic)Secret对象,该对象包含两个键值对。以下是命令的解释:- `kubectl create secret generic test-secret`:这部分指定了要创建一个名为`test-secret`的通用Secret对象。通用Secret是一种存储敏感信息的Secret类型,它可以包含多个键值对。- `--from-literal='username=my-app'`:这是一个标志,表示从文本字面值创建Secret中的一个键值对。在这里,我们创建了一个键值对,键是`username`,值是`my-app`。这意味着在`test-secret` Secret对象中将包含一个名为`username`的键,其值为`my-app`。- `--from-literal='password=39528$vdg7Jb'`:类似地,这也是一个标志,用于从文本字面值创建Secret中的另一个键值对。在这里,我们创建了一个键值对,键是`password`,值是`39528$vdg7Jb`。这将在`test-secret` Secret对象中包含一个名为`password`的键,其值为`39528$vdg7Jb`。总之,这个命令创建了一个通用的Secret对象`test-secret`,其中包含两个键值对,分别是`username`和`password`,用于存储应用程序或服务所需的敏感信息。这个Secret对象可以在Kubernetes中的Pod中挂载为Volume或注入到Pod的环境变量中,以供应用程序使用。5、创建一个可以通过卷访问 Secret 数据的 Pod(创建secret-pod.yaml 文件)
[root@master secrect]# cat secret-pod.yaml 
apiVersion: v1
kind: Pod
metadata:name: secret-test-pod
spec:containers:- name: test-containerimage: nginxvolumeMounts:# name 必须与下面的卷名匹配- name: secret-volumemountPath: /etc/secret-volumereadOnly: true# Secret 数据通过一个卷暴露给该 Pod 中的容器volumes:- name: secret-volumesecret:secretName: test-secret
[root@master secrect]# 
代码详解:
这个YAML文件描述了一个Kubernetes Pod,名为`secret-test-pod`,该Pod使用了一个Secret来挂载敏感数据到容器中。以下是代码的详细解释:- `apiVersion: v1` 和 `kind: Pod`:这两行指定了创建一个Pod资源。- `metadata`:这个部分包含了Pod的元数据,其中`name`字段指定了Pod的名称为`secret-test-pod`。- `spec`:这是Pod的规格部分,包含了容器和卷的配置。- `containers`:这个列表包含了Pod中运行的容器的配置。在这里,有一个名为`test-container`的容器,它使用了`nginx`镜像。- `volumeMounts`:这个字段指定了要挂载到容器中的卷的配置。在这里,我们有一个名为`secret-volume`的卷,它被挂载到容器的`/etc/secret-volume`路径下,并设置为只读。- `volumes`:这个字段定义了Pod中的卷。在这里,我们定义了一个名为`secret-volume`的卷,它使用了一个Secret来提供数据。- `secret`:在`volumes`下的`secret`字段指定了卷的类型是Secret,并且使用了一个叫做`test-secret`的Secret。这意味着Pod中的容器将能够访问`test-secret`中的敏感数据,并且该数据将被挂载到容器的`/etc/secret-volume`路径下。总之,这个YAML文件描述了一个Pod,该Pod包含一个运行`nginx`容器,并且通过一个名为`secret-volume`的卷将一个Secret对象`test-secret`中的数据挂载到容器内部。这使得容器能够访问`test-secret`中的敏感信息,而且这些信息只能以只读方式被容器访问。6、运行secret-pod.yaml 文件创建 Pod:
[root@master secrect]# kubectl apply -f secret-pod.yaml 
pod/secret-test-pod created
[root@master secrect]# 
确认 Pod 正在运行:
[root@master secrect]# kubectl get pod -o wide
NAME                                READY   STATUS              RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
redis                               1/1     Running             0          80m     10.244.1.18   node1   <none>           <none>
secret-test-pod                     1/1     Running             0          2m14s   10.244.1.19   node1   <none>           <none>
test                                1/1     Running             0          29h     10.244.2.7    node2   <none>           <none>
[root@master secrect]# 
7、进入secret-test-pod这个Pod 中的运行的容器:
[root@master secrect]# kubectl exec -i -t secret-test-pod -- /bin/bash
root@secret-test-pod:/# 
8、查看卷所在地:(Secret 数据通过挂载在 /etc/secret-volume 目录下的卷暴露在容器中。)
 
root@secret-test-pod:/# cd /etc/secret-volume/
root@secret-test-pod:/etc/secret-volume# ls
password  username
root@secret-test-pod:/etc/secret-volume# 
9、在 Shell 中,显示 username 和 password 文件的内容:
root@secret-test-pod:/etc/secret-volume# echo "$(cat password)" 
39528$vdg7Jb
root@secret-test-pod:/etc/secret-volume# echo "$(cat username)"
my-app
root@secret-test-pod:/etc/secret-volume# 
最后实验证明我们使用Secret将我们的用户名和密码都通过卷挂载到了secret-test-pod这个容器上,说明了Secret和Configmap都具有相似的功能:(Secret可以将敏感信息挂载为Volume,以便Pod中的容器可以访问这些信息)
案例:使用Secret + Configmap + nginx服务,实现nginx的HTTPS的功能
实验思想:
通过启动nginx的pod,使用configmap投射nginx.conf配置文件到pod里面
使用secret然后投射SSL证书(https证书)到Pod里,让pod支持https协议的访问
1、准备SSL证书(用于验证HTTPS协议)和 nginx.conf配置文件
nginx.conf文件
# claylpf test
user  nginx;
worker_processes  auto;error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;events {worker_connections  1024;
}http {include       /etc/nginx/mime.types;default_type  application/octet-stream;log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  /var/log/nginx/access.log  main;sendfile        on;#tcp_nopush     on;keepalive_timeout  65;#gzip  on;include /etc/nginx/conf.d/*.conf;
}2、使用configmap投射nginx.conf配置文件到pod里的nginx容器里去
2.1、将nginx.conf的内容投射到configmap上去
[root@master nginx]#  kubectl create configmap sc-nginx-1 --from-file=nginx.conf
configmap/sc-nginx-1 created
查看详细内容:
[root@master nginx]# kubectl get cm
NAME                   DATA   AGE
example-redis-config   1      9h
kube-root-ca.crt       1      41h
sc-nginx-1             1      56s
[root@master nginx]# 
3、配置nginx_secret.yaml
[root@master nginx]# cat nginx_secret.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: sanchuang-nginx
spec:replicas: 3selector:matchLabels:app: sanchuang-nginxtemplate:metadata:labels:app: sanchuang-nginxspec:containers:- name: nginximage: "nginx:latest"imagePullPolicy: IfNotPresentports:- containerPort: 80volumeMounts:- name: sanchuang-nginx-configmountPath: /etc/nginx/nginx.confsubPath: nginx.confvolumes:- name: sanchuang-nginx-configconfigMap:name: sc-nginx-1items:- key: nginx.confpath: nginx.conf              创建Pod启动secret
[root@master nginx]# kubectl get pod -o wide
NAME                                READY   STATUS              RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
sanchuang-nginx-77cdd449c-fs6s6     1/1     Running             0          2m39s   10.244.3.11   node3   <none>           <none>
sanchuang-nginx-77cdd449c-ht2hr     1/1     Running             0          2m39s   10.244.1.20   node1   <none>           <none>
sanchuang-nginx-77cdd449c-zxx2c     1/1     Running             0          2m39s   10.244.2.10   node2   <none>           <none>
secret-test-pod                     1/1     Running             0          9h      10.244.1.19   node1   <none>           <none>
test                                1/1     Running             0          38h     10.244.2.7    node2   <none>           <none>
[root@master nginx]# 
然后去查看容器里启动的nginx是否有4个worker进程
root@sanchuang-nginx-77cdd449c-fs6s6:/etc/nginx# cat nginx.conf 
worker_processes  4;
events {worker_connections  2048;
}
http {include       mime.types;default_type  application/octet-stream;sendfile        on;keepalive_timeout  65;server {listen  80;server_name localhost;location / {root   html;index  index.html index.htm;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}
}
root@sanchuang-nginx-77cdd449c-fs6s6:/etc/nginx# 
详细请看:(137条消息) 使用nginx搭建http和https环境_nginx搭建http服务器_Claylpf的博客-CSDN博客
将证书传给master


下载unzip进行解压
[root@master conf]# yum install unzip -y
解压:
[root@master conf]# unzip 9581058_claylpf.xyz_nginx.zip 
Archive:  9581058_claylpf.xyz_nginx.zip
Aliyun Certificate Downloadinflating: claylpf.xyz.pem         inflating: claylpf.xyz.key         
nginx.conf配置文件也需要提前上传到服务器之中
[root@master conf]# cat nginx.conf#user  nobody;
worker_processes  4;#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#pid        logs/nginx.pid;events {worker_connections  2048;
}#HTTP协议的配置
http {include       mime.types;default_type  application/octet-stream;#(定义访问日志的格式  日志保存在/usr/local/scnginx/logs/access.log文件中)log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  logs/access.log  main;   #--》日志保存的地址 sendfile        on;#tcp_nopush     on;#keepalive_timeout  0;keepalive_timeout  65;      #--》65秒后用户和web服务器建立的连接就会断开、 保持连接65秒的时间、 连接的超时时间#gzip  on; limit_conn_zone $binary_remote_addr  zone=addr:10m;    #创建一个连接区域(开辟了一个名叫addr的内存空间、像一个字典)limit_req_zone $binary_remote_addr  zone=one:10m rate=1r/s;    #创建一个连接区域(开辟了一个名叫one的内存空间、像一个字典)、每一秒产生1个可以访问的请求server {listen       80;server_name  www.claylpf.xyz;           #目的是直接从http协议跳转到https协议去return       301        https://www.claylpf.xyz;  #永久重定向}server {listen       80;server_name  www.feng.com;      #可以自己定义域名access_log  logs/feng.com.access.log  main;limit_rate_after 100k;  #下载速度达到100k每秒的时候、进行限制   limit_rate 10k;         #限制每秒10k的速度limit_req zone=one burst=5;  #同一时间同一ip最多5人同时访问 峰值是5 每一秒通过one的设定、产生一个空位 1r/s  location / {root   html/feng;index  index.html index.htm;}error_page  404              /404.html;   #无法找到error_page   500 502 503 504  /50x.html;  #一般是nginx内部出现问题才会出现的提示location = /50x.html {root   html;}location = /info {stub_status;    #返回你的nginx的状态统计信息    #access_log off; #在访问的时候不计入访问日志里面去     auth_basic      "sanchuang website";auth_basic_user_file htpasswd;#allow  172.20.10.2;    #允许172.20.10.2的ip地址访问#deny   all;            #拒绝所有用户访问}}}# HTTPS serverserver {listen       443 ssl;server_name  www.claylpf.xyz;     #证书上对应的域名ssl_certificate      claylpf.xyz.pem;   #自己在阿里云上申请的免费的CA证书ssl_certificate_key  claylpf.xyz.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   html;index  index.html index.htm;}}
}
[root@master conf]# 
2、根据nginx.conf的内容生成configmap(在存放nginx.conf目录下/usr/local/scnginx66/conf)
查看效果
[root@master conf]# kubectl get cm
NAME                   DATA   AGE
example-redis-config   1      8h
kube-root-ca.crt       1      40h
nginxconfigmap         1      3m10s
[root@master conf]# 
查看详细内容
[root@master conf]# kubectl describe cm nginxconfigmap
Name:         nginxconfigmap
Namespace:    default
Labels:       <none>
Annotations:  <none>Data
====
nginx.conf:
----#user  nobody;
worker_processes  4;#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#pid        logs/nginx.pid;events {worker_connections  2048;
}#HTTP协议的配置
http {include       mime.types;default_type  application/octet-stream;#(定义访问日志的格式  日志保存在/usr/local/scnginx/logs/access.log文件中)log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';access_log  logs/access.log  main;   #--》日志保存的地址 sendfile        on;#tcp_nopush     on;#keepalive_timeout  0;keepalive_timeout  65;      #--》65秒后用户和web服务器建立的连接就会断开、 保持连接65秒的时间、 连接的超时时间#gzip  on; limit_conn_zone $binary_remote_addr  zone=addr:10m;    #创建一个连接区域(开辟了一个名叫addr的内存空间、像一个字典)limit_req_zone $binary_remote_addr  zone=one:10m rate=1r/s;    #创建一个连接区域(开辟了一个名叫one的内存空间、像一个字典)、每一秒产生1个可以访问的请求server {listen       80;server_name  www.claylpf.xyz;           #目的是直接从http协议跳转到https协议去return       301        https://www.claylpf.xyz;  #永久重定向}server {listen       80;server_name  www.feng.com;      #可以自己定义域名access_log  logs/feng.com.access.log  main;limit_rate_after 100k;  #下载速度达到100k每秒的时候、进行限制   limit_rate 10k;         #限制每秒10k的速度limit_req zone=one burst=5;  #同一时间同一ip最多5人同时访问 峰值是5 每一秒通过one的设定、产生一个空位 1r/s  location / {root   html/feng;index  index.html index.htm;}error_page  404              /404.html;   #无法找到error_page   500 502 503 504  /50x.html;  #一般是nginx内部出现问题才会出现的提示location = /50x.html {root   html;}location = /info {stub_status;    #返回你的nginx的状态统计信息    #access_log off; #在访问的时候不计入访问日志里面去     auth_basic      "sanchuang website";auth_basic_user_file htpasswd;#allow  172.20.10.2;    #允许172.20.10.2的ip地址访问#deny   all;            #拒绝所有用户访问}}}# HTTPS serverserver {listen       443 ssl;server_name  www.claylpf.xyz;     #证书上对应的域名ssl_certificate      claylpf.xyz.pem;   #自己在阿里云上申请的免费的CA证书ssl_certificate_key  claylpf.xyz.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   html;index  index.html index.htm;}}
}BinaryData
====Events:  <none>
[root@master conf]# 
3、根据证书(文件)创建secret
[root@master conf]# kubectl create secret tls nginxsecret --key claylpf.xyz.key --cert claylpf.xyz.pem
secret/nginxsecret created
[root@master conf]# 
查看效果:
[root@master conf]# kubectl describe secret nginxsecret
Name:         nginxsecret
Namespace:    default
Labels:       <none>
Annotations:  <none>Type:  kubernetes.io/tlsData
====
tls.crt:  3818 bytes
tls.key:  1675 bytes
[root@master conf]# 
实验拓扑图:

创建svc_pod_secret_configmap.yaml