33、K8S-配置管理之Secret、DownwardAPI
1、secret
1.1、基础知识
1.1.1、Secret简介
secret volume为Pod提供加密的信息,相比于直接将敏感数据配置在Pod的定义或者镜像中,Secret提供
了更加安全的机制,将共享的数据进行加密,防止数据泄露。
Secret的对象需要单独定义并创建,然后以数据卷的形式挂载到Pod中,Secret的数据将以文件的形式保
存,容器通过读取文件可以获取需要的数据。
secret volume是通过tmpfs(内存文件系统)实现的,所以这种类型的volume不是永久存储的。
1.1.2、Secret创建方式
手动创建:大部分情况用来存储用户私有的一些信息
自动创建:用来作为集群中各个组件之间通信的身份校验使用
1.1.3、Secret类型
类型 解析 generic 通用类型,基于base64编码的,长用来存储密码,公钥之类的。常见的子类型有:kubernetes.io/basic-auth、kubernetes.io/rbd、kubernetes.io/ssh-auth(比较重要)。 dockerregistry 专用于让kubelet启动Pod时从私有镜像仓库pull镜像时,首先认证到Registry时使用。 tls 专门用于保存tls/ssl用到证书和配对儿的私钥。
1.1.4、属性解析
master1 ]# kubectl get secrets NAME TYPE DATA AGE k8s-auth kubernetes.io/dockerconfigjson 1 11d master1 ]# kubectl -n kubernetes-dashboard get secrets kubernetes-dashboard-certs -o yaml apiVersion: v1 kind: Secret metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"labels":{"k8s-app":"kubernetes-dashboard"},
"name":"kubernetes-dashboard-certs","namespace":"kubernetes-dashboard"},"type":"Opaque"} creationTimestamp: "2023-03-17T07:47:04Z" labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard-certs namespace: kubernetes-dashboard resourceVersion: "74280" uid: dd2cf9d5-2a78-45e0-917c-e72968f30ce9 type: Opaque 属性解析: 资源的元数据:除了name, namespace之外,常用的还有labels, annotations; 1、annotation的名称遵循类似于labels的名称命名格式,但其数据长度不受限制; 2、它不能用于被标签选择器作为筛选条件;但常用于为那些仍处于Beta阶段的应用程序提供临时的配置接口; 3、管理命令:kubectl annotate TYPE/NAME KEY=VALUE, kubectl annotate TYPE/NAME KEY-
1.2、创建Secrets命令介绍
master ~]# kubectl create secret -h Create a secret using specified subcommand. Available Commands: docker-registry----创建一个给 Docker registry 使用的 secret generic ----从本地 file, directory 或者 literal value 创建一个 secret tls ----创建一个 TLS secret Usage: kubectl create secret [flags] [options]
1.3、 docker-registry、generic、tls命令行方法-实践
1.3.1、docker-registry
kubectl create secret docker-registry my-secret --dockerserver=DOCKER_REGISTRY_SERVER \
--docker-username=DOCKER_USER --dockerpassword=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
1.3.2、generic
kubectl create secret generic my-secret --from-file=path/to/bar kubectl create secret generic my-secret --from-file=ssh-privatekey=ssh-key/id_rsa --from-file=ssh-publickey=ssh-key/id_rsa.pub kubectl create secret generic my-secret --from-literal=key1=supersecret --fromliteral=key2=topsecret kubectl create secret generic my-secret --from-env-file=path/to/bar.env
1.3.3、tls
kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key
1.4、创建generic Secret-yaml实践
1.4.1、准备传递信息
master1 ]# echo -n 'password' | base64 cGFzc3dvcmQ= master1 ]# echo -n 'admin' | base64 YWRtaW4=
1.4.2、定义资源配置清单
cat >nginx-secret-demo.yml<<'EOF' apiVersion: v1 kind: Secret metadata: name: nginx-secret type: kubernetes.io/basic-auth data: username: YWRtaW4= password: cGFzc3dvcmQ= EOF type类型指定为 Opaque username和password是加密的信息 资源定义文件的时候,与命令行创建secret的时候,--from-literal=key1=supersecret 效果是一样的
1.4.3、应用资源配置清单
master1 ]# kubectl apply -f nginx-secret-demo.yml secret/nginx-secret created master1 ]# kubectl get secrets NAME TYPE DATA AGE k8s-auth kubernetes.io/dockerconfigjson 1 11d nginx-secret kubernetes.io/basic-auth 2 3s master1 ]# kubectl get secrets nginx-secret -o yaml apiVersion: v1 data: password: cGFzc3dvcmQ= username: YWRtaW4= kind: Secret metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"v1","data":{"password":"cGFzc3dvcmQ=","username":"YWRtaW4="},
"kind":"Secret","metadata":{"annotations":{},"name":"nginx-secret",
"namespace":"default"},"type":"kubernetes.io/basic-auth"} creationTimestamp: "2023-03-28T09:29:23Z" name: nginx-secret namespace: default resourceVersion: "777404" uid: da8bdf68-7e27-4ef6-802f-a97aa253e092 type: kubernetes.io/basic-auth # 返编码显示明文 master1 ]# echo -n 'cGFzc3dvcmQ=' | base64 -d password
1.5、创建generic Secret挂载至Pod-yaml实践
1.5.1、定义资源配置清单
cat >nginx-secret-pod.yml<<'EOF' apiVersion: v1 kind: Secret metadata: name: nginx-secret type: kubernetes.io/basic-auth data: username: YWRtaW4= password: cGFzc3dvcmQ= --- apiVersion: v1 kind: Pod metadata: name: secret-volume spec: volumes: - name: secret secret: secretName: nginx-secret containers: - name: nginx-secrec image: 192.168.10.33:80/k8s/my_nginx:v1 volumeMounts: - name: secret mountPath: /nginx_secret/ readOnly: true EOF
1.5.2、应用资源配置清单
master1 ]# kubectl apply -f nginx-secret-pod.yml master1 ]# kubectl get pods NAME READY STATUS RESTARTS AGE secret-volume 1/1 Running 0 2s master1 ]# kubectl exec -it secret-volume -- /bin/bash root@secret-volume:/# cat /nginx_secret/password password root@secret-volume:/# cat /nginx_secret/username admin
1.6、secretKeyRef-创建secret给mariadb数据库设置root密码-实践
1.6.1、Docker演示设置的原理
master1 ~]# docker run --name mariadb_test -e MYSQL_ROOT_PASSWORD=12345678 -d 192.168.10.33:80/k8s/mariadb:10.6 master1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 80808a79e9ea 192.168.10.33:80/k8s/mariadb:10.6 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 3306/tcp mariadb_test [root@master1 ~]# docker exec -it 80808a79e9ea /bin/bash root@80808a79e9ea:/# mysql -uroot -p12345678
1.6.2、定义资源配置清单
cat >mysql-init-secret.yml<<'EOF' apiVersion: v1 kind: Secret metadata: name: mysql-secret type: kubernetes.io/basic-auth data: username: cm9vdAo= password: MTIzNDU2Nzg= --- apiVersion: v1 kind: Pod metadata: name: mysql-init-secret spec: containers: - name: mariadb image: 192.168.10.33:80/k8s/mariadb:10.6 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password EOF
1.6.3、应用资源配置清单
master1 ]# kubectl apply -f mysql-init-secret.yml master1 ]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES mysql-init-secret 1/1 Running 0 43s 10.244.4.103 node2 <none> <none> master1 ]# kubectl exec -it mysql-init-secret -- mysql -uroot -p12345678 -e "show databases;" +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+
1.7、tls-基于https来访问的nginx的web服务-实践
1.7.1、创建CA证书
mkdir https-ca && cd https-ca # 生成证书的密钥 openssl genrsa -out tls.key 2048 # 创建证书的公钥 openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=www.sswang.com
1.7.2、创建secret tls
master1 ]# kubectl create secret tls nginx-ssl-secret --cert=tls.crt --key=tls.key # 创建 master1 ]# kubectl get secrets NAME TYPE DATA AGE k8s-auth kubernetes.io/dockerconfigjson 1 11d nginx-ssl-secret kubernetes.io/tls 2 71s master1 ]# kubectl get secrets nginx-ssl-secret -o yaml
1.7.3、创建nginx配置
mkdir nginx-ssl-conf.d && cd nginx-ssl-conf.d cat >myserver-gzip.cfg<<'EOF' gzip on; gzip_comp_level 5; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css application/xml text/javascript; EOF cat >myserver-status.cfg<<'EOF' location /nginx-status { stub_status on; access_log off; } EOF cat >myserver.conf<<'EOF' server { listen 443 ssl; server_name www.sswang.com; ssl_certificate /etc/nginx/certs/tls.crt; ssl_certificate_key /etc/nginx/certs/tls.key; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; include /etc/nginx/conf.d/myserver-*.cfg; location / { root /usr/share/nginx/html; } } server { listen 80; server_name www.sswang.com; return 301 https://$host$request_uri; } EOF cd .. master1 ]# kubectl create configmap nginx-conf-ssl --from-file=nginx-ssl-conf.d/ master1 ]# kubectl get cm NAME DATA AGE kube-root-ca.crt 1 12d nginx-conf-ssl 3 3s
1.7.4、定义资源配置清单
cat >nginx-ssl-server.yml<<'EOF' apiVersion: v1 kind: Pod metadata: name: nginx-ssl-server namespace: default spec: containers: - image: 192.168.10.33:80/k8s/my_nginx:v1 name: nginx-ssl-server volumeMounts: - name: nginxcerts mountPath: /etc/nginx/certs/ readOnly: true - name: nginxconfs mountPath: /etc/nginx/conf.d/ readOnly: true volumes: - name: nginxcerts secret: secretName: nginx-ssl-secret - name: nginxconfs configMap: name: nginx-conf-ssl optional: false EOF
1.7.5、应用资源配置清单
master1 ]# kubectl apply -f nginx-ssl-server.yml master1 ]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-ssl-server 1/1 Running 0 4m3s 10.244.3.249 node1 <none> <none> # 测试访问 master1 ]# curl -k -H "Host:www.sswang.com" https://10.244.3.249:443 nginx v1版本
2、downwardAPI
2.1、基础知识
2.1.1、场景
在k8s集群场景中,对于运行中的pod来说,我们可以通过 configmap 、secret、volume等方式为
pod提供相应的配置属性或者配置文件等信息。但是对于pod中的应用程序来说,有时候还需要基于其所在的
宿主机提供的外在环境信息。
比如:我们知道集群节点主机本身是有资源容量的,我们可以通过resources的limits或者requests
对pod内部的容器进行资源限制,如果我们能够将宿主机本地的相关资源信息,传递到pod内部,便于其在进
行资源调度的时候,做成充分的考量。
那么基于此,我们就可以基于一种 downwardAPI 的资源对象,将宿主机相关的信息以存储卷的样式加载到pod内部。
2.1.2、简介
从严格意义上来说,downwardAPI不是存储卷,它自身就存在。相较于configmap、secret等资源对象需
要创建后才能使用,而downwardAPI引用的是Pod自身的运行环境信息,这些信息在Pod启动的时候就存在。
downwardAPI 为运行在pod中的应用容器提供了一种反向引用。让容器中的应用程序了解所处pod或Node的一些基础属性信息。
2.1.3、需求
类似于ConfigMap或Secret资源,容器能够在环境变量中在valueFrom字段中嵌套fieldRef或 resourceFieldRef字段来引用其所属Pod对象的元数据信息。不过,通常只有常量类型的属性才能够通过环 境变量注入到容器中,毕竟,在进程启动完成后无法再向其告知变量值的变动,于是,环境变量也就不支持中 途的更新操作。 容器规范中可在环境变量配置中的valueFrom通过内嵌字段fieldRef引用的信息包括如下这些: metadata.name:Pod对象的名称; metadata.namespace:Pod对象隶属的名称空间; metadata.uid:Pod对象的UID; metadata.labels['<KEY>']:Pod对象标签中的指定键的值,例如 metadata.labels['mylabel'] metadata.annotations['<KEY>']:Pod对象注解信息中的指定键的值。 容器上的计算资源需求和资源限制相关的信息,以及临时存储资源需求和资源限制相关的信息可通过容器规范 中的resourceFieldRef字段引用,相关字段包括requests.cpu、limits.cpu、requests.memory和 limits.memory等。另外,可通过环境变量引用的信息有如下几个: status.podIP:Pod对象的IP地址 spec.serviceAccountName:Pod对象使用的ServiceAccount资源名称 spec.nodeName:节点名称 status.hostIP:节点IP地址 容器上的当前容器的资源请求及资源限额的定义,可以通过resourceFieldRef字段引用,因此它们包括 requests.cpu、requests.memory、requests.ephemeral-storage、limits.cpu、limits.memory和limits.ephemeral-storage这6项。
2.2、resourceFieldRef、fieldRef-获取基本的变量信息-实践
2.2.1、定义资源配置清单
cat >downwardapi-env-test.yml<<'EOF' apiVersion: v1 kind: Pod metadata: name: downwardapi-env-test labels: app: downwardapi-env spec: containers: - name: downwardapi-env-test image: 192.168.10.33:80/k8s/my_nginx:v1 resources: requests: memory: "100Mi" cpu: "250m" limits: memory: "200Mi" cpu: "500m" env: - name: THIS_POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: THIS_POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: THIS_APP_LABEL valueFrom: fieldRef: fieldPath: metadata.labels['app'] - name: THIS_CPU_LIMIT valueFrom: resourceFieldRef: resource: limits.cpu - name: THIS_MEM_REQUEST valueFrom: resourceFieldRef: resource: requests.memory divisor: 1Mi EOF
2.2.2、应用资源配置清单
master1 ]# kubectl apply -f downwardapi-env-test.yml master1 ]# kubectl exec -it downwardapi-env-test -- printenv | grep -i this THIS_POD_NAME=downwardapi-env-test THIS_POD_NAMESPACE=default THIS_APP_LABEL=downwardapi-env THIS_CPU_LIMIT=1 THIS_MEM_REQUEST=100 # 这些变量,就是我们metadata中获取字段的环境变量
2.3、downwardAPI、resourceFieldRef、fieldRef-存储卷方式使用-实践
2.3.1、定义资源配置清单
cat >downwardapi-volume-test.yml<<'EOF' kind: Pod apiVersion: v1 metadata: name: downwardapi-volume-test labels: zone: Shanghai rack: pudong001 app: redis-master annotations: region: Asia-China spec: containers: - name: downwardapi-volume-test image: 192.168.10.33:80/k8s/my_nginx:v1 resources: requests: memory: "100Mi" cpu: "250m" limits: memory: "200Mi" cpu: "500m" volumeMounts: - name: podinfo mountPath: /etc/podinfo readOnly: false volumes: - name: podinfo downwardAPI: defaultMode: 420 items: - fieldRef: fieldPath: metadata.namespace path: pod_namespace - fieldRef: fieldPath: metadata.labels path: pod_labels - fieldRef: fieldPath: metadata.annotations path: pod_annotations - resourceFieldRef: containerName: downwardapi-volume-test resource: limits.cpu path: "cpu_limit" - resourceFieldRef: containerName: downwardapi-volume-test resource: requests.memory divisor: "1Mi" path: "mem_request" EOF
2.3.2、应用资源配置清单
master1 ]# kubectl apply -f downwardapi-volume-test.yml pod/downwardapi-volume-test created master1 ]# kubectl get pods NAME READY STATUS RESTARTS AGE downwardapi-volume-test 1/1 Running 0 3s master1 ]# kubectl exec -it downwardapi-volume-test -- ls -l /etc/podinfo lrwxrwxrwx 1 root root 16 Mar 28 14:35 cpu_limit -> ..data/cpu_limit lrwxrwxrwx 1 root root 18 Mar 28 14:35 mem_request -> ..data/mem_request lrwxrwxrwx 1 root root 22 Mar 28 14:35 pod_annotations -> ..data/pod_annotations lrwxrwxrwx 1 root root 17 Mar 28 14:35 pod_labels -> ..data/pod_labels lrwxrwxrwx 1 root root 20 Mar 28 14:35 pod_namespace -> ..data/pod_namespace master1 ]# kubectl exec -it downwardapi-volume-test -- cat /etc/podinfo/mem_request 100