-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for DNS names in egress routes #15409
Support for DNS names in egress routes #15409
Conversation
021c3ea
to
caae214
Compare
@openshift/networking PTAL |
[test] |
Evaluated for origin test up to caae214 |
continuous-integration/openshift-jenkins/test FAILURE (https://ci.openshift.redhat.com/jenkins/job/test_pull_request_origin/3408/) (Base Commit: e97ba37) (PR Branch Commit: caae214) |
/unassign kargakis |
caae214
to
77c1008
Compare
images/egress/dns-proxy/Dockerfile
Outdated
tar xvzf haproxy-1.7.5.tar.gz && \ | ||
groupadd haproxy && \ | ||
useradd -g haproxy haproxy && \ | ||
cd haproxy-* && make TARGET=linux2628 CPU=native USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 && make install && \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eek... Not sure about this. We don't do anything like that anywhere else...
What exactly is different if we don't have the new haproxy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dynamic DNS resolution feature is only available in HAProxy 1.6+ version (currently we are running haproxy 1.5). I don't know if this method is acceptable currently or not but we have done similar stuff in release-1.3 (https://github.com/openshift/origin/blob/release-1.3/images/router/haproxy/Dockerfile)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Dynamic DNS resolution" meaning that if we used haproxy 1.5, it would only do the DNS resolution at startup and not notice any changes after that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like we need some sort of higher-up (ie, not just networking team) approval for actually building binaries from source in the images like this...
(Another possibility maybe is to pre-build the package into an RPM and make it available in a COPR, like we do for the openvswitch packages for the dind image.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, haproxy 1.5.x resolves DNS at startup and will fail if the IP changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eparis @smarterclayton is this acceptable? (building haproxy from source)..if not, how should we proceed?
Having haproxy 1.6+ will also solve this card: https://trello.com/c/J1ODldZK/516-move-to-a-version-of-haproxy-with-lua-capability
function generate_dns_resolvers() { | ||
echo "resolvers dns-resolver" | ||
# Fetch nameservers from /etc/resolv.conf | ||
declare -a nameservers=$(cat /etc/resolv.conf |grep nameserver|awk -F" " '{print $2}') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
origin style is to put declaration and initialization on separate lines. (IIRC because if you write it the way you did here, and there's an error, the error gets ignored)
also, you don't need cat and grep: $(awk '/nameserver/ {print $2}' /etc/resolv.conf)
also, actually you need a ^
before nameserver
so it doesn't get tripped up by the comments NetworkManager sometimes adds:
# NOTE: the libc resolver may not support more than 3 nameservers.
# The nameservers listed below may not be recognized.
echo " nameserver ns$n ${ns}:${NS_PORT}" | ||
done | ||
|
||
# Add google DNS servers as fallback |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh no, don't do that. The user may not want to leak their DNS requests to google.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I will remove.
generate_haproxy_frontends_backends | ||
} | ||
|
||
function setup_haproxy_syslog() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh. There's no way to get it to just log to stdout/stderr?
We might want to make it not bother doing this unless the pod spec sets some sort of "debug" variable...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default it is not logging stuff to stdout/stderr, I will enable this stuff when 'debug' variable is set.
|
||
check_prereqs | ||
|
||
rm -f ${CONF} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"${CONF}"
(everywhere)
die "Failed to fetch Pod IP" | ||
fi | ||
|
||
echo -A PREROUTING -p tcp -d "${pod_ip}" -j DNAT --to-destination "${EGRESS_SOURCE}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need the pod_ip match here? We don't do that in the standard egress-router.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the standard egress-router, iptables rules are set on the pod and packets from service IP to pod IP will hit the iptables on the pod that does the actual job.
In this dns proxy case, haproxy is running on the macvlan interface and packets from service IP will only reach the pod IP. This additional rule will forward all tcp packets from pod to macvlan interface which has the egress source IP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually haproxy doesn't need to listen on macvlan interface. It can listen on pod/all interfaces and we don't need this additional iptables forward rule.
} | ||
out := string(outBytes) | ||
for _, frontend := range test.frontends { | ||
if !strings.Contains(out, frontend) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't verify that there are no unexpected additional frontend/backend rules
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will add this test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you fix this? Basically I was suggesting you should parse the output into static config, resolvers, and frontends sections, so you could then just check for equality rather than just "contains". (This might be easier if you had multiple testing modes; eg, one that just runs generate_dns_resolvers
and nothing else, and one that just runs generate_haproxy_frontends_backends
and nothing else.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may have multiple frontends and backends and equality check will work if the order is predefined among the frontends/backends. We don't have to enforce the order when generating these frontends/backends, instead we are checking for exact number of frontends and backends expected. Lines 137 to 140 and 147 to 150 validates this case.
} | ||
} | ||
|
||
func TestHAProxyDefaults(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is really testing anything useful. OTOH, it might be good to test the resolver code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to catch the case where config file was overwritten by some write instead of append('>' instead of '>>' in the script). I will add the resolver test.
39825e5
to
6cdaa67
Compare
@danwinship updated, ptal |
@pravisankar maybe need ot rebase to get an update to contrib/completions/OWNERS? It's failing the verify there with |
6cdaa67
to
9e4afb1
Compare
images/egress/dns-proxy/Dockerfile
Outdated
tar xvzf haproxy-1.7.5.tar.gz && \ | ||
groupadd haproxy && \ | ||
useradd -g haproxy haproxy && \ | ||
cd haproxy-* && make TARGET=linux2628 CPU=native USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 && make install && \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Dynamic DNS resolution" meaning that if we used haproxy 1.5, it would only do the DNS resolution at startup and not notice any changes after that?
images/egress/dns-proxy/Dockerfile
Outdated
tar xvzf haproxy-1.7.5.tar.gz && \ | ||
groupadd haproxy && \ | ||
useradd -g haproxy haproxy && \ | ||
cd haproxy-* && make TARGET=linux2628 CPU=native USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 && make install && \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like we need some sort of higher-up (ie, not just networking team) approval for actually building binaries from source in the images like this...
(Another possibility maybe is to pre-build the package into an RPM and make it available in a COPR, like we do for the openvswitch packages for the dind image.)
images/egress/dns-proxy/Dockerfile
Outdated
RUN INSTALL_PKGS="rsyslog gcc make openssl-devel pcre-devel tar wget socat" && \ | ||
yum install -y $INSTALL_PKGS && \ | ||
rpm -V $INSTALL_PKGS && \ | ||
wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.5.tar.gz && \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we are doing this, can we verify the md5sum as well before building?
function generate_haproxy_defaults() { | ||
echo " | ||
global | ||
log 127.0.0.1 local2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this cause problems if the debug logging isn't enabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested with and without debug logging and found no issues.
} | ||
out := string(outBytes) | ||
for _, frontend := range test.frontends { | ||
if !strings.Contains(out, frontend) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you fix this? Basically I was suggesting you should parse the output into static config, resolvers, and frontends sections, so you could then just check for equality rather than just "contains". (This might be easier if you had multiple testing modes; eg, one that just runs generate_dns_resolvers
and nothing else, and one that just runs generate_haproxy_frontends_backends
and nothing else.)
Now that the router has been updated to HAProxy 1.8 (#18053), can the egress router be updated to support dynamic DNS resolution? |
Introduced dns-proxy egress router that allows specifying DNS name for EGRESS_DESTINATION. Currently, dns-proxy egress mode implementation is based on HAProxy. HAProxy 1.6+ version is used to leverage DNS resolution at runtime.
9e4afb1
to
5a94143
Compare
@openshift/sig-networking @danwinship @knobunc ready for re-review, PTAL |
/retest |
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: danwinship, pravisankar The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these OWNERS Files:
You can indicate your approval by writing |
/hold |
/hold cancel |
/test all [submit-queue is verifying that this PR is safe to merge] |
/retest |
Automatic merge from submit-queue (batch tested with PRs 15409, 18763). |
@pravisankar: The following tests failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
Introduced dns-proxy egress router mode that allows specifying DNS name for EGRESS_DESTINATION.
Currently, dns-proxy egress mode implementation is based on HAProxy.
HAProxy 1.6+ version is used to leverage DNS resolution at runtime.
Trello Card: https://trello.com/c/407uoUFz