docker-mailserver / docker-mailserver-helm

Kubernetes Helm chart for docker-mailserver
https://github.com/docker-mailserver/docker-mailserver/
MIT License
107 stars 67 forks source link

Bare Metal Port Exposure via NodePort #138

Open kaktus42 opened 1 month ago

kaktus42 commented 1 month ago

I am trying to migrate from a custom postfix deployment to docker-mailserver.

My current approach is to use a specific node for the mailserver using a NodePort service. For this I configure (next to type: NodePort) externalIPs: <server's public IP> and externalTrafficPolicy: Local for retaining the client IP. In your chart this is not possible (straight forward), e.g. because it will set externalTrafficPolicy: Cluster when using NodePort. Why did you make that decision? Is there a downside of my configuration that I am missing? (I am not super experienced with K8S). I am looking for some understanding and possibly we can make this chart more flexible.

cfis commented 4 weeks ago

If you look at the git history, this change was made four years ago:

https://github.com/docker-mailserver/docker-mailserver-helm/commit/a42d9552a19ea298faae5b6d24667b7a67bfbc71

I also see this three year old K8 issue that seems to say what that what you are asking for doesn't work:

https://github.com/kubernetes/kubernetes/issues/104105

But of course things likely have changed in the last 3 years! Having said that, if you read this:

https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/

If two Pods in your cluster want to communicate, and both Pods are actually running on the same node, use Service Internal Traffic Policy to keep network traffic within that node. Avoiding a round trip via the cluster network can help with reliability, performance (network latency and throughput), or cost.

So that seems to be the K8 recommended approach?

kaktus42 commented 4 weeks ago

I already have a postfix running with the mentioned config, so I know that it is working (at least for the use cases I have). The links you gave are more about the internal handling of the traffic if I'm not mistaken. So I'm not sure if we are talking about the same use cases, as I care mostly about the internet being able to reach me and me having the correct IPs for spam checks. Also: I do not plan to run more than one instance of docker-mailserver, so a single IP and a fixed node is fine for me. I'm not sure if this chart is supposed to support multiple instances anyways (?). But of course for it to be a solution for this chart, it should cover all the possibilities, so I did some testing.

I have a docker-mailserver running on node-1, using my config (overridden the default chart) with type: NodePort, externalTrafficPolicy: Local and externalIPs set to the static IP of that node.

When sending an email to a mail-address for this mailserver from different locations, all using the DNS name for smpt connection, I see this:

EDIT: This is also the expected behavior from what I understand from the discussion in the linked k8s repo issue. (internal traffic using internal pod/node network) and external traffic using external traffic policy (with local, retaining IP)

So, all works fine with ETP: Local. Do you think it's worth integrating it for this chart? With this, the extra proxy service would not be needed for a bare-metal installation, removing some overhead and complexity.

cfis commented 3 weeks ago

Ok - want to provide a PR?

kaktus42 commented 2 weeks ago

yes, can do. Is it okay to offer .Values.serviceOverride.[type|externalIPs|externalTrafficPolicy|internalTrafficPolicy]?