Kubernetes进阶实战读书笔记:配置容器应用(容器化应用配置方式)

 一、容器化应用配置方式

每个应用程序都是一个可执行程序文件、它包含操作码列表、CPU通过执行这些操作码来完成特定的操作、例如,cat命令是由:/usr/bin/cat文件提供的、该文件含有机器指令的列表、在屏幕上显示制定文件的内容时需要使用这些机器指令、几乎每个程序的行为都可以通过其命令选项及参数或配置文件来按需定制、实践中、人们通常不会以默认的配置参数运行应用程序、而是需要根据特定的环境或具体的需求定制起运行特性、对于复杂的服务类应用程序更是如此,如NGINX、tomacat和HBase等、而且通过配置文件定义其配置通常首选甚至是唯一的途径

为nginx配置一个特定的SERVER 或指定worker进程的数量、为tomcat的JVM配置起队内存的大小等

1、通过命令行参数进行配置

dockerfile中的ENTRPOINT和CMD、同时使用CMD指令列表的所有元素均被视作是由ENTRPOINT制定的程序的命令行参数
在基于某镜像使用docker命令创建容器时、可以在冥想行向ENTRPOINT中的程序传递额外的自定义参数、甚至还可以修改要运行的应用程序本身
在kubernetes系统上创建pod资源是、也能像容器话应用传递命令行参数,甚至制定运行其他应用程序、相关字段分别为

[root@master ~]# kubectl explain pod.spec.containers.command
KIND:     Pod
VERSION:  v1

FIELD:    command <[]string>

DESCRIPTION:
     Entrypoint array. Not executed within a shell. The docker image's
     ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME)
     are expanded using the container's environment. If a variable cannot be
     resolved, the reference in the input string will be unchanged. The
     $(VAR_NAME) syntax can be escaped with a double $$, ie: $$(VAR_NAME).
     Escaped references will never be expanded, regardless of whether the
     variable exists or not. Cannot be updated. More info:
     https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

root@master ~]# kubectl explain pod.spec.containers.args
KIND:     Pod
VERSION:  v1

FIELD:    args <[]string>

DESCRIPTION:
     Arguments to the entrypoint. The docker image's CMD is used if this is not
     provided. Variable references $(VAR_NAME) are expanded using the
     container's environment. If a variable cannot be resolved, the reference in
     the input string will be unchanged. The $(VAR_NAME) syntax can be escaped
     with a double $$, ie: $$(VAR_NAME). Escaped references will never be
     expanded, regardless of whether the variable exists or not. Cannot be
     updated. More info:
     https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shel

2、将配置文件键入镜像文件

dockerfile:COPY到系统上的目标位置或者用sed或echo一类的命令修改配置文件从而额外添加配置文件之目的
优点:简单易用、不用任何额外的设定就能启动符合需求的容器、
用于kubernetes环境亦无需多余的配置、但配置文件相关的任何额外的修改需求都不得不通过重新构建镜像文件来实现、路径长、效率低

3、通过环境变量向容器注入配置信息

MySQL官网提供的惊险该文件启动MySQL容器时使用的MYSQL_ROOT_PASSWORD环境变量、它用于MySQL服务的root用户设置登录密码

dokcer run -e SETTING1=foo -e SETTING2=bar .... <image name>

另外、也可以让容器的ENTRPOINT启动脚本通过网络中的K/V存储获取配置参数、常用的此类存储系统有Consul或etcd等
这种方式较简单的环境变量能够提供更复杂的配置信息、因为KV存储系统支持多层级的嵌套数据结构、有一些应用广泛的数据抓取工具能够从
K/V存储中加载相关的数据并替换于配置文件中,甚至与像confd这类的工具还能在KV中的数据变化时自动将其重载至配置文件中、这一点实现了真正意义上的配置动态化、不过,这种方式为容器化用用引入了额外的依赖条件

kubernetes系统支持在pod资源配置容器时使用pod.spec.containers.env为容器的环境变量值从而完成用用的配置、如前所述、这种方式无法应付较复杂的配置场景、因此提供的配置能力也很有限

4、通过存储卷向容器注入配置信息

docker 存储卷能够将宿主机之上的任何文件或目录迎神到容器文件系统上、因此、可以事先将配置文件放置于用户需要实现将配置数据提供在宿主机上的特定路径下
优点:这种方式灵活医用、但也以来与用户需要实现将配置数据提供在宿主机上的特定路径下、而且在多主机模型中,若容器存在被调度至任一主机运行的可能性时、用户还需要将配置共享到任一宿主机以确保容器能够正确地获取到它们

5、借助docker config进行容器配置

