K8s-day10-配置中心Configmap+Secret
文章目录
配置中心Condifmap+Secret
一、ConfigMap
能使一个配置文件多台机器共用,杜绝重复修改,支持热更新,且解决了应用挂载的问题!
- configMap是K8s中的标准组件,有两种方式实现给Pod传递配置参数:
- 挂载的方式:将环境变量直接定义在configMap中,当Pod启动时,通过env来引用configMap中定义的环境变量。
- 存储卷方式:将一个完整配置文件封装到configMap中,然后通过共享卷的方式挂载到Pod中,实现给应用传参。
了解:
- 修改configmap中的文件,可以同步到所有的挂载此configmap的容器中(仅仅同步到容器中),但是如果使用subPath参数,则热更新失效。
- configMap挂载会直接覆盖原来的目录,如果不覆盖则需要使用subPath参数(subPath参数只能够针对文件,同时不支持热更新)
1.创建configmap的三种方式
1)配置清单的方式
1> 编写配置清单
- 存储卷方式
cat > configmap.yaml <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
data:
default.conf: |
server {
listen 80;
listen [::]:80;
server_name _;
location / {
root /usr/share/nginx/html;
index index.html index.php;
}
location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
include fastcgi_params;
}
}
EOF
2> 部署测试
# 部署
[root@k8s-master1 ~]# kubectl apply -f configmap.yaml
configmap/nginx-config created
# 查看
[root@k8s-master1 ~]# kubectl get configmaps
NAME DATA AGE
nginx-config 1 2m49s
# 删除
[root@k8s-master1 ~]# kubectl delete -f configmap.yaml
configmap "nginx-config" deleted
2)部署目录的方式
# 删除
[root@k8s-master1 ~]# kubectl create configmap nginx-tls --from-file=./
# 查看
[root@k8s-master1 ~]# kubectl get configmaps
NAME DATA AGE
nginx-tls 12 7s
# 删除
[root@k8s-master1 ~]# kubectl delete configmaps nginx-tls
configmap "nginx-tls" deleted
3)部署文件的方式
- 需指定证书路径,若在当前路径可不指定
# 部署
[root@k8s-m-01 ~/zs/Nginx]# kubectl create configmap nginx-tls-crt --from-file=tls.crt
# 查看
[root@k8s-master1 ~]# kubectl get configmaps
NAME DATA AGE
kube-root-ca.crt 1 20d
# 删除
[root@k8s-master1 ~]# kubectl delete configmaps kube-root-ca.crt
configmap "kube-root-ca.crt" deleted
2.用configmap配置部署项目
- 配置discuz的配置文件到配置清单
- 下面使用挂载的方式,将配置文件挂载到容器中
cat condig-discuz.yaml <<EOF
# 配置discuz的配置文件到配置清单
kind: ConfigMap
apiVersion: v1
metadata:
namespace: discuz
name: discuz-configmap
data:
default.conf: |
server {
listen 80;
server_name linux.discuz.com;
root /opt/upload/;
location / {
index index.php;
}
location ~* \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include fastcgi_params;
}
}
---
# 使用挂载的方式,将配置文件挂载到容器中
kind: Deployment
apiVersion: apps/v1
metadata:
name: discuz
namespace: discuz
spec:
selector:
matchLabels:
app: discuz
deploy: discuz
template:
metadata:
labels:
app: discuz
deploy: discuz
spec:
containers:
- name: php
image: 18954354671/lnmp-php-discuz:v2 # 此时去准备构建discuz的镜像并上传,再往下写
livenessProbe: # 存活检测定义
tcpSocket: # tcpSocket连接端口
port: 9000
initialDelaySeconds: 30 # 数据库初始化启动时间,根据机器反应快慢定义
successThreshold: 1 # 探测数据库启动成功次数
failureThreshold: 3 # 探测数据库启动失败次数
timeoutSeconds: 1 # 本地连接探测超时时间,一秒足够长
periodSeconds: 2 # 执行探测频率,几秒一次,默认10秒
readinessProbe: # 就绪检测定义,同上
tcpSocket:
port: 9000
initialDelaySeconds: 30
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 1
periodSeconds: 2
- name: nginx
image: 18954354671/lnmp-nginx-discuz:v2
command: ["/bin/bash","-c","--"]
#args: ["while true;do sleep 30;done;"]
livenessProbe: # 存活检测定义
tcpSocket:
port: 80 # tcpSocket连接端口
initialDelaySeconds: 30 # 数据库初始化启动时间,根据机器反应快慢定义
successThreshold: 1 # 探测数据库启动成功次数
failureThreshold: 3 # 探测数据库启动失败次数
timeoutSeconds: 1 # 本地连接探测超时时间,一秒足够长
periodSeconds: 2 # 执行探测频率,几秒一次,默认10秒
readinessProbe: # 就绪检测定义,同上
tcpSocket:
port: 80
initialDelaySeconds: 30
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 1
periodSeconds: 2
volumeMounts:
- mountPath: /usr/share/nginx/html/upload
name: upload-data
- mountPath: /etc/nginx/conf.d
name: discuz-configmap
volumes: # 此时需要给Deployment创建pv(建议单独创建,不能随便修改且防止误删除:deployment-pv.yaml)
- name: upload-data # pv需指定为此discuz的命名空间
persistentVolumeClaim:
claimName: upload-data
- name: discuz-configmap
configMap:
name: discuz-configmap
items:
- key: default.conf
path: default.conf
---
# 部署discuz-Service
kind: Service
apiVersion: v1
metadata:
name: discuz-svc
namespace: discuz
spec:
ports:
- port: 80
targetPort: 80
name: http
selector:
app: discuz
deploy: discuz
clusterIP: None
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: discuz
namespace: discuz
spec:
rules:
- host: linux.discuz.com
http:
paths:
- backend:
serviceName: discuz-svc
servicePort: 80
EOF
4、Secret
Secret用来保存敏感数据,保存之前就必须将文件进行base64加密,挂载到pod中,自动解密。
Secret类型:
tls: 一般用来部署证书
Opaque : 一般用来部署密码
Service Account : 部署kubernetes API认证信息
kubernetes.io/dockerconfigjson : 部署容器仓库登录信息
apiVersion: v1
kind: Secret
metadata:
name: test
data:
name: b2xkYm95Cg==
二、secret
将密码转换为密文,写入配置清单中,起到加密的作用。
k8s secrets用于存储和管理一些敏感数据,比如密码、token、密钥等敏感信息;它把 Pod 想要访问的加密数据存放到 Etcd 中,然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变量的方式访问到这些 Secret 里保存的信息了。
-
Secret有三种类型:
- Opaque
- base64 编码格式的 Secret,用来存储密码、密钥等;但数据也可以通过base64 –decode解码得到原始数据,所以加密性很弱。
- Service Account
- 用来访问Kubernetes API,由Kubernetes自动创建;
- 并且会自动挂载到Pod的run/secrets/kubernetes.io/serviceaccount 目录中。
- kubernetes.io/dockerconfigjson
- 用来存储私有docker registry的认证信息。
- Opaque
-
Pod需要先引用才能使用某个secret,Pod有2种方式来使用secret:
- 作为volume的一个域,被一个或多个容器挂载;
- 在拉取镜像的时候被kubelet引用。
1.创建secret两种方式
1)基于参数创建
- 可将加密密码写入配置清单,对于不会解密的人来说相对安全
- 创建变量参数(进行base64解码)
1> 创建变量参数
-n:不换行输出,换行的话就不是123的加密字符了,会多一个换行
# 创建加密用户名、密码
[root@k8s-master1 ~]# echo -n "user" | base64
dXNlcg==
[root@k8s-master1 ~]# echo -n "pwd" | base64
cHdk
# 解密方式参考:
[root@k8s-master1 ~]# echo -n "dXNlcg==" | base64 -d
user
2> 创建yaml文件
- 将创建的用户名、密码调用至配置清单内
cat > secret.yaml <<EOF
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: cHdk
data:
username: cHdk
password: MTIzYWRtaW4=
EOF
3> 运行测试
# 运行
[root@k8s-master1 ~]# kubectl apply -f secret.yaml
secret/mysecret created
# 查看状态
[root@k8s-master1 ~]# kubectl get secrets mysecret
NAME TYPE DATA AGE
mysecret cHdk 2 12s
# 查看详情
[root@k8s-master1 ~]# kubectl describe secrets mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>
Type: cHdk
Data
====
password: 8 bytes
username: 3 bytes
# 删除
[root@k8s-master1 ~]# kubectl delete secrets mysecret
secret "mysecret" deleted
2)基于文件创建secret
1> 创建用户与密码文件
# 定义用户名、密码
[root@k8s-master1 ~]# echo -n 'zhangsan' > username.txt
[root@k8s-master1 ~]# echo -n '123admin' > password.txt
2> 运行测试
# 运行测试,此处不能用apply
[root@k8s-master1 ~]# kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret/db-user-pass created
# 查看状态
[root@k8s-master1 ~]# kubectl get secrets db-user-pass
NAME TYPE DATA AGE
db-user-pass Opaque 2 33s
# 查看详细信息
[root@k8s-master1 ~]# kubectl describe secrets db-user-pass
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password.txt: 8 bytes
username.txt: 8 bytes
# 删除
[root@k8s-master1 ~]# kubectl delete secrets db-user-pass
secret "db-user-pass" deleted
2.Secret应用到Pod中
- 以下两种方式均用一个密文生成的密码
1)通过变量的方式
- 调用流程:生成密文>>>secret清单调用生成的密文>>>Pod清单直接调用如下固定格式:
- SECRET_USERNAME
- SECRET_PASSWORD
- 默认调用这两个格式,在下面指定密文的变量名与变量密码,Pod会自己去找对应的值~
- 这样可以多一层防护,Pod也可以直接调用生成的密文,相比不够这样安全。
1> 生成密文
[root@k8s-master1 ~]# echo -n 'user' | base64
dXNlcg==
[root@k8s-master1 ~]# echo -n "pwd" | base64
cHdk
2> 定义secret清单
- 两个清单可以合并到一起,用三个减号隔开即可,Pod清单在下
cat > secret.yaml <<EOF
# 定义secret清单
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: dXNlcg== # SECRET_USERNAME的 key 填写 username
password: cHdk # SECRET_PASSWORD的 key 填写 password
---
# 定义Pod清单
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: nginx
image: nginx
env:
- name: SECRET_USERNAME # 定义用户名变量名,固定格式
valueFrom:
secretKeyRef:
name: mysecret
key: username # 指定用户名的变量名
- name: SECRET_PASSWORD # 定义密码变量名,固定格式
valueFrom:
secretKeyRef:
name: mysecret
key: password # 指定密码的变量名
EOF
3> 运行测试
# 创建Pod
[root@k8s-master1 ~]# kubectl apply -f secret.yaml
secret/mysecret created
pod/mypod created
# 查看secret状态
[root@k8s-master1 ~]# kubectl get secrets mysecret
NAME TYPE DATA AGE
mysecret Opaque 2 16s
# 查看Pod状态
[root@k8s-master1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mypod 1/1 Running 0 2m56s
# 查看详细信息
[root@k8s-master1 ~]# kubectl describe secrets mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 3 bytes
username: 4 bytes
4> 进入Pod查看密文
# 进入容器
[root@k8s-master1 ~]# kubectl exec -it mypod bash
# 解密验证成功,与当初定义一致
root@mypod:/# echo $SECRET_USERNAME
user
root@mypod:/# echo $SECRET_PASSWORD
pwd
2)通过挂载的方式
- 以volume的形式挂载到pod的某个目录下
1> 定义配置清单
cat > secret-pod.yaml <<EOF
# 先定义
kind: Secret
apiVersion: v1
metadata:
name: test
data:
username: dXNlcg== # 将定义的加密密码写到此处,pod起来后,密文推过去会自动解密
---
# 后调用
kind: Deployment
apiVersion: apps/v1
metadata:
name: mysecret
spec:
selector:
matchLabels:
app: mysecret
template:
metadata:
labels:
app: mysecret
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
# 容器被挂载目录
- mountPath: /usr/share/nginx/html
# 存储卷的名字
name: mysecret
volumes:
- name: mysecret
secret:
secretName: test
items:
# 调用密文变量名
- key: username
path: name
EOF
2> 运行测试
#运行Pod
[root@k8s-master1 ~]# kubectl apply -f secret-pod.yaml
secret/test unchanged
deployment.apps/mysecret created
# 查看运行状态
[root@k8s-master1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysecret-776998db65-rqhpn 1/1 Running 0 2m55s
3> 进入Pod查看密文
# 进入容器
[root@k8s-master1 ~]# kubectl exec -it mysecret-776998db65-rqhpn bash
# # 解密验证成功,与当初定义一致
root@mysecret-776998db65-rqhpn:/# cat /usr/share/nginx/html/name
user