kubernetes云原生纪元:深入pod(下)


续深入pod(上)

ProjectedVolume投射数据卷

它并不是挂在宿主机的目录,也不是容器之间共享存储的,它是轻量级的volume 他是由apiServer投射到pod里面,比如说apiserver知道pod需要什么文件,在你启动的时候把这个文件给扔过来,程序里就会读取到这个文件来使用,一般有三种方式 Secret ConfigMap DownwardAPI,他们实现原理都是使用的ProjectedVolume

Secret

存放密钥加密的东西,存放在etcd里面,唯一一个有存储能力组件。一般用来存储用户名密码之类的。

kubernetes也是使用到secret

[root@master-001 ~]# kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-bljfc   kubernetes.io/service-account-token   3      10d

default-token-bljfc 里面定义了ca.crtnamespacetoken 内容是用base64加密的🔐

[root@master-001 ~]# kubectl get secret default-token-bljfc -o yaml
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRW..........
  namespace: ZGV2
  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNkltMHpNRWh2TlZCNlYxRnJRV05GT0UxNmVYWk1UblpqYkVkdWFGTXdSbUpRWDBSa.........
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: default
    kubernetes.io/service-account.uid: d52a71e8-7695-4b5a-b7fc-2be3125b10b6
  creationTimestamp: "2020-01-16T03:03:35Z"
  name: default-token-bljfc
  namespace: dev
  resourceVersion: "39725"
  selfLink: /api/v1/namespaces/dev/secrets/default-token-bljfc
  uid: 52c3d1f1-da26-403c-8fa8-a0b2af8f1e23
type: kubernetes.io/service-account-token

kubernetes会把service-account-token自动加入到每个pod里面,我们可以简单看下它的用法

查看下随意一个pod 的信息,会发现 volumes下的 secret 指定的名字就是我们上面看到的default-token-bljfc,这个volumes挂载到容器的/var/run/secrets/kubernetes.io/serviceaccount

[root@master-001 ~]# kubectl get pod web-bluegreen-9668758db-vr26g -o yaml
其他省略....
  volumes: # volumes名字是我们刚才看到的secret的名字一样
  - name: default-token-bljfc
    secret:
      defaultMode: 420 #文件权限
      secretName: default-token-bljfc  #定义secret的名字
volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-bljfc
      readOnly: true

可以去运行节点找打这个容器,找到这个目录看大挂载的什么,

挂载的三个文件跟我们刚才看到的default-token-bljfc的配置一样,但是内容是bash64解密之后的东西

[root@node-001 ~]# docker ps|grep demo
efa33c7cc45b        2304e340e238                                        "catalina.sh run"        6 hours ago         Up 6 hours                              k8s_tomcat-demo_tomcat-demo-5f4b587679-7mpz9_default_a69f7d7a-562f-4c1d-9d73-e6468837a0ff_10
161967313cd1        registry.aliyuncs.com/google_containers/pause:3.1   "/pause"                 6 hours ago         Up 6 hours                              k8s_POD_tomcat-demo-5f4b587679-7mpz9_default_a69f7d7a-562f-4c1d-9d73-e6468837a0ff_10
[root@node-001 ~]# docker exec -it efa sh
/usr/local/tomcat # cd /var/run/secrets/kubernetes.io/serviceaccount
/run/secrets/kubernetes.io/serviceaccount # ls
ca.crt     namespace  token
/run/secrets/kubernetes.io/serviceaccount # ls -l
total 0
lrwxrwxrwx    1 root     root            13 Jan 26 03:40 ca.crt -> ..data/ca.crt
lrwxrwxrwx    1 root     root            16 Jan 26 03:40 namespace -> ..data/namespace
lrwxrwxrwx    1 root     root            12 Jan 26 03:40 token -> ..data/token

我们在讲认证授权的时候讲到过secret,他们的本质就是secret,他主要作用:跟APIserver交互,进行认证授权的

如何创建使用secret?

  1. 创建自己的secret

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: dbpass #数据库密码
type: Opaque # 类型是不透明浑浊,
data: #经过bae64加密用户密码
  username: aW1vb2M= 
  passwd:  aW1vb2MxMjM=

base64创建方法

[root@master-001 ~]# echo -n imooc|base64 aW1vb2M=

aW1vb2M=

创建下secret.yaml

[root@master-001 ~]# kubectl create -f secret.yaml
secret/dbpass created
  1. 使用secret

secret创建完就自动 存放到了etcd,并且写入到pod里面了,但是如何使用呢?

需要通过数据卷引用指定secret的名字