docker swarm service 自1.13版本起支持使用secret于容器之外保存二进制数据、包括口令、SSH私钥、SSL证书以及其他不建议通过网络传输或不应该在dockerfile及程序源码中非加密保存的机密数据。

用户可使用secret集中化管理这类数据并将其安全关联至那些需要访问这些数据的容器中、docker 17.06版本起为swarm service引入了允许用户于容器之外存储非敏感信息

(如配置文件)的组件"service config",从而支持用户创建通用目的镜像文件、并且不再需要通过挂在存储卷或使用环境变量为容器提供配置文件

docker swarm service secret和config为容器化应用的配置提供了极大的灵活性、不过、他们也只能应用于docker swarm service环境中、而不能用用语单独运行的容器之上

kubernetes系统也有类似的组件、他们成为Secret和ConfigMap、而且是kubernetes系统上一等类别的资源对象、他们要么被pod自愿以存储卷的形式加载、要么由容器通过哟envFrom字段以变量的形式加载

二、通过命令行参数进行配置容器应用

1、配置清单

下面是定义在command-demo.yaml文件中的pod资源示例、它在容器command-demo-container中将busybox镜像文件中默认运行的命令["/bin/sh","-c"]修改为["httpd"],并且为其额外传递了["-f"]选项

[root@master chapter8]# cat command-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: command-demo
  labels:
    purpose: demonstrate-command
spec:
  containers:
  - name: command-demo-container
    image: busybox
    command: ["httpd"]
    args: ["-f"]
  restartPolicy: OnFailur

2、只提供args字段

只提供args字段、以实现向默认运行的程序提供额外的参数、如果默认的命令为shell解释器或entypoint启动脚本

例如下面的容器配置、表示要运行的程序为"/bin/sh -c httpd","-f" 实现了以shell解释器解释运行指定的程序之目的

spec:
  containers:
  - name: command-demo-container
    image: busybox
    args: ["httpd","-f"]
    - containerport: 80

kubernetes配置文件中的command对应于Dockerfile中的ENTRPOINT、而同时给出command和args时,会对应覆盖ENTRPOINT和CMD其应用生效的、例如下图所示

通过命令行参数的方式向容器应用传递配置数据的操作比较简单、但其功能有限、难以为应用生成复杂配置,尤其是那些不支持通过命令行参数进行的配置将无法基于这种机制来实现、另外需要注意的是,在容器创建完成后,修改command和args并不会直接生效除非重建Pod对象

三、利用环境变量配置容器  

1、在容器启动时向其传递环境变量

docker原生的应用程序应该使用很小的配置文件,并且每一项参数都可以由环境变量或命令选项覆盖、从而能够在运行时完成任意的按需配置。然而,目前有极少一部分应用程序为为容器环境原生设计
毕竟为容器原生重构应用程序工程浩大、切旷日持久

好在有通过容器启动脚本为应用程序预设运行环境的方法可用通过docker镜像时为ENTRPOINT指定一个脚本,
它能够在启动容器时将环境变量替换至应用程序的配置文件中,而后再由此脚本启动相应的应用程序、基于这类镜像运行容器是、即可通过向环境变量传值的方式来配置应用程序

在kubernetes中使用镜像启动容器时、也可以在pod资源或pod模板资源的定义中为容器配置段使用env参数来定义所使用的环境变量、只不过他不被使用罢了

2、pod.spec.containers.env

环境变量配置容器化应用时,需要在容器配置段中嵌套使用env字段、它的值是一个由环境变量构建的列表。环境变量通常由name和value字段构成

[root@master ~]# kubectl explain pod.spec.containers.env
KIND:     Pod
VERSION:  v1

RESOURCE: env <[]Object>

DESCRIPTION:
     List of environment variables to set in the container. Cannot be updated.

     EnvVar represents an environment variable present in a Container.

FIELDS:
   name	<string> -required-
   #环境变量的名称、必选字段
     Name of the environment variable. Must be a C_IDENTIFIER.

   value	<string>
   #环境变量的值、通过$(VAR_NAME)引用,逃逸格式为"$$(VAR_NAME)"
     Variable references $(VAR_NAME) are expanded using the previous defined
     environment variables in the container and any service environment
     variables. If a variable cannot be resolved, the reference in the input
     string will be unchanged. The $(VAR_NAME) syntax can be escaped with a
     double $$, ie: $$(VAR_NAME). Escaped references will never be expanded,
     regardless of whether the variable exists or not. Defaults to "".

   valueFrom	<Object>
   #环境变量值的引用源、例如,当前pod资源的名称、名称空间、标签等、不能与非空值value字段同时使用、即环境变量的值要么源于value字段、要么源于valueFrom字段可饮用的值有多种来源,包括当前pod资源的属性值、容器相关的系统资源配置、ConfigMap对象中的key以及sercret对象中key、它们应分别使用不同的嵌套字段进行定义
   
     Source for the environment variable's value. Cannot be used if value is not empty.

