1 容器化应用配置方式概述

1 启动时直接向命令传递参数

docker 容器可用来运行单个应用程序,在制作docker镜像时,Dockerfile中的ENTRYPOINT 和 CMD 指令可用于指定容器启动时要运行的程序及相关的参数,CMD 指令以列表的形式指定要运行的程序及相关的参数,但若同时存在ENTRYPOINT指令,则CMD指令列表中的所有元素都被视为是ENTRYPOINT中程序的命令行参数,另外,在基于某镜像使用Docker 命令创建容器时,可在命令行向ENTRYPOINT中的程序传递额外的自定义参数,甚至可以修改要运行的应用程序本身。
Docker run [COMMAND] [ARG]为自定义运行程序,[ARG]则是要传递给程序的参数,若定义相关镜像文件时使用了ENTRYPOINT 指令,则[COMMAND]和[ARG]都被当做命令行参数传递给ENTRYPOINT指令中指定的程序,除非docker run明文指定额外使用--entrypoint 选项覆盖


补充
如果 ENTRYPOINT 使用了 shell 模式,CMD 指令会被忽略。
如果 ENTRYPOINT 使用了 exec 模式,CMD 指定的内容被追加为 ENTRYPOINT 指定命令的参数。
如果 ENTRYPOINT 使用了 exec 模式,CMD 也应该使用 exec 模式。

2 将定义好的配置文件硬编码到镜像文件中

在Dockerfile中使用COPY指令将定义好的配置文件复制到镜像文件系统上的目标位置,或使用RUN指令调用sed或echo修改配置文件从而达到目的

3 通过环境变量传递配置数据

用户为docker run 命令通过-e 选项向环境指令变量传值即能实现应用配置,命令格式为docker run -e NAME=tomcat -e PORT=80 ,启动时,容器的ENTRYPOINT脚本应该为这些环境变量提供默认值,以方便用户在未定义环境变量时也能基于此类需要环境变量的镜像启动容器,使用环境变量这种配置方式的优势在于能够将配置信息的动态化,。

另外,也可通过容器的ENTPYPOINT启动脚本通过网络中的K/V 存储获取配置参数,常用的此类存储有Consul 或 etcd等。

4 基于Docker卷传送配置文件

docker 存储卷 可将宿主机上的任何文件或目录映射到容器文件系统中,使用-v 参数可挂载

5 借助 docker config 进行容器配置

docker 自17.06 版本其为swarm service 引入了允许用户于容器之外存储非敏感信息的组件 service config,从而支持用户创建通用的景象文件,并且不再需要通过挂载存储卷或使用环境变量为容器提供配置文件。
docker swarm service secret 和 config 为容器化应用的配置提供了极大的灵活性,其缺点是只能应用于docker swarm service环境中,不能单独运行与容器之上。

2 通过命令行参数配置容器应用

1 总述

创建POD资源时,可以在容器中定义要运行的命令以及其传递的参数和选项,在容器的配置上下文中,可使用command字段指定运行的程序,而args字段可以用于指定传递程序的选项及参数,在配置文件中定义command和args 会覆盖镜像文件中相关的默认设定,这类程序会被直接运行,而不会由shell 解释器运行,因此与shell相关的特性均不被支持,如 {} 、重定向等操作。

2 实例

1 查看默认镜像命令

kubernetes ConfigMap和Secret
busvbox 中默认运行的命令是/bin/sh

2 配置实例

#[root@master all]# cat demo.yaml 
apiVersion: v1
kind: Pod
metadata:
    name: nginx
    namespace: default
spec:
    containers:
        - name: busybox
          image: busybox
          command: ["httpd"]  # 默认此镜像对应的COMMAND 是"/bin/sh"  "-c"
          args: ["-f"]
          ports:
            - containerPort: 80
    restartPolicy: OnFailure

3 部署

kubectl apply -f demo.yaml 

4 查看

kubernetes ConfigMap和Secret

用户也可以在容器配置的下上文中提供args字段,以实现向默认运行的程序提供额外的参数,如果默认的命令为shell 解释器或entrypoint启动脚本,那么这些参数本身还需要时运行的命令和参数。

