Basic IPv6 support in DevStack

This commit enables basic support for IPv6 pod and service subnet. Also
two gates are added - an OVS and OVN one, both as non-voting at the
moment.

The DevStack changes are mostly about putting correct --ethertype on
SGs, using ip6tables and IPv6 subnetpool.

The Kuryr change required putting IPv6 address of K8s API in brackets.

Please note that this unblocks just the most basic use case, network
policy support will still not work with IPv6.

Depends-On: https://review.opendev.org/#/c/707103/
Implements: blueprint kuryr-ipv6-support
Change-Id: Id56b622a5038d8e5c072aa00a9f38a2418e6268f
This commit is contained in:
Michał Dulko 2020-02-07 15:47:05 +01:00
parent 911d65fea7
commit ca770736ed
7 changed files with 71 additions and 15 deletions

View File

@ -60,6 +60,17 @@
devstack_localrc:
KURYR_K8S_CONTAINERIZED_DEPLOYMENT: true
- job:
name: kuryr-kubernetes-tempest-containerized-ipv6
parent: kuryr-kubernetes-tempest-containerized
description: |
Kuryr-Kubernetes tempest job running kuryr containerized with IPv6 pod
and service networks
vars:
devstack_localrc:
KURYR_IPV6: true
voting: false
- job:
name: kuryr-kubernetes-tempest-containerized-lower-constraints
parent: kuryr-kubernetes-tempest-containerized

View File

@ -23,6 +23,8 @@
- kuryr-kubernetes-tempest-containerized-ovn
- kuryr-kubernetes-tempest-containerized-network-policy
- kuryr-kubernetes-tempest-multinode-containerized
- kuryr-kubernetes-tempest-containerized-ipv6
- kuryr-kubernetes-tempest-containerized-ovn-ipv6
gate:
jobs:
- kuryr-kubernetes-tempest

View File

@ -53,6 +53,17 @@
devstack_localrc:
KURYR_K8S_CONTAINERIZED_DEPLOYMENT: true
- job:
name: kuryr-kubernetes-tempest-containerized-ovn-ipv6
parent: kuryr-kubernetes-tempest-containerized-ovn
description: |
Kuryr-Kubernetes tempest job running kuryr containerized with OVN and
IPv6 pod and service networks
vars:
devstack_localrc:
KURYR_IPV6: true
voting: false
- job:
name: kuryr-kubernetes-tempest-dragonflow
parent: kuryr-kubernetes-tempest

View File

