簡體   English   中英

用於對另一個 Kube.netes 容器的 GET 請求的正確 URL 是什么?

[英]What is the correct URL to use for GET requests to another Kubernetes container?

我正在嘗試創建一個簡單的微服務,其中一個 Docker 容器中的 JQuery 應用程序使用此代碼從在不同容器中運行的另一個(分析)應用程序獲取 JSON object:

<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> 

另一個應用程序將其用於Deployment containerPort。

  ports:
    - containerPort: 8082

這些用於Service端口。

  type: ClusterIP
  ports:
    - targetPort: 8082
      port: 8084   

“分析”應用程序是一個監聽 8082 的 golang 程序。

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

在 Minikube 上運行時,我遇到了 CORS 的問題,當返回 JSON object 作為響應時,通過在 golang 代碼中使用它解決了這個問題:

w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type") 

所有這些在 Minikube 上運行良好(盡管在 Minikube 中我使用的是localhost:8082 )。 第一個應用程序將向http://localhost:8084/productinfo發送 GET 請求,第二個應用程序將返回 JSON object。

但是當我通過以下方式訪問第一個應用程序在雲 Kube.netes 設置上嘗試它時:,當我打開瀏覽器控制台時,我不斷收到錯誤Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8084/productinfo

問題:為什么它在 Minikube 上工作而不在雲 Kube.netes 工作節點上工作? 使用localhost是訪問另一個容器的正確方法嗎? 我怎樣才能讓它工作? 實施微服務的人如何跨容器使用他們的 GET 和 POST 請求? 我找到的所有微服務示例都是為 Minikube 上的簡單演示而構建的,因此很難掌握這種細微差別。

@P....絕對正確,我只想提供更多關於DNS 的詳細信息,以了解同一 Pod 中容器之間的服務和通信。

DNS 服務

正如我們在文檔中所見,Kube.netes 服務被分配了一條 DNS A(或 AAAA)記錄,其名稱格式為<serviceName>.<namespaceName>.svc.<cluster-domain> 這將解析為服務的集群 IP。

“正常”(非無頭)服務分配有 DNS A 或 AAAA 記錄,具體取決於服務的 IP 系列,名稱格式為 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><serviceName>.<namespaceName>.svc或 FQDN <serviceName>.<namespaceName>.svc.<cluster-domain>

如果服務在不同的命名空間中,單個<serviceName>是不夠的,我們需要使用<serviceName>.<namespaceName> (我們也可以使用: <serviceName>.<namespaceName>.svc<serviceName>.<namespaceName>.svc.<cluster-domain> )。

在以下示例中, app-1app-2在同一命名空間中, app-2在端口8084上通過 ClusterIP 公開(如您的情況):

$ 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

注意: app-2app-1在同一個命名空間中,因此我們可以使用<serviceName>app-1訪問它,您還可以注意到我們獲得了app-2的 FQDN ( app-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

注意:我們需要提供端口號,因為app-2正在偵聽8084

root@app-1:/# curl app-2.default.svc.cluster.local:8084
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

讓我們在不同的命名空間中創建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

注意:使用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>
...

同一 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

我們可以連接到alpine-container容器並檢查我們是否可以使用localhost訪問位於nginx-container中的 nginx web 服務器:

$ 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>
...

有關同一 Pod 中容器之間通信的更多信息,請參見此處

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM