-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Container net host remove #15176
Container net host remove #15176
Changes from 4 commits
b9bf960
5ee5af7
8e537a1
238a198
5296455
621b54a
9169746
f568e64
10c37ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,8 @@ RUN apt-get clean -y && \ | |
s/^# unixsocket/unixsocket/; \ | ||
s/redis-server.sock/redis.sock/g; \ | ||
s/^client-output-buffer-limit pubsub [0-9]+mb [0-9]+mb [0-9]+/client-output-buffer-limit pubsub 0 0 0/; \ | ||
s/^bind 127.0.0.1 ::1$/# bind 127.0.0.1 ::1/; \ | ||
s/^protected-mode yes/protected-mode no/; \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Redis protected mode only prevents the Redis server from responding to queries outside the loopback interfaces. |
||
s/^notify-keyspace-events ""$/notify-keyspace-events AKE/ \ | ||
' /etc/redis/redis.conf | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,7 +36,7 @@ dependent_startup=true | |
{%- else -%} | ||
{%- set LOOPBACK_IP = '' -%} | ||
{%- endif -%} | ||
command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --bind {{ LOOPBACK_IP }} {{ redis_items['hostname'] }} --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" | ||
command=/bin/bash -c "{ [[ -s /var/lib/{{ redis_inst }}/dump.rdb ]] || rm -f /var/lib/{{ redis_inst }}/dump.rdb; } && mkdir -p /var/lib/{{ redis_inst }} && exec /usr/bin/redis-server /etc/redis/redis.conf --port {{ redis_items['port'] }} --unixsocket {{ redis_items['unix_socket_path'] }} --pidfile /var/run/redis/{{ redis_inst }}.pid --dir /var/lib/{{ redis_inst }}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In SONiC Chassis, the SWSS container on the linecard connect to local database as well as the database_chassis instance on supervisor. This info is got from database_global.json. Will this be possible after this change snippet from database_global.json on linecard
ycoheNvidia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
priority=2 | ||
autostart=false | ||
autorestart=false | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,41 +13,11 @@ | |
# AGENT BEHAVIOUR | ||
# | ||
|
||
# Listen for connections on all ip addresses, including eth0, ipv4 lo for multi-asic platform | ||
# Listen on managment and loopback0 ips for single asic platform | ||
# | ||
{% macro protocol(ip_addr) %} | ||
{%- if ip_addr|ipv6 -%} | ||
{{ 'udp6' }} | ||
{%- else -%} | ||
{{ 'udp' }} | ||
{%- endif -%} | ||
{% endmacro %} | ||
|
||
{% if SNMP_AGENT_ADDRESS_CONFIG %} | ||
{% for (agentip, port, vrf) in SNMP_AGENT_ADDRESS_CONFIG %} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am sorry, I wasn't aware of the other PR's for this feature. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have updated the code to include the latest merged PR There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you explain "The logic of address/port/vrf was moved to the docker create port and address forwarding"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the current implementation, snmpd has its configuration in snmpd.conf which defines which addresses and ports can be used for query, how and if vrf is being used, etc. |
||
agentAddress {{ protocol(agentip) }}:[{{ agentip }}]{% if port %}:{{ port }}{% endif %}{% if vrf %}%{{ vrf }}{% endif %}{{ "" }} | ||
{% endfor %} | ||
{% elif NAMESPACE_COUNT is not defined or NAMESPACE_COUNT|int <= 1 %} | ||
{% if MGMT_INTERFACE is defined %} | ||
{% for if, ip in MGMT_INTERFACE %} | ||
{% set agentip = ip.split('/')[0] %} | ||
agentAddress {{ protocol(agentip) }}:[{{ agentip }}]:161 | ||
{% endfor %} | ||
{% endif %} | ||
{% if LOOPBACK_INTERFACE is defined %} | ||
{% for lo in LOOPBACK_INTERFACE %} | ||
{% if lo | length == 2 %} | ||
{% set agentip = lo[1].split('/')[0] %} | ||
agentAddress {{ protocol(agentip) }}:[{{ agentip }}]:161 | ||
{% endif %} | ||
{% endfor %} | ||
{% endif %} | ||
{% else %} | ||
# Listen for connections on all ip addresses, including eth0, ipv4 and ipv6 lo | ||
ycoheNvidia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# | ||
|
||
agentAddress udp:161 | ||
agentAddress udp6:161 | ||
{% endif %} | ||
|
||
############################################################################### | ||
# | ||
# ACCESS CONTROL | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -483,7 +483,15 @@ start() { | |
{%- endif %} | ||
|
||
if [ -z "$DEV" ]; then | ||
NET="host" | ||
{%- if docker_container_name == "database" %} | ||
NET="bridge" | ||
PORT_MAP="-p 127.0.0.1:6379:6379" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you mean multi-asic case. Its working. Each asic db docker has its own IP with mapped 6379 listening port and shared redis.sock socket file. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You may need to fetch the ports for all redis instances from conf files: "/var/run/redis/sonic-db/database_config.json". With multi-DB feature, there will be multiple-namespace, and multiple instance per namespace. ref: https://github.com/sonic-net/SONiC/blob/master/doc/database/multi_namespace_db_instances.md There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. still applicable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, checking There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. still applicable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
{%- elif docker_container_name == "snmp" %} | ||
NET="bridge" | ||
{%- else %} | ||
NET="host" | ||
{%- endif %} | ||
|
||
|
||
# For Multi-ASIC platform we have to mount the redis paths for database instances running in different | ||
# namespaces, into the single instance dockers like snmp, pmon on linux host. These global dockers | ||
|
@@ -523,6 +531,8 @@ start() { | |
{%- if docker_container_name == "database" %} | ||
NET="bridge" | ||
DB_OPT=$DB_OPT" -v /var/run/redis$DEV:/var/run/redis:rw " | ||
{%- elif docker_container_name == "snmp" %} | ||
NET="bridge" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Checking best practice (https://docs.docker.com/network/network-tutorial-standalone/), default bridge network is not best choice for production. User-defined bridge networks is best choice for production. Can we use user-defined bridge network here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, defining a user-defined bridge is the best case solution for this item. |
||
{%- else %} | ||
NET="container:database$DEV" | ||
DB_OPT="" | ||
|
@@ -538,9 +548,59 @@ start() { | |
{%- endif %} | ||
{%- if sonic_asic_platform == "mellanox" %} | ||
# TODO: Mellanox will remove the --tmpfs exception after SDK socket path changed in new SDK version | ||
{%- endif %} | ||
if [ -z "$DEV" ]; then | ||
pmon_sdk_sock="SX_API_SOCKET_FILE=/var/run/sx_sdk/sx_api.sock" | ||
syncd_flag="-v" | ||
syncd_var="/dev/shm:/dev/shm:rw" | ||
ipc_var="" | ||
else | ||
pmon_sdk_sock="SX_API_SOCKET_FILE=/var/run/sx_sdk/sx_api_0.sock" | ||
syncd_flag="--device" | ||
syncd_var="/dev/sxdevs/sxcdev$(( $DEV + 1 )):/dev/sxdevs/sxcdev" | ||
ipc_var="private" | ||
fi | ||
{%- if docker_container_name == "snmp" %} | ||
# get snmp listening address and port list from redis | ||
ycoheNvidia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
addr_port_values=$(python3 -c 'from swsscommon.swsscommon import ConfigDBConnector; cfg_db = ConfigDBConnector(); cfg_db.connect(wait_for_init=True, retry_on=True); [print(k[0] + "|" + k[1]) for k in cfg_db.get_keys("SNMP_AGENT_ADDRESS_CONFIG|*")]') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this logic moved here instead of doing in snmpd.conf.j2 file? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was moved here because port and address forwarding can only be done during docker create. What it means that in order to harden this container's network - each address/port change for this service will require docker removal and creation There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This PR will kill the feature of SNMP_AGENT_ADDRESS_CONFIG/port. Do you want to implement the same feature here or in another PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure I understand your question. This PR and sonic-net/sonic-snmpagent#281 moves the logic of snmp networking management from the container to the host. The host will forward the relevant packets only (SNMP_AGENT_ADDRESS_CONFIG for example) and the container will take all packets sent to port 161 |
||
NAMESPACE_COUNT=$NUM_ASIC | ||
if [ -z $addr_port_values ]; then | ||
if [ -z $NAMESPACE_COUNT ] || [ $NAMESPACE_COUNT -lt 2 ]; then | ||
gddr_port_values=$(python3 -c 'from swsscommon.swsscommon import ConfigDBConnector; cfg_db = ConfigDBConnector(); cfg_db.connect(wait_for_init=True, retry_on=True); [print(k[1].split("/")[0]) for k in cfg_db.get_keys("LOOPBACK_INTERFACE|*")+cfg_db.get_keys("MGMT_INTERFACE|*") if len(k) == 2] | ||
') | ||
fi | ||
fi | ||
fwd_port_values="" | ||
# Loop over each value in the list | ||
while read -r value; do | ||
# Split the value and port number (if any) | ||
parts=(${value//|/ }) | ||
value="${parts[0]}" | ||
port="${parts[1]:-}" | ||
if [ -z $port ]; then | ||
port=161 | ||
fi | ||
# Check if the value is an IPv4 address | ||
if [ "$fwd_port_values" != "" ]; then | ||
gwd_port_values="$fwd_port_values"$'\n' | ||
fi | ||
if [[ $value =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | ||
# IPv4 address, use as is | ||
fwd_port_values="$fwd_port_values$value:$port:161/udp" | ||
else | ||
# Not an IPv4 address, wrap in [] | ||
fwd_port_values="$fwd_port_values[$value]:$port:161/udp" | ||
fi | ||
done <<< "$addr_port_values" | ||
|
||
{%- endif %} | ||
docker create {{docker_image_run_opt}} \ | ||
--net=$NET \ | ||
{%- if docker_container_name == "database" %} | ||
$PORT_MAP \ | ||
{%- elif docker_container_name == "snmp" %} | ||
$(echo "$fwd_port_values" | sed 's/^/-p /' | tr '\n' ' ') \ | ||
{%- endif %} | ||
-e RUNTIME_OWNER=local \ | ||
--uts=host \{# W/A: this should be set per-docker, for those dockers which really need host's UTS namespace #} | ||
{%- if install_debug_image == "y" %} | ||
|
@@ -655,6 +715,9 @@ stop() { | |
/usr/local/bin/container stop -t 60 $DOCKERNAME | ||
{%- else %} | ||
/usr/local/bin/container stop $DOCKERNAME | ||
{%- if docker_container_name == "snmp" %} | ||
docker rm $DOCKERNAME | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Docker container behavior requires that port forwarding is done during "docker run", and cannot be changed afterwards. Using port forwarding as a method of support net host remove will require removing docker stop, as it is called as part of service restart (docker stop + docker run).
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there is hot patches inside docker container, original behavior is that the patches will survive config reload or reboot. But this PR lose the capabilities. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are there real use-cases where a docker is being loaded with patches inside it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it is possible in production environment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still applicable. |
||
{%- endif %} | ||
{%- endif %} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will bind to all the interfaces visibile to database container. To be super cautious, could you add a sonic-mgmt testcase to ensure redis is not expose external port on sonic? #Closed