pod-secret.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
spec:
  containers:
  - name: springboot-web
    image: hub.zhang.com/kubernetes/demo:2020011512381579063123
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: db-secret
      mountPath: /db-secret #把volumes挂载到/db-secret文件夹下
      readOnly: true
  volumes: #定义一个数据卷名字叫db-secret
  - name: db-secret
    projected:
      sources:
      - secret: #指定secret的名字
          name: dbpass
  1. 查看是否被挂载

创建一下,去运行容器机器查看这个容器发现在数据卷挂载目录 db-secretpasswd username

[root@master-001 ~]# kubectl create -f pod-secret.yaml
pod/pod-secret created
[root@node-001 /]# docker exec -it f6 sh
/usr/local/tomcat # cd /
/ # ls
bin        db-secret  dev        etc        home       lib        media      mnt        proc       root       run        sbin       srv        sys        tmp        usr        var
/ # cd db-secret/
/db-secret # ls
passwd    username
/db-secret # cat -n passwd
    1  imooc123
/db-secret # cat -n username
    1  imooc

有我们定义的secret,我们这个程序就可以根据这个目录的文件去访问数据库,如果用户名错了直接修改secret.yaml 再重新创建下就可以,就同步过去了,这里不演示。

configMap

configMap是存储不需要加密的数据,比如应用的启动参数各种参数的配置

如何使用?

现在有一个game.properties,我想把它放到kubernetes里面最好的方式就是configmap

enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30

创建方式有3种

  1. 命令方式

通过命令方式根据文件创建一个configmap

kubectl create configmap configmap名字 --from-file 指定的文件

[root@master-001 ~]# kubectl create configmap web-game --from-file game.properties
configmap/web-game created

查看创建的configmap,|以下都是文件信息

[root@master-001 ~]# kubectl get cm web-game -o yaml
apiVersion: v1
data:
  game.properties: |+#下面这些都属于文件的内容
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
    #end
kind: ConfigMap
metadata:
  creationTimestamp: "2020-01-26T10:30:27Z"
  name: web-game
  namespace: dev
  resourceVersion: "288497"
  selfLink: /api/v1/namespaces/dev/configmaps/web-game
  uid: a49c456b-fd03-4fb2-a5c5-bdb86d1dd454
  1. yaml方式

把上面的yaml文件复制,然后创建也是可以的

我们也是可以通过yaml文件创建

创建好ConfigMap了,但是如何使用?

可以在deploy模版也可以是pod中配置使用

以pod-game.yaml为例,通过数据卷引入configMap,通过名字指定configmap,然后 挂载到容器的/etc/config/game

pod-game.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-game
spec:
  containers:
  - name: web
    image: hub.zhang.com/kubernetes/demo:2020011512381579063123
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: game # 3.把数据卷挂载到/etc/config/game
      mountPath: /etc/config/game
      readOnly: true
  volumes: #1.通过数据卷加载configmap
  - name: game
    configMap: #2.通过名字指定我们刚才创建的configmap
      name: web-game

创建一下

[root@master-001 ~]# kubectl create -f pod-game.yaml
pod/pod-game created

来到运行节点查看,game.properties配置文件

果然被挂载过来了,我们的java程序就可以访问这个目录下的这个配置文件拿到一些参数

[root@node-001 /]# docker ps|grep game
50a1c8381362        c2c8abe7e363                                        "sh /usr/local/tomca…"   6 seconds ago       Up 6 seconds                            k8s_web_pod-game_dev_9366b665-bbb1-4273-9e1a-8c900692e073_0
cb4016dac256        registry.aliyuncs.com/google_containers/pause:3.1   "/pause"                 7 seconds ago       Up 6 seconds                            k8s_POD_pod-game_dev_9366b665-bbb1-4273-9e1a-8c900692e073_0
[root@node-001 /]# docker exec -it 50 sh
/var # cd /etc/config/game/
/etc/config/game # ls
game.properties

我们是否可以把root目录下一些配置比如log4j也拿到configmap,不行因为game是一个目录,如果映射到现有的一个目录,它也会相当把那个目录直接覆盖掉了。并不会单独替换某一个文件,而是把目录直接覆盖掉。因为我们诠释mount进去的。

修改configmap,瞬间同步

我们修改下configmap里面的参数 enemies.cheat=fasle 然后在容器查看被挂载过来的文件,延迟在2s左右

[root@master-001 ~]# kubectl edit cm web-game
修改成false
enemies.cheat=fasle
......

#查看下容器被挂载的
/etc/config/game #  cat game.properties
enemies=aliens
lives=3
enemies.cheat=false
.....
环境变量的方式使用configMap

