配置 Istio、Kubernetes 和 MetalLB 以使用 Istio LoadBalancer

Configuring Istio, Kubernetes and MetalLB to use a Istio LoadBalancer

我正在为在裸机实例上使用 MetalLB、Kubernetes、Istio 配置的最后一步而苦苦挣扎,那就是通过 Istio VirtualService 路由从服务向外界返回一个网页.我刚刚将实例更新为

我将从有效的开始。

所有补充服务都已部署,大部分都在运行:

  1. http://localhost:8001
  2. 上的 Kubernetes 仪表板
  3. http://localhost:10010 上的 Prometheus Dashboard(我在 9009 上有其他东西)
  4. 特使管理员 http://localhost:15000
  5. http://localhost:3000
  6. 上的 Grafana(Istio 仪表板)
  7. Jaeger http://localhost:16686

我说最多是因为自升级到 Istio 1.0.3 以来,我在 Jaeger 仪表板中丢失了来自 istio-ingressgateway 的遥测数据,我不确定如何将其恢复。我已经删除了 pod 并重新创建了无用。

除此之外,MetalLB 和 K8S 似乎工作正常并且负载均衡器配置正确(使用 ARP)。

kubectl get svc -n istio-system
NAME                     TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                                                                                                   AGE
grafana                  ClusterIP      10.109.247.149   <none>          3000/TCP                                                                                                                  9d
istio-citadel            ClusterIP      10.110.129.92    <none>          8060/TCP,9093/TCP                                                                                                         28d
istio-egressgateway      ClusterIP      10.99.39.29      <none>          80/TCP,443/TCP                                                                                                            28d
istio-galley             ClusterIP      10.98.219.217    <none>          443/TCP,9093/TCP                                                                                                          28d
istio-ingressgateway     LoadBalancer   10.108.175.231   192.168.1.191   80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:30805/TCP,8060:32514/TCP,853:30601/TCP,15030:31159/TCP,15031:31838/TCP   28d
istio-pilot              ClusterIP      10.97.248.195    <none>          15010/TCP,15011/TCP,8080/TCP,9093/TCP                                                                                     28d
istio-policy             ClusterIP      10.98.133.209    <none>          9091/TCP,15004/TCP,9093/TCP                                                                                               28d
istio-sidecar-injector   ClusterIP      10.102.158.147   <none>          443/TCP                                                                                                                   28d
istio-telemetry          ClusterIP      10.103.141.244   <none>          9091/TCP,15004/TCP,9093/TCP,42422/TCP                                                                                     28d
jaeger-agent             ClusterIP      None             <none>          5775/UDP,6831/UDP,6832/UDP,5778/TCP                                                                                       27h
jaeger-collector         ClusterIP      10.104.66.65     <none>          14267/TCP,14268/TCP,9411/TCP                                                                                              27h
jaeger-query             LoadBalancer   10.97.70.76      192.168.1.193   80:30516/TCP                                                                                                              27h
prometheus               ClusterIP      10.105.176.245   <none>          9090/TCP                                                                                                                  28d
zipkin                   ClusterIP      None             <none>          9411/TCP                                                                                                                  27h

我可以使用以下方式公开我的部署:

kubectl expose deployment enrich-dev --type=LoadBalancer --name=enrich-expose

一切正常,我可以从外部负载平衡 IP 地址访问网页(此后我删除了暴露的服务)。

NAME             TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)           AGE
enrich-expose    LoadBalancer   10.108.43.157   192.168.1.192   31380:30170/TCP   73s
enrich-service   ClusterIP      10.98.163.217   <none>          80/TCP            57m
kubernetes       ClusterIP      10.96.0.1       <none>          443/TCP           36d

如果我在默认命名空间中创建一个 K8S 服务(我已经尝试了多个)

apiVersion: v1
kind: Service
metadata:
  name: enrich-service
  labels:
    run: enrich-service
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
  selector:
    app: enrich

后面是网关和路由 (VirtualService),我得到的唯一响应是网格外的 404。您会在网关中看到我使用的是保留字 mesh,但我已经尝试过这两种方法并命名了特定的网关。我还为特定的 URI 和您在下面看到的端口尝试了不同的匹配前缀。

网关

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: enrich-dev-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"

虚拟服务

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: enrich-virtualservice
spec:
  hosts:
  - "enrich-service.default"
  gateways:
  - mesh
  http:
  - match:
    - port: 80
    route:
    - destination:
        host: enrich-service.default
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: enrich-destination
spec:
  host: enrich-service.default
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
  subsets:
  - name: v1
    labels:
      app: enrich

我已经仔细检查过这不是 DNS 在播放,因为我可以通过 busybox 或使用 K8S 仪表板进入入口网关的 shell

http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/shell/istio-system/istio-ingressgateway-6bbdd58f8c-glzvx/?namespace=istio-system

并同时执行

nslookup enrich-service.default

curl -f http://enrich-service.default/

并且都成功运行,所以我知道 ingress-gateway pod 可以看到这些。 sidecars 在默认命名空间和 istio-system 命名空间中设置为自动注入。

入口网关的日志显示 404:

[2018-11-01T03:07:54.351Z] "GET /metadataHTTP/1.1" 404 - 0 0 1 - "192.168.1.90" "curl/7.58.0" "6c1796be-0791-4a07-ac0a-5fb07bc3818c" "enrich-service.default" "-" - - 192.168.224.168:80 192.168.1.90:43500
[2018-11-01T03:26:39.339Z] "GET /HTTP/1.1" 404 - 0 0 1 - "192.168.1.90" "curl/7.58.0" "ed956af4-77b0-46e6-bd26-c153e29837d7" "enrich-service.default" "-" - - 192.168.224.168:80 192.168.1.90:53960

192.168.224.168:80是网关的IP地址。 192.168.1.90:53960是我外部客户端的IP地址。

任何建议,我已经尝试从多个角度解决这个问题几天了,我觉得我只是缺少一些简单的东西。建议查看日志?

只是为了解决我的实例中的问题而关闭这个问题。配置错误一直追溯到 Kubernetes 集群初始化。我申请了:

kubeadm init --pod-network-cidr=n.n.n.n/n --apiserver-advertise-address 0.0.0.0

pod-network-cidr 使用与部署 Kubernetes 安装的本地 LAN 相同的地址范围,即 Ubuntu 主机的桌面使用与我分配的相同的 IP 子网容器网络。

在大多数情况下,如上所述,一切都运行良好,直到 Istio 代理尝试将数据包从外部负载均衡器 IP 地址路由到恰好位于同一子网上的内部 IP 地址。带有 Kubernetes 的 Calico 项目似乎能够应对它,因为它实际上是第 3/4 层策略,但 Istio 在 L7 上遇到了问题(即使它位于下面的 Calico 上)。

解决方案是拆除我的整个 Kubernetes 部署。我很偏执,甚至卸载 Kubernetes 并再次部署并重新部署 172 范围内的 pod 网络,这与我的本地 lan 没有任何关系。我还在 Project Calico 配置文件中进行了相同的更改以匹配 pod 网络。更改之后,一切都按预期运行。

我怀疑在更多 public 配置中,您的集群直接连接到 BGP 路由器,而不是使用具有 L2 配置的 MetalLB 作为 LAN 的子集,也不会出现此问题。我在 post:

中对此进行了更多记录

Microservices: .Net, Linux, Kubernetes and Istio make a powerful combination