书籍来源:《CKA/CKAD应试指南:从Docker到Kubernetes完全攻略》
一边学习一边整理读书笔记,并与大家分享,侵权即删,谢谢支持!
附上汇总贴:Kubernetes认证考试自学系列 | 汇总_热爱编程的通信人的博客-CSDN博客
secret的主要作用是存储密码信息,以及往pod里传递文件。secret以键值对的方式存储,格式如下。
键=值 或者是 key=value
其中这里的“值”不是以明文的方式存储的, 而是通过base64编码过的。
7.1.1 创建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]# kube ns 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-g6nch kubernetes.io/service-account-token 3 25d
[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-g6nch kubernetes.io/service-account-token 3 25d
mysecret1 Opaque 2 43s
[root@vms10 secret]#
步骤3:查看mysecret1的具体属性。
[root@vms10 secret]# kubectl describe secrets mysecret1
Name: mysecret1
Namespace: nssec
Labels: <none>
... 输出 ...
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
...
[root@vms10 secret]#
上面data字段里列出来的就是mysecret1的键值对, 其中xx和yy的值都是经过base64编码的,需要解码才能看到具体值。
步骤5:解码。
[root@vms10 secret]# echo "dG9t" | base64 --decode
tom[root@vms10 secret]#
[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.26.10 vms10.rhce.cc vms10
192.168.26.11 vms11.rhce.cc vms11
192.168.26.12 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:
MTI3LjAuMC4XICAgbG9JYWxob3N0IGXVY2FsaG9zdC5sb2NhbGRvbWFpbiBsb2NhbGhvc3Q0IGxvY2FsaG9zdDQubG9jYwxkb21haw40Cjo6MSAgICAgIAgIGxvY2FSaG9zdCBsb2NhbGhvc3QubG9jYwxk2iebG9jYWxob3NeNiBsb2NhbGhvc3Q2LmxvY2FsZG9tYWluNeOXOTTUMTY4LiT2LiEWIHZtCzEwLnJOYVTZPSZG9CYWlUNgoxOTIUMTY4LJI2LJEWIHZLCxMi5yaGNlLmNjICB2bXMxMgo=2MgIHZtczEwCjE5Mi4xNjguMjYuMTEgdm1zMTEucmhi7SVVAAm1TMTEKMTKVLiE20C4yNi4xVi
... 大量输出 ...
[root@vms10 secret]#
这里hosts就是文件名, 下面的值是hosts文件里的内容。这段内容也可以直接通过如下命令来获取。
[root@vms10 secret]# kubectl get secrets mysecret2 -o jsonpath='{.data.hosts}'
MTI3LjAuMC4XICAgbG9JYWxob3N0IGXVY2FsaG9zdC5sb2NhbGRvbWFpbiBsb2NhbGhvc3Q0IGxvY2FsaG9zdDQubG9jYwxkb21haw40Cjo6MSAgICAgIAgIGxvY2FSaG9zdCBsb2NhbGhvc3QubG9jYwxk2iebG9jYWxob3NeNiBsb2NhbGhvc3Q2LmxvY2FsZG9tYWluNeOXOTTUMTY4LiT2LiEWIHZtCzEwLnJOYVTZPSZG9CYWlUNgoxOTIUMTY4LJI2LJEWIHZLCxMi5yaGNlLmNjICB2bXMxMgo=2MgIHZtczEwCjE5Mi4xNjguMjYuMTEgdm1zMTEucmhi7SVVAAm1TMTEKMTKVLiE20C4yNi4xVi
[root@vms10 secret]#
步骤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.26.10 vms10.rhce.cc vms10
192.168.26.11 vms11.rhce.cc vms11
192.168.26.12 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: MTI3LjAuMC4XICAgbG9JYWxob3N0IGXVY2FsaG9zdC5sb2NhbGRvbWFpbiBsb2NhbGhvc3Q0IGxvY2FsaG9zdDQubG9jYwxkb21haw40Cjo6MSAgICAgIAgIGxvY2FSaG9zdCBsb2NhbGhvc3QubG9jYwxk2iebG9jYWxob3NeNiBsb2NhbGhvc3Q2LmxvY2FsZG9tYWluNeOXOTTUMTY4LiT2LiEWIHZtCzEwLnJOYVTZPSZG9CYWlUNgoxOTIUMTY4LJI2LJEWIHZLCxMi5yaGNlLmNjICB2bXMxMgo=2MgIHZtczEwCjE5Mi4xNjguMjYuMTEgdm1zMTEucmhi7SVVAAm1TMTEKMTKVLiE20C4yNi4xVi
isue:XFMKS2VybmVsIFxyIG9uIGFuIFxtCgoxOTIuMTY4LjI2LjEwCg==
kind:Secret
从上面可以看到两个键hosts和issue, 以及它们对应的值, 还可以通过如下命令分别获取其key的值。
kubectl get secrets mysecret3 -o json path='{.data.hosts}'
kubectl get secrets mysecret3 -o json path='{.data.issue}'
这种用法一般用在创建pod的时候给pod传递文件。
方法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/mysecret3 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/mysecret4 created
[root@vms10 secret]# kubectl get secrets
NAME TYPE DATA AGE
default-token-g6nch kubernetes.io/service-account-token 3 25d
mysecret1 Opaque 2 16m
mysecret2 Opaque 2 8m40s
mysecret3 Opaque 2 2m59s
mysecret4 Opaque 2 2m
mysecret5 Opaque 2 3s
[root@vms10 secret]#
步骤4:删除某secret。
[root@vms10 secret]# kubectl delete secrets mysecret5
secret "mysecret5" deleted
[root@vms10 secret]#
7.1.2 使用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 7s
步骤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.26.10 vms10.rhce.cc vms10
192.168.26.11 vms11.rhce.cc vms11
192.168.26.12 vms12.rhce.cc vms12
[root@vms10 secret]#
可以看到就是/etc/hosts的内容, 删除此pod。
如果使用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这个文件。
步骤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
192.168.26.10
[root@vms10 secret]#
可以看到把/etc/issue的内容写入容器里了。
方法2:以变量的方式
前面讲了, 在定义pod的yaml文件的时候, 如果想使用变量的话, 格式为:
env:
- name: 变量名
value: 值
但是如果想从secret引用值的话, 此处就不再写value了, 而是写valueFrom, 即从什么地方来引用这个变量的值,如下所示。
env:
- name: 变量名
valueFrom:
secretKeyRef:
name: secretX
key: keyX
意思是, 变量的值将会使用secretX里的keyX这个键所对应的值。
下面创建一个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]#
这里通过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 14s
[root@vms10 secret]#
步骤3:获取pod的IP。
[root@vms10 secret]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP ...
pod2 1/1 Running 0 18s 10.244.3.39 ...
[root@vms10 secret]#
步骤4:安装MariaDB, 然后用root和密码redhat登录验证。
[root@vms10 secret]# mysql -uroot -predhat -h10.244.3.39
Welcome to the MariaDB monitor. Command send 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。