一、Configmap

1.1 关于Configmap

Configmap 是k8s中的资源对象,用于保存非机密性的配置的,数据可以用key/value键值对的形式保存,也可以使用文件的形式保存。

 

k8s中的pod(服务)都有自己的配置文件,如果需要扩容时,为保证服务的一致性,可以将Configmap做成volume,并挂载到新扩容的服务上。

1.2 Configmap 创建方法

1.2.1 命令行方式创建

命令行中指定configmap参数创建,通过使用--from-literal 指定参数

 

命令解释:

kubectl create configmap nginx --from-literal=nginx-port=80

create configmap  (创建), nginx (为创建的名称),--from-literal=(定义key)=(key的值)

#创建configmap 
[root@k8s-master ~]# kubectl create configmap nginx --from-literal=nginx-port=80 --from-literal=server-name=mynginx
configmap/nginx created

#查看 (可简写为cm)
[root@k8s-master ~]# kubectl get cm | grep nginx 
nginx              2      17s

#查看详细信息
[root@k8s-master ~]# kubectl describe cm nginx
Name:         nginx
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx-port:         //可以看到创建时定义的值
----
80
server-name:
----
mynginx

BinaryData
====

Events:  <none>

1.2.2 通过文件方式创建

通过指定的文件创建一个Configmap,--from-file=(文件名称)

#创建一个nginx的conf文件 (简写)
[root@k8s-master ~]# cat nginx.conf 
server {
  server_name www.nginx.com
  listen 80;
  root /home/nginx/www/
}

#指定文件创建configmap    (--from-file=(key值)=(指定的文件))
[root@k8s-master ~]# kubectl create configmap nginx-01 --from-file=key01=./nginx.conf
configmap/nginx-01 created

[root@k8s-master ~]# kubectl get cm | grep nginx
nginx-01           1      7s

[root@k8s-master ~]# kubectl describe cm nginx-01
Name:         nginx-01
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
key01:     //指定的key ,下面是对应key值的是指定的配置文件中的内容,如果创建时不指定key(--from-file=./nginx.conf),那么这里显示的就是文件的名称
----
server {
  server_name www.nginx.com
  listen 80;
  root /home/nginx/www/
}


BinaryData
====

Events:  <none>

1.2.3 指定目录创建

可以将目录下的文件都做成configmap

#创建目录及文件
[root@k8s-master ~]# mkdir test-01
[root@k8s-master ~]# cat test-01/001.cnf 
server-id=1
[root@k8s-master ~]# cat test-01/002.cnf 
server-id=2

#指定目录创建configmap
[root@k8s-master ~]# kubectl create configmap mysql --from-file=./test-01/
configmap/mysql created

[root@k8s-master ~]# kubectl get cm 
NAME               DATA   AGE
kube-root-ca.crt   1      110d
mysql              2      6s

[root@k8s-master ~]# kubectl describe cm mysql
Name:         mysql
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data          //如下显示目录中两个文件的配置信息。
====
001.cnf:
----
server-id=1

002.cnf:
----
server-id=2


BinaryData
====

Events:  <none>

1.2.4 通过yaml文件创建

如下(1.2.4.1~~1.2.4.2)两种方式使用环境变量的方式将configmap注入到pod容器中

2.4.3使用volume卷方式进行挂载到pod容器内。

使用环境变量方式进行
1.2.4.1 使用configMapKeyRef

通过环境变量引入:使用env字段下的configMapKeyRef编写configmap资源清单的yaml文件来创建

通过如下命令查看 configmap的字段信息: kubectl explain cm (configmap可缩写为cm) 如下图所示:

k8s 配置管理中心Configmap 和 Secret 实现微服务配置管理_linux

#编写cm的yaml文件
[root@k8s-master ~]# vim cm01.yaml
 
apiVersion: v1
kind: ConfigMap
metadata:        #定义configmap的名称和标签
  name: cm01
  labels:
    app: app-1
data:            #定义key的数据
    a: a-01
    b: b-01

#创建
[root@k8s-master ~]# kubectl apply -f cm01.yaml 
configmap/cm01 created

[root@k8s-master ~]# kubectl get cm | grep cm01
cm01               2      33s

