华为云用户手册

  • 通过工作负载YAML进行DNS配置 您也可以通过YAML的方式创建工作负载,以nginx应用为例,其YAML文件中的DNS配置示例如下: apiVersion: apps/v1kind: Deploymentmetadata: name: nginx namespace: defaultspec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: container-1 image: nginx:latest imagePullPolicy: IfNotPresent imagePullSecrets: - name: default-secret dnsPolicy: None dnsConfig: options: - name: ndots value: '5' - name: timeout value: '3' nameservers: - 10.2.3.4 searches: - my.dns.search.suffix dnsPolicy字段说明: dnsPolicy字段是应用设置的DNS策略,默认值为“ClusterFirst”。基于dnsPolicy策略生成的域名解析文件会与dnsConfig设置的DNS参数进行合并,合并规则将在表2中说明,dnsPolicy当前支持四种参数值: 表1 dnsPolicy字段说明 参数 说明 ClusterFirst(默认值) 应用对接CoreDNS(CCE集群的CoreDNS默认级联云上DNS)。这种场景下,容器既能够解析service注册的集群内部域名,也能够解析发布到互联网上的外部域名。由于该配置下,域名解析文件设置了search搜索域列表和ndots: 5,因此当访问外部域名和集群内部长域名(如kubernetes.default.svc.cluster.local)时,大部分域名都会优先遍历search搜索域列表,导致至少有6次无效的DNS查询,只有访问集群内部短域名(如kubernetes)时,才不存在无效的DNS查询。 ClusterFirstWithHostNet 对于配置主机网络的应用,即设置hostNetwork字段为true时,默认对接kubelet的“--resolv-conf”参数指向的域名解析文件(CCE集群在该配置下对接云上DNS)。如需对接集群的Kube-DNS/CoreDNS,dnsPolicy字段需设置为ClusterFirstWithHostNet,此时容器的域名解析文件配置与“ClusterFirst”一致,也存在无效的DNS查询。 ...spec: containers: - image: nginx:latest imagePullPolicy: IfNotPresent name: container-1 restartPolicy: Always hostNetwork: true dnsPolicy: ClusterFirstWithHostNet Default 容器的域名解析文件使用kubelet的“--resolv-conf”参数指向的域名解析文件(CCE集群在该配置下对接云上DNS),没有配置search搜索域列表和options。该配置只能解析注册到互联网上的外部域名,无法解析集群内部域名,且不存在无效的DNS查询。 None 设置为None之后,必须设置dnsConfig字段,此时容器的域名解析文件将完全通过dnsConfig的配置来生成。 此处如果dnsPolicy字段未被指定,其默认值为ClusterFirst,而不是Default。 dnsConfig字段说明: dnsConfig为应用设置DNS参数,设置的参数将合并到基于dnsPolicy策略生成的域名解析文件中。当dnsPolicy为“None”,应用的域名解析文件完全由dnsConfig指定;当dnsPolicy不为“None”时,会在基于dnsPolicy生成的域名解析文件的基础上,追加dnsConfig中配置的dns参数。 表2 dnsConfig字段说明 参数 说明 options DNS的配置选项,其中每个对象可以具有name属性(必需)和value属性(可选)。该字段中的内容将合并到基于dnsPolicy生成的域名解析文件的options字段中,dnsConfig的options的某些选项如果与基于dnsPolicy生成的域名解析文件的选项冲突,则会被dnsConfig所覆盖。 nameservers DNS的IP地址列表。当应用的dnsPolicy设置为“None”时,列表必须至少包含一个IP地址,否则此属性是可选的。列出的DNS的IP列表将合并到基于dnsPolicy生成的域名解析文件的nameserver字段中,并删除重复的地址。 searches 域名查询时的DNS搜索域列表,此属性是可选的。指定后,提供的搜索域列表将合并到基于dnsPolicy生成的域名解析文件的search字段中,并删除重复的域名。Kubernetes最多允许6个搜索域。
  • 工作负载的DNS配置实践 前面介绍了Linux系统域名解析文件以及Kubernetes为应用提供的DNS相关配置项,下面将举例介绍应用如何进行DNS配置。 场景1 对接kubernetes内置的Kube-DNS/CoreDNS 场景说明: 这种方式适用于应用中的域名解析只涉及集群内部域名,或者集群内部域名+外部域名两种方式,应用默认采用这种配置。 示例: apiVersion: v1kind: Podmetadata: namespace: default name: dns-examplespec: containers: - name: test image: nginx:alpine dnsPolicy: ClusterFirst 该配置下容器的域名解析文件将如下所示: nameserver 10.247.3.10search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:5 场景2 直接对接云DNS 场景说明: 这种方式适用于应用只访问注册到互联网的外部域名,该场景不能解析集群内部域名。 示例: apiVersion: v1kind: Podmetadata: namespace: default name: dns-examplespec: containers: - name: test image: nginx:alpine dnsPolicy: Default //使用kubelet的“--resolv-conf”参数指向的域名解析文件(CCE集群在该配置下对接云DNS) 该配置下容器的域名解析文件将如下所示: nameserver 100.125.x.x 场景3 主机网络模式的应用对接Kube-DNS/CoreDNS 场景说明: 对于配置主机网络模式的应用,默认对接云DNS,如果应用需要对接Kube-DNS/CoreDNS,需将dnsPolicy设置为“ClusterFirstWithHostNet”。 示例: apiVersion: v1kind: Podmetadata: name: nginxspec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet containers: - name: nginx image: nginx:alpine ports: - containerPort: 80 该配置下容器的域名解析文件将如下所示: nameserver 10.247.3.10search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:5 场景4 自定义应用的域名配置 场景说明: 用户可以完全自定义配置应用的域名解析文件,这种方式非常灵活,dnsPolicy和dnsConfig配合使用,几乎能够满足所有使用场景,如对接用户自建DNS的场景、串联多个DNS的场景以及优化DNS配置选项的场景等等。 示例1:对接用户自建DNS 该配置下,dnsPolicy为“None”,应用的域名解析文件完全根据dnsConfig配置生成。 apiVersion: v1kind: Podmetadata: namespace: default name: dns-examplespec: containers: - name: test image: nginx:alpine dnsPolicy: "None" dnsConfig: nameservers: - 10.2.3.4 //用户自建DNS的IP地址 searches: - ns1.svc.cluster.local - my.dns.search.suffix options: - name: ndots value: "2" - name: timeout value: "3" 该配置下容器的域名解析文件将如下所示: nameserver 10.2.3.4search ns1.svc.cluster.local my.dns.search.suffixoptions timeout:3 ndots:2 示例2:修改域名解析文件的ndots选项,减少无效的DNS查询 该配置下,dnsPolicy不为“None”,会在基于dnsPolicy生成的域名解析文件的基础上,追加dnsConfig中配置的dns参数。 apiVersion: v1kind: Podmetadata: namespace: default name: dns-examplespec: containers: - name: test image: nginx:alpine dnsPolicy: "ClusterFirst" dnsConfig: options: - name: ndots value: "2" //该配置会将基于ClusterFirst策略生成的域名解析文件的ndots:5参数改写为ndots:2 该配置下容器的域名解析文件将如下所示: nameserver 10.247.3.10search default.svc.cluster.local svc.cluster.local cluster.localoptions ndots:2
  • 使用CoreDNS级联自建DNS 使用kubectl连接集群。 修改CoreDNS配置文件,将forward后面的/etc/resolv.conf,改成外部DNS的地址,如下所示。 $ kubectl edit configmap coredns -n kube-systemapiVersion: v1data: Corefile: |- .:5353 { bind {$POD_IP} cache 30 errors health {$POD_IP}:8080 kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } loadbalance round_robin prometheus {$POD_IP}:9153 forward . 192.168.1.1 reload }kind: ConfigMapmetadata: creationTimestamp: "2021-08-23T13:27:28Z" labels: app: coredns k8s-app: coredns kubernetes.io/cluster-service: "true" kubernetes.io/name: CoreDNS release: cceaddon-coredns name: coredns namespace: kube-system resourceVersion: "460" selfLink: /api/v1/namespaces/kube-system/configmaps/coredns uid: be64aaad-1629-441f-8a40-a3efc0db9fa9
  • 为CoreDNS配置存根域 集群管理员可以修改CoreDNS Corefile的ConfigMap以更改服务发现的工作方式。使用插件proxy可对CoreDNS的存根域进行配置。 若集群管理员有一个位于10.150.0.1的Consul域名解析服务器,并且所有Consul的域名都带有.consul.local的后缀。 登录CCE控制台。 在左侧导航栏中选择“插件管理”,在“插件实例”页签下,单击CoreDNS插件,进入插件详情页。 单击参数列表下的“编辑”按钮,在弹出窗口中添加存根域。 图1 配置存根域 单击“确定”。
  • 添加CoreDNS Rewrite配置指向域名到集群内服务 使用 CoreDNS 的 Rewrite 插件,将指定域名解析到某个 Service 的域名,相当于给Service取了个别名。 使用kubectl连接集群。 修改CoreDNS配置文件,将example.com指向default命名空间下的example服务。 $ kubectl edit configmap coredns -n kube-systemapiVersion: v1data: Corefile: |- .:5353 { bind {$POD_IP} cache 30 errors health {$POD_IP}:8080 kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } rewrite name example.com example.default.svc.cluster.local loadbalance round_robin prometheus {$POD_IP}:9153 forward . /etc/resolv.conf reload }kind: ConfigMapmetadata: creationTimestamp: "2021-08-23T13:27:28Z" labels: app: coredns k8s-app: coredns kubernetes.io/cluster-service: "true" kubernetes.io/name: CoreDNS release: cceaddon-coredns name: coredns namespace: kube-system resourceVersion: "460" selfLink: /api/v1/namespaces/kube-system/configmaps/coredns uid: be64aaad-1629-441f-8a40-a3efc0db9fa9
  • 解决方案 使用CoreDNS有以下几种自定义域名解析的方案。 为CoreDNS配置存根域:可以直接在控制台添加,简单易操作。 使用 CoreDNS Hosts 插件配置任意域名解析:简单直观,可以添加任意解析记录,类似在本地/etc/hosts中添加解析记录。 使用 CoreDNS Rewrite 插件指向域名到集群内服务:相当于给Kubernetes中的Service名称取了个别名,无需提前知道解析记录的IP地址。 使用 CoreDNS Forward 插件将自建 DNS 设为上游 DNS:自建DNS中,可以管理大量的解析记录,解析记录专门管理,增删记录无需修改CoreDNS配置。
  • 修改CoreDNS Hosts配置 使用kubectl连接集群。 修改CoreDNS配置文件,将自定义域名添加到hosts中。 将www.example.com指向192.168.1.1,通过CoreDNS解析www.example.com时,会返回192.168.1.1。 此处配置不能遗漏fallthrough字段,fallthrough表示当在hosts找不到要解析的域名时,会将解析任务传递给CoreDNS的下一个插件。如果不写fallthrough的话,任务就此结束,不会继续解析,会导致集群内部域名解析失败的情况。 hosts的详细配置请参见https://coredns.io/plugins/hosts/。 $ kubectl edit configmap coredns -n kube-systemapiVersion: v1data: Corefile: |- .:5353 { bind {$POD_IP} cache 30 errors health {$POD_IP}:8080 kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa } hosts { 192.168.1.1 www.example.com fallthrough } loadbalance round_robin prometheus {$POD_IP}:9153 forward . /etc/resolv.conf reload }kind: ConfigMapmetadata: creationTimestamp: "2021-08-23T13:27:28Z" labels: app: coredns k8s-app: coredns kubernetes.io/cluster-service: "true" kubernetes.io/name: CoreDNS release: cceaddon-coredns name: coredns namespace: kube-system resourceVersion: "460" selfLink: /api/v1/namespaces/kube-system/configmaps/coredns uid: be64aaad-1629-441f-8a40-a3efc0db9fa9 在CoreDNS中修改hosts后,就不用单独在每个Pod中配置hosts了,带来了一定的方便性。
  • 使用NodeLocal DNSCache 有两种方式可以使用NodeLocal DNSCache: 自动注入:创建Pod时自动配置Pod的dnsConfig字段。(kube-system命名空间下的Pod不支持自动注入) 手动配置:手动配置Pod的dnsConfig字段,从而使用NodeLocal DNSCache。 自动注入 自动注入需要满足如下条件: 插件需要将enable_dnsconfig_admission参数配置为true 命名空间添加node-local-dns-injection=enabled标签 kubectl label namespace default node-local-dns-injection=enabled 新建Pod不位于kube-system和kube-public命名空间 新建Pod没有被打上禁用DNS注入node-local-dns-injection=disabled标签 新建Pod的网络为hostNetwork且DNSPolicy为ClusterFirstWithHostNet,或Pod为非hostNetwork且DNSPolicy为ClusterFirst 开启自动注入后,创建的Pod会自动添加如下dnsConfig字段,nameservers中除了NodeLocal DNSCache的地址169.254.20.10外,还添加了CoreDNS的地址10.247.3.10,保障了业务DNS请求高可用。 dnsConfig: nameservers: - 169.254.20.10 - 10.247.3.10 searches: - default.svc.cluster.local - svc.cluster.local - cluster.local options: - name: timeout value: '' - name: ndots value: '5' - name: single-request-reopen 手动配置 手动配置即自行给Pod加上dnsConfig配置。 创建一个Pod,将dnsconfig配置为169.254.20.10。 apiVersion: v1kind: Podmetadata: name: nginxspec: containers: - image: nginx:alpine name: container-0 dnsConfig: nameservers: - 169.254.20.10 searches: - default.svc.cluster.local - svc.cluster.local - cluster.local options: - name: ndots value: '2' imagePullSecrets: - name: default-secret
  • 优先缩容老实例生效说明 优先缩容老实例不生效: 按照上述优先级,如果节点数为2(同规格),Deployment实例数为5时(可以是任意奇数个),此时A节点分布3个Pod,B节点分布2个Pod;如果此时将实例数缩容至3个,上述步骤中会先执行5,此时根据Pod判断,会确定缩容的节点为A;再执行6,缩容一个老实例后发现目前已无老实例,且限定了缩容节点为A,此时会缩容一个新实例。 优先缩容老实例生效:如果节点数为2(同规格),Deployment实例数为6时(可以是任意偶数个),此时A、B节点均分布3个Pod;如果此时将实例数缩容至4个,此时代码会判定不符合5的条件,此时根据Pod判断,会确定缩容的节点为A、B;再执行6,回去将两个节点上的实例排序,成功缩容两个老的实例。
  • 插件安装 CCE提供了node-local-dns插件,可以方便的安装NodeLocal DNSCache。 node-local-dns插件仅支持1.19及以上版本集群。 NodeLocal DNSCache不提供Hosts、Rewrite等插件能力,仅作为CoreDNS的透明缓存代理。如有需要,可在CoreDNS配置中修改。 kube-system命名空间下的Pod不支持自动注入。 CCI上不支持NodeLocal DNSCache。当负载动态弹性伸缩到CCI时,CCI上Pod会因为无法联通NodeLocal DNSCache导致域名解析超时,此时可进行注入豁免。 (可选)修改CoreDNS配置,让CoreDNS优先采用UDP协议与上游DNS服务器通信。 NodeLocal DNSCache采用TCP协议与CoreDNS进行通信,CoreDNS会根据请求来源使用的协议与上游DNS服务器进行通信。当使用了NodeLocal DNSCache时,访问上游DNS服务器时会使用TCP协议,而云上DNS服务器对TCP协议支持有限,如果您使用了NodeLocal DNSCache,您需要修改CoreDNS配置,让其总是优先采用UDP协议与上游DNS服务器进行通信,避免解析异常。 执行如下命令修改。 kubectl edit configmap coredns -nkube-system 在forward插件中指定请求上游的协议为perfer_udp,修改之后CoreDNS会优先使用UDP协议与上游通信。 forward . /etc/resolv.conf { prefer_udp } 登录CCE控制台,进入集群,在左侧导航栏中选择“插件管理”,在右侧找到node-local-dns,单击“安装”。 在安装插件页面,选择插件规格,并配置相关参数。 enable_dnsconfig_admission:是否自动注入DNSConfig至新建的Pod中。默认为false,设置为true表示支持自动注入,避免您手工配置Pod YAML进行注入。 完成以上配置后,单击“安装”。
  • IPVS IPVS(IP Virtual Server)是在Netfilter上层构建的,并作为Linux内核的一部分,实现传输层负载均衡。IPVS可以将基于TCP和UDP服务的请求定向到真实服务器,并使真实服务器的服务在单个IP地址上显示为虚拟服务。 IPVS 模式下,kube-proxy 使用 IPVS 负载均衡代替了 iptable。这种模式同样有效,IPVS 的设计就是用来为大量服务进行负载均衡的,它有一套优化过的 API,使用优化的查找算法,而不是简单的从列表中查找规则。
  • 应用现状 Kubernetes集群可以将运行在一组Pod上的应用程序发布为服务,提供统一的四层访问入口。对于Loadbalancer类型的service,kube-proxy默认会将Service的status中LoadbalanceIP地址配置到节点本地的转发规则中,集群内部访问ELB的地址,流量就会在集群内部转发,而不会经过ELB转发。 集群内部转发功能是kube-proxy组件负责,kube-proxy有iptables和IPVS两种转发模式,iptables是一种简单的轮询转发,IPVS虽有多种转发模式,但也需要修改kube-proxy的启动参数,不能像ELB那样灵活配置转发策略,且无法利用ELB的健康检查能力。
  • 操作步骤 下文以nginx镜像创建无状态工作负载,并创建一个具有pass-through的Service。 使用nginx镜像创建无状态负载。 apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx:latest name: container-0 resources: limits: cpu: 100m memory: 200Mi requests: cpu: 100m memory: 200Mi imagePullSecrets: - name: default-secret Loadbalance类型的Service,并设置kubernetes.io/elb.pass-through为true。 Loadbalance类型的Service具体创建方法请参见自动创建负载均衡类型Service。 apiVersion: v1 kind: Service metadata: annotations: kubernetes.io/elb.pass-through: "true" kubernetes.io/elb.class: union kubernetes.io/elb.autocreate: '{"type":"public","bandwidth_name":"cce-bandwidth","bandwidth_chargemode":"bandwidth","bandwidth_size":5,"bandwidth_sharetype":"PER","eip_type":"5_bgp","name":"james"}' labels: app: nginx name: nginx spec: externalTrafficPolicy: Local ports: - name: service0 port: 80 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer 此处是自动创建一个名为james的共享型ELB实例,需要通过kubernetes.io/elb.subnet-id指定ELB所在VPC子网,必须和集群在同一个VPC。
  • 容忍度(Toleration) 容忍度应用于Pod上,允许(但并不要求)Pod 调度到带有与之匹配的污点的节点上。 污点和容忍度相互配合,可以用来避免 Pod 被分配到不合适的节点上。 每个节点上都可以应用一个或多个污点,这表示对于那些不能容忍这些污点的 Pod,是不会被该节点接受的。 可以在 Pod 中容忍度。 apiVersion: v1kind: Podmetadata: name: nginx labels: env: testspec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" 上面示例表示这个Pod容忍标签为key1=value1,效果为NoSchedule的污点,所以这个Pod能够调度到对应的节点上。 同样还可以按如下方式写,表示当节点有key1这个污点时,可以调度到节点。 tolerations:- key: "key1" operator: "Exists" effect: "NoSchedule"
  • iptables iptables 是一个 Linux 内核功能,提供了大量的数据包处理和过滤方面的能力。它可以在核心数据包处理管线上用 Hook 挂接一系列的规则。iptables 模式中 kube-proxy 在 NAT pre-routing Hook 中实现它的 NAT 和负载均衡功能。 kube-proxy 的用法是一种 O(n) 算法,其中的 n 随集群规模同步增长,这里的集群规模,更明确的说就是服务和后端 Pod 的数量。
  • 解决方案 CCE服务支持pass-through能力,通过Loadbalance类型Service配置kubernetes.io/elb.pass-through的annotation实现集群内部访问Service的ELB地址时绕出集群,并通过ELB的转发最终转发到后端的Pod。 图1 pass-through访问示例 对于CCE集群: 集群内部客户端访问LB类型Service时,访问请求默认是通过集群服务转发规则(iptables或IPVS)转发到后端的容器实例。 当LB类型Service配置elb.pass-through后,集群内部客户端访问Service地址时会先访问到ELB,再通过ELB的负载均衡能力先访问到节点,然后通过集群服务转发规则(iptables或IPVS)转发到后端的容器实例。 对于 CCE Turbo 集群: 集群内部客户端访问LB类型Service时,访问请求默认也是通过集群服务转发规则(iptables或IPVS)转发到后端的容器实例。 当LB类型Service配置elb.pass-through后,集群内部客户端访问Service地址时会先访问到ELB,然后通过ELB直通容器的能力直接访问容器实例。
  • 配置镜像拉取策略 创建工作负载会从镜像仓库拉取容器镜像到节点上,当前Pod重启、升级时也会拉取镜像。 默认情况下容器镜像拉取策略imagePullPolicy是IfNotPresent,表示如果节点上有这个镜像就直接使用节点已有镜像,如果没有这个镜像就会从镜像仓库拉取。 容器镜像拉取策略还可以设置为Always,表示无论节点上是否有这个镜像,都会从镜像仓库拉取,并覆盖节点上的镜像。 apiVersion: v1kind: Pod metadata: name: nginx spec: containers: - image: nginx:alpine name: container-0 resources: limits: cpu: 100m memory: 200Mi requests: cpu: 100m memory: 200Mi imagePullPolicy: Always imagePullSecrets: - name: default-secret 在CCE控制台也可以设置镜像拉取策略,在创建工作负载时设置。如下所示,勾选表示总是拉取镜像(Always),不勾选就是IfNotPresent。 建议您在制作镜像时,每次制作一个新的镜像都使用一个新的Tag,如果不更新Tag只更新镜像,当拉取策略选择为IfNotPresent时,CCE会认为当前节点已经存在这个Tag的镜像,不会重新拉取。 父主题: 容器设置
  • 使用NPU 创建工作负载申请NPU资源,可按如下方法配置,指定显卡的数量。 kind: DeploymentapiVersion: apps/v1metadata: name: npu-test namespace: defaultspec: replicas: 1 selector: matchLabels: app: npu-test template: metadata: labels: app: npu-test spec: containers: - name: container-0 image: nginx:perl resources: limits: cpu: 250m huawei.com/ascend-310: '1' memory: 512Mi requests: cpu: 250m huawei.com/ascend-310: '1' memory: 512Mi imagePullSecrets: - name: default-secret 通过 huawei.com/ascend-310 指定申请NPU的数量。 指定 huawei.com/ascend-310 后,在调度时不会将负载调度到没有NPU的节点。如果缺乏NPU资源,会报类似“0/2 nodes are available: 2 Insufficient huawei.com/ascend-310.”的Kubernetes事件。 在CCE控制台使用NPU资源,只需在创建负载时,勾选昇腾310配额,并指定使用310芯片的数量,如下图所示。 图1 使用NPU
  • NPU节点标签 购买NPU节点后,CCE会给节点打上对应标签,如下所示。 图2 NPU标签 在使用NPU时,可以根据标签让Pod与节点亲和,从而让Pod选择正确的节点,如下所示。 kind: DeploymentapiVersion: apps/v1metadata: name: npu-test namespace: defaultspec: replicas: 1 selector: matchLabels: app: npu-test template: metadata: labels: app: npu-test spec: nodeSelector: accelerator/huawei-npu: ascend-310 containers: - name: container-0 image: nginx:perl resources: limits: cpu: 250m huawei.com/ascend-310: '1' memory: 512Mi requests: cpu: 250m huawei.com/ascend-310: '1' memory: 512Mi imagePullSecrets: - name: default-secret
  • 时区同步 创建工作负载时,支持设置容器使用节点相同的时区。您可以在创建工作负载时打开时区同步配置,如下所示。 时区同步功能依赖容器中挂载的本地磁盘(HostPath),如下所示,开启时区同步后,Pod中会通过HostPath方式,将节点的“/etc/localtime”挂载到容器的“/etc/localtime”,从而使得节点和容器使用相同的时区配置文件。 kind: DeploymentapiVersion: apps/v1metadata: name: test namespace: defaultspec: replicas: 2 selector: matchLabels: app: test template: metadata: labels: app: test spec: volumes: - name: vol-162979628557461404 hostPath: path: /etc/localtime type: '' containers: - name: container-0 image: 'nginx:alpine' volumeMounts: - name: vol-162979628557461404 readOnly: true mountPath: /etc/localtime imagePullPolicy: IfNotPresent imagePullSecrets: - name: default-secret 父主题: 容器设置
  • 动态创建对象存储卷时指定挂载密钥 动态创建对象存储卷时,可通过如下方法指定挂载密钥。 新建一个pvc的yaml文件,如pvc-example.yaml。 apiVersion: v1kind: PersistentVolumeClaimmetadata: annotations: csi.storage.k8s.io/node-publish-secret-name: test-user csi.storage.k8s.io/node-publish-secret-namespace: default everest.io/obs-volume-type: STANDARD csi.storage.k8s.io/fstype: obsfs name: obs-secret namespace: defaultspec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi storageClassName: csi-obs 参数 描述 csi.storage.k8s.io/node-publish-secret-name 指定secret的名字 csi.storage.k8s.io/node-publish-secret-namespace 指定secret的命令空间 创建PVC。 kubectl create -f pvc-example.yaml PVC创建后,就可以创建工作负载挂载PVC使用存储。
  • 配置验证 根据上述步骤,使用 IAM 用户的密钥挂载对象存储卷。假设工作负载名称为obs-secret,容器内挂载目录是/temp,IAM用户权限为CCE ReadOnlyAccess和Tenant Guest。 查询工作负载实例名称。 kubectl get po | grep obs-secret 期望输出: obs-secret-5cd558f76f-vxslv 1/1 Running 0 3m22s 查询挂载目录下对象,查询正常。 kubectl exec obs-secret-5cd558f76f-vxslv -- ls -l /temp/ 尝试在挂在目录内写入数据,写入失败。 kubectl exec obs-secret-5cd558f76f-vxslv -- touch /temp/test 期望输出: touch: setting times of '/temp/test': No such file or directorycommand terminated with exit code 1 参考桶策略配置,给挂载桶的子用户设置读写权限。 再次尝试在挂在目录内写入数据,写入成功。 kubectl exec obs-secret-5cd558f76f-vxslv -- touch /temp/test 查看容器内挂载目录,验证数据写入成功。 kubectl exec obs-secret-5cd558f76f-vxslv -- ls -l /temp/ 期望输出: -rwxrwxrwx 1 root root 0 Jun 7 01:52 test
  • 关闭自动挂载访问密钥 老版本控制台会要求您上传AK/SK,对象存储卷挂载时默认使用您上传的访问密钥,相当于所有IAM用户(即子用户)都使用的是同一个访问密钥挂载的对象捅,对桶的权限都是一样的,导致无法对IAM用户使用对象存储桶进行权限控制。 如果您之前上传过AK/SK,为防止IAM用户越权,建议关闭自动挂载访问密钥,即需要在Everest插件中将disable_auto_mount_secret参数打开,这样使用对象存储时就不会自动使用在控制台上传的访问密钥。 设置disable-auto-mount-secret时要求当前集群中无对象存储卷,否则挂载了该对象卷的工作负载扩容或重启的时候会由于必须指定访问密钥而导致挂卷失败。 disable-auto-mount-secret设置为true后,则创建PV和PVC时必须指定挂载访问密钥,否则会导致对象卷挂载失败。 kubectl edit ds everest-csi-driver -nkube-system 搜索disable-auto-mount-secret,并将值设置为true。 执行 :wq 保存退出,等待实例重启完毕即可。
  • 静态创建对象存储卷时指定挂载Secret 使用访问密钥创建Secret后,在创建PV时只需要关联上Secret,就可以使用Secret中的访问密钥(AK/SK)挂载对象存储卷。 登录OBS控制台,创建对象存储桶,记录桶名称和存储类型,以并行文件系统为例。 新建一个pv的yaml文件,如pv-example.yaml。 apiVersion: v1kind: PersistentVolumemetadata: name: pv-obs-example annotations: pv.kubernetes.io/provisioned-by: everest-csi-provisionerspec: accessModes: - ReadWriteMany capacity: storage: 1Gi csi: nodePublishSecretRef: name: test-user namespace: default driver: obs.csi.everest.io fsType: obsfs volumeAttributes: everest.io/obs-volume-type: STANDARD everest.io/region: cn-north-4 storage.kubernetes.io/csiProvisionerIdentity: everest-csi-provisioner volumeHandle: obs-normal-static-pv persistentVolumeReclaimPolicy: Delete storageClassName: csi-obs 参数 描述 nodePublishSecretRef 挂载时指定的密钥,其中 name:指定secret的名字 namespace:指定secret的命令空间 fsType 文件类型,支持“obsfs”与“s3fs”,取值为s3fs时创建是obs对象桶,配套使用s3fs挂载;取值为obsfs时创建的是obs并行文件系统,配套使用obsfs挂载,推荐使用。 volumeHandle 对象存储的桶名称。 创建PV。 kubectl create -f pv-example.yaml PV创建完成后,就可以创建PVC关联PV。 新建一个PVC的yaml文件,如pvc-example.yaml。 PVC yaml文件配置示例: apiVersion: v1kind: PersistentVolumeClaimmetadata: annotations: csi.storage.k8s.io/node-publish-secret-name: test-user csi.storage.k8s.io/node-publish-secret-namespace: default volume.beta.kubernetes.io/storage-provisioner: everest-csi-provisioner everest.io/obs-volume-type: STANDARD csi.storage.k8s.io/fstype: obsfs name: obs-secret namespace: defaultspec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi storageClassName: csi-obs volumeName: pv-obs-example 参数 描述 csi.storage.k8s.io/node-publish-secret-name 指定secret的名字 csi.storage.k8s.io/node-publish-secret-namespace 指定secret的命令空间 创建PVC。 kubectl create -f pvc-example.yaml PVC创建后,就可以创建工作负载挂载PVC使用存储。
  • 使用访问密钥创建Secret 获取访问密钥。 获取访问密钥的方法,具体请参见获取访问密钥(AK/SK)。 对访问密钥进行base64编码(假设上文获取到的ak为“xxx”,sk为“yyy”)。 echo -n xxx|base64 echo -n yyy|base64 记录编码后的AK和SK。 新建一个secret的yaml,如test-user.yaml。 apiVersion: v1data: access.key: WE5WWVhVNU***** secret.key: Nnk4emJyZ0*****kind: Secretmetadata: name: test-user namespace: default labels: secret.kubernetes.io/used-by: csitype: cfe/secure-opaque 其中: 参数 描述 access.key base64编码后的ak。 secret.key base64编码后的sk。 name secret的名称 namespace secret的命名空间 secret.kubernetes.io/used-by: csi 带上这个标签才能在控制台上创建OBS PV/PVC时可见。 type 密钥类型,该值必须为cfe/secure-opaque 使用该类型,用户输入的数据会自动加密。 创建Secret。 kubectl create -f test-user.yaml
  • CPU管理策略 默认情况下,kubelet使用CFS 配额来执行 Pod 的 CPU 约束。 当节点上运行了很多 CPU 密集的 Pod 时,工作负载可能会迁移到不同的 CPU 核, 这取决于调度时 Pod 是否被扼制,以及哪些 CPU 核是可用的。许多工作负载对这种迁移不敏感,因此无需任何干预即可正常工作。 在创建集群时可以配置CPU管理策略,如下图所示。 CPU 管理策略通过 kubelet 参数 --cpu-manager-policy 来指定。支持两种策略: 关闭(none):默认策略,显式地启用现有的默认 CPU 亲和方案,不提供操作系统调度器默认行为之外的亲和性策略。 开启(static):针对具有整数型 CPU requests 的 Guaranteed Pod ,它允许该类 Pod 中的容器访问节点上的独占 CPU 资源。 CPU管理策略的详情请参见CPU 管理策略。 父主题: 集群参数说明
  • 容器网络 vs 主机网络 创建Pod时,可以选择Pod使用容器网络或是宿主机网络。 容器网络:默认使用容器网络,Pod的网络由集群网络插件负责分配,每个Pod分配一个IP地址,会占用容器网络的IP。 主机网络:Pod直接使用宿主机的网络(Pod需要配置hostNetwork: true),会占用宿主机的端口,Pod的IP就是宿主机的IP,不会占用容器网络的IP。使用时需要考虑是否与宿主机上的端口冲突,因此一般情况下除非您知道需要某个特定应用占用宿主机上的特定端口时,不建议使用主机网络。
  • 节点可分配容器IP数 在创建CCE集群时,如果网络模型选择“VPC网络”,会让您选择每个节点可供分配的容器IP数量,如下图所示。 该参数会影响节点上可以创建最大Pod的数量,因为每个Pod会占用一个IP(使用容器网络),如果可用IP数量不够的话,就无法创建Pod。 节点默认会占用掉3个容器IP地址(网络地址、网关地址、广播地址),因此节点上 可分配给容器使用的IP数量 = 您选择的容器IP数量 - 3,例如上面图中可分配给容器使用的IP数量为 128-3=125。
  • 使用GPU 创建工作负载申请GPU资源,可按如下方法配置,指定显卡的数量。 apiVersion: apps/v1kind: Deploymentmetadata: name: gpu-test namespace: defaultspec: replicas: 1 selector: matchLabels: app: gpu-test template: metadata: labels: app: gpu-test spec: containers: - image: nginx:perl name: container-0 resources: requests: cpu: 250m memory: 512Mi nvidia.com/gpu: 1 # 申请GPU的数量 limits: cpu: 250m memory: 512Mi nvidia.com/gpu: 1 # GPU数量的使用上限 imagePullSecrets: - name: default-secret 通过 nvidia.com/gpu 指定申请GPU的数量,支持申请设置为小于1的数量,比如 nvidia.com/gpu: 0.5,这样可以多个Pod共享使用GPU。 指定nvidia.com/gpu后,在调度时不会将负载调度到没有GPU的节点。如果缺乏GPU资源,会报类似“0/2 nodes are available: 2 Insufficient nvidia.com/gpu.”的Kubernetes事件。 在CCE控制台使用GPU资源,只需在创建负载时,勾选GPU配额,并指定使用的比例即可,如下图所示。 图1 使用GPU
  • GPU节点标签 购买GPU节点后,CCE会给节点打上对应标签,如下所示,不同类型的GPU节点有不同标签。 图2 GPU节点标签 在使用GPU时,可以根据标签让Pod与节点亲和,从而让Pod选择正确的节点,如下所示。 apiVersion: apps/v1kind: Deploymentmetadata: name: gpu-test namespace: defaultspec: replicas: 1 selector: matchLabels: app: gpu-test template: metadata: labels: app: gpu-test spec: nodeSelector: accelerator: nvidia-t4 containers: - image: nginx:perl name: container-0 resources: requests: cpu: 250m memory: 512Mi nvidia.com/gpu: 1 # 申请GPU的数量 limits: cpu: 250m memory: 512Mi nvidia.com/gpu: 1 # GPU数量的使用上限 imagePullSecrets: - name: default-secret
共100000条