本章主要讲如何向容器传递环境变量或配置信息等

一、docker如何写启动命令

1、ENTRYPOINT和CMD

Dockerfile中的ENTRYPOINT一定会执行,所以一般把命令放在ENTRYPOINT,把参数放在CMD,这样运行docker run 时,加的命令行参数只会覆盖CMD,而ENTRYPOINT依然会执行

2、两种写法

(1)shell形式-----如 ENTRYPOINT  node  app.js

(2)exec形式----如  ENTRYPOINT  ["node", "app.js"]

区别在于第一个的主进程是shell,然后在shell里运行了node  app.js这个命令,第二个主进程直接是node进程

假设原来的Dockerfile长这样:

直接运行docker run,容器就会执行脚本,参数为10

而运行docker run 镜像名  15,那么容器就会执行脚本,但参数是15

3、使用k8s覆盖容器的启动命令

用command参数直接连ENTRYPOINT都可以覆盖,不想覆盖ENTRYPOINT可以只写args:

kind: Pod
spec:
  containers:
  - image: some/image
    command: ["/bin/command"]
    args: ["arg1", "arg2", "arg3"]

二、为容器设置环境变量

复用其他环境变量:

env:
- name: FIRST_VAR
  value: "foo"
- name: SECOND_VAR
  value: "$(FIRST_VAR)bar"     // SECOND_VAR=foobar

三、利用ConfigMap解耦配置

试想,如果开发环境、测试环境、生产环境对某个环境变量的配置都不一样,那是不是这些变化都要侵入代码呢?因为pod的定义yaml肯定是放到代码仓库里的,所以找一种方法不改yaml还能让环境变量在不同环境上不一样,就需要ConfigMap

ConfigMap是一些键值对,每个环境上不一样,当同一份pod的yaml部署在不同环境上时,需要的环境变量会去ConfigMap中查找,这样就只需要针对不同环境,制作不同ConfigMap即可

1、创建ConfigMap

ConfigMap是k8s的一种资源,但与之前的资源不同,它不需要通过yaml创建(kubectl  create  -f),而是直接用命令创建

kubectl  create  configmap  config名称   --选项

选项有两种:

(1)from-literal   字面量

kubectl  create  configmap  fortune-config  --from-literal=sleep-interval=25

会创建一个名为fortune-config的ConfigMap,其中只包含一个键值对,key是sleep-interval,value是25

(2)from-file  文件

kubectl  create  configmap  my-config  --from-file=config-file.conf

会创建一个名为my-config的ConfigMap,其中只包含一个键值对,key是config-file.conf(字符串),value是config-file.conf的文件内容

kubectl  create  configmap  my-config  --from-file=customkey=config-file.conf

key是customkey(字符串),value是config-file.conf的文件内容

kubectl  create  configmap  my-config  --from-file=/path/dir

key是路径下所有的文件名,value是文件名对应的文件内容

上面几种方式可以混合使用

kubectl create configmap my-config \
    --from-file=foo.json
    --from-file=bar=foobar.conf
    --from-file=config-opts/
    --from-literal=some=thing

2、给容器传递ConfigMap条目作为环境变量

如果pod引用了不存在的ConfigMap,则容器启动失败,之后创建了这个缺失的ConfigMap后,失败的容器会自动重启,无需自己重建pod

可以设置configMapKeyRef . option:  true,这样即便引用的ConfigMap不存在,容器也能正常启动

3、一次性传递ConfigMap的所有条目作为环境变量

假设一个ConfigMap又三个键:FOO, BAR, FOO-BAR

现在这个容器有两个环境变量:CONFIG_FOO和CONFIG_BAR

为什么是两个?因为FOO-BAR的破折号不符合环境变量的命名规范

4、传递ConfigMap条目作为命令行参数

将容器启动时的命令行参数做成可配置,通过ConfigMap来配置参数

5、使用ConfigMap挂载配置文件(configmap卷类型)

(1)创建一个ConfigMap:

kubectl create configmap fortune-config --from-file=configmap-files

configmap-files文件夹下有两个文件:一个nginx的配置文件my-nginx-config.conf,一个变量型的文件sleep-interval

查看一下configmap:

(2)使用:

这样容器内/etc/nginx/conf.d文件夹下就有两个文件,跟configmap里一样

如果只想挂载configmap里的一个文件my-nginx-config.conf,那就在卷声明时加上一个参数items:

(3)注意:挂载卷到一个文件夹,会隐藏该文件夹下原有的文件

上述的例子中,如果容器里/etc/nginx/conf.d文件下之前有文件,那么现在会被隐藏

解决方法:指定subpath

(4)修改卷中文件权限

卷中文件的权限默认都是644

改:

5、不重启pod修改配置

修改configmap,pod不用重启也会自动更新、重载

原理:

可以查看之前容器/etc/nginx/conf.d下的内容,发现它们其实是个软链接,每当配置更新后,k8s会在容器某个位置新创建一个文件夹,然后将这些文件链接到新文件夹下。

但如果使用items只挂载部分条目,那修改configmap,这些文件不会更新。解决:挂载完整卷到另一目录,在/etc/nginx/conf.d下手动设置软链接到挂载的目录

四、Secret卷类型

Secret和ConfigMap基本一致,只是查看卷中的变量时,是base64编码过的,所以起到加密敏感数据的作用,一般用于存放证书、私钥等。

kubectl get secret fortune-https -o yaml
apiVersion: v1
data:
  foo: YmFyCg==
  https.cert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tL...
  https.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVk...
kind: Secret

创建一个fortune-secret卷并挂载到pod

secret挂载文件的使用的是tmpfs,存储在secret中的数据不会写入磁盘,这样也就无法被盗取

通过环境变量暴露secret里的内容是不明智的,因为都是敏感数据,非敏感数据应该用configmap存储

镜像拉取Secret:

一种特殊的Secret,假设dockhub上有私仓,需要配置证书私钥,那么可以这样做:

首先创建一个docker-registry Secret

kubectl create secret docker-registry mydockerhubsecret \
  --docker-username=myusername --docker-password=mypassword \
  --docker-email=my.email@provider.com

pod定义中使用:

 

Logo

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

更多推荐