Add resource Constraints to Nova containers.
This commit will constrain the dimensions of service `Nova` and sub-containers deployed along with it. A user can give the dimension values in `/etc/kolla/globals.yml` the data-types just like stated in this commit. Reference-Docs: https://docs.docker.com/config/containers/resource_constraints/ Added Test-cases for the same. Partially-Implements: blueprint resource-constraints Change-Id: I6458d8fb7b26a6e7c3a9fd0d674d9cf129b0bf5d
This commit is contained in:
parent
2f37a2b4af
commit
297eb5e88f
@ -108,6 +108,11 @@ docker_common_options:
|
|||||||
restart_policy: "{{ docker_restart_policy }}"
|
restart_policy: "{{ docker_restart_policy }}"
|
||||||
restart_retries: "{{ docker_restart_policy_retry }}"
|
restart_retries: "{{ docker_restart_policy_retry }}"
|
||||||
|
|
||||||
|
####################
|
||||||
|
# Dimensions options
|
||||||
|
####################
|
||||||
|
# Dimension options for Docker Containers
|
||||||
|
default_container_dimensions: {}
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# keepalived options
|
# keepalived options
|
||||||
|
@ -552,6 +552,18 @@ class DockerWorker(object):
|
|||||||
'volumes_from': self.params.get('volumes_from')
|
'volumes_from': self.params.get('volumes_from')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.params.get('dimensions'):
|
||||||
|
supported = {'cpu_period', 'cpu_quota', 'cpu_shares',
|
||||||
|
'cpuset_cpus', 'cpuset_mems', 'mem_limit',
|
||||||
|
'mem_reservation', 'memswap_limit',
|
||||||
|
'kernel_memory', 'blkio_weight'}
|
||||||
|
unsupported = set(self.params.get('dimensions')) - supported
|
||||||
|
if unsupported:
|
||||||
|
self.module.exit_json(failed=True,
|
||||||
|
msg=repr("Unsupported dimensions"),
|
||||||
|
unsupported_dimensions=unsupported)
|
||||||
|
options.update(self.params.get('dimensions'))
|
||||||
|
|
||||||
if self.params.get('restart_policy') in ['on-failure',
|
if self.params.get('restart_policy') in ['on-failure',
|
||||||
'always',
|
'always',
|
||||||
'unless-stopped']:
|
'unless-stopped']:
|
||||||
@ -772,7 +784,8 @@ def generate_module():
|
|||||||
tls_key=dict(required=False, type='str'),
|
tls_key=dict(required=False, type='str'),
|
||||||
tls_cacert=dict(required=False, type='str'),
|
tls_cacert=dict(required=False, type='str'),
|
||||||
volumes=dict(required=False, type='list'),
|
volumes=dict(required=False, type='list'),
|
||||||
volumes_from=dict(required=False, type='list')
|
volumes_from=dict(required=False, type='list'),
|
||||||
|
dimensions=dict(required=False, type='dict', default=dict())
|
||||||
)
|
)
|
||||||
required_if = [
|
required_if = [
|
||||||
['action', 'pull_image', ['image']],
|
['action', 'pull_image', ['image']],
|
||||||
|
@ -21,6 +21,7 @@ nova_services:
|
|||||||
- "nova_compute:/var/lib/nova/"
|
- "nova_compute:/var/lib/nova/"
|
||||||
- "{% if enable_cinder_backend_nfs | bool %}/var/lib/nova/mnt:/var/lib/nova/mnt:shared{% endif %}"
|
- "{% if enable_cinder_backend_nfs | bool %}/var/lib/nova/mnt:/var/lib/nova/mnt:shared{% endif %}"
|
||||||
- "nova_libvirt_qemu:/etc/libvirt/qemu"
|
- "nova_libvirt_qemu:/etc/libvirt/qemu"
|
||||||
|
dimensions: "{{ nova_libvirt_dimensions }}"
|
||||||
nova-ssh:
|
nova-ssh:
|
||||||
container_name: "nova_ssh"
|
container_name: "nova_ssh"
|
||||||
group: "compute"
|
group: "compute"
|
||||||
@ -32,6 +33,7 @@ nova_services:
|
|||||||
- "kolla_logs:/var/log/kolla"
|
- "kolla_logs:/var/log/kolla"
|
||||||
- "nova_compute:/var/lib/nova"
|
- "nova_compute:/var/lib/nova"
|
||||||
- "{% if enable_cinder_backend_nfs | bool %}/var/lib/nova/mnt:/var/lib/nova/mnt:shared{% endif %}"
|
- "{% if enable_cinder_backend_nfs | bool %}/var/lib/nova/mnt:/var/lib/nova/mnt:shared{% endif %}"
|
||||||
|
dimensions: "{{ nova_ssh_dimensions }}"
|
||||||
placement-api:
|
placement-api:
|
||||||
container_name: "placement_api"
|
container_name: "placement_api"
|
||||||
group: "placement-api"
|
group: "placement-api"
|
||||||
@ -41,6 +43,7 @@ nova_services:
|
|||||||
- "{{ node_config_directory }}/placement-api/:{{ container_config_directory }}/:ro"
|
- "{{ node_config_directory }}/placement-api/:{{ container_config_directory }}/:ro"
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
- "kolla_logs:/var/log/kolla/"
|
- "kolla_logs:/var/log/kolla/"
|
||||||
|
dimensions: "{{ placement_api_dimensions }}"
|
||||||
nova-api:
|
nova-api:
|
||||||
container_name: "nova_api"
|
container_name: "nova_api"
|
||||||
group: "nova-api"
|
group: "nova-api"
|
||||||
@ -52,6 +55,7 @@ nova_services:
|
|||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
- "/lib/modules:/lib/modules:ro"
|
- "/lib/modules:/lib/modules:ro"
|
||||||
- "kolla_logs:/var/log/kolla/"
|
- "kolla_logs:/var/log/kolla/"
|
||||||
|
dimensions: "{{ nova_api_dimensions }}"
|
||||||
nova-consoleauth:
|
nova-consoleauth:
|
||||||
container_name: "nova_consoleauth"
|
container_name: "nova_consoleauth"
|
||||||
group: "nova-consoleauth"
|
group: "nova-consoleauth"
|
||||||
@ -61,6 +65,7 @@ nova_services:
|
|||||||
- "{{ node_config_directory }}/nova-consoleauth/:{{ container_config_directory }}/:ro"
|
- "{{ node_config_directory }}/nova-consoleauth/:{{ container_config_directory }}/:ro"
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
- "kolla_logs:/var/log/kolla/"
|
- "kolla_logs:/var/log/kolla/"
|
||||||
|
dimensions: "{{ nova_consoleauth_dimensions }}"
|
||||||
nova-novncproxy:
|
nova-novncproxy:
|
||||||
container_name: "nova_novncproxy"
|
container_name: "nova_novncproxy"
|
||||||
group: "nova-novncproxy"
|
group: "nova-novncproxy"
|
||||||
@ -70,6 +75,7 @@ nova_services:
|
|||||||
- "{{ node_config_directory }}/nova-novncproxy/:{{ container_config_directory }}/:ro"
|
- "{{ node_config_directory }}/nova-novncproxy/:{{ container_config_directory }}/:ro"
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
- "kolla_logs:/var/log/kolla/"
|
- "kolla_logs:/var/log/kolla/"
|
||||||
|
dimensions: "{{ nova_novncproxy_dimensions }}"
|
||||||
nova-scheduler:
|
nova-scheduler:
|
||||||
container_name: "nova_scheduler"
|
container_name: "nova_scheduler"
|
||||||
group: "nova-scheduler"
|
group: "nova-scheduler"
|
||||||
@ -79,6 +85,7 @@ nova_services:
|
|||||||
- "{{ node_config_directory }}/nova-scheduler/:{{ container_config_directory }}/:ro"
|
- "{{ node_config_directory }}/nova-scheduler/:{{ container_config_directory }}/:ro"
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
- "kolla_logs:/var/log/kolla/"
|
- "kolla_logs:/var/log/kolla/"
|
||||||
|
dimensions: "{{ nova_scheduler_dimensions }}"
|
||||||
nova-spicehtml5proxy:
|
nova-spicehtml5proxy:
|
||||||
container_name: "nova_spicehtml5proxy"
|
container_name: "nova_spicehtml5proxy"
|
||||||
group: "nova-spicehtml5proxy"
|
group: "nova-spicehtml5proxy"
|
||||||
@ -88,6 +95,7 @@ nova_services:
|
|||||||
- "{{ node_config_directory }}/nova-spicehtml5proxy/:{{ container_config_directory }}/:ro"
|
- "{{ node_config_directory }}/nova-spicehtml5proxy/:{{ container_config_directory }}/:ro"
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
- "kolla_logs:/var/log/kolla/"
|
- "kolla_logs:/var/log/kolla/"
|
||||||
|
dimensions: "{{ nova_spicehtml5proxy_dimensions }}"
|
||||||
nova-serialproxy:
|
nova-serialproxy:
|
||||||
container_name: "nova_serialproxy"
|
container_name: "nova_serialproxy"
|
||||||
group: "nova-serialproxy"
|
group: "nova-serialproxy"
|
||||||
@ -97,6 +105,7 @@ nova_services:
|
|||||||
- "{{ node_config_directory }}/nova-serialproxy/:{{ container_config_directory }}/:ro"
|
- "{{ node_config_directory }}/nova-serialproxy/:{{ container_config_directory }}/:ro"
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
- "kolla_logs:/var/log/kolla/"
|
- "kolla_logs:/var/log/kolla/"
|
||||||
|
dimensions: "{{ nova_serialproxy_dimensions }}"
|
||||||
nova-conductor:
|
nova-conductor:
|
||||||
container_name: "nova_conductor"
|
container_name: "nova_conductor"
|
||||||
group: "nova-conductor"
|
group: "nova-conductor"
|
||||||
@ -106,6 +115,7 @@ nova_services:
|
|||||||
- "{{ node_config_directory }}/nova-conductor/:{{ container_config_directory }}/:ro"
|
- "{{ node_config_directory }}/nova-conductor/:{{ container_config_directory }}/:ro"
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
- "kolla_logs:/var/log/kolla/"
|
- "kolla_logs:/var/log/kolla/"
|
||||||
|
dimensions: "{{ nova_conductor_dimensions }}"
|
||||||
nova-compute:
|
nova-compute:
|
||||||
container_name: "nova_compute"
|
container_name: "nova_compute"
|
||||||
group: "compute"
|
group: "compute"
|
||||||
@ -126,6 +136,7 @@ nova_services:
|
|||||||
- "libvirtd:/var/lib/libvirt"
|
- "libvirtd:/var/lib/libvirt"
|
||||||
- "nova_compute:/var/lib/nova/"
|
- "nova_compute:/var/lib/nova/"
|
||||||
- "{% if enable_cinder_backend_nfs | bool %}/var/lib/nova/mnt:/var/lib/nova/mnt:shared{% endif %}"
|
- "{% if enable_cinder_backend_nfs | bool %}/var/lib/nova/mnt:/var/lib/nova/mnt:shared{% endif %}"
|
||||||
|
dimensions: "{{ nova_compute_dimensions }}"
|
||||||
nova-compute-ironic:
|
nova-compute-ironic:
|
||||||
container_name: "nova_compute_ironic"
|
container_name: "nova_compute_ironic"
|
||||||
group: "nova-compute-ironic"
|
group: "nova-compute-ironic"
|
||||||
@ -135,6 +146,7 @@ nova_services:
|
|||||||
- "{{ node_config_directory }}/nova-compute-ironic/:{{ container_config_directory }}/:ro"
|
- "{{ node_config_directory }}/nova-compute-ironic/:{{ container_config_directory }}/:ro"
|
||||||
- "/etc/localtime:/etc/localtime:ro"
|
- "/etc/localtime:/etc/localtime:ro"
|
||||||
- "kolla_logs:/var/log/kolla/"
|
- "kolla_logs:/var/log/kolla/"
|
||||||
|
dimensions: "{{ nova_compute_ironic_dimensions }}"
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# Ceph
|
# Ceph
|
||||||
@ -232,6 +244,19 @@ placement_api_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ d
|
|||||||
placement_api_tag: "{{ nova_tag }}"
|
placement_api_tag: "{{ nova_tag }}"
|
||||||
placement_api_image_full: "{{ placement_api_image }}:{{ placement_api_tag }}"
|
placement_api_image_full: "{{ placement_api_image }}:{{ placement_api_tag }}"
|
||||||
|
|
||||||
|
nova_libvirt_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
nova_ssh_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
placement_api_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
nova_api_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
nova_consoleauth_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
nova_novncproxy_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
nova_scheduler_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
nova_spicehtml5proxy_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
nova_serialproxy_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
nova_conductor_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
nova_compute_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
nova_compute_ironic_dimensions: "{{ default_container_dimensions }}"
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# OpenStack
|
# OpenStack
|
||||||
####################
|
####################
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
pid_mode: "{{ service.pid_mode | default('') }}"
|
pid_mode: "{{ service.pid_mode | default('') }}"
|
||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
@ -37,6 +38,7 @@
|
|||||||
pid_mode: "{{ service.pid_mode | default('') }}"
|
pid_mode: "{{ service.pid_mode | default('') }}"
|
||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
register: restart_nova_libvirt
|
register: restart_nova_libvirt
|
||||||
# NOTE(Jeffrey4l): retry 5 to remove nova_libvirt container because when
|
# NOTE(Jeffrey4l): retry 5 to remove nova_libvirt container because when
|
||||||
# guests running, nova_libvirt will raise error even though it is removed.
|
# guests running, nova_libvirt will raise error even though it is removed.
|
||||||
@ -65,6 +67,7 @@
|
|||||||
name: "{{ service.container_name }}"
|
name: "{{ service.container_name }}"
|
||||||
image: "{{ service.image }}"
|
image: "{{ service.image }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
@ -91,6 +94,7 @@
|
|||||||
image: "{{ service.image }}"
|
image: "{{ service.image }}"
|
||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
@ -116,6 +120,7 @@
|
|||||||
image: "{{ service.image }}"
|
image: "{{ service.image }}"
|
||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
@ -141,6 +146,7 @@
|
|||||||
image: "{{ service.image }}"
|
image: "{{ service.image }}"
|
||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
@ -167,6 +173,7 @@
|
|||||||
image: "{{ service.image }}"
|
image: "{{ service.image }}"
|
||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
@ -192,6 +199,7 @@
|
|||||||
image: "{{ service.image }}"
|
image: "{{ service.image }}"
|
||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
@ -217,6 +225,7 @@
|
|||||||
image: "{{ service.image }}"
|
image: "{{ service.image }}"
|
||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
@ -242,6 +251,7 @@
|
|||||||
image: "{{ service.image }}"
|
image: "{{ service.image }}"
|
||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
@ -269,6 +279,7 @@
|
|||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
ipc_mode: "{{ service.ipc_mode | default(omit) }}"
|
ipc_mode: "{{ service.ipc_mode | default(omit) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
@ -295,6 +306,7 @@
|
|||||||
image: "{{ service.image }}"
|
image: "{{ service.image }}"
|
||||||
privileged: "{{ service.privileged | default(False) }}"
|
privileged: "{{ service.privileged | default(False) }}"
|
||||||
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
volumes: "{{ service.volumes|reject('equalto', '')|list }}"
|
||||||
|
dimensions: "{{ service.dimensions }}"
|
||||||
when:
|
when:
|
||||||
- kolla_action != "config"
|
- kolla_action != "config"
|
||||||
- inventory_hostname in groups[service.group]
|
- inventory_hostname in groups[service.group]
|
||||||
|
@ -27,3 +27,4 @@ Projects Deployment References
|
|||||||
tacker-guide
|
tacker-guide
|
||||||
xenserver-guide
|
xenserver-guide
|
||||||
horizon-guide
|
horizon-guide
|
||||||
|
resource-constraints
|
||||||
|
84
doc/source/reference/resource-constraints.rst
Normal file
84
doc/source/reference/resource-constraints.rst
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
.. _resource-constraints:
|
||||||
|
|
||||||
|
=====================================
|
||||||
|
Resource Constraints in Kolla Ansible
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Overview
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
Since the Rocky release it is possible to restrict
|
||||||
|
the resource usage of deployed containers.
|
||||||
|
The following components support this feature:
|
||||||
|
|
||||||
|
* Nova
|
||||||
|
|
||||||
|
In Kolla Ansible,
|
||||||
|
container resources to be constrained are referred to as dimensions.
|
||||||
|
|
||||||
|
The `Docker documentation <https://docs.docker.com/config/containers/resource_constraints/>`__
|
||||||
|
provides information on container resource constraints.
|
||||||
|
The resources currently supported by Kolla Ansible are:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
cpu_period
|
||||||
|
cpu_quota
|
||||||
|
cpu_shares
|
||||||
|
cpuset_cpus
|
||||||
|
cpuset_mems
|
||||||
|
mem_limit
|
||||||
|
mem_reservation
|
||||||
|
memswap_limit
|
||||||
|
kernel_memory
|
||||||
|
blkio_weight
|
||||||
|
|
||||||
|
.. end
|
||||||
|
|
||||||
|
Pre-deployment Configuration
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Dimensions are defined as a mapping from a Docker resource name
|
||||||
|
(e.g. ``cpu_period``) to a string constraint value.
|
||||||
|
|
||||||
|
The variable ``default_container_dimensions`` sets the default dimensions
|
||||||
|
for all supported containers, and by default these are unconstrained.
|
||||||
|
|
||||||
|
Each supported container has an associated variable,
|
||||||
|
``<container name>_dimensions``, that can be used to set the resources
|
||||||
|
for the container. For example, dimensions for the ``nova_libvirt``
|
||||||
|
container are set via the variable ``nova_libvirt_dimensions``.
|
||||||
|
|
||||||
|
For example,
|
||||||
|
to constrain the number of CPUs that may be used by all supported containers,
|
||||||
|
add the following to the dimensions options section in
|
||||||
|
``/etc/kolla/globals.yml``:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
default_container_dimensions:
|
||||||
|
cpuset_cpus: "1"
|
||||||
|
|
||||||
|
.. end
|
||||||
|
|
||||||
|
For example, to constrain the number of CPUs that may be used by
|
||||||
|
the ``nova_libvirt`` container, add the following to the dimensions
|
||||||
|
options section in ``/etc/kolla/globals.yml``:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
nova_libvirt_dimensions:
|
||||||
|
cpuset_cpus: "2"
|
||||||
|
|
||||||
|
.. end
|
||||||
|
|
||||||
|
Deployment
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
To deploy resource constrained containers, run the deployment as usual:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ kolla-ansible deploy -i /path/to/inventory
|
||||||
|
|
||||||
|
.. end
|
@ -113,6 +113,28 @@ kolla_internal_vip_address: "10.10.10.254"
|
|||||||
# Arbitrary unique number from 0..255
|
# Arbitrary unique number from 0..255
|
||||||
#keepalived_virtual_router_id: "51"
|
#keepalived_virtual_router_id: "51"
|
||||||
|
|
||||||
|
###################
|
||||||
|
# Dimension options
|
||||||
|
###################
|
||||||
|
# This is to provide an extra option to deploy containers with Resource constraints.
|
||||||
|
# We call it dimensions here.
|
||||||
|
# The dimensions for each container are defined by a mapping, where each dimension value should be a
|
||||||
|
# string.
|
||||||
|
# Reference_Docs
|
||||||
|
# https://docs.docker.com/config/containers/resource_constraints/
|
||||||
|
# eg:
|
||||||
|
# <container_name>_dimensions:
|
||||||
|
# blkio_weight:
|
||||||
|
# cpu_period:
|
||||||
|
# cpu_quota:
|
||||||
|
# cpu_shares:
|
||||||
|
# cpuset_cpus:
|
||||||
|
# cpuset_mems:
|
||||||
|
# mem_limit:
|
||||||
|
# mem_reservation:
|
||||||
|
# memswap_limit:
|
||||||
|
# kernel_memory:
|
||||||
|
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# TLS options
|
# TLS options
|
||||||
|
@ -83,7 +83,8 @@ class ModuleArgsTest(base.BaseTestCase):
|
|||||||
tls_key=dict(required=False, type='str'),
|
tls_key=dict(required=False, type='str'),
|
||||||
tls_cacert=dict(required=False, type='str'),
|
tls_cacert=dict(required=False, type='str'),
|
||||||
volumes=dict(required=False, type='list'),
|
volumes=dict(required=False, type='list'),
|
||||||
volumes_from=dict(required=False, type='list')
|
volumes_from=dict(required=False, type='list'),
|
||||||
|
dimensions=dict(required=False, type='dict', default=dict())
|
||||||
)
|
)
|
||||||
required_if = [
|
required_if = [
|
||||||
['action', 'pull_image', ['image']],
|
['action', 'pull_image', ['image']],
|
||||||
@ -191,14 +192,38 @@ class TestContainer(base.BaseTestCase):
|
|||||||
super(TestContainer, self).setUp()
|
super(TestContainer, self).setUp()
|
||||||
self.fake_data = copy.deepcopy(FAKE_DATA)
|
self.fake_data = copy.deepcopy(FAKE_DATA)
|
||||||
|
|
||||||
def test_create_container(self):
|
def test_create_container_without_dimensions(self):
|
||||||
self.dw = get_DockerWorker(self.fake_data['params'])
|
self.dw = get_DockerWorker(self.fake_data['params'])
|
||||||
self.dw.dc.create_host_config = mock.MagicMock(
|
self.dw.dc.create_host_config = mock.MagicMock(
|
||||||
return_value=self.fake_data['params']['host_config'])
|
return_value=self.fake_data['params']['host_config'])
|
||||||
self.dw.create_container()
|
self.dw.create_container()
|
||||||
self.assertTrue(self.dw.changed)
|
self.assertTrue(self.dw.changed)
|
||||||
|
|
||||||
|
def test_create_container_with_dimensions(self):
|
||||||
|
self.fake_data['params']['dimensions'] = {'blkio_weight': 10}
|
||||||
|
self.dw = get_DockerWorker(self.fake_data['params'])
|
||||||
|
self.dw.dc.create_host_config = mock.MagicMock(
|
||||||
|
return_value=self.fake_data['params']['host_config'])
|
||||||
|
self.dw.create_container()
|
||||||
|
self.assertTrue(self.dw.changed)
|
||||||
|
self.fake_data['params'].pop('dimensions')
|
||||||
|
self.fake_data['params']['host_config']['blkio_weight'] = '10'
|
||||||
self.dw.dc.create_container.assert_called_once_with(
|
self.dw.dc.create_container.assert_called_once_with(
|
||||||
**self.fake_data['params'])
|
**self.fake_data['params'])
|
||||||
|
self.dw.dc.create_host_config.assert_called_with(
|
||||||
|
cap_add=None, network_mode='host', ipc_mode=None,
|
||||||
|
pid_mode=None, volumes_from=None, blkio_weight=10,
|
||||||
|
security_opt=None, privileged=None)
|
||||||
|
|
||||||
|
def test_create_container_wrong_dimensions(self):
|
||||||
|
self.fake_data['params']['dimensions'] = {'random': 10}
|
||||||
|
self.dw = get_DockerWorker(self.fake_data['params'])
|
||||||
|
self.dw.dc.create_host_config = mock.MagicMock(
|
||||||
|
return_value=self.fake_data['params']['host_config'])
|
||||||
|
self.dw.create_container()
|
||||||
|
self.dw.module.exit_json.assert_called_once_with(
|
||||||
|
failed=True, msg=repr("Unsupported dimensions"),
|
||||||
|
unsupported_dimensions=set(['random']))
|
||||||
|
|
||||||
def test_start_container_without_pull(self):
|
def test_start_container_without_pull(self):
|
||||||
self.fake_data['params'].update({'auth_username': 'fake_user',
|
self.fake_data['params'].update({'auth_username': 'fake_user',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user