CKA备考实验 | secret

书籍来源:《CKA/CKAD应试指南:从Docker到Kubernetes完全攻略》

一边学习一边整理老师的课程内容及实验笔记,并与大家分享,侵权即删,谢谢支持!

附上汇总贴:CKA备考实验 | 汇总_热爱编程的通信人的博客-CSDN博客


secret的主要作用是存储密码信息,以及往pod里传递文件。secret以键值对的方式存储,格式如下。

键=值 或者是 key=value

其中这里的“值”不是以明文的方式存储的,而是通过base64编码过的,具体看下面的例子。

创建secret

创建secret的方法很多,可以直接指定key和value,也可以把一个文件的内容作为value,还可以直接写yaml文件,下面分别用不同的方法来创建。

为了区分前面章节创建的文件区分,这里单独创建一个目录secret,本章所需要的文件全部在目录secret里创建。

##########实操验证##########
[root@vms10 ~]# mkdir secret
[root@vms10 ~]# cd secret/
[root@vms10 secret]#

创建一个命名空间nssec,本章所有实验均在这个命名空间里操作。

##########实操验证##########
[root@vms10 secret]# kubectl create ns nssec
namespace/nssec created
[root@vms10 secret]# kubens nssec
Context "kubernetes-admin@kubernetes" modified.
Active namespace is "nssec".
[root@vms10 secret]#

查看当前命名空间里现存的secret。

##########实操验证##########
[root@vms10 secret]# kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-cp9rm   kubernetes.io/service-account-token   3      35s
[root@vms10 secret]#

创建secret有以下多种方法。

方法1:命令行的方式

语法:

kubectl create secret generic 名字 --from-literal=k1=v1 --from-literal=k2=v2 ...

这里k1的值为v1,k2的值为v2,如果需要多个变量,就写多个--from-literal。

步骤1:创建一个名字为mysecret1的secret。

##########实操验证##########
[root@vms10 secret]# kubectl create secret generic mysecret1 --from-literal=xx=tom --from-literal=yy=redhat
secret/mysecret1 created
[root@vms10 secret]#

步骤2:查看现有的secret。

##########实操验证##########
[root@vms10 secret]# kubectl get secrets
NAME                  TYPE                                  DATA   AGE
default-token-cp9rm   kubernetes.io/service-account-token   3      2m49s
mysecret1             Opaque                                2      92s
[root@vms10 secret]#

secret有三种类型。

(1)Opaque:base64编码格式的secret,用来存储密码、密钥等,但数据也通过base64-decode解码得到原始数据,加密型很弱。

(2)http://kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。

(3)http://kubernetes.io/service-account-token:用于被serviceaccount引用。

创建serviceaccount时,kubernetes会默认创建对应的secret。pod如果使用了serviceaccount,对应的secret会自动挂裁到Pod目录/run/secrets/http://kubernetes.io/serviceaccount(后面有专门章节将serviceaccount)中。

步骤3:查看mysecret1的具体属性。

##########实操验证##########
[root@vms10 secret]# kubectl describe secrets mysecret1
Name:         mysecret1
Namespace:    nssec
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
xx:  3 bytes
yy:  6 bytes
[root@vms10 secret]#

这里可以看到mysecret1里有两个变量,分别是xx和yy,xx的值有3个字符,yy的值有6个字符,具体是什么这里看不出来。

步骤4:查看mysecret1的键值对。

##########实操验证##########
[root@vms10 secret]# kubectl get secret mysecret1 -o yaml
apiVersion: v1
data:
  xx: dG9t
  yy: cmVkaGF0
kind: Secret
metadata:
  creationTimestamp: "2023-05-30T07:59:25Z"
  name: mysecret1
  namespace: nssec
  resourceVersion: "38416"
  selfLink: /api/v1/namespaces/nssec/secrets/mysecret1
  uid: 67e180f5-136a-48be-9a56-49d18a3b919a
type: Opaque
[root@vms10 secret]#

上面data字段里列出来的就是mysecret1的键值对,其中xx和yy的值都是经过base64编码的,需要解码才能看到具体值。

步骤5:解码。

##########实操验证##########
[root@vms10 secret]# echo "dG9t" | base64 --decode
tom[root@vms10 secret]# echo "cmVkaGF0" | base64 --decode
redhat[root@vms10 secret]# 
[root@vms10 secret]#

