【问题标题】:Istio direct Pod to Pod communicationIstio 直接 Pod 到 Pod 通信
【发布时间】:2019-04-01 12:48:45
【问题描述】:

我在使用 Istio 部署的 Pod 与 Pod 的通信时遇到问题?我实际上需要它到make Hazelcast discovery working with Istio,但我会尝试在这里概括这个问题。

让我们在 Kubernetes 上部署一个示例 hello world 服务。服务在 8000 端口上响应 HTTP 请求。

$ kubectl create deployment nginx --image=crccheck/hello-world

创建的 Pod 分配了一个内部 IP:

$ kubectl get pods -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP           NODE                                                  NOMINATED NODE
hello-deployment-84d876dfd-s6r5w   1/1     Running   0          8m    10.20.3.32   gke-rafal-test-istio-1-0-default-pool-91f437a3-cf5d   <none>

在jobcurl.yaml中,我们可以直接使用Pod IP。

apiVersion: batch/v1
kind: Job
metadata:
  name: curl
spec:
  template:
    spec:
      containers:
      - name: curl
        image: byrnedo/alpine-curl
        command: ["curl",  "10.20.3.32:8000"]
      restartPolicy: Never
  backoffLimit: 4

在没有 Istio 的情况下运行作业可以正常工作。

$ kubectl apply -f curl.yaml
$ kubectl logs pod/curl-pptlm
...
Hello World
...

但是,当我尝试对 Istio 执行相同操作时,它不起作用。 HTTP 请求被 Envoy 阻止。

$ kubectl apply -f <(istioctl kube-inject -f curl.yaml)
$ kubectl logs pod/curl-s2bj6 curl
...
curl: (7) Failed to connect to 10.20.3.32 port 8000: Connection refused

我使用过服务条目、MESH_INTERNAL 和 MESH_EXTERNAL,但没有成功。如何绕过 Envoy 直接调用 Pod?


编辑:istioctl kube-inject -f curl.yaml 的输出。

$ istioctl kube-inject -f curl.yaml
apiVersion: batch/v1
kind: Job
metadata:
  creationTimestamp: null
  name: curl
spec:
  backoffLimit: 4
  template:
    metadata:
      annotations:
        sidecar.istio.io/status: '{"version":"dbf2d95ff300e5043b4032ed912ac004974947cdd058b08bade744c15916ba6a","initContainers":["istio-init"],"containers":["istio-proxy"],"volumes":["istio-envoy","istio-certs"],"imagePullSecrets":null}'
      creationTimestamp: null
    spec:
      containers:
      - command:
        - curl
        - 10.16.2.34:8000/
        image: byrnedo/alpine-curl
        name: curl
        resources: {}
      - args:
        - proxy
        - sidecar
        - --domain
        - $(POD_NAMESPACE).svc.cluster.local
        - --configPath
        - /etc/istio/proxy
        - --binaryPath
        - /usr/local/bin/envoy
        - --serviceCluster
        - curl.default
        - --drainDuration
        - 45s
        - --parentShutdownDuration
        - 1m0s
        - --discoveryAddress
        - istio-pilot.istio-system:15010
        - --zipkinAddress
        - zipkin.istio-system:9411
        - --connectTimeout
        - 10s
        - --proxyAdminPort
        - "15000"
        - --concurrency
        - "2"
        - --controlPlaneAuthPolicy
        - NONE
        - --statusPort
        - "15020"
        - --applicationPorts
        - ""
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: INSTANCE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: ISTIO_META_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: ISTIO_META_CONFIG_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: ISTIO_META_INTERCEPTION_MODE
          value: REDIRECT
        image: docker.io/istio/proxyv2:1.1.1
        imagePullPolicy: IfNotPresent
        name: istio-proxy
        ports:
        - containerPort: 15090
          name: http-envoy-prom
          protocol: TCP
        readinessProbe:
          failureThreshold: 30
          httpGet:
            path: /healthz/ready
            port: 15020
          initialDelaySeconds: 1
          periodSeconds: 2
        resources:
          limits:
            cpu: "2"
            memory: 128Mi
          requests:
            cpu: 100m
            memory: 128Mi
        securityContext:
          readOnlyRootFilesystem: true
          runAsUser: 1337
        volumeMounts:
        - mountPath: /etc/istio/proxy
          name: istio-envoy
        - mountPath: /etc/certs/
          name: istio-certs
          readOnly: true
      initContainers:
      - args:
        - -p
        - "15001"
        - -u
        - "1337"
        - -m
        - REDIRECT
        - -i
        - '*'
        - -x
        - ""
        - -b
        - ""
        - -d
        - "15020"
        image: docker.io/istio/proxy_init:1.1.1
        imagePullPolicy: IfNotPresent
        name: istio-init
        resources:
          limits:
            cpu: 100m
            memory: 50Mi
          requests:
            cpu: 10m
            memory: 10Mi
        securityContext:
          capabilities:
            add:
            - NET_ADMIN
      restartPolicy: Never
      volumes:
      - emptyDir:
          medium: Memory
        name: istio-envoy
      - name: istio-certs
        secret:
          optional: true
          secretName: istio.default
