一、Secret的资源配置
1.1 Secret配置的相关说明
Secret 是用来保存密码、token、密钥等敏感数据的 k8s 资源,这类数据虽然也可以存放在 Pod 或者镜像中,但是放在 Secret 中是为了更方便的控制如何使用数据,并减少暴露的风险。
有四种类型:
●kubernetes.io/service-account-token:由 Kubernetes 自动创建,用来访问 APIServer 的 Secret,Pod 会默认使用这个 Secret 与 APIServer 通信, 并且会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中;
●Opaque :base64 编码格式的 Secret,用来存储用户自定义的密码、密钥等,默认的 Secret 类型;
●kubernetes.io/dockerconfigjson :用来存储私有 docker registry 的认证信息。
●kubernetes.io/tls:用于存储TLS证书和私钥,通常用于Ingress控制器或其他需要TLS加密通信的服务。
Pod 需要先引用才能使用某个 secret,Pod 有 3 种方式来使用 secret:
●作为挂载到一个或多个容器上的卷 中的文件。
●作为容器的环境变量。
●由 kubelet 在为 Pod 拉取镜像时使用。
应用场景:凭据 Secret | Kubernetes
1.2 陈述式创建 Secret配置
Secret 的创建是根据文件中保存到相应信息 进行。例如我们要通过一个用户名文件和密码文件来创建具体的Secret资源配置。
#首先准备好相对应的用户和密码文件
#echo 中 “-n” 选项为不换行
echo -n 'limahua' > username.txt
echo -n 'qq666' > passwd.txt
用kubectl create secret命令创建Secret
kubectl create secret generic mysecret --from-file=username.txt --from-file=passwd.txt
kubectl describe secrets mysecret
1.3 声明式 + base64编码 创建Secret
echo limahua | base64
echo qq666 | base64
通过管道符base64 将明文进行转码
编写yaml文件
vim secret01.yaml
apiVersion: v1
kind: Secret #表明资源的类型为Secret,用于存储敏感信息
metadata:
name: my-secret1
type: Opaque # base64 进行转码信息保护
data: #定义secret的配置信息
username: bGltYWh1YQo= #Base64编码后的用户名
password: cXE2NjYK #Base64编码后的密码
kubectl apply -f secret01.yaml
1.4 将secret 以volume形式挂载到pod中
创建一个pod模板,对其进行修改编辑
kubectl run nginx-secret --image=nginx:1.18 --port=80 --dry-run=client -o yaml > ng-secret.yaml
vim ng-secret.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx-secret
name: nginx-secret
spec:
containers:
- image: nginx:1.18
name: nginx-secret
ports:
- containerPort: 80
volumeMounts:
- name: secrets #引用一个卷(volume)的名称,该卷在此容器内挂载
mountPath: "/etc/secret" #指定容器内挂载的路径
readOnly: true #只读
volumes:
- name: secrets #卷的名称,与上述容器中引用的卷名对应
secret:
secretName: mysecret #指定了此卷的数据来源是一个名为mysecret的Secret对象
Kubernetes会自动将mysecret Secret中的数据挂载到指定的/etc/secret路径下,
所有数据都是以文件形式存在且根据Secret的原始内容Base64解码。
kubectl apply -f ng-secret.yaml
1.5 将Secret导入到pod中,充当环境变量
复制上一个模板,进行修改编辑
cp ng-secret.yaml env-secret.yaml
进行编辑修改
vim env-secret.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: nginx-secret2
name: nginx-secret2
spec:
containers:
- image: nginx:1.18
name: nginx-secret2
ports:
- containerPort: 80
env: #定义了环境变量
- name: THIS_USER #环境变量从名为my-secret1的Secret中通过键username获取值
volumeFrom:
secretKeyRef:
name: my-secret1
key: username
- name: THIS_PASSWORD #环境变量同样从my-secret1 Secret中通过键password获取值
volumeFrom:
secretKeyRef:
name: my-secret1
key: password
kubectl apply -f env-secret.yaml
1.6 实战运用:使用secret配置免密交互拉取habor私有仓库镜像
harbor仓库的搭建详见:kubeadm 部署k8s集群-CSDN博客
在pod详解里有
我们在搭建好docker的私有仓库后,在使用私有仓库时需要通过docker login指令来登录到私有仓库中。
但同时在使用的过程中也会把habor仓库的用户名和密码暴露在命令行中,存在一定的安全隐患。k8s中的secret配置的运用能够实现并且规避这一问题的存在
进行私有仓库的secret资源创建
#私有仓库的secret配置
kubectl create secret docker-registry myharbor --docker-server=hub.benet.com --docker-username=admin --docker-password=Harbor12345 --docker-email=admin@qq.com
引用secret资源拉取私有仓库镜像创建pod
vim harbor-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-nginx
spec:
replicas: 3
selector:
matchLabels:
app: myapp-nginx
template:
metadata:
labels:
app: myapp-nginx
spec:
containers:
- name: myapp-container
image: hub.benet.com/library/nginx:v1
#从私有 Docker registry hub.benet.com 中拉取 library/nginx 镜像的 v1 版本
imagePullSecrets: #定义了用于拉取私有 Docker registry 镜像所需的 Secret
- name: myharbor
#指定了一个 Secret 的名称,这里为 myharbor,这意味着 Kubernetes 在拉取私有 Docker registry 的
镜像时,将使用 myharbor Secret 中的认证信息
kubectl apply -f harbor-nginx.yaml
以下是实验没有结果可能存在的问题:
注意以上配置完成后要重启docker 加载该配置。
另一种方法:
---------- 部署 harbor 创建私有项目 ----------
//在 Docker harbor 节点(192.168.80.13)上操作
systemctl stop firewalld.service
systemctl disable firewalld.service
setenforce 0
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install -y docker-ce
systemctl start docker.service
systemctl enable docker.service
docker version
//上传 docker-compose 和 harbor-offline-installer-v1.2.2.tgz 到 /opt 目录中
cd /opt
chmod +x docker-compose
mv docker-compose /usr/local/bin/
//部署 Harbor 服务
tar zxvf harbor-offline-installer-v1.2.2.tgz -C /usr/local/
vim /usr/local/harbor/harbor.cfg
--5行--修改,设置为Harbor服务器的IP地址或者域名
hostname = 192.168.80.13
cd /usr/local/harbor/
./install.sh
//在 Harbor 中创建一个新项目
(1)浏览器访问:http://192.168.80.13 登录 Harbor WEB UI 界面,默认的管理员用户名和密码是 admin/Harbor12345
(2)输入用户名和密码登录界面后可以创建一个新项目。点击“+项目”按钮
(3)填写项目名称为“kgc-project”,点击“确定”按钮,创建新项目
//在每个 node 节点配置连接私有仓库(注意每行后面的逗号要添加)
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://6ijb8ubo.mirror.aliyuncs.com"],
"insecure-registries":["192.168.80.13"]
}
EOF
systemctl daemon-reload
systemctl restart docker
//在每个 node 节点登录 harbor 私有仓库
docker login -u admin -p harbor12345 http://192.168.80.13
//在一个 node 节点下载 Tomcat 镜像进行推送
docker pull tomcat:8.0.52
docker images
docker tag tomcat:8.0.52 192.168.80.13/kgc-project/tomcat:v1
docker images
docker push 192.168.80.13/kgc-project/tomcat:v1
//查看登陆凭据
cat /root/.docker/config.json | base64 -w 0 #base64 -w 0:进行 base64 加密并禁止自动换行
ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjE5NS44MCI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9IgoJCX0KCX0sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy41IChsaW51eCkiCgl9Cn0=
//创建 harbor 登录凭据资源清单,用于 K8S 访问 Harbor 私服拉取镜像所需要的密钥权限凭证 secret 资源
vim harbor-pull-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: harbor-pull-secret
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjE5NS44MCI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9IgoJCX0KCX0sCgkiSHR0cEhlYWRlcnMiOiB7CgkJIlVzZXItQWdlbnQiOiAiRG9ja2VyLUNsaWVudC8xOS4wMy41IChsaW51eCkiCgl9Cn0= #复制粘贴上述查看的登陆凭据
type: kubernetes.io/dockerconfigjson
//创建 secret 资源
kubectl create -f harbor-pull-secret.yaml
//查看 secret 资源
kubectl get secret
//创建资源从 harbor 中下载镜像
cd /opt/demo
vim tomcat-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-tomcat
spec:
replicas: 2
selector:
matchLabels:
app: my-tomcat
template:
metadata:
labels:
app: my-tomcat
spec:
imagePullSecrets: #添加 K8S 访问 Harbor 私服拉取镜像所需要的 secret 资源选项
- name: harbor-pull-secret #指定 secret 资源名称
containers:
- name: my-tomcat
image: 192.168.80.13/kgc-project/tomcat:v1 #指定 harbor 中的镜像名
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-tomcat
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 31111
selector:
app: my-tomcat
//删除之前在 node 节点下载的 Tomcat 镜像
docker rmi tomcat:8.0.52
docker rmi 192.168.80.13/kgc-project/tomcat:v1
docker images
//创建资源
kubectl create -f tomcat-deployment.yaml
kubectl get pods
NAME READY STATUS RESTARTS AGE
my-tomcat-d55b94fd-29qk2 1/1 Running 0
my-tomcat-d55b94fd-9j42r 1/1 Running 0
//查看 Pod 的描述信息,可以发现镜像时从 harbor 下载的
kubectl describe pod my-tomcat-d55b94fd-29qk2
//刷新 harbor 页面,可以看到镜像的下载次数增加了
二、ConfigMap资源配置
与Secret类似,区别在于ConfigMap保存的是不需要加密配置的信息。
ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制大对象。
应用场景:应用配置
2.1 使用目录来创建configMap资源
创建一个目录并且在一个目录中填写两个文件:
mkdir /opt/configmap/
vim /opt/configmap/game.properties
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
vim /opt/configmap/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
kubectl create configmap game-config --from-file=/opt/configmap/
//--from-file 指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容
2.2 使用文件创建configMap资源
只要指定为一个文件就可以从单个文件中创建 ConfigMap
--from-file 这个参数可以使用多次,即可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的
kubectl create configmap game-config-2 --from-file=/opt/configmap/game.properties --from-file=/opt/configmap/ui.properties
2.3 直接使用参数创建confidenceMap资源
使用字面值创建
使用文字值创建,利用 --from-literal 参数传递配置信息,该参数可以使用多次,格式如下
kubectl create configmap special-config --from-literal=name=huhu --from-literal=hobby=play
这里的--from-literal 后跟 key=value
2.4 pod利用configMap资源
(1) 使用 ConfigMap 来替代环境变量
vim env.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config1
namespace: default
data:
special.how: very #这里定义了一些configMap的配置资源
special.type: good #这里定义了一些configMap的配置资源
---
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config1
namespace: default
data:
log_level: INFO #这里定义了一些configMap的配置资源
kubectl apply -f env.yaml
(2) 创建pod,并且引用configMap资源
vim test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: busybox
image: busybox:1.28.4
command: [ "/bin/sh", "-c", "env" ]
#容器启动时执行的命令,这里运行env命令来打印环境变量。
env:
- name: SPECIAL_HOW_KEY
valueFrom:
configMapKeyRef:
name: special-config1
key: special.how
#从名为special-config1的ConfigMap中通过键special.how获取值,并设置为环境变量。
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config1
key: special.type
#同样从special-config1 ConfigMap中通过键special.type获取值设置为环境变量。
envFrom:
- configMapRef:
name: env-config1
#从名为env-config1的ConfigMap中批量导入所有键值对作为环境变量。
restartPolicy: Never
kubectl create -f test-pod.yaml
2.5 使用 ConfigMap 设置命令行参数
vim test-pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod2
spec:
containers:
- name: busybox
image: busybox:1.28.4
command:
- /bin/sh
- -c
- echo "$(SPECIAL_HOW_KEY) $(SPECIAL_TYPE_KEY)"
#与上一个配置文件相同这里把configMap中配置设置为pod中环境变量 再用echo将其输出
env:
- name: SPECIAL_HOW_KEY
valueFrom:
configMapKeyRef:
name: special-config1
key: special.how
- name: SPECIAL_TYPE_KEY
valueFrom:
configMapKeyRef:
name: special-config1
key: special.type
envFrom:
- configMapRef:
name: env-config1
restartPolicy: Never
kubectl create -f test-pod2.yaml
2.6 通过数据卷插件使用ConfigMap
在数据卷里面使用 ConfigMap,就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容
vim test-pod3.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod3
spec:
containers:
- name: busybox
image: busybox:1.28.4
command: [ "/bin/sh", "-c", "sleep 36000" ]
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: special-config1
restartPolicy: Never
kubectl create -f test-pod3.yaml
我想通过configMap实现单独挂载pod中的nginx.conf配置
#首先获取nginx.conf 下载或则之前保存都可以
# nginx.conf 配置文件在/opt/benet/目录 下
kubectl create cm my-nginx --from-file=/opt/benet
vim pod-nginx1.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod1
spec:
volumes:
- name: nginx
configMap: #指定卷数据来源于 ConfigMap
name: my-nginx #具体指定了 ConfigMap 的名称
containers:
- image: nginx:1.18
name: nginx
volumeMounts:
- name: nginx
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf #subPath 可以实现只覆盖修改该文件,而不影响目录
如果不加subPath,你挂载到容器内的目录中其它文件将被覆盖。且如果configMap有其它键值也会被一起挂载。
kubectl apply -f pod-nginx1.yaml
2.7 configMap 的热更新
#创建一个cm资源
kubectl create configmap name-hobby --from-literal=hobby=fly
#创建一个pod,并且通过volume的方式挂载configMap中的name-config
vim pod-demo5.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: namepod1
name: namepod1
spec:
replicas: 1
selector:
matchLabels:
app: namepod1
template:
metadata:
labels:
app: namepod1
spec:
volumes:
- name: pod-test
configMap:
name: name-hobby
containers:
- image: nginx:1.18
name: mypod
volumeMounts:
- name: pod-test
mountPath: /opt/
开启另一个终端进行实时修改:
kubectl edit cm name-hobby
等大概一分钟左右,使用该 ConfigMap 挂载的 Volume 中的数据同步更新
ConfigMap 更新后滚动更新 Pod
更新 ConfigMap 目前并不会触发相关 Pod 的滚动更新,可以通过在 .spec.template.metadata.annotations 中添加 version/config ,每次通过修改 version/config 来触发滚动更新
kubectl patch deployment namepod1 --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "20240603" }}}}}'
PS:更新 ConfigMap 后:
●使用该 ConfigMap 挂载的 Env 不会同步更新。
●使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新。
总结
使用 Secret 资源
挂载的方式
在 pod.spec.volumes 字段中定义卷类型为 secret
在 pod.spec.containers.volumeMounts 字段中把存储卷挂载到指定的容器目录,secret资源数据的key将
以文件名的形式存在,value为文件内容
容器环境变量引用的方式
在 pod.spec.containers.env.name 字段中自定义容器的环境变量名
在.containers.env.valueFrom.secretKeyRef.name字段中指定secret资源的名
称,.containers.env.valueFrom.secretKeyRef.key字段中指定这个secret资源数据的key,
从而确定引用那个secret资源的key的value作为这个环境变量的值
在 .containers.envFrom.secretRef.name 字段中指定secret资源的名称,可实现使用secret资源数据的
key作为容器环境变量名,value作为这个环境变量的值
K8S从私有仓库拉取镜像时使用
在 pod.spec.imagePullSecrets 字段中指定 kubernetes.io/dockerconfigjson 类型的 secret 资源来
作为连接私有仓库的认证信息
ConfigMap 简称 cm ,保存配置文件 环境变量 命令行参数 之类的不需要加密的信息
创建 cm 资源
kubectl create cm XXX --from-file=文件/目录 --from-literal=变量的键值对(key=value)
查看cm资源的数据,数据以明文格式显示key的value
kubectl describe cm XXX 或 kubectl get cm XXX -o yaml
使用 cm 资源
容器环境变量引用的方式
env 指定自定义的环境变量名,通过指定的cm资源名称和key来给这个变量赋值
envFrom 直接使用cm资源的key作为容器的环境变量名,key的value作为这个变量的值
挂载的方式
volumes 定义卷类型为 configMap ,使用 items 字段可以自定义挂载的文件的子目录和文件名
volumeMounts 把卷挂载到容器目录。cm资源数据中的key以文件名的形式存在,value为文件内容
使用 subPath 指定文件名,实现只把卷挂载到指定的文件名上
cm资源热更新
更新cm资源的数据可以同步更新通过挂载的方式使用cm资源数据的Pod中的配置(注:使用subPath挂载的文件
不会更新)
如果使用env或envFrom引用环境变量的方式,是不会同步更新Pod中的配置