【笔记10】DNS、服务入口和节点调度

DNS

Kubernetes中存在一个DNS服务,其作用是提供一个service名和IP的对应关系

以下是DNS服务常见的资源

[root@master ~]# kubectl get deploy,po,svc,ep -n kube-system | grep dns
deployment.apps/coredns                   2/2     2            2           25h
pod/coredns-66f779496c-dvbjx                   1/1     Running   1 (5h56m ago)   25h
pod/coredns-66f779496c-fvjkt                   1/1     Running   1 (5h56m ago)   25h
service/kube-dns         ClusterIP   10.65.0.10      <none>        53/UDP,53/TCP,9153/TCP   25h
endpoints/kube-dns         10.64.219.73:53,10.64.219.75:53,10.64.219.73:53 + 3 more...   25h

CoreDNS 是一个灵活可扩展的 DNS 服务器,可以作为 Kubernetes 集群 DNS。 与 Kubernetes 一样,CoreDNS 项目由 CNCF 托管。目前使用官方的kubeadm安装工具进行部署会自动安装CoreDNS,其他的Kubernetes 发行版也将CoreDNS 作为默认的DNS服务,如rancher。

配置文件格式

配置文件使用cm进行传递,格式如下:

[root@master ~]# kubectl get cm -n kube-system coredns -o yaml 
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
           pods insecure
           fallthrough in-addr.arpa ip6.arpa
           ttl 30
        }
        prometheus :9153
        forward . /etc/resolv.conf {
           max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
kind: ConfigMap
metadata:
  creationTimestamp: "2023-12-13T05:47:21Z"
  name: coredns
  namespace: kube-system
  resourceVersion: "255"
  uid: d1ad3fbe-7c4a-45d8-af31-10c082c3a442

大括号中即是CoreDNS的配置项,意义如下:

  • errors:错误信息到标准输出。
  • health:CoreDNS自身健康状态报告,默认监听端口8080,一般用来做健康检查。您可以通过http://10.18.206.207:8080/health获取健康状态。(10.18.206.207为coredns其中一个Pod的IP)
  • ready:CoreDNS插件状态报告,默认监听端口8181,一般用来做可读性检查。
  • kubernetes:CoreDNS kubernetes插件,提供集群内服务解析能力。
  • prometheus:CoreDNS自身metrics数据接口。
  • forward:将域名查询请求转到预定义的DNS服务器。
  • cache:DNS缓存时长,单位秒。
  • loop:环路检测,如果检测到环路,则停止CoreDNS。
  • reload:允许自动重新加载已更改的Corefile。编辑ConfigMap配置后,请等待两分钟以使更改生效。
  • loadbalance:循环DNS负载均衡器,可以在答案中随机A、AAAA、MX记录的顺序。

服务入口

服务入口有三个主要概念:
ingress:用来定义路由规则
ingress controller:解析ingress定义的路由规则并提供服务
ingress class:将ingress与ingress controller关联在一起

ingress

ingress对象描述了一组服务的访问规则,并通过ingress插件将服务发布出去,用户和其他系统通过对应的规则访问到对应的服务。

ingress示例:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /apppath
spec:
  rules:
  - http:
      paths:
      - path: /apppath
        backend:
          service:
            name: test
            port: 80

ingress controller

仅创建 Ingress 资源本身是没有任何作用的,还需要部署 Ingress Controller。为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress Controller。
Ingress Controller不是随集群自动启动的。 基于此页面,可选择最适合你的集群的 ingress 控制器实现。
Kubernetes 作为一个项目,目前支持和维护 AWSGCENginx Ingress 控制器。

常见的ingress controller可以在此地址查看:

https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress-controllers/#additional-controllers

ingress class

在 Kubernetes 1.18 之前,需要在 Ingress 资源上通过 kubernetes.io/ingress.class 注解来指定使用的 Ingress Controller。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /apppath
spec:
  rules:
  - http:
      paths:
      - path: /apppath
        backend:
          service:
            name: test
            port: 80

在创建 Ingress Controller 对象时,通过 --ingress-class 来指定此 Ingress Controller 对应的 class,如:

    spec:
      containers:
      - args:
        - /nginx-ingress-controller
        - --ingress-class=nginx

这种方式可以将 Ingress 资源与 Ingress Controller 联系在一起,进行工作。但带来的问题是这两个资源的关联非常紧密。

随着集群规模不断变大,应用的访问需求不断增加,单一的 Ingress Controller 很难满足需求,可能需要用到不同的 Ingress Controller 共同协作,这样紧密的关系无法满足部署多个 Ingress Controller 的场景,这样就有了 ingress class。

示例如下:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: external-lb
spec:
  controller: example.com/ingress-controller
  parameters:
    apiGroup: k8s.example.com
    kind: IngressParameters
    name: external-lb

其中重要的属性是 metadata.name 和 spec.controller,前者是这个 IngressClass 的名称,需要设定在 Ingress 中,后者是 Ingress Controller 的名称。
spec.parameters属性用于定义一些额外的配置。

在 Ingress 中添加 spec.ingressClassName 参数即可关联在此 IngressClass 上。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
spec:
  ingressClassName: external-lb
  defaultBackend:
    service:
      name: test
      port:
        number: 80

节点调度

K8S调度器kube-schduler的主要作用是将新创建的Pod调度到集群中的合适节点上运行。kube-schduler的调度算法非常灵活,可以根据不同的需求进行自定义配置,比如资源限制、亲和性和反亲和性等。

kube-schduler的工作原理:

  • 监听API Server:kube-schduler会监听API Server上的Pod对象,以获取需要被调度的Pod信息。
  • 节点预选:kube-schduler会根据Pod的资源需求和约束条件筛选出可用的Node节点。
  • 计算分值:kube-schduler会为每一个可用节点计算一个分值,计算方法可以通过调度算法指定。
  • 选择节点:kube-schduler会选择分值最高的节点作为最终的调度目标,如果多个节点分数相等,kube-schduler会随机选择一个节点。
  • 更新API Server:kube-schduler会更新API Server上的Pod对象,将选定的Node节点信息写入Pod对象的spec字段中。

NodeSelector

NodeSelector会将Pod根据定义的标签选定到匹配的Node上去。

关键词:

  • nodeSelector:预选规则,调度器的节点选择范围缩小有某一个或几个标签的节点上

示例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-ssd
spec:
  containers:
  - name: nginx-ssd
    image: nginx:1.23.2
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
  nodeSelector:
    disktype: ssd

此示例会把此pod调度到含有 disktype: ssd 标签的节点中,但由于其是预选函数,调度器会将所有含有同样标签的节点都作为备选的调度节点,然后根据调度算法选取一个最优节点进行调度。

节点亲和性NodeAffinity

NodeAffinity的目的是把Pod部署到符合要求的Node上。

关键词:

  • requiredDuringSchedulingIgnoredDuringExecution:表示强匹配,必须要满足,否则不进行调度
  • preferredDuringSchedulingIgnoredDuringExecution:表示弱匹配,尽可能满足,优先在符合要求的节点调度

示例:

apiVersion: v1
kind: Pod
metadata:
  name: node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:  ##必须满足下面匹配规则
        nodeSelectorTerms:
        - matchExpressions:
          - key: env
            operator: NotIn  ##逻辑运算符支持:In,NotIn,Exists,DoesNotExist,Gt,Lt
            values:
            - test
            - dev
      preferredDuringSchedulingIgnoredDuringExecution: ##尽可能满足,但不保证
      - weight: 1
        preference:
          matchExpressions:
          - key: project
            operator: In
            values:
            - app
  containers:
  - name: redis
    image: redis

Pod亲和性与反亲和

podAffinity、podantiAffinity的目的是把Pod部署到符合要求的Node上。‘

关键词:

  • podAffinity:将Pod与符合匹配规则的Pod调度在一起
  • podAntiAffinity:将Pod与符合匹配规则的Pod不调度在一起
  • requiredDuringSchedulingIgnoredDuringExecution:表示强匹配,必须要满足,否则不进行调度
  • preferredDuringSchedulingIgnoredDuringExecution:表示弱匹配,尽可能满足,优先在符合要求的节点调度

示例:

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:										 # pod亲和规则
      requiredDuringSchedulingIgnoredDuringExecution:    # 必须要满足此规则,此规则匹配 security = S1 的Pod
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: kubernetes.io/hostname
    podAntiAffinity:									 # 反亲和规则
      preferredDuringSchedulingIgnoredDuringExecution:   # 尽量满足此规则,此规则匹配 security = S2 的Pod
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: kubernetes.io/hostname
  containers:
 - name: with-pod-affinity
    image: k8s.gcr.io/pause:2.0

此示例定义了一个Pod,此Pod有特殊的调度方式:

  • 需要将其与拥有 security = S1 标签的Pod调度在一起
  • 同时需要注意尽量不和拥有 security = S2 标签的Pod调度在一起

污点和容忍

污点(Taint)针对节点来说,和节点亲和性正好相对,节点亲和性使Pod被吸引到一类特定的节点,而污点则使节点能够排斥一类特定的Pod。

容忍度(Toleration)应用于Pod上,它用来允许调度器调度带有对应污点的节点。 容忍度允许调度但并不保证调度:作为其功能的一部分, 调度器也会评估其他参数。

污点和容忍度(Toleration)相互配合,可以避免Pod被分配到不合适的节点上。 每个节点上都可以应用一个或多个污点,这表示对于那些不能容忍这些污点的Pod, 是不会被该节点接受的。

命令格式如下:

kubectl taint node [node] key=value:[effect]

说明:
其中[effect] 可取值:[ NoSchedule | PreferNoSchedule | NoExecute ]:
NoSchedule :一定不能被调度,已经在运行中的Pod不受影响。
PreferNoSchedule:尽量不要调度,实在没有节点可调度再调度到此节点。
NoExecute:不仅不会调度,还会驱逐Node上已有的Pod。

清除污点命令格式:

kubectl taint node [node] key:[effect]-

设置容忍的几种规则:

1、 匹配特定污点

tolerations:
- key: "taintKey"      #和污点的key名字保持一致
  operator: "Equal"    #匹配类型,Equal表示匹配污点的所有值
  value: "taintValue"  #和污点key的值保持一致
  effect: "NoSchedule" #污点类型

2、不完全匹配(未比对污点key的value)

tolerations:
- key: "taintKey"      #和污点的key名字保持一致
  operator: "Exists"   #匹配类型,只要符合污点设置的key即可
  effect: "NoSchedule" #污点的类型

3、范围匹配(仅匹配了污点key是否存在)

tolerations:
- key: "taintKey"      #和污点的key名字保持一致
  operator: "Exists"   

4、匹配所有(仅匹配了是否存在污点)

tolerations:
- operator: "Exists"  

可以通过以下配置设置驱逐容忍时间:
如果这个Pod 正在运行,此时节点被打上对应的污点,那么Pod还将继续在节点上运行3600秒,然后被驱逐。 如果在此之前上述污点被删除了,则Pod不会被驱逐。

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
  tolerationSeconds: 3600

完整Pod YAML示例:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: dev
spec:
  containers:
  - name: ng
    image: nginx:1.21.0
  tolerations:
  - key: name
    operator: Exists
    effect: NoSchedule
  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值