From c85a584046e05f4120dd0c414e96e610b5c9a035 Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Mon, 5 Oct 2020 14:48:05 +0200 Subject: [PATCH 1/4] Compose to ACI mapping documentation Signed-off-by: Guillaume Tardif --- docs/aci-compose-features.md | 118 +++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 docs/aci-compose-features.md diff --git a/docs/aci-compose-features.md b/docs/aci-compose-features.md new file mode 100644 index 000000000..360c27b9c --- /dev/null +++ b/docs/aci-compose-features.md @@ -0,0 +1,118 @@ +# Compose - Azure Container Instances mapping + +This document outlines mapping between `docker-compose.yaml` files and corresponding ACI equivalents. +At a high-level, each Compose deployment is mapped to a single ACI container group. +Each service is mapped to a container in the container group, the Docker ACI integration provides no scaling of services. + +## Compose fields mapping + +Table bellow list supported Compose file fields with equivalent ACI when supported. + +__Glossary:__ + +- __✓:__ Converts +- __n:__ Not yet implemented +- __x:__ Not applicable / no 1-1 conversion + +| Keys | Map| Notes | +|--------------------------------|----|--------------------------------------------------------------| +| __Service__ | ✓ | | +| service.service.build | x | Ignored. no image build support on ACI. | +| service.cap_add, cap_drop | x | | +| service.command | ✓ | Override container Command. on ACI, specifying command will currently also override image entrypoint if the image has an Entrypoint defined | +| service.configs | n | | +| service.cgroup_parent | x | +| service.container_name | x | Service name is used as container name in ACI | +| service.credential_spec | x | | +| service.deploy | ✓ | | +| service.deploy.endpoint_mode | x | | +| service.deploy.mode | x | | +| service.deploy.replicas | x | Only one replica is started for each service with the docker-ACI integration. | +| service.deploy.placement | x | +| service.deploy.update_config | x | +| service.deploy.resources | ✓ | Restriction: ACI Resource limits cannot be greater than the sum of resource requests for all containers in the container group. This will allow one containers in the same container group to compete with resources. +| service.deploy.restart_policy | ✓ | One of: any - none - on-failure. Restriction: All services must have the ame restart policy. The entire ACI container group will be restarted if needed. | +| service.deploy.labels | x | ACI does not have container-level labels. In addition, Azure tag are too restrictive to support Docker container labels.| +| service.devices | x | +| service.depends_on | x | +| service.dns | x | +| service.dns_search | x | +| service.domainname | ✓ | Mapped to ACI DNSLabelName. Restriction: all services must specify the same domainname, if specified. +| service.tmpfs | x | +| service.entrypoint | x | ACI allows to override Command, but not Entrypoint. +| service.env_file | ✓ | +| service.environment | ✓ | +| service.expose | x | +| service.extends | x | +| service.external_links | x | +| service.extra_hosts | x | +| service.group_add | x | +| service.healthcheck | x | +| service.hostname | x | +| service.image | ✓ | Private images will be accessible if the user is logged in against the corresponding registry at deploy time. Users will be automatically logged in to Azure Container Registry from Azure login if possible. +| service.isolation | x | +| service.labels | x | ACI does not have container-level labels. In addition, Azure tag are too restrictive to support Docker container labels. | +| service.links | x | +| service.logging | x | +| service.network_mode | x | +| service.networks | x | Communication between services is supported by defining mapping for each service in `/etc/hosts` in the container group. Each service can resolve names for other services and the resulting network calls will be redirected to `localhost`. +| service.pid | x | +| service.ports | ✓ | +| service.secrets | ✓ | +| service.security_opt | x | +| service.stop_grace_period | x | +| service.stop_signal | x | +| service.sysctls | x | +| service.ulimits | x | +| service.userns_mode | x | +| service.volumes | ✓ | Mapped to AZure File Shares. See #persistent_volumes +| service.restart | x | Replaced by service.deployment.restrt_policy | +| | | | +| __Volume__ | x | | +| driver | ✓ | | +| driver_opts | ✓ | | +| external | x | | +| labels | x | | +| | | | +| __Secret__ | x | | +| TBD | x | | +| | | | +| __Config__ | x | | +| TBD | x | | +| | | | + + +## Port Exposure + +When one of the service exposes ports, the entire ACI container group will be exposed and will get a public IP allocated. +Since all services are mapped to containers in the same container group, several services cannot expose the same port number. +[ACI does not support port mapping](https://feedback.azure.com/forums/602224-azure-container-instances/suggestions/34082284-support-for-port-mapping), so source and target port defined in the Compose file must be identical. + +When exposing ports, a service can also specify the service `domainname` field to set a DNS hostname. `domainname` will be used to specify ACI DNS Label Name, and the ACI container group will be reachable at .region.azurecontainer.io. +All services specifying a domainname must set the same value, applied to the entire container group. + +## Persistent Volumes + +Docker volumes are mapped to Azure File Shares. The compose file must define volumes in the `volume` section in order to be able to use them for one or several services. +Volumes are defined with a name, the `driver` field must be set to `azure_file`, and `driver_options` must define the storage account and fileshare to use for the volume. +A service can then reference the volume by its name, and specify the target path to be mounted in the container. + +```yaml +services: + myservice: + image: nginx + volumes: + - mydata:/mount/testvolumes + +volumes: + mydata: + driver: azure_file + driver_opts: + share_name: myfileshare + storage_account_name: mystorageaccount +``` + +Short volume syntax is not allowed for ACI volumes, as it wa designed for local path when running local containers. +A Compose file can defined several volumes, with different Azure file shares or storage accounts. + +Credentials for storage account will be automatically fetched at deployment time, using the Azure login to retrive storage account key for each storage account used. \ No newline at end of file From e3b22ecd0b6344aae62bfaa58fd8e08febbdec9a Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Wed, 7 Oct 2020 10:50:59 +0200 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Chris Crone Signed-off-by: Guillaume Tardif --- docs/aci-compose-features.md | 58 ++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/aci-compose-features.md b/docs/aci-compose-features.md index 360c27b9c..cc03ef074 100644 --- a/docs/aci-compose-features.md +++ b/docs/aci-compose-features.md @@ -1,45 +1,45 @@ # Compose - Azure Container Instances mapping -This document outlines mapping between `docker-compose.yaml` files and corresponding ACI equivalents. +This document outlines the conversion of an application defined in a Compose file to ACI objects. At a high-level, each Compose deployment is mapped to a single ACI container group. -Each service is mapped to a container in the container group, the Docker ACI integration provides no scaling of services. +Each service is mapped to a container in the container group. The Docker ACI integration provides does not allow scaling of services. ## Compose fields mapping -Table bellow list supported Compose file fields with equivalent ACI when supported. +The table below lists supported Compose file fields and their ACI counterparts. -__Glossary:__ +__Legend:__ -- __✓:__ Converts +- __✓:__ Implemented - __n:__ Not yet implemented -- __x:__ Not applicable / no 1-1 conversion +- __x:__ Not applicable / no available conversion | Keys | Map| Notes | |--------------------------------|----|--------------------------------------------------------------| | __Service__ | ✓ | | -| service.service.build | x | Ignored. no image build support on ACI. | +| service.service.build | x | Ignored. No image build support on ACI. | | service.cap_add, cap_drop | x | | | service.command | ✓ | Override container Command. on ACI, specifying command will currently also override image entrypoint if the image has an Entrypoint defined | | service.configs | n | | | service.cgroup_parent | x | -| service.container_name | x | Service name is used as container name in ACI | +| service.container_name | x | Service name is used as container name on ACI. | | service.credential_spec | x | | | service.deploy | ✓ | | | service.deploy.endpoint_mode | x | | | service.deploy.mode | x | | -| service.deploy.replicas | x | Only one replica is started for each service with the docker-ACI integration. | +| service.deploy.replicas | x | Only one replica is started for each service. | | service.deploy.placement | x | | service.deploy.update_config | x | | service.deploy.resources | ✓ | Restriction: ACI Resource limits cannot be greater than the sum of resource requests for all containers in the container group. This will allow one containers in the same container group to compete with resources. -| service.deploy.restart_policy | ✓ | One of: any - none - on-failure. Restriction: All services must have the ame restart policy. The entire ACI container group will be restarted if needed. | -| service.deploy.labels | x | ACI does not have container-level labels. In addition, Azure tag are too restrictive to support Docker container labels.| +| service.deploy.restart_policy | ✓ | One of: `any`, `none`, `on-failure`. Restriction: All services must have the ame restart policy. The entire ACI container group will be restarted if needed. | +| service.deploy.labels | x | ACI does not have container-level labels. | | service.devices | x | | service.depends_on | x | | service.dns | x | | service.dns_search | x | -| service.domainname | ✓ | Mapped to ACI DNSLabelName. Restriction: all services must specify the same domainname, if specified. +| service.domainname | ✓ | Mapped to ACI DNSLabelName. Restriction: all services must specify the same `domainname`, if specified. | | service.tmpfs | x | -| service.entrypoint | x | ACI allows to override Command, but not Entrypoint. +| service.entrypoint | x | ACI only supports overriding the container command. | | service.env_file | ✓ | | service.environment | ✓ | | service.expose | x | @@ -49,13 +49,13 @@ __Glossary:__ | service.group_add | x | | service.healthcheck | x | | service.hostname | x | -| service.image | ✓ | Private images will be accessible if the user is logged in against the corresponding registry at deploy time. Users will be automatically logged in to Azure Container Registry from Azure login if possible. +| service.image | ✓ | Private images will be accessible if the user is logged into the corresponding registry at deploy time. Users will be automatically logged in to Azure Container Registry using their Azure login if possible. | | service.isolation | x | -| service.labels | x | ACI does not have container-level labels. In addition, Azure tag are too restrictive to support Docker container labels. | +| service.labels | x | ACI does not have container-level labels. | | service.links | x | | service.logging | x | | service.network_mode | x | -| service.networks | x | Communication between services is supported by defining mapping for each service in `/etc/hosts` in the container group. Each service can resolve names for other services and the resulting network calls will be redirected to `localhost`. +| service.networks | x | Communication between services is implemented by defining mapping for each service in the shared `/etc/hosts` file of the container group. Each service can resolve names for other services and the resulting network calls will be redirected to `localhost`. | | service.pid | x | | service.ports | ✓ | | service.secrets | ✓ | @@ -66,7 +66,7 @@ __Glossary:__ | service.ulimits | x | | service.userns_mode | x | | service.volumes | ✓ | Mapped to AZure File Shares. See #persistent_volumes -| service.restart | x | Replaced by service.deployment.restrt_policy | +| service.restart | x | Replaced by service.deployment.restart_policy | | | | | | __Volume__ | x | | | driver | ✓ | | @@ -82,19 +82,19 @@ __Glossary:__ | | | | -## Port Exposure +## Exposing ports -When one of the service exposes ports, the entire ACI container group will be exposed and will get a public IP allocated. -Since all services are mapped to containers in the same container group, several services cannot expose the same port number. -[ACI does not support port mapping](https://feedback.azure.com/forums/602224-azure-container-instances/suggestions/34082284-support-for-port-mapping), so source and target port defined in the Compose file must be identical. +When one or more services expose ports, the entire ACI container group will be exposed and will get a public IP allocated. +As all services are mapped to containers in the same container group, only one service cannot expose a given port number. +[ACI does not support port mapping](https://feedback.azure.com/forums/602224-azure-container-instances/suggestions/34082284-support-for-port-mapping), so the source and target ports defined in the Compose file must be the same. -When exposing ports, a service can also specify the service `domainname` field to set a DNS hostname. `domainname` will be used to specify ACI DNS Label Name, and the ACI container group will be reachable at .region.azurecontainer.io. -All services specifying a domainname must set the same value, applied to the entire container group. +When exposing ports, a service can also specify the service `domainname` field to set a DNS hostname. `domainname` will be used to specify the ACI DNS Label Name, and the ACI container group will be reachable at ..azurecontainer.io. +All services specifying a `domainname` must set the same value, as it is applied to the entire container group. -## Persistent Volumes +## Persistent volumes -Docker volumes are mapped to Azure File Shares. The compose file must define volumes in the `volume` section in order to be able to use them for one or several services. -Volumes are defined with a name, the `driver` field must be set to `azure_file`, and `driver_options` must define the storage account and fileshare to use for the volume. +Docker volumes are mapped to Azure file shares. Only the long Compose volume format is supported meaning that volumes must be defined in the `volume` section. +Volumes are defined with a name, the `driver` field must be set to `azure_file`, and `driver_options` must define the storage account and file share to use for the volume. A service can then reference the volume by its name, and specify the target path to be mounted in the container. ```yaml @@ -112,7 +112,7 @@ volumes: storage_account_name: mystorageaccount ``` -Short volume syntax is not allowed for ACI volumes, as it wa designed for local path when running local containers. -A Compose file can defined several volumes, with different Azure file shares or storage accounts. +The short volume syntax is not allowed for ACI volumes, as it was designed for local path bind mounting when running local containers. +A Compose file can define several volumes, with different Azure file shares or storage accounts. -Credentials for storage account will be automatically fetched at deployment time, using the Azure login to retrive storage account key for each storage account used. \ No newline at end of file +Credentials for storage accounts will be automatically fetched at deployment time using the Azure login to retrieve the storage account key for each storage account used. From c3983eea786b5f77c287a74a2dc551df9b77d4ec Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Wed, 7 Oct 2020 12:07:39 +0200 Subject: [PATCH 3/4] More changes from feedback Signed-off-by: Guillaume Tardif --- docs/aci-compose-features.md | 162 +++++++++++++++++++++-------------- 1 file changed, 96 insertions(+), 66 deletions(-) diff --git a/docs/aci-compose-features.md b/docs/aci-compose-features.md index cc03ef074..16ec9fc6f 100644 --- a/docs/aci-compose-features.md +++ b/docs/aci-compose-features.md @@ -14,72 +14,72 @@ __Legend:__ - __n:__ Not yet implemented - __x:__ Not applicable / no available conversion -| Keys | Map| Notes | -|--------------------------------|----|--------------------------------------------------------------| -| __Service__ | ✓ | | -| service.service.build | x | Ignored. No image build support on ACI. | -| service.cap_add, cap_drop | x | | -| service.command | ✓ | Override container Command. on ACI, specifying command will currently also override image entrypoint if the image has an Entrypoint defined | -| service.configs | n | | -| service.cgroup_parent | x | -| service.container_name | x | Service name is used as container name on ACI. | -| service.credential_spec | x | | -| service.deploy | ✓ | | -| service.deploy.endpoint_mode | x | | -| service.deploy.mode | x | | -| service.deploy.replicas | x | Only one replica is started for each service. | -| service.deploy.placement | x | -| service.deploy.update_config | x | -| service.deploy.resources | ✓ | Restriction: ACI Resource limits cannot be greater than the sum of resource requests for all containers in the container group. This will allow one containers in the same container group to compete with resources. -| service.deploy.restart_policy | ✓ | One of: `any`, `none`, `on-failure`. Restriction: All services must have the ame restart policy. The entire ACI container group will be restarted if needed. | -| service.deploy.labels | x | ACI does not have container-level labels. | -| service.devices | x | -| service.depends_on | x | -| service.dns | x | -| service.dns_search | x | -| service.domainname | ✓ | Mapped to ACI DNSLabelName. Restriction: all services must specify the same `domainname`, if specified. | -| service.tmpfs | x | -| service.entrypoint | x | ACI only supports overriding the container command. | -| service.env_file | ✓ | -| service.environment | ✓ | -| service.expose | x | -| service.extends | x | -| service.external_links | x | -| service.extra_hosts | x | -| service.group_add | x | -| service.healthcheck | x | -| service.hostname | x | -| service.image | ✓ | Private images will be accessible if the user is logged into the corresponding registry at deploy time. Users will be automatically logged in to Azure Container Registry using their Azure login if possible. | -| service.isolation | x | -| service.labels | x | ACI does not have container-level labels. | -| service.links | x | -| service.logging | x | -| service.network_mode | x | -| service.networks | x | Communication between services is implemented by defining mapping for each service in the shared `/etc/hosts` file of the container group. Each service can resolve names for other services and the resulting network calls will be redirected to `localhost`. | -| service.pid | x | -| service.ports | ✓ | -| service.secrets | ✓ | -| service.security_opt | x | -| service.stop_grace_period | x | -| service.stop_signal | x | -| service.sysctls | x | -| service.ulimits | x | -| service.userns_mode | x | -| service.volumes | ✓ | Mapped to AZure File Shares. See #persistent_volumes -| service.restart | x | Replaced by service.deployment.restart_policy | -| | | | -| __Volume__ | x | | -| driver | ✓ | | -| driver_opts | ✓ | | -| external | x | | -| labels | x | | -| | | | -| __Secret__ | x | | -| TBD | x | | -| | | | -| __Config__ | x | | -| TBD | x | | -| | | | +| Keys |Map| Notes | +|--------------------------------|---|--------------------------------------------------------------| +| __Service__ | ✓ | +| service.service.build | x | Ignored. No image build support on ACI. +| service.cap_add, cap_drop | x | +| service.command | ✓ | Override container Command. On ACI, specifying `command` will override the image command and entrypoint, if the image has an command or entrypoint defined | +| service.configs | x | +| service.cgroup_parent | x | +| service.container_name | x | Service name is used as container name on ACI. +| service.credential_spec | x | +| service.deploy | ✓ | +| service.deploy.endpoint_mode | x | +| service.deploy.mode | x | +| service.deploy.replicas | x | Only one replica is started for each service. +| service.deploy.placement | x | +| service.deploy.update_config | x | +| service.deploy.resources | ✓ | Restriction: ACI resource limits cannot be greater than the sum of resource reservations for all containers in the container group. Using container limits that are greater than container reservations will cause containers in the same container group to compete with resources. +| service.deploy.restart_policy | ✓ | One of: `any`, `none`, `on-failure`. Restriction: All services must have the same restart policy. The entire ACI container group will be restarted if needed. +| service.deploy.labels | x | ACI does not have container-level labels. +| service.devices | x | +| service.depends_on | x | +| service.dns | x | +| service.dns_search | x | +| service.domainname | ✓ | Mapped to ACI DNSLabelName. Restriction: all services must specify the same `domainname`, if specified. `domainname` must be unique globally in .azurecontainer.io +| service.tmpfs | x | +| service.entrypoint | x | ACI only supports overriding the container command. +| service.env_file | ✓ | +| service.environment | ✓ | +| service.expose | x | +| service.extends | x | +| service.external_links | x | +| service.extra_hosts | x | +| service.group_add | x | +| service.healthcheck | n | +| service.hostname | x | +| service.image | ✓ | Private images will be accessible if the user is logged into the corresponding registry at deploy time. Users will be automatically logged in to Azure Container Registry using their Azure login if possible. +| service.isolation | x | +| service.labels | x | ACI does not have container-level labels. +| service.links | x | +| service.logging | x | +| service.network_mode | x | +| service.networks | x | Communication between services is implemented by defining mapping for each service in the shared `/etc/hosts` file of the container group. Each service can resolve names for other services and the resulting network calls will be redirected to `localhost`. +| service.pid | x | +| service.ports | ✓ | Only symetrical por mapping is supported in ACI. See #exposing-ports. +| service.secrets | ✓ | +| service.security_opt | x | +| service.stop_grace_period | x | +| service.stop_signal | x | +| service.sysctls | x | +| service.ulimits | x | +| service.userns_mode | x | +| service.volumes | ✓ | Mapped to AZure File Shares. See #persistent-volumes. +| service.restart | x | Replaced by service.deployment.restart_policy +| | | +| __Volume__ | x | +| driver | ✓ | See #persistent-volumes. +| driver_opts | ✓ | +| external | x | +| labels | x | +| | | +| __Secret__ | x | +| TBD | x | +| | | +| __Config__ | x | +| TBD | x | +| | | ## Exposing ports @@ -90,6 +90,7 @@ As all services are mapped to containers in the same container group, only one s When exposing ports, a service can also specify the service `domainname` field to set a DNS hostname. `domainname` will be used to specify the ACI DNS Label Name, and the ACI container group will be reachable at ..azurecontainer.io. All services specifying a `domainname` must set the same value, as it is applied to the entire container group. +`domainname` must be unique globally in .azurecontainer.io ## Persistent volumes @@ -116,3 +117,32 @@ The short volume syntax is not allowed for ACI volumes, as it was designed for l A Compose file can define several volumes, with different Azure file shares or storage accounts. Credentials for storage accounts will be automatically fetched at deployment time using the Azure login to retrieve the storage account key for each storage account used. + +## Container Resources + +CPU and memory reservations and limits can be set in compose. +Resource limits must be greater than reservation. In ACI, setting resource limits different from resource reservation will cause containers in the same container group to compete for resources. Resource limits cannot be greater than the total resource reservation for the container group. (Therefore single containers cannot have resoure limits different from resource reservations) + +```yaml +services: + db: + image: mysql + deploy: + resources: + reservations: + cpus: '2' + memory: 2G + limits: + cpus: '3' + memory: 3G + web: + image: nginx + deploy: + resources: + reservations: + cpus: '1.5' + memory: 1.5G +``` + +In this example, the db container will be allocated 2 CPUs and 2G of memory. It will be allowed to use up to 3 CPUs and 3G of memory, using some of the resources allocated to the web container. +The web container will have its limits set to the same values as reservations, by default. From 808715d740b6279766ffc58b692ffce8a157a27e Mon Sep 17 00:00:00 2001 From: Guillaume Tardif Date: Wed, 7 Oct 2020 15:50:04 +0200 Subject: [PATCH 4/4] Adding secrets details Signed-off-by: Guillaume Tardif --- docs/aci-compose-features.md | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/docs/aci-compose-features.md b/docs/aci-compose-features.md index 16ec9fc6f..50d7afb6e 100644 --- a/docs/aci-compose-features.md +++ b/docs/aci-compose-features.md @@ -2,7 +2,7 @@ This document outlines the conversion of an application defined in a Compose file to ACI objects. At a high-level, each Compose deployment is mapped to a single ACI container group. -Each service is mapped to a container in the container group. The Docker ACI integration provides does not allow scaling of services. +Each service is mapped to a container in the container group. The Docker ACI integration does not allow scaling of services. ## Compose fields mapping @@ -58,7 +58,7 @@ __Legend:__ | service.networks | x | Communication between services is implemented by defining mapping for each service in the shared `/etc/hosts` file of the container group. Each service can resolve names for other services and the resulting network calls will be redirected to `localhost`. | service.pid | x | | service.ports | ✓ | Only symetrical por mapping is supported in ACI. See #exposing-ports. -| service.secrets | ✓ | +| service.secrets | ✓ | See #secrets. | service.security_opt | x | | service.stop_grace_period | x | | service.stop_signal | x | @@ -118,6 +118,33 @@ A Compose file can define several volumes, with different Azure file shares or s Credentials for storage accounts will be automatically fetched at deployment time using the Azure login to retrieve the storage account key for each storage account used. +## Secrets + +Secrets can be defined in compose files, and will need secret files available at deploy time next to the compose file. +The content of the secret file will be made available inside selected containers, under `/run/secrets// +External secrets are not supported with the ACI integration. +Due to ACI secret volume mounting, each secret file is mounted in its own folder named after the secret. + +```yaml +services: + nginx: + image: nginx + secrets: + - mysecret1 + db: + image: mysql + secrets: + - mysecret2 + +secrets: + mysecret1: + file: ./my_secret1.txt + mysecret2: + file: ./my_secret2.txt +``` + +The nginx container will have secret1 mounted as `/run/secrets/mysecret1/mysecret1`, the db container will have secret2 mounted as `/run/secrets/mysecret1/mysecret2` + ## Container Resources CPU and memory reservations and limits can be set in compose.