一、前言

     本章节我们继续学习Namespace、ConfigMap、Secret基础概念,了解他们基本用法和操作。NameSpace为命名空间,在同一集群中试下资源隔离。ConfigMap通过key-value的方式实现明文配置数据的保存,Secret与ConfigMap类似,不过是采用密文方式保存。

二、Namespace(命名空间)

     K8S集群可以通过Namespace创建多个"虚拟的集群",这些虚拟的集群之间可以完成隔离,包括访问权限,资源,支持了多租户特性,这点在实际工程中非常重要,比如对外的产品系统与内部的IT系统虽然都位于同一集群中,但是我们不希望他们之前可以有任何交互,此时就可以使用不同的Namespace进行隔离。

1、Namespace查看

   我们看下目前K8s中有哪些预置的Namespace,使用kubectl get ns指令

[root@k8s-master yaml]# kubectl get ns
NAME                   STATUS   AGE
default                Active   43d
kube-public            Active   43d
kube-system            Active   43d
kubernetes-dashboard   Active   42d

    一般情况下,环境安装完成后,就会有kube-system,default两个命名空间,与集群管理相关的,为整个集群提供服务的pod都放在kube-system,比如etcd,apiserver等。可以使用kubectl get pod -n <namespace>查看该命名空间下的pod列表。

[root@k8s-master yaml]# kubectl get pod -n kube-system
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-6b8c67b6b5-fsp65   1/1     Running   0          42d
calico-node-bwcfh                          1/1     Running   0          42d
calico-node-f976g                          1/1     Running   0          42d
coredns-6d8c4cb4d-9n8jg                    1/1     Running   0          43d
coredns-6d8c4cb4d-kmh4l                    1/1     Running   0          43d
etcd-k8s-master                            1/1     Running   0          43d
kube-apiserver-k8s-master                  1/1     Running   0          43d
kube-controller-manager-k8s-master         1/1     Running   0          43d
kube-proxy-db9dm                           1/1     Running   0          43d
kube-proxy-jqnnq                           1/1     Running   0          42d
kube-scheduler-k8s-master                  1/1     Running   0          43d

       而普通用户创建的pod,如果不指定Namespace,将统一放到default中,比如前一章节创建的busybox-pod就在default命名空间下。

[root@k8s-master yaml]# kubectl get pod -n default
NAME          READY   STATUS    RESTARTS   AGE
busybox-pod   1/1     Running   0          31m

2、Namespace创建

Namespace可以通过命令直接创建,也可以使用yaml文件创建

(1)使用命令创建

命令创建非常简单,指令为kubectl create ns <namespace>,如下例创建dev的命名空间。

[root@k8s-master yaml]# kubectl create ns dev
namespace/dev created
[root@k8s-master yaml]# kubectl get ns
NAME                   STATUS   AGE
default                Active   43d
dev                    Active   9s
kube-public            Active   43d
kube-system            Active   43d
kubernetes-dashboard   Active   42d

(2)使用yaml文件

编辑namespace-demo.yaml,内容如下:

[root@k8s-master yaml]# cat namespace-demo.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: dev

执行该yaml文件,创建dev命名空间。

[root@k8s-master yaml]# kubectl apply -f namespace-demo.yaml 
namespace/dev created
[root@k8s-master yaml]# kubectl get ns
NAME                   STATUS   AGE
default                Active   43d
dev                    Active   8s
kube-public            Active   43d
kube-system            Active   43d
kubernetes-dashboard   Active   42d

(3)使用namespace,创建pod

接下来我们创建一个pod,指定命名空间为dev,编辑ns-pod.yaml文件,其内如如下:

[root@k8s-master yaml]# cat ns-dev-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: ns-pod
  namespace: dev
  labels: 
     app: nginx-pod 
spec:
  containers:
  - name: nginx
    image: nginx:1.8

在metadata中指定namespace为dev,通过yaml文件创建pod,并查看命名空间下的pod列表。

