美文网首页云原生
八 Kubernetes配置管理

八 Kubernetes配置管理

作者: 負笈在线 | 来源:发表于2022-05-16 09:31 被阅读0次

    (一) ConfigMap(配置分离)

    1.什么是ConfigMap

    ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。
    举一个例子更直观的看出ConfigMap是什么:比如我有一个nginx的Pod资源,那么ConfigMap就相当于nginx.conf这个配置文件。
    需要注意的是:这个Pod和ConfigMap必须要在同一个命名空间中,不可跨命名空间。
    ConfigMap供容器使用的典型用法如下:
    A:生成容器内的环境变量。
    B:设置容器启动命令的启动参数(需设置为环境变量)。
    C:以Volume的形式挂载为容器内部的文件或目录。

    ConfigMap与Secret类似,更倾向于前者适用于明文配置,后者适用于密码等配置。

    2.ConfigMap的创建方式

    configmap创建语法:

    kubectl create configmap NAME [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run=server|client|none]
    [options]
    

    基于目录/文件方式创建configmap
    创建一个用于练习的目录及文件,其中包含两个用于测试的文件

    [root@k8s-master01 ~]# mkdir /configmap
    [root@k8s-master01 ~]# cd /configmap/
    [root@k8s-master01 configmap]# mkdir conf
    [root@k8s-master01 configmap]# vim conf/test01.conf
    [root@k8s-master01 configmap]# vim conf/test02.conf
    [root@k8s-master01 configmap]# cat conf/test1.conf
    lives=3
    name=haha
    [root@k8s-master01 configmap]# cat conf/test2.conf
    color.good=yellow
    user=mysql
    

    创建一个cm(cm为configmap的缩写),与创建其他资源类型一样

    [root@k8s-master01 configmap]# kubectl create configmap cmfile --from-file=conf/
    [root@k8s-master01 configmap]# kubectl get cm
    NAME DATA AGE
    cmfile 2 13s
    kube-root-ca.crt 1 21d
    # 可以看到刚才创建的资源已经成功了
    

    我们可以查看一下生成的cm的yaml文件

    [root@k8s-master01 configmap]# kubectl get cm cmfile -oyaml
    apiVersion: v1
    data:
     test1.conf: |
     lives=3
     name=haha
     test2.conf: |
     color.good=yellow
     user=mysql
    kind: ConfigMap
    metadata:
     creationTimestamp: "2022-02-23T02:50:40Z"
     name: cmfile
     namespace: default
     resourceVersion: "1050098"
     uid: 39b904c2-c1a4-442c-a6fe-6a3d89af36ac
    

    找到data,可以看到data下内容包含了之前测试创建的两个文件及内容
    基于文件创建和目录是相似的,只要加上目录下的指定文件即可,比如:

    [root@k8s-master01 configmap]# kubectl create cm cmfromfile --from-file=conf/test02.conf
    

    有一个不常用的地方,自定义configmap中的名称

    [root@k8s-master01 configmap]# vim test03.conf
    [root@k8s-master01 configmap]# kubectl create cm test03 --from-file=test03-conf=test03.conf
    configmap/test03 created
    [root@k8s-master01 configmap]# kubectl get cm test03 -o yaml
    apiVersion: v1
    data:
     test03-conf: |
     user=www
     passwd=123456
    kind: ConfigMap
    metadata:
     creationTimestamp: "2022-02-20T10:52:11Z"
     name: test03
     namespace: default
     resourceVersion: "914180"
     uid: 2f41ffa8-f200-48ee-8e61-729cfdf81b97
    

    可以看到上面例子中的test03.conf已经变成test03-conf格式了,这个了解即可。
    基于env文件创建configmap
    其实方式都一样,不细写了,看下创建方式:适用于较多的键值对

    [root@k8s-master01 configmap]# kubectl create cm envfile --from-env-file=envfile.conf
    configmap/envfile created
    [root@k8s-master01 configmap]# kubectl get cm envfile -o yaml
    apiVersion: v1
    data:
     age: "25"
     hehe: haha
     name: yy
    kind: ConfigMap
    metadata:
     creationTimestamp: "2022-02-23T03:02:58Z"
     name: envfile
     namespace: default
     resourceVersion: "1051876"
     uid: 27a62b22-cd46-4dbe-bf12-6b34a67befe8
    # 可以看到里面的等号换成冒号
    

    基于literal直接创建configmap
    比如我们只需要一两个或很少的变量,没有写成文件的必要的时候可以用这种方式

    [root@k8s-master01 configmap]# kubectl create cm literaltest --from-literal=PORT=8080 --from-literal=PASSWORD=123456
    

    基于yaml文件创建configmap
    参考官方例子:https://kubernetes.io/zh/docs/concepts/configuration/configmap/

    3.使用valueFrom定义环境变量

    适合配置参数比较少的地方
    我们先创建一个deploy资源方便测试,–dry-run的作用是只生成yaml文件而不创建资源

    # kubectl create deployment dp-cm --image=nginx --dry-run=client -o yaml > dp-cm.yaml
    [root@k8s-master01 configmap]# cat dp-cm.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
     labels:
     app: dp-cm
     name: dp-cm
    spec:
     replicas: 1
     selector:
     matchLabels:
     app: dp-cm
     strategy: {}
     template:
     metadata:
     labels:
     app: dp-cm
     spec:
     containers:
     - image: nginx
     name: nginx
    

    我们分别添加一个传统的环境变量和使用configmap定义一个

     spec:
     containers:
     - image: nginx
     name: nginx
     env:
     - name: TEST_ENV
     value: test_env
     - name: TEST_X
     valueFrom:
     configMapKeyRef:
     name: envfile
     key: hehe
    

    env下第一个环境变量是我们按照传统模式定义;第二个是在configmap中取值,先看一下效果

    [root@k8s-master01 configmap]# kubectl create -f dp-cm.yaml
    deployment.apps/dp-cm created
    [root@k8s-master01 configmap]# kubectl exec dp-cm-f8c48c84c-zvcwt -- env
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    HOSTNAME=dp-cm-f8c48c84c-zvcwt
    NGINX_VERSION=1.21.6
    NJS_VERSION=0.7.2
    PKG_RELEASE=1~bullseye
    TEST_ENV=test_env
    TEST_X=haha
    

    最后两个分别是我们直接定义的变量和引用configmap中的变量
    如果引用多个变量只需要在后面添加定义即可

     - name: TEST_X
     valueFrom:
     configMapKeyRef:
     name: envfile
     key: hehe
     - name: TEST_Y
     valueFrom:
     configMapKeyRef:
     name: envfile
     key: name
    

    注意:如果引用的变量不存在会报错,Pod创建不成功

    4.使用envfrom批量生成环境变量

     spec:
     containers:
     - image: nginx
     name: nginx
     envFrom:
     - configMapRef:
     name: envfile
    

    更新一下Pod,然后看一下结果

    [root@k8s-master01 configmap]# kubectl replace -f dp-cm.yaml
    deployment.apps/dp-cm replaced
    [root@k8s-master01 configmap]# kubectl exec dp-cm-8565c44587-x8k62 -- env
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    HOSTNAME=dp-cm-8565c44587-x8k62
    NGINX_VERSION=1.21.6
    NJS_VERSION=0.7.2
    PKG_RELEASE=1~bullseye
    age=25
    hehe=haha
    name=yy
    TEST_ENV=test_env
    

    可以看到后面三行小写名称的就是我们envfileconfigMap中的内容
    当一个Pod中变量有直接定义的也有从configMap定义时,我们可以加prefix前缀进行区分:

     spec:
     containers:
     - image: nginx
     name: nginx
     envFrom:
     - configMapRef:
     name: envfile
     prefix: fromCm_
     env:
     - name: TEST_ENV
     value: test_env
    

    5.以文件形式挂载ConfigMap

    我们事先创建了一个redis-conf的cm副本,然后挂载到下面文件的Pod中

     spec:
     containers:
     - image: nginx
     name: nginx
     volumeMounts:
     - name: redisconf
     mountPath: /etc/config
     volumes:
     - name: redisconf
     configMap:
     name: redis-conf
    

    上面这部分内容中volumes下有两个name,第一个是需要挂载到Pod的名称,第二个是configMap的名称,已经做了区分了。
    执行yaml文件,进入Pod内部查看一下挂载情况

    # 创建Pod
    [root@k8s-master01 ~]# kubectl create -f dp-cm.yaml
    # 进入到Pod中查看挂载情况
    [root@k8s-master01 ~]# kubectl exec -ti dp-cm-77b4666649-jd4sc -- bash
    root@dp-cm-77b4666649-jd4sc:/# cd /etc/config/
    root@dp-cm-77b4666649-jd4sc:/etc/config# ls
    redis-conf
    root@dp-cm-77b4666649-jd4sc:/etc/config# cat redis-conf
    hehe 123123
    # 可以看到我们之前创建的文件已经挂载好了
    

    在线编辑cm文件内容,挂载到Pod中的文件也会随着更改

    [root@k8s-master01 ~]# kubectl edit cm redis-conf
    [root@k8s-master01 ~]# kubectl get cm redis-conf -o yaml
     redis-conf: |
     hehe 23412423412
    [root@k8s-master01 ~]# kubectl exec -ti dp-cm-77b4666649-jd4sc -- bash
    root@dp-cm-77b4666649-jd4sc:/# cat /etc/config/redis-conf
    hehe 23412423412
    # Pod中的文件也随着修改了
    

    6.防止覆盖操作

    比如我们有一个nginx-conf的configMap要挂载到nginx的/etc/nginx目录下,如果直接操作的话会发生覆盖/etc/nginx下所有内容,导致Pod报错。
    所以需要加上subPath来防止内容会覆盖,如下:

     spec:
     containers:
     - image: nginx
     name: nginx
     volumeMounts:
     - name: nginxconf
     mountPath: /etc/nginx/nginx.conf
     subPath: nginx.conf # 这样只会对这一个文件进行覆盖
     volumes:
     - name: nginxconf
     configMap:
     name: nginx-conf
    

    7.自定义文件名与授权

    使用item自定义文件名:相当于做一个软连接

     volumes:
     - name: redisconf
     configMap:
     name: redis-conf
     items:
     - key: redis.conf
     path: redis2.conf
    

    使用defaultMode给ConfigMap中文件进行权限管理

     volumes:
     - name: redisconf
     configMap:
     name: redis-conf
     items:
     - key: redis.conf
     path: redis2.conf
     mode: 0644 # 具体文件权限,优先级高
     defaultMode: 0666 # configMap的默认权限
    

    8.热更新操作

    如果是通过yaml文件创建的,只需要在yaml文件中修改,然后kubectl replace更新即可
    如果是通过命令创建的话:可以把cm导成yaml文件进行修改,然后更新,但是可能会出现错误,不建议。还可以修改创建cm前使用的原始文件,比如nginx.conf文件,然后利用--dry-run=client生成一个yaml文件,然后进行更新。如下:

    # kubectl create cm nginx-conf --from-file=nginx.conf --dry-run=client -oyaml
    # kubectl replace -f -
    

    9.使用限制

    l 需要提前创建ConfigMap或者Secret
    l 引用的Key必须存在
    l envFrom、valueFrom无法热更新操作
    l envFrom配置环境变量,如果Key无效,会忽略无效的Key
    l 资源需要在同一个命名空间
    l subPath也是无法热更新的

    10.内容不可变

    ConfigMap或Secret中加入以下内容,执行后不可再修改资源

    immutable: ture
    

    (二) Secret**

    1.[Secret]

    Secret 是一种包含少量敏感信息例如密码、令牌或[密钥]的对象。 这样的信息可能会被放在 Pod 规约中或者镜像中。 使用 Secret 意味着你不需要在应用程序代码中包含机密数据。
    使用过程与ConfigMap类似
    与ConfigMap不同的是:
    ConfigMap用于明文,Secret用于加密文件,如:密码
    ConfigMap是没有类型的,但是Secret有类型(type)

    常用的Secret类型:

    2.[Secret的创建]

    还是使用比较常用的两种方式:kubectl和配置文件方式来创建
    先创建一个实验环境:包含一个文件夹和两个文件

    [root@k8s-master01 ~]# cd /secret/
    [root@k8s-master01 secret]# echo -n 'yyang' > user.txt
    [root@k8s-master01 secret]# echo -n '1qaz2wsx' > passwd.txt
    [root@k8s-master01 secret]# ls
    passwd.txt user.txt
    

    利用上面的环境创建以一个Secret

    [root@k8s-master01 secret]# kubectl create secret generic db-user-pass \
    > --from-file=user.txt \
    > --from-file=passwd.txt
    secret/db-user-pass created
    

    查看这个secret的内容:类型为Opaque;内容中data下的内容已经用密文表示

    [root@k8s-master01 secret]# kubectl get secrets
    NAME TYPE DATA AGE
    db-user-pass Opaque 2 68s
    default-token-7h7vk kubernetes.io/service-account-token 3 5h51m
    [root@k8s-master01 secret]# kubectl get secrets db-user-pass -o yaml
    apiVersion: v1
    data:
     passwd.txt: MXFhejJ3c3g=
     user.txt: eXlhbmc=
    kind: Secret
    metadata:
     creationTimestamp: "2022-03-02T07:36:41Z"
     name: db-user-pass
     namespace: default
     resourceVersion: "40252"
     uid: a46ab9ed-c67c-4195-a5d6-f38dfc3d2016
    type: Opaque
    

    这个值是可以解密出来的:邮件前边的数据即为之前的加密数据

    [root@k8s-master01 secret]# echo "MXFhejJ3c3g=" | base64 -d
    1qaz2wsx
    

    kubectl方式创建效果类似,就只给出官方的例子了(注意用单引号)

    # kubectl create secret generic db-user-pass \
     --from-literal=username=devuser \
     --from-literal=password='S!B\*d$zDsb='
    

    还有一种是配置文件方式,这种方式是先把账号密码之类的数据转换为加密数据,然后创建一个yaml文件,随后执行yaml文件;这种方法比较麻烦就不说了,可以看一下官方的例子:
    [使用配置文件创建Secret]
    https://kubernetes.io/zh/docs/tasks/configmap-secret/managing-secret-using-config-file/

    3.[应用于docker私有仓库的secret]

    pull私有仓库的镜像时需要验证的情况,可以为docker私有仓库创建相应的secret。格式如下:
    我就不写具体的创建了

    # kubectl create secret docker-registry secret-tiger-docker \
     --docker-username=user \
     --docker-password=pass113 \
     --docker-email=tiger@acme.com \
     --docker-server=string
    

    以上几项内容分别的仓库的用户名、密码、邮箱和仓库地址
    当你创建完这个secret后使用的时候可以放在spec下,与containers同级

     spec:
     imagePullSecrets:
     - name: secret-tiger-docker
     containers:
     - image: 私有仓库地址
     name: nginx
    

    这样下载私有仓库镜像时就不需要密码了
    注意的点:注意命名空间隔离问题
    还有一个常用的类型就是tls,创建方式类似,使用也类似。就不写了,我也没有合适的环境。

    4.[其他]

    其他方面Secret与ConfigMap相近,请看[ConfigMap]相关内容

    相关文章

      网友评论

        本文标题:八 Kubernetes配置管理

        本文链接:https://www.haomeiwen.com/subject/ixtuurtx.html