配置管理

一、ConfigMap

  ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时, Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。ConfigMap 将环境配置信息和容器镜像解耦(不用因为数据库更换密码之后重新修改代码,重新只做镜像),方便了应用配置的修改。

  使用ConfigMap需要注意的是:

  a.)ConfigMap并不提供保密或者加密功能。

  b.)ConfigMap并不能保存大量数据,保存的数据不可超过1MiB。如果需要保存超过1MiB的数据,可以采取挂载存储卷 或者使用独立的数据库或者文件服务。

  有四种方式来使用 ConfigMap配置Pod中的容器:

  a.)在容器命令和参数内

  b.)容器的环境变量

  c.)在只读卷里面添加一个文件,让应用来读取,这种方式使用居多

  d.)编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap

1.1 使用键值对来创建ConfigMap

  使用官网案例

apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  # 类属性键;每一个键都映射到一个简单的值
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"

  # 类文件键
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5    
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true  
---
apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]
      env:
        # 定义环境变量
        - name: PLAYER_INITIAL_LIVES # 请注意这里和 ConfigMap 中的键名是不一样的
          valueFrom:
            configMapKeyRef:
              name: game-demo           # 这个值来自 ConfigMap
              key: player_initial_lives # 需要取值的键
        - name: UI_PROPERTIES_FILE_NAME
          valueFrom:
            configMapKeyRef:
              name: game-demo
              key: ui_properties_file_name
      volumeMounts:
      - name: config
        mountPath: "/config"
        readOnly: true   # 配置文件设置只读
  volumes:
    # 你可以在 Pod 级别设置卷,然后将其挂载到 Pod 内的容器中
    - name: config
      configMap:
        # 提供你想要挂载的 ConfigMap 的名字
        name: game-demo
        # 来自 ConfigMap 的一组键,将被创建为文件
        items:
        - key: "game.properties"
          path: "game.properties"
        - key: "user-interface.properties"
          path: "user-interface.properties"

  PS:或者可以使用命令直接创建

kubectl create configmap  game-config --from-file ./configmap

创建完成后进入容器可以观察到定义了一个卷并将它作为 /config 文件夹挂载到demo容器内,创建两个文件,/config/game.properties 和 /config/user-interface.properties, 尽管 ConfigMap 中包含了四个键。这是因为 Pod 定义中在 volumes 节指定了一个 items 数组。 如果你完全忽略 items 数组,则 ConfigMap 中的每个键都会变成一个与 该键同名的文件,因此你会得到四个文件。

# ls -l /config/*.properties
lrwxrwxrwx    1 root     root            22 Aug 16 00:53 /config/game.properties -> ..data/game.properties
lrwxrwxrwx    1 root     root            32 Aug 16 00:53 /config/user-interface.properties -> ..data/user-interface.properties

# kubectl exec -it configmap-demo-pod -- sh
/ # echo $PLAYER_INITIAL_LIVES
3
/ # echo $UI_PROPERTIES_FILE_NAME
user-interface.properties
PS:当 ConfigMap以数据卷的形式挂载进Pod的时,这时更新 ConfigMap(或删掉重建ConfigMap),Pod内挂载的配置信息会热更新。这时可以增加一些监测配置文件变更的脚本,然后重加载对应服务就可以实现应用的热更新

二、Secret

  Secret用来保存敏感信息,例如密码、OAuth 令牌和 ssh key 等等,将这些信息放在 Secret 中比放在 Pod 的定义中或者 Docker 镜像中要更加安全和灵活。

  但是,Secret默认采用base64-编码的、非加密的字符串,任何人都可以做反向base64解码。如果有更安全的要求,可以采取以下方式:

  a.)为 Secret 启用静态加密;

  b.)启用 或配置 RBAC 规则来限制对 Secret 的读写操作。 要注意,任何被允许创建 Pod 的人都默认地具有读取 Secret 的权限。

2.1 Secret的使用

  a.)作为挂载到一个或多个容器上的卷 中的文件。

  b.)作为容器的环境变量

  c.)由 kubelet 在为 Pod 拉取镜像时使用(docker registry)

2.2 Secret的类型

  类型主要有以下几种:

    Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;但数据也可以通过base64 –-decode解码得到原始数据,所有加密性很弱。

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

kubernetes.io/service-account-token:用于被 ServiceAccount ServiceAccount 创建时 Kubernetes 会默认创建一个对应的 Secret 对象。Pod 如果使用了 ServiceAccount,对应的 Secret 会自动挂载到 Pod 目录 /run/secrets/kubernetes.io/serviceaccount 中。
bootstrap.kubernetes.io/token:用于节点接入集群的校验的 Secret.

2.3 Opaque

  创建Secret

# echo -n "admin" | base64
YWRtaW4=
# echo -n "admin@123" | base64
YWRtaW5AMTIz

