vcluster icon indicating copy to clipboard operation
vcluster copied to clipboard

Point `Service` of type `ExternalName` to internal service if externalName is like `*.svc.cluster.local`

Open lucasfcnunes opened this issue 7 months ago • 6 comments

Is your feature request related to a problem?

Yes.

I need to create services that point to services in other namespaces. It doesn't work in the vcluster as it works in the host cluster.

Which solution do you suggest?

Map any VCluster Kind: Service, spec.type: ExternalName, externalName: [<pod>.][<svc>[.<namespace>]][.svc[.cluster.local|<custom_suffix>]] only to resources inside the VCluster.

*All resources are inside a vcluster created with vcluster create vcluster -n vcluster

...
---
apiVersion: v1
kind: Service
metadata:
  name: svc-a
  namespace: a
spec:
  type: ClusterIP
  ports:
    - name: http
      port: 80
      targetPort: http
  selector:
    # ...
---
apiVersion: v1
kind: Service
metadata:
  name: svc-b
  namespace: b
spec:
  type: ExternalName
  # map from:
  externalName: svc-a.a.svc.cluster.local
  # to: (right now, only this 👇 fqdn works)
  # externalName: svc-a-x-a-x-vcluster.vcluster.svc.cluster.local
  ports:
    - name: http
      port: 80
      targetPort: 80

Which alternative solutions exist?

Use e.g. svc-a-x-a-x-vcluster.vcluster.svc.cluster.local

Additional context

vcluster v0.24.1

lucasfcnunes avatar May 12 '25 18:05 lucasfcnunes

Are both ClusterIP type and ExternalName type services synced from the physical k8s?

mayooot avatar May 26 '25 09:05 mayooot

@mayooot

Are both ClusterIP type and ExternalName type services synced from the physical k8s?'

Seems so


$ kubectl --context kind-kind get svc -A
NAMESPACE     NAME                                TYPE           CLUSTER-IP      EXTERNAL-IP                 PORT(S)                  AGE
default       kubernetes                          ClusterIP      10.96.0.1       <none>                      443/TCP                  130m
kube-system   kube-dns                            ClusterIP      10.96.0.10      <none>                      53/UDP,53/TCP,9153/TCP   130m
vcluster      kube-dns-x-kube-system-x-vcluster   ClusterIP      10.96.126.182   <none>                      53/UDP,53/TCP,9153/TCP   6m52s
vcluster      svc-a-x-a-x-vcluster                ClusterIP      10.96.235.165   <none>                      80/TCP                   57s
vcluster      svc-b-x-b-x-vcluster                ExternalName   <none>          svc-a.a.svc.cluster.local   80/TCP                   57s
vcluster      vcluster                            ClusterIP      10.96.116.14    <none>                      443/TCP,10250/TCP        7m39s
vcluster      vcluster-headless                   ClusterIP      None            <none>                      443/TCP                  7m39s
vcluster      vcluster-node-kind-control-plane    ClusterIP      10.96.97.89     <none>                      10250/TCP                6m52s
$ kubectl --context vcluster_vcluster_vcluster_kind-kind get svc -A
NAMESPACE     NAME         TYPE           CLUSTER-IP      EXTERNAL-IP                 PORT(S)                  AGE
a             svc-a        ClusterIP      10.96.235.165   <none>                      80/TCP                   2m30s
b             svc-b        ExternalName   <none>          svc-a.a.svc.cluster.local   80/TCP                   2m30s
default       kubernetes   ClusterIP      10.96.116.14    <none>                      443/TCP                  8m25s
kube-system   kube-dns     ClusterIP      10.96.126.182   <none>                      53/UDP,53/TCP,9153/TCP   8m25s
$ kubectl --context vcluster_vcluster_vcluster_kind-kind run tmp-shell --restart=Never --rm -it --image arunvelsriram/utils -- dig A svc-b.b.svc.cluster.local +short
svc-a.a.svc.cluster.local.
10.96.235.165
pod "tmp-shell" deleted
$ kubectl --context kind-kind run tmp-shell --restart=Never --rm -it --image arunvelsriram/utils -- dig A svc-b-x-b-x-vcluster.vcluster.svc.cluster.local +short
# >>> no result. should return `svc-a-x-a-x-vcluster.vcluster.svc.cluster.local` so that the ingress controller on the host works
pod "tmp-shell" deleted

The behavior I want only works after

$ kubectl --context vcluster_vcluster_vcluster_kind-kind -n b patch svc/svc-b --patch='{"spec":{"externalName":"svc-a-x-a-x-vcluster.vcluster.svc.cluster.local"}}'
service/svc-b patched
$ kubectl --context kind-kind run tmp-shell --restart=Never --rm -it --image arunvelsriram/utils -- dig A svc-b-x-b-x-vcluster.vcluster.svc.cluster.local +short
svc-a-x-a-x-vcluster.vcluster.svc.cluster.local.
10.96.235.165
pod "tmp-shell" deleted
$ kubectl --context vcluster_vcluster_vcluster_kind-kind run tmp-shell --restart=Never --rm -it --image arunvelsriram/utils -- dig A svc-b.b.svc.cluster.local +short
# >>> BUT breaks inside vcluster
pod "tmp-shell" deleted

lucasfcnunes avatar May 26 '25 17:05 lucasfcnunes

The behavior I want only works after

$ kubectl --context vcluster_vcluster_vcluster_kind-kind -n b patch svc/svc-b --patch='{"spec":{"externalName":"svc-a-x-a-x-vcluster.vcluster.svc.cluster.local"}}'
service/svc-b patched
$ kubectl --context kind-kind run tmp-shell --restart=Never --rm -it --image arunvelsriram/utils -- dig A svc-b-x-b-x-vcluster.vcluster.svc.cluster.local +short
svc-a-x-a-x-vcluster.vcluster.svc.cluster.local.
10.96.235.165
pod "tmp-shell" deleted

When you update the ExternalName type service within the vcluster, this will be result in the ExternalName type service being unavilable in the vcluster?

mayooot avatar May 27 '25 03:05 mayooot

Overall, our requiremente is to use Service synchronized from vcluster in physical cluster.

I read the source code and the general idea is as follows:

  1. modify pkg/controllers/resources/services below the file, in the synchronization Service judgment vObj.Spec.Type == corev1.ServiceTypeExternalName && vObj.Spec.ExternalName has ".svc.cluster.local" .
  2. find out whether the Service pointed by ExternalName exists in Vcluster. If so, change the value of ExternalName, update and to the format with '-x-' . If not, don't change it.

@lucasfcnunes @matskiv Does this look good to you?

mayooot avatar May 27 '25 07:05 mayooot

@mayooot

When you update the ExternalName type service within the vcluster, this will be result in the ExternalName type service being unavilable in the vcluster?

Yep. It breaks. *I edited my comment to add this case.

modify pkg/controllers/resources/services below the file, in the synchronization Service judgment vObj.Spec.Type == corev1.ServiceTypeExternalName && vObj.Spec.ExternalName has ".svc.cluster.local" .

Seems the way to go. Notice that the complete service hostname string can be as complex as follows [<pod>.][<svc>[.<namespace>]][.svc[.cluster.local|<custom_suffix>]].

lucasfcnunes avatar May 27 '25 17:05 lucasfcnunes

Hi, Is this being worked upon? I can take it up otherwise.

azgartaj avatar Nov 06 '25 17:11 azgartaj