• k8s资源对象(二)


    1、Configmap和Secret资源介绍

    secret和configmap资源都是通过挂载的方式将对应数据挂载到容器内部环境中去使用,两者的使用没有太多的不同 ,configmap资源通常用于为pod提供配置文件;secret资源主要用于为pod提供证书、用户名密码等敏感数据;

    1.1、configmap资源

    Configmap将非机密性信息(如配置信息)和镜像解耦, 实现方式为将配置信息放到configmap对象中,然后在pod的中作为Volume挂载到pod中,从而实现导入配置的目的。

    1.1.1、ConfigMap资源使用场景

    • 通过Configmap给pod中的容器服务提供配置文件,配置文件以挂载到容器的形式使用。
    • 通过Configmap给pod定义全局环境变量。
    • 通过Configmap给pod传递命令行参数,如mysql -u -p中的账户名密码可以通过Configmap传递。

    1.1.2、注意事项

    • Configmap需要在pod使用它之前创建。
    • pod只能使用位于同一个namespace的Configmap,即Configmap不能跨namespace使用。
    • 通常用于非安全加密的配置场景。
    • Configmap通常是小于1MB的配置。

    1.2、secret资源

    Secret 的功能类似于 ConfigMap给pod提供额外的配置信息,但是Secret是一种包含少量敏感信息例如密码、令牌或密钥的对象。Secret 的名称必须是合法的 DNS 子域名。每个Secret的大小最多为1MiB,主要是为了避免用户创建非常大的Secret进而导致API服务器和kubelet内存耗尽,不过创建很多小的Secret也可能耗尽内存,可以使用资源配额来约束每个名字空间中Secret的个数。在通过yaml文件创建secret时,可以设置data或stringData字段,data和stringData字段都是可选的,data字段中所有键值都必须是base64编码的字符串,如果不希望执行这种 base64字符串的转换操作,也可以选择设置stringData字段,其中可以使用任何非加密的字符串作为其取值。

    1.2.1、Secret资源使用流程

    首先用户向apiserver提交创建secret资源的请求;apiserver收到用户的资源创建请求,通过apiserver的认证授权、准入控制后,apiserver会将创建好的secret信息存放在etcd中;随后用户在创建pod中调用了挂载某个secret以后,对应在pod创建时会被pause容器将对应secret资源中的data数据加载至对应pod中,从而实现让向pod内部传递敏感数据的目的;

    1.2.2、Secret资源使用场景

    • 作为挂载到一个或多个容器上的卷 中的文件(crt文件、key文件)。
    • 作为容器的环境变量。
    • 由 kubelet 在为 Pod 拉取镜像时使用(与镜像仓库的认证)。

    1.2.3、Secret资源类型简介

    Kubernetes默认支持多种不同类型的secret,用于一不同的使用场景,不同类型的secret的配置参数也不一样。

    2、configmap资源使用示例

    2.1、基于configmap给nginx pod提供自定义的server配置

    2.1.1、创建configmap资源

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-config
    data:
      mysite: |
        server {
           listen       80;
           server_name  www.mysite.com;
           index        index.html index.php index.htm;
    
           location / {
               root /data/nginx/mysite;
               if (!-e $request_filename) {
                   rewrite ^/(.*) /index.html last;
               }
           }
        }
    
      myserver: |
        server {
           listen       80;
           server_name  www.myserver.com;
           index        index.html index.php index.htm;
    
           location / {
               root /data/nginx/myserver;
               if (!-e $request_filename) {
                   rewrite ^/(.*) /index.html last;
               }
           }
        }  
    
    

    data字段中的mysite和myserver是用来标识不同配置信息的,即该名称用于pod挂载configmap资源时被引用的名称;

    应用资源配置清单

    kubectl apply -f nginx-configmap-demo.yaml
    

    验证configmap资源

    kubectl get cm
    

    kubectl describe cm nginx-config  
    

    2.1.2、创建pod使用使用挂载configmap

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ng-deploy-80
      template:
        metadata:
          labels:
            app: ng-deploy-80
        spec:
          containers:
          - name: ng-deploy-80
            image: harbor.ik8s.cc/baseimages/nginx:1.20.0
            ports:
            - containerPort: 80
            volumeMounts:
            - mountPath: /data/nginx/mysite
              name: nginx-mysite-statics
            - mountPath: /data/nginx/myserver
              name: nginx-myserver-statics
            - name: nginx-mysite-config
              mountPath:  /etc/nginx/conf.d/mysite/
            - name: nginx-myserver-config
              mountPath:  /etc/nginx/conf.d/myserver/
          volumes:
          - name: nginx-mysite-config
            configMap:
              name: nginx-config
              items:
                 - key: mysite
                   path: mysite.conf
          - name: nginx-myserver-config
            configMap:
              name: nginx-config
              items:
                 - key: myserver
                   path: myserver.conf
          - name: nginx-myserver-statics
            nfs:
              server: 192.168.0.42
              path: /data/k8sdata/myserver
          - name: nginx-mysite-statics
            nfs:
              server: 192.168.0.42
              path: /data/k8sdata/mysite
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ng-deploy-80
    spec:
      ports:
      - name: http
        port: 80
        targetPort: 80
        nodePort: 30019
        protocol: TCP
      type: NodePort
      selector:
        app: ng-deploy-80
    

    上述配置清单主要定义了一个deploy类型的控制器和nodeport类型的service,其中deploy控制器定义了一个nginx pod 挂载使用nfs服务上的静态资源和挂载使用configmap给nginx提供配置;service主要定义了通过标签选择器来匹配pod来实现将用户请求的流量转发至后端nginx pod;

    在nfs服务器上准备静态资源目录

    在nfs服务器上创建静态资源

    应用配置清单创建pod使用configmap资源和挂载nfs服务器上的静态资源

    kubectl apply -f nginx-dep-demo.yaml
    

    验证,查看pod配置信息是否正常被pod挂载?

    可以看到pod正常挂载configmap中指定的配置信息;

    在k8s集群节点任意节点上修改hosts文件来解析域名

    在k8s的节点上将对应域名指向集群任意节点地址上即可

    访问nginx,看看对应nfs静态资源是否能够正常被访问到?

    这里虽然能够正常被访问nginx主页,但是不是我们想要的页面,这其中的原因是,我们把nginxpod的配置文件挂载的路径没有在nginx.conf中导入,导致我们挂载的配置在nginx中没有生效;

    解决办法

    • 进入pod内部,修改nginx.conf配置文件 (临时生效,pod重建失效,不推荐)
    • 在制作镜像时,直接将主配置文件写好,再制作好镜像;(推荐)
    • 使用configmap资源将导入nginx配置再此挂载至/etc/nginx/conf.d/目录下;(默认nginx只导入了/etc/nginx/conf.d/*.conf,我们只需要将导入配置以.conf结尾的配置文件挂载至/etc/nginx/conf.d/目录下即可)

    进入nginxpod,修改主配置文件

    这里主要加上导入/etc/nginx/conf.d/下子目录下的.conf结尾的配置文件,让/etc/nginx/conf.d/myserver/myserver.conf和/etc/nginx/conf.d/mysite/mysite.conf配置文件被nginx加载;

    验证:使用不同域名访问nginx看看是否能够访问到对应不同的静态资源?

    现在使用不同域名的方式访问nginx就可以访问到不同站点的资源了;生产中会通过前端一个负载均衡器来反向代理nodeport类型的service;

    2.2、基于configmap给pod提供自定义环境变量

    2.2.1、创建configmap资源

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-config
    data:
      host: "172.31.7.189"
      username: "user1"
      password: "12345678"
    

    应用上述配置清单,创建configmap资源

    2.2.2、创建pod使用configmap资源

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ng-deploy-80
      template:
        metadata:
          labels:
            app: ng-deploy-80
        spec:
          containers:
          - name: ng-deploy-80
            image: harbor.ik8s.cc/baseimages/nginx:1.20.0
            env:
            - name: HOST
              valueFrom:
                configMapKeyRef:
                  name: nginx-config
                  key: host
            - name: USERNAME
              valueFrom:
                configMapKeyRef:
                  name: nginx-config
                  key: username
            - name: PASSWORD
              valueFrom:
                configMapKeyRef:
                  name: nginx-config
                  key: password
            ######
            - name: "password"
              value: "123456"
            ports:
            - containerPort: 80
    

    向pod内部传递环境变量的方式有两种,一种是通过env字段来引用configmap资源,使用name字段来指定环境变量名称,使用valueFrom字段来指定对应环境变量值的来源;configMapKeyRef字段表示使用configmap资源来向对应环境变量赋值;name是指定configmap的名称,key是用来指定configmap中对应key;另外一种就是使用env字段,通过列表的方式直接向pod传递键值环境变量;

    应用配置清单

    可以看到创建的pod内部有我们再configmap中定义的环境变量,也有我们通过env直接指定键值的环境变量;

    3、secret资源使用示例

    3.1、基于自定义的Secret实现Nginx https认证

    3.1.1、自签名证书制作

    3.1.1.1、生成自签名CA证书

    openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 3560 -nodes -subj '/CN=www.ca.com'
    

    3.1.1.2、生成自签名证书私钥和CSR

    openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=www.mysite.com'
    

    3.1.1.3、用自签名CA证书签发自签名证书csr生成自签名证书crt

    openssl x509 -req -sha256 -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
    

    3.1.2、基于自签名证书在k8s上创建secret资源

    kubectl create secret tls myserver-tls-key --cert=./server.crt --key=./server.key
    

    3.1.3、创建nginx配置清单使用secret

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-config
    data:
     default: |
        server {
           listen       80;
           server_name  www.mysite.com;
           listen 443 ssl;
           ssl_certificate /etc/nginx/conf.d/certs/tls.crt;
           ssl_certificate_key /etc/nginx/conf.d/certs/tls.key;
    
           location / {
               root /usr/share/nginx/html; 
               index index.html;
               if ($scheme = http ){  #未加条件判断,会导致死循环
                  rewrite / https://www.mysite.com permanent;
               }  
    
               if (!-e $request_filename) {
                   rewrite ^/(.*) /index.html last;
               }
           }
        }
    
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myserver-myapp-frontend-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: myserver-myapp-frontend
      template:
        metadata:
          labels:
            app: myserver-myapp-frontend
        spec:
          containers:
          - name: myserver-myapp-frontend
            image: harbor.ik8s.cc/baseimages/nginx:1.20.0
            ports:
              - containerPort: 80
            volumeMounts:
              - name: nginx-config
                mountPath:  /etc/nginx/conf.d/myserver
              - name: myserver-tls-key
                mountPath:  /etc/nginx/conf.d/certs
          volumes:
          - name: nginx-config
            configMap:
              name: nginx-config
              items:
                 - key: default
                   path: mysite.conf
          - name: myserver-tls-key
            secret:
              secretName: myserver-tls-key 
    
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: myserver-myapp-frontend
    spec:
      type: NodePort
      ports:
      - name: http
        port: 80
        targetPort: 80
        nodePort: 30018
        protocol: TCP
      - name: htts
        port: 443
        targetPort: 443
        nodePort: 30019
        protocol: TCP
      selector:
        app: myserver-myapp-frontend 
    

    上述配置清单主要创建了一个configmap资源,用来给nginxpod提供配置信息,然后创建了一个deploy控制器运行了一个nginx pod ,这个pod挂载使用configmap和secret资源;最后创建了一个service将对应nginx Pod服务暴露给集群外部客户端访问;

    应用配置清单

    验证:进入pod内部,查看对应配置信息和证书文件是否正常挂载?

    可以看到我们创建configmap资源中的配置信息和secret资源中的证书信息都正常挂载至nginx pod对应指定目录下

    修改nginx主配置文件,让其加载我们通过configmap挂载的配置文件

    重载nginx pod配置文件

    上述方法不推荐,正确的做法就是在打镜像的时候,将对应配置文件打入镜像;或者我们使用configmap将对应配置信息创建为configmap资源对象,然后再pod中挂载对应配置信息即可;

    验证:访问集群任意节点30018端口和30019端口,看看对应nginx pod是否能够正常被访问?是否是加密访问呢?

    从上面的访问情况可以看到,直接访问30019,会报400,这是因为30019时一个https的端口,用http的协议去访问肯定不能正常响应;当我们访问30018时,对应页面会进行跳转到https://www.mysite.com,这是因为我们在nginx的配置中配置了访问http端口进行重定向https://www.mysite.com;访问30019端口时,用https协议访问30019时,也正常加载了证书;

    使用configmap将nginx配置信息导入主配置文件

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: include-conf
    data:
     include.conf: |
        include /etc/nginx/conf.d/*/*.conf;
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: nginx-config
    data:
     default: |
        server {
           listen       80;
           server_name  www.mysite.com;
           listen 443 ssl;
           ssl_certificate /etc/nginx/conf.d/certs/tls.crt;
           ssl_certificate_key /etc/nginx/conf.d/certs/tls.key;
    
           location / {
               root /usr/share/nginx/html; 
               index index.html;
               if ($scheme = http ){  #未加条件判断,会导致死循环
                  rewrite / https://www.mysite.com permanent;
               }  
    
               if (!-e $request_filename) {
                   rewrite ^/(.*) /index.html last;
               }
           }
        }
    
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myserver-myapp-frontend-deployment-v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: myserver-myapp-frontend-v1
      template:
        metadata:
          labels:
            app: myserver-myapp-frontend-v1
        spec:
          containers:
          - name: myserver-myapp-frontend-v1
            image: harbor.ik8s.cc/baseimages/nginx:1.20.0
            ports:
              - containerPort: 80
            volumeMounts:
              - name: nginx-config
                mountPath:  /etc/nginx/conf.d/myserver
              - name: myserver-tls-key
                mountPath:  /etc/nginx/conf.d/certs
              - name: include-conf
                mountPath: /etc/nginx/conf.d
          volumes:
          - name: nginx-config
            configMap:
              name: nginx-config
              items:
                 - key: default
                   path: mysite.conf
          - name: myserver-tls-key
            secret:
              secretName: myserver-tls-key 
          - name: include-conf
            configMap:
              name: include-conf
              items:
                 - key: include.conf
                   path: include.conf
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: myserver-myapp-frontend-v1
    spec:
      type: NodePort
      ports:
      - name: http
        port: 80
        targetPort: 80
        nodePort: 31080
        protocol: TCP
      - name: htts
        port: 443
        targetPort: 443
        nodePort: 31443
        protocol: TCP
      selector:
        app: myserver-myapp-frontend-v1
    

    pod挂载使用configmap时,对应pod内部必须事先不存在对应文件,如果对应文件存在,则对应pod会启不起来;所以我们挂载configmap时指定挂载至/etc/nginx/conf.d即可;

    应用配置清单,看看使用https访问31443是否可以正常访问?


    3.2、基于自定义的Secret实现私有镜像的下载认证

    3.2.1、创建secret资源

    3.2.1.1、通过命令创建secret资源

    kubectl create secret docker-registry harbor.ik8s.cc-imagepull \
                                        --docker-server=harbor.ik8s.cc \
                                        --docker-username=admin \
                                        --docker-password=123456
    

    3.2.1.2、通过docker/containerd认证文件创建secret资源

    登录harbor,生成config.json文件

    使用config.json文件创建secret资源

    kubectl create secret generic harbor.k8s.cc-registry-image-pull-key \
                    --from-file=.dockerconfigjson=/root/.docker/config.json \
                    --type=kubernetes.io/dockerconfigjson
    

    在harbor上将baseimgaes仓库设置为私有仓库

    验证,使用docker/containerd拉取harbor.k8s.cc/baseimages下的镜像,看看是否可以正常拉取?

    可以看到现在更改仓库为私有仓库以后,对应仓库中的镜像不可以正常被拉取

    验证,使用私有仓库镜像创建pod,看看pod是否能够正常运行起来?

    apiVersion: v1
    kind: Pod
    metadata:
      name: "tomcat-demo"
      namespace: default
      labels:
        app: "tomcat-demo"
    spec:
      containers:
      - name: tomcat-demo
        image: "harbor.ik8s.cc/baseimages/tomcat:v1"
        ports:
        - containerPort:  8080
          name:  http
    

    应用配置清单,看看对应pod是否能够正常跑起来?

    可以看到对应pod处于ErrImagePull状态,该状态就是表示pod在创建时,下载镜像错误

    查看pod详细信息

    3.2.2、创建pod使用secret

    apiVersion: v1
    kind: Pod
    metadata:
      name: "tomcat-demo"
      namespace: default
      labels:
        app: "tomcat-demo"
    spec:
      containers:
      - name: tomcat-demo
        image: "harbor.ik8s.cc/baseimages/tomcat:v1"
        imagePullPolicy: Always
        ports:
        - containerPort:  8080
          name:  http
      imagePullSecrets:
        - name: harbor.k8s.cc-registry-image-pull-key
    

    spec字段中使用imagePullSecrets字段来引用dockerconfigjson类型的secret资源,使用name字段指定secret的名称即可

    3.2.3、验证pod运行状态

    应用配置清单,看看对应pod是否能够正常跑起来?

    可以看到现在对应pod正常跑起来

  • 相关阅读:
    【计算机网络】第三章·数据链路层 超硬核复习好物,考前必看!!!
    HTML5 跨屏前端框架 Amaze UI
    现在的湖仓一体像是个伪命题
    解决在服务器中减少删除大文件夹耗时太久的问题
    分布式软件开发的相关技术
    pdf转jpg怎么转?转换软件分享
    【第六章-函数】1.函数的灵活性
    用例图中include和extend的含义
    计算机毕业设计(附源码)python元江特色农产品售卖平台
    k8s中Endpoint是什么
  • 原文地址:https://www.cnblogs.com/qiuhom-1874/p/17412997.html