注: kubernetes 中的command 命令对应容器中的ENTRYPOINT,而args则对应容器中的CMD,kubernetes只给出args字段,其会覆盖CMD,若同时给出command和args,则会覆盖ENTRYPOINT和CMD。容器创建完成后,修改command和args字段并不会直接生效,除非重建POD对象

2 利用环境变量配置容器应用

1 总述

在kubernetes使用镜像启动容器时,也可以在Pod资源或Pod模板资源的定义中,为容器配置段使用env参数来定义所使用的环境变量列表。事实上,不指定环境变量的容器其自身还会传递环境变量,不过其不会被使用罢了。

2 核心字段概述

pods.spec.containers.env
pods.spec.containers.env.name: 环境变量名称,必选字段
pods.spec.containers.env.value: 环境变量的值,默认为空
pods.spec.containers.env.valueFrom: 环境变量引用源
pods.spec.containers.env.valueFrom.fieldRef: 当前POD资源的指定字段,目前支持的字段有 metadata.name,metadata.namespace、metadata.labels、metadata.annotations、spec.nodeName、spec.serviceAccountName、status.hostIP 和 status.podIP。
pods.spec.containers.env.valueFrom.configMapKeyRef: ConfigMap 对象中的特定的key 
pods.spec.containers.env.valueFrom.resourceFieldRef : 当前容器的特定资源的最小值或最大值,目前支持的对象包括limits.cpu、limits.memory、limits.ephermeral-storage、requests.cpu、requests.memory和requests.ephemeral-storage。
pods.spec.containers.env.valueFrom.secretKeyRef: Secret 对象中的特定Key。

3 实战

1 实例

#[root@master all]# cat demo1.yaml 
apiVersion: v1
kind: Pod
metadata:
    name: nginx1
    namespace: default
spec:
    containers:
        - name: busybox1
          image: busybox
          command: ["httpd"]  # 默认此镜像对应的COMMAND 是"/bin/sh"  "-c"
          args: ["-f"]
          ports:
            - containerPort: 80
          env:
            - name: HOSTNAME  #key-value 格式
              value: nginx1
            - name: DEFAULT_NAMESPACE  #指定当前kubernetes相关参数作为环境变量
              valueFrom:
                fieldRef: 
                    fieldPath: metadata.namespace                
    restartPolicy: OnFailure

2部署

kubectl apply -f demo1.yaml 

3 查看

kubernetes ConfigMap和Secret
其环境变量已显示成功

注: 上述两种方式的缺点是不能在容器运行过程中进行修改参数完成配置,需要进行重新部署

3 ConfigMap

1 总述

kubernetes 基于ConfigMap对象将配置技术局以键值对的形式进行存储,这些数据可以在Pod对象中使用或者为系统组件提供配置,其是基于名称空间的,用户可以在不同环境中创建名称相同但内容不同的ConfigMap对象, 从而为不同环境中同一功能的Pod资源提供不同的配置信息,从而实现更加灵活的配置。

2 创建ConfigMap对象

1 命令行方式创建

1 创建基于键值对的字符value

kubectl create configmap  config  --from-literal=name=web  --from-literal=ip='127.0.0.1'

kubectl create configmap 对象名称 --from-literal=对应的键=对应的值

查看
kubernetes ConfigMap和Secret

查看详细信息
kubernetes ConfigMap和Secret

2 基于文件传递的方式创建/创建挂载配置文件至指定目录

创建配置文件

#[root@master all]# cat nginx-www.conf 
server  {
    server_name  www.zhangbing.com;
    listen 80;
    location  / {
    root  /usr/share/nginx/html1;
        }
}
server  {
    server_name  _;
    listen  80 default_server;
    location / {
        root /usr/share/nginx/html;
}
}

创建服务

kubectl create  configmap  nginx-www --from-file=./nginx-www.conf

kubectl create configmap 对象名称 --from-file=对象文件(可包含目录)
此时的key值为对象文件名称,其可重新定义为如下
kubectl create configmap 对象名称 --from-file=对象key值=对象文件(可包含目录) value

查看
kubernetes ConfigMap和Secret

3 基于目录方式创建configmap

1 创建目录配置文件

kubernetes ConfigMap和Secret

