云原生|kubernetes|关于secret的一些使用

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 云原生|kubernetes|关于secret的一些使用

前言

kubernetes集群内的两种资源secret和configMap是比较类似的两种资源,但使用范围以及使用方法上又有所不同,因此,本文将两者合并到一起来讲。下面是关于两者的一些简单介绍。

Secret介绍
k8s secrets用于存储和管理一些敏感数据,比如密码,token,密钥等敏感信息。它把 Pod 想要访问的加密数据存放到 Etcd 中。然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变量的方式访问到这些 Secret 里保存的信息了,从名字上看,我们应该也能想到,有一些不太方便向外人展示的信息加密是secret的主要功能。

configMap介绍

ConfigMap是一种API对象,用来将非加密数据保存到键值对中。可以用作环境变量、命令行参数或者存储卷中的配置文件,从名字上看,我们也应该能想到,此类资源主要是做配置映射的,当然了,配置的一般内容是包括环境变量,命令行参数以及配置文件的形式这些的。

ConfigMap可以将环境变量配置信息和容器镜像解耦,便于应用配置的修改。如果需要存储加密信息时可以使用Secret对象。主要作用就是为了让镜像和配置文件解耦,以便实现镜像的可移植性和可复用性。

OK,以上所述讲的就一个意思,secret和configMap都是实现和pod交互作用。




secret的表现形式

A,Secret有三种类型

  • generic(通用的):保存密码数据等用它就可以Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;但数据也可以通过base64 –decode解码得到原始数据,所有加密性很弱。在真正的生产环境中,你需要在 Kubernetes 中开启 Secret 的加密插件,增强数据的安全性。

命令行快速创建secret:

此secret有三个键值对,password1到3

kubectl create secret generic mysql-root-password --from-literal=password1=MyP@ss123 --from-literal=password2=123456 --from-literal=password3=456789--dry-run=client -o yaml>test-secret.yaml

文件清单形式:

apiVersion: v1
data:           #1. data 字段用来存储 base64 编码的任意数据
  password1: TXlQQHNzMTIz  #base64编码之后的字符串
  password2: MTIzNDU2      #base64编码之后的字符串
  password3: NDU2Nzg5       #base64编码之后的字符串
stringData:     #2. stringData 字段是为了方便,它允许 Secret 使用未编码的字符串
  password4: qwerty
kind: Secret
metadata:
  name: mysql-root-password

 

通常此类secret是自定义的。

  • tls:保存私钥和证书Service Account:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的 /run/secrets/kubernetes.io/serviceaccount 目录中。

例如,我的集群只是一个初始的集群,secret和sa集群认为是一样的,都是一样的,describe查看也是一样的(当然,这里的作用是传递token,与apiserver和etcd交互):

[root@k8s-master ~]# k get sa -A
NAMESPACE         NAME                      SECRETS   AGE
default           default                   1         3d
kube-node-lease   default                   1         3d
kube-public       default                   1         3d
kube-system       calico-kube-controllers   1         2d12h
kube-system       calico-node               1         2d12h
kube-system       coredns                   1         2d20h
kube-system       default                   1         3d
kube-system       metrics-server            1         2d13h
[root@k8s-master ~]# k get secret -A
NAMESPACE         NAME                                  TYPE                                  DATA   AGE
default           default-token-w5n59                   kubernetes.io/service-account-token   3      3d
kube-node-lease   default-token-tnvkp                   kubernetes.io/service-account-token   3      3d
kube-public       default-token-gprb8                   kubernetes.io/service-account-token   3      3d
kube-system       calico-kube-controllers-token-sstpp   kubernetes.io/service-account-token   3      2d12h
kube-system       calico-node-token-6mx29               kubernetes.io/service-account-token   3      2d12h
kube-system       coredns-token-ff62s                   kubernetes.io/service-account-token   3      2d20h
kube-system       default-token-wrcjr                   kubernetes.io/service-account-token   3      3d
kube-system       metrics-server-token-k6szn            kubernetes.io/service-account-token   3      2d13h

只是查看secret会有详细的值而已

[root@k8s-master ~]# k describe secret metrics-server-token-k6szn -n kube-system
Name:         metrics-server-token-k6szn
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: metrics-server
              kubernetes.io/service-account.uid: 689995bb-1f70-4a19-a02b-e491d8ffe8e4
