我在尝试在 Kubernetes 集群中的两个服务之间进行通信时遇到问题。我们使用 kong 入口对象作为“api 网关”来重新路由来自简单 Angular 前端的 http 调用,以将其发送到 .NET Core 3.1 API 控制器接口后端。
在这两个 ClusterIP 服务前面有一个入口控制器,用于从我们的 kubernetes 集群接收外部 http(s) 调用以启动前端服务。此入口显示在此处:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx
namespace: kong
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: app.***.*******.com << Obfuscated
http:
paths:
- path: /
backend:
serviceName: frontend-service
servicePort: 80
第一个服务称为“前端服务”,这是一个简单的 Angular 9 前端,允许我输入 http 字符串并将这些字符串提交给后端。
清单 yaml 文件如下所示。请注意,由于各种原因,图像名称被混淆了。
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: kong
labels:
app: frontend
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
imagePullSecrets:
- name: regcred
containers:
- name: frontend
image: ***********/*******************:**** << Obfuscated
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
namespace: kong
name: frontend-service
spec:
type: ClusterIP
selector:
app: frontend
ports:
- port: 80
targetPort: 80
protocol: TCP
第二个服务是一个简单的 .NET Core 3.1 API 接口,它在到达控制器时打印回一些文本。后端服务称为“dataapi”,其中有一个简单的控制器,称为 ValuesController。
清单 yaml 文件如下所示。
replicas: 1
selector:
matchLabels:
app: dataapi
template:
metadata:
labels:
app: dataapi
spec:
imagePullSecrets:
- name: regcred
containers:
- name: dataapi
image: ***********/*******************:**** << Obfuscated
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: dataapi
namespace: kong
labels:
app: dataapi
spec:
ports:
- port: 80
name: http
targetPort: 80
selector:
app: dataapi
我们使用 kong 入口作为代理将传入的 http 调用重定向到 dataapi 服务。此清单文件如下所示:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kong-gateway
namespace: kong
spec:
ingressClassName: kong
rules:
- http:
paths:
- path: /dataapi
pathType: Prefix
backend:
service:
name: dataapi
port:
number: 80
执行“kubectl get all”会产生以下输出:
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/dataapi-dbc8bbb69-mzmdc 1/1 Running 0 2d2h
pod/frontend-5d5ffcdfb7-kqxq9 1/1 Running 0 65m
pod/ingress-kong-56f8f44fd5-rwr9j 2/2 Running 0 6d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dataapi ClusterIP 10.128.72.137 <none> 80/TCP,443/TCP 2d2h
service/frontend-service ClusterIP 10.128.44.109 <none> 80/TCP 2d
service/kong-proxy LoadBalancer 10.128.246.165 XX.XX.XX.XX 80:31289/TCP,443:31202/TCP 6d
service/kong-validation-webhook ClusterIP 10.128.138.44 <none> 443/TCP 6d
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/dataapi 1/1 1 1 2d2h
deployment.apps/frontend 1/1 1 1 2d
deployment.apps/ingress-kong 1/1 1 1 6d
NAME DESIRED CURRENT READY AGE
replicaset.apps/dataapi-dbc8bbb69 1 1 1 2d2h
replicaset.apps/frontend-59bf9c75dc 0 0 0 25h
replicaset.apps/ingress-kong-56f8f44fd5 1 1 1 6d
'kubectl get ingresses' 给出:
NAME CLASS HOSTS (Obfuscated)
ingress-nginx <none> ***.******.com,**.********.com,**.****.com,**.******.com + 1 more... xx.xx.xxx.xx 80 6d ADDRESS PORTS AGE
kong-gateway kong * xx.xx.xxx.xx 80 2d2h
从前端来看,期望构造 http 字符串:
http://kong-proxy/dataapi/api/values
将在后端输入我们的“值”控制器并从该控制器返回文本字符串。
这两个服务都运行在同一个 kubernetes 集群上,这里使用的是 Linode。我们的想法是,它是两种类型为 ClusterIP 的两个服务之间的“集群内”通信。
Chrome 控制台报错是:
zone-evergreen.js:2828 GET http://kong-proxy/dataapi/api/values net::ERR_NAME_NOT_RESOLVED
请注意,我们发现了与我们类似的StackOverflow 问题,并且该结果中的建议是将“default.svc.cluster.local”添加到 http 字符串中,如下所示:
http://kong-proxy.default.svc.cluster.local/dataapi/api/values
这没有用。我们还将服务的命名空间 kong 替换为默认值,如下所示:
http://kong-proxy.kong.svc.cluster.local/dataapi/api/values
产生与上述相同的错误。
我是否缺少关键步骤?任何意见是极大的赞赏!
****************** Eric Gagnon 的回复更新 **************
再次感谢 Eric 的回复。这是我的同事和我根据您的建议尝试过的
- Pod dns 配置错误:检查 pod 的第一个名称服务器是否等于 'kube-dns' svc ip 以及搜索是否以 kong.svc.cluster.local 开头:
kubectl exec -i -t -n kong frontend-simple-deployment-7b8b9cfb44-f2shk -- cat /etc/resolv.conf
nameserver 10.128.0.10
search kong.svc.cluster.local svc.cluster.local cluster.local members.linode.com
options ndots:5
kubectl get -n kube-system svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.128.0.10 <none> 53/UDP,53/TCP,9153/TCP 55d
kubectl describe -n kube-system svc kube-dns
Name: kube-dns
Namespace: kube-system
Labels: k8s-app=kube-dns
kubernetes.io/cluster-service=true
kubernetes.io/name=KubeDNS
Annotations: lke.linode.com/caplke-version: v1.19.9-001
prometheus.io/port: 9153
prometheus.io/scrape: true
Selector: k8s-app=kube-dns
Type: ClusterIP
IP: 10.128.0.10
Port: dns 53/UDP
TargetPort: 53/UDP
Endpoints: 10.2.4.10:53,10.2.4.14:53
Port: dns-tcp 53/TCP
TargetPort: 53/TCP
Endpoints: 10.2.4.10:53,10.2.4.14:53
Port: metrics 9153/TCP
TargetPort: 9153/TCP
Endpoints: 10.2.4.10:9153,10.2.4.14:9153
Session Affinity: None
Events: <none>
- 应用程序不使用 pod dns:在 Node 中,将 dns.getServers() 输出到控制台
I do not understand where and how to do this. We tried to add DNS directly inside our Angular frontend app, but we found out it is not possible to add this.
- Kong-proxy 不喜欢某些东西:设置日志记录调试、多次点击应用程序以及 grep 日志。
我们在这里尝试了两个测试。首先,我们的 kong-proxy 服务可以从入口控制器访问。请注意,这不是我们简单的前端应用程序。它只不过是一个将 http 字符串传递给我们设置的公共网关的代理。这确实有效。我们通过以下方式暴露了这一点:
http://gateway.cwg.stratbore.com/test/api/test
["Successfully pinged Test controller!!"]
kubectl logs -n kong ingress-kong-56f8f44fd5-rwr9j | grep test
10.2.4.11 - - [16/Apr/2021:16:03:42 +0000] "GET /test/api/test HTTP/1.1" 200 52 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36"
So this works.
但是,当我们尝试从与后端在同一集群中运行的简单前端界面执行此操作时:
它不适用于文本框中显示的文本。此命令不会添加任何新内容:
kubectl logs -n kong ingress-kong-56f8f44fd5-rwr9j | grep test
前端返回错误。
但是如果我们添加这个 http 文本:
kong-ingress pod 被击中:
kubectl logs -n kong ingress-kong-56f8f44fd5-rwr9j | grep test
10.2.4.11 - - [16/Apr/2021:16:03:42 +0000] "GET /test/api/test HTTP/1.1" 200 52 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36"
10.2.4.11 - - [17/Apr/2021:16:55:50 +0000] "GET /test/api/test HTTP/1.1" 200 52 "http://app-basic.cwg.stratbore.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36"
但前端得到一个错误。
所以在这一点上,我们已经尝试了很多事情来让我们的前端应用程序成功地向我们的后端发送一个 http 并得到响应,但我们没有成功。我还尝试了与我们的前端应用程序一起打包的 nginx.conf 文件的各种配置,但那里也没有运气。
我将把所有这些打包到一个 github 项目中。谢谢。