2 生成configmap
kubectl create configmap   nginx-con --from-file=/conf/

其可使用相对目录
查看
kubernetes ConfigMap和Secret

kubernetes ConfigMap和Secret

2 配置文件方式创建

1 创建简单的key-value 键值对

#[root@master all]# cat demo2.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
    name: config1
    namespace: default
data:  #配置环境变量为字符串
    name: web1
    ip: 192.168.100.100

部署

kubectl apply -f demo2.yaml

查看
kubernetes ConfigMap和Secret

2 创建文件形式的value 数据

#[root@master all]# cat demo3.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
    name: config2
    namespace: default
data:  #配置环境变量为文件内容,及字符串集合
    nginx-www1.conf: |
        server  {
            server_name  www.bbb.com;
            listen 80;
            location  / {
                root  /usr/share/nginx/html1;
            }
        }
        server  {
            server_name  _;
            listen  80 default_server;
            location / {
            root /usr/share/nginx/html;
                        }
                }

部署

 kubectl apply -f demo3.yaml 

查看
kubernetes ConfigMap和Secret

3 修改

kubectl edit configmap config1

修改的内容如下:
kubernetes ConfigMap和Secret

查看
kubernetes ConfigMap和Secret

4 configmap环境变量传入

1 向POD环境变量中传递键值数据

当以环境变量方式注入的configmap中的键不存在时会被忽略,POD 可以正常启动,但错误引用的信息会以"InvalidVariableNames"事件记录于日志中。

1 创建实例

#[root@master all]# cat nginx.yaml
apiVersion: v1
kind: ConfigMap
metadata:
    name: config1
    namespace: default
data:  #配置环境变量为字符串
    name: web1
    ip: 192.168.100.100
---
apiVersion: v1
kind: Pod
metadata:
    name: nginx-demo
    namespace: default
    labels:
        app: nginx-configm
spec:
    containers:
        - name: nginx-demo
          image: nginx:1.14
          ports:
            - name: http
              containerPort: 80
          env:
            - name: NGINX_NAME  # 设置容器中环境变量名称
              valueFrom:
                configMapKeyRef:
                    name: config1  #配置configmap中对象名称
                    key: name  #配置configmap中对象的key名称
            - name: NGINX_IP
              valueFrom:
                configMapKeyRef:
                    name: config1
                    key: ip

2 部署实例

 kubectl apply -f nginx.yaml

3 查看实例
kubernetes ConfigMap和Secret

4 修改实例并查看

kubectl edit configmap  config1

kubernetes ConfigMap和Secret
查看,其未发生变化,因其是环境变量,需要重新部署后才能生效
kubernetes ConfigMap和Secret

2 多个key-value一同引入

当存在多个环境变量同时需要引入该POD时,其可使用envFrom来通过prefix定义前缀的方式引入服务。

#[root@master all]# cat nginx1.yaml
apiVersion: v1
kind: ConfigMap
metadata:
    name: config1
    namespace: default
data:  #配置环境变量为字符串
    name: web1
    ip: 192.168.100.100
---
apiVersion: v1
kind: Pod
metadata:
    name: nginx-demo
    namespace: default
    labels:
        app: nginx-configm
spec:
    containers:
        - name: nginx-demo
          image: nginx:1.14
          ports:
            - name: http
              containerPort: 80
          envFrom:
                - prefix: NGINX_  #设置环境变量前缀,用于匹配上述配置的环境变量列表
                  configMapRef:
                    name: config1  #设置configmaP中资源名称
                    optional: false 

部署

kubectl apply -f nginx1.yaml 

查看
其前缀为上述定义的NGINX_,其key为NGINX_后缀,值为其值
kubernetes ConfigMap和Secret

5 ConfigMap 存储卷

1 总述

若configmap 对象中的键值来源于较长的文件内容,则使用环境变量将其导入将变得不易处理,此时将其以配置文件的形式挂载是较为理想的方式。

2 相关字段说明

pods.spec.volumes.configMap
pods.spec.volumes.configMap.name : 用于定义configmap中存在的资源卷的名称。
pods.spec.volumes.configMap.optional: 用于定义是否允许未存在的configmap挂载至POD,默认为false,若设置为true,则其可以允许不存在的configmap存在于POD挂载之上。
pods.spec.volumes.configMap.items : 用于定义子configmap中资源情况 。
pods.spec.volumes.configMap.items.key: 用于引用configmap中资源的key值,必选字段。
pods.spec.volumes.configMap.items.path: 定义引用资源在目标宿主机中的相对路径,必选字段。
pods.spec.volumes.configMap.items.mode:定义挂载后其权限,可选范围是0-0777。

3 挂载整个存储卷

1 创建html目录和相关index.html文件

kubernetes ConfigMap和Secret

2 创建实例

#[root@master all]# cat nginx2.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
    name: config1
    namespace: default
data:  #配置环境变量为配置文件集合
    nginx-www1.conf: |
        server  {
            server_name  www.bbb.com;
            listen 80;
            location  / {
                root  /usr/share/nginx/html1;
            }
        }
        server  {
            server_name  _;
            listen  80 default_server;
            location / {
            root /usr/share/nginx/html;
                        }
                }
---
apiVersion: v1
kind: Pod
metadata:
    name: nginx-demo
    namespace: default
    labels:
        app: nginx-configm
spec:
    containers:
        - name: nginx-demo
          image: nginx:1.14
          ports:
            - name: http
              containerPort: 80
          volumeMounts:  #配置挂载
            - name: config
              mountPath: /etc/nginx/conf.d/
              readOnly: true  
            - name: html
              mountPath: /usr/share/nginx/html1
              readOnly: false
    volumes:
        - name: config
          configMap:  #设置配置文件挂载方式
            name: config1  #设置configmap中配置文件名称
        - name: html
          hostPath:
            path: /html
---
apiVersion:  v1  #配置service,使其可以通过外部网络访问
kind: Service
metadata:
    name: nginx-dep
spec:
    selector:
         app: nginx-configm
    type: NodePort
    ports:
        - targetPort: 80
          nodePort: 30888
          protocol: TCP
          port: 80

部署

#删除上面的资源,因为其名称是相同的
kubectl delete -f nginx1.yaml
kubectl apply -f nginx2.yaml

配置主机的域名解析
kubernetes ConfigMap和Secret

kubernetes ConfigMap和Secret
其默认配置为主页
kubernetes ConfigMap和Secret

修改configmap

kubectl edit  configmap  config1

kubernetes ConfigMap和Secret
查看

kubernetes ConfigMap和Secret

重载配置

kubectl exec nginx-demo   -- nginx -s reload

查看
kubernetes ConfigMap和Secret

4 挂载存储卷中的部分键值

只需要挂载存储卷中的部分配置文件用于完成对应的功能

1 创建实例

#[root@master all]# cat nginx3.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
    name: config1
    namespace: default
data:  #配置存储为配置文件
    nginx-www1.conf: |
        server  {
            server_name  www.bbb.com;
            listen 80;
            location  / {
                root  /usr/share/nginx/html1;
            }
        }
        server  {
            server_name  _;
            listen  80 default_server;
            location / {
            root /usr/share/nginx/html;
                        }
                }
    nginx-www2.conf: |
        server  {
            server_name  www.ccc.com;
            listen 80;
            location  / {
                root  /usr/share/nginx/html1;
            }
        }
        server  {
            server_name  _;
            listen  80 default_server;
            location / {
            root /usr/share/nginx/html;
                        }
                }

---
apiVersion: v1
kind: Pod
metadata:
    name: nginx-demo
    namespace: default
    labels:
        app: nginx-configm
spec:
    containers:
        - name: nginx-demo
          image: nginx:1.14
          ports:
            - name: http
              containerPort: 80
          volumeMounts:  #配置挂载
            - name: config
              mountPath: /etc/nginx/conf.d/
              readOnly: true  
            - name: html
              mountPath: /usr/share/nginx/html1
              readOnly: false
    volumes:
        - name: config
          configMap:  #设置配置文件挂载方式
            name: config1  #设置configmap中配置文件名称
            items:  
                - key: nginx-www2.conf  #要引用的键名称,必选字段
                  path: nginx-www2.conf  # 对应的键挂载于挂载点中生成的文件相对路径,可以不同于键名称,必选
                  mode: 0644 #配置文件的权限模型
        - name: html
          hostPath:
            path: /html
---
apiVersion:  v1
kind: Service
metadata:
    name: nginx-dep
spec:
    selector:
         app: nginx-configm
    type: NodePort
    ports:
        - targetPort: 80
          nodePort: 30888
          protocol: TCP
          port: 80

2 部署实例

kubectl delete -f  nginx2.yaml
kubectl apply -f  nginx3.yaml

3 查看
kubernetes ConfigMap和Secret
4 测试
kubernetes ConfigMap和Secret

4 secret 资源

1 总述

1 概述:

secret 资源的功能类似于configmap,但其专用于存放敏感数据,如密码,数字证书,私钥,令牌和SSH key 等。

其是以键值的方式进行数据存储的,在POD资源中通过环境变量或存储卷进行数据访问,不同的是,secret对象仅仅会被分发至调用了此对象的POD资源所在的节点,且只能由节点将其存储于内存中,其数据存储及打印格式都是使用base64编码的字符串,因此用户在创建secret对象时也要使用此种编码格式的数据,不过,在容器中以环境变量或存储卷的方式访问时,其会被自动解码为明文格式。

在master上,secret对象以非加密的格式存储于etcd中,管理员必须确保etcd集群键API server的安全通信,etcd服务的授权访问,还包括用户访问API Server时的授权,因为拥有创建POD资源的用户都可以使用secret资源并能够通过Pod中的容器访问其数据。

2 secret 用途:

1 作为存储卷注入到POD上用于其上的容器
2 用于kubelet 为POD中的容器拉去镜像时向私有仓库提供认证信息。

3 secret 的类型

1 opaque: 自定义数据内容;base64编码,用于存储密码、秘钥、信息、证书等数据,类型标识符为generic

2 kubernetes.io/service-account-token: service account 的认证信息,可在创建serviceaccount时由kubernetes自动创建。

3 kubernetes.io/dockerconfigjson: 用于存储Docker镜像仓库的认证信息,类型标识为docker-registry。

4 kubernetes.io/tls :用于为SSL通信模式存储证书和私钥文件,命令式创建时类型标识为tls。

2 创建secret资源

1 通过命令式创建

1 模式

kubectl create secret 类型 名称 --from-litrteral=key=value

2 实例

1 创建数据库认证

1 创建

kubectl create secret  generic mysql-auth --from-literal=user=root --from-literal=password=passwd

2 查看
kubernetes ConfigMap和Secret
3 解码
kubernetes ConfigMap和Secret

2 创建存储ssh公钥和私钥信息

1 创建ssh公钥和私钥
ssh-keygen -C "18829272841@163.com"
kubernetes ConfigMap和Secret

2 查看其路径和情况
kubernetes ConfigMap和Secret

3 导入
kubectl create secret generic ssh-key --from-file=ssh-privatekey=/root/.ssh/id_rsa --from-file=ssh-publickey=/root/.ssh/id_rsa.pub

4 查看
kubernetes ConfigMap和Secret

3 创建基于SSL/TLS通信的secret对象

1 创建秘钥

(umask 077;openssl genrsa -out nginx.key 2048)

2 创建crt

openssl req -new -x509 -key nginx.key -out nginx.crt -subj /C=CN/ST=shaanxi/L=xi\'an/O=linux/CN=www.zhangbing.com

其CN 中的值必须和需要访问的URL相同,否则将不能被访问

3 创建 secret资源

kubectl create secret tls nginx-ssl --key=./nginx.key --cert=./nginx.crt 

4 查看
kubernetes ConfigMap和Secret

2 配置文件式创建资源

1 核心字段

secret.data: 键值对数据类型,数据格式是base64格式编码的字符串,用户需事先进行编码
secret.stringData:以明文格式定义key和value数据,无需进行编码
secret.type: 为了便于编程方式处理secret数据而提供的类型标识

2 创建资源

#[root@master all]# cat demose.yaml 
apiVersion: v1
kind: Secret
metadata:
    name: mysql-a
data: 
    user: cm9vdAo=
    password: cGFzc3dkCg==
---
apiVersion: v1
kind: Secret
metadata:
    name: mysql-b
stringData: 
    user: root
    password: passwd

部署

kubectl apply -f demose.yaml

查看
kubernetes ConfigMap和Secret

3 secret 存储卷

secret对象可注入为环境变量,也可以以存储卷的方式进行挂载,但其在出现错误时会将环境变量保存在日志中,其不利于信息的保存,再者,其容器若调用第三方程序为子进程时,这些子进程能够继承并使用父进程的所有环境变量,因此,使用secret注入环境变量是不明智的。
pods.spec.volumes.secret 其配置方式与configmap完全相同

4 实例

1 创建资源

#[root@master all]# cat nginx2.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
    name: config1
    namespace: default
data:  #配置环境变量为字符串
    nginx-www1.conf: |
        server  {
            server_name  www.zhangbing.com;
            listen 443;
            ssl on;
            ssl_certificate  /etc/nginx/ssl/tls.crt;
            ssl_certificate_key /etc/nginx/ssl/tls.key;
            location  / {
                root  /usr/share/nginx/html1;
            }
        }
        server  {
            server_name  _;
            listen  80 default_server;
            location / {
            root /usr/share/nginx/html;
                        }
                }
---
apiVersion: v1
kind: Pod
metadata:
    name: nginx-demo
    namespace: default
    labels:
        app: nginx-configm
spec:
    containers:
        - name: nginx-demo
          image: nginx:1.14
          ports:
            - name: http
              containerPort: 80
          volumeMounts:  #配置挂载
            - name: config
              mountPath: /etc/nginx/conf.d/
              readOnly: true  
            - name: html
              mountPath: /usr/share/nginx/html1
              readOnly: false
            - name: ssl
              mountPath: /etc/nginx/ssl
    volumes:
        - name: config
          configMap:  #设置配置文件挂载方式
            name: config1  #设置configmap中配置文件名称
        - name: html
          hostPath:
            path: /html
        - name: ssl
          secret:   #配置挂载secret
            secretName: nginx-ssl  #之前上述使用命令行方式创建的服务
---
apiVersion:  v1
kind: Service
metadata:
    name: nginx-dep
spec:
    selector:
         app: nginx-configm
    type: NodePort
    ports:
        - targetPort: 443
          nodePort: 31443
          protocol: TCP
          port: 443

2 部署

删除之前配置
kubectl delete -f nginx2.yaml
kubectl apply -f nginx2.yaml

3 访问查看

kubernetes ConfigMap和Secret

4 查看其证书信息

kubernetes ConfigMap和Secret

4 imagepullsecret资源对象

1 总述

imageoullsecret 资源可用于辅助kubelet从需要认证的私有镜像仓库获取镜像,其通过secret提供的密码传递给kueblet从而在拉取镜像前完成必要的认证过程。

2 使用imagePullSecret 的方式:

1 创建docker-registry类型的secret对象,并在定义POD资源时明确通过imagePullSecrets字段给出。

2 创建docker-registry 类型的secret对象,将其添加到某特定的ServiceAccount对象中,那些使用该ServiceAccount资源创建的POD对象,以及默认使用该ServiceAccount 的POD对象都将会直接使用imagePullSecrets 中的认证信息。

3 创建实例

kubectl create secret docker-registry local-registry --docker-server=192.168.1.10 --docker-username=admin --docker-password=Admin --docker-email=18829272841@163.com

查看资源
kubernetes ConfigMap和Secret

创建POD并指定资源

# [root@master1 all]# cat sec.yaml 
apiVersion: v1
kind: Pod
metadata:
    name: pod-de
    namespace: default
spec:
    imagePullSecrets:  #指定使用的secret
        - name: local-registry
    containers:
        - image: 192.168.1.10/test/nginx:1.14  #指定要访问的容器镜像
          name: pods
          ports:
            - name: http
              containerPort: 80

此处默认的镜像仓库拉去时https服务,若想http拉取,则需要配置

kubernetes ConfigMap和Secret
并重启docker

部署服务

 kubectl apply  -f /root/all/sec.yaml 

查看服务
kubernetes ConfigMap和Secret