Skip to content

Commit

Permalink
Add support for the sidecar containers in neutron_metadata role
Browse files Browse the repository at this point in the history
Similarly to what was done in Tripleo, neutron agents which are spawning
some long running processes, like haproxy should run them in the sidecar
containers to avoid breakege in the dataplane when e.g. agent's container
is restarted.

This patch adds wrapper for haproxy sidecar in the neutron_metadata role.
This wrapper script is taken almost directly from the TripleO's
puppet module [1] and is just converted to jinja2 format and to support
only Podman as container_cli.

[1] https://opendev.org/openstack/puppet-tripleo/src/branch/master/templates/neutron/haproxy.epp
  • Loading branch information
slawqo committed Oct 11, 2023
1 parent 472ffaa commit 185bc8a
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 0 deletions.
6 changes: 6 additions & 0 deletions roles/edpm_neutron_metadata/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ edpm_neutron_metadata_images_download_retries: 5
edpm_neutron_metadata_config_src: /var/lib/openstack/configs/neutron-metadata
edpm_neutron_metadata_agent_config_dir: /var/lib/config-data/ansible-generated/neutron-ovn-metadata-agent
edpm_neutron_metadata_agent_log_dir: "/var/log/neutron"
edpm_neutron_metadata_agent_lib_dir: "/var/lib/neutron"

edpm_neutron_metadata_agent_image: "quay.io/podified-antelope-centos9/openstack-neutron-metadata-agent-ovn:current-podified"

Expand All @@ -19,6 +20,11 @@ edpm_neutron_metadata_common_volumes:
- /run/netns:/run/netns:shared
- /var/log/containers/neutron:/var/log/neutron:z
- /var/lib/kolla/config_files/ovn_metadata_agent.json:/var/lib/kolla/config_files/config.json:ro
- "{{ edpm_neutron_metadata_agent_lib_dir }}/ovn_metadata_haproxy_wrapper:/usr/local/bin/haproxy:ro"

# Sidecar containers settings
edpm_neutron_metadata_agent_sidecar_debug: false
edpm_neutron_metadata_agent_sidecar_haproxy_image_name: "{{ edpm_neutron_metadata_agent_image }}"

# Neutron conf
# DEFAULT
Expand Down
15 changes: 15 additions & 0 deletions roles/edpm_neutron_metadata/meta/argument_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ argument_specs:
default: /var/log/neutron
description: ''
type: str
edpm_neutron_metadata_agent_lib_dir:
default: "/var/lib/neutron"
description: |
The path to the directory containing files required by the Neutron OVN metadata
agent, like e.g. sidecar container wrappers.
type: str
edpm_neutron_metadata_agent_DEFAULT_debug:
default: 'True'
description: ''
Expand Down Expand Up @@ -107,9 +113,18 @@ argument_specs:
- /run/netns:/run/netns:shared
- /var/log/containers/neutron:/var/log/neutron:z
- /var/lib/kolla/config_files/ovn_metadata_agent.json:/var/lib/kolla/config_files/config.json:ro
- "{{ edpm_neutron_metadata_agent_lib_dir }}/ovn_metadata_haproxy_wrapper:/usr/local/bin/haproxy:ro"
description: ''
type: list
edpm_neutron_metadata_agent_config_dir:
default: /var/lib/config-data/ansible-generated/neutron-ovn-metadata-agent
description: 'The directory that contains configuration files for Neutron OVN Metadata Agent.'
type: str
edpm_neutron_metadata_agent_sidecar_debug:
default: false
description: ''
type: bool
edpm_neutron_metadata_agent_sidecar_haproxy_image_name:
default: "{{ edpm_neutron_metadata_agent_image }}"
description: Image used to spawn haproxy sidecar containers.
type: str
12 changes: 12 additions & 0 deletions roles/edpm_neutron_metadata/molecule/default/converge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,18 @@
hosts: all
gather_facts: true
become: true
pre_tasks:
- name: set basic user fact
set_fact:
ansible_user: "{{ lookup('env', 'USER') }}"
when:
- ansible_user is undefined

- name: set basic home fact
set_fact:
ansible_user_dir: "{{ lookup('env', 'HOME') }}"
when:
- ansible_user_dir is undefined
tasks:
- ansible.builtin.include_role:
name: "osp.edpm.edpm_neutron_metadata"
Expand Down
14 changes: 14 additions & 0 deletions roles/edpm_neutron_metadata/molecule/default/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,17 @@
that:
- metadata_config.stat.exists
fail_msg: "metadata agent config file does not exist"

