用于向另一个 Kubernetes 容器发出 GET 请求的正确 URL 是什么?

Nav*_*Nav 1 docker kubernetes minikube

我正在尝试创建一个简单的微服务,其中一个 Docker 容器中的 JQuery 应用程序使用此代码从在不同容器中运行的另一个(分析)应用程序获取 JSON 对象:

<script type="text/javascript">
$(document).ready(function(){
$('#get-info-btn').click(function(){
  $.get("http://localhost:8084/productinfo", 
  function(data, status){          
    $.each(data, function(i, obj) {
      //some code
    });   
  });
});
});
</script> 
Run Code Online (Sandbox Code Playgroud)

另一个应用程序将其用于Deployment容器端口。

  ports:
    - containerPort: 8082
Run Code Online (Sandbox Code Playgroud)

这些是针对Service港口的。

  type: ClusterIP
  ports:
    - targetPort: 8082
      port: 8084   
Run Code Online (Sandbox Code Playgroud)

“analytics”应用程序是一个监听 8082 的 golang 程序。

func main() {
    http.HandleFunc("/productinfo", getInfoJSON)    
    log.Fatal(http.ListenAndServe(":8082", nil))
}
Run Code Online (Sandbox Code Playgroud)

当在 Minikube 上运行这个时,我遇到了 CORS 问题,通过在 golang 代码中返回 JSON 对象作为响应时使用它来解决这个问题:

w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type") 
Run Code Online (Sandbox Code Playgroud)

所有这些在 Minikube 上都运行良好(尽管在 Minikube 中我使用的是localhost:8082)。第一个应用程序将发送 GET 请求http://localhost:8084/productinfo,第二个应用程序将返回一个 JSON 对象。

但是,当我通过 : 访问第一个应用程序在云 Kubernetes 设置上尝试它时,当我打开浏览器控制台时,我不断收到错误Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8084/productinfo

问: 为什么在 Minikube 上可以运行,但在云 Kubernetes Worker 节点上却不行?是否使用localhost正确的方式访问另一个容器?我怎样才能让它发挥作用?实现微服务的人们如何跨容器使用 GET 和 POST 请求?我发现的所有微服务示例都是为 Minikube 上的简单演示而构建的,因此很难掌握这种细微差别。

mat*_*t_j 5

@P....绝对正确,我只想提供有关DNS 服务以及同一 Pod 中容器之间通信的更多详细信息。

服务 DNS

正如我们在文档中可以找到的,Kubernetes 服务被分配了一条 DNS A(或 AAAA)记录,其名称形式为<serviceName>.<namespaceName>.svc.<cluster-domain>. 这将解析为服务的集群 IP。

根据服务的 IP 系列,为“正常”(非无头)服务分配 DNS A 或 AAAA 记录,其名称格式为 my-svc.my-namespace.svc.cluster-domain.example。这将解析为服务的集群 IP。

让我们将表格分解<serviceName>.<namespaceName>.svc.<cluster-domain>为各个部分:

  • <serviceName>- 您要连接的服务的名称。

  • <namespaceName>- 您要连接的服务所在的命名空间的名称。

  • svc- 不应更改 -svc代表服务。

  • <cluster-domain>- 集群域,默认为cluster.local.

我们可以用来<serviceName>访问同一命名空间中的服务,但是我们也可以使用<serviceName>.<namespaceName>or<serviceName>.<namespaceName>.svc或 FQDN <serviceName>.<namespaceName>.svc.<cluster-domain>

如果Service位于不同的Namespace中,单个<serviceName>是不够的,我们需要使用 <serviceName>.<namespaceName>(我们也可以使用:<serviceName>.<namespaceName>.svc<serviceName>.<namespaceName>.svc.<cluster-domain>)。

在以下示例中,app-1app-2位于同一命名空间中,并app-2通过端口上的 ClusterIP 公开8084(如您的情况):

$ kubectl run app-1 --image=nginx
pod/app-1 created

$ kubectl run app-2 --image=nginx
pod/app-2 created

$ kubectl expose pod app-2 --target-port=80 --port=8084
service/app-2 exposed

$ kubectl get pod,svc
NAME        READY   STATUS    RESTARTS   AGE
pod/app-1   1/1     Running   0          45s
pod/app-2   1/1     Running   0          41s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
service/app-2        ClusterIP   10.8.12.83   <none>        8084/TCP   36s
Run Code Online (Sandbox Code Playgroud)

注意:app-2位于同一命名空间中app-1,因此我们可以 <serviceName>从 访问它,您还可以注意到我们获得了( )app-1的 FQDN :app-2app-2.default.svc.cluster.local

$ kubectl exec -it app-1 -- bash
root@app-1:/# nslookup app-2
Server:         10.8.0.10
Address:        10.8.0.10#53

Name:   app-2.default.svc.cluster.local
Address: 10.8.12.83
Run Code Online (Sandbox Code Playgroud)

注意:我们需要提供端口号,因为app-2正在侦听8084

root@app-1:/# curl app-2.default.svc.cluster.local:8084
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
Run Code Online (Sandbox Code Playgroud)

让我们app-3在不同的命名空间中创建并查看如何从以下位置连接到它app-1

$ kubectl create ns test-namespace
namespace/test-namespace created

$ kubectl run app-3 --image=nginx -n test-namespace
pod/app-3 created

$ kubectl expose pod app-3 --target-port=80 --port=8084 -n test-namespace
service/app-3 exposed
Run Code Online (Sandbox Code Playgroud)

注意:使用app-3( ) 还不够,我们还需要提供( ) 所在的<serviceName>命名空间的名称:app-3<serviceName>.<namespaceName>

# nslookup app-3
Server:         10.8.0.10
Address:        10.8.0.10#53

** server can't find app-3: NXDOMAIN

# nslookup app-3.test-namespace
Server:         10.8.0.10
Address:        10.8.0.10#53

Name:   app-3.test-namespace.svc.cluster.local
Address: 10.8.12.250

# curl app-3.test-namespace.svc.cluster.local:8084
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
Run Code Online (Sandbox Code Playgroud)

同一 Pod 中容器之间的通信

我们可以用来localhost与其他容器通信,但只能在同一个 Pod(多容器 pod)内进行。

我创建了一个简单的多容器 Pod,其中包含两个容器:nginx-containeralpine-container

$ cat multi-container-app.yml
apiVersion: v1
kind: Pod
metadata:
  name: multi-container-app
spec:
  containers:
  - image: nginx
    name: nginx-container
  - image: alpine
    name: alpine-container
    command: ["sleep", "3600"]

$ kubectl apply -f multi-container-app.yml
pod/multi-container-app created
Run Code Online (Sandbox Code Playgroud)

我们可以连接到容器并检查是否可以访问位于以下位置alpine-container的 nginx Web 服务器:nginx-containerlocalhost

$ kubectl exec -it multi-container-app -c alpine-container -- sh

/ # netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -
tcp        0      0 :::80                   :::*                    LISTEN      -

/ # curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
Run Code Online (Sandbox Code Playgroud)

有关同一 Pod 中容器之间通信的更多信息可以在此处找到。