Karmada 结合 coreDNS 插件实现跨集群统一域名访问

本文分享自华为云社区《Karmada 结合 coreDNS 插件实现跨集群统一域名访问》,作者:云容器大未来 。

在多云与混合云越来越成为企业标配的今天,服务的部署和访问往往不在一个 K8s集群中。如何做到服务访问与集群无关,成为了各个云服务提供商必须要面对的问题。本文基于Karmada v1.6.1版本,探索使用一致域名跨集群访问服务的方法,来解决该问题。

一、实践官方例子

按照官网例子(配置多集群服务发现)【1】,详细操作如下:

1. 部署业务

以部署 deployment 与service为例。在控制平面创建 deployment 和 service 并通过 PropagationPolicy 发到集群 member1 中。该步骤合并的 yaml 如下:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: serve
spec:
  replicas: 2
  selector:
    matchLabels:
      app: serve
  template:
    metadata:
      labels:
        app: serve
    spec:
      containers:
      - name: serve
        image: jeremyot/serve:0a40de8
        args:
        - "--message='hello from cluster member1 (Node: {{env \"NODE_NAME\"}} Pod: {{env \"POD_NAME\"}} Address: {{addr}})'"
        env:
          - name: NODE_NAME
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
          - name: POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
      dnsPolicy: ClusterFirst   # 优先使用集群的coredns来解析
---
apiVersion: v1
kind: Service
metadata:
  name: serve
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: serve
---
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
  name: mcs-workload
spec:
  resourceSelectors:
    - apiVersion: apps/v1
      kind: Deployment
      name: serve
    - apiVersion: v1
      kind: Service
      name: serve
  placement:
    clusterAffinity:
      clusterNames:
        - member1

2. 创建 ServiceExport 与 ServiceImport 的 CPP规则

需要在控制面创建 ServiceExport 与 ServiceImport 两个 CRD 前创建其在集群的传播规则 。本例中通过 ClusterPropagationPolicy 将这两个CRD 安装到member1 和 member2 中去。该步骤的 yaml 如下:

yaml 复制代码
# propagate ServiceExport CRD
apiVersion: policy.karmada.io/v1alpha1
kind: ClusterPropagationPolicy
metadata:
  name: serviceexport-policy
spec:
  resourceSelectors:
    - apiVersion: apiextensions.k8s.io/v1
      kind: CustomResourceDefinition
      name: serviceexports.multicluster.x-k8s.io
  placement:
    clusterAffinity:
      clusterNames:
        - member1
        - member2
---
# propagate ServiceImport CRD
apiVersion: policy.karmada.io/v1alpha1
kind: ClusterPropagationPolicy
metadata:
  name: serviceimport-policy
spec:
  resourceSelectors:
    - apiVersion: apiextensions.k8s.io/v1
      kind: CustomResourceDefinition
      name: serviceimports.multicluster.x-k8s.io
  placement:
    clusterAffinity:
      clusterNames:
        - member1
        - member2

3. 创建从成员集群导出service

从 member1 中导出service。即在 Karmada 的控制面创建该 server 的 serviceExport,并创建 serviceExport 的 PropagationPolicy。使得 Karmada 可以管理 member1 的 serviceExport。

yaml 复制代码
apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceExport
metadata:
  name: serve
---
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
  name: serve-export-policy
spec:
  resourceSelectors:
    - apiVersion: multicluster.x-k8s.io/v1alpha1
      kind: ServiceExport
      name: serve
  placement:
    clusterAffinity:
      clusterNames:
        - member1

4. 导出service到成员集群

将 service 导入到 member2 中。同样在 Karmada 的控制面创建 ServiceImport 以及 PropagationPolicy。使得 Karmada 可以管理 member2 中的ServiceImport。

yaml 复制代码
apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceImport
metadata:
  name: serve
spec:
  type: ClusterSetIP
  ports:
  - port: 80
    protocol: TCP
---
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
  name: serve-import-policy
spec:
  resourceSelectors:
    - apiVersion: multicluster.x-k8s.io/v1alpha1
      kind: ServiceImport
      name: serve
  placement:
    clusterAffinity:
      clusterNames:
        - member2

5. 测试结果

在 member2 中,通过创建一个测试 pod 来请求 member1 中的 pod。过程中会通过 derived-serve 这个 service 来中转。

切换到 member2:

ruby 复制代码
root@zishen:/home/btg/yaml/mcs# export KUBECONFIG="$HOME/.kube/members.config"
root@zishen:/home/btg/yaml/mcs# kubectl config use-context member2
Switched to context "member2".

使用 member2 中服务的 ip 测试

ruby 复制代码
root@zishen:/home/btg/yaml/mcs# kubectl get svc -A
NAMESPACE     NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
default       derived-serve   ClusterIP   10.13.166.120   <none>        80/TCP                   4m37s
default       kubernetes      ClusterIP   10.13.0.1       <none>        443/TCP                  6d18h
kube-system   kube-dns        ClusterIP   10.13.0.10      <none>        53/UDP,53/TCP,9153/TCP   6d18h
#使用ip测试服务
root@zishen:/home/btg/yaml/mcs# kubectl --kubeconfig ~/.kube/members.config --context member2 run -i --rm --restart=Never --image=jeremyot/request:0a40de8 request -- --duration=3s --address=10.13.166.120
If you don't see a command prompt, try pressing enter.
2023/06/12 02:58:03 'hello from cluster member1 (Node: member1-control-plane Pod: serve-5899cfd5cd-6l27j Address: 10.10.0.17)'
2023/06/12 02:58:04 'hello from cluster member1 (Node: member1-control-plane Pod: serve-5899cfd5cd-6l27j Address: 10.10.0.17)'
pod "request" deleted
root@zishen:/home/btg/yaml/mcs# 

测试成功,在 member1 中使用 k8s 默认域名 serve.default.svc.cluster.local

ruby 复制代码
root@zishen:/home/btg/yaml/mcs# kubectl get svc -A
NAMESPACE     NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
default       derived-serve   ClusterIP   10.13.166.120   <none>        80/TCP                   4m37s
default       kubernetes      ClusterIP   10.13.0.1       <none>        443/TCP                  6d18h
kube-system   kube-dns        ClusterIP   10.13.0.10      <none>        53/UDP,53/TCP,9153/TCP   6d18h
#使用ip测试服务
root@zishen:/home/btg/yaml/mcs# kubectl --kubeconfig ~/.kube/members.config --context member2 run -i --rm --restart=Never --image=jeremyot/request:0a40de8 request -- --duration=3s --address=10.13.166.120
If you don't see a command prompt, try pressing enter.
2023/06/12 02:58:03 'hello from cluster member1 (Node: member1-control-plane Pod: serve-5899cfd5cd-6l27j Address: 10.10.0.17)'
2023/06/12 02:58:04 'hello from cluster member1 (Node: member1-control-plane Pod: serve-5899cfd5cd-6l27j Address: 10.10.0.17)'
pod "request" deleted

测试成功,在 member2 中使用影子域名 derived-serve.default.svc.cluster.local。

ruby 复制代码
root@zishen:/home/btg/yaml/mcs# kubectl --kubeconfig ~/.kube/members.config --context member2 run -i --rm --restart=Never --image=jeremyot/request:0a40de8 request -- --duration=3s --address=derived-serve.default.svc.cluster.local
If you don't see a command prompt, try pressing enter.
2023/06/12 03:30:41 'hello from cluster member1 (Node: member1-control-plane Pod: serve-5899cfd5cd-6l27j Address: 10.10.0.17)'
2023/06/12 03:30:42 'hello from cluster member1 (Node: member1-control-plane Pod: serve-5899cfd5cd-6l27j Address: 10.10.0.17)'
pod "request" deleted

测试成功,至此官网例子测试通过。

从官网例子可以看出,也就是 Karmada 的 v1.6.1目前的跨集群访问方式是:在需要的集群中部署 ServiceImport,生成影子服务 derived-服务名 ;再通过 derived-服务名.default.svc.cluster.local 来实现跨集群服务的访问。

这和使用统一域名访问的目标还存在差距,访问者还需要感知访问方式。

二、探索各集群使用一致域名

1. 各方案说明

目前来说针对mcs的提案KEP-1645【2】,主要有三类实现方式

  • 使用影子服务

即在客户端集群创建一样名字的服务,但 endpointSlice 的 ENDPOINTS 却指向目标 pods。这类方式需要解决本地同名服务的冲突,Karmada 社区 bivas【3】的 pr【4】正在讨论此方案。

  • 采用拓展coreDNS的方式

类似 submariner 的SERVICE DISCOVERY【5】的方式。需要开发一个拓展的 dns 解析器,并在 coreDNS 中安装对应的插件将带有指定后缀的域名(如 clusterset.local)转到这个 dns 扩展解析器。从而实现域名的解析。

▲流程图如上

该种方式的优点如下:

  • 可以实现优先访问本地服务。由于自定义了扩展 dns 解析器,故客户可在此实现服务访问的优先策略。

  • 可以实现按照原有方式访问。自定义插件中可以决定对本地服务和远端服务的规则。故可以保持原有的访问方式,本例中为:foo.default.svc.cluster.local。

  • 不需要 dns 的其他配置。由于有自定义的 dns 解析器,无需对 dns search进行配置。故没有方案一中对 dns search的配置。

该种方式的缺点如下:

  • 同样需要修改 coredns 组件。也需要重新编译 coredns 以便安装对应的插件,也需要修改对应的 coredns 配置。

  • 需要在成员集群中部署新组件。该方案需要安装一个dns扩展解析器。

  • 使用SeviseImport

其原理为 1645-multi-cluster-services-api【6】或 [Multi-Cluster DNS 【7】本文所介绍的 coredns 的插件 multicluster【8】即是这类的实现。下面将对其的实现进行探索分析。

2. coredns的multicluster插件探索

multicluster 插件的原理比较简单,需要客户端集群的 ServiceImport 拥有原始服务的名称和对应需要解析的 clusterIP(这个ip可以是原始集群的--需要打通,也可以是本集群的)。multicluster 将这些信息生成coredns的rr记录。在遇到 multicluster 需要解析的域名时候,即可完成解析。

2.1 编译安装coreDNS的multicluster插件

编译带 multicluster 插件的 coredns

按照官网的文档 multicluster插件【9】下载coredns,k8s 1.26对应版本为v1.9.3(实测最新的v1.10.1也可):

bash 复制代码
git clone https://github.com/coredns/coredns
cd coredns
git checkout v1.9.3

添加 multicluster 插件,打开 plugin.cfg 文件,添加 multicluster

makefile 复制代码
kubernetes:kubernetes
multicluster:github.com/coredns/multicluster

执行编译

bash 复制代码
cd ../ 
make

制作镜像:

直接在目录下执行(使用coreDNS v1.10以下版本,否则需要升级docker版本):

ruby 复制代码
root@zishen:/usr/workspace/go/src/github.com/coredns# docker build -f Dockerfile -t registry.k8s.io/coredns/coredns:v1.9.3 ./

查看

ruby 复制代码
root@zishen:/usr/workspace/go/src/github.com/coredns# docker images|grep core
registry.k8s.io/coredns/coredns                         v1.9.3             9a15fc60cfea   27 seconds ago   49.8MB

load到kind中:

ruby 复制代码
root@zishen:/usr/workspace/go/src/github.com/coredns# kind load docker-image registry.k8s.io/coredns/coredns:v1.9.3 --name member2
Image: "registry.k8s.io/coredns/coredns:v1.9.3" with ID "sha256:9a15fc60cfea3f7e1b9847994d385a15af6d731f86b7f056ee868ac919255dca" not yet present on node "member2-control-plane", loading...
root@zishen:/usr/workspace/go/src/github.com/coredns# 

配置 member2 中的 coredns 权限

kubectl edit clusterrole system:coredns

ruby 复制代码
root@zishen:/usr/workspace/go/src/github.com/coredns# kind load docker-image registry.k8s.io/coredns/coredns:v1.9.3 --name member2
Image: "registry.k8s.io/coredns/coredns:v1.9.3" with ID "sha256:9a15fc60cfea3f7e1b9847994d385a15af6d731f86b7f056ee868ac919255dca" not yet present on node "member2-control-plane", loading...
root@zishen:/usr/workspace/go/src/github.com/coredns# 

配置 multicluster 的 zone 规则

在coredns中的 corefile 中增加 multicluster 的处理规则(以 clusterset.local后缀为例)。

arduino 复制代码
  Corefile: |
    .:53 {
        errors
        health {
           lameduck 5s
        }
        ready
        multicluster clusterset.local
        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
    }

【注意】clusterset.local不能为系统默认的cluster.local,否则会被multicluster之前的kubernetes插件拦截。若一定需要,需要在编译前,在plugin.cfg文件中把multicluster放到kubernetes插件前。但造成的影响还未完全测试,需要进一步分析。

然后重启 coredns:

ruby 复制代码
root@zishen:/home/btg/yaml/mcs# kubectl delete pod -n kube-system          coredns-787d4945fb-mvsv4 
pod "coredns-787d4945fb-mvsv4" deleted
root@zishen:/home/btg/yaml/mcs# kubectl delete pod -n kube-system          coredns-787d4945fb-62nxv
pod "coredns-787d4945fb-62nxv" deleted

在member2 的serviceImport 中添加clusterIP

由于当前 Karmada 还未填充 serviceImport 的 ips 字段,故需要我们自己填写。删除member2 的 ServiceImport,在 karmada 控制面删除 ServiceImport。具体 yaml 参考本文之前的(导入Service到成员集群)。创建新的 ServiceImport,由于 member2 中已经没有 ServiceImport,故没了影子服务(没有clusterip)。为调试,ips 暂时用源端的 pod ip。

新的 ServiceImport 的 yaml 如下:

yaml 复制代码
apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceImport
metadata:
  name: serve
  namespace: default
spec:
  type: ClusterSetIP
  ports:
  - name: "http"
    port: 80
    protocol: TCP
  ips:
  - "10.10.0.5"

切换到member2里面创建该ServiceImport。

创建好后效果如下:

ruby 复制代码
root@zishen:/home/btg/yaml/mcs/test# kubectl get serviceImport -A
NAMESPACE   NAME    TYPE           IP              AGE
default     serve   ClusterSetIP   ["10.10.0.5"]   4h42m

验证

可以使用(之前介绍的方法:测试结果),但为了调试方便,本文使用直接创建客户端 pod 的方式。

在 member2 上创建 pod

css 复制代码
kubectl --kubeconfig ~/.kube/members.config --context member2 run -i --image=ubuntu:18.04 btg

创建好后,ctrl+c 退出。进入这个 pod

sql 复制代码
kubectl exec -it -n default btg bash

安装软件

sql 复制代码
apt-get update
apt-get install dnsutils
apt install iputils-ping
apt-get install net-tools 
apt install curl
apt-get install vim

测试可配置域名,在 /etc/resolv.conf 中添加 clusterset.local 后缀。(解释详细点)

lua 复制代码
root@btg:/# cat /etc/resolv.conf 
search default.svc.cluster.local svc.cluster.local cluster.local clusterset.local
nameserver 10.13.0.10
options ndots:5

访问域名:serve.default.svc.clusterset.local

ruby 复制代码
root@btg:/# curl serve.default.svc.clusterset.local:8080
'hello from cluster member1 (Node: member1-control-plane Pod: serve-5899cfd5cd-dvxz8 Address: 10.10.0.7)'root@btg:/#

【注意】由于我们使用的域名不是clusterIP,故需要加上端口8080

测试成功,故后续在 Karmada中实现对集群成员 ServiceImport 的 ips 添加即可。

访问方式说明

由于使用了 dns 的 search 功能,故其访问与其保持一致。若服务为 foo,则访问方式为:

  • foo.default.svc 访问。该方式会按照 coredns 的 searches 配置顺序进行解析。可实现在无本地同名服务时,访问远端集群服务;本地服务存在时(与该服务是否可用无关),则访问本地服务。

  • foo.default.svc.clusterset.local 全域名访问。该请求会直接转到远端服务处理。

缺点

  • 使用 foo.default.svc 访问并不能做到优先本地服务。只会在无本地同名服务时,才会访问远端。故,不能满足本地服务不可用时,再使用远端集群的服务的场景。

  • 使用 foo.default.svc 方式还需要修改 dns 配置。若是使用 resolv.conf方式,则需要修改每台可能的服务端服务的resolv.conf 文件。若是使用 dnsConfig 方式,则需要修改下发 pod 的 yaml 或 api。

  • 不能动态加载 multicluster 插件。需要客户重新编译 coredns,并且修改成员集群的 coredns 配置。原有访问方式会被改变。该方案采用不同后缀的方式来区分本地,远端服务。故原有的访问方式 foo.default.svc.cluster.local 会变为 foo.default.svc.clusterset.local。客户需要修改代码来适配。

优点

  • 影响可控。不会新增组件,coredns 增加multicluster的方式也是遵守coredns 官方提案,且代码公开。

  • 修改量小,使用 multicluster 已有代码和方案即可完成。

三、问题记录

1. Failed to watch *v1alpha1.Servicelmport

现象:

vbnet 复制代码
W0612 12:18:13.939070       1 reflector.go:324] pkg/mod/k8s.io/client-go@v0.24.0/tools/cache/reflector.go:167: failed to list *v1alpha1.ServiceImport: serviceimports.multicluster.x-k8s.io is forbidden: User "system:serviceaccount:kube-system:coredns" cannot list resource "serviceimports" in API group "multicluster.x-k8s.io" at the cluster scope
E0612 12:18:13.939096       1 reflector.go:138] pkg/mod/k8s.io/client-go@v0.24.0/tools/cache/reflector.go:167: Failed to watch *v1alpha1.ServiceImport: failed to list *v1alpha1.ServiceImport: serviceimports.multicluster.x-k8s.io is forbidden: User "system:serviceaccount:kube-system:coredns" cannot list resource "serviceimports" in API group "multicluster.x-k8s.io" at the cluster scope

解决方法:添加RBAC权限:

yaml 复制代码
root@zishen:/home/btg/yaml/mcs# kubectl edit clusterrole system:coredns

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  creationTimestamp: "2023-06-12T07:50:29Z"
  name: system:coredns
  resourceVersion: "225"
  uid: 51e7d961-29a6-43dc-ac0f-dbca68271e46
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  - services
  - pods
  - namespaces
  - ServiceImport
  verbs:
  - list
  - watch
...
- apiGroups:
  - multicluster.x-k8s.io
  resources:
  - serviceimports
  verbs:
  - list
  - watch

2. 编译 coredns的master分支的镜像报:invalid argument

二进制编译好后,编译镜像的具体报错如下:

python 复制代码
failed to parse platform : "" is an invalid component of "": platform specifier component must match "

升级 docker 解决。我是升级到24.0.2解决。

【注意】不能直接apt-get install docker-ce ,否则装出来的是20版本,还是有这个问题。

  • apt切换源

编写文件/etc/apt/sources.list,内容改为如下:

arduino 复制代码
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse

3. dig中报WARNING:recursion requested but not available

现象如下:

ini 复制代码
root@btg:/# dig @10.13.0.10 serve.default.svc.cluster.local  A

; <<>> DiG 9.11.3-1ubuntu1.18-Ubuntu <<>> @10.13.0.10 serve.default.svc.cluster.local A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 57327
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 24c073ed74240563 (echoed)
;; QUESTION SECTION:
;serve.default.svc.cluster.local. IN A

参考header插件,在corefile中增加即可

vbscript 复制代码
header {
  response set ra # set RecursionAvailable flag
}

四、要求

1、coredns 版本必须为 v1.9.3及其以上,否则不支持 multicluster 特性。配套的 K8s 版本至少 v1.21.0。

2、服务中最好指定 dnsPolicy: ClusterFirst。

五、参考

1\] 官网例子,详细操作如下:[karmada.io/zh/docs/use...](https://link.juejin.cn?target=https%3A%2F%2Fkarmada.io%2Fzh%2Fdocs%2Fuserguide%2Fservice%2Fmulti-cluster-service "https://karmada.io/zh/docs/userguide/service/multi-cluster-service") \[2\] Multi-ClusterServicesAPI:[github.com/kubernetes/...](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fkubernetes%2Fenhancements%2Fblob%2Fmaster%2Fkeps%2Fsig-multicluster%2F1645-multi-cluster-services-api%2FREADME.md "https://github.com/kubernetes/enhancements/blob/master/keps/sig-multicluster/1645-multi-cluster-services-api/README.md") \[3\] Karmada 社区bivas:[github.com/bivas](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fbivas "https://github.com/bivas") \[4\] proposal for native service discovery:[github.com/karmada-io/...](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fkarmada-io%2Fkarmada%2Fpull%2F3694 "https://github.com/karmada-io/karmada/pull/3694") \[5\] SERVICE DISCOVERY:[submariner.io/getting-sta...](https://link.juejin.cn?target=https%3A%2F%2Fsubmariner.io%2Fgetting-started%2Farchitecture%2Fservice-discovery%2F "https://submariner.io/getting-started/architecture/service-discovery/") \[6\] 1645-multi-cluster-services-api:[github.com/kubernetes/...](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fkubernetes%2Fenhancements%2Ftree%2Fmaster%2Fkeps%2Fsig-multicluster%2F1645-multi-cluster-services-api "https://github.com/kubernetes/enhancements/tree/master/keps/sig-multicluster/1645-multi-cluster-services-api") \[7\] Multi-Cluster DNS :[docs.google.com/document/d/...](https://link.juejin.cn?target=https%3A%2F%2Fdocs.google.com%2Fdocument%2Fd%2F1-jy1WM4Tb4iz4opBTxviap5PnpfRWd-NZvwhmZWOpRk%2Fedit%23heading%3Dh.uk21d87cd2uk "https://docs.google.com/document/d/1-jy1WM4Tb4iz4opBTxviap5PnpfRWd-NZvwhmZWOpRk/edit#heading=h.uk21d87cd2uk") \[8\] multicluster:[github.com/coredns/mul...](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fcoredns%2Fmulticluster "https://github.com/coredns/multicluster") \[9\] multicluster插件:[github.com/coredns/mul...](https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Fcoredns%2Fmulticluster "https://github.com/coredns/multicluster") \[10\] CoreDNS篇2-编译安装ExternalPlugins\][zhuanlan.zhihu.com/p/387807927](https://link.juejin.cn?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F387807927 "https://zhuanlan.zhihu.com/p/387807927") \[11\] MCP多云跨集群pod互访 [www.361way.com/mcp-multi-p...](https://link.juejin.cn?target=https%3A%2F%2Fwww.361way.com%2Fmcp-multi-pod-access%2F6873.html "https://www.361way.com/mcp-multi-pod-access/6873.html") \[12\] 采坑指南------K8s域名解析coredns问题排查过程 [zhuanlan.zhihu.com/p/89898164](https://link.juejin.cn?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F89898164 "https://zhuanlan.zhihu.com/p/89898164") **▍相关学习** 1、Submariner 原理说明:【Kubernetes CNI 插件选型和应用场景探讨: [zhuanlan.zhihu.com/p/582102994](https://link.juejin.cn?target=https%3A%2F%2Fzhuanlan.zhihu.com%2Fp%2F582102994 "https://zhuanlan.zhihu.com/p/582102994") 2、coredns原理:【K8s 服务注册与发现(三)CoreDNS : [cloud.tencent.com/developer/a...](https://link.juejin.cn?target=https%3A%2F%2Fcloud.tencent.com%2Fdeveloper%2Farticle%2F2126512 "https://cloud.tencent.com/developer/article/2126512") 3、service原理:【浅谈 Kubernetes Service: [z.itpub.net/article/det...](https://link.juejin.cn?target=https%3A%2F%2Fz.itpub.net%2Farticle%2Fdetail%2FA0463024894EF7FEEDBFC4DDF0E797C8 "https://z.itpub.net/article/detail/A0463024894EF7FEEDBFC4DDF0E797C8") 4、endpointSlice原理:【重识云原生】第六章容器基础 6.4.9.5 节------ Service特性端点切片(Endpoint Slices): [blog.csdn.net/junbaozi/ar...](https://link.juejin.cn?target=https%3A%2F%2Fblog.csdn.net%2Fjunbaozi%2Farticle%2Fdetails%2F127857965 "https://blog.csdn.net/junbaozi/article/details/127857965") [**点击关注,第一时间了解华为云新鲜技术\~**](https://link.juejin.cn?target=https%3A%2F%2Fbbs.huaweicloud.com%2Fblogs%3Futm_source%3Djuejin%26utm_medium%3Dbbs-ex%26utm_campaign%3Dother%26utm_content%3Dcontent "https://bbs.huaweicloud.com/blogs?utm_source=juejin&utm_medium=bbs-ex&utm_campaign=other&utm_content=content")

相关推荐
zopple4 小时前
常见的 Spring 项目目录结构
java·后端·spring
cjy0001116 小时前
springboot的 nacos 配置获取不到导致启动失败及日志不输出问题
java·spring boot·后端
小江的记录本7 小时前
【事务】Spring Framework核心——事务管理:ACID特性、隔离级别、传播行为、@Transactional底层原理、失效场景
java·数据库·分布式·后端·sql·spring·面试
sheji34167 小时前
【开题答辩全过程】以 基于springboot的校园失物招领系统为例,包含答辩的问题和答案
java·spring boot·后端
程序员cxuan7 小时前
人麻了,谁把我 ssh 干没了
人工智能·后端·程序员
wuyikeer9 小时前
Spring Framework 中文官方文档
java·后端·spring
Victor3569 小时前
MongoDB(61)如何避免大文档带来的性能问题?
后端
Victor3569 小时前
MongoDB(62)如何避免锁定问题?
后端
wuyikeer9 小时前
Spring BOOT 启动参数
java·spring boot·后端
子木HAPPY阳VIP10 小时前
Ubuntu 22.04 VMware 设置固定IP配置
人工智能·后端·目标检测·机器学习·目标跟踪