• 《前端运维》五、k8s4机密信息存储与统一管理服务环境变量


    一、储存机密信息

      Secret 是 Kubernetes 内的一种资源类型,可以用它来存放一些机密信息(密码,token,密钥等)。信息被存入后,我们可以使用挂载卷的方式挂载进我们的 Pod 内。当然也可以存放docker私有镜像库的登录名和密码,用于拉取私有镜像。

    一)Opaque 类型

      Opaque 类型一般拿来存放密码,密钥等信息,存储格式为 base64。我们可以通过命令行和配置文件两种方式来创建Secret资源。

    1)命令行方式

    kubectl create secret generic mysql-account --from-literal=username=zaking--from-literal=password=123456
    kubectl get secret
    //编辑值
    kubectl edit secret account
    //输出yaml格式
    kubectl get secret account -o yaml
    //输出json格式
    kubectl get secret account -o json
    //对Base64进行解码
    echo MTIzNDU2 | base64 -d

    2)配置文件创建

      创建一个mysql-account.yml文件:

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysql-account
    stringData:
      username: root
      password: root
    type: Opaque

      然后:

    kubectl apply -f mysql-account.yaml 
    secret/mysql-account created
    kubectl get secret mysql-account -o yaml

    二)私有镜像库认证

    1)命令行创建

    kubectl create secret docker-registry private-registry \
    --docker-username=[用户名] \
    --docker-password=[密码] \
    --docker-email=[邮箱] \
    --docker-server=[私有镜像库地址]
    //查看私有库密钥组
    kubectl get secret private-registry -o yaml
    echo [value] | base64 -d

    2)配置文件创建

    vi private-registry-file.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: private-registry-file
    data:
      .dockerconfigjson: eyJhdXRocyI6eyJodHRwczo
    type: kubernetes.io/dockerconfigjson
    kubectl apply -f ./private-registry-file.yaml
    kubectl get secret private-registry-file -o yaml

    三)使用

    1)Volume 挂载

      通过存储卷的方式挂载进去,添加文件并书写内容如下:

    apiVersion: apps/v1  #API 配置版本
    kind: Deployment     #资源类型
    metadata:
      name: user-v1     #资源名称
    spec:
      minReadySeconds: 1
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 0
      selector:
        matchLabels:
          app: user-v1 #告诉deployment根据规则匹配相应的Pod进行控制和管理,matchLabels字段匹配Pod的label值
    + replicas: 1 #声明一个 Pod,副本的数量
      template:
        metadata:
          labels:
            app: user-v1 #Pod的名称
        spec:   #组内创建的 Pod 信息
    +     volumes:
    +       - name: mysql-account
    +         secret:
    +           secretName: mysql-account
          containers:
          - name: nginx #容器的名称
            image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 #使用哪个镜像
    +       volumeMounts:
    +       - name: mysql-account
    +         mountPath: /mysql-account
    +         readOnly: true
            ports:
            - containerPort: 80 #容器内映射的端口

      执行命令:

    kubectl describe pods  user-v1-b88799944-tjgrs 
    kubectl exec -it user-v1-b88799944-tjgrs  -- ls /root 

    2)环境变量注入

      修改之前的deployment-user-v1.yaml文件:

    apiVersion: apps/v1  #API 配置版本
    kind: Deployment     #资源类型
    metadata:
      name: user-v1     #资源名称
    spec:
      minReadySeconds: 1
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 0
      selector:
        matchLabels:
          app: user-v1 #告诉deployment根据规则匹配相应的Pod进行控制和管理,matchLabels字段匹配Pod的label值
      replicas: 1 #声明一个 Pod,副本的数量
      template:
        metadata:
          labels:
            app: user-v1 #Pod的名称
        spec:   #组内创建的 Pod 信息
          volumes:
            - name: mysql-account
              secret:
                secretName: mysql-account
          containers:
          - name: nginx #容器的名称
    +       env:
    +       - name: USERNAME
    +         valueFrom:
    +           secretKeyRef:
    +             name: mysql-account
    +             key: username
    +       - name: PASSWORD
    +         valueFrom:
    +           secretKeyRef:
    +             name: mysql-account
    +             key: password
            image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 #使用哪个镜像
            volumeMounts:
            - name: mysql-account
              mountPath: /mysql-account
              readOnly: true
            ports:
            - containerPort: 80 #容器内映射的端口

      然后:

    kubectl apply -f deployment-user-v1.yaml 
    kubectl get pods
    kubectl describe pod  user-v1-5f48f78d86-hjkcl
    kubectl exec -it user-v1-688486759f-9snpx -- env | grep USERNAME

    3)Docker 私有库认证

      这种方法只能用来配置私有镜像库认证。添加文件,vi v4.yaml:

    image: [仅有镜像库地址]/[镜像名称]:[镜像标签]

      

    kubectl apply -f v4.yaml
    kubectl get pods
    kubectl describe pods [POD_NAME]
    +imagePullSecrets:
    + - name: private-registry-file
    containers:
      - name: nginx
    kubectl apply -f v4.yaml

     二、服务发现

      服务发现是指使用一个注册中心来记录分布式系统中的全部服务的信息,以便其他服务能够快速的找到这些已注册的服务。

      Pod 的 IP 常常是漂移且不固定的,所以我们要使用 Service 这个神器来将它的访问入口固定住。可以利用 DNS 的机制给每个 Service 加一个内部的域名,指向其真实的IP。在Kubernetes中,对 Service 的服务发现,是通过一种叫做 CoreDNS 的组件去实现的。

      coreDNS 是使用 Go 语言实现的一个DNS服务器

    • -n 按命名空间过滤
    • -l 按标签过滤
    • -o wide 输出额外信息。对于Pod,将输出Pod所在的Node名
    kubectl -n kube-system get all  -l k8s-app=kube-dns -o wide

      kubectl exec 的作用是可以直接在容器内执行Shell脚本

    • 命令格式:kubectl exec -it [PodName] -- [Command]
    • -i:即使没有连接,也要保持标准输入保持打开状态。一般与 -t 连用。
    • -t:分配一个伪TTY(终端设备终端窗口),一般与 -i 连用。可以分配给我们一个Shell终端
    kubectl get pods
    kubectl get svc
    kubectl exec -it user-v1-688486759f-9snpx -- /bin/sh
    curl http://service-user-v2

      kubernetes namespace(命名空间)是 kubernetes 里比较重要的一个概念。在启动集群后,kubernetes 会分配一个默认命名空间,叫default。不同的命名空间可以实现资源隔离,服务隔离,甚至权限隔离。因为我们在之前创建的服务,都没有指定 namespace ,所以我们的服务都是在同一个 namespace default下。在同 namespace 下的规则,我们只需要直接访问 http://ServiceName:Port 就可以访问到相应的 Service。不同 namespace 下的规则是 [ServiceName].[NameSpace].svc.cluster.local。ServiceName 就是我们创建的 Service 名称,NameSpace 则是命名空间。如果你没有命名空间,则这个值为 default。

    curl http://service-user-v2.default.svc.cluster.local

      

     三、统一管理服务环境变量 

      Kubernetes Secret 的主要作用是来存放密码,密钥等机密信息。对于环境变量的配置:例如你的数据库地址,负载均衡要转发的服务地址等信息。这部分内容使用 Secret 显然不合适,打包在镜像内耦合又太严重。这里,我们可以借助 Kubernetes ConfigMap 来配置这项事情。ConfigMap 是 Kubernetes 的一种资源类型,我们可以使用它存放一些环境变量和配置文件。信息存入后,我们可以使用挂载卷的方式挂载进我们的 Pod 内,也可以通过环境变量注入。和 Secret 类型最大的不同是,存在 ConfigMap 内的内容不会加密。

    一)创建

      创建的方式有很多种,我们下面来一一试一下:

    1、命令行创建

    kubectl create configmap [config_name] --from-literal=[key]=[value]
    kubectl create configmap mysql-config --from-literal=MYSQL_HOST=192.168.1.172 --from-literal=MYSQL_PORT=3306

      需要注意,configmap 的名称必须是全小写,特殊符号只能包含 '-' 和 '.'。可以用下面的这个正则表达式校验下看看符不符合规则:[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')。

    kubectl get cm
    kubectl describe cm mysql-config

    2、配置清单创建

      创建一个mysql-config-file.yaml文件:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: mysql-config-file
    data:
      MYSQL_HOST: "192.168.1.172"
      MYSQL_PORT: "3306"
    • kind 的值为 ConfigMap,代表声明一个 ConfigMap 类型的资源
    • metadata.name 代表是该 configmap 的名称
    • data 是存放数据的地方,数据格式为 key:value
    kubectl apply -f ./mysql-config-file.yaml
    kubectl describe cm mysql-config-file

    3、文件创建

    kubectl create configmap [configname] --from-file=[key]=[file_path]
    • --from-file代表一个文件
    • key是文件在 configmap 内的 key
    • file_path 是文件的路径

      添加env.config文件:

    HOST: 192.168.0.1
    PORT: 8080
    kubectl create configmap env-from-file --from-file=env=./env.config
    configmap/env-from-file created
    kubectl get cm env-from-file -o yaml

    4、目录创建

      也可以直接将一个目录下的文件整个存入进去。

    kubectl create configmap [configname] --from-file=[dir_path]
    
    mkdir env && cd ./env
    echo 'local' > env.local
    echo 'test' > env.test
    echo 'prod' > env.prod
    
    kubectl create configmap env-from-dir --from-file=./
    
    kubectl get cm env-from-dir -o yaml

    二)使用方式

    1、环境变量注入

      

    containers:
      - name: nginx #容器的名称
    +   env:
    +     - name: MYSQL_HOST
    +       valueFrom:
    +         configMapKeyRef:
    +           name: mysql-config
    +           key: MYSQL_HOST
    kubectl apply -f ./v1.yaml
    //kubectl exec -it [POD_NAME] -- env | grep MYSQL_HOST
    kubectl exec  -it user-v1-744f48d6bd-9klqr -- env | grep MYSQL_HOST
    kubectl exec  -it user-v1-744f48d6bd-9klqr  -- env | grep MYSQL_PORT
          containers:
          - name: nginx #容器的名称
            env:
    +       envFrom:
    +       - configMapRef:
    +           name: mysql-config
    +           optional: true  
            image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 #使用哪个镜像
            volumeMounts:
            - name: mysql-account
              mountPath: /mysql-account
              readOnly: true
            ports:
            - containerPort: 80 #容器内映射的端口

    2、存储卷挂载

      存储卷挂载会将 configmap 里内容中的每个 key 和 value,以独立文件方式以外部挂载卷方式挂载进去( key 是文件名,value 是文件内容)。

    • 在 Pod 层面声明一个外部存储卷
      • name 为存储卷名称
      • configMap 代表存储卷的文件来源
      • configMap.name 要填入要加载的 configMap 名称
    • 在容器镜像层面配置存储卷
      • name 的值来源于第一步配置的 name 值
      • mountPath 为要挂载的目录
      • readonly 则代表文件是不是只读
      template:
        metadata:
          labels:
            app: user-v1 #Pod的名称
        spec:   #组内创建的 Pod 信息
          volumes:
            - name: mysql-account
              secret:
                secretName: mysql-account
    +       - name: envfiles
    +         configMap:
    +           name: env-from-dir
          containers:
          - name: nginx #容器的名称
            env:
            - name: USERNAME
              valueFrom:
                secretKeyRef:
                  name: mysql-account
                  key: username
            - name: PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-account
                  key: password
            envFrom:
            - configMapRef:
                name: mysql-config
                optional: true  
            image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 #使用哪个镜像
            volumeMounts:
            - name: mysql-account
              mountPath: /mysql-account
              readOnly: true
    +       - name: envfiles
    +         mountPath: /envfiles
    +         readOnly: true
            ports:
            - containerPort: 80 #容器内映射的端口
    kubectl apply -f deployment-user-v1.yaml 
    kubectl get pods
    kubectl describe pod user-v1-79b8768f54-r56kd
    kubectl exec -it user-v1-744f48d6bd-9klqr -- ls /envfiles

      可以借助 volumes.configMap.items[] 字段来配置多个 item 项。

     spec:   #组内创建的 Pod 信息
          volumes:
            - name: mysql-account
              secret:
                secretName: mysql-account
            - name: envfiles
              configMap:
                name: env-from-dir
    +           items:
    +           - key: env.local
    +             path: env.local

    四、污点与容忍

    • 在 Kubernetes 中, Pod 被部署到 Node 上面去的规则和逻辑是由 Kubernetes 的调度组件根据 Node 的剩余资源,地位,以及其他规则自动选择调度的
    • 但前端和后端往往服务器资源的分配都是不均衡的,甚至有的服务只能让特定的服务器来跑
    • 在这种情况下,我们选择自动调度是不均衡的,就需要人工去干预匹配选择规则了
    • 这时候,就需要在给 Node 添加一个叫做污点的东西,以确保 Node 不被 Pod 调度到
    • 当你给 Node 设置一个污点后,除非给 Pod 设置一个相对应的容忍度,否则 Pod 才能被调度上去。这也就是污点和容忍的来源
    • 污点的格式是 key=value,可以自定义自己的内容,就像是一组 Tag 一样
    • Node_Name 为要添加污点的 node 名称
    • key 和 value 为一组键值对,代表一组标示标签
    • NoSchedule 则为不被调度的意思,和它同级别的还有其他的值:PreferNoSchedule 和 NoExecute
    kubectl taint nodes [Node_Name] [key]=[value]:NoSchedule
    //添加污点
    kubectl taint nodes node1 user-v4=true:NoSchedule
    //查看污点
    kubectl describe node node1
    kubectl describe node master
    Taints: node-role.kubernetes.io/master:NoSchedule
    vi deployment-user-v4.yaml
    apiVersion: apps/v1 
    kind: Deployment 
    metadata:
      name: user-v4 
    spec:
      minReadySeconds: 1
      selector:
        matchLabels:
          app: user-v4 
      replicas: 1
      template:
        metadata:
          labels:
            app: user-v4 
        spec:
          containers:
          - name: nginx
            image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 
            ports:
            - containerPort: 80
    kubectl apply -f deployment-user-v4.yaml
    • 给 Pod 设置容忍度
      • 想让 Pod 被调度过去,需要在 Pod 一侧添加相同的容忍度才能被调度到
      • 给 Pod 设置一组容忍度,以匹配对应的 Node 的污点
      • key 和 value 是你配置 Node 污点的 key 和 value
      • effect 是 Node 污点的调度效果,和 Node 的设置项也是匹配的
      • operator 是运算符,equal 代表只有 key 和 value 相等才算数。当然也可以配置 exists ,代表只要 key 存在就匹配,不需要校验 value 的值
    vi deployment-user-v4.yaml
    apiVersion: apps/v1 
    kind: Deployment 
    metadata:
      name: user-v4 
    spec:
      minReadySeconds: 1
      selector:
        matchLabels:
          app: user-v4 
      replicas: 1
      template:
        metadata:
          labels:
            app: user-v4 
        spec:  
    +     tolerations:
    +     - key: "user-v4"
    +       operator: "Equal"
    +       value: "true"
    +       effect: "NoSchedule"
          containers:
          - name: nginx
            image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 
            ports:
            - containerPort: 80
    # 修改Node污点
    kubectl taint nodes node1 user-v4=1:NoSchedule --overwrite
    # 删除Node污点
    kubectl taint nodes node1 user-v4-
    # 在Master上部署pod
    kubectl taint nodes node1 user-v4=true:NoSchedule
    kubectl describe node node1
    kubectl describe node master
    vi deployment-user-v4.yaml
    apiVersion: apps/v1 
    kind: Deployment 
    metadata:
      name: user-v4 
    spec:
      minReadySeconds: 1
      selector:
        matchLabels:
          app: user-v4 
      replicas: 1 
      template:
        metadata:
          labels:
            app: user-v4 
        spec:  
    +     tolerations:
    +     - key: "node-role.kubernetes.io/master"
    +       operator: "Exists"
    +       effect: "NoSchedule"
          containers:
          - name: nginx
            image: registry.cn-beijing.aliyuncs.com/zhangrenyang/nginx:user-v3 
            ports:
            - containerPort: 80
     kubectl apply -f deployment-user-v4.yaml
  • 相关阅读:
    pycharm 使用pip3更新插件已经更新时报错
    剑指Offer系列之题11~题15
    剑指Offer系列之题1~题5
    个人hexo博客(静态,无后台)搭建
    设计模式之单例模式
    Hibernate实现limit语句效果
    Springboot项目中 前端展示本地图片
    eclipse报错:problems during content assist
    python中open与with open的区别
    修改Jenkins目录
  • 原文地址:https://www.cnblogs.com/zaking/p/15144395.html
Copyright © 2020-2023  润新知