Run native netns cleanup in neutron

drive-by changes
- Use the same node selector for ovn metadata agent as ovs
  because both should be run on the same nodes
- fix ovn_metadata_agent endpoint config

Change-Id: I81402d6f877a469a6f4beeb5550bbb8f9e75cb43
This commit is contained in:
okozachenko 2023-09-05 23:13:15 +10:00 committed by Vladimir Kozhukalov
parent 5aadee0dc8
commit 6b55070317
9 changed files with 36 additions and 177 deletions

View File

@ -14,7 +14,7 @@ apiVersion: v1
appVersion: v1.0.0
description: OpenStack-Helm Neutron
name: neutron
version: 0.3.20
version: 0.3.21
home: https://docs.openstack.org/neutron/latest/
icon: https://www.openstack.org/themes/openstack/images/project-mascots/Neutron/OpenStack_Project_Neutron_vertical.png
sources:

View File

@ -1,157 +0,0 @@
#!/usr/bin/env python
import sys
import os
import time
import socket
from neutron.common import config
from oslo_config import cfg
from oslo_concurrency import processutils
from neutron.agent.linux import dhcp
from neutron.agent.l3 import namespaces
from neutron.agent.l3 import dvr_snat_ns
from neutron.agent.l3 import dvr_fip_ns
from neutron.cmd.netns_cleanup import setup_conf
from neutron.cmd.netns_cleanup import unplug_device
from neutron.cmd.netns_cleanup import eligible_for_deletion
from neutron.conf.agent import common as agent_config
from neutron.agent.linux import ip_lib
from keystoneauth1.identity import v3
from keystoneauth1 import session
from neutronclient.neutron import client as neutron_client
NS_PREFIXES = {'l3': [namespaces.NS_PREFIX, dvr_snat_ns.SNAT_NS_PREFIX,
dvr_fip_ns.FIP_NS_PREFIX]}
DHCP_NS_PREFIX = dhcp.NS_PREFIX
def get_neutron_creds():
opts = {'auth_url': os.getenv('OS_AUTH_URL', 'https://keystone-api.openstack.svc.cluster.local:5000/v3'),
'password': os.getenv('OS_PASSWORD','nopassword'),
'project_domain_name': os.getenv('OS_PROJECT_DOMAIN_NAME', 'default'),
'project_name': os.getenv('OS_PROJECT_NAME', 'admin'),
'user_domain_name': os.getenv('OS_USER_DOMAIN_NAME', 'default'),
'username': os.getenv('OS_USERNAME', 'admin'),
'cafile' : os.getenv('OS_CACERT','/var/lib/neutron/openstack-helm/openstack-helm.crt'),
'insecure' : os.getenv('NEUTRON_CLEANUP_INSECURE', 'true'),
'debug': os.getenv('NEUTRON_CLEANUP_DEBUG', 'true'),
'wait': os.getenv('NEUTRON_CLEANUP_TIMEOUT', '600')}
return opts
def ldestroy_namespace(conf, namespace):
try:
ip = ip_lib.IPWrapper(namespace=namespace)
if ip.netns.exists(namespace):
cmd = ['ip', 'netns', 'pids', namespace]
output = processutils.execute(*cmd, run_as_root=True, root_helper=conf.AGENT.root_helper)
for pid in output[0].splitlines():
utils.kill_process(pid, signal.SIGTERM, run_as_root=True, root_helper=conf.AGENT.root_helper)
for device in ip.get_devices():
unplug_device(device)
ip.garbage_collect_namespace()
except Exception as e:
sys.stderr.write("Error - unable to destroy namespace: {} : {}\n".format(namespace, e))
def net_list(neutron_get):
hosts = dict()
net_list = neutron_get.list_networks()
if net_list['networks']:
for item in net_list['networks']:
net_id=item['id']
dhcp_agents = neutron_get.list_dhcp_agent_hosting_networks(net_id)['agents']
agents = list()
if dhcp_agents:
for agent in dhcp_agents:
agents.append(agent['host'].split('.')[0])
hosts[net_id] = agents
return hosts
def sort_ns(all_ns, dhcp_prefix):
dhcp_ns = list()
not_dhcp_ns = list()
for ns in all_ns:
if ns[:len(dhcp_prefix)] == dhcp_prefix:
dhcp_ns.append(ns)
else:
not_dhcp_ns.append(ns)
return dhcp_ns, not_dhcp_ns
def del_bad_dhcp(dhcp_ns, dhcp_hosts, conf, dhcp_prefix, debug):
for ns in dhcp_ns:
cut_ns_name = ns[len(dhcp_prefix):]
if cut_ns_name in dhcp_hosts:
if hostname not in dhcp_hosts[cut_ns_name]:
ldestroy_namespace(conf, ns)
if debug:
sys.stderr.write("DEBUG: {} host {} deleted {} because host wrong\n"
.format(sys.argv[0], hostname, ns))
else:
if debug:
sys.stderr.write("DEBUG: {} host {} {} looks ok\n"
.format(sys.argv[0], hostname, ns))
else:
ldestroy_namespace(conf, ns)
if debug:
sys.stderr.write("DEBUG: {} host {} deleted {} because no related network found\n"
.format(sys.argv[0], hostname, ns))
def del_bad_not_dhcp(not_dhcp_ns, conf, debug):
for ns in not_dhcp_ns:
if eligible_for_deletion(conf, ns, conf.force):
ldestroy_namespace(conf, ns)
if debug:
sys.stderr.write("DEBUG: {} host {} deleted {} because no IP addr\n"
.format(sys.argv[0], hostname, ns))
if __name__ == "__main__":
conf = setup_conf()
cfg.CONF(sys.argv[1:])
opts = get_neutron_creds()
debug = False
verify= False
if opts.pop('debug') in ('true', '1', 'True'):
debug = True
insecure = opts.pop('insecure')
cafile = opts.pop('cafile')
if insecure in ('false', '0', 'False'):
verify = cafile
timeout = int(opts.pop('wait'))
conf()
config.setup_logging()
agent_config.setup_privsep()
auth = v3.Password(**opts)
hostname = socket.gethostname().split('.')[0]
while True:
try:
all_ns = ip_lib.list_network_namespaces()
sess = session.Session(auth=auth, verify=verify)
neutron_get = neutron_client.Client('2.0', session=sess)
dhcp_hosts = net_list(neutron_get)
if all_ns:
dhcp_ns, not_dhcp_ns = sort_ns(all_ns, DHCP_NS_PREFIX)
if dhcp_ns:
del_bad_dhcp(dhcp_ns, dhcp_hosts, conf, DHCP_NS_PREFIX, debug)
else:
if debug:
sys.stderr.write("DEBUG: {} host {} no dhcp ns found\n"
.format(sys.argv[0], hostname))
if not_dhcp_ns:
del_bad_not_dhcp(not_dhcp_ns, conf, debug)
else:
if debug:
sys.stderr.write("DEBUG: {} host {} no not_dhcp ns found\n"
.format(sys.argv[0], hostname))
else:
if debug:
sys.stderr.write("DEBUG: {} host {} no ns found at all\n"
.format(sys.argv[0], hostname))
except Exception as ex:
sys.stderr.write(
"Cleaning network namespaces caught an exception %s"
% str(ex))
time.sleep(30)
except:
sys.stderr.write(
"Cleaning network namespaces caught an exception")
time.sleep(30)
time.sleep(timeout)

