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/[email protected]/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/[email protected]/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")

相关推荐
bing_15813 分钟前
Spring Boot 中如何启用 MongoDB 事务
spring boot·后端·mongodb
zhojiew42 分钟前
service mesh的定制化与性能考量
java·云原生·service_mesh
小屁孩大帅-杨一凡1 小时前
Azure Document Intelligence
后端·python·microsoft·flask·azure
alden_ygq2 小时前
K8S服务的请求访问转发原理
云原生·容器·kubernetes
Mr_wilson_liu2 小时前
k8s删除pv和pvc后,vg存储没释放分析
云原生·容器·kubernetes
Code哈哈笑2 小时前
【图书管理系统】深度讲解:图书列表展示的后端实现、高内聚低耦合的应用、前端代码讲解
java·前端·数据库·spring boot·后端
无名之逆3 小时前
Hyperlane: Unleash the Power of Rust for High-Performance Web Services
java·开发语言·前端·后端·http·rust·web
薯条不要番茄酱3 小时前
【SpringBoot】从环境准备到创建SpringBoot项目的全面解析.
java·spring boot·后端
alden_ygq4 小时前
K8S Svc Port-forward 访问方式
云原生·容器·kubernetes
hwj运维之路4 小时前
k8s监控方案实践(二):集成Alertmanager告警与钉钉Webhook通知
云原生·容器·kubernetes