status: {}
---

【问题讨论】:

  • 两个 pod 都注入了​​ istio side car?
  • 不,只是第二个 (curl)。但是,如果两者都注入了 Istio,它也不起作用。
  • 如果一个 pod 没有 Istio,它会解释为什么它无法通信,低于 1.1 的 Istio 版本不允许在没有“ExternalService”资源的情况下连接到网格之外。当两个 pod 都注入 instio 时,您是否看到相同的错误?
  • 是的,当两个 Pod 都安装了 Istio 时,我遇到了同样的问题。另外,我尝试使用最新的 Istio 版本(1.1.1),所以如果我理解正确,我不必指定任何 ExternalService
  • 嗨。我认为 istio 不允许在 pod 之间直接通信,但它可以在服务之间工作。

标签: kubernetes istio


【解决方案1】:

当一个带有 istio side car 的 pod 启动时,会发生以下事情

  1. 一个 init 容器更改了 iptables 规则,以便所有传出的 tcp 流量都被路由到端口 15001 上的 sidecar 容器 (istio-proxy)。

  2. pod 的容器并行启动(curlistio-proxy

如果您的 curl 容器在 istio-proxy 侦听端口 15001 之前执行,则会出现错误。

我用 sleep 命令启动了这个容器,exec-d 进入容器并且 curl 工作了。

$ kubectl apply -f <(istioctl kube-inject -f curl-pod.yaml)

$ k exec -it -n noistio curl -c curl bash
[root@curl /]# curl 172.16.249.198:8000
<xmp>
Hello World


                                       ##         .
                                 ## ## ##        ==
                              ## ## ## ## ##    ===
                           /""""""""""""""""\___/ ===
                      ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~
                           \______ o          _,/
                            \      \       _,'
                             `'--.._\..--''
</xmp>
[root@curl /]# 

curl-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: curl
spec:
  containers:
  - name: curl
    image: centos
    command: ["sleep",  "3600"]

【讨论】:

  • 我明白了,这正是我所需要的!谢谢@christian。你认为这是一个应该作为 GH 问题报告给 istio/istio 的错误吗?或者它是一种已知的行为?
  • 错误听起来很难。我宁愿说这是应用程序容器和 istio sidecar 之间的新依赖关系,并且使用 istio 不像我希望的那样透明。
【解决方案2】:

确保您已配置入口“网关”,然后您需要配置“虚拟服务”。有关简单示例,请参见下面的链接。

https://istio.io/docs/tasks/traffic-management/ingress/#configuring-ingress-using-an-istio-gateway

一旦您部署了网关和虚拟服务,您应该能够从外部 IP 的集群外部“卷曲”您的服务。

但是如果你想检查来自集群 INSIDE 的流量,你需要使用 istio 的镜像 API 将服务(pod)从一个 pod 镜像到另一个 pod,然后使用你的命令( kubectl apply -f curl.yaml) 查看流量。

镜像示例见以下链接:

https://istio.io/docs/tasks/traffic-management/mirroring/

希望对你有帮助

【讨论】:

  • 感谢@dgant1024 的回答。如果我理解正确,如果您想从外部访问 Pod/Service(位于 Istio 集群内部),则网关是相反的。我需要反过来,我需要从 INSIDE 访问。我检查了镜像,但它似乎镜像(克隆流量)到另一个 Pod,但我不需要克隆流量,只需通过其 IP 地址访问 Pod。喜欢绕过 Istio 并能够直接通信。
  • 您的意思是要执行到位于已由 istio-proxy 注入的 pod 中的容器中? (例如:kubectl exec -it -c -n -- /bin/bash)
  • 不,我想做的只是通过 IP 地址访问 Pod(假设两个 Pod 都在 Istio 中)。假设 Pod 1 具有 IP:10.0.0.4,那么我希望能够通过 curl 10.0.0.4 从另一个 Pod 访问它。但是被特使挡住了。
猜你喜欢
  • 2022-01-08
  • 2020-07-19
  • 2020-04-20
  • 1970-01-01
  • 2020-01-16
  • 1970-01-01
  • 2019-06-21
  • 1970-01-01
  • 2019-06-23
相关资源
最近更新 更多