实验环境:

在这里插入图片描述
按照图示部署好了K8s集群,一个Master,两个worker nodes。

没有密码管理的场景:

master上编辑mysql的yaml文件并应用:

[root@vms201 secret_manager]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod1
  name: mysqldb
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: mysql:latest
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: mysql111
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
[root@vms201 secret_manager]# kubectl apply -f pod.yaml
pod/mysqldb created

通过yaml文件设置的环境变量,登陆mysql数据库,首先要找到运行的node为vms203.rhce.cc:

[root@vms201 secret_manager]# kubectl get pod mysqldb -o wide
NAME      READY   STATUS    RESTARTS   AGE     IP              NODE             NOMINATED NODE   READINESS GATES
mysqldb   1/1     Running   0          7m42s   10.244.185.93   vms203.rhce.cc   <none>           <none>

在vms203.rhce.cc上:进入mysql容器,用设置的账号密码登陆mysql。

[root@vms203 ~]# docker exec -it 8106c3ed3f52  bash
root@mysqldb:/# mysql -uroot -pmysql111
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 8.0.25 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

通过在yaml文件直接设置容器的密码(或者其他敏感信息)十分的方便,但是由于密码在yaml文件中是明文的,十分不安全。所以如何保护用户的密码等敏感信息,则需要用K8s的密码管理功能来完成。

K8s的密码管理分为两种:

  1. secret
  2. configmap–cm

一、secret:

使用方式:

  1. 以变量的方式;(推荐,用来保存密码)
  2. 以卷的方式。

secret的类型:

  1. Opaque:base64编码格式的Secret,用来存储密码、密钥等;但数据也通过base64 –decode解码得到原始数据,所有加密性很弱。(本节重点)
  2. kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息,在yaml文件中可以使用imagePullSecrets来引用。
  3. kubernetes.io/service-account-token: 用于被serviceaccount引用。serviceaccout创建时Kubernetes会默认创建对应的secret。Pod如果使用了serviceaccount,对应的secret会自动挂载到Pod目录/run/secrets/ kubernetes.io/serviceaccount中。

如何创建Opaque的secret:

secret以键值对的方式存在。

方式1: 命令行的方式(推荐)

语法:

kubectl create secret generic mysecret1 --from-literal=user=tom --from-literal=键1=值1 --from-literal=键2=值2
kubectl create secret generic mysecret1 --from-file=user=tom --from-file=/etc/hosts(文件信息)

第二种语法secret的键为去掉路径的文件名hosts,值为文件的内容。

创建并查看其中的secret:

[root@vms201 secret_manager]# kubectl create secret generic mysecret1 --from-literal=user=tom --from-literal=password1=redhat --from-literal=password2=redhat
secret/mysecret1 created
[root@vms201 secret_manager]# kubectl get secrets mysecret1
NAME        TYPE     DATA   AGE
mysecret1   Opaque   3      32s
[root@vms201 secret_manager]# kubectl describe secrets mysecret1
Name:         mysecret1
Namespace:    3-volume
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password1:  6 bytes
password2:  6 bytes
user:       3 bytes

以yaml文件输出:

[root@vms201 secret_manager]# kubectl get secrets mysecret1 -o yaml
apiVersion: v1
data:
  password1: cmVkaGF0
  password2: cmVkaGF0
  user: dG9t
kind: Secret
metadata:
  creationTimestamp: "2021-07-06T13:52:58Z"
  name: mysecret1
  namespace: 3-volume
  resourceVersion: "164131"
  selfLink: /api/v1/namespaces/3-volume/secrets/mysecret1
  uid: 1a92f9d7-560b-4fca-969e-c8da94554468
type: Opaque

其中存储的信息被base64编码过,可以解码检查一下是不是保存的密码redhat:

[root@vms201 secret_manager]# echo cmVkaGF0 | base64 -d
redhat

以json格式输出:

[root@vms201 secret_manager]# kubectl get secrets mysecret1 -o jsonpath={.data.password1} | base64 -d
redhat

其他方式:

1.设置文件:

cat env.txt
user=tom
password1=redhat
password2=redhat

kubectl create secret generic mysecret3--from-env-file=env.txt

2.自己编写yaml文件:

echo -n 'tom' | base64
echo -n 'redhat' | base64

apiVersion: v1
kind: Secret
metadata:
name: mysecret4
type: Opaque
data:
user: dG9t
password1: cmVkaGF0
password2: cmVkaGF0

以变量的方式引用Opaque的secret:

编辑pod的yaml文件:

[root@vms201 secret_manager]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod1
  name: mysqldb
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: mysql:latest
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
    env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        secretKeyRef:
          name: mysecret1
          key: password1
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

yaml文件引用了之前创建的mysecret1和其password1。应用yaml文件生成mysql的pod:

[root@vms201 secret_manager]# kubectl apply -f pod.yaml
pod/mysqldb created

查看其运行在哪个worker node上,并在在其node上登陆mysql:

[root@vms201 secret_manager]# kubectl get pod mysqldb  -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP              NODE             NOMINATED NODE   READIN        ESS GATES
mysqldb   1/1     Running   0          69s   10.244.185.94   vms203.rhce.cc   <none>           <none>

[root@vms203 ~]# docker exec -it bc79448a1142 bash
root@mysqldb:/# mysql -uroot -predhat
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.25 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

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

mysql>

以卷的方式引用Opaque的secret:

修改pod的yaml文件,并应用:

[root@vms201 secret_manager]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod1
  name: podsecret
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: v1
    secret:
      secretName: mysecret1
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
    volumeMounts:
    - name: v1
      mountPath: /xx
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}


[root@vms201 secret_manager]# kubectl apply -f pod.yaml
pod/podsecret created

进入此pod查看secret是否被挂载进来:在/xx目录下有mysecret1的下记录的密码信息。

[root@vms201 secret_manager]# kubectl exec -it podsecret -- bash
root@podsecret:/# cat /xx/password1
redhatroot

如果只想传递mysecret1下的指定信息,例如password1到容器内,需要修改yaml文件,在mountPath下一行加入subPath,指定password1:

    - name: v1
      mountPath: /xx/password1
      subPath: password1  

这样一来,仅会将mysecret1的password1挂载到容器的/xx/下,命名为password1(可修改)。

以卷的方式引用Opaque的secret的常用应用:例如将Nginx的配置文件设置为secret,然后在设置Nginx的pod时,将其挂载到/etc/nginx/nginx.conf文件下,这样就传递了Nginx的配置文件,但是不推荐这种方法,在edit secret时,其中的内容是被base64编码的的,不方便修改。

二、configmap–cm

使用方式:

  1. 以变量的方式;
  2. 以卷的方式。(推荐,来来传递配置文件)

其创建方式和secret类似:这里只说明了以literal的方式创建,同样可以file的方式创建

[root@vms201 secret_manager]# kubectl create cm  mycm1 --from-literal=password1=redhat
configmap/mycm1 created
[root@vms201 secret_manager]# kubectl get cm mycm1
NAME    DATA   AGE
mycm1   1      26s
[root@vms201 secret_manager]# kubectl describe cm mycm1
Name:         mycm1
Namespace:    3-volume
Labels:       <none>
Annotations:  <none>

Data
====
password1:
----
redhat
Events:  <none>

当我们以yaml文件输出cm时,可以看到信息没有被base64编码:

[root@vms201 secret_manager]# kubectl get cm mycm1 -o yaml
apiVersion: v1
data:
  password1: redhat
kind: ConfigMap
metadata:
  creationTimestamp: "2021-07-06T15:04:26Z"
  name: mycm1
  namespace: 3-volume
  resourceVersion: "170439"
  selfLink: /api/v1/namespaces/3-volume/configmaps/mycm1
  uid: e3d3d3b2-f47f-41eb-9aea-dc7d1bcd7732

以变量的方式调用cm:

其yaml文件如下:

[root@vms201 secret_manager]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod1
  name: mysqldb
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: mysql:latest
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
    env:
    - name: MYSQL_ROOT_PASSWORD
      valueFrom:
        configMapKeyRef:
          name: mycm1
          key: password1
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

以卷的方式调用cm:

在master上保存nginx.conf文件:

[root@vms201 secret_manager]# cat nginx.conf
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

创建mycm2:

[root@vms201 secret_manager]# kubectl create cm mycm2 --from-file nginx.conf
configmap/mycm2 created

编辑pod的yaml文件,将mycm2挂载到指定目录:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod1
  name: podcm
spec:
  terminationGracePeriodSeconds: 0
  volumes:
  - name: v1
    configMap:
      name: mycm2
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
    volumeMounts:
    - name: v1
      mountPath: /etc/nginx/nginx.conf
      subPath: nginx.conf
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

生成对应的pod:

[root@vms201 secret_manager]# kubectl apply -f pod.yaml
pod/podcm created

可以在pod中查看到到对应的配置文件:

[root@vms201 secret_manager]# kubectl exec -it podcm -- bash
root@podcm:/# cat /etc/nginx/nginx.conf
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

如果想要修改这个nginx的配置文件,仅需要在master上edit对应的cm即可:

[root@vms201 secret_manager]# kubectl edit cm mycm2

由于其中保存的信息是明文,方便修改。然后删除掉当前pod,重新创建即可。

K8s创建后存在的一些cm:

[root@vms201 secret_manager]# kubectl get cm -n kube-system
NAME                                 DATA   AGE
calico-config                        4      5d1h
coredns                              1      5d1h
extension-apiserver-authentication   6      5d1h
kube-proxy                           2      5d1h
kube-root-ca.crt                     1      5d1h
kubeadm-config                       2      5d1h
kubelet-config-1.21                  1      5d1h

这些cm都可以修改,完成后删除重建对应pod即可。

参考资料:
《老段CKA课程》

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