configMap另一种配置使用通过env 环境变量去加载configmap对应的值configMapKeyRef指定key

用yaml定义configmap

configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: configs
data:
  JAVA_OPTS: -Xms1024m
  LOG_LEVEL: DEBUG

pod-env.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-env
spec:
  containers:
  - name: web
    image: hub.zhang.com/kubernetes/demo:2020011512381579063123
    ports:
    - containerPort: 8080
    env: # 环境变量
      - name: LOG_LEVEL_CONFIG #环境变量name
        valueFrom: #值的获取
          configMapKeyRef: # 通过configmap 获取key=LOG_LEVEL的value 
            name: configs
            key: LOG_LEVEL

我们把configmap 和pod都创建下

[root@master-001 ~]# kubectl create -f configmap.yaml
configmap/configs created
[root@master-001 ~]# kubectl create -f pod-env.yaml
pod/pod-env created

然后来到运行机器进入创建的容器查看下环境变量,我们程序可以通过环境变量获取到这个值了。

[root@node-001 /]# docker exec -it 5c sh
/usr/local/tomcat # env |grep LOG
LOG_LEVEL_CONFIG=DEBUG  #被挂载到环境变量 
Env挂载configmap使用场景

设置程序的启动内存

先通过环境变量挂载configmap值,然后 在command启动命令中获取被挂载的值 -DJAVA_OPTS=$(JAVA_OPTS)

Pod-cmd.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-cmd
spec:
  containers:
  - name: web
    image: hub.mooc.com/kubernetes/springboot-web:v1               
    command: ["/bin/sh", "-c", "java -jar /springboot-web.jar -DJAVA_OPTS=$(JAVA_OPTS)"]
    ports:
    - containerPort: 8080
    env:
      - name: JAVA_OPTS
        valueFrom:
          configMapKeyRef:
            name: configs
            key: JAVA_OPTS

创建一下

[root@master-001 ~]# kubectl create -f pod-cmd.yaml
pod/pod-cmd created

来到容器运行节点查看,已经被获取

image-20200127163347521

DownwardAPI

跟上面两个不太一样,作用是让我们程序取得到pod对象本身的一些相关信息,说白了就是可以取得自己当前的配置然后传给容器

基本使用

通过 volumes 指定downwardAPI为数据来源,然后通过 items:声明文件比如labels ,fieldRef:``fieldPath: 指定值路径

pod-downwardapi.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-downwardapi
  labels:
    app: downwardapi
    type: webapp
spec:
  containers:
  - name: web
    image: hub.zhang.com/kubernetes/demo:2020011512381579063123
    ports:
    - containerPort: 8080
    volumeMounts:
      - name: podinfo
        mountPath: /etc/podinfo
  volumes:
    - name: podinfo
      projected:
        sources: # 来源
        - downwardAPI: #使用数据卷加载downwardAPI
            items:
              - path: "labels" 
                fieldRef: #获取当前配置信息的label
                  fieldPath: metadata.labels 
              - path: "name"
                fieldRef: #获取当前配置信息的名字
                  fieldPath: metadata.name
              - path: "namespace"
                fieldRef: #获取当前pod 的命名空间
                  fieldPath: metadata.namespace 
              - path: "mem-request"
                resourceFieldRef: #获取当前配置的内存
                  containerName: web # 配置具体容器的名字
                  resource: limits.memory # 获取容器内存

创建一下

[root@master-001 ~]# kubectl create -f pod-downwardapi.yaml
pod/pod-downwardapi created

来到运行容器节点,我们获取的labels 就是我创建pod的label

[root@node-001 /]# docker exec -it 7b4 sh
/usr/local/tomcat # cd /etc/podinfo
/etc/podinfo # ls -l
total 0
lrwxrwxrwx    1 root     root            13 Jan 26 11:26 labels -> ..data/labels
lrwxrwxrwx    1 root     root            18 Jan 26 11:26 mem-request -> ..data/mem-request
lrwxrwxrwx    1 root     root            11 Jan 26 11:26 name -> ..data/name
lrwxrwxrwx    1 root     root            16 Jan 26 11:26 namespace -> ..data/namespace
/etc/podinfo # cat labels
app="downwardapi"
/etc/podinfo # cat -n labels
    1  app="downwardapi"
    2  type="webapp"

downwardAPI 还有很多用法,可以查看kubernetes API

这节我们主要讲了pod概念、设计思想共享和隔离到生命周期、常见的配置,后期我们可以多多使用加深对呀pod的理解。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