33、K8S-配置管理之Secret、DownwardAPI

发布时间 2023-03-28 22:41:13作者: 小粉优化大师

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