Skip to content
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

Pods in different networks are unable to communicate between them. #1824

Closed
alekc opened this issue May 23, 2020 · 22 comments
Closed

Pods in different networks are unable to communicate between them. #1824

alekc opened this issue May 23, 2020 · 22 comments

Comments

@alekc
Copy link

alekc commented May 23, 2020

This might be related to the discussion on #881, but with some slight differences.

Version:

k3s -v
k3s version v1.18.2+k3s1 (698e444a)

K3s arguments:

curl -sfL https://get.k3s.io | K3S_TOKEN="${token}" K3S_URL="https://${endpoint}:6443/" sh -s - $(scw-userdata k3s_node_labels) --node-external-ip="$(scw-metadata --cached PUBLIC_IP_ADDRESS)"

Describe the bug
I am trying to run a cluster which has some nodes hosted on scaleway vps and some in another network/provider.

On scaleway nodes are assigned private ips, but they also have a routable public ip (1:1) and by passing a flag node-external-ip I am able to have a proper internal and external ip assigned to nodes, i.e.

NAME             STATUS   ROLES    AGE    VERSION        INTERNAL-IP     EXTERNAL-IP      OS-IMAGE                       KERNEL-VERSION   CONTAINER-RUNTIME
k3s-server-001   Ready    <none>   23m    v1.18.2+k3s1   10.64.212.xx    212.47.252.xx     Ubuntu 20.04 LTS               5.4.0-1011-kvm   containerd://1.3.3-k3s2
k3s-server-002   Ready    <none>   39m    v1.18.2+k3s1   10.69.66.xx     51.158.109.xx   Ubuntu 20.04 LTS               5.4.0-1011-kvm   containerd://1.3.3-k3s2
k3s-online-01    Ready    master   4h3m   v1.18.2+k3s1   62.210.202.xx   <none>           Debian GNU/Linux 10 (buster)   4.19.0-9-amd64   containerd://1.3.3-k3s2

(above the third node is the master and 2 scaleway's nodes are workers, it was a test to see if having master on public ip solves this issue or not. Normal situation is that 2 scaleway nodes are master and the k3s-online-01 is slave)

Third node which is situated on another provider has only public ip address.

For test purposes all nodes have been wiped clean, they also had the same OS version (debian buster), no firewall is set up.

The issue is that until I remain in the Scaleway realm, everything works as expected. When I add an external node from a different network it shows up as ready in the cluster, I am able to deploy pods to it and exec into a shell.
However I am unable to reach any of the other network, dns resolution doesnt' work on any address (kubernetes or outside word), and I am only able to ping resources in WWW.

Is there something I am missing? I tried flannel with default/ipsec/wireguard setting with no success so far.

@alekc
Copy link
Author

alekc commented May 24, 2020

After a bit of investigation I am able to shed more light onto this issue.

So, it turns out the problem is indeed in flannel. Even though node have private and public ip correctly reported in kubectl get nodes -o wide, on node annotation flannel reports

    flannel.alpha.coreos.com/backend-data: '{"VtepMAC":"e2:f3:3c:16:6b:e8"}'
    flannel.alpha.coreos.com/backend-type: vxlan
    flannel.alpha.coreos.com/kube-subnet-manager: "true"
    flannel.alpha.coreos.com/public-ip: 10.x.x.x

node public-ip which contains node's private ip.

After adding an additional annotation to the node

flannel.alpha.coreos.com/public-ip-overwrite: 51.158.109.xxx

and restarting k3s-agent, I can see in logs

3415 kube.go:247] Overriding public ip with '51.158.109.xxx' from node annotation 'flannel.alpha.coreos.com/public-ip-overwrite'

After that everything begins to work again.
I need to do some further testing, but so far results are encouraging.

@alekc
Copy link
Author

alekc commented May 25, 2020

For now I've put up a deployable workaround (https://github.com/alekc-go/flannel-fixer) which involves launching a listener deployment which fixes this annotation on existing and any new node joining the cluster. Will try to chase it/debug on flannel side of things.

