在kubernetes+istio中通过FQDN请求Nacos服务
背景是我们希望能在k8s中通过DNS方式,访问服务的FQDN来调用虚拟机注册到nacos的服务。我们vm和k8s的网段配置了相关路由能相互访问之前nacos有维护了一个同步去coredns的项目,但是年久失修,支持的nacos版本和coredns版本都不高。后面在官方文档找资料的时候,发现nacos是支持istio MCP协议的,于是采取这个方案来完成目标。
公众号:《尹安灿》 欢迎交流
背景是我们希望能在k8s中通过DNS方式,访问服务的FQDN来调用虚拟机注册到nacos的服务。
我们vm和k8s的网段配置了相关路由能相互访问
之前nacos有维护了一个同步去coredns的项目,但是年久失修,支持的nacos版本和coredns版本都不高。后面在官方文档找资料的时候,发现nacos是支持istio MCP协议的 Pilot MCP协议介绍,于是采取这个方案来完成目标。《Nacos 1.1.4发布,业界率先支持Istio MCP协议》
环境:
istio: 1.10
nacos: 2.1.0
配置nacos开启MCP Server
进入nacos配置目录,执行以下命令,把 nacos.istio.mcp.server.enabled
值设置为 true。重启nacos server 让它运行MCP Server。
[root@dev_10.1.10.209 nacos]#sed -i 's/nacos.istio.mcp.server.enabled=false/nacos.istio.mcp.server.enabled=true/g' conf/application.properties
重启后nacos MCP server会监听 18848
端口
[root@dev_10.1.10.209 nacos]#lsof -i:18848
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 98108 root 171u IPv4 834348182 0t0 TCP *:18848 (LISTEN)
配置istio添加MCP server sources
我测试的nacos server所在的服务器IP10.1.10.209
nacos MCP server监听的端口 18848
编辑istio的configmap,添加以下配置
kubectl edit -n istio-system cm istio
configSources:
- address: xds://10.1.10.209:18848
添加后的配置大概如下:
apiVersion: v1
data:
mesh: |-
accessLogFile: /dev/stdout
configSources:
- address: xds://10.1.10.209:18848
defaultConfig:
discoveryAddress: istiod.istio-system.svc:15012
proxyMetadata: {}
tracing:
zipkin:
address: zipkin.istio-system:9411
enablePrometheusMerge: true
rootNamespace: istio-system
trustDomain: cluster.local
meshNetworks: 'networks: {}'
重启下istiod 连接MCP server同步信息
kubectl rollout restart -n istio-system deployment istiod
服务访问
同步nacos服务信息到istio后,我们可以在服务的sidecar envoy看到同步下来的服务配置信息。
如以下是我 ops-apollo-probe
服务的pod ops-apollo-probe-7765fd445f-smstf
的envoy配置信息,搜索nacos后的结果。
➜ ~ istioctl pc all -n develop ops-apollo-probe-7765fd445f-smstf|grep nacos
msg-group.DEFAULT-GROUP.public.nacos 80 - outbound EDS
nacos-test.develop.svc.cluster.local.DEFAULT-GROUP.public.nacos 80 - outbound EDS
nacos-vm.DEFAULT-GROUP.public.nacos 7788 - outbound EDS
80 msg-group.DEFAULT-GROUP.public.nacos /*
80 nacos-test.develop.svc.cluster.local.DEFAULT-GROUP.public.nacos, nacos-test + 1 more... /*
7788 nacos-vm.DEFAULT-GROUP.public.nacos /*
带着 nacos结尾的域名就是nacos同步下来的,比如 nacos-vm.DEFAULT-GROUP.public.nacos
但是现在,在我ops-apollo-probe容器里面,依旧是无法通过nacos-vm.DEFAULT-GROUP.public.nacos
访问到我的 nacos-vm服务的。
因为现在大概的访问流程是这样的,详情见Understanding DNS - istio
因为coredns中并没有 nacos-vm.DEFAULT-GROUP.public.nacos
的解析,所以解析失败,报错退出。
以下为在ops-apollo-probe服务的容器内请求:
/app # curl -v nacos-vm.DEFAULT-GROUP.public.nacos:7788/healthz
* Could not resolve host: nacos-vm.DEFAULT-GROUP.public.nacos
* Closing connection 0
curl: (6) Could not resolve host: nacos-vm.DEFAULT-GROUP.public.nacos
/app # nslookup nacos-vm.DEFAULT-GROUP.public.nacos
Server: 10.17.0.10
Address: 10.17.0.10:53
** server can't find nacos-vm.DEFAULT-GROUP.public.nacos: NXDOMAIN
** server can't find nacos-vm.DEFAULT-GROUP.public.nacos: NXDOMAIN
curl显示不能解析,nslookup没解析出IP,可以看到nameserver是coredns的IP(10.17.0.10)。
➜ ~ kubectl get svc -n kube-system kube-dns
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.17.0.10 <none> 53/UDP,53/TCP 35d
所以要解决访问,还要能有个IP把包先发出去,到istio sidecar接管请求后就完事,因为envoy有服务的真正IP信息。
所以我们可以瞎指定一个IP,比如1.1.1.1。
hosts大法指定IP
域名解析,hosts文件的记录优先级高于nameserver的记录
# 添加hosts
/app # echo '1.1.1.1 nacos-vm.DEFAULT-GROUP.public.nacos' >> /etc/hosts
/app # curl -v nacos-vm.DEFAULT-GROUP.public.nacos:7788/healthz
* Trying 1.1.1.1:7788...
* Connected to nacos-vm.DEFAULT-GROUP.public.nacos (1.1.1.1) port 7788 (#0)
> GET /healthz HTTP/1.1
> Host: nacos-vm.DEFAULT-GROUP.public.nacos:7788
> User-Agent: curl/7.80.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/plain;charset=UTF-8
< content-length: 2
< date: Mon, 19 Sep 2022 11:57:22 GMT
< x-envoy-upstream-service-time: 4
< server: envoy
<
* Connection #0 to host nacos-vm.DEFAULT-GROUP.public.nacos left intact
OK
可以看到能正常请求到nacos-vm的健康检查接口
直接指定IP
可以直接指定连接IP,跳过域名解析环境,带上host头来用来匹配envoy的规则即可。
如curl实现如下:
/app # ping nacos-vm.DEFAULT-GROUP.public.nacos
ping: bad address 'nacos-vm.DEFAULT-GROUP.public.nacos'
/app # curl -v -H "Host: nacos-vm.DEFAULT-GROUP.public.nacos" 1.1.1.1:7788/healthz
* Trying 1.1.1.1:7788...
* Connected to 1.1.1.1 (1.1.1.1) port 7788 (#0)
> GET /healthz HTTP/1.1
> Host: nacos-vm.DEFAULT-GROUP.public.nacos
> User-Agent: curl/7.80.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/plain;charset=UTF-8
< content-length: 2
< date: Mon, 19 Sep 2022 12:03:59 GMT
< x-envoy-upstream-service-time: 3
< server: envoy
<
* Connection #0 to host 1.1.1.1 left intact
OK/app #
可以看到携带相关host头,直接请求1.1.1.1:7788/healthz 也是能访问到相关接口。
nacos官方给的例子其实就是这种做法。
Instance instance = new Instance();
instance.setIp("1.1.1.1");
instance.setPort(80);
// 必须设置ephemeral=false,来保证服务端使用的是严格的一致性协议,否则可能会导致生成的instance id冲突:
instance.setEhpemeral(false);
instance.setMetadata(new HashMap<String, String>());
instance.getMetadata().put(PreservedMetadataKeys.INSTANCE_ID_GENERATOR, Constants.SNOWFLAKE_INSTANCE_ID_GENERATOR);
coredns增加nacos后缀解析为固定的IP
kubectl edit cm -n kube-system coredns
增加以下配置:
10.96.0.10
是我coredns的cluster IP
template IN ANY public.nacos {
answer "{{ .Name }} 60 IN A 1.1.1.1"
rcode NOERROR
authority "public.nacos. 60 IN NS ns0.public.nacos."
additional "ns0.public.nacos. 60 IN A 10.96.0.10"
}
添加后效果如下:
ping和nslookup的结果符合预期
/app # ping nacos-vm.DEFAULT-GROUP.public.nacos
PING nacos-vm.DEFAULT-GROUP.public.nacos (1.1.1.1): 56 data bytes
64 bytes from 1.1.1.1: seq=0 ttl=53 time=158.908 ms
^C
--- nacos-vm.DEFAULT-GROUP.public.nacos ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 158.908/158.908/158.908 ms
/app # nslookup nacos-vm.DEFAULT-GROUP.public.nacos
Server: 10.17.0.10
Address: 10.17.0.10:53
Name: nacos-vm.default-group.public.nacos
Address: 1.1.1.1
Name: nacos-vm.default-group.public.nacos
Address: 1.1.1.1
请求自然也是没问题。
istio DNS代理
istio sidecar提供dns解析DNS Proxying,既可以减少coredns压力,又可以加快解析速度。它会从预留的IP段 240.240.0.0/16
中分配一个。
kubectl edit -n istio-system cm istio
增加如下配置:
defaultConfig:
proxyMetadata:
# Enable basic DNS proxying
ISTIO_META_DNS_CAPTURE: "true"
# Enable automatic address allocation, optional
ISTIO_META_DNS_AUTO_ALLOCATE: "true"
加好的配置大概如下:
apiVersion: v1
data:
mesh: |-
accessLogFile: /dev/stdout
configSources:
- address: xds://10.1.10.209:18848
defaultConfig:
discoveryAddress: istiod.istio-system.svc:15012
proxyMetadata:
ISTIO_META_DNS_CAPTURE: "true"
ISTIO_META_DNS_AUTO_ALLOCATE: "true"
tracing:
zipkin:
address: zipkin.istio-system:9411
enablePrometheusMerge: true
extensionProviders:
- envoyOtelAls:
port: 4317
service: otel-collector.istio-system.svc.cluster.local
name: otel
rootNamespace: istio-system
trustDomain: cluster.local
meshNetworks: 'networks: {}'
我重启了相关服务
kubectl rollout restart -n develop deployment ops-apollo-probe
验证nslookup结果,
/app # nslookup nacos-vm.default-group.public.nacos
Server: 10.17.0.10
Address: 10.17.0.10:53
Name: nacos-vm.default-group.public.nacos
Address: 240.240.0.2
/app #
请求自然也是没问题
/app # curl -v nacos-vm.default-group.public.nacos:7788/healthz
* Trying 240.240.0.2:7788...
* Connected to nacos-vm.default-group.public.nacos (240.240.0.2) port 7788 (#0)
> GET /healthz HTTP/1.1
> Host: nacos-vm.default-group.public.nacos:7788
> User-Agent: curl/7.80.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/plain;charset=UTF-8
< content-length: 2
< date: Mon, 19 Sep 2022 16:04:51 GMT
< x-envoy-upstream-service-time: 5
< server: envoy
<
* Connection #0 to host nacos-vm.default-group.public.nacos left intact
OK
更多推荐
所有评论(0)