在Kubernetes中,Pod携带的信息即为丰富,比如调度,镜像相关的字段,但是除了这些,还有些特殊的小点需要我们了解,从而加深对Pod的理解

比如,我们要讲的特殊的Volume,叫做Projected Volume,投射数据卷

在Kubernetes中,有几种特殊的Volume,其意义,就是为了存放容器内的数据,也不是为了进行容器和宿主机之间的数据交换,这些Volume,就是为容器提供预先定义好的数据,就好比是从Kubernetes投射进入容器中的,这就是Projected Volume的含义

到现在为止,常见的Projected Volume一共有四种

Secret

ConfigMap

Download API

ServiceAccountToken

首先是Secret,其作用是将Pod中想要访问的加密数据,放在Etcd中,这样,就可以在Pod中以挂载Volume的方式,访问到Secret里的信息了

Serect的典型使用场景,就是在存放数据库的登录信息

apiVersion: v1

kind: Pod

metadata:

  name: test-projected-volume 

spec:

  containers:

  – name: test-secret-volume

    image: busybox

    args:

    – sleep

    – “86400”

    volumeMounts:

    – name: mysql-cred

      mountPath: “/projected-volume”

      readOnly: true

  volumes:

  – name: mysql-cred

    projected:

      sources:

      – secret:

          name: user

      – secret:

          name: pass

定义了一个容器,挂载的Volume,不是常见的emptyDir或者hostPath类型,而是projected类型,这个volume的数据来源,是user和pass的Secret对象,对应的分别是数据库的用户名和密码

而这两个projected volume的来源,正是以Secret对象的方式交给Kubernetes保存的,完成这个操作的指令

$ cat ./username.txt

admin

$ cat ./password.txt

c1oudc0w!

$ kubectl create secret generic user –from-file=./username.txt

$ kubectl create secret generic pass –from-file=./password.txt

这样,就创建了两个secret对象,我们可以直接查看一下

kubectl get secrets

图片

当然,还可以使用YAML的方式来创建Secret对象

apiVersion: v1

kind: Secret

metadata:

  name: mysecret

type: Opaque

data:

  user: YWRtaW4=

  pass: MWYyZDFlMmU2N2Rm

通过其编写YAML文件创建出的Secret对象只有一个,但是data字段,却利用key-value保存了两份Secret数据,其中user是第一份数据的key pass是第二份数据的key

这两个数据,是我们经过Base64转码得到的,这也是K8s要求的

当然,简单的转码并不能满足我们的加密需求,一般还需要开启专门的加密插件,先不说这个

然后我们创建最开始的挂载了Volume的这个Pod

kubectl create -f test-projected-volume.yaml

然后我们尝试获取到这个文本对象

当Pod变成Running状态之后了,我们验证一下Secret对象是不是已经在容器了

kubectl exec -it test-projected-volume — /bin/sh

/ # ls /projected-volume/

password.txt  username.txt

/ # cd /projected-volume/

/projected-volume # ls

password.txt  username.txt

/projected-volume # cat password.txt 

wow

/projected-volume # cat username.txt 

admin

/projected-volume # 

这样,就是我们以文件的形式,展示了对应的用户名和密码

这些实际文件中的数据,就是保存在Etcd对应的用户和密码,以文件的形式保存在了这里,这个文件的名字,就是

kubectl create secret 指令的key或者secret对象的data字段的key

而且,一旦是以挂载的方式进入容器的secret,如果Etcd的数据被更新,那么Volume内的文件也会被更新,这是kubelet组件在定期的维护这些volume

这个更新可能会有一定延时,在编写应用程序时候,发起数据库连接的代码处理好

然后其次是ConfigMap,和Secret的区别在于,ConfigMap是提供不需要进行加密,应用所需要的配置信息,ConfigMap的用法和Secret完全相同,可以使用kubectl create configmap 从文件或者目录创建ConfigMap,可以直接编写对应的YAML文件

假设我们有一个properties类型的对象

cat ./hbase-1.3.5/conf/log4j.properties 

# Licensed to the Apache Software Foundation (ASF) under one

# or more contributor license agreements.  See the NOTICE file

# distributed with this work for additional information

# regarding copyright ownership.  The ASF licenses this file

# to you under the Apache License, Version 2.0 (the

# “License”); you may not use this file except in compliance

# with the License.  You may obtain a copy of the License at

#

#     http://www.apache.org/licenses/LICENSE-2.0

#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an “AS IS” BASIS,

# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

# See the License for the specific language governing permissions and

# limitations under the License.

# Define some default values that can be overridden by system properties

hbase.root.logger=INFO,console

hbase.security.logger=INFO,console

hbase.log.dir=.

hbase.log.file=hbase.log

# Define the root logger to the system property “hbase.root.logger”.

log4j.rootLogger=${hbase.root.logger}

# Logging Threshold

log4j.threshold=ALL

#

# Daily Rolling File Appender

#

log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender

log4j.appender.DRFA.File=${hbase.log.dir}/${hbase.log.file}

# Rollver at midnight

log4j.appender.DRFA.DatePattern=.yyyy-MM-dd

# 30-day backup

#log4j.appender.DRFA.MaxBackupIndex=30

log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout

# Pattern format: Date LogLevel LoggerName LogMessage

log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n

# Rolling File Appender properties

hbase.log.maxfilesize=256MB

hbase.log.maxbackupindex=20

# Rolling File Appender

log4j.appender.RFA=org.apache.log4j.RollingFileAppender

log4j.appender.RFA.File=${hbase.log.dir}/${hbase.log.file}

log4j.appender.RFA.MaxFileSize=${hbase.log.maxfilesize}

log4j.appender.RFA.MaxBackupIndex=${hbase.log.maxbackupindex}

log4j.appender.RFA.layout=org.apache.log4j.PatternLayout

log4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n

#

# Security audit appender

#

hbase.security.log.file=SecurityAuth.audit

hbase.security.log.maxfilesize=256MB

hbase.security.log.maxbackupindex=20

log4j.appender.RFAS=org.apache.log4j.RollingFileAppender

log4j.appender.RFAS.File=${hbase.log.dir}/${hbase.security.log.file}

log4j.appender.RFAS.MaxFileSize=${hbase.security.log.maxfilesize}

log4j.appender.RFAS.MaxBackupIndex=${hbase.security.log.maxbackupindex}

log4j.appender.RFAS.layout=org.apache.log4j.PatternLayout

log4j.appender.RFAS.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n

log4j.category.SecurityLogger=${hbase.security.logger}

log4j.additivity.SecurityLogger=false

#log4j.logger.SecurityLogger.org.apache.hadoop.hbase.security.access.AccessController=TRACE

#log4j.logger.SecurityLogger.org.apache.hadoop.hbase.security.visibility.VisibilityController=TRACE

#

# Null Appender

#

log4j.appender.NullAppender=org.apache.log4j.varia.NullAppender

#

# console

# Add “console” to rootlogger above if you want to use this

#

log4j.appender.console=org.apache.log4j.ConsoleAppender

log4j.appender.console.target=System.err

log4j.appender.console.layout=org.apache.log4j.PatternLayout

log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n

log4j.appender.asyncconsole=org.apache.hadoop.hbase.AsyncConsoleAppender

log4j.appender.asyncconsole.target=System.err

# Custom Logging levels

log4j.logger.org.apache.zookeeper=INFO

#log4j.logger.org.apache.hadoop.fs.FSNamesystem=DEBUG

log4j.logger.org.apache.hadoop.hbase=INFO

# Make these two classes INFO-level. Make them DEBUG to see more zk debug.

log4j.logger.org.apache.hadoop.hbase.zookeeper.ZKUtil=INFO

log4j.logger.org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher=INFO

#log4j.logger.org.apache.hadoop.dfs=DEBUG

# Set this class to log INFO only otherwise its OTT

# Enable this to get detailed connection error/retry logging.

# log4j.logger.org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation=TRACE

# Uncomment this line to enable tracing on _every_ RPC call (this can be a lot of output)

#log4j.logger.org.apache.hadoop.ipc.HBaseServer.trace=DEBUG

# Uncomment the below if you want to remove logging of client region caching’

# and scan of hbase:meta messages

# log4j.logger.org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation=INFO

# log4j.logger.org.apache.hadoop.hbase.client.MetaScanner=INFO

# Prevent metrics subsystem start/stop messages (HBASE-17722)

log4j.logger.org.apache.hadoop.metrics2.impl.MetricsConfig=WARN

log4j.logger.org.apache.hadoop.metrics2.impl.MetricsSinkAdapter=WARN

log4j.logger.org.apache.hadoop.metrics2.impl.MetricsSystemImpl=WARN

然后进行创建

kubectl create configmap hbasemap –from-file=./hbase-1.3.5/conf/log4j.properties 

最后我们尝试获取到这个ConfigMap中保存的数据

kubectl get configmap -o yaml

apiVersion: v1

items:

– apiVersion: v1

  data:

    log4j.properties: |

      # Licensed to the Apache Software Foundation (ASF) under one

      # or more contributor license agreements.  See the NOTICE file

      # distributed with this work for additional information

      # regarding copyright ownership.  The ASF licenses this file

      # to you under the Apache License, Version 2.0 (the

      # “License”); you may not use this file except in compliance

      # with the License.  You may obtain a copy of the License at

      #

      #     http://www.apache.org/licenses/LICENSE-2.0

      #

      # Unless required by applicable law or agreed to in writing, software

      # distributed under the License is distributed on an “AS IS” BASIS,

      # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

      # See the License for the specific language governing permissions and

      # limitations under the License.

      # Define some default values that can be overridden by system properties

      hbase.root.logger=INFO,console

      hbase.security.logger=INFO,console

      hbase.log.dir=.

      hbase.log.file=hbase.log

      # Define the root logger to the system property “hbase.root.logger”.

      log4j.rootLogger=${hbase.root.logger}

      # Logging Threshold

      log4j.threshold=ALL

      #

      # Daily Rolling File Appender

      #

      log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender

      log4j.appender.DRFA.File=${hbase.log.dir}/${hbase.log.file}

      # Rollver at midnight

      log4j.appender.DRFA.DatePattern=.yyyy-MM-dd

      # 30-day backup

      #log4j.appender.DRFA.MaxBackupIndex=30

      log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout

      # Pattern format: Date LogLevel LoggerName LogMessage

      log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n

      # Rolling File Appender properties

      hbase.log.maxfilesize=256MB

      hbase.log.maxbackupindex=20

      # Rolling File Appender

      log4j.appender.RFA=org.apache.log4j.RollingFileAppender

      log4j.appender.RFA.File=${hbase.log.dir}/${hbase.log.file}

      log4j.appender.RFA.MaxFileSize=${hbase.log.maxfilesize}

      log4j.appender.RFA.MaxBackupIndex=${hbase.log.maxbackupindex}

      log4j.appender.RFA.layout=org.apache.log4j.PatternLayout

      log4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n

      #

      # Security audit appender

      #

      hbase.security.log.file=SecurityAuth.audit

      hbase.security.log.maxfilesize=256MB

      hbase.security.log.maxbackupindex=20

      log4j.appender.RFAS=org.apache.log4j.RollingFileAppender

      log4j.appender.RFAS.File=${hbase.log.dir}/${hbase.security.log.file}

      log4j.appender.RFAS.MaxFileSize=${hbase.security.log.maxfilesize}

      log4j.appender.RFAS.MaxBackupIndex=${hbase.security.log.maxbackupindex}

      log4j.appender.RFAS.layout=org.apache.log4j.PatternLayout

      log4j.appender.RFAS.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n

      log4j.category.SecurityLogger=${hbase.security.logger}

      log4j.additivity.SecurityLogger=false

      #log4j.logger.SecurityLogger.org.apache.hadoop.hbase.security.access.AccessController=TRACE

      #log4j.logger.SecurityLogger.org.apache.hadoop.hbase.security.visibility.VisibilityController=TRACE

      #

      # Null Appender

      #

      log4j.appender.NullAppender=org.apache.log4j.varia.NullAppender

      #

      # console

      # Add “console” to rootlogger above if you want to use this

      #

      log4j.appender.console=org.apache.log4j.ConsoleAppender

      log4j.appender.console.target=System.err

      log4j.appender.console.layout=org.apache.log4j.PatternLayout

      log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n

      log4j.appender.asyncconsole=org.apache.hadoop.hbase.AsyncConsoleAppender

      log4j.appender.asyncconsole.target=System.err

      # Custom Logging levels

      log4j.logger.org.apache.zookeeper=INFO

      #log4j.logger.org.apache.hadoop.fs.FSNamesystem=DEBUG

      log4j.logger.org.apache.hadoop.hbase=INFO

      # Make these two classes INFO-level. Make them DEBUG to see more zk debug.

      log4j.logger.org.apache.hadoop.hbase.zookeeper.ZKUtil=INFO

      log4j.logger.org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher=INFO

      #log4j.logger.org.apache.hadoop.dfs=DEBUG

      # Set this class to log INFO only otherwise its OTT

      # Enable this to get detailed connection error/retry logging.

      # log4j.logger.org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation=TRACE

      # Uncomment this line to enable tracing on _every_ RPC call (this can be a lot of output)

      #log4j.logger.org.apache.hadoop.ipc.HBaseServer.trace=DEBUG

      # Uncomment the below if you want to remove logging of client region caching’

      # and scan of hbase:meta messages

      # log4j.logger.org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation=INFO

      # log4j.logger.org.apache.hadoop.hbase.client.MetaScanner=INFO

      # Prevent metrics subsystem start/stop messages (HBASE-17722)

      log4j.logger.org.apache.hadoop.metrics2.impl.MetricsConfig=WARN

      log4j.logger.org.apache.hadoop.metrics2.impl.MetricsSinkAdapter=WARN

      log4j.logger.org.apache.hadoop.metrics2.impl.MetricsSystemImpl=WARN

  kind: ConfigMap

  metadata:

    creationTimestamp: 2020-09-07T06:57:16Z

    name: hbasemap

    namespace: default

    resourceVersion: “911931”

    selfLink: /api/v1/namespaces/default/configmaps/hbasemap

    uid: 5da36979-f0d7-11ea-9934-000c29945dd1

kind: List

metadata:

  resourceVersion: “”

  selfLink: “”

最后是Downward API ,让Pod容器能直接获取到Pod Api对象本身的信息

我们尝试定义一个Pod

apiVersion: v1

kind: Pod

metadata:

  name: test-downwardapi-volume

  labels:

    zone: us-est-coast

    cluster: test-cluster1

    rack: rack-22

spec:

  containers:

    – name: client-container

      image: k8s.gcr.io/busybox

      command: [“sh”, “-c”]

      args:

      – while true; do

          if [[ -e /etc/podinfo/labels ]]; then

            echo -en ‘\n\n’; cat /etc/podinfo/labels; fi;

          sleep 5;

        done;

      volumeMounts:

        – name: podinfo

          mountPath: /etc/podinfo

          readOnly: false

  volumes:

    – name: podinfo

      projected:

        sources:

        – downwardAPI:

            items:

              – path: “labels”

                fieldRef:

                  fieldPath: metadata.labels

在这个Pod的Yaml文件中,定义了一个简单的容器,声明了一个projected类型的volume,不过这个volume的数据源,变成了Downward API,这个Downward API Volume,声明了要暴露的Pod的metedata.labels信息给容器

通过这样的声明让是,我们就能获取到Labels中的字段

这个容器,会不断的打印这个labels中的指令,所以,创建了Pod之后,就可以通过kubectl logs,查看这些Labels字段被打印出来

kubectl logs test-peojected-volume

1. 使用fieldRef可以声明使用:

spec.nodeName – 宿主机名字

status.hostIP – 宿主机IP

metadata.name – Pod的名字

metadata.namespace – Pod的Namespace

status.podIP – Pod的IP

spec.serviceAccountName – Pod的Service Account的名字

metadata.uid – Pod的UID

metadata.labels[‘<KEY>’] – 指定<KEY>的Label值

metadata.annotations[‘<KEY>’] – 指定<KEY>的Annotation值

metadata.labels – Pod的所有Label

metadata.annotations – Pod的所有Annotation

2. 使用resourceFieldRef可以声明使用:

容器的CPU limit

容器的CPU request

容器的memory limit

容器的memory request

这个列表还在不断的增长中

通过这三个Volume定义的信息,其实大多还可以通过环境变量的方式来出现在容器中,但是一般通过环境变量的设置的,是不具有自动更新功能的,所以,还是建议通过Volume文件方式来获取信息

其次是Pod中一个密切相关的概念,Service Account

这个是用于一个概念,就是在Pod中提供Kubernetes的Api

Service Account的作用,就是Kubernetes内置的一种服务账户,是Kubernetes进行权限分配的对象,比如Service Account A,只被允许对Kubernetes Api进行 GET操作, Service Account B,可以进行所有操作

这个Service Account,其实本质上,是一个特殊的Secret对象,这个特殊的Secret对象,叫做ServiceAccountToken,

所以说,Kubernetes中的Projected Volume只有三种,第四种ServiceAccountToken,只是一种特殊的Secret而已

当然,为了方便使用,Kubernetes提供了一个默认的服务账户,在任何的Pod中,都可以默认的使用这个Service Account

这是如何做到的呢?

靠的还是Projected Volume机制

如果查看任何一个运行在K8S集群中的Pod,都会已经挂载了一个Volume

图片

这个默认的Secret类型的Volume,正是默认Service Account对应的ServiceAccountToken,所以说,Kubernetes在每个Pod都创建的时候,再其spec.volumes部分添加上了默认ServiceAccountToken的定义,整个过程对用户来说是完全透明的

一旦Pod创建完成,容器内就会直接从这个默认的ServiceAccountToken中获取到授权信息

这个授权信息的路径在K8S中是固定的,即为/var/run/secrets/kubernetes/serviceaccount

其中的内容如下

图片

这样,只要加载这些授权文件,就可以访问操作K8s的API了,如果是官方的client包,可以自动加载这个目录下的文件,不需要做任何的配置或者编码操作

这种将Kubernetes客户端以容器的方式运行在集群,然后进行管理的方式,叫做InClusterConfig,也是极好的处理方式

当然,可以选择设置默认不为Pod挂载这个Volume

在Kubernetes中,可以为Pod中的容器定义一个健康检查的探针,这个机制叫做Probe,这样,kubelet会根据Probe的返回值来确定这个容器的状态,而不是根据Docker状态来确定

这种机制,非常适合生产环境去保证健康存活

apiVersion: v1

kind: Pod

metadata:

  labels:

    test: liveness

  name: test-liveness-exec

spec:

  containers:

  – name: liveness

    image: busybox

    args:

    – /bin/sh

    – -c

    – touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600

    livenessProbe:

      exec:

        command:

        – cat

        – /tmp/healthy

      initialDelaySeconds: 5

      periodSeconds: 5

我们尝试定义一个容器,在启动之后做的第一件事,就是在/tmp目录下创建了一个healthy的文件,作为自己正常运行的标志,30s后,进行删除

然后,在下面,我们定义了一个livenessProbe健康检查,类型是exec,在启动之后,容器内执行一条执行的命令,比如 cat上面的healthy文件,查看返回值是否为0来判断是否是健康的,这个健康检查,在容器启动5s后执行,每5秒执行一次

接下来我们试验下这个pod

kubectl create -f test-liveness-exec.yaml

然后查看这个Pod状态

$ kubectl get pod

NAME                READY     STATUS    RESTARTS   AGE

test-liveness-exec   1/1       Running   0          10s

然后过了30秒,查看这个Pod的Events

$ kubectl describe pod test-liveness-exec

会发现在Eevets中报告了一个异常

FirstSeen LastSeen    Count   From            SubobjectPath           Type        Reason      Message

——— ——–    —–   —-            ————-           ——–    ——      ——-

2s        2s      1   {kubelet worker0}   spec.containers{liveness}   Warning     Unhealthy   Liveness probe failed: cat: can’t open ‘/tmp/healthy’: No such file or directory

但是,这个Pod状态仍然是Running

这是因为这个异常的容器已经被Kubernetes重启了,这个过程中,Pod保持Running不变

而这个重启,实际上是重新创建了容器

这就是Kubernetes中的Pods恢复机制,默认的值是Always,一旦发生了异常,就一定会被重新创建

Pod的恢复过程,永远都在当前节点上,而不会跑到别的节点上,所以当节点宕机了,也不会主动的迁移到别的节点

如果是希望,可以出现在别的节点上,就需要使用一个Deployment这样的控制器

而且恢复机制restartPolicy,除了Always,还有OnFailure和Never两种情况

Always,在任何的情况下,只要容器不再运行,就自动重启

OnFailure,在容器异常时候才会自动重启容器

Never,从来不重启容器

总结下来,

对于Pod的restartPolicy指定的策略允许重启异常的容器,那么这个Pod就会一直保持Running状态,进行容器重启,不然,Pod就会进入Failed状态

对于多个容器的Pod,只有所有的容器都进入了异常状态后,Pod才会进入Failed状态,不然就是Running状态,Pod的Ready会显示正常容器的个数

$ kubectl get pod test-liveness-exec

NAME           READY     STATUS    RESTARTS   AGE

liveness-exec   0/1       Running   1          1m

而且,除了在容器内执行命令外,livenessProbe定义发起HTTP或者TCP请求,例如

livenessProbe:

     httpGet:

       path: /healthz

       port: 8080

       httpHeaders:

       – name: X-Custom-Header

         value: Awesome

       initialDelaySeconds: 3

       periodSeconds: 3

或者

    livenessProbe:

      tcpSocket:

        port: 8080

      initialDelaySeconds: 15

      periodSeconds: 20

Pod可以暴露一个健康检查的URL,来检查对应的服务状态

最后,说一下Kubernetes的默认模板

对于Kuberenetes中,我们提交了一个基本的简单的Pod,由K8s来对Pod加上对应的必要信息,比如labels,annotations,volumes

这样,就降低了Pod Yaml的编写门槛,这个机制叫做PodPreset

我们,直接看一下PodPreset对象的定义,就是在开发人员编写的Pod里追加的字段,都可以提前定义好

apiVersion: settings.k8s.io/v1alpha1

kind: PodPreset

metadata:

  name: allow-database

spec:

  selector:

    matchLabels:

      role: frontend

  env:

    – name: DB_PORT

      value: “6379”

  volumeMounts:

    – mountPath: /cache

      name: cache-volume

  volumes:

    – name: cache-volume

      emptyDir: {}

在这个PodPreset中,首先是一个selector,意味着这个后面追加的请求,只会作用于selector定义的,带有role:frontend标签Pod对象,防止误伤

然后我们定义了一组Pod中的字段,来进行挂载

env定义了环境变量

volumeMounts定义了容器volume的挂载目录

volumes定义了一个emptyDir的Volume

这样我们创建这个PodPreset对象

kubectl create -f preset.yaml

这样,后面带有selector中匹配的上的 role: frontend的Pod就会被修改上

要说明的是,Pod API对象被创建之前追加到这个对象本身上,而不会影响到任何Pod的控制器的定义

比如提交的是一个deployment,那么这个Deployement本身不会被PodPresent改变,被修改的是Deployment创建出来的所有Pod

而且,如果定义了多个同时作用于同一个Pod对象的多个podPresent,会发生什么?

会进行合并多个PodPresent做的修改,但是修改有冲突的话,冲突字段不会被修改

本章总结一下

我们说了Pod对象中的特殊对象,和一些关于默认Pod的设置

在此过程中

我们学习了Secret对象保存应用的密码,保存配置信息的是ConfigMap对象

最后是自动填充的PodPreset对Pod进行批量化,自动化修改的工具对象

思考题:

在没有Kubernetes的时候,是通过什么方式进行的健康检查的,Kubernetes的livenessProbe是否足够了

之前利用shell脚本来进行过探测,也是利用的健康监测接口,一旦返回值不是200,直接杀死进程,然后java -jar命令尝试重启

probe原理是sidecar容器来实现的

不是的,是使用的exec

而且Deployment中,其重启策略一直是always的

发表评论

邮箱地址不会被公开。 必填项已用*标注