- name: Ensure that haproxy wrapper script was created
block:
- name: haproxy wrapper exists
become: true
ansible.builtin.stat:
path: "/var/lib/neutron/ovn_metadata_haproxy_wrapper"
register: haproxy_wrapper

- name: assert that haproxy wrapper exists
ansible.builtin.assert:
that:
- haproxy_wrapper.stat.exists
fail_msg: "haproxy wrapper script does not exist"
12 changes: 12 additions & 0 deletions roles/edpm_neutron_metadata/tasks/install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@
path: "{{ item.path }}"
state: directory
setype: "container_file_t"
owner: "{{ item.owner | default(ansible_user) }}"
group: "{{ item.group | default(ansible_user) }}"
mode: "{{ item.mode | default(omit) }}"
loop:
- {'path': "{{ edpm_neutron_metadata_agent_config_dir }}"}
- {'path': "/var/log/containers/neutron"}
- {'path': "{{ edpm_neutron_metadata_agent_lib_dir }}", "mode": "0755"}

- name: Enable virt_sandbox_use_netlink for healthcheck
ansible.posix.seboolean:
Expand All @@ -32,3 +35,12 @@
when:
- ansible_facts.selinux is defined
- ansible_facts.selinux.status == "enabled"

- name: Configure sidecar containers scripts
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ edpm_neutron_metadata_agent_lib_dir }}/{{ item.dest }}"
setype: "container_file_t"
mode: "0755"
with_items:
- {"src": "wrappers/haproxy.j2", "dest": "ovn_metadata_haproxy_wrapper"}
57 changes: 57 additions & 0 deletions roles/edpm_neutron_metadata/templates/wrappers/haproxy.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/bin/bash

{% if edpm_neutron_metadata_agent_sidecar_debug -%}
set -x
{%- endif -%}

ARGS="$@"

IMAGE_NAME={{ edpm_neutron_metadata_agent_sidecar_haproxy_image_name }}

{% raw -%}
# Extract the network namespace UUID from the command line args provided by
# neutron. Typically of the form (with dnsmasq as an example):
#
# dnsmasq --no-hosts --no-resolv --except-interface=lo \
# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \
# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ...
NETNS=$(ip netns identify)
NAME=neutron-haproxy-${NETNS}
HAPROXY_CMD='$(if [ -f /usr/sbin/haproxy-systemd-wrapper ]; then echo "/usr/sbin/haproxy -Ds"; else echo "/usr/sbin/haproxy -Ws"; fi)'

CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t 1 podman"
LOGGING="--log-driver k8s-file --log-opt path=/var/log/containers/stdouts/${NAME}.log"
CMD='$HAPROXY'

LIST=$($CLI ps -a --filter name=neutron-haproxy- --format '{{.ID}}:{{.Names}}:{{.Status}}' | awk '{print $1}')

# Find orphaned containers left for dead after its main process terminated by neutron parent process
# FIXME(cjeanner): https://github.com/containers/libpod/issues/1703
ORPHANS=$(printf "%s\n" "${LIST}" | grep -E ":(Exited|Created)")
if [ -n "${ORPHANS}" ]; then
for orphant in $(printf "%s\n" "${ORPHANS}" | awk -F':' '{print $1}'); do
echo "Removing orphaned container ${orphant}"
# TODO(slaweq): script should at least log what error
# prevented to stop or rm orphaned container if there will be any error
$CLI stop ${orphant} || true
$CLI rm -f ${orphant} || true
done
fi

# If the NAME is already taken by a container, give it an unique name
printf "%s\n" "${LIST}" | grep -q "${NAME}$" && NAME="${NAME}-$(date +%Y-%m-%d-%H%M%S-%N)"
echo "Starting a new child container ${NAME}"
$CLI run --detach ${LOGGING} \
-v /var/lib/config-data/puppet-generated/neutron/etc/neutron:/etc/neutron:ro \
-v /run/netns:/run/netns:shared \
-v /var/lib/neutron:/var/lib/neutron:shared \
-v /dev/log:/dev/log \
--net host \
--pid host \
--cgroupns host \
--privileged \
-u root \
--name $NAME \
${IMAGE_NAME} \
/bin/bash -c "HAPROXY=\"$HAPROXY_CMD\"; exec $CMD $ARGS"
{%- endraw %}

0 comments on commit 185bc8a

Please sign in to comment.