apiVersion: v1
kind: Secret
metadata:
  name: secret1
type: Opaque   # 通过TYPE字段指定类型
data:
  username: YWRtaW4=
  password: YWRtaW5AMTIz
 
# kubectl apply -f secret1.yaml

  使用Secret

apiVersion: v1
kind: Pod
metadata:
  name: secret1-test
spec:
  containers:
  - name: secret1-test
    image: busybox
    command: [ "/bin/sh", "-c", "sleep 3600" ]
    env:         # 环境变量方式
    - name: USERNAME
      valueFrom:
        secretKeyRef:
          name: secret1
          key: username
    - name: PASSWORD
      valueFrom:
        secretKeyRef:
          name: secret1
          key: password
    volumeMounts:   # 卷挂载方式
    - name: secrets
      mountPath: /etc/secrets

  volumes:
  - name: secrets
    secret:
     secretName: secret1

# kubectl exec -it secret1-test -- sh
/ # cat /etc/secrets/username 
admin/ # 
/ # cat /etc/secrets/password 
admin@123/ # 
/ # echo $USERNAME
admin
/ # echo $PASSWORD
admin@123

2.4 kubernetes.io/dockerconfigjson

# kubectl create secret docker-registry myregistry --docker-server=10.255.20.93 --docker-username=admin --docker-password=Harbor123 --docker-email=2841184943@xsky.com

  去私有镜像仓库拉取镜像

apiVersion: v1
kind: Pod
metadata:
  name: foo
spec:
  containers:
  - name: foo
    image: 10.255.20.93/busybox:latest
  imagePullSecrets:  # 只能由 Kubelet 访问
  - name: myregistry

2.6 kubernetes.io/service-account-token

  ServiceAccout创建时Kubernetes会默认创建对应的 Secret。Pod如果使用了ServiceAccount,对应的Secret 会自动挂载到 Pod的/var/run/secrets/kubernetes.io/serviceaccount/ 目录中。该服务账号令牌 Secret 中包含了访问 Kubernetes API 所需要的凭据。

# kubectl run secret2-test --image nginx

# kubectl get pods secret2-test -o yaml | grep -i Secret
    run: secret2-test
          k:{"name":"secret2-test"}:
  name: secret2-test
    name: secret2-test
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
    secret:
      secretName: default-token-x4hgv
    name: secret2-test

三、ServiceAccount

  ServiceAccount主要是用于解决Pod在集群中的身份认证问题的。认证使用的授权信息其实就是之前提到的一个类型为kubernetes.io/service-account-token进行管理的。

  ServiceAccount是命名空间级别的,每一个命名空间创建的时候就会自动创建一个名为default的ServiceAccount 对象,当创建的Pod没有指定ServiceAccount就会使用default ServiceAccount,对应的Secret会自动挂载到Pod的/var/run/secrets/kubernetes.io/serviceaccount/目录中,这样我们就可以在Pod里面获取到用于身份认证的信息了:

# kubectl create ns development
namespace/development created
# kubectl get ServiceAccount -n development
NAME      SECRETS   AGE
default   1         11s
# kubectl get secret -n development
NAME                  TYPE                                  DATA   AGE
default-token-52srg   kubernetes.io/service-account-token   3      6m6s

  查看默认secret