[root@k8s-master yaml]# kubectl apply -f ns-dev-pod.yaml 
pod/ns-pod created
[root@k8s-master yaml]# kubectl get pod -n dev
NAME     READY   STATUS    RESTARTS   AGE
ns-pod   1/1     Running   0          86s

 可以看到pod正确创建,并在dev的命名空间下。

3、Namespace的删除

下面我们将dev的namespace删除

[root@k8s-master yaml]# kubectl delete ns dev
namespace "dev" deleted

该Namespace下的所有Pod也将一并删除。

关于Namspace的对于网络,计算资源的隔离性,我们将后续章节介绍。

三、ConfigMap

      在实际工程中,我们需要将配置数据与代码进行分离,比如说 Nginx 的 nginx.conf、Redis 的 redis.conf、MySQL 的 my.cnf 等等,这些配置文件会根据不同环境配置不同的数据,且在运行过程中,需要做到动态调整,及时更新。

      K8S提供了ConfigMap对象,用来保存配置数据,实现配置和镜像的解耦,便于应用配置的修改。

1、ConfigMap创建

     ConfigMap保存的是多组key-value键值对数据,其创建方式可以有多种,包括使用yaml文件,以及通过命令行创建。

(1)yaml文件

     编辑 data-config.yaml文件,其内容如下:

[root@k8s-master yaml]# cat data-config.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
 name: data-config
data:
 username: 'root'
 pwd: 'qwert'

    这个yaml文件比较简单,前面几个属性,如apiVersion,kind,metadata都比较熟悉了,这里主要介绍下data部分,定义了多组健值对,实现配置数据的定义,比如本例的username和pwd。

    使用命令创建ConfigMap对象。

[root@k8s-master yaml]# kubectl apply -f data-config.yaml 

   创建完成后,查看configMap列表和详情

[root@k8s-master yaml]# kubectl get cm
NAME               DATA   AGE
data-config        2      79m
kube-root-ca.crt   1      49d
[root@k8s-master yaml]# kubectl describe cm data-config
Name:         data-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
pwd:
----
qwert
username:
----
root

BinaryData
====

Events:  <none>

可以看到已创建名为data-config的ConfigName对象。

(2)命名行

      一般使用命令行,最常用的是通过已存在配置文件,直接生成ConfigMap对象。配置文件可以是具体的文件,也可以是配置文件的目录。接下来,我们演示下通过配置文件目录生成ConfigMap对象。

     首先创建config目录,再在该目录下创建username,pwd两个文件,其内容分别是其对应的value值,结果如下:

[root@k8s-master yaml]# cd config
[root@k8s-master config]# ls
pwd  username
[root@k8s-master config]# cat pwd
123456
[root@k8s-master config]# cat username
root

      使用命令根据config目录创建configMap对象。其命令行kubectl create configmap <configmap name> --from-file=< file path>

[root@k8s-master config]# kubectl create configmap file-configmap --from-file=./
configmap/file-configmap created

--from-file表示通过指定的文件或者目录来创建,本例中指定该目录为当前目录,即config。

同样看下创建结果。

[root@k8s-master config]# kubectl get cm
NAME               DATA   AGE
data-config        2      93m
file-configmap     3      71s
kube-root-ca.crt   1      49d
[root@k8s-master config]# kubectl describe cm file-configmap
Name:         file-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
pwd:
----
123456

username:
----
root


BinaryData
====
.pwd.swp: 159744 bytes

Events:  <none>

      当使用文件创建configMap时,默认情况下,key是文件名,value是文件里的内容。当然也可以使用kubectl create configmap <configmap name> --from-file=<key>=< file path>自定义key值。

2、ConfigMap的使用

     配置数据生成后,需要在容器中挂载并使用,这里也有两种使用方式,一种是环境变量方式,另一种是使用Volume 的方式。

(1)环境变量方式

   创建Pod的yaml文件configmap-env-pod.yaml ,其内容如下:

[root@k8s-master yaml]# cat configmap-env-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: configmap-env-pod
spec:
 containers:
  - name: test-busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    args:
    - sleep
    - "3600"
    env:
    - name: name
      valueFrom:
       configMapKeyRef:
        name: data-config
        key: username
    - name: password
      valueFrom:
       configMapKeyRef:
        name: data-config
        key: pwd

       该Pod配置一个busybox镜像的容器,容器启动了sleep 3600s,以便我们有时间进入容器进行操作。最核心的是env的配置,这里数据来源于前面的配置的data-config对象。这里我们用下面一张图来描述如何关联的。

      env变量的valueFrom使用configMapKeyRef,表明数据来源于configMap,name是指定该configMap的名称,即ConfigMap对象在metadata定义的name值,本例指定的是data-config;key指定使用该configMap的哪条健值,比如本例中,env定义了两个环境变量name和password,其值分别为data-configmap的配置的username以及pwd。

     下面我们创建该Pod,并进入到容器内部,打印出这两个环境变量的值。

[root@k8s-master yaml]# kubectl exec -it configmap-env-pod  sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo $name
root
/ # echo $password
qwert

    可以看到其环境变量的值,就是我们之前在data-config配置的。

(2)Volume 的方式

       除了环境变量的方式,还支持Volume的方式,至于Volume的内容我们K8S初级入门系列之九-共享存储会详细介绍,这里可以理解是容器挂载一个存储目录。

同样,我们编辑pod的yaml文件。内如如下;

[root@k8s-master yaml]# cat configmap-volume-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: configmap-volume-pod
spec:
 containers:
  - name: test-busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    args:
    - sleep
    - "3600"
    volumeMounts:
    - name: config-volume
      mountPath: /tmp/config
 volumes:
 - name: config-volume
   configMap:
     name: data-config

用图示的方式描述下之间的关系:

    containers容器的volumeMounts属性,定义一个volume挂载点,并挂载到指定目录mountPath(本例的/tmp/config)。该挂载点内容在Pod的volumes的定义,本例中volumes关联到指定的configMap,其名称为data-config。所以从分析看,容器里会创建/tmp/config目录,且该目录下能查看到data-config配置的内容。

    创建pod,并进入容器查看。

[root@k8s-master yaml]# kubectl exec -it configmap-volume-pod sh 
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cd /tmp/config
/tmp/config # ls
pwd       username
/tmp/config # cat pwd
qwert
/tmp/config # cat username
root
/tmp/config # 

     可以看到,在/tmp/config目录下生成了两个文件,分别为key值,即pwd,username,其内容对应的value值,与前面的分析保持一致。

     前面讲过,在实际工程中,配置文件是需要实时更新并生效的,我们看下configMap是否支持。修改data-config.yaml文件,将pwd改为"123456",并更新。

[root@k8s-master yaml]# cat data-config.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
 name: data-config
data:
 username: 'root'
 pwd: '123456'
[root@k8s-master yaml]# kubectl apply -f data-config.yaml 
configmap/data-config configured

再进入 容器内容看下是否有更新

[root@k8s-master yaml]# kubectl exec -it configmap-volume-pod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cd /tmp/config
/tmp/config # ls
pwd       username
/tmp/config # cat pwd
123456
/tmp/config # 

      看到已经更新,这个延时在秒级,需要注意的是,同步更新仅针对Volume挂载 的方式,而对于环境变量的方式是不生效的。有兴趣的同学可以测试下。

四、Secret

     configMap配置的数据是明文的,但是很多情况下,对于一些敏感数据,我们不希望暴露明文,需要采用加密的方式保存,比如上面例子中的username和pwd。K8S提供了secret对象实现密文配置数据的保存。

     Secret有多种类型,这里我们了解最常用的,也是最简单的Opaque 类型,其实质就是对字符进行base64格式编码。我们使用Opaque 类型介绍Secret的创建和使用方式,它与configMap非常类似。

1、Secret创建

Secret的创建也分为命令行和yaml文件。

(1)命令行方式

    采用kubectl create secret generic <secret name> --from-file=<file path>命令创建基于文件或目录的secret对象。我们还是以前面的config目录下的文件为例

[root@k8s-master yaml]# kubectl create secret generic file-secret --from-file=./config/
secret/file-secret created