@ -84,12 +84,21 @@ function ovs_bind_for_kubelet() {
if [ -n "$port_number" ]; then
# if openstack-INPUT chain doesn't exist we create it in INPUT (for
# local development envs since openstack-INPUT is usually only in gates)
sudo iptables -I openstack-INPUT 1 \
-p tcp -s 0.0.0.0/0 -d 0.0.0.0/0 --dport $port_number -j ACCEPT || \
sudo iptables -I INPUT 1 \
-p tcp -m conntrack --ctstate NEW \
-m tcp --dport "$port_number" \
-m comment --comment "kuryr-devstack: Access to OpenShift API" -j ACCEPT
if [ "$KURYR_IPV6" == "False" ]; then
sudo iptables -I openstack-INPUT 1 \
-p tcp -s 0.0.0.0/0 -d 0.0.0.0/0 --dport $port_number -j ACCEPT || \
sudo iptables -I INPUT 1 \
-p tcp -m conntrack --ctstate NEW \
-m tcp --dport "$port_number" \
-m comment --comment "kuryr-devstack: Access to OpenShift API" -j ACCEPT
else
sudo ip6tables -I openstack-INPUT 1 \
-p tcp -s ::/0 -d ::/0 --dport $port_number -j ACCEPT || \
sudo ip6tables -I INPUT 1 \
-p tcp -m conntrack --ctstate NEW \
-m tcp --dport "$port_number" \
-m comment --comment "kuryr-devstack: Access to OpenShift API" -j ACCEPT
fi
fi
}
@ -196,6 +205,7 @@ function create_k8s_icmp_sg_rules {
security group rule create \
--project "$project_id" \
--protocol icmp \
--ethertype "$KURYR_ETHERTYPE" \
--"$direction" "$sg_id")
die_if_not_set $LINENO icmp_sg_rules \
"Failure creating icmp sg ${direction} rule for ${sg_id}"
@ -212,7 +222,6 @@ function create_k8s_icmp_sg_rules {
# split_allocation - Whether to allocate on all the subnet or only the
# latter half
function create_k8s_subnet {
# REVISIT(apuimedo): add support for IPv6
local project_id=$1
local net_name="$2"
local subnet_name="$3"
@ -224,7 +233,13 @@ function create_k8s_subnet {
split_allocation="${6:-False}"
subnet_params+="--ip-version 4 "
if [ "$KURYR_IPV6" == "False" ]; then
subnet_params+="--ip-version 4 "
else
# NOTE(dulek): K8s API won't accept subnets bigger than 20 bits.
# And 20 will totally be fine for us.
subnet_params+="--ip-version 6 --prefix-length 108 "
fi
subnet_params+="--no-dhcp --gateway none "
subnet_params+="--subnet-pool $subnetpool_id "

View File

@ -280,7 +280,15 @@ function configure_neutron_defaults {
# If a subnetpool is not passed, we get the one created in devstack's
# Neutron module
subnetpool_id=${KURYR_NEUTRON_DEFAULT_SUBNETPOOL_ID:-${SUBNETPOOL_V4_ID}}
KURYR_IPV6=$(trueorfalse False KURYR_IPV6)
if [ "$KURYR_IPV6" == "False" ]; then
export KURYR_ETHERTYPE=IPv4
subnetpool_id=${KURYR_NEUTRON_DEFAULT_SUBNETPOOL_ID:-${SUBNETPOOL_V4_ID}}
else
export KURYR_ETHERTYPE=IPv6
subnetpool_id=${KURYR_NEUTRON_DEFAULT_SUBNETPOOL_ID:-${SUBNETPOOL_V6_ID}}
fi
router=${KURYR_NEUTRON_DEFAULT_ROUTER:-$Q_ROUTER_NAME}
if [ "$router" != "$Q_ROUTER_NAME" ]; then
openstack --os-cloud devstack-admin --os-region "$REGION_NAME" \
@ -330,14 +338,14 @@ function configure_neutron_defaults {
openstack --os-cloud devstack-admin --os-region "$REGION_NAME" \
security group rule create --project "$project_id" \
--description "k8s service subnet allowed" \
--remote-ip "$service_cidr" --ethertype IPv4 --protocol tcp \
--remote-ip "$service_cidr" --ethertype "$KURYR_ETHERTYPE" --protocol tcp \
"$service_pod_access_sg_id"
# Since Octavia supports also UDP load balancing, we need to allow
# also udp traffic
openstack --os-cloud devstack-admin --os-region "$REGION_NAME" \
security group rule create --project "$project_id" \
--description "k8s service subnet UDP allowed" \
--remote-ip "$service_cidr" --ethertype IPv4 --protocol udp \
--remote-ip "$service_cidr" --ethertype "$KURYR_ETHERTYPE" --protocol udp \
"$service_pod_access_sg_id"
if [[ "$KURYR_K8S_OCTAVIA_MEMBER_MODE" == "L3" ]]; then
@ -365,14 +373,14 @@ function configure_neutron_defaults {
openstack --os-cloud devstack-admin --os-region "$REGION_NAME" \
security group rule create --project "$project_id" \
--description "k8s pod subnet allowed from k8s-pod-subnet" \
--remote-ip "$pod_cidr" --ethertype IPv4 --protocol tcp \
--remote-ip "$pod_cidr" --ethertype "$KURYR_ETHERTYPE" --protocol tcp \
"$octavia_pod_access_sg_id"
# Since Octavia supports also UDP load balancing, we need to allow
# also udp traffic
openstack --os-cloud devstack-admin --os-region "$REGION_NAME" \
security group rule create --project "$project_id" \
--description "k8s pod subnet allowed from k8s-pod-subnet" \
--remote-ip "$pod_cidr" --ethertype IPv4 --protocol udp \
--remote-ip "$pod_cidr" --ethertype "$KURYR_ETHERTYPE" --protocol udp \
"$octavia_pod_access_sg_id"
if [ -n "$sg_ids" ]; then
sg_ids+=",${octavia_pod_access_sg_id}"
@ -399,7 +407,7 @@ function configure_neutron_defaults {
openstack --os-cloud devstack-admin --os-region "$REGION_NAME" \
security group rule create --project "$project_id" \
--description "allow all ingress traffic" \
--ethertype IPv4 --ingress --protocol any \
--ethertype "$KURYR_ETHERTYPE" --ingress --protocol any \
"$allow_all_sg_id"
if [ -n "$sg_ids" ]; then
sg_ids+=",${allow_all_sg_id}"
@ -894,7 +902,7 @@ function configure_overcloud_vm_k8s_svc_sg {
awk '{if ($2=="default") print $1}')
openstack --os-cloud devstack-admin --os-region "$REGION_NAME" \
security group rule create --project "$project_id" \
--dst-port "$dst_port" "$security_group"
--dst-port "$dst_port" --ethertype "$KURYR_ETHERTYPE" "$security_group"
openstack port set "$KURYR_OVERCLOUD_VM_PORT" --security-group service_pod_access
}
@ -933,6 +941,9 @@ function update_tempest_conf_file {
if [[ "$KURYR_CONFIGMAP_MODIFIABLE" == "True" ]]; then
iniset $TEMPEST_CONFIG kuryr_kubernetes configmap_modifiable True
fi
if [[ "$KURYR_IPV6" == "True" ]]; then
iniset $TEMPEST_CONFIG kuryr_kubernetes ipv6 True
fi
iniset $TEMPEST_CONFIG kuryr_kubernetes validate_crd True
}

View File

@ -102,3 +102,5 @@ KURYR_CONTAINERS_USE_LOWER_CONSTRAINTS=${KURYR_CONTAINERS_USE_LOWER_CONSTRAINTS:
# Kuryr overcloud VM port's name
KURYR_OVERCLOUD_VM_PORT=${KURYR_OVERCLOUD_VM_PORT:-port0}
KURYR_IPV6=${KURYR_IPV6:-False}

View File

@ -14,6 +14,7 @@
# under the License.
from functools import partial
import ipaddress
import os
from kuryr.lib import utils
@ -80,6 +81,9 @@ def setup_kubernetes_client():
# K8s Pods.
host = os.environ['KUBERNETES_SERVICE_HOST']
port = os.environ['KUBERNETES_SERVICE_PORT_HTTPS']
addr = ipaddress.ip_address(host)
if addr.version == 6:
host = '[%s]' % host
api_root = "https://%s:%s" % (host, port)
_clients[_KUBERNETES_CLIENT] = k8s_client.K8sClient(api_root)