Skip to content
Snippets Groups Projects
Commit f599c2a6 authored by Simon Lelievre's avatar Simon Lelievre Committed by Kubernetes Prow Robot
Browse files

add macvlan cni to kubespray (#4901)

* add macvlan cni to kubespray

* macvlan: lint yaml files and fix sample config file

* macvlan: add OWNERS file

* add macvlan to README

* macvlan : CI first shoot

* macvlan : CI add full masquerade

* delegate retrive pod cidr to master only

* macvlan: add config for CI

* macvlan: add netchecker deployment
parent bc7d1f36
No related branches found
No related tags found
No related merge requests found
Showing
with 347 additions and 5 deletions
...@@ -71,6 +71,11 @@ packet_ubuntu18-cilium-sep: ...@@ -71,6 +71,11 @@ packet_ubuntu18-cilium-sep:
<<: *packet <<: *packet
when: manual when: manual
packet_debian9-macvlan-sep:
stage: deploy-part2
<<: *packet
when: on_success
packet_debian9-calico-upgrade: packet_debian9-calico-upgrade:
stage: deploy-part2 stage: deploy-part2
<<: *packet <<: *packet
......
...@@ -178,6 +178,8 @@ You can choose between 6 network plugins. (default: `calico`, except Vagrant use ...@@ -178,6 +178,8 @@ You can choose between 6 network plugins. (default: `calico`, except Vagrant use
iptables for network policies, and BGP for ods L3 networking (with optionally BGP peering with out-of-cluster BGP peers). iptables for network policies, and BGP for ods L3 networking (with optionally BGP peering with out-of-cluster BGP peers).
It can also optionally advertise routes to Kubernetes cluster Pods CIDRs, ClusterIPs, ExternalIPs and LoadBalancerIPs. It can also optionally advertise routes to Kubernetes cluster Pods CIDRs, ClusterIPs, ExternalIPs and LoadBalancerIPs.
- [macvlan](docs/macvlan.md): Macvlan is a Linux network driver. Pods have their own unique Mac and Ip address, connected directly the physical (layer 2) network.
- [multus](docs/multus.md): Multus is a meta CNI plugin that provides multiple network interface support to pods. For each interface Multus delegates CNI calls to secondary CNI plugins such as Calico, macvlan, etc. - [multus](docs/multus.md): Multus is a meta CNI plugin that provides multiple network interface support to pods. For each interface Multus delegates CNI calls to secondary CNI plugins such as Calico, macvlan, etc.
The choice is defined with the variable `kube_network_plugin`. There is also an The choice is defined with the variable `kube_network_plugin`. There is also an
......
Macvlan
===============
How to use it :
-------------
* Enable macvlan in `group_vars/k8s-cluster/k8s-cluster.yml`
```
...
kube_network_plugin: macvlan
...
```
* Adjust the `macvlan_interface` in `group_vars/k8s-cluster/k8s-net-macvlan.yml` or by host in the `host.yml` file:
```
all:
hosts:
node1:
ip: 10.2.2.1
access_ip: 10.2.2.1
ansible_host: 10.2.2.1
macvlan_interface: ens5
```
Issue encountered :
-------------
- Service DNS
reply from unexpected source:
add `kube_proxy_masquerade_all: true` in `group_vars/all/all.yml`
- Disable nodelocaldns
The nodelocal dns IP is not reacheable.
Disable it in `sample/group_vars/k8s-cluster/k8s-cluster.yml`
```
enable_nodelocaldns: false
```
---
# private interface, on a l2-network
macvlan_interface: "eth1"
# Enable nat in default gateway network interface
enable_nat_default_gateway: true
...@@ -114,7 +114,7 @@ KUBELET_HOSTNAME="--hostname-override={{ kube_override_hostname }}" ...@@ -114,7 +114,7 @@ KUBELET_HOSTNAME="--hostname-override={{ kube_override_hostname }}"
{% endif %} {% endif %}
KUBELET_ARGS="{{ kubelet_args_base }} {{ kubelet_args_dns }} {{ kube_reserved }} {% if node_taints|default([]) %}--register-with-taints={{ node_taints | join(',') }} {% endif %}--node-labels={{ all_node_labels | join(',') }} {% if kube_feature_gates %} --feature-gates={{ kube_feature_gates|join(',') }} {% endif %} {% if kubelet_custom_flags is string %} {{kubelet_custom_flags}} {% else %}{% for flag in kubelet_custom_flags %} {{flag}} {% endfor %}{% endif %}{% if inventory_hostname in groups['kube-node'] %}{% if kubelet_node_custom_flags is string %} {{kubelet_node_custom_flags}} {% else %}{% for flag in kubelet_node_custom_flags %} {{flag}} {% endfor %}{% endif %}{% endif %}" KUBELET_ARGS="{{ kubelet_args_base }} {{ kubelet_args_dns }} {{ kube_reserved }} {% if node_taints|default([]) %}--register-with-taints={{ node_taints | join(',') }} {% endif %}--node-labels={{ all_node_labels | join(',') }} {% if kube_feature_gates %} --feature-gates={{ kube_feature_gates|join(',') }} {% endif %} {% if kubelet_custom_flags is string %} {{kubelet_custom_flags}} {% else %}{% for flag in kubelet_custom_flags %} {{flag}} {% endfor %}{% endif %}{% if inventory_hostname in groups['kube-node'] %}{% if kubelet_node_custom_flags is string %} {{kubelet_node_custom_flags}} {% else %}{% for flag in kubelet_node_custom_flags %} {{flag}} {% endfor %}{% endif %}{% endif %}"
{% if kube_network_plugin is defined and kube_network_plugin in ["calico", "canal", "cni", "flannel", "weave", "contiv", "cilium", "kube-router"] %} {% if kube_network_plugin is defined and kube_network_plugin in ["calico", "canal", "cni", "flannel", "weave", "contiv", "cilium", "kube-router", "macvlan"] %}
KUBELET_NETWORK_PLUGIN="--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin" KUBELET_NETWORK_PLUGIN="--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"
{% elif kube_network_plugin is defined and kube_network_plugin == "cloud" %} {% elif kube_network_plugin is defined and kube_network_plugin == "cloud" %}
KUBELET_NETWORK_PLUGIN="--hairpin-mode=promiscuous-bridge --network-plugin=kubenet" KUBELET_NETWORK_PLUGIN="--hairpin-mode=promiscuous-bridge --network-plugin=kubenet"
......
...@@ -62,7 +62,7 @@ KUBELET_HOSTNAME="--hostname-override={{ kube_override_hostname }}" ...@@ -62,7 +62,7 @@ KUBELET_HOSTNAME="--hostname-override={{ kube_override_hostname }}"
{% endif %} {% endif %}
KUBELET_ARGS="{{ kubelet_args_base }} {% if node_taints|default([]) %}--register-with-taints={{ node_taints | join(',') }} {% endif %}--node-labels={{ all_node_labels | join(',') }} {% if kube_feature_gates %} --feature-gates={{ kube_feature_gates|join(',') }} {% endif %} {% if kubelet_custom_flags is string %} {{kubelet_custom_flags}} {% else %}{% for flag in kubelet_custom_flags %} {{flag}} {% endfor %}{% endif %}{% if inventory_hostname in groups['kube-node'] %}{% if kubelet_node_custom_flags is string %} {{kubelet_node_custom_flags}} {% else %}{% for flag in kubelet_node_custom_flags %} {{flag}} {% endfor %}{% endif %}{% endif %}" KUBELET_ARGS="{{ kubelet_args_base }} {% if node_taints|default([]) %}--register-with-taints={{ node_taints | join(',') }} {% endif %}--node-labels={{ all_node_labels | join(',') }} {% if kube_feature_gates %} --feature-gates={{ kube_feature_gates|join(',') }} {% endif %} {% if kubelet_custom_flags is string %} {{kubelet_custom_flags}} {% else %}{% for flag in kubelet_custom_flags %} {{flag}} {% endfor %}{% endif %}{% if inventory_hostname in groups['kube-node'] %}{% if kubelet_node_custom_flags is string %} {{kubelet_node_custom_flags}} {% else %}{% for flag in kubelet_node_custom_flags %} {{flag}} {% endfor %}{% endif %}{% endif %}"
{% if kube_network_plugin is defined and kube_network_plugin in ["calico", "canal", "cni", "flannel", "weave", "contiv", "cilium", "kube-router"] %} {% if kube_network_plugin is defined and kube_network_plugin in ["calico", "canal", "cni", "flannel", "weave", "contiv", "cilium", "kube-router", "macvlan"] %}
KUBELET_NETWORK_PLUGIN="--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin" KUBELET_NETWORK_PLUGIN="--network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin"
{% elif kube_network_plugin is defined and kube_network_plugin == "cloud" %} {% elif kube_network_plugin is defined and kube_network_plugin == "cloud" %}
KUBELET_NETWORK_PLUGIN="--hairpin-mode=promiscuous-bridge --network-plugin=kubenet" KUBELET_NETWORK_PLUGIN="--hairpin-mode=promiscuous-bridge --network-plugin=kubenet"
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
- name: Stop if unknown network plugin - name: Stop if unknown network plugin
assert: assert:
that: kube_network_plugin in ['calico', 'canal', 'flannel', 'weave', 'cloud', 'cilium', 'cni', 'contiv', 'kube-router'] that: kube_network_plugin in ['calico', 'canal', 'flannel', 'weave', 'cloud', 'cilium', 'cni', 'contiv', 'kube-router', 'macvlan']
when: kube_network_plugin is defined when: kube_network_plugin is defined
ignore_errors: "{{ ignore_assert_errors }}" ignore_errors: "{{ ignore_assert_errors }}"
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
- "/opt/cni/bin" - "/opt/cni/bin"
- "/var/lib/calico" - "/var/lib/calico"
when: when:
- kube_network_plugin in ["calico", "weave", "canal", "flannel", "contiv", "cilium", "kube-router"] - kube_network_plugin in ["calico", "weave", "canal", "flannel", "contiv", "cilium", "kube-router", "macvlan"]
- inventory_hostname in groups['k8s-cluster'] - inventory_hostname in groups['k8s-cluster']
tags: tags:
- network - network
......
# See the OWNERS docs at https://go.k8s.io/owners
approvers:
- simon
reviewers:
- simon
---
macvlan_interface: eth0
enable_nat_default_gateway: true
# sysctl_file_path to add sysctl conf to
sysctl_file_path: "/etc/sysctl.d/99-sysctl.conf"
#!/bin/bash
POSTDOWNNAME="/etc/sysconfig/network-scripts/post-down-$1"
if [ -x $POSTDOWNNAME ]; then
exec $POSTDOWNNAME
fi
#!/bin/bash
#
# initscripts-macvlan
# Copyright (C) 2014 Lars Kellogg-Stedman
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
. /etc/init.d/functions
cd /etc/sysconfig/network-scripts
. ./network-functions
[ -f ../network ] && . ../network
CONFIG=${1}
need_config ${CONFIG}
source_config
OTHERSCRIPT="/etc/sysconfig/network-scripts/ifdown-${REAL_DEVICETYPE}"
if [ ! -x ${OTHERSCRIPT} ]; then
OTHERSCRIPT="/etc/sysconfig/network-scripts/ifdown-eth"
fi
${OTHERSCRIPT} ${CONFIG}
ip link del ${DEVICE} type ${TYPE:-macvlan}
#!/bin/bash
POSTUPNAME="/etc/sysconfig/network-scripts/post-up-$1"
if [ -x $POSTUPNAME ]; then
exec $POSTUPNAME
fi
#!/bin/bash
#
# initscripts-macvlan
# Copyright (C) 2014 Lars Kellogg-Stedman
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
. /etc/init.d/functions
cd /etc/sysconfig/network-scripts
. ./network-functions
[ -f ../network ] && . ../network
CONFIG=${1}
need_config ${CONFIG}
source_config
OTHERSCRIPT="/etc/sysconfig/network-scripts/ifup-${REAL_DEVICETYPE}"
if [ ! -x ${OTHERSCRIPT} ]; then
OTHERSCRIPT="/etc/sysconfig/network-scripts/ifup-eth"
fi
ip link add \
link ${MACVLAN_PARENT} \
name ${DEVICE} \
type ${TYPE:-macvlan} mode ${MACVLAN_MODE:-private}
${OTHERSCRIPT} ${CONFIG}
---
- name: Macvlan | restart network
command: /bin/true
notify:
- Macvlan | reload network
when: not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"]
- name: Macvlan | reload network
service:
name: >-
{% if ansible_os_family == "RedHat" -%}
network
{%- elif ansible_distribution == "Ubuntu" and ansible_distribution_release == "bionic" -%}
systemd-networkd
{%- elif ansible_os_family == "Debian" -%}
networking
{%- endif %}
state: restarted
when: not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] and kube_network_plugin not in ['canal', 'calico']
---
- name: Macvlan | Set cni directory permissions
file:
path: /opt/cni/bin
state: directory
owner: kube
recurse: true
mode: 0755
- name: Macvlan | Copy cni plugins
unarchive:
src: "{{ local_release_dir }}/cni-plugins-linux-{{ image_arch }}-{{ cni_version }}.tgz"
dest: "/opt/cni/bin"
mode: 0755
remote_src: yes
- name: Macvlan | Retreive Pod Cidr
command: "{{ bin_dir }}/kubectl get nodes {{ kube_override_hostname | default(inventory_hostname) }} -o jsonpath='{.spec.podCIDR}'"
register: node_pod_cidr_cmd
delegate_to: "{{ groups['kube-master'][0] }}"
- name: Macvlan | set node_pod_cidr
set_fact:
node_pod_cidr={{ node_pod_cidr_cmd.stdout }}
- name: Macvlan | Retreive default gateway network interface
become: false
raw: ip -4 route list 0/0 | sed 's/.*dev \([[:alnum:]]*\).*/\1/'
register: node_default_gateway_interface_cmd
- name: Macvlan | set node_default_gateway_interface
set_fact:
node_default_gateway_interface={{ node_default_gateway_interface_cmd.stdout | trim }}
- name: Macvlan | Install network gateway interface on debian
template:
src: debian-network-macvlan.cfg.j2
dest: /etc/network/interfaces.d/60-mac0.cfg
notify: Macvlan | restart network
when: ansible_os_family in ["Debian"]
- name: Macvlan | Install macvlan script on centos
copy:
src: "{{ item }}"
dest: /etc/sysconfig/network-scripts/
owner: root
group: root
mode: "0755"
with_fileglob:
- files/*
when: ansible_os_family in ["CentOS","RedHat"]
- name: Macvlan | Install post-up script on centos
copy:
src: "files/ifup-local"
dest: /sbin/
owner: root
group: root
mode: "0755"
when: ansible_os_family in ["CentOS","RedHat"] and enable_nat_default_gateway
- name: Macvlan | Install network gateway interface on centos
template:
src: "{{ item.src }}.j2"
dest: "/etc/sysconfig/network-scripts/{{ item.dst }}"
with_items:
- {src: centos-network-macvlan.cfg, dst: ifcfg-mac0 }
- {src: centos-routes-macvlan.cfg, dst: route-mac0 }
- {src: centos-postup-macvlan.cfg, dst: post-up-mac0 }
notify: Macvlan | restart network
when: ansible_os_family in ["CentOS","RedHat"]
- name: Macvlan | Install service nat via gateway on coreos
template:
src: coreos-service-nat_ouside.j2
dest: /etc/systemd/system/enable_nat_ouside.service
when: ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] and enable_nat_default_gateway
- name: Macvlan | Enable service nat via gateway on coreos
command: "{{ item }}"
with_items:
- systemctl daemon-reload
- systemctl enable enable_nat_ouside.service
when: ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] and enable_nat_default_gateway
- name: Macvlan | Install network gateway interface on coreos
template:
src: "{{ item.src }}.j2"
dest: "/etc/systemd/network/{{ item.dst }}"
with_items:
- {src: coreos-device-macvlan.cfg, dst: macvlan.netdev }
- {src: coreos-interface-macvlan.cfg, dst: output.network }
- {src: coreos-network-macvlan.cfg, dst: macvlan.network }
notify: Macvlan | restart network
when: ansible_os_family in ["CoreOS", "Container Linux by CoreOS"]
- name: Macvlan | Install cni definition for Macvlan
template:
src: 10-macvlan.conf.j2
dest: /etc/cni/net.d/10-macvlan.conf
- name: Macvlan | Install loopback definition for Macvlan
template:
src: 99-loopback.conf.j2
dest: /etc/cni/net.d/99-loopback.conf
- name: Enable net.ipv4.conf.all.arp_notify in sysctl
sysctl:
name: net.ipv4.conf.all.arp_notify
value: 1
sysctl_set: yes
sysctl_file: "{{ sysctl_file_path }}"
state: present
reload: yes
{
"cniVersion": "0.3.0",
"name": "mynet",
"type": "macvlan",
"master": "{{ macvlan_interface }}",
"hairpinMode": true,
"ipam": {
"type": "host-local",
"subnet": "{{ node_pod_cidr }}",
"routes": [
{ "dst": "0.0.0.0/0" }
],
"gateway": "{{ node_pod_cidr|ipaddr('net')|ipaddr(1)|ipaddr('address') }}"
}
}
{
"cniVersion": "0.2.0",
"name": "lo",
"type": "loopback"
}
DEVICE=mac0
DEVICETYPE=macvlan
TYPE=macvlan
BOOTPROTO=none
ONBOOT=yes
NM_CONTROLLED=no
MACVLAN_PARENT=eth2
MACVLAN_MODE=bridge
IPADDR={{ node_pod_cidr|ipaddr('net')|ipaddr(1)|ipaddr('address') }}
NETMASK={{ node_pod_cidr|ipaddr('netmask') }}
NETWORK={{ node_pod_cidr|ipaddr('network') }}
{% if enable_nat_default_gateway %}
iptables -t nat -D POSTROUTING -s {{ node_pod_cidr|ipaddr('net') }} -o {{ node_default_gateway_interface }} -j MASQUERADE
{% endif %}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment