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
This commit is contained in:
parent
6d2ab68a8a
commit
b050996b9f
@ -18,7 +18,7 @@ WORKDIR /opt/trove/backup
|
|||||||
RUN ./install.sh $DATASTORE
|
RUN ./install.sh $DATASTORE
|
||||||
|
|
||||||
RUN apt-get update \
|
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 \
|
&& apt-get clean \
|
||||||
&& rm -rf /var/lib/apt/lists/* \
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
&& pip3 --no-cache-dir install -U -r requirements.txt \
|
&& pip3 --no-cache-dir install -U -r requirements.txt \
|
||||||
|
@ -15,7 +15,17 @@ import psycopg2
|
|||||||
|
|
||||||
|
|
||||||
class PostgresConnection(object):
|
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.user = user
|
||||||
self.password = password
|
self.password = password
|
||||||
self.host = host
|
self.host = host
|
||||||
|
@ -42,5 +42,5 @@ rsyslog:
|
|||||||
ubuntu-cloudimage-keyring:
|
ubuntu-cloudimage-keyring:
|
||||||
ureadahead:
|
ureadahead:
|
||||||
uuid-runtime:
|
uuid-runtime:
|
||||||
vim-tiny:
|
vim:
|
||||||
vlan:
|
vlan:
|
||||||
|
14
releasenotes/notes/xena-container-bridge-network.yaml
Normal file
14
releasenotes/notes/xena-container-bridge-network.yaml
Normal file
@ -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.
|
@ -1097,7 +1097,7 @@ postgresql_opts = [
|
|||||||
),
|
),
|
||||||
cfg.StrOpt(
|
cfg.StrOpt(
|
||||||
'backup_docker_image',
|
'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.'
|
help='The docker image used for backup and restore.'
|
||||||
),
|
),
|
||||||
cfg.BoolOpt('icmp', default=False,
|
cfg.BoolOpt('icmp', default=False,
|
||||||
|
@ -112,8 +112,10 @@ class MySqlManager(manager.Manager):
|
|||||||
"""
|
"""
|
||||||
LOG.info(f"Creating backup {backup_info['id']}")
|
LOG.info(f"Creating backup {backup_info['id']}")
|
||||||
with EndNotification(context):
|
with EndNotification(context):
|
||||||
|
# Set /var/run/mysqld to allow localhost access.
|
||||||
volumes_mapping = {
|
volumes_mapping = {
|
||||||
'/var/lib/mysql': {'bind': '/var/lib/mysql', 'mode': 'rw'},
|
'/var/lib/mysql': {'bind': '/var/lib/mysql', 'mode': 'rw'},
|
||||||
|
"/var/run/mysqld": {"bind": "/var/run/mysqld", "mode": "ro"},
|
||||||
'/tmp': {'bind': '/tmp', 'mode': 'rw'}
|
'/tmp': {'bind': '/tmp', 'mode': 'rw'}
|
||||||
}
|
}
|
||||||
self.app.create_backup(context, backup_info,
|
self.app.create_backup(context, backup_info,
|
||||||
|
@ -586,13 +586,20 @@ class BaseMySqlApp(service.BaseDbApp):
|
|||||||
if extra_volumes:
|
if extra_volumes:
|
||||||
volumes.update(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:
|
try:
|
||||||
LOG.info("Starting docker container, image: %s", image)
|
|
||||||
docker_util.start_container(
|
docker_util.start_container(
|
||||||
self.docker_client,
|
self.docker_client,
|
||||||
image,
|
image,
|
||||||
volumes=volumes,
|
volumes=volumes,
|
||||||
network_mode="host",
|
network_mode="bridge",
|
||||||
|
ports=ports,
|
||||||
user=user,
|
user=user,
|
||||||
environment={
|
environment={
|
||||||
"MYSQL_ROOT_PASSWORD": root_pass,
|
"MYSQL_ROOT_PASSWORD": root_pass,
|
||||||
|
@ -190,13 +190,20 @@ class PgSqlApp(service.BaseDbApp):
|
|||||||
if extra_volumes:
|
if extra_volumes:
|
||||||
volumes.update(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:
|
try:
|
||||||
LOG.info("Starting docker container, image: %s", image)
|
|
||||||
docker_util.start_container(
|
docker_util.start_container(
|
||||||
self.docker_client,
|
self.docker_client,
|
||||||
image,
|
image,
|
||||||
volumes=volumes,
|
volumes=volumes,
|
||||||
network_mode="host",
|
network_mode="bridge",
|
||||||
|
ports=ports,
|
||||||
user=user,
|
user=user,
|
||||||
environment={
|
environment={
|
||||||
"POSTGRES_PASSWORD": postgres_pass,
|
"POSTGRES_PASSWORD": postgres_pass,
|
||||||
@ -727,7 +734,17 @@ class PgSqlAdmin(object):
|
|||||||
|
|
||||||
|
|
||||||
class PostgresConnection(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.user = user
|
||||||
self.password = password
|
self.password = password
|
||||||
self.host = host
|
self.host = host
|
||||||
|
@ -395,6 +395,9 @@ class BaseDbApp(object):
|
|||||||
):
|
):
|
||||||
raise exception.TroveError("Failed to stop database")
|
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):
|
def start_db_with_conf_changes(self, config_contents, ds_version):
|
||||||
LOG.info(f"Starting database service with new configuration and "
|
LOG.info(f"Starting database service with new configuration and "
|
||||||
f"datastore version {ds_version}.")
|
f"datastore version {ds_version}.")
|
||||||
@ -435,7 +438,8 @@ class BaseDbApp(object):
|
|||||||
db_userinfo = ''
|
db_userinfo = ''
|
||||||
if need_dbuser:
|
if need_dbuser:
|
||||||
admin_pass = self.get_auth_password()
|
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}")
|
f"--db-password={admin_pass}")
|
||||||
|
|
||||||
swift_metadata = (
|
swift_metadata = (
|
||||||
|
@ -82,6 +82,7 @@ class MysqlReplicationBase(base.Replication):
|
|||||||
|
|
||||||
volumes_mapping = {
|
volumes_mapping = {
|
||||||
'/var/lib/mysql': {'bind': '/var/lib/mysql', 'mode': 'rw'},
|
'/var/lib/mysql': {'bind': '/var/lib/mysql', 'mode': 'rw'},
|
||||||
|
"/var/run/mysqld": {"bind": "/var/run/mysqld", "mode": "ro"},
|
||||||
'/tmp': {'bind': '/tmp', 'mode': 'rw'}
|
'/tmp': {'bind': '/tmp', 'mode': 'rw'}
|
||||||
}
|
}
|
||||||
service.create_backup(context, snapshot_info,
|
service.create_backup(context, snapshot_info,
|
||||||
|
@ -56,9 +56,14 @@ def start_container(client, image, name="database",
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
container = client.containers.get(name)
|
container = client.containers.get(name)
|
||||||
|
LOG.info(f'Starting existing container {name}')
|
||||||
container.start()
|
container.start()
|
||||||
except docker.errors.NotFound:
|
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(
|
container = client.containers.run(
|
||||||
image,
|
image,
|
||||||
name=name,
|
name=name,
|
||||||
|
Loading…
Reference in New Issue
Block a user