Type:  kubernetes.io/service-account-token
Data
====
ca.crt:     1359 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IjQtS3N6djBxZmotSFJtTUdFTzhQWFVlQmE3TnBzeTlKLVJjY05fYWxqRkkifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJtZXRyaWNzLXNlcnZlci10b2tlbi1rNnN6biIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJtZXRyaWNzLXNlcnZlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjY4OTk5NWJiLTFmNzAtNGExOS1hMDJiLWU0OTFkOGZmZThlNCIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTptZXRyaWNzLXNlcnZlciJ9.M-NA1Pab26QkAbsjWxCxB7aIgRkAbcVjmJSjEIOY-gpkvNKkJET4NsDVKm2cZ7y4AMlZtn6l3lP-7OdS_IEP359vyCX3WeBWZbdwkva39GCt4ErD-Mmhonhxt4vE9oC17yRg3GvGI-o3TSsJ61QKEJE76bz4tpqKJNQh__AxdvsqWd1s0c6oNLZrycYjzBVW1cRVNWQqfbByYPN23KOWxc4Od452RYn1tS07exIO2JOdgoq4Dw7mG0rqeaeL99Gae4XJ3EnM0C3OPkeLN40dCE75XKGeL5dS3aFJrlDQTPmZ9962-YORzQU2Xu4rVZzzkh67ed9CAg61IIaPJm7NOQ
[root@k8s-master ~]# 
[root@k8s-master ~]# k describe sa metrics-server -n kube-system
Name:                metrics-server
Namespace:           kube-system
Labels:              k8s-app=metrics-server
Annotations:         Image pull secrets:  <none>
Mountable secrets:   metrics-server-token-k6szn
Tokens:              metrics-server-token-k6szn
Events:              <none>

 

  • docker-registry: 用来存储私有docker registry的认证信息,我们每一个node运行pod之前会把pod依赖的镜像要先检查本地有没有,如果没有就回去仓库服务器上拖,如果我们用的是私有仓库的话,必须要输入账号和密码才能访问,账号密码放哪儿呢?也就意味着当前node要自动去通过认证然后去拖镜像否则pod就会运行失败,也就意味着拉取的时候要现在节点上使用docker login然后docker pull。因此很多时候我们k8s节点要运行pod获取镜像,而若镜像若托管在在必须要认证才能获取到的私有镜像仓库中时,kubelet要能自动完成,因此拖镜像和认证是通过kubelet指挥着docker去做的,那我们怎么去提供这个私有数据呢。第一种方式是我们使用secret,使用我们pods.spec.imagePullSecrets字段,表示pod创建时,它如果要连到私有镜像仓库服务器,需要认证那么这里我们应该放个secret,这个secret包含了让我们kubelet或我们docker去链接私有仓库服务器时的账号和密码,这个账号密码就是由secret提供的,这个对象必须是专用的对象,就是我们这个docker-registry

定义的时候通常tpye是type: kubernetes.io/dockerconfigjson

B,

pod引用secret的三种形式:

  1. 作为挂载到一个或多个容器上的卷 中的文件。
  2. 映射为容器内的环境变量。
  3. 由 kubelet 在为 Pod 拉取镜像时使用

1)作为文件挂载到pod内

创建一个pod,此pod使用上面创建的secret,挂载到opt目录下:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.20
        name: nginx
        volumeMounts:  #在容器中使用pod定义的volumes
        - name: secretconfig
          mountPath: /opt/
          readOnly: true
      volumes:  #在pod中定义volumes
      - name: secretconfig
        secret:
          secretName: mysql-root-password

进入pod查看是否挂载,并查看stringDate的值是否和上面的secret一致:

[root@k8s-master wd]# k exec -it nginx-85cf9f64ff-tljmd  -- /bin/bash
root@nginx-85cf9f64ff-tljmd:/# ls -al /opt/
total 0
drwxrwxrwt 3 root root 160 Oct  7 12:00 .
drwxr-xr-x 1 root root  51 Oct  7 10:16 ..
drwxr-xr-x 2 root root 120 Oct  7 12:00 ..2022_10_07_12_00_52.102045942
lrwxrwxrwx 1 root root  31 Oct  7 12:00 ..data -> ..2022_10_07_12_00_52.102045942
lrwxrwxrwx 1 root root  16 Oct  7 10:16 password1 -> ..data/password1
lrwxrwxrwx 1 root root  16 Oct  7 10:16 password2 -> ..data/password2
lrwxrwxrwx 1 root root  16 Oct  7 10:16 password3 -> ..data/password3
lrwxrwxrwx 1 root root  16 Oct  7 12:00 password4 -> ..data/password4
root@nginx-85cf9f64ff-tljmd:/# cat /opt/password4
qwertyr

热更新secret:

