envoyproxy / gateway

Manages Envoy Proxy as a Standalone or Kubernetes-based Application Gateway
https://gateway.envoyproxy.io
Apache License 2.0
1.46k stars 300 forks source link

egctl translate doesn't work if clusterIP is not present in k8s Service #3707

Closed luvk1412 closed 1 week ago

luvk1412 commented 2 weeks ago

Description:

When using egctl to translate from k8s config to xDS config, if a clusterIP is not mentioned in Service, then translation fails but if I add a clusterIP the translation succeeds. To me it looks like a bug because clusterIP is not a requirement in k8s config and i am not sure why it should be required here.

Repro steps:

cat <<EOF | egctl x translate --from gateway-api --to xds -f -
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: eg
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: eg
spec:
  gatewayClassName: eg
  listeners:
    - name: http
      protocol: HTTP
      port: 80
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: backend
---
apiVersion: v1
kind: Service
metadata:
  name: backend
  labels:
    app: backend1
    service: backend1
spec:
  ports:
    - name: http
      port: 8080
      targetPort: 8080
  selector:
    app: backend
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: routes
spec:
  parentRefs:
    - name: eg
  rules:
    - backendRefs:
        - group: ""
          kind: Service
          name: backend
          port: 8080
      matches:
        - path:
            type: PathPrefix
            value: /service
EOF

fails with below error

Error: failed to translate xds ir for key envoy-gateway-system/eg value &{AccessLog:0x14000694730 Tracing:<nil> Metrics:<nil> HTTP:[0x140006bc000] TCP:[] UDP:[] EnvoyPatchPolicies:[] FilterOrder:[]}, error:validation failed for xds resource cluster_name:"httproute/envoy-gateway-system/routes/rule/0" endpoints:{locality:{region:"httproute/envoy-gateway-system/routes/rule/0/backend/0"} lb_endpoints:{endpoint:{address:{socket_address:{port_value:8080}}} load_balancing_weight:{value:1}} load_balancing_weight:{value:1}}, err: invalid ClusterLoadAssignment.Endpoints[0]: embedded message failed validation | caused by: invalid LocalityLbEndpoints.LbEndpoints[0]: embedded message failed validation | caused by: invalid LbEndpoint.Endpoint: embedded message failed validation | caused by: invalid Endpoint.Address: embedded message failed validation | caused by: invalid Address.SocketAddress: embedded message failed validation | caused by: invalid SocketAddress.Address: value length must be at least 1 runes
failed to translate xds ir for key envoy-gateway-system/eg value &{AccessLog:0x14000694730 Tracing:<nil> Metrics:<nil> HTTP:[0x140006bc000] TCP:[] UDP:[] EnvoyPatchPolicies:[] FilterOrder:[]}, error:validation failed for xds resource cluster_name:"httproute/envoy-gateway-system/routes/rule/0" endpoints:{locality:{region:"httproute/envoy-gateway-system/routes/rule/0/backend/0"} lb_endpoints:{endpoint:{address:{socket_address:{port_value:8080}}} load_balancing_weight:{value:1}} load_balancing_weight:{value:1}}, err: invalid ClusterLoadAssignment.Endpoints[0]: embedded message failed validation | caused by: invalid LocalityLbEndpoints.LbEndpoints[0]: embedded message failed validation | caused by: invalid LbEndpoint.Endpoint: embedded message failed validation | caused by: invalid Endpoint.Address: embedded message failed validation | caused by: invalid Address.SocketAddress: embedded message failed validation | caused by: invalid SocketAddress.Address: value length must be at least 1 runes

Following command works

cat <<EOF | egctl x translate --from gateway-api --to xds -f -
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: eg
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: eg
spec:
  gatewayClassName: eg
  listeners:
    - name: http
      protocol: HTTP
      port: 80
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: backend
---
apiVersion: v1
kind: Service
metadata:
  name: backend
  labels:
    app: backend1
    service: backend1
spec:
  clusterIP: 10.0.171.239
  ports:
    - name: http
      port: 8080
      targetPort: 8080
  selector:
    app: backend
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: routes
spec:
  parentRefs:
    - name: eg
  rules:
    - backendRefs:
        - group: ""
          kind: Service
          name: backend
          port: 8080
      matches:
        - path:
            type: PathPrefix
            value: /service
EOF
shawnh2 commented 2 weeks ago

egctl translate command treats input yaml files as it generated by k8s, so it's normal to have clusterIP populated.

But I think this can be improved by not requiring users to set clusterIP explicitly, egctl should fill a dummy IP for those Service that missing clusterIP settings.