3、配置清单

[root@master chapter8]# cat env-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: env-demo
  labels:
    purpose: demonstrate-environment-variables
spec:
  containers:
  - name: env-demo-container
    image: busybox
    command: ["httpd"]
    args: ["-f"]
    env:
    - name: HELLO_WORLD
      value: just a demo
    - name: MY_NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: MY_NODE_IP
      valueFrom:
        fieldRef:
          fieldPath: status.hostIP
    - name: MY_POD_NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
  restartPolicy: OnFailure

4、创建运行

创建上面资源清单中定义的pod对象env-demo、而后打印它的环境变量列表、命令及其结果如下:  

[root@master chapter8]# kubectl apply -f env-demo.yaml 
pod/env-demo created
[root@master chapter8]# kubectl exec env-demo printenv
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=env-demo
HELLO_WORLD=just a demo
......

四、应用程序配置管理及ConfigMap资源(创建对象)

分布式环境中,基于负载、容错等需求的考虑、几乎所有的服务都需要在不同的机器节点上部署不止一个实例、随着程序功能的日益复杂、程序的配置日益增多、而且配置文件的修改频率通常圆圆大于代码本身,这种个情况下、有时仅仅是一个配置内容的修改、就不得不重新进行代码提交到SVN/Git、打包、分发上线的流程、部署规则较大的场景中、分发上线工作繁杂又沉重

作为分布式系统kubernetes的也也提供了统一的配置管理方案ConfigMap。kubernetes基于ConfigMap对象实现了将配置文件从容器镜像中解耦、从而增强了容器应用的可一移植性。简单来说、一个ConfigMap对象就是一系列配置数据的集合、这些数据可注入到POD对象中、并且为容器应用所使用、注入方式有挂载为存储卷和传递为环境变量两种

 1、查看帮助信息

reate a configmap based on a file, directory, or specified literal value.

 A single configmap may package one or more key/value pairs.

 When creating a configmap based on a file, the key will default to the basename of the file, and the value will default
to the file content.  If the basename is an invalid key, you may specify an alternate key.

 When creating a configmap based on a directory, each file whose basename is a valid key in the directory will be
packaged into the configmap.  Any directory entries except regular files are ignored (e.g. subdirectories, symlinks,
devices, pipes, etc).

Aliases:
configmap, cm

Examples:
  # Create a new configmap named my-config based on folder bar
  kubectl create configmap my-config --from-file=path/to/bar
  
  # Create a new configmap named my-config with specified keys instead of file basenames on disk
  kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
  
  # Create a new configmap named my-config with key1=config1 and key2=config2
  kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
  
  # Create a new configmap named my-config from the key=value pairs in the file
  kubectl create configmap my-config --from-file=path/to/bar
  
  # Create a new configmap named my-config from an env file
  kubectl create configmap my-config --from-env-file=path/to/bar.env

Options:
      --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in
the template. Only applies to golang and jsonpath output formats.
      --append-hash=false: Append a hash of the configmap to its name.
      --dry-run='none': Must be "none", "server", or "client". If client strategy, only print the object that would be
sent, without sending it. If server strategy, submit server-side request without persisting the resource.
      --from-env-file='': Specify the path to a file to read lines of key=val pairs to create a configmap (i.e. a Docker
.env file).
      --from-file=[]: Key file can be specified using its file path, in which case file basename will be used as
configmap key, or optionally with a key and file path, in which case the given key will be used.  Specifying a directory
will iterate each named file in the directory whose basename is a valid configmap key.
      --from-literal=[]: Specify a key and literal value to insert in configmap (i.e. mykey=somevalue)
  -o, --output='': Output format. One of:
json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
      --save-config=false: If true, the configuration of current object will be saved in its annotation. Otherwise, the
annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
      --template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The
template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
      --validate=true: If true, use a schema to validate the input before sending it

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

Use "kubectl options" for a list of global command-line options (applies to all commands)

2、利用直接值创建

语法格式:

为"kubectl create configmap"命令使用"--from-literal"选项可在命令行直接给出键值来创建configmap对象,重复使用此项可以传递多个键值对命令格式如下:

 kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2

示例:

root@master chapter8]# kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm
configmap/special-config created

查看创建的configmap对象special-config的相关信息  

[root@master chapter8]# kubectl get configmaps special-config  -o yaml
apiVersion: v1
data:
  special.how: very
  special.type: charm