再看下该secret对象的详情

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

Type:  Opaque

Data
====
.pwd.swp:  159744 bytes
pwd:       7 bytes
username:  5 bytes

可以看到,详情中看不到实际的值。

(2)yaml文件方式

   采用yaml文件方式,我们需要将value值进行base64编码。

[root@k8s-master yaml]# echo -n 'root' | base64     
cm9vdA==
[root@k8s-master yaml]# echo -n 'qwert' | base64    
cXdlcnQ=

然后将值写入到yaml中,yaml文件内容如下:

[root@k8s-master yaml]# cat data-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
 name: data-secret
data:
 username: cm9vdA==
 pwd: cXdlcnQ=

执行该文件,并查看详情

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

Type:  Opaque

Data
====
pwd:       6 bytes
username:  4 bytes

2、Secret使用

Secret使用方式与configMap也很类似,分为环境变量和volume挂载两种。

(1)环境变量方式

创建Pod的yaml文件,内容如下:

[root@k8s-master yaml]# cat secret-env-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: secret-env-pod
spec:
 containers:
  - name: test-busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    args:
    - sleep
    - "3600"
    env:
    - name: name
      valueFrom:
       secretKeyRef:
        name: data-secret
        key: username
    - name: password
      valueFrom:
       secretKeyRef:
        name: data-secret
        key: pwd

    可以看到与configMap的结构一致,仅将configMapKeyRef换成secretKeyRef,并将name修改为指定secret对象的name。

   创建该Pod,进入到容器内部查看环境变量

[root@k8s-master yaml]# kubectl exec -it secret-env-pod  sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo $name
root
/ # echo $password
qwert

 容器内可以正确的打印出解密后的字符。

(2)volume挂载方式

创建Pod的yaml文件,内容如下:

[root@k8s-master yaml]# cat secret-volume-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: secret-volume-pod
spec:
 containers:
  - name: test-busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    args:
    - sleep
    - "3600"
    volumeMounts:
    - name: config-volume
      mountPath: /tmp/config
 volumes:
 - name: config-volume
   secret:
     secretName: data-secret

     其与configMap的结构也一致,仅volumes的定义指定来源是secret,要主要使用secretName属性指定secret的对象。

    创建pod,并进入容器内部查看

[root@k8s-master yaml]# kubectl exec -it secret-volume-pod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cd /tmp/config
/tmp/config # ls
pwd       username
/tmp/config # cat pwd
qwert
/tmp/config # cat username
root
/tmp/config # 

可以看到正确的读取数据了。与configMap一样,其同步更新仅对volume挂载方式有效

五、总结

      本篇主要介绍了Namespace,ConfigMap以及secret的基本用法。

      Namespace可以在K8S集群中创建多个"虚拟集群",集群间实现隔离,本篇主要介绍了Namespace的创建,查看,删除以及如何创建指定Namespace的Pod。

      ConfigMap通过key-value的方式实现明文配置数据的保存,其创建方式包括yaml文件,以及通过命令行使用指定的配置文件或者目录,Pod使用ConfigMap对象也包括两种方式,环境变量方式和volume挂载方式,其中volume挂载方式可实现同步更新。

       Secret和ConfigMap在创建和使用方式上非常类似,区别在于其以密文的方式保存配置数据,一般用于用户名密码,token等敏感数据配置。

 附:

K8S初级入门系列之一-概述

K8S初级入门系列之二-集群搭建

K8S初级入门系列之三-Pod的基本概念和操作

K8S初级入门系列之四-Namespace/ConfigMap/Secret

K8S初级入门系列之五-Pod的高级特性

K8S初级入门系列之六-控制器(RC/RS/Deployment)

K8S初级入门系列之七-控制器(Job/CronJob/Daemonset)

K8S初级入门系列之八-网络

K8S初级入门系列之九-共享存储

K8S初级入门系列之十-控制器(StatefulSet)

K8S初级入门系列之十一-安全

K8S初级入门系列之十二-计算资源管理

Logo

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

更多推荐