You need to enable JavaScript to run this app.
导航
手动开启服务拓扑
最近更新时间:2023.10.07 14:17:47首次发布时间:2023.08.16 21:36:19

默认情况下,发送到一个 Service 的流量会被均匀地转发到每个后端 Endpoint 上。而在服务拓扑机制下,kube-dns 能够基于节点名称进行服务发现,从而将 DNS 路由到最近的副本上。
在边缘托管服务下,边缘节点与管控面机器网络不通,导致 Pod 内 DNS 无法使用。本文内容将指导您将 DNS 路由到边缘节点的本机进行使用,从而解决这一问题。

前提条件

已通过 kubectl 连接 Kubernetes 集群。

操作步骤

  1. 在 kube-apiserver 开启服务拓扑功能;
  2. 修改 kube-proxy 的配置,并重启 kube-proxy;
  3. 修改 CoreDNS 的部署方案,改成 DaemonSet 部署;
  4. 修改 CoreDNS 的 Service,将服务拓扑设置成优先读取本机。

步骤详情

  1. 联系火山引擎边缘托管的商务同学开启底层服务拓扑功能。
  2. 修改 kube-proxy 的配置,并重启 kube-proxy 服务:
  • 获取配置文件:
# 获取配置文件
kubectl get cm -n kube-system kube-proxy -o jsonpath={.data.config\\.conf}
  • 修改 Configmap里的 config.conf,添加如下字段:
# 添加字段
featureGates:
  ServiceTopology: true
  • 清理掉所有 kube-proxy,重启后重新加载配置。
kubectl get pods -n kube-system | grep kube-proxy |awk '{print $1}'| xargs -I {} kubectl delete pod {} -n kube-system
  1. 修改 CoreDNS 的部署:
# 创建一个 DaemonSet 的 CoreDNS
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: coredns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
spec:
  selector:
    matchLabels:
      k8s-app: kube-dns
  template:
    metadata:
      labels:
        k8s-app: kube-dns
    spec:
      volumes:
        - name: config-volume
          configMap:
            name: coredns
            items:
              - key: Corefile
                path: Corefile
            defaultMode: 420
      containers:
        - name: coredns
          image: $(kubectl get deployment -n kube-system coredns -o jsonpath="{$.spec.template.spec.containers[0].image}")
          args:
            - '-conf'
            - /etc/coredns/Corefile
          ports:
            - name: dns
              containerPort: 53
              protocol: UDP
            - name: dns-tcp
              containerPort: 53
              protocol: TCP
            - name: metrics
              containerPort: 9153
              protocol: TCP
          resources:
            limits:
              memory: 2000Mi
            requests:
              cpu: 100m
              memory: 200Mi
          volumeMounts:
            - name: config-volume
              readOnly: true
              mountPath: /etc/coredns
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 60
            timeoutSeconds: 5
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 5
          readinessProbe:
            httpGet:
              path: /ready
              port: 8181
              scheme: HTTP
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
          securityContext:
            capabilities:
              add:
                - NET_BIND_SERVICE
              drop:
                - all
            readOnlyRootFilesystem: true
            allowPrivilegeEscalation: false
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: Default
      serviceAccountName: coredns
      serviceAccount: coredns
      securityContext: {}
      schedulerName: default-scheduler
      tolerations:
        - key: CriticalAddonsOnly
          operator: Exists
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
        - key: node-role.kubernetes.io/control-plane
          effect: NoSchedule
        - key: vei.bytedance.com/edge-node
          operator: Exists
          effect: NoSchedule
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  revisionHistoryLimit: 10
EOF
  • 删除 Deployment 类型的 CoreDNS。
kubectl get deployment -n kube-system -o yaml > backup.yaml # 备份当前的 CoreDNS
kubectl delete deployment -n kube-system coredns
  1. 更新 kube-dns 配置,给 kube-dns 添加服务拓扑。
kubectl patch svc -n kube-system kube-dns  --type='json' -p='[{"op": "add", "path": "/spec/topologyKeys", "value": ["kubernetes.io/hostname","*"]}]'