更改上面的secret清单文件,增加一个password5,然后apply secret文件,此时nginx这个pod不需要更新就可以看到多出一个password5文件

[root@k8s-master wd]# cat test-secret.yaml 
apiVersion: v1
data:
  password1: TXlQQHNzMTIz
  password2: MTIzNDU2
  password3: NDU2Nzg5
stringData:
  password4: qwerty
  password5: 324dfe3432423
kind: Secret
metadata:
  name: mysql-root-password
#更改secret文件
[root@k8s-master wd]# k apply -f test-secret.yaml 
secret/mysql-root-password configured
root@nginx-85cf9f64ff-tljmd:/# ls -al /opt/
total 0
drwxrwxrwt 3 root root 180 Oct  7 12:36 .
drwxr-xr-x 1 root root  51 Oct  7 10:16 ..
drwxr-xr-x 2 root root 140 Oct  7 12:36 ..2022_10_07_12_36_50.416957405
lrwxrwxrwx 1 root root  31 Oct  7 12:36 ..data -> ..2022_10_07_12_36_50.416957405
lrwxrwxrwx 1 root root  16 Oct  7 10:16 password1 -> ..data/password1
lrwxrwxrwx 1 root root  16 Oct  7 10:16 password2 -> ..data/password2
lrwxrwxrwx 1 root root  16 Oct  7 10:16 password3 -> ..data/password3
lrwxrwxrwx 1 root root  16 Oct  7 12:00 password4 -> ..data/password4
lrwxrwxrwx 1 root root  16 Oct  7 12:36 password5 -> ..data/password5

2)

env环境变量形式挂载

修改上面的那个nginx部署清单文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.20
        name: nginx
        env:
        - name: PASSWORD1
          valueFrom:
            secretKeyRef:
              name: mysql-root-password
              key: password1
        - name: PASSWORD5
          valueFrom:
            secretKeyRef:
              name: mysql-root-password
              key: password5

此时,重新应用这个部署文件后,pod的名称会发生改变,因此,重新查询出此pod的名字,并进入pod打印变量password1的值:

[root@k8s-master wd]# k get po
NAME                    READY   STATUS    RESTARTS   AGE
nginx-5cd897998-rm4kv   1/1     Running   0          87s
[root@k8s-master wd]# k exec -it nginx-5cd897998-rm4kv -- /bin/bash
root@nginx-5cd897998-rm4kv:/# echo $PASSWORD1
MyP@ss123

OK,可以看到环境变量在pod内生效了,打印出了正确的值,那么,stringDate能否正确打印呢,答案是肯定的,但,此时secret不能热更新了,也就是说环境变量形式的引用secret,secret改变不会自动将它的值作为变量映射到pod内。

[root@k8s-master wd]# k exec -it nginx-cb84ddc9-lvz4k -- /bin/bash
root@nginx-cb84ddc9-lvz4k:/# echo $PASSWORD5
324dfe3432423

3)

docker私有仓库的专有secret引用

第一种方式:

假设本地的docker仓库已经安装完毕并调试好了,不管是habore还是官方镜像搭建的私人仓库都有配置文件,此文件假定名字是config.json

[root@ip-172-31-10-110 ~]# base64 -w 0 ~/.docker/config.json
ewoJImF1dGhjNWdlpHVnVaenB5Wld4aFFFeFdUa2xCVGtBeU1ERTMiCgkJfSwKCQkidXJlZy5rOHMueXVud2VpLnJlbGEubWUiOiB7CgkJCSJhdXRoIjogIloyRnZaM1Z2WkdWdVp6cHlaV3hoUUV4V1RrbEJUa0F5TURFMyIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTguMDYuMS1jZSAobGludXgpIgoJfQp9

创建secret:

### vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: regsecret
  namespace: default
data:
    .dockerconfigjson: ewoJImF1dGhjNWdlpHVnVaenB5Wld4aFFFeFdUa2xCVGtBeU1ERTMiCgkJfSwKCQkidXJlZy5rOHMueXVud2VpLnJlbGEubWUiOiB7CgkJCSJhdXRoIjogIloyRnZaM1Z2WkdWdVp6cHlaV3hoUUV4V1RrbEJUa0F5TURFMyIKCQl9Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTguMDYuMS1jZSAobGludXgpIgoJfQp9
type: kubernetes.io/dockerconfigjson

pod 拉取镜像的时候引用此secret:

[root@ip-172-31-10-110 ~]#  vim test.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: dentestreplce
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: dentestreplace
    spec:
      containers:
      - name: dentestreplace 
        imagePullPolicy: Always
        image: ureg.k8s.test.com/rela_dev/logreport:latest
      imagePullSecrets:
      - name: regsecret

第二种方式:

使用命令创建Secret

 

kubectl create secret docker-registry regsecret --docker-server=ureg.k8s.test.com --docker-username=lvnian --docker-password=LVNIAN@2017 --docker-email=lvnian@rela.me
regsecret: 指定密钥的键名称, 可自行定义
--docker-server: 指定docker仓库地址
--docker-username: 指定docker仓库账号
--docker-password: 指定docker仓库密码
--docker-email: 指定邮件地址
-n : 命名空间,在那个命名空间创建,就只能在那个命名空间使用这个secret

命令行生成的secret和上面文件生成的secret引用都是一样的,没什么可说的了。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
7月前
|
Cloud Native Serverless 数据中心
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
ACK One注册集群已正式支持ACS(容器计算服务)算力,为企业的容器化工作负载提供更多选择和更强大的计算能力。
|
7月前
|
Cloud Native Serverless 数据中心
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
阿里云ACK One:注册集群支持ACS算力——云原生时代的计算新引擎
207 10
|
9月前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
369 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
10月前
|
Kubernetes Cloud Native 开发者
云原生入门:Kubernetes的简易指南
【10月更文挑战第41天】本文将带你进入云原生的世界,特别是Kubernetes——一个强大的容器编排平台。我们将一起探索它的基本概念和操作,让你能够轻松管理和部署应用。无论你是新手还是有经验的开发者,这篇文章都能让你对Kubernetes有更深入的理解。
|
10月前
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
10月前
|
运维 Kubernetes Cloud Native
云原生技术入门:Kubernetes和Docker的协同工作
【10月更文挑战第43天】在云计算时代,云原生技术成为推动现代软件部署和运行的关键力量。本篇文章将带你了解云原生的基本概念,重点探讨Kubernetes和Docker如何协同工作以支持容器化应用的生命周期管理。通过实际代码示例,我们将展示如何在Kubernetes集群中部署和管理Docker容器,从而为初学者提供一条清晰的学习路径。
|
10月前
|
Kubernetes 负载均衡 Cloud Native
探索Kubernetes:云原生应用的基石
探索Kubernetes:云原生应用的基石
|
10月前
|
Kubernetes Cloud Native 云计算
云原生入门:Kubernetes 和容器化基础
在这篇文章中,我们将一起揭开云原生技术的神秘面纱。通过简单易懂的语言,我们将探索如何利用Kubernetes和容器化技术简化应用的部署和管理。无论你是初学者还是有一定经验的开发者,本文都将为你提供一条清晰的道路,帮助你理解和运用这些强大的工具。让我们从基础开始,逐步深入了解,最终能够自信地使用这些技术来优化我们的工作流程。
|
存储 运维 Kubernetes
阿里云数字新基建系列:云原生操作系统Kubernetes-第1章(4)
阿里云数字新基建系列包括5本书,题材涉及Kubernetes、混合云架构、云数据库、CDN原理与流媒体技术、云服务器运维(Windows),囊括了领先的云技术知识与阿里云技术团队独到的实践经验,是国内IT技术图书中又一套重磅作品! 本书是阿里云容器服务产品线上实践的技术沉淀,主要包括理论篇和实践篇两部分内容。理论篇注重理论介绍,核心是Kubernetes on Cloud,即着重介绍Kubernetes和阿里云产品的结合。实践篇是疑难问题的诊断案例,希望通过案例来和读者分享Kubernetes深度问题诊断......
阿里云数字新基建系列:云原生操作系统Kubernetes-第1章(4)
|
运维 Kubernetes Cloud Native
阿里云数字新基建系列:云原生操作系统Kubernetes-第1章(3)
阿里云数字新基建系列包括5本书,题材涉及Kubernetes、混合云架构、云数据库、CDN原理与流媒体技术、云服务器运维(Windows),囊括了领先的云技术知识与阿里云技术团队独到的实践经验,是国内IT技术图书中又一套重磅作品! 本书是阿里云容器服务产品线上实践的技术沉淀,主要包括理论篇和实践篇两部分内容。理论篇注重理论介绍,核心是Kubernetes on Cloud,即着重介绍Kubernetes和阿里云产品的结合。实践篇是疑难问题的诊断案例,希望通过案例来和读者分享Kubernetes深度问题诊断......
阿里云数字新基建系列:云原生操作系统Kubernetes-第1章(3)

热门文章

最新文章

推荐镜像

更多