# kubectl get secret default-token-52srg -n development -o yaml | grep -v -E '^[[:space:]]+f:'
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeE1ETXpNREEzTURZMU4xb1hEVE14TURNeU9EQTNNRFkxTjFvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTkR0CnllcEpqNTFKa3R6WW1SOWlTY1dadjdyWE1SSDR5QU0zZWxEb3d4RDJwaFNzZDFUUkE0Q1pjNGV5enFUcmlDbWYKQVl5NFNNdXlJVzdpNEozUVd5ZEpnQndITGlvSDNLa2NzV3l0T1duR25vZUVSUVIvaHVubmRtZGhnd01HbTZ0TApONTB1Y2ZZcXlBUXFFV3grTGhCb2FUQWlubVl3UU9aMnVqN2JaNFBxTUFlN0Z5d0NUbWsxWlRIZ3hncVM3TWU4ClVSRC9xWjVYbVBVZjlkdFVwRit5OVFBdDVBOFd4YlBQSXNOQ3o3VVZIOWE2RklpY2VwSnNOdUdsMXNnd09veVcKbkJWdVJGZGVWbFREREUvcFB3UndMUWNMUzFEdGhGWDdwQnhTUmVUaHd2SlpSOVU2SEtEdldFTm5HMGdzOTFwWQpZNzJJalVOaHh3aXFNcnZmUVk4Q0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZFWlA4ZmlDb250dTNwMmNOQzhmV3NnbmlEVXdNQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFBVDZVd2NYNWtCOTdOK0E4cTJ1ZTBIbVRZYUNSUG1NMnEvZTlPWjlMQURTdjMzbUgwWgpneEZrOUxIb3N5NDVmeGI3MXFCd2txMGtMRUhpSXh0eTdOc1o4ZWxhaVhuR3pwUy9EUE5yYTI4TVA0Q0orU3hECkVHaTNNK3RmMXN5RENFRnZrVU1jZXlpdW92TU94cEVnR05CMGUrQXNySllFSlg1Qm1OLzJmNTJzNEpNVmNsZ28KelRRVitFZjQyNWFaUmdHWTZha25WUll1OUkyNmRrcFZMbCtKdk5Sc3dQb1VXQmo4NnF1T2xUblZVZm9FanNaZwp2QUpyREJTeDQ2azh0MnNOVVNFOVNnN0dRMS8wMTJpY3ZFTW9FOWdwZmg4eEF0MDRjbXhUeWhyREs4ZnRQcjc5CjBPYVlSWFJCZEY1RDBkTVZtZXdZTFdkMTVVa09xblJSN0g5OQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
  namespace: ZGV2ZWxvcG1lbnQ=
  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkltWmZlVWx3VTNOVVJGaEpkWGhzUjBOclRFUk5SakZhV1MxaWRYVldSbVp2WTBaSmNFVTRVamxEVG1NaWZRLmV5SnBjM01pT2lKcmRXSmxjbTVsZEdWekwzTmxjblpwWTJWaFkyTnZkVzUwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXVZVzFsYzNCaFkyVWlPaUprWlhabGJHOXdiV1Z1ZENJc0ltdDFZbVZ5Ym1WMFpYTXVhVzh2YzJWeWRtbGpaV0ZqWTI5MWJuUXZjMlZqY21WMExtNWhiV1VpT2lKa1pXWmhkV3gwTFhSdmEyVnVMVFV5YzNKbklpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WlhKMmFXTmxMV0ZqWTI5MWJuUXVibUZ0WlNJNkltUmxabUYxYkhRaUxDSnJkV0psY201bGRHVnpMbWx2TDNObGNuWnBZMlZoWTJOdmRXNTBMM05sY25acFkyVXRZV05qYjNWdWRDNTFhV1FpT2lJNU5HUXdZMk5qTmkwMU5tVTBMVFExT0RjdE9XVmhOQzFrTWprMlkySTRNMk0wTmpBaUxDSnpkV0lpT2lKemVYTjBaVzA2YzJWeWRtbGpaV0ZqWTI5MWJuUTZaR1YyWld4dmNHMWxiblE2WkdWbVlYVnNkQ0o5LnE4VUNZbnVDYThtUlE2RnNidHNpbzJzbDRvYTJTUWZNc0l5Tkt1T1I2UEhrQkZjVmlRZHh4VW95UkQxMXJ2THltTm9Xam93NjNEaDdHYXZGSEx5TGVCeW1TcWRRSnJjazBnUmNnWmYwR3VlMnlkOWc4SlNMZmVIV20tVkM2UGF1amdWbnVJejZUNVU1UXVrUkJCZFhUWldpUGhxOElScXBwa1hmbEtvZ0hpX041V0psQzIxUHo3cm53dGNOa3o4NkVuc0FnaWxfazRpTXVKUjB0ay10UTU0dVU0NzQyMmNsZnh1akJiTUptN2FOYUtOSWhTT2Fac0lHYm9xbHdKcV9nVW53S3NicUVvam1kc2ROMFlqb3BXQUJIYnJwN2FQME5HRHd4Y1NBQjBOY1A5VXBQbTd6NzEwbGVPRmg5MnpsQmFNaF9iZUN3enJTQzJuaDVEMkFRZw==
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: default
    kubernetes.io/service-account.uid: 94d0ccc6-56e4-4587-9ea4-d296cb83c460
  creationTimestamp: "2021-08-17T01:35:18Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
        .: {}
          .: {}
    manager: kube-controller-manager
    operation: Update
    time: "2021-08-17T01:35:18Z"
  name: default-token-52srg
  namespace: development
  resourceVersion: "15648510"
  uid: a27e033e-ef63-4a98-8684-94042923ca79
type: kubernetes.io/service-account-token

  在data区域可以看到有3个信息:

    ca.crt:用于校验服务端的证书信息

    namespace:表示当前管理的命名空间

    token:用于 Pod 身份认证的 Token

  当我们在Pod里面访问集群的时候,就可以默认利用挂载到 Pod 内部的 token文件来认证Pod的身份,ca.crt 则用来校验服务端是否可信,最后服务端会根据我们提供的 token文件对 Pod 进行认证。

Logo

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

更多推荐