kind: ConfigMap
metadata:
  creationTimestamp: "2020-09-01T02:53:29Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:special.how: {}
        f:special.type: {}
    manager: kubectl
    operation: Update
    time: "2020-09-01T02:53:29Z"
  name: special-config
  namespace: default
  resourceVersion: "6269132"
  selfLink: /api/v1/namespaces/default/configmaps/special-config
  uid: 81c8074e-a9d7-463e-b5ea-e8dc2b3e7dd7

 此类方式提供的数据量有限、一般是在仅通过有限的几个数据项即可为pod资源提供足够的配置信息时使用 

2、基于文件创建

语法格式

为"kubectl create configmap"命令使用"--from-file"选项可基于文件内容创建创建configmap对象,命令格式如下。可重复多次使用"--from-file"选项以传递多个文件内容

kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2

示例

 例如下面的命令可以把事先准备好的nginx配置文件模板保存于configmap对象nginx-config中

[root@master data]# kubectl create configmap nginx-config --from-file=/data/kubernetes_Advanced_Practical/chapter8/data/configs/nginx/conf.d/myserver.conf 
configmap/nginx-config created

查看创建的configmap对象special-config的相关信息 

这种方式创建的configmap对象、其输存储的键为文件路径的基名,值为文件内容、例如下面命令显示的nginx-config对象的信息

[root@master data]# kubectl get configmaps nginx-config  -o yaml
apiVersion: v1
data:
  myserver.conf: |
    server {
        listen 8080;
        server_name www.ikubernetes.io;

        include /etc/nginx/conf.d/myserver-*.cfg;

        location / {
            root /usr/share/nginx/html;
        }
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2020-09-01T03:00:37Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:myserver.conf: {}
    manager: kubectl
    operation: Update
    time: "2020-09-01T03:00:37Z"
  name: nginx-config
  namespace: default
  resourceVersion: "6270215"
  selfLink: /api/v1/namespaces/default/configmaps/nginx-config
  uid: 03970850-43c2-4699-9039-0a0210131b68

如果需要自行指定键名,则可在"--from-file"选项中直接指定自定义的键,命令格式如下:

kubectl create configmap NAME --from-file=<my-key-name>=<path-to-file>

通过这种方式创建的configmap资源可以直接以键值形式收纳应用程序的完整配置信息、多个文件可分别存储于不同的键值当中、另外需要说明的是基于直接值和基于文件创建方式可以混编使用

3、基于目录创建(测试失败用多文件替代)

命令格式如下:

kubectl create configmap NAME --from-file=<path-to-directory>

如下面的命令、将/data/configs/nginx/conf.d/目录下的所有文件都保存于nginx-config-files对象中

[root@master chapter8]# kubectl create configmap nginx-config-files --from-file=./data/configs/nginx/conf.d/myserver.conf --from-file=./data/configs/nginx/conf.d/myserver-gzip.cfg --from-file=./data/configs/nginx/conf.d/myserver-status.cfg
configmap/nginx-config-files created
[root@master chapter8]# kubectl get cm
NAME                   DATA   AGE
busybox-httpd-config   2      19h
nginx-config-files     3      7s
special-config         2      23h

此目录中包含myserver.conf、myserver-gzip.cfg和myserver-status.cfg三个配置文件、创建资源时、它们会被分贝存储为三个键值数据,如下面的命令及其结果所示:

[root@master chapter8]# ll /data/configs/nginx/conf.d/
total 12
-rw-r--r-- 1 root root 171 Aug 5 15:17 myserver.conf
-rw-r--r-- 1 root root 159 Aug 5 15:17 myserver-gzip.cfg
-rw-r--r-- 1 root root 67 Aug 5 15:17 myserver-status.cfg

创建验证

[root@master chapter8]# kubectl create configmap nginx-config-files --from-file= ./data/configs/nginx/conf.d/
[root@master chapter8]# kubectl get cm nginx-config-files -o yaml

4、使用清单创建 

基于配置文件创建configmap资源时,它所使用的字段包括通常的apiVersion、kind、metadata字段、以及用于存储数据的关键字段"data"

apiVersion:v1
kind: ConfigMap
metadata:
  name: configmap-demo
  namespace: default
data:
  log_level: INFO
  log_file: /var/log/test.log

如果其值来自于文件内容时,则使用配置文件创建configmap资源的便捷性还不如直接通过命令的方式、因此建议直接使用命令行加载文件或目录的方式进行创建。为了便于配置留存
可以在创建完成后使用get -O yaml 命令获取到相关信息后再进行编辑留存

posted @ 2020-09-05 23:04  活的潇洒80  阅读(563)  评论(0编辑  收藏  举报