@brandond
Copy link
Member

brandond commented May 25, 2020

@alekc did you try setting that address with --node-external-ip on the k3s command line?

@alekc
Copy link
Author

alekc commented May 26, 2020 via email

@brandond
Copy link
Member

brandond commented May 26, 2020

Ah OK, I missed that at the end of the command there.

Looks like there's an open issue for RKE to do the same thing: rancher/rancher#22190

Honestly I'm surprised that Flannel invented their own annotation when kuberenetes already has an ExternalIP address type that can be set on nodes. This is actually what you're seeing in the kubectl get nodes -o wide output, and setting the addresses properly is just about the only thing that the k3s cloud-controller does.

What do you get from:

kubectl get nodes -o 'jsonpath={range.items[*].status}{.addresses}{"\n"}{end}'

@alekc
Copy link
Author

alekc commented May 26, 2020

Yeah, I was surprised as well once i got to the root of the issue.

I ran this command on a "fixed" cluster, should not matter match since my fix involves only the annotations

[map[address:10.64.8.51 type:InternalIP] map[address:51.158.109.151 type:ExternalIP] map[address:k3s-server-002 type:Hostname]]
[map[address:62.210.202.xx type:InternalIP] map[address:k3s-online-01 type:Hostname]]
[map[address:10.69.92.xx type:InternalIP] map[address:212.47.252.x type:ExternalIP] map[address:k3s-server-001 type:Hostname]]
[map[address:10.65.40.xx type:InternalIP] map[address:51.158.113.xx type:ExternalIP] map[address:k3s-ingress-c60b2402 type:Hostname]]
[map[address:10.69.148.xx type:InternalIP] map[address:51.15.238.xx type:ExternalIP] map[address:k3s-ingress-b17dd622 type:Hostname]]

@brandond
Copy link
Member

brandond commented May 26, 2020

One of your nodes has a public address for it's InternalIP and no ExternalIP. If you fix that, does it work without any extra annotations?

@alekc
Copy link
Author

alekc commented May 26, 2020

It would probably work, but the issue is that the third node is on another network, and private network range common to 2 other nodes is not routable for him.

@brandond
Copy link
Member

brandond commented May 26, 2020

right, but if you set all the internal and external IPs correctly, I think it should figure out how to set things up properly without any hacks. That's the whole point of kubernetes having a field for the external address. The overlay should use those addresses when building the mesh to carry the pod and service network traffic.

@alekc
Copy link
Author

alekc commented May 26, 2020

Let me give some more details on the matter and why I can't do any other way around (at least until flannel doesn't fix this behaviour).

2 Servers are running on Scaleway, each of those have 1 single interface with private ip assigned to them. There is no way (if you are not calling the equivalent of aws 169.254.169.254 endpoint) for those servers to know their public ip, thats why in the stage of installation, I am passing --node-external-ip="$(scw-metadata --cached PUBLIC_IP_ADDRESS)" which sets the proper address.

Third server is running on Online.net provider, it has only 1 interface with public ip assigned to it. It doesn't have a private ip, and private ips from Scaleway are not routable.

So, in this situation I cannot really do anything more, and generally speaking in my opinion since flannel has the label public-ip it should give priority to the public address of the node if it's set and ignore the interface (I believe that currently thats how it does it).

This ticket can probably be closed since this issue is not related to the k3s but to flannel, and until the underlying behaviour is changed there is not a lot we can do (well, maybe set the flannel.alpha.coreos.com/public-ip-overwrite annotation to the node in case we specify the external address, but I am feeling a bit uneasy about that).

@brandond
Copy link
Member

brandond commented May 26, 2020

OK, even if the node doesn't have a separate private IP, couldn't you still set --node-external-ip to the public IP to see if it changes the behavior at all?

Also, couldn't you just do add --node-label=flannel.alpha.coreos.com/public-ip-overwrite=$(scw-metadata --cached PUBLIC_IP_ADDRESS) to the command line instead of doing it with a deployment?