方法2:把文件创建为secret

也可以把一个文件创建为secret,此时文件的文件名作为key,文件的内容为value,如果要把一个文件创建为secret的话,使用的命令如下。

kubectl create secret generic mysecret2 --from-file=file1 --from-file=file2 ..

这种创建secret的作用是,把一个文件的内容写入secret里,后面通过卷的方式来引用这个secret,就可以把此文件写入pod里了。

步骤1:查看/etc/hosts的内容。

##########实操验证##########
[root@vms10 secret]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.110   vms10.rhce.cc          vms10
192.168.1.111   vms11.rhce.cc          vms11
192.168.1.112   vms12.rhce.cc          vms12
[root@vms10 secret]#

这里文件名为hosts,现在要把这个文件创建为一个secret。

步骤2:创建secret。

##########实操验证##########
[root@vms10 secret]# kubectl create secret generic mysecret2 --from-file=/etc/hosts
secret/mysecret2 created
[root@vms10 secret]#

步骤3:下面查看这个secret的内容。

##########实操验证##########
[root@vms10 secret]# kubectl get secrets mysecret2 -o yaml
apiVersion: v1
data:
  hosts: MTI3LjAuMC4xICAgbG9jYWxob3N0IGxvY2FsaG9zdC5sb2NhbGRvbWFpbiBsb2NhbGhvc3Q0IGxvY2FsaG9zdDQubG9jYWxkb21haW40Cjo6MSAgICAgICAgIGxvY2FsaG9zdCBsb2NhbGhvc3QubG9jYWxkb21haW4gbG9jYWxob3N0NiBsb2NhbGhvc3Q2LmxvY2FsZG9tYWluNgoxOTIuMTY4LjEuMTEwICAgdm1zMTAucmhjZS5jYyAgICAgICAgICB2bXMxMAoxOTIuMTY4LjEuMTExICAgdm1zMTEucmhjZS5jYyAgICAgICAgICB2bXMxMQoxOTIuMTY4LjEuMTEyICAgdm1zMTIucmhjZS5jYyAgICAgICAgICB2bXMxMgo=
kind: Secret
metadata:
  creationTimestamp: "2023-05-30T08:04:35Z"
  name: mysecret2
  namespace: nssec
  resourceVersion: "39007"
  selfLink: /api/v1/namespaces/nssec/secrets/mysecret2
  uid: 22856070-7c5c-494e-9230-69a64fabf841
type: Opaque
[root@vms10 secret]#

这里hosts就是文件名,下面的值是hosts文件里的内容。这段内容也可以直接通过如下命令来获取。

##########实操验证##########
[root@vms10 secret]# kubectl get secrets mysecret2 -o jsonpath='{.data.hosts}'
MTI3LjAuMC4xICAgbG9jYWxob3N0IGxvY2FsaG9zdC5sb2NhbGRvbWFpbiBsb2NhbGhvc3Q0IGxvY2FsaG9zdDQubG9jYWxkb21haW40Cjo6MSAgICAgICAgIGxvY2FsaG9zdCBsb2NhbGhvc3QubG9jYWxkb21haW4gbG9jYWxob3N0NiBsb2NhbGhvc3Q2LmxvY2FsZG9tYWluNgoxOTIuMTY4LjEuMTEwICAgdm1zMTAucmhjZS5jYyAgICAgICAgICB2bXMxMAoxOTIuMTY4LjEuMTExICAgdm1zMTEucmhjZS5jYyAgICAgICAgICB2bXMxMQoxOTIuMTY4LjEuMTEyICAgdm1zMTIucmhjZS5jYyAgICAgICAgICB2bXMxMgo=[root@vms10 secret]# 
[root@vms10 secret]#

-o指的是输出的格式,这里以json格式输出,并获取data下hosts字段的值。

步骤4:解码。

上面这段输出通过管道传递给base64 -d后的结果是这样的。

##########实操验证##########
[root@vms10 secret]# kubectl get secrets mysecret2 -o jsonpath='{.data.hosts}' | base64 -d
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.110   vms10.rhce.cc          vms10
192.168.1.111   vms11.rhce.cc          vms11
192.168.1.112   vms12.rhce.cc          vms12
[root@vms10 secret]#

可以看到这个就是hosts文件的内容。

步骤5:创建一个包含两个文件的secret mysecret3。

##########实操验证##########
[root@vms10 secret]# kubectl create secret generic mysecret3 --from-file=/etc/hosts --from-file=/etc/issue
secret/mysecret3 created
[root@vms10 secret]#

这个secret里包含了两个文件:/etc/hosts和/etc/issue,即mysecret3里有两个key,分别是hosts和issue,它们的值分别是/etc/hosts和/etc/issue的内容。

步骤6:获取mysecret3的键值对。

##########实操验证##########
[root@vms10 secret]# kubectl get secrets mysecret3 -o yaml
apiVersion: v1
data:
  hosts: MTI3LjAuMC4xICAgbG9jYWxob3N0IGxvY2FsaG9zdC5sb2NhbGRvbWFpbiBsb2NhbGhvc3Q0IGxvY2FsaG9zdDQubG9jYWxkb21haW40Cjo6MSAgICAgICAgIGxvY2FsaG9zdCBsb2NhbGhvc3QubG9jYWxkb21haW4gbG9jYWxob3N0NiBsb2NhbGhvc3Q2LmxvY2FsZG9tYWluNgoxOTIuMTY4LjEuMTEwICAgdm1zMTAucmhjZS5jYyAgICAgICAgICB2bXMxMAoxOTIuMTY4LjEuMTExICAgdm1zMTEucmhjZS5jYyAgICAgICAgICB2bXMxMQoxOTIuMTY4LjEuMTEyICAgdm1zMTIucmhjZS5jYyAgICAgICAgICB2bXMxMgo=
  issue: XFMKS2VybmVsIFxyIG9uIGFuIFxtCgo=
kind: Secret
metadata:
  creationTimestamp: "2023-05-30T08:07:54Z"
  name: mysecret3
  namespace: nssec
  resourceVersion: "39387"
  selfLink: /api/v1/namespaces/nssec/secrets/mysecret3
  uid: c729f03e-4fcb-4b1b-bd99-d450cb9b35fb
type: Opaque
[root@vms10 secret]#

从上面可以看到两个键hosts和issue,以及它们对应的值,还可以通过如下命令分别获取其key的值。

##########实操验证##########
[root@vms10 secret]# kubectl get secrets mysecret3 -o jsonpath='{.data.hosts}'
MTI3LjAuMC4xICAgbG9jYWxob3N0IGxvY2FsaG9zdC5sb2NhbGRvbWFpbiBsb2NhbGhvc3Q0IGxvY2FsaG9zdDQubG9jYWxkb21haW40Cjo6MSAgICAgICAgIGxvY2FsaG9zdCBsb2NhbGhvc3QubG9jYWxkb21haW4gbG9jYWxob3N0NiBsb2NhbGhvc3Q2LmxvY2FsZG9tYWluNgoxOTIuMTY4LjEuMTEwICAgdm1zMTAucmhjZS5jYyAgICAgICAgICB2bXMxMAoxOTIuMTY4LjEuMTExICAgdm1zMTEucmhjZS5jYyAgICAgICAgICB2bXMxMQoxOTIuMTY4LjEuMTEyICAgdm1zMTIucmhjZS5jYyAgICAgICAgICB2bXMxMgo=[root@vms10 secret]# 
[root@vms10 secret]# kubectl get secrets mysecret3 -o jsonpath='{.data.issue}'
XFMKS2VybmVsIFxyIG9uIGFuIFxtCgo=[root@vms10 secret]# 
[root@vms10 secret]#

这种用法一般用在创建pod的时候给pod传递文件,后面讲解如何使用secret时会详细描述。

方法3:变量文件的方法

第3种创建secret的方法是,通过创建变量文件的方式创建一个文件,里面的格式为:

变量1=值1
变量2=值2

这种格式,等号前面的为key,等号后面的为value,看下面的例子。

步骤1:创建变量文件env.txt。

##########实操验证##########
[root@vms10 secret]# cat env.txt 
xx=tom
yy=redhat
[root@vms10 secret]#

在env.txt里定义了两个变量xx和yy,其值分别为tom和redhat。

步骤2:创建secret。

##########实操验证##########
[root@vms10 secret]# kubectl create secret generic mysecret4 --from-env-file=env.txt
secret/mysecret4 created
[root@vms10 secret]#

方法4:通过yaml文件的方式

