clusterlink-net / clusterlink

A Gateway for connecting application services in different domains, networks, and cloud infrastructures
https://clusterlink.net
Other
17 stars 18 forks source link

Add CoreDNS rewrite support for external services. #656

Open aviweit opened 2 weeks ago

aviweit commented 2 weeks ago

This PR deals with updating CoreDNS configuration to rewrite/resolve external names as described in issue #26.

Fixes #26

aviweit commented 2 weeks ago

End to end tests were made with two EKS AWS clusters with three Import CRs:

  1. internal nginx service
  2. external s3 using vpe dns name
  3. external lambda using vpe dns name

these CRs had been added and removed during the tests - to ensure coredns configmap is properly updated.

It was also tested with two local kind clusters ensuring that coredns is properly updated.

Thanks.

orozery commented 1 week ago

@aviweit can you give examples of aliases (those you set in Import.spec.alias) for your use-case?

aviweit commented 1 week ago

@aviweit can you give examples of aliases (those you set in Import.spec.alias) for your use-case?

@orozery ,

aviweit commented 1 week ago

The PR is set with the discussed changes.

It was tested with kind and AWS EKS clusters.

Thanks.

aviweit commented 1 week ago

I have tested this PR with two kind clusters using various Import CRs some of them with invalid alias:

  1. during the rollout (patch) there is always at least one coredns pod in running state; I am able to curl www.google.com
  2. if the coredns pods fail to start, there is still at least one pod in running state (probably being configured with the old version of config map); if additional Imports are being added, configmap is updated, however, the running coredns pod still uses the old good version
  3. when deleting the corrupted Import CR(s), rollout is success and coredns pods are available and the other Imports that are valid, can be served.
echo "
apiVersion: clusterlink.net/v1alpha1
kind: Import
metadata:
  name: nginx-project
  namespace: default
spec:
  port:  80
  alias: www.example.com
  sources:
    - exportName:       nginx-project
      exportNamespace:  default
      peer:             cl-peer1
" | kubectl --kubeconfig ~/.kube/cl-peer2 apply -f -
echo "
apiVersion: clusterlink.net/v1alpha1
kind: Import
metadata:
  name: nginx-project-wildcard
  namespace: default
spec:
  port:  80
  alias: \"*.wildcard.example.com\"
  sources:
    - exportName:       nginx-project
      exportNamespace:  default
      peer:             cl-peer1
" | kubectl --kubeconfig ~/.kube/cl-peer2 apply -f -
echo "
apiVersion: clusterlink.net/v1alpha1
kind: Import
metadata:
  name: nginx-project-another
  namespace: default
spec:
  port:  80
  alias: www.example-another.com
  sources:
    - exportName:       nginx-project
      exportNamespace:  default
      peer:             cl-peer1
" | kubectl --kubeconfig ~/.kube/cl-peer2 apply -f -
echo "
apiVersion: clusterlink.net/v1alpha1
kind: Import
metadata:
  name: nginx-project-no-alias
  namespace: default
spec:
  port:  80
  sources:
    - exportName:       nginx-project
      exportNamespace:  default
      peer:             cl-peer1
" | kubectl --kubeconfig ~/.kube/cl-peer2 apply -f -
echo "
apiVersion: clusterlink.net/v1alpha1
kind: Import
metadata:
  name: nginx-project-invalid
  namespace: default
spec:
  port:  80
  alias:  $www.example.com
  sources:
    - exportName:       nginx-project
      exportNamespace:  default
      peer:             cl-peer1
" | kubectl --kubeconfig ~/.kube/cl-peer2 apply -f -
echo "
apiVersion: clusterlink.net/v1alpha1
kind: Import
metadata:
  name: nginx-project-invalid-2
  namespace: default
spec:
  port:  80
  alias:  \"*.www....example-another.com\"
  sources:
    - exportName:       nginx-project
      exportNamespace:  default
      peer:             cl-peer1
" | kubectl --kubeconfig ~/.kube/cl-peer2 apply -f -
echo "
apiVersion: clusterlink.net/v1alpha1
kind: Import
metadata:
  name: nginx-project-invalid-3
  namespace: default
spec:
  port:  80
  alias:  www www.example-another.com
  sources:
    - exportName:       nginx-project
      exportNamespace:  default
      peer:             cl-peer1
" | kubectl --kubeconfig ~/.kube/cl-peer2 apply -f -

I have also tested with two AWS EKS clusters in respect to internal service (e.g. incluster nginx-project) and external ones e.g. AWS s3, AWS lambda.

The policies being used for all tests where "allow all".

elevran commented 1 week ago

@aviweit - thank you for this contribution - we're looking for the the best way to make it available in ClusterLink, safely. Thus, I'm marking it as on hold for now.

The main concern is that Imports are namespace scoped but using an alias has cluster-wide impact. This would elevate a user from having only namespace local permissions to affecting workloads across the entire cluster (e.g., the DNS alias could be set to anything, including grabbing service names from another namespace or affecting external services used by workloads in another namespace).

The maintainers will follow up on this work to address the above concern and allow users to experiment with it. For example, we're considering putting this behind a feature flag (with default set to disabled), adding policies for which aliases are allowed in which namespace, using pod.Spec.hostAliases to affects specific Pods in only the namespace where the import is defined, etc.