summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLingxian Kong <anlin.kong@gmail.com>2021-06-18 11:30:03 +1200
committerLingxian Kong <anlin.kong@gmail.com>2021-06-22 19:10:14 +1200
commitb050996b9f6df738a0f68ac36a5b5f17f8bb2bc2 (patch)
tree13a5124d6ea4b9d13e892601034bc5ac004284dc
parent6d2ab68a8aa0406ee6320e778b8e290827c9e730 (diff)
downloadtrove-b050996b9f6df738a0f68ac36a5b5f17f8bb2bc2.tar.gz
Use bridge network for db container
- Changed the network mode of database container to "bridge" and exposed the service ports. - Use socket file to connect with the database. - Upgrade the backup container image for postgressql. Change-Id: Id5b119f8a474befc3a2cd6e061bbffc4ae5f7bb6
-rw-r--r--backup/Dockerfile2
-rw-r--r--backup/utils/postgresql.py12
-rw-r--r--integration/scripts/files/elements/guest-agent/package-installs.yaml2
-rw-r--r--releasenotes/notes/xena-container-bridge-network.yaml14
-rw-r--r--trove/common/cfg.py2
-rw-r--r--trove/guestagent/datastore/mysql_common/manager.py2
-rw-r--r--trove/guestagent/datastore/mysql_common/service.py11
-rw-r--r--trove/guestagent/datastore/postgres/service.py23
-rw-r--r--trove/guestagent/datastore/service.py6
-rw-r--r--trove/guestagent/strategies/replication/mysql_base.py1
-rw-r--r--trove/guestagent/utils/docker.py7
11 files changed, 71 insertions, 11 deletions
diff --git a/backup/Dockerfile b/backup/Dockerfile
index f60149c7..3827bfc7 100644
--- a/backup/Dockerfile
+++ b/backup/Dockerfile
@@ -18,7 +18,7 @@ WORKDIR /opt/trove/backup
RUN ./install.sh $DATASTORE
RUN apt-get update \
- && apt-get install $APTOPTS build-essential python3-setuptools python3-all python3-all-dev python3-pip libffi-dev libssl-dev libxml2-dev libxslt1-dev libyaml-dev \
+ && apt-get install $APTOPTS build-essential python3-setuptools python3-all python3-all-dev python3-pip libffi-dev libssl-dev libxml2-dev libxslt1-dev libyaml-dev libpq-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& pip3 --no-cache-dir install -U -r requirements.txt \
diff --git a/backup/utils/postgresql.py b/backup/utils/postgresql.py
index 033652f0..e43570e9 100644
--- a/backup/utils/postgresql.py
+++ b/backup/utils/postgresql.py
@@ -15,7 +15,17 @@ import psycopg2
class PostgresConnection(object):
- def __init__(self, user, password='', host='localhost', port=5432):
+ def __init__(self, user, password='', host='/var/run/postgresql',
+ port=5432):
+ """Utility class to communicate with PostgreSQL.
+
+ Connect with socket rather than IP or localhost address to avoid
+ manipulation of pg_hba.conf when the database is running inside
+ container with bridge network.
+
+ This class is consistent with PostgresConnection in
+ trove/guestagent/datastore/postgres/service.py
+ """
self.user = user
self.password = password
self.host = host
diff --git a/integration/scripts/files/elements/guest-agent/package-installs.yaml b/integration/scripts/files/elements/guest-agent/package-installs.yaml
index 6f2e7892..5eccd1fe 100644
--- a/integration/scripts/files/elements/guest-agent/package-installs.yaml
+++ b/integration/scripts/files/elements/guest-agent/package-installs.yaml
@@ -42,5 +42,5 @@ rsyslog:
ubuntu-cloudimage-keyring:
ureadahead:
uuid-runtime:
-vim-tiny:
+vim:
vlan:
diff --git a/releasenotes/notes/xena-container-bridge-network.yaml b/releasenotes/notes/xena-container-bridge-network.yaml
new file mode 100644
index 00000000..b70d370e
--- /dev/null
+++ b/releasenotes/notes/xena-container-bridge-network.yaml
@@ -0,0 +1,14 @@
+---
+security:
+ - |
+ Changed the network mode of database container to "bridge" and exposed the
+ service ports. Cloud operator could adjust the iptables to restrict network
+ access from the database container to the outside. An example::
+
+ iptables -t filter -I DOCKER-USER 1 -d [restricted-network-range] -i docker0 ! -o docker0 -j REJECT
+
+upgrade:
+ - The default value of the trove guest agent config option
+ ``[postgresql] backup_docker_image`` is changed to
+ ``openstacktrove/db-backup-postgresql:1.1.1``. There is nothing to do if
+ the option is not configured explicitly.
diff --git a/trove/common/cfg.py b/trove/common/cfg.py
index e4c91802..49ea8b82 100644
--- a/trove/common/cfg.py
+++ b/trove/common/cfg.py
@@ -1097,7 +1097,7 @@ postgresql_opts = [
),
cfg.StrOpt(
'backup_docker_image',
- default='openstacktrove/db-backup-postgresql:1.1.0',
+ default='openstacktrove/db-backup-postgresql:1.1.1',
help='The docker image used for backup and restore.'
),
cfg.BoolOpt('icmp', default=False,
diff --git a/trove/guestagent/datastore/mysql_common/manager.py b/trove/guestagent/datastore/mysql_common/manager.py
index a81431a1..e27b47ff 100644
--- a/trove/guestagent/datastore/mysql_common/manager.py
+++ b/trove/guestagent/datastore/mysql_common/manager.py
@@ -112,8 +112,10 @@ class MySqlManager(manager.Manager):
"""
LOG.info(f"Creating backup {backup_info['id']}")
with EndNotification(context):
+ # Set /var/run/mysqld to allow localhost access.
volumes_mapping = {
'/var/lib/mysql': {'bind': '/var/lib/mysql', 'mode': 'rw'},
+ "/var/run/mysqld": {"bind": "/var/run/mysqld", "mode": "ro"},
'/tmp': {'bind': '/tmp', 'mode': 'rw'}
}
self.app.create_backup(context, backup_info,
diff --git a/trove/guestagent/datastore/mysql_common/service.py b/trove/guestagent/datastore/mysql_common/service.py
index 1ab1d5fc..64abe542 100644
--- a/trove/guestagent/datastore/mysql_common/service.py
+++ b/trove/guestagent/datastore/mysql_common/service.py
@@ -586,13 +586,20 @@ class BaseMySqlApp(service.BaseDbApp):
if extra_volumes:
volumes.update(extra_volumes)
+ # Expose ports
+ ports = {}
+ tcp_ports = cfg.get_configuration_property('tcp_ports')
+ for port_range in tcp_ports:
+ for port in port_range:
+ ports[f'{port}/tcp'] = port
+
try:
- LOG.info("Starting docker container, image: %s", image)
docker_util.start_container(
self.docker_client,
image,
volumes=volumes,
- network_mode="host",
+ network_mode="bridge",
+ ports=ports,
user=user,
environment={
"MYSQL_ROOT_PASSWORD": root_pass,
diff --git a/trove/guestagent/datastore/postgres/service.py b/trove/guestagent/datastore/postgres/service.py
index 404db303..4c2435f0 100644
--- a/trove/guestagent/datastore/postgres/service.py
+++ b/trove/guestagent/datastore/postgres/service.py
@@ -190,13 +190,20 @@ class PgSqlApp(service.BaseDbApp):
if extra_volumes:
volumes.update(extra_volumes)
+ # Expose ports
+ ports = {}
+ tcp_ports = cfg.get_configuration_property('tcp_ports')
+ for port_range in tcp_ports:
+ for port in port_range:
+ ports[f'{port}/tcp'] = port
+
try:
- LOG.info("Starting docker container, image: %s", image)
docker_util.start_container(
self.docker_client,
image,
volumes=volumes,
- network_mode="host",
+ network_mode="bridge",
+ ports=ports,
user=user,
environment={
"POSTGRES_PASSWORD": postgres_pass,
@@ -727,7 +734,17 @@ class PgSqlAdmin(object):
class PostgresConnection(object):
- def __init__(self, user, password=None, host='localhost', port=5432):
+ def __init__(self, user, password=None, host='/var/run/postgresql',
+ port=5432):
+ """Utility class to communicate with PostgreSQL.
+
+ Connect with socket rather than IP or localhost address to avoid
+ manipulation of pg_hba.conf when the database is running inside
+ container with bridge network.
+
+ This class is consistent with PostgresConnection in
+ backup/utils/postgresql.py
+ """
self.user = user
self.password = password
self.host = host
diff --git a/trove/guestagent/datastore/service.py b/trove/guestagent/datastore/service.py
index d016ab5d..fe30652d 100644
--- a/trove/guestagent/datastore/service.py
+++ b/trove/guestagent/datastore/service.py
@@ -395,6 +395,9 @@ class BaseDbApp(object):
):
raise exception.TroveError("Failed to stop database")
+ def start_db(self, *args, **kwargs):
+ pass
+
def start_db_with_conf_changes(self, config_contents, ds_version):
LOG.info(f"Starting database service with new configuration and "
f"datastore version {ds_version}.")
@@ -435,7 +438,8 @@ class BaseDbApp(object):
db_userinfo = ''
if need_dbuser:
admin_pass = self.get_auth_password()
- db_userinfo = (f"--db-host=127.0.0.1 --db-user=os_admin "
+ # Use localhost to avoid host access verification.
+ db_userinfo = (f"--db-host=localhost --db-user=os_admin "
f"--db-password={admin_pass}")
swift_metadata = (
diff --git a/trove/guestagent/strategies/replication/mysql_base.py b/trove/guestagent/strategies/replication/mysql_base.py
index e6dfc3cc..744aec6b 100644
--- a/trove/guestagent/strategies/replication/mysql_base.py
+++ b/trove/guestagent/strategies/replication/mysql_base.py
@@ -82,6 +82,7 @@ class MysqlReplicationBase(base.Replication):
volumes_mapping = {
'/var/lib/mysql': {'bind': '/var/lib/mysql', 'mode': 'rw'},
+ "/var/run/mysqld": {"bind": "/var/run/mysqld", "mode": "ro"},
'/tmp': {'bind': '/tmp', 'mode': 'rw'}
}
service.create_backup(context, snapshot_info,
diff --git a/trove/guestagent/utils/docker.py b/trove/guestagent/utils/docker.py
index 0f254aa6..beff4f1c 100644
--- a/trove/guestagent/utils/docker.py
+++ b/trove/guestagent/utils/docker.py
@@ -56,9 +56,14 @@ def start_container(client, image, name="database",
"""
try:
container = client.containers.get(name)
+ LOG.info(f'Starting existing container {name}')
container.start()
except docker.errors.NotFound:
- LOG.warning("Failed to get container %s", name)
+ LOG.info(
+ f"Creating docker container, image: {image}, "
+ f"volumes: {volumes}, ports: {ports}, user: {user}, "
+ f"network_mode: {network_mode}, environment: {environment}, "
+ f"command: {command}")
container = client.containers.run(
image,
name=name,