#创建pod 引用configmap中的内容
[root@k8s-master ~]# vim pod-cm01.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-01
spec:
  containers:             #创建容器
  - name: my-busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    env:                  #定义环境变量
    - name: aaa           #定义第一个环境变量aaa
      valueFrom: 
        configMapKeyRef:  #定义使用configmap类型
          name: cm01      #指定创建好的configmap的名字
          key: a          #指定configmap中的key(表示将cm01中的key ”a“ 的值赋给了上面定义的变量aaa)
    - name: bbb           #定义第二个环境变量bbb
      valueFrom:
        configMapKeyRef:
          name: cm01
          key: b
  restartPolicy: Never    #定义pod重启策略,never 从不重启


#创建pod
[root@k8s-master ~]# kubectl apply -f pod-cm01.yaml 
pod/pod-01 created

[root@k8s-master ~]# kubectl get pods | grep pod
pod-01                               1/1     Running   0          12s

#进入pod进行验证
[root@k8s-master ~]# kubectl exec -it pod-01 -- /bin/sh
/ # printenv | grep -Ei "aaa|bbb"     //查看容器中的环境变量,已经将创建的configmap中定义的key值引用到了容器中。
aaa=a-01
bbb=b-01
1.2.4.2 使用envfrom
#编写yaml文件
[root@k8s-master ~]# vim pod-env.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-02
spec:
  containers:
  - name: mybusybox
    image: busybox
    imagePullPolicy: IfNotPresent
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    envFrom:           #使用envfrom环境变量形式进行赋值注入到pod
    - configMapRef:    #定义使用configmap类型
       name: cm01      #指定创建好的configmap的名字
  restartPolicy: Never

#创建
[root@k8s-master ~]# kubectl apply -f pod-env.yaml 
pod/pod-02 created

[root@k8s-master ~]# kubectl get pods | grep pod-02
pod-02                               1/1     Running   0          9s

#进入pod容器中验证
[root@k8s-master ~]# kubectl exec -it pod-02 -- /bin/sh
/ # printenv | grep -Ei "a=|b="  //与使用env字段引用变量不同的是,使用envfrom即将configmap直接注入到pod容器中,看到的变量内容也是configmap定义好的。
a=a-01
b=b-01
使用volume方式进行
1.2.4.3 使用volume 方式创建

上方两种方式是使用环境变量的方式将configmap注入到容器中,如下将使用存储卷的方式将configmap做成volume,然后将其挂到pod容器中进行使用。

#编写configmap的yaml文件
[root@k8s-master ~]# vim cm01.yaml 

apiVersion: v1
kind: ConfigMap
metadata:        #定义configmap的名称和标签
  name: cm01
  labels:
    app: app-1
data:            #定义key的数据
    a: a-01
    b: b-01
    ccc.cnf: |   #"|" 表示该key下面可以定义多行的内容(可用于配置文件,该行定义问件名称,下面定义文件内容)
      Hi
      How are you! 

#创建更新
[root@k8s-master ~]# kubectl apply -f cm01.yaml 
configmap/cm01 configured

[root@k8s-master ~]# kubectl get cm | grep cm
cm01               3      57m

[root@k8s-master ~]# kubectl describe cm cm01
Name:         cm01
Namespace:    default
Labels:       app=app-1
Annotations:  <none>

Data
====
ccc.cnf:
----
Hi
How are you! 

a:
----
a-01
b:
----
b-01

BinaryData
====

Events:  <none>

#创建pod, 将configmap以volume的形式挂载进去
[root@k8s-master ~]# vim pod-volume.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-03
spec:
  containers:             #定义创建的容器
  - name: my-busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    volumeMounts:
    - name: vu-01         #写下面volume的名称
      mountPath: /config  #定义容器内的挂载路径
  volumes:
  - name: vu-01           #定义卷的名称    
    configMap:            #定义使用volume的类型是configma
      name: cm01          #写创建好的configmap的名称(表示将其做成volume卷)
  restartPolicy: Never    #定义pod重启策略,never 从不重启


#创建
[root@k8s-master ~]# kubectl apply -f pod-volume.yaml 
pod/pod-03 created

