Bug 1812333

Summary: egressnetworkpolicy cannot work if use custom dnsname
Product: OpenShift Container Platform Reporter: huirwang
Component: NetworkingAssignee: Alexander Constantinescu <aconstan>
Networking sub component: openshift-sdn QA Contact: huirwang
Status: CLOSED DUPLICATE Docs Contact:
Severity: low    
Priority: medium CC: aconstan, aos-bugs, ehashman, mmasters, ricarril, weliang
Version: 4.4   
Target Milestone: ---   
Target Release: 4.7.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2020-10-26 09:32:06 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description huirwang 2020-03-11 02:24:07 UTC
Description of problem:
egressnetworkpolicy cannot work if use  custom dnsname

Version-Release number of selected component (if applicable):
4.4.0-0.nightly-2020-03-09-060825

How reproducible:
Always

Steps to Reproduce:

1. Create  a DNS sever which can resolve pod2.ec2.internal , DNServer is 10.0.79.93

2. Create project hrw1 and a test pod
add dns server to /etc/resolve.conf on test pod

oc get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE   IP            NODE                          NOMINATED NODE   READINESS GATES
hello-pod   1/1     Running   0          43m   10.131.0.33   huirwang-43-46jj8-compute-1   <none>           <none>

oc rsh hello-pod
/ # cat /etc/resolv.conf
search hrw1.svc.cluster.local svc.cluster.local cluster.local huirwang-43.qe.devcluster.openshift.com
search ec2.internal
nameserver 10.0.79.93
nameserver 172.30.0.10
options ndots:5

ping pod2.ec2.internal
PING pod2.ec2.internal (220.181.38.150) 56(84) bytes of data.
64 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=1 ttl=32 time=239 ms

3. deploy a egressnetworkpolicy by 
oc create -f https://raw.githubusercontent.com/weliang1/Openshift_Networking/master/dns-egresspolicy/dns-egresspolicy4.json

oc describe egressnetworkpolicy        
Name:		policy-test
Namespace:	hrw1
Created:	13 minutes ago
Labels:		<none>
Annotations:	<none>
Rule:		Deny to pod2.ec2.internal
Rule:		Allow to 0.0.0.0/0

4. add DNS server info to /etc/resolv.conf on host huirwang-43-46jj8-compute-1 and restart sdn pod.
search ec2.internal
nameserver 10.0.79.93

5. From hello-pod try to access pod2.ec2.internal, still can accessed.
PING pod2.ec2.internal (220.181.38.150) 56(84) bytes of data.
64 bytes from 220.181.38.150 (220.181.38.150): icmp_seq=1 ttl=32 time=239 ms


6. Check openflow from sdn pod located on node huirwang-43-46jj8-compute-1, not added.
ovs-ofctl -O openflow13 dump-flows br0 | grep  "220.181.38.150"
sh-4.2# 

7. Check sdn logs, resolve pod2.ec2.internal fail.
failed to get a valid answer: ;; opcode: QUERY, status: NXDOMAIN, id: 8469
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;pod2.ec2.internal.	IN	 A

;; AUTHORITY SECTION:
.	9454	IN	SOA	a.root-servers.net. nstld.verisign-grs.com. 2020030401 1800 900 604800 86400
E0304 10:00:10.168990 1004855 egress_dns.go:64] failed to get a valid answer: ;; opcode: QUERY, status: NXDOMAIN, id: 7927
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;; QUESTION SECTION:
;pod2.ec2.internal.	IN	 A

;; AUTHORITY SECTION:
.	9454	IN	SOA	a.root-servers.net. nstld.verisign-grs.com. 2020030401 1800 900 604800 86400


Actual results:
The egressnetworkpolicy cannot work in this situation, no related ip was added into ovs 

Expected results:
The egressnetworkpolicy should work even use custom dnsname

Additional info:

We have added dns server iformation in SDN/OVS pod's /etc/resolv.conf, also the nodes. Using ping from sdn pod to pod2.ec2.internal  succeeded.

Comment 1 Alexander Constantinescu 2020-03-19 12:07:43 UTC
Hi Huiran

Could you confirm that your cluster is running the "redhat/openshift-ovs-multitenant" network plugin? This is the not the default network plugin in 4.4, hence why I ask. And egressnetworkpolicy is only expected to work with that network plugin.

Do: 

oc get clusternetwork -o yaml 

to find out

Thanks in advance!

-Alex

Comment 2 Alexander Constantinescu 2020-03-19 14:00:12 UTC
Hi again

Could you also provide me with a kubeconfig when you reproduce this next time so that I can jump on the cluster and have a look?

Thanks again

-Alex

Comment 3 Weibin Liang 2020-03-19 20:44:36 UTC
Hi Alex,

QE tracked this bug and found it can also be reproduced in v3.11 with "redhat/openshift-ovs-multitenant" network plugin

Here is information to login v3.11 cluster with "redhat/openshift-ovs-multitenant" network plugin

Master: sudo ssh -i "/home/weliang/.ssh/openshift-qe.pem" ci-vm-10-0-150-160.hosted.upshift.rdu2.redhat.com
Router node: sudo ssh -i "/home/weliang/.ssh/openshift-qe.pem" ci-vm-10-0-148-140.hosted.upshift.rdu2.redhat.com
application node: sudo ssh -i "/home/weliang/.ssh/openshift-qe.pem" ci-vm-10-0-149-197.hosted.upshift.rdu2.redhat.com

According to test case from https://polarion.engineering.redhat.com/polarion/#/project/OSE/workitem?id=OCP-13503, both pod and egressnetworkpolicy policy-test are applied under project p1, you can easily reproduce the bug by ping pod2.ec2.internal after you ssh to hello-pod.

Thanks,
Weibin

Comment 5 huirwang 2020-03-20 01:42:32 UTC
Hi Alex, 

From the doc, https://docs.openshift.com/container-platform/4.3/networking/openshift_sdn/configuring-egress-firewall.html,  "You must have OpenShift SDN configured to use either the network policy or multitenant modes to configure egress firewall policy."  That means it "egressnetworkpolicy" supports both network policy and multitenant modes.

Thanks
Huiran

Comment 6 Alexander Constantinescu 2020-03-20 09:59:59 UTC
Hi 

> From the doc, https://docs.openshift.com/container-platform/4.3/networking/openshift_sdn/configuring-egress-firewall.html,  "You must have OpenShift SDN configured to use either the network policy or multitenant modes to configure egress firewall policy."  That means it "egressnetworkpolicy" supports both network policy and multitenant modes.

Fair enough

I spent time looking at the 3.11 cluster Weibin created yesterday and the problem is definately not in the SDN, it has to do with the fact that /etc/resolv.conf is not populated with your customer nameserver when the container starts. Which means one out of two things:

1) Either they way you're testing it (by adding it to the host's /etc/resolv.conf and re-starting the SDN pod) is not supported
2) Or, there's a bug

However, 3.11 is waayyyy too far back in time to be worth the effort to investigate properely. Could you guys thus create a cluster with >= 4.2? I could verify that the same issue happens there, investigate a bit and then send it off to the network-edge team for a final verdict (they are the ones handling DNS).

Thanks in advance guys!

-Alex

Comment 7 Alexander Constantinescu 2020-03-20 14:35:53 UTC
Hi again guys

Just to finish on the last comment, I figured out how to make it work on 3.11:

The SDN daemonset needs to be edited, and you need to change:

dnsPolicy: ClusterFirst -> dnsPolicy: Default

But this is if you want the nameserver record to be taken into account when modifying /etc/resolv.conf on the host, as you guys have been doing. I am not sure if it's worth doing on 3.11 just to satisfy this use-case (no customer has ever complained about this from my knowledge), and it might impact other functionality so I don't think it's worth pushing a PR to 3.11 for. 

Like I said, get back to me with a 4.X cluster and I'll debug on a more recent tech stack. 

-Alex

Comment 8 Weibin Liang 2020-03-20 18:53:15 UTC
Hi Alex,

I installed v4.4 cluster and update dnsPolicy: ClusterFirst -> dnsPolicy: Default, but dnsPolicy value change back to ClusterFirst after a while.

[weliang@weliang FILE]$ while true; do oc get daemonset.apps/sdn -o yaml | grep dnsPolicy;sleep 5;done
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: Default
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst
      dnsPolicy: ClusterFirst

Comment 9 Alexander Constantinescu 2020-03-20 19:25:02 UTC
Hi Weibin

Yes, that solution was for a 3.11 cluster, not 4.X. I suspect the network-operator modifies the SDN daemonset back to it's original configuration. 

On 4.X cluster I suspect you should follow this: https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#configuration-of-stub-domain-and-upstream-nameserver-using-coredns

If that does not work, then I'd recommend that you assign the bug to network-edge so that they can advise. Anyways, as I mentioned: this is not a bug in SDN, it only tries to resolve the DNS entry in the egressnetworkpolicy object, it's up to the user to make sure that it's correctly configured and able to be resolved in every pod across his/hers cluster.

-Alex

Comment 10 Dan Mace 2020-03-23 11:06:18 UTC
Network policy is SDN, reassigning so the right folks can take a look

Comment 11 Ricardo Carrillo Cruz 2020-03-23 14:39:00 UTC
Alex, assigning to you since it seems you were looking into it.
If you too many bugs on your plate, just unassign or ping me and we find a better home.

Comment 13 Alexander Constantinescu 2020-03-30 12:11:25 UTC
@Dan

As mentioned in #comment 9, the problem is not egressnetworkpolicy, the problem is how the custom nameserver in /etc/resolv.conf is/is supposed to be propagated from the node -> pods, and if what the QE guys are doing when testing this is valid or not. 

Could you please have a look at the procedure they've described in #comment 1 and advise if:

1) It's the proper way to add a custom nameserver to openshift in 4.X  (confirm if what I advised in #comment 9 is correct)
2) It's the proper way to add a custom nameserver to openshift in 3.11 (confirm if what I advised in #comment 7 is correct)

-Alex

Comment 14 Dan Mace 2020-03-30 12:25:27 UTC
(In reply to Alexander Constantinescu from comment #13)
> @Dan
> 
> As mentioned in #comment 9, the problem is not egressnetworkpolicy, the
> problem is how the custom nameserver in /etc/resolv.conf is/is supposed to
> be propagated from the node -> pods, and if what the QE guys are doing when
> testing this is valid or not. 
> 
> Could you please have a look at the procedure they've described in #comment
> 1 and advise if:
> 
> 1) It's the proper way to add a custom nameserver to openshift in 4.X 
> (confirm if what I advised in #comment 9 is correct)
> 2) It's the proper way to add a custom nameserver to openshift in 3.11
> (confirm if what I advised in #comment 7 is correct)
> 
> -Alex

I don't know if user modifications to /etc/resolv.conf are supported in v4. I believe the machine-config-operator owns it. My team owns dns-operator and ingress-operator, neither of which manage /etc/resolv.conf on nodes.

If you're concerned only with DNS forwarding from _pods_, upstream nameservers can be added using the DNS operator's forwarding API[1]. Note this will have _no effect_ on resolution from the node context — the DNS forwarding API applies only to DNS queries from pod clients.

Looking at the procedure you cited, I suspect (but can't confirm at this very moment) those SDN pods are using host network. If that's true, I recommend engaging the MCO team to understand the option available for managing node /etc/resolv.conf.

Make sense?

[1] https://docs.openshift.com/container-platform/4.3/networking/dns-operator.html#nw-dns-forward_dns-operator

Comment 15 Alexander Constantinescu 2020-03-30 13:18:29 UTC
Hi 

Understood, thanks for the help!

I will re-assign to the MCO team in that case as the SDN pods are indeed running hostNetwork: true. 

Could the MCO team please advise the QE guys how they're supposed to add a custom nameserver to their cluster, so that it in turn can be picked up by the SDN pod, so that the SDN can perform DNS name resolution against it? 

-Alex

Comment 17 Antonio Murdaca 2020-04-14 13:47:31 UTC
(In reply to Alexander Constantinescu from comment #15)
> Hi 
> 
> Understood, thanks for the help!
> 
> I will re-assign to the MCO team in that case as the SDN pods are indeed
> running hostNetwork: true. 
> 
> Could the MCO team please advise the QE guys how they're supposed to add a
> custom nameserver to their cluster, so that it in turn can be picked up by
> the SDN pod, so that the SDN can perform DNS name resolution against it? 
> 
> -Alex

apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
  labels:
    machineconfiguration.openshift.io/role: worker
  name: 50-nameserver
spec:
  config:
    ignition:
      version: 2.2.0
    storage:
      files:
      - contents:
          source: data:text/plain;charset=utf-8;base64,<base_64_encoding_of_etc_resolv_conf>
        filesystem: root
        mode: 0644
        path: /etc/resolv.conf


The above should work, you'd rewrite the whole resolv.conf tho, so check what's inside before overwriting - and this is just for testing I suppose

Comment 19 Antonio Murdaca 2020-04-16 10:16:06 UTC
I'm moving back to Routing, clearly shipping the new resolv.conf worked right? so, if it gets overwritten or isn't picked up by sdn pod it's not MCO

Comment 20 Miciah Dashiel Butler Masters 2020-04-29 05:16:13 UTC
Based on the following, this appears to be an SDN issue:

* /etc/resolv.conf has the expected name server,
* ping can resolve the name, and
* SDN fails to resolve the name.

Looking at the getIPsAndMinTTL function (https://github.com/openshift/sdn/blob/3bc47150a058cce2e6c5d01518b6ff6239e0959b/pkg/network/common/dns.go#L130-L161), it looks like SDN tries every name server in /etc/resolv.conf and fails with "failed to get a valid answer" if any one of the name servers responds with NXDOMAIN.

To solve this issue, I believe the getIPsAndMinTTL function should ignore NXDOMAIN responses.  There isn't an obvious reason to return an error if some servers respond with NXDOMAIN, so long as at least one server responds with an address.

A possible workaround for QE would be to (1) create another name server that forwarded the ec2.internal zone to the custom name server and forwarded everything else to the cluster DNS service (172.30.0.10), (2) delete any existing nameserver entries from /etc/resolv.conf, and (3) add a single entry for the name server created in the first step to /etc/resolv.conf.  This way, getIPsAndMinTTL could resolve pod2.ec2.internal as well as other addresses (such as the API's) and would not get any NXDOMAIN responses for pods2.ec2.internal or other resolvable addresses.

Comment 21 Ben Bennett 2020-05-28 15:11:04 UTC
Bumping the priority and moving to 4.6 so we can think about this.

Comment 22 Ricardo Carrillo Cruz 2020-08-03 11:49:32 UTC
Unassigning as I'm on long vacation.

Comment 23 Alexander Constantinescu 2020-09-10 15:23:09 UTC
Hi Huiran

Could you reproduce this bug and provide me with a kubeconfig? 

Thanks in advance!
/Alex

Comment 27 Daneyon Hansen 2020-10-15 16:27:51 UTC
*** Bug 1861925 has been marked as a duplicate of this bug. ***