如同创建pod一样,可以写一个secret的yaml文件,然后通过kubectl apply来创建。下面的例子里将会创建一个名字为mysecret5的secret,里面包含两个键值对:xx=tom和yy=redhat。

步骤1:先求出两个值tom和redhat对应的base64编码之后的值。

##########实操验证##########
[root@vms10 secret]# echo -n 'tom' | base64
dG9t
[root@vms10 secret]# echo -n 'redhat' | base64
cmVkaGF0
[root@vms10 secret]#

步骤2:创建yaml文件。

##########实操验证##########
[root@vms10 secret]# cat secret5.yaml 
apiVersion: v1
kind: Secret 
metadata:
  name: mysecret5
type: Opaque 
data:
  xx: dG9t 
  yy: cmVkaGF0
[root@vms10 secret]#

步骤3:创建secret。

##########实操验证##########
[root@vms10 secret]# kubectl apply -f secret5.yaml 
secret/mysecret5 created
[root@vms10 secret]# kubectl get secrets
NAME                  TYPE                                  DATA   AGE
default-token-cp9rm   kubernetes.io/service-account-token   3      102m
mysecret1             Opaque                                2      100m
mysecret2             Opaque                                1      95m
mysecret3             Opaque                                2      92m
mysecret4             Opaque                                2      25m
mysecret5             Opaque                                2      7s
[root@vms10 secret]#

步骤4:删除某secret。

##########实操验证##########
[root@vms10 secret]# kubectl delete secrets mysecret5
secret "mysecret5" deleted
[root@vms10 secret]#

使用secret

上面已经把secret创建出来了,那么如何在pod里使用这些secret呢?主要有两种方式来引用卷,即卷和变量的方式。

方法1:以卷的方式

这种方式主要是在pod的yaml文件里,创建一个类型为secret的卷,然后挂载到容器里某个指定的目录里,容器创建好之后,会在容器的挂载目录里创建一个文件,此文件的文件名为secret里的key,文件的内容为对应key的value。这种以卷的方式引用secret的主要作用是往pod里传递文件。

下面创建一个名字为pod1的pod,以卷的方式挂载mysecret2到容器的/etc/test目录里。

步骤1:创建pod的yaml文件。

##########实操验证##########
[root@vms10 secret]# cat pod1.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null 
  labels:
    run: pod1
  name: pod1
spec:
  volumes:
  - name: xx 
    secret:
      secretName: mysecret2
  containers:
  - image: nginx 
    imagePullPolicy: IfNotPresent 
    name: pod1
    volumeMounts:
    - name: xx 
      mountPath: "/etc/test"
status: {}  
[root@vms10 secret]#

在这个yaml文件里创建了一个名字为xx、类型为secret的卷,使用mysecret2,在pod1里的容器里把xx这个卷挂载到/etc/test目录里。因为mysecret2有一个键hosts,值为文件/etc/hosts的内容(前面演示过),所以在容器/etc/test目录里有一个文件hosts,内容就是/etc/hosts的内容。

步骤2:创建此pod。

##########实操验证##########
[root@vms10 secret]# kubectl apply -f pod1.yaml
pod/pod1 created
[root@vms10 secret]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          4s
[root@vms10 secret]#

步骤3:查看此pod里/etc/test有什么文件。

##########实操验证##########
[root@vms10 secret]# kubectl exec pod1 -- ls /etc/test
hosts
[root@vms10 secret]#

可以看到里面有一个文件hosts。

步骤4:查看这个文件的内容。

##########实操验证##########
[root@vms10 secret]# kubectl exec pod1 -- cat /etc/test/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.110   vms10.rhce.cc          vms10
192.168.1.111   vms11.rhce.cc          vms11
192.168.1.112   vms12.rhce.cc          vms12
[root@vms10 secret]#

可以看到就是/etc/hosts的内容,删除此pod。

如果在上面pod1里定义volumes的时候,引用的是mysecret3(mysecret3里使用了两个文件),则在容器里的/etc/test里会创建两个文件:hosts和issue。但是如果使用mysecret3,不想把两个文件全部写入挂载点,只想使用一个文件的话,那怎么办?此时可以用subPath来解决这个问题。

步骤5:修改pod1.yaml,内容如下。

##########实操验证##########
[root@vms10 secret]# cat pod1.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null 
  labels:
    run: pod1
  name: pod1
spec:
  volumes:
  - name: xx 
    secret:
      secretName: mysecret3
  containers:
  - image: nginx 
    imagePullPolicy: IfNotPresent 
    name: pod1
    volumeMounts:
    - name: xx 
      mountPath: "/etc/test/issue"
      subPath: issue
status: {}  
[root@vms10 secret]#

这里创建一个卷xx,里面使用的是mysecret3,在容器里引用卷xx,这里比刚才多了一个subPath,即只引用issue这个文件。

subpath指定从secret里引用哪个文件,把这个文件写入/etc/test里,然后命名为issue。如果想命名为其他名字,比如filex,则mountPath的值应该写/etc/test/filex。如果mountPath的值只写为/etc/test的话,则是把issue写入/etc/里,然后命名为test,即/etc/test是一个文件,内容为issue的内容。

步骤6:查看容器里/etc/test的内容。

##########实操验证##########
[root@vms10 secret]# kubectl exec pod1 -- ls /etc/test
issue
[root@vms10 secret]#

可以看到此容器里只有一个文件hosts。

步骤7:查看/etc/test/hosts的内容。

##########实操验证##########
[root@vms10 secret]# kubectl exec pod1 -- cat /etc/test/issue
\S
Kernel \r on an \m

[root@vms10 secret]#

可以看到把/etc/issue的内容写入容器里了。

如果要修改服务的配置文件,比如nginx的配置文件,就可以不必重新编译镜像,只要把写好的一个nginx.conf创建为一个secret,然后在创建pod的时候,通过卷的方式就可以把新的配置文件写入pod里了。

方法2:以变量的方式

前面讲了,在定义pod的yaml文件的时候,如果想使用变量的话,格式为:

env:
- name: 变量名
  value: 值

但是如果想从secret引用值的话,此处就不再写value了,而是写valueFrom,即从什么地方来引用这个变量的值,如下所示。

env:
- name: 变量名
  valueFrom:
    secretKeyRef:
      name: secretX 
      key: keyX

意思是,变量的值将会使用secretX里的keyX这个键所对应的值。

前面创建mysecret1的时候,通过--from-literal=xx=tom --from-literral=yy=redhat创值了2个键值对,即xx=tom、yy=redhat。

下面创建一个mysql的pod,MYSQL_ROOT_PASSWORD这个变量的值不直接写在yaml文件里,而是引用mysecret1里的yy这个键的值。

步骤1:创建pod的yaml文件。

##########实操验证##########
[root@vms10 secret]# cat pod2.yaml 
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null 
  labels:
    run: pod2
  name: pod2
spec:
  containers: 
  - image: hub.c.163.com/library/mysql:latest 
    imagePullPolicy: IfNotPresent
    name: pod2
    env:
    - name: MYSQL_ROOT_PASSWORD 
      valueFrom: 
        secretKeyRef: 
          name: mysecret1
          key: yy 
[root@vms10 secret]#

此yaml文件是用于创建一个MySQL的pod,在创建容器时,需要指定一个变量MYSQL_ROOT_PASSWORD(用env下的name指定)。这个变量的值并没有直接用value写出来,而是用valueFrom从其他地方引用过来。这里通过secretKeyRef里的name引用mysecret1,然后通过key引用mysecret1里的yy这个键,整体的意思就是,MYSQL_ROOT_PASSWORD的值使用的是mysecret里yy这个键对应的值(为redhat)。

步骤2:创建pod并验证。

##########实操验证##########
[root@vms10 secret]# kubectl apply -f pod2.yaml 
pod/pod2 created
[root@vms10 secret]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
pod2   1/1     Running   0          37s
[root@vms10 secret]#

步骤3:获取pod的IP。

##########实操验证##########
[root@vms10 secret]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP             NODE            NOMINATED NODE   READINESS GATES
pod2   1/1     Running   0          60s   10.244.81.93   vms11.rhce.cc   <none>           <none>
[root@vms10 secret]#

步骤4:安装MariaDB,然后用root和密码redhat登录验证。

##########实操验证##########
[root@vms10 secret]# yum install -y mariadb
[root@vms10 secret]# mysql -uroot -predhat -h10.244.81.93
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.18 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]>

登录成功,说明密码引用成功。

自行删除此pod及刚创建的secret。

猜你喜欢

转载自blog.csdn.net/guolianggsta/article/details/131473710
今日推荐