[root@k8s-master ~]# kubectl get pods | grep pod-03
pod-03                               1/1     Running   0          14s

#进入pod容器内验证
[root@k8s-master ~]# kubectl exec -it pod-03 -- /bin/sh
/ # ls /config/              //yaml文件中定义的路径已经在容器中自动创建并将宿主的configmap以volume的形式挂载到了pod容器中。
a        b        ccc.cnf
/ # cat /config/a 
a-01/ # 
/ # cat config/b 
b-01/ # 
/ # cat config/ccc.cnf 
Hi
How are you! 
/ #

1.3 Configmap 热更新

当configmap文件已经做成了volume并挂载到了pod容器中之后,该configmap文件发生了更新,pod中也需要一并实现更新

 

如上方2.4.3标题内容所示,该configmap文件已经挂载到了pod-03中,此时更新configmap,查看已挂载过的pod是否同步更新

#修改配置文件,在末尾添加一个新的key
[root@k8s-master ~]# tail -4 cm01.yaml 
    ccc.cnf: | 
      Hi
      How are you! 
    d: d-01         #添加该行

#更新文件
[root@k8s-master ~]# kubectl apply -f cm01.yaml 
configmap/cm01 configured

[root@k8s-master ~]# kubectl get cm | grep cm01
cm01               4      86m

#进入pod容器内验证  (已同步更新:pod中同步更新了d这个key,而查看该值为 d-01)
[root@k8s-master ~]# kubectl exec -it pod-03 -- /bin/sh
/ # ls config/
a        b        ccc.cnf  d
/ # cat config/d 
d-01/ #

PS:上方1.2.4.1~~1.2.4.2使用变量方式挂载configmap到pod中的方式,在更新了configmap之后,pod中是不会发生改变的。

二、Secret

2.1 关于Secret

与Configmap不同的是,Configmap是管理存放明文数据的,如配置文件,而对于一些敏感数据,如密码、私钥等数据保存时,需要使用到Secret

 

Secret解决了密码、token、秘钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。

 

想要使用Secret,pod需要引用Secret,pod有两种方式使用Secret:

1、作为volume中的文件被挂载到pod中的一个或者多个容器里。

2、当kubelet为pod拉取镜像时使用。

2.2 Secret 可用参数及类型

secret可选参数有三种:

1、generic: 通用类型,通常用于存储密码数据。


2、tls:      此类型仅用于存储私钥和证书。


3、docker-registry: 若要保存docker仓库的认证信息的话,就必须使用此种类型来创建。


Secret类型也可分为三种:

1、Service Account:用于被 serviceaccount 引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。


2、Opaque:base64编码格式的Secret,用来存储密码、秘钥等。可以通过base64 --decode解码获得原始数据,因此安全性弱


3、kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。


 

可使用如下命令进行查看secret的字段信息:如下图所示

kubectl explain secret

k8s 配置管理中心Configmap 和 Secret 实现微服务配置管理_linux_02

2.3 使用Secret

2.3.1 环境变量方式

创建一个pod并通过使用环境变量的方式引用Secret至pod容器内

#创建一个secret 名字为my-passwd 定义其key为passwd且其值为123456(密码)
[root@k8s-master ~]# kubectl create secret generic my-passwd --from-literal=passwd=123456
secret/my-passwd created

#查看  (类型是Opaque)
[root@k8s-master ~]# kubectl get secret 
NAME        TYPE     DATA   AGE
my-passwd   Opaque   1      5s

[root@k8s-master ~]# kubectl describe secret my-passwd
Name:         my-passwd
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
passwd:  6 bytes           //这里显示key即加过密的值(6 bytes)


#创建pod  yaml文件
[root@k8s-master ~]# vim pod-secret01.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-04
spec:
  containers:             #创建容器
  - name: my-httpd
    image: httpd
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    env:                  #定义环境变量
    - name: aaa           #定义环境变量aaa(pod中容器的环境变量名)
      valueFrom:
        secretKeyRef:     #定义secret类型
          name: my-passwd #指定创建好的secret的名字
          key: passwd     #指定secret中的key(表示将secret中的key ”passwd“ 的值赋给了上面定义的变量aaa)


#创建
[root@k8s-master ~]# kubectl apply -f pod-secret01.yaml 
pod/pod-04 created

[root@k8s-master ~]# kubectl get pods 
NAME     READY   STATUS    RESTARTS   AGE
pod-04   1/1     Running   0          6s

#进入pid容器中验证
[root@k8s-master ~]# kubectl exec -it pod-04 -- /bin/bash
root@pod-04:/usr/local/apache2# printenv | grep aaa
aaa=123456                //可以看到 secret中key (passwd)的值已经引入进了pod容器中

#ps:创建的secret定义的key的值是加密的,引入到pod容器中之后,自动的显示了信息

2.3.2 使用volume方式进行

#手动生成一个以base64加密的账户和密码
[root@k8s-master ~]# echo -n name001 | base64
bmFtZTAwMQ==

[root@k8s-master ~]# echo -n passwd | base64
cGFzc3dk

#将生成的加密过的账户及密码定义到secret
[root@k8s-master ~]# vim secret-01.yaml

cat pod-secret02.yaml
apiVersion: v1
kind: Secret
metadata:
  name: secret-02
type: Opaque        #定义secret 的类型为Opaque
data:
  useranme: bmFtZTAwMQ==    #这里定义上方生成的加密账户和密码
  password: cGFzc3dk


#创建更新secret
[root@k8s-master ~]# kubectl apply -f secret-01.yaml 
secret/secret-02 created

[root@k8s-master ~]# kubectl get secret 
NAME        TYPE     DATA   AGE
secret-02   Opaque   2      7s

[root@k8s-master ~]# kubectl describe secret secret-02
Name:         secret-02
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  6 bytes         //这里看到对应的值都是加密过的
useranme:  7 bytes

#创建pod将secret 以volume的形式挂到pod容器中
[root@k8s-master ~]# vim pod-secret02.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-05
spec:
  containers:               #定义创建的容器
  - name: my-nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: vu-02           #写下面volume的名称
      mountPath: /test      #定义容器内的挂载路径
      readOnly: true        #定义只读权限
  volumes:
  - name: vu-02             #定义卷的名称    
    secret:                 #定义使用volume的类型是secret
      secretName: secret-02 #写创建好的configmap的名称(表示将其做成volume卷)
      
      
#创建
[root@k8s-master ~]# kubectl apply -f pod-secret02.yaml 
pod/pod-05 created

[root@k8s-master ~]# kubectl get pods 
NAME     READY   STATUS    RESTARTS   AGE
pod-05   1/1     Running   0          4s

#进入pod容器中验证
[root@k8s-master ~]# kubectl exec -it pod-05 -- /bin/bash
root@pod-05:/# ls /test/                //挂载的/test路径下已经创建了两个secret的key(以文件形式存在)
password  useranme
root@pod-05:/# cat /test/useranme       //查看其值得出的结果是最开始使用base64加密之前的真是数据“name001”
name001root@pod-05:/# 
root@pod-05:/# cat /test/password 
passwdroot@pod-05:/#

2.3.3 测试热更新

测试更新secret文本的值,已挂载进pod容器中的值是否会发生改变

#创建一个以base64加密的值并在secret的yaml文件中增加
[root@k8s-master ~]# echo -n test | base64
dGVzdA==

[root@k8s-master ~]# tail -4 secret-01.yaml 
  useranme: bmFtZTAwMQ==
  password: cGFzc3dk
  test: test001           //增加其内容

#更新secret的yaml文件
[root@k8s-master ~]# kubectl apply -f secret-01.yaml 
secret/secret-02 configured

[root@k8s-master ~]# kubectl get secret 
NAME        TYPE     DATA   AGE
secret-02   Opaque   3      21m

[root@k8s-master ~]# kubectl describe secret secret-02
Name:         secret-02
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  6 bytes
test:      4 bytes
useranme:  7 bytes


#进入pod容器内验证
[root@k8s-master ~]# kubectl exec -it pod-05 -- /bin/bash 
root@pod-05:/# ls /test/
password  test	useranme
root@pod-05:/# cat /test/test 
testroot@pod-05:/#              //验证ok (见左侧值)