View File

@ -0,0 +1,25 @@
#!/bin/bash
{{/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/}}
set -xe
# Run "neutron-netns-cleanup" every 5 minutes
while sleep 300; do
neutron-netns-cleanup \
--config-file /etc/neutron/neutron.conf \
--config-file /etc/neutron/dhcp_agent.ini \
--config-file /etc/neutron/l3_agent.ini
done

View File

@ -91,8 +91,8 @@ data:
{{ tuple "bin/_neutron-server.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
neutron-ironic-agent.sh: |
{{ tuple "bin/_neutron-ironic-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
neutron-netns-cleanup-cron.py: |
{{ tuple "bin/_neutron-netns-cleanup-cron.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
neutron-netns-cleanup-cron.sh: |
{{ tuple "bin/_neutron-netns-cleanup-cron.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
rabbit-init.sh: |
{{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }}
neutron-test-force-cleanup.sh: |

View File

@ -138,13 +138,13 @@ just set it along with nova_metadata_host.
{{- end -}}
{{- if empty $envAll.Values.conf.ovn_metadata_agent.DEFAULT.nova_metadata_host -}}
{{- $_ := tuple "compute_metadata" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" | set $envAll.Values.conf.metadata_agent.DEFAULT "nova_metadata_host" -}}
{{- $_ := tuple "compute_metadata" "internal" . | include "helm-toolkit.endpoints.hostname_fqdn_endpoint_lookup" | set $envAll.Values.conf.ovn_metadata_agent.DEFAULT "nova_metadata_host" -}}
{{- end -}}
{{- if empty $envAll.Values.conf.ovn_metadata_agent.cache.memcache_servers -}}
{{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set $envAll.Values.conf.metadata_agent.cache "memcache_servers" -}}
{{- $_ := tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" | set $envAll.Values.conf.ovn_metadata_agent.cache "memcache_servers" -}}
{{- end -}}
{{- if empty $envAll.Values.conf.ovn_metadata_agent.DEFAULT.nova_metadata_port -}}
{{- $_ := tuple "compute_metadata" "internal" "metadata" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set $envAll.Values.conf.metadata_agent.DEFAULT "nova_metadata_port" }}
{{- $_ := tuple "compute_metadata" "internal" "metadata" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | set $envAll.Values.conf.ovn_metadata_agent.DEFAULT "nova_metadata_port" }}
{{- end -}}
{{- if empty $envAll.Values.conf.neutron.DEFAULT.interface_driver -}}

View File

@ -68,14 +68,7 @@ spec:
{{ tuple $envAll $envAll.Values.pod.resources.netns_cleanup_cron | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
{{ dict "envAll" $envAll "application" "neutron_netns_cleanup_cron" "container" "neutron_netns_cleanup_cron" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
command:
- python
- /tmp/neutron-netns-cleanup-cron.py
- --config-file
- /etc/neutron/neutron.conf
- --config-file
- /etc/neutron/dhcp_agent.ini
- --config-file
- /etc/neutron/l3_agent.ini
- /tmp/neutron-netns-cleanup-cron.sh
env:
{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" false }}
{{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }}
@ -84,8 +77,8 @@ spec:
- name: pod-tmp
mountPath: /tmp
- name: neutron-bin
mountPath: /tmp/neutron-netns-cleanup-cron.py
subPath: neutron-netns-cleanup-cron.py
mountPath: /tmp/neutron-netns-cleanup-cron.sh
subPath: neutron-netns-cleanup-cron.sh
readOnly: true
- name: neutron-etc
mountPath: /etc/neutron/neutron.conf

View File

@ -80,7 +80,7 @@ spec:
{{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }}
{{ end }}
nodeSelector:
{{ .Values.labels.agent.ovn_metadata.node_selector_key }}: {{ .Values.labels.agent.ovn_metadata.node_selector_value }}
{{ .Values.labels.ovs.node_selector_key }}: {{ .Values.labels.ovs.node_selector_value }}
dnsPolicy: ClusterFirstWithHostNet
hostNetwork: true
{{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }}

View File

@ -64,9 +64,6 @@ labels:
metadata:
node_selector_key: openstack-control-plane
node_selector_value: enabled
ovn_metadata:
node_selector_key: openstack-compute-node
node_selector_value: enabled
l2gw:
node_selector_key: openstack-control-plane
node_selector_value: enabled

View File

@ -62,4 +62,5 @@ neutron:
- 0.3.18 Improve OVN support
- 0.3.19 Fix getting IP for interface when there are multiple IPs assigned
- 0.3.20 Add Ubuntu Jammy overrides
- 0.3.21 Run native netns cleanup
...