云服务器内容精选

  • 升级示例 Deployment的升级可以是声明式的,也就是说只需要修改Deployment的YAML定义即可,比如使用kubectl edit命令将上面Deployment中的镜像修改为nginx:alpine。修改完成后再查询ReplicaSet和Pod,发现创建了一个新的ReplicaSet,Pod也重新创建了。 $ kubectl edit deploy nginx $ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-6f9f58dffd 2 2 2 1m nginx-7f98958cdf 0 0 0 48m $ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-6f9f58dffd-tdmqk 1/1 Running 0 1m nginx-6f9f58dffd-tesqr 1/1 Running 0 1m Deployment可以通过maxSurge和maxUnavailable两个参数控制升级过程中同时重新创建Pod的比例,这在很多时候是非常有用,配置如下所示。 spec: strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 0 type: RollingUpdate 在前面的例子中,由于spec.replicas是2,如果maxSurge和maxUnavailable都为默认值25%,那实际升级过程中,maxSurge允许最多3个Pod存在(向上取整,2*1.25=2.5,取整为3),而maxUnavailable则不允许有Pod Unavailable(向上取整,2*0.75=1.5,取整为2),也就是说在升级过程中,一直会有2个Pod处于运行状态,每次新建一个Pod,等这个Pod创建成功后再删掉一个旧Pod,直至Pod全部为新Pod。
  • 回滚 回滚也称为回退,即当发现升级出现问题时,让应用回到原版本。Deployment可以非常方便的回滚到原版本。 例如上面升级的新版镜像有问题,可以执行kubectl rollout undo命令进行回滚。 $ kubectl rollout undo deployment nginx deployment.apps/nginx rolled back Deployment之所以能如此容易的做到回滚,是因为Deployment是通过ReplicaSet控制Pod的,升级后之前ReplicaSet都一直存在,Deployment回滚做的就是使用之前的ReplicaSet再次把Pod创建出来。Deployment中保存ReplicaSet的数量可以使用revisionHistoryLimit参数限制,默认值为10。
  • 升级参数说明 最大浪涌(maxSurge) 与spec.replicas相比,可以有多少个Pod存在,默认值是25%,比如spec.replicas为 4,那升级过程中就不能超过5个Pod存在,即按1个的步伐升级,实际升级过程中会换算成数字,且换算会向上取整。这个值也可以直接设置成数字。 仅Deployment在“滚动升级”方式下支持配置。 最大无效实例数(maxUnavailable) 与spec.replicas相比,可以有多少个Pod失效,也就是删除的比例,默认值是25%,比如spec.replicas为4,那升级过程中就至少有3个Pod存在,即删除Pod的步伐是1。同样这个值也可以设置成数字。 仅Deployment、DaemonSet在“滚动升级”方式下支持配置。 实例可用最短时间(minReadySeconds) 指定新创建的 Pod 在没有任意容器崩溃情况下的最小就绪时间, 只有超出这个时间 Pod 才被视为可用。默认值为 0(Pod 在准备就绪后立即将被视为可用)。 仅Deployment、DaemonSet支持配置。 最大保留版本数(revisionHistoryLimit) 用来设定出于回滚目的所要保留的旧 ReplicaSet 数量。 这些旧 ReplicaSet 会消耗 etcd 中的资源,并占用 kubectl get rs 的输出。 每个工作负载修订版本的配置都存储在其 ReplicaSets 中;因此,一旦删除了旧的 ReplicaSet, 将失去回滚到工作负载的对应修订版本的能力。 默认情况下,系统保留 10 个旧 ReplicaSet,但其理想值取决于新工作负载的频率和稳定性。 升级最大时长(progressDeadlineSeconds) 指定系统在报告 Deployment 进展失败 之前等待 Deployment 取得进展的秒数。 这类报告会在资源状态中体现为 Type=Progressing、Status=False、 Reason=ProgressDeadlineExceeded。Deployment 控制器将持续重试 Deployment。 将来,一旦实现了自动回滚,Deployment 控制器将在探测到这样的条件时立即回滚 Deployment。 如果指定,则此字段值需要大于 .spec.minReadySeconds 取值。 仅Deployment支持配置。 缩容时间窗(terminationGracePeriodSeconds): 优雅删除时间,默认为30秒,删除Pod时发送SIGTERM终止信号,然后等待容器中的应用程序终止执行,如果在terminationGracePeriodSeconds时间内未能终止,则发送SIGKILL的系统信号强行终止。
  • 操作符取值说明 您可以使用操作符(operator字段)来设置使用规则的逻辑关系,operator取值如下: In:亲和/反亲和对象的标签在标签值列表(values字段)中。 NotIn:亲和/反亲和对象的标签不在标签值列表(values字段)中。 Exists:亲和/反亲和对象存在指定标签名。 DoesNotExist:亲和/反亲和对象不存在指定标签名。 Gt:仅在节点亲和性中设置,调度节点的标签值大于列表值 (字符串比较)。 Lt:仅在节点亲和性中设置,调度节点的标签值小于列表值 (字符串比较)。
  • 通过控制台配置负载亲和调度策略 在创建工作负载时,在“高级设置”中找到“调度策略”。创建工作负载的步骤详情请参见创建工作负载。 选择负载亲和调度的策略类型。 不配置:不设置负载亲和策略。 优先多可用区部署:该策略通过Pod自身反亲和实现,优先将工作负载的Pod调度到不同可用区的节点上。 强制多可用区部署:该策略通过Pod自身反亲和实现,强制将工作负载的Pod调度到不同可用区,并且强制调度到不同节点上。使用该调度策略时,如果节点数小于实例数或节点资源不足,Pod将无法全部运行。 自定义亲和策略:根据Pod标签实现灵活的调度策略,支持的调度策略类型请参见表1。选择合适的策略类型后,单击添加调度策略,参数详情请参见表2。 表1 负载亲和策略类型 策略 规则类型 说明 工作负载亲和性 必须满足 即硬约束,设置必须满足的条件,对应YAML定义中的requiredDuringSchedulingIgnoredDuringExecution字段。 通过标签筛选需要亲和的Pod,如果满足筛选条件的Pod已经运行在拓扑域中的某个节点上,调度器会将本次创建的Pod强制调度到该拓扑域。 说明: 添加多条亲和性规则时,即设置多个标签筛选需要亲和的Pod,则本次创建的Pod必须要同时亲和所有满足标签筛选的Pod,即所有满足标签筛选的Pod要处于同一拓扑域中才可以调度。 尽量满足 即软约束,设置尽量满足的条件,对应YAML定义中的preferredDuringSchedulingIgnoredDuringExecution字段。 通过标签筛选需要亲和的Pod,如果满足筛选条件的Pod已经运行在拓扑域中的某个节点上,调度器会将本次创建的Pod优先调度到该拓扑域。 说明: 添加多条亲和性规则时,即设置多个标签筛选需要亲和的Pod,则本次创建的Pod会尽量同时亲和多个满足标签筛选的Pod。但即使所有Pod都不满足标签筛选条件,也会选择一个拓扑域进行调度。 工作负载反亲和性 必须满足 即硬约束,设置必须满足的条件,对应YAML定义中的requiredDuringSchedulingIgnoredDuringExecution字段。 通过标签筛选需要反亲和的一个或多个Pod,如果满足筛选条件的Pod已经运行在拓扑域中的某个节点上,调度器不会将本次创建的Pod调度到该拓扑域。 说明: 添加多条反亲和性规则时,即设置多个标签筛选需要反亲和的Pod,则本次创建的Pod必须要同时反亲和所有满足标签筛选的Pod,即所有满足标签筛选的Pod所处的拓扑域都不会被调度。 尽量满足 即软约束,设置尽量满足的条件,对应YAML定义中的preferredDuringSchedulingIgnoredDuringExecution字段。 通过标签筛选需要反亲和的一个或多个Pod,如果满足筛选条件的Pod已经运行在拓扑域中的某个节点上,调度器会将本次创建的Pod优先调度到其他拓扑域。 说明: 添加多条反亲和性规则时,即设置多个标签筛选需要反亲和的Pod,则本次创建的Pod会尽量同时反亲和多个满足标签筛选的Pod。但即使每个拓扑域都存在需要反亲和的Pod,也会选择一个拓扑域进行调度。 表2 负载亲和/反亲和调度策略设置参数说明 参数名 参数描述 权重 仅支持在“尽量满足”策略中添加。权重的取值范围为1-100,调度器在进行调度时会将该权重加到其他优先级函数的评分上,最终将Pod调度到总分最大的节点上。 命名空间 指定调度策略生效的命名空间。 拓扑域 拓扑域(topologyKey)通过节点的标签先圈定调度的节点范围,例如标签指定为kubernetes.io/hostname,则根据标签值不同(标签值为节点名称)区分范围,不同名称的节点为不同的拓扑域,此时一个拓扑域中仅包含一个节点;如果指定标签为kubernetes.io/os,则根据标签值不同(标签值为节点的操作系统类型)来区分,不同操作系统的节点为不同的拓扑域,此时一个拓扑域中可能包含多个节点。 根据拓扑域确定节点范围后,然后再选择策略定义的内容(通过标签名、操作符、标签值确定)进行调度,调度时最小单位为拓扑域。例如,某个拓扑域中的一个节点满足负载亲和性规则,则该拓扑域中的节点均可以被调度。 标签名 设置工作负载亲和/反亲和性时,填写需要匹配的工作负载标签。 该标签可以使用系统默认的标签,也可以使用自定义标签。 操作符 可以设置四种匹配关系(In、NotIn、Exists、DoesNotExist)。 In:亲和/反亲和对象的标签在标签值列表(values字段)中。 NotIn:亲和/反亲和对象的标签不在标签值列表(values字段)中。 Exists:亲和/反亲和对象存在指定标签名。 DoesNotExist:亲和/反亲和对象不存在指定标签名。 标签值 设置工作负载亲和/反亲和性时,填写工作负载标签对应的标签值。 调度策略添加完成后,单击“创建工作负载”。
  • 通过控制台配置节点亲和调度策略 在创建工作负载时,在“高级设置”中找到“调度策略”。创建工作负载的步骤详情请参见创建工作负载。 选择节点亲和调度的策略类型。 不配置:不设置节点亲和策略。 指定节点调度:指定工作负载Pod部署的节点。若不指定,将根据集群默认调度策略随机调度。 指定节点池调度:指定工作负载Pod部署的节点池。若不指定,将根据集群默认调度策略随机调度。 自定义亲和策略:根据节点标签实现灵活的调度策略,支持的调度策略类型请参见表3。选择合适的策略类型后,单击添加调度策略,参数详情请参见表4。您也可以单击“指定节点”或“指定可用区”通过控制台快速选择需要调度的节点或可用区。 “指定节点”和“指定可用区”本质也是通过标签实现,只是通过控制台提供了更为便捷的操作,无需手动填写节点标签和标签值。指定节点使用的是 kubernetes.io/hostname 标签,指定可用区使用的是 failure-domain.beta.kubernetes.io/zone 标签。 表3 节点亲和性设置 参数名 参数描述 必须满足 即硬约束,设置必须要满足的条件,对应requiredDuringSchedulingIgnoredDuringExecution。 添加多条“必须满足”规则时,只需要满足一条规则就会进行调度。 尽量满足 即软约束,设置尽量满足的条件,对应preferredDuringSchedulingIgnoredDuringExecution。 添加多条“尽量满足”规则时,满足其中一条或者都不满足也会进行调度。 表4 节点亲和性调度策略设置参数说明 参数名 参数描述 标签名 设置节点亲和性时,填写需要匹配的节点标签。 该标签可以使用系统默认的标签,也可以使用自定义标签。 操作符 可以设置六种匹配关系(In、NotIn、Exists、DoesNotExist、Gt、Lt)。 In:亲和/反亲和对象的标签在标签值列表(values字段)中。 NotIn:亲和/反亲和对象的标签不在标签值列表(values字段)中。 Exists:亲和/反亲和对象存在指定标签名。 DoesNotExist:亲和/反亲和对象不存在指定标签名。 Gt:仅在节点亲和性中设置,调度节点的标签值大于列表值 (字符串比较)。 Lt:仅在节点亲和性中设置,调度节点的标签值小于列表值 (字符串比较)。 标签值 设置节点亲和性时,填写节点标签对应的标签值。 调度策略添加完成后,单击“创建工作负载”。
  • 环境变量查看 如果configmap-example和secret-example的内容如下。 $ kubectl get configmap configmap-example -oyaml apiVersion: v1 data: configmap_key: configmap_value kind: ConfigMap ... $ kubectl get secret secret-example -oyaml apiVersion: v1 data: secret_key: c2VjcmV0X3ZhbHVl # c2VjcmV0X3ZhbHVl为secret_value的base64编码 kind: Secret ... 则进入Pod中查看的环境变量结果如下。 $ kubectl get pod NAME READY STATUS RESTARTS AGE env-example-695b759569-lx9jp 1/1 Running 0 17m $ kubectl exec env-example-695b759569-lx9jp -- printenv / # env key=value # 自定义环境变量 key1=configmap_value # 配置项键值导入 key2=secret_value # 密钥键值导入 key3=env-example-695b759569-lx9jp # Pod的metadata.name key4=1 # container1这个容器的limits.cpu,单位为Core,向上取整 configmap_key=configmap_value # 配置项导入,原配置项中的键值直接会导入结果 secret_key=secret_value # 密钥导入,原密钥中的键值直接会导入结果
  • 操作场景 环境变量是指容器运行环境中设定的一个变量,环境变量可以在工作负载部署后修改,为工作负载提供极大的灵活性。 CCE中设置的环境变量与Dockerfile中的“ENV”效果相同。 容器启动后,容器中的内容不应修改。如果修改配置项(例如将容器应用的密码、证书、环境变量配置到容器中),当容器重启(例如节点异常重新调度Pod)后,会导致配置丢失,业务异常。 配置信息应通过入参等方式导入容器中,以免重启后配置丢失。 环境变量支持如下几种方式设置。 自定义:手动填写环境变量名称及对应的参数值。 配置项导入:将配置项中所有键值都导入为环境变量。 配置项键值导入:将配置项中某个键的值导入作为某个环境变量的值。例如图1中将configmap-example这个配置项中configmap_key的值configmap_value导入为环境变量key1的值,导入后容器中将会存在一个名为key1的环境变量,其值为configmap_value。 密钥导入:将密钥中所有键值都导入为环境变量。 密钥键值导入:将密钥中某个键的值导入作为某个环境变量的值。例如图1中将secret-example这个配置项中secret_key的值secret_value导入为环境变量key2的值,导入后容器中将会存在一个名为key2的环境变量,其值为secret_value。 变量/变量引用:用Pod定义的字段作为环境变量的值。例如图1中将此Pod的名称导入为环境变量key3的值,导入后容器中将会存在一个名为key3的环境变量,其值为该Pod的名称。 资源引用:用容器定义的资源申请值或限制值作为环境变量的值。例如图1中将容器container-1的CPU限制值导入为环境变量key4的值,导入后容器中将会存在一个名为key4的环境变量,其值为容器container-1的CPU限制值。
  • YAML样例 apiVersion: apps/v1 kind: Deployment metadata: name: env-example namespace: default spec: replicas: 1 selector: matchLabels: app: env-example template: metadata: labels: app: env-example spec: containers: - name: container-1 image: nginx:alpine imagePullPolicy: Always resources: requests: cpu: 250m memory: 512Mi limits: cpu: 250m memory: 512Mi env: - name: key # 自定义 value: value - name: key1 # 配置项键值导入 valueFrom: configMapKeyRef: name: configmap-example key: configmap_key - name: key2 # 密钥键值导入 valueFrom: secretKeyRef: name: secret-example key: secret_key - name: key3 # 变量引用,用Pod定义的字段作为环境变量的值 valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: key4 # 资源引用,用Container定义的字段作为环境变量的值 valueFrom: resourceFieldRef: containerName: container1 resource: limits.cpu divisor: 1 envFrom: - configMapRef: # 配置项导入 name: configmap-example - secretRef: # 密钥导入 name: secret-example imagePullSecrets: - name: default-secret
  • 检查方式 HTTP 请求检查 HTTP 请求方式针对的是提供HTTP/HTTPS服务的容器,集群周期性地对该容器发起HTTP/HTTPS GET请求,如果HTTP/HTTPS response返回码属于200~399范围,则证明探测成功,否则探测失败。使用HTTP请求探测必须指定容器监听的端口和HTTP/HTTPS的请求路径。 例如:提供HTTP服务的容器,HTTP检查路径为:/health-check;端口为:80;主机地址可不填,默认为容器实例IP,此处以172.16.0.186为例。那么集群会周期性地对容器发起如下请求:GET http://172.16.0.186:80/health-check。 图1 HTTP请求检查 TCP 端口检查 对于提供TCP通信服务的容器,集群周期性地对该容器建立TCP连接,如果连接成功,则证明探测成功,否则探测失败。选择TCP端口探测方式,必须指定容器监听的端口。 例如:有一个nginx容器,它的服务端口是80,对该容器配置了TCP端口探测,指定探测端口为80,那么集群会周期性地对该容器的80端口发起TCP连接,如果连接成功则证明检查成功,否则检查失败。 图2 TCP 端口检查 执行命令检查 命令检查是一种强大的检查方式,该方式要求用户指定一个容器内的可执行命令,集群会周期性地在容器内执行该命令,如果命令的返回结果是0则检查成功,否则检查失败。 对于上面提到的TCP端口检查和HTTP请求检查,都可以通过执行命令检查的方式来替代: 对于TCP端口探测,可以使用程序来对容器的端口进行connect,如果connect成功,脚本返回0,否则返回-1。 对于HTTP请求探测,可以使用脚本来对容器进行wget。 wget http://127.0.0.1:80/health-check 并检查response 的返回码,如果返回码在200~399 的范围,脚本返回0,否则返回-1。如下图: 图3 执行命令检查 必须把要执行的程序放在容器的镜像里面,否则会因找不到程序而执行失败。 如果执行的命令是一个shell脚本,由于集群在执行容器里的程序时,不在终端环境下,因此不能直接指定脚本为执行命令,需要加上脚本解析器。比如脚本是/data/scripts/health_check.sh,那么使用执行命令检查时,指定的程序应该是sh /data/scripts/health_check.sh。究其原因是集群在执行容器里的程序时,不在终端环境下。
  • YAML示例 apiVersion: v1 kind: Pod metadata: labels: test: liveness name: liveness-http spec: containers: - name: liveness image: nginx:alpine args: - /server livenessProbe: httpGet: path: /healthz port: 80 httpHeaders: - name: Custom-Header value: Awesome initialDelaySeconds: 3 periodSeconds: 3 readinessProbe: exec: command: - cat - /tmp/healthy initialDelaySeconds: 5 periodSeconds: 5
  • 操作场景 健康检查是指容器运行过程中,根据用户需要,定时检查容器健康状况。若不配置健康检查,如果容器内应用程序异常,Pod将无法感知,也不会自动重启去恢复。最终导致虽然Pod状态显示正常,但Pod中的应用程序异常的情况。 Kubernetes提供了两种健康检查的探针: 存活探针:livenessProbe,用于检测容器是否正常,类似于执行ps命令检查进程是否存在。如果容器的存活检查失败,集群会对该容器执行重启操作;若容器的存活检查成功则不执行任何操作。 就绪探针:readinessProbe,用于检查用户业务是否就绪,如果未就绪,则不转发流量到当前实例。一些程序的启动时间可能很长,比如要加载磁盘数据或者要依赖外部的某个模块启动完成才能提供服务。这时候程序进程在,但是并不能对外提供服务。这种场景下该检查方式就非常有用。如果容器的就绪检查失败,集群会屏蔽请求访问该容器;若检查成功,则会开放对该容器的访问。
  • 公共参数说明 表1 公共参数说明 参数 参数说明 检测周期(periodSeconds) 探针检测周期,单位为秒。 例如,设置为30,表示每30秒检测一次。 延迟时间(initialDelaySeconds) 延迟检查时间,单位为秒,此设置与业务程序正常启动时间相关。 例如,设置为30,表明容器启动后30秒才开始健康检查,该时间是预留给业务程序启动的时间。 超时时间(timeoutSeconds) 超时时间,单位为秒。 例如,设置为10,表明执行健康检查的超时等待时间为10秒,如果超过这个时间,本次健康检查就被视为失败。若设置为0或不设置,默认超时等待时间为1秒。 成功阈值(successThreshold) 探测失败后,被视为成功的最小连续成功数。 默认值是 1,最小值是 1。 存活探测的这个值必须是 1。 最大失败次数(failureThreshold) 当探测失败时重试的次数。 存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃 Pod 会被打上未就绪的标签。 默认值是 3。最小值是 1。
  • 申请与限制 在CPU配额和内存配额设置中,申请与限制的含义如下: 申请(Request):根据申请值调度该实例到满足条件的节点去部署工作负载。 限制(Limit):根据限制值限制工作负载使用的资源。 如果实例运行所在的节点具有足够的可用资源,实例可以使用超出申请的资源量,但不能超过限制的资源量。 例如,如果您将实例的内存申请值为1GiB、限制值为2GiB,而该实例被调度到一个具有8GiB CPU的节点上,且该节点上没有其他实例运行,那么该实例在负载压力较大的情况下可使用超过1GiB的内存,但内存使用量不得超过2GiB。若容器中的进程尝试使用超过2GiB的资源时,系统内核将会尝试将进程终止,出现内存不足(OOM)错误。 创建工作负载时,建议设置CPU和内存的资源上下限。同一个节点上部署的工作负载,对于未设置资源上下限的工作负载,如果其异常资源泄露会导致其它工作负载分配不到资源而异常。未设置资源上下限的工作负载,工作负载监控信息也会不准确。
  • 通过控制台配置容忍策略 登录CCE控制台。 在创建工作负载时,在“高级设置”中找到“容忍策略”。 添加污点容忍策略。 表1 容忍策略设置参数说明 参数名 参数描述 污点键 节点的污点键。 操作符 Equal:设置此操作符表示准确匹配指定污点键(必填)和污点值的节点。如果不填写污点值,则表示可以与所有污点键相同的污点匹配。 Exists:设置此操作符表示匹配存在指定污点键的节点,此时容忍度不能指定污点值。若不填写污点键则可以容忍全部污点。 污点值 操作符为Equal时需要填写污点值。 污点策略 全部:表示匹配所有污点效果。 NoSchedule:表示匹配污点效果为NoSchedule的污点。 PreferNoSchedule:表示匹配污点效果为PreferNoSchedule的污点。 NoExecute:表示匹配污点效果为NoExecute的污点。 容忍时间窗 即tolerationSeconds参数,当污点策略为NoExecute时支持配置。 在容忍时间窗内,Pod还会在拥有污点的节点上运行,超出时间后会被驱逐。