Setting that only works at registration time so you can't add it now, but it's an easy thing to do if you're scripting builds.

@alekc
Copy link
Author

alekc commented May 26, 2020

Oh I am adding --node-label=flannel.alpha.coreos.com/public-ip-overwrite=$(scw-metadata --cached PUBLIC_IP_ADDRESS) on a command line during the registration process, sorry if that wasn't clear.

Deployment only adds flannel.alpha.coreos.com/public-ip-overwrite annotation and changes flannel.alpha.coreos.com/public-ip since we are at it.

I will try to add a --node-external-ip to the server which doesn't have one (because it's private ip is already public) but I doubt it will change a great deal of things because if nothing is done, on other 2 nodes flannel sets unroutable private ip, so the initial handshake cannot be performed.

@brandond
Copy link
Member

brandond commented May 26, 2020

I wonder what you would have seen from

kubectl get node -o 'jsonpath={range.items[*].metadata.annotations}{.flannel\.alpha\.coreos\.com/public-ip}{"\n"}{end}'

I see that you've fixed that up with your deployment, but if that's getting set to private addresses that would explain why you have to override it.

@alekc
Copy link
Author

alekc commented May 27, 2020

That annotation had the private address of the node in it.

@brandond
Copy link
Member

Yeah, that'd do it. I bet setting the external ip on the command line will correct that.

@alekc
Copy link
Author

alekc commented May 27, 2020

Nope, this is the whole point of that fixing deployment. Without it the node looks like this

apiVersion: v1
kind: Node
metadata:
  annotations:
    flannel.alpha.coreos.com/backend-data: '"/2OwTq4SN4x0="'
    flannel.alpha.coreos.com/backend-type: extension
    flannel.alpha.coreos.com/kube-subnet-manager: "true"
    flannel.alpha.coreos.com/public-ip: 10.65.40.139
    k3s.io/node-args: '["agent","--node-label","node-size","tiny","--node-label","ingress","true","--node-external-ip","51.158.113.162"]'
    k3s.io/node-config-hash: xxx====
    k3s.io/node-env: xxxx
    node.alpha.kubernetes.io/ttl: "0"
    volumes.kubernetes.io/controller-managed-attach-detach: "true"
  creationTimestamp: "2020-05-27T07:37:40Z"
  finalizers:
  - wrangler.cattle.io/node
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/instance-type: k3s
    beta.kubernetes.io/os: linux
    ingress: "true"
    k3s.io/external-ip: 51.158.113.xx
    k3s.io/hostname: k3s-ingress-c60b2402
    k3s.io/internal-ip: 10.65.40.xx
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: k3s-ingress-c60b2402
    kubernetes.io/os: linux
    node-size: tiny
    node.kubernetes.io/instance-type: k3s
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:flannel.alpha.coreos.com/backend-data: {}
          f:flannel.alpha.coreos.com/backend-type: {}
          f:flannel.alpha.coreos.com/kube-subnet-manager: {}
          f:flannel.alpha.coreos.com/public-ip: {}
          f:k3s.io/node-args: {}
          f:k3s.io/node-config-hash: {}
          f:k3s.io/node-env: {}
          f:node.alpha.kubernetes.io/ttl: {}
          f:volumes.kubernetes.io/controller-managed-attach-detach: {}
        f:finalizers:
          .: {}
          v:"wrangler.cattle.io/node": {}
        f:labels:
          .: {}
          f:beta.kubernetes.io/arch: {}
          f:beta.kubernetes.io/instance-type: {}
          f:beta.kubernetes.io/os: {}
          f:ingress: {}
          f:k3s.io/external-ip: {}
          f:k3s.io/hostname: {}
          f:k3s.io/internal-ip: {}
          f:kubernetes.io/arch: {}
          f:kubernetes.io/hostname: {}
          f:kubernetes.io/os: {}
          f:node-size: {}
          f:node.kubernetes.io/instance-type: {}
      f:spec:
        f:podCIDR: {}
        f:podCIDRs:
          .: {}
          v:"10.42.2.0/24": {}
        f:providerID: {}
      f:status:
        f:addresses:
          .: {}
          k:{"type":"ExternalIP"}:
            .: {}
            f:address: {}
            f:type: {}
          k:{"type":"Hostname"}:
            .: {}
            f:address: {}
            f:type: {}
          k:{"type":"InternalIP"}:
            .: {}
            f:address: {}
            f:type: {}
        f:allocatable:
          .: {}
          f:cpu: {}
          f:ephemeral-storage: {}
          f:hugepages-2Mi: {}
          f:memory: {}
          f:pods: {}
        f:capacity:
          .: {}
          f:cpu: {}
          f:ephemeral-storage: {}
          f:hugepages-2Mi: {}
          f:memory: {}
          f:pods: {}
        f:conditions:
          .: {}
          k:{"type":"DiskPressure"}:
            .: {}
            f:lastHeartbeatTime: {}
            f:lastTransitionTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
          k:{"type":"MemoryPressure"}:
            .: {}
            f:lastHeartbeatTime: {}
            f:lastTransitionTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
          k:{"type":"NetworkUnavailable"}:
            .: {}
            f:lastHeartbeatTime: {}
            f:lastTransitionTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
          k:{"type":"PIDPressure"}:
            .: {}
            f:lastHeartbeatTime: {}
            f:lastTransitionTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
          k:{"type":"Ready"}:
            .: {}
            f:lastHeartbeatTime: {}
            f:lastTransitionTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
        f:daemonEndpoints:
          f:kubeletEndpoint:
            f:Port: {}
        f:images: {}
        f:nodeInfo:
          f:architecture: {}
          f:bootID: {}
          f:containerRuntimeVersion: {}
          f:kernelVersion: {}
          f:kubeProxyVersion: {}
          f:kubeletVersion: {}
          f:machineID: {}
          f:operatingSystem: {}
          f:osImage: {}
          f:systemUUID: {}
    manager: k3s
    operation: Update
    time: "2020-05-27T07:43:11Z"
  name: k3s-ingress-c60b2402
  resourceVersion: "503787"
  selfLink: /api/v1/nodes/k3s-ingress-c60b2402
  uid: 5b0a18b7-c92a-4053-8d8c-10b60cdc3084
spec:
  podCIDR: 10.42.2.0/24
  podCIDRs:
  - 10.42.2.0/24
  providerID: k3s://k3s-ingress-c60b2402
status:
  addresses:
  - address: 10.65.40.xx
    type: InternalIP
  - address: 51.158.113.xx
    type: ExternalIP
  - address: k3s-ingress-c60b2402
    type: Hostname
  allocatable:
    cpu: "2"
    ephemeral-storage: "18239898815"
    hugepages-2Mi: "0"
    memory: 2041840Ki
    pods: "110"
  capacity:
    cpu: "2"
    ephemeral-storage: 18749896Ki
    hugepages-2Mi: "0"
    memory: 2041840Ki
    pods: "110"
  conditions:
  - lastHeartbeatTime: "2020-05-27T07:37:43Z"
    lastTransitionTime: "2020-05-27T07:37:43Z"
    message: Flannel is running on this node
    reason: FlannelIsUp
    status: "False"
    type: NetworkUnavailable
  - lastHeartbeatTime: "2020-05-27T07:43:11Z"
    lastTransitionTime: "2020-05-27T07:37:40Z"
    message: kubelet has sufficient memory available
    reason: KubeletHasSufficientMemory
    status: "False"
    type: MemoryPressure
  - lastHeartbeatTime: "2020-05-27T07:43:11Z"
    lastTransitionTime: "2020-05-27T07:37:40Z"
    message: kubelet has no disk pressure
    reason: KubeletHasNoDiskPressure
    status: "False"
    type: DiskPressure
  - lastHeartbeatTime: "2020-05-27T07:43:11Z"
    lastTransitionTime: "2020-05-27T07:37:40Z"
    message: kubelet has sufficient PID available
    reason: KubeletHasSufficientPID
    status: "False"
    type: PIDPressure
  - lastHeartbeatTime: "2020-05-27T07:43:11Z"
    lastTransitionTime: "2020-05-27T07:37:50Z"
    message: kubelet is posting ready status. AppArmor enabled
    reason: KubeletReady
    status: "True"
    type: Ready
  daemonEndpoints:
    kubeletEndpoint:
      Port: 10250
  images:
  - names:
    - quay.io/kubernetes-ingress-controller/nginx-ingress-controller@sha256:251e733bf41cdf726092e079d32eed51791746560fff4d59cf067508ed635287
    - quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.32.0
    sizeBytes: 116356305
  - names:
    - gcr.io/kubernetes-e2e-test-images/dnsutils@sha256:b31bcf7ef4420ce7108e7fc10b6c00343b21257c945eec94c21598e72a8f2de0
    - gcr.io/kubernetes-e2e-test-images/dnsutils:1.3
    sizeBytes: 30566616
  - names:
    - docker.io/rancher/pause@sha256:d22591b61e9c2b52aecbf07106d5db313c4f178e404d660b32517b18fcbf0144
    - docker.io/rancher/pause:3.1
    sizeBytes: 326597
  nodeInfo:
    architecture: amd64
    bootID: d06ccf9b-26c9-4fb8-aa3e-eb9eba1c1ae9
    containerRuntimeVersion: containerd://1.3.3-k3s2
    kernelVersion: 5.4.0-1011-kvm
    kubeProxyVersion: v1.18.2+k3s1
    kubeletVersion: v1.18.2+k3s1
    machineID: 4eaf85aa16ec4abb84493f6f61a91936
    operatingSystem: linux
    osImage: Ubuntu 20.04 LTS
    systemUUID: 4eaf85aa-16ec-4abb-8449-3f6f61a91936

@haflinger
Copy link

I'm on Scaleway too. I have the same problem as @alekc . Adding the annotation "flannel.alpha.coreos.com/public-ip-overwrite" fix the problem for me too.

@xonvanetta
Copy link

xonvanetta commented Nov 22, 2020

I had something similar with this, although it wasnt really a problem for me but i still wanted it fixed, im using DO (digitalocean) and have a private ips for the cluster that it can talk with, the problem was that flannel would default to the external adress instead of the internal one, which caused it to use the public interface.

My workaround was to use --flannel-iface and set it to the private interface.

A thought i had in mind, could flannel just default to the first interface it finds which causes this kind of issue?
Edit found some documents that flannel would use first interface in some case

@alekc alekc mentioned this issue Dec 21, 2020
@agorgl
Copy link

agorgl commented Jun 2, 2021

Any update on this?
Having the same issue trying to make a cluster with docker containers in different machines which are essentially NATed nodes.

Both internal-ip and external-ip are set correctly on all nodes but flannel communication does not work because external flannel address (public-ip flannel param) is set here:

ExtAddr: ifaceAddr,
to the interface ip.
Either using the external ip here or providing an option to override this like --flannel-public-ip would suffice.

@trevorlinton
Copy link

FYI,

I had a similar issue and it had to do with using the latest ubuntu 21 and k3s, flannel will try and program a virtual interface and so will systemd and they conflict. Flannel then goes about and publishes arp tables with an incorrect mac address and hilarity ensues, see: flannel-io/flannel#1155

@agorgl
Copy link

agorgl commented Jun 9, 2021

Current issue is specific to the flannel implementation when agents/nodes are behind NAT, as demostrated in current the code

@stale
Copy link

stale bot commented Dec 6, 2021

This repository uses a bot to automatically label issues which have not had any activity (commit/comment/label) for 180 days. This helps us manage the community issues better. If the issue is still relevant, please add a comment to the issue so the bot can remove the label and we know it is still valid. If it is no longer relevant (or possibly fixed in the latest release), the bot will automatically close the issue in 14 days. Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants