23 Things You Should Know
Vini Soto редактировал(а) эту страницу 2020-12-11 12:52:36 -08:00
Этот файл содержит неоднозначные символы Юникода!

Этот файл содержит неоднозначные символы Юникода, которые могут быть перепутаны с другими в текущей локали. Если это намеренно, можете спокойно проигнорировать это предупреждение. Используйте кнопку Экранировать, чтобы подсветить эти символы.

General Information

Deployment

Configuration

Troubleshooting

Best Practices

General Information

If a feature is disabled in the portal then it is not enabled for Windows Container base Apps

Azure App Service has a rich feature-set, but not all of those features are currently available for apps deployed in Windows Containers. We're working on adding new features all the time, and once new features are added, they'll be enabled on the menu in the Azure portal. If the menu item for a particular feature is disabled (greyed out) in the menu for your Windows Container based apps, it's simply because we haven't enabled that feature yet.

If you do not see a feature you want then you can request the feature

If you want a feature that isn't currently available, please feel free to request the feature in our Web Apps Feedback forum. Please make sure to put "[Windows Container]" in the title so that we'll know it applies to Windows Container support.

Available Resources per App Service Plan SKU

Windows Containers are deployed onto the local SSD Storage in each instance within the App Service Plan. Below is a table of the maximum available storage and addressable memory per SKU. Each container by default is deployed configured to address 2GB of Memory, but you can change this setting. To gain more overall memory or storage you can scale up the App Service Plan.

App Service Plan SKU Code Maximum Available Disk Maximum Addressable Memory
PC2 19 GB 6.5 GB
PC3 60 GB 13.5 GB
PC4 79 GB 29 GB

Deployment

If you change your Docker container then it may take a few minutes for it to take effect

If you change your Docker container settings to point to a new container and then click Save, it may take a minute or so before you'll see the new container when you browse to your site. While the new container is being pulled and started, we will continue to serve requests to your site using the old container. Only when the new container is started and ready to receive requests will we start sending requests to it.

Container images are stored on disk unless a worker change happens

The first time you use a custom Docker image, we will do a "docker pull" and pull all layers. These layers are stored on disk just as if you were using Docker on-premises. When we do a "docker pull" after a site restart, we will only pull layers that have changed. If there have been no changes, we will simply use existing layers on the local disk.

If you change workers for any reason, however, we will have to pull down all layers again. Your worker will change if you scale up/down or if you scale out to add additional workers. There are also rare cases where your worker may change without a scale operation, but these cases are uncommon.

Configuration

You can enable and disable storage persistence with an app setting.

You can use an app setting called WEBSITES_ENABLE_APP_SERVICE_STORAGE to control whether or not the /home directory of your app is mapped to Azure Storage. If you need files to be persisted in scale operations or across restarts, you should add this app setting and set it to "true". If you don't require file persistence, you can set this app setting to false.

The absence of this app setting will result in the setting being "true". In other words, if this app setting does not exist in your app, you will see the /home directory mapped to Azure Storage.

Keep in mind that if you enable App Service Storage, when an Azure Storage changeover occurs (which does happen periodically), your site will restart when the storage volume changes.

Note: If App Service Storage is not enabled, any files written into the /home folder will not be persisted across instances (in the case of a scale out) or across restarts.

Even if storage persistence is disabled, the /home directory will be mapped to Azure Storage in the Kudu (Advanced Tools). That way, the /home/LogFiles directory will persist between restarts and scale out operations in the Kudu container.

App Settings are injected into your app as environment variables at runtime.

If you need to set an environment variable for your application, simply add an App Setting in the Azure portal. When your app runs, we will inject the app setting into the process as an environment variable automatically.

All containers have 1GB Ram assigned by default but you can configure this setting

By default all Windows Containers deployed in Azure App Service are limited to 1GB RAM. You can change this value by providing the following setting as an app setting - CONTAINER_MEMORY: defined in MB and must be <= to the total physical memory of the host.

Reducing the number of Cores used by your container

Using Application Settings in your configuration blade, you are able to reduce the number of cores used per container. This enables you to take advantage of scenarios like allocating resources to appropriate slots as you may want to reduce the number of cores used in your staging slot in comparison to your production slot.

NOTE: Updating your app setting without a manual restart may trigger your application to restart automatically causing minimal downtime. Use best practice here and change the app setting in a staging slot before you swap it to production.

By default, the Windows Containers run with all available cores for your chosen App Service Plan SKU.
If you want to reduce the number of cores used by your container, you can do so by using the CONTAINER_CPU_CORES attribute in your Application Settings and setting the preferred number as your value. Save the new App Setting and restart your application. Verify your adjusted number by going to the Kudu Console (https://.scm.azurewebsites.net) and typing in the following commands using powershell. Each command will output a number.

  • Get-ComputerInfo | ft CsNumberOfLogicalProcessors
  • Get-ComputerInfo | ft CsNumberOfProcessors

The number of logical processors shown is the number of enabled processors for a system, which doesn't include the disabled processors. If the computer system has two physical processors each container two logical processors, then the CsNumberOfProcessors is 2 and the CsNumberOfLogicalProcessors is 4. The processors may be multicore or hyperthreading processors. Information on how many cores are available per SKU can be found here.

Troubleshooting

If your site does not start then check the Docker log

We log useful information into the Docker log that can help you troubleshoot your site when it doesn't start or if it's restarting. We log a lot more than you might be used to seeing in a Docker log, and we will continue to work on making this logging more useful.

There are several ways to access Docker logs:

Docker logs appear on the Container Settings page in the portal. (These are truncated, but you can download them by clicking on the Download Logs button.) You can find the Docker log in the /LogFiles directory. You can access this via the Kudu (Advanced Tools) console or by using an FTP client to access it. You can use our API to download the current logs. (See "You can discover and download the latest Docker logs using Kudu" in this post for info on that.) The naming convention for the Docker log is YYYY_MM_DD_RDxxxxxxxxxxxx_docker.log. Note that if you try and download the Docker log that is currently in use using an FTP client, you may get an error because of a file lock. In that case, you can download it using our API (see "You can discover and download the latest Docker logs using Kudu" in this post) or you can use "tail" in the console to view it. (Our API gets you the current Docker log, so if you want to review a past log, use the "tail" option.)

To view the Docker log using tail, access the console, switch into the LogFiles directory, and run this command:

tail 2017_09_05_RD*0FA_docker.log

In this example, I'm viewing the Docker log for September 5. Note that I'm also using a wildcard replacement for the machine ID (the RD number) so that I don't have to type all the characters.

You can discover and download the latest Docker logs using Kudu

We have an API that allows you to easily see the current Docker log details (such as the filename, etc.) and also download the current Docker logs in Zip format.

To see details on the current Docker logs in JSON format, you can use this URL:

https://[sitename].scm.azurewebsites.net/api/logs/docker

You can get to this easily by going to Advanced Tools (Kudu) and then appending "/api/logs/docker" to the URL. The output of this will be a JSON response with the most relevant and current Docker logs.

If you want to download the logs shown in the above API in Zip format, append "zip" to the URL. For example:

https://[sitename].scm.azurewebsites.net/api/logs/docker/zip

You can also click the link in Advanced Tools (Kudu) to download your latest Docker logs in Zip format.

You can view the most recent entries in your Docker log in the Azure Portal

To make it easier to see what's going on with your Docker container, we show you the latest entries in the Docker log in the Azure portal. Simply click on Container Settings in the portal menu and you'll see the Docker log as shown in the figure below.

Viewing the Docker Log

You can click the Copy button to copy the Docker log. You can also download the full Docker log by clicking on Download Logs.

Your container must respond to an HTTP ping

As I've already said, we will wait a certain amount of time for your container to start before we consider it be a failed start. In order for us to consider a container to be successfully started, the container must start and it must respond to an HTTP ping. If the container starts but does not respond to a ping, we will eventually log an event in the Docker log saying that it didn't start.

If your application is memory/resource intensive it is likely that the container might not be able to respond within these parameters.

We introduced some application settings which you can set on your app which will enable you to control the actions when availability checks fail:

CONTAINER_AVAILABILITY_CHECK_MODE=Repair

The platform checks for availability and stops and restart the container after 3 consecutive availability checks (default)

CONTAINER_AVAILABILITY_CHECK_MODE=ReportOnly

The platform checks for availability and reports (in the logs) the container after 3 consecutive availability checks (default). The platform doesnt stop/restart the container

CONTAINER_AVAILABILITY_CHECK_MODE=Off

The platform doesnt check for availability

Your container starts when testing locally but immediately exits or fails to start on App Service

As you examine your logs, you might find errors like:

Container fails to start with a Docker API error. For example:

21/11/2020 00:10:43.954 ERROR - Site: my-windows-container-site - [8ca444ad9cca68451c0aa3f39909d60d1cd9e424955910fb43dfe9c7c67b64c3] - Docker client error. Failed to start container. Container: 8ca444ad9cca68451c0aa3f39909d60d1cd9e424955910fb43dfe9c7c67b64c3. StatusCode: InternalServerError. Message: Docker API responded with status code=InternalServerError, response={"message":"container 8ca444ad9cca68451c0aa3f39909d60d1cd9e424955910fb43dfe9c7c67b64c3 encountered an error during hcsshim::System::Start: context deadline exceeded"}

Container fails to start with a Compute System error, for example:

20/11/2020 05:22:46.269 ERROR - Site: my-windows-container-site - Unable to start container. Error message: Modify Compute System failed.

Error when configuring container:

20/11/2020 05:19:59.870 INFO - Site: my-windows-container-site - [871adc6c257238d53361f530c3f312cbac92ef17e1d3a424c4b1a9959af6e57a] - CONTAINER_SKIP_CONFIGURATION app setting is set to 0
20/11/2020 05:19:59.870 INFO - Site: my-windows-container-site - [871adc6c257238d53361f530c3f312cbac92ef17e1d3a424c4b1a9959af6e57a] - Configuring container
20/11/2020 05:19:59.870 INFO - Site: my-windows-container-site - [871adc6c257238d53361f530c3f312cbac92ef17e1d3a424c4b1a9959af6e57a] - Call configure container utility
20/11/2020 05:19:59.925 ERROR - Site: my-windows-container-site - [871adc6c257238d53361f530c3f312cbac92ef17e1d3a424c4b1a9959af6e57a] - Error configuring container

Container exits by itself immediately with no evident error:

20/11/2020 05:19:59.926 INFO - Site: app-PartnerIntegrationService-PROD - [871adc6c257238d53361f530c3f312cbac92ef17e1d3a424c4b1a9959af6e57a] - Container has started.
20/11/2020 05:20:20.967 INFO - Site: app-PartnerIntegrationService-PROD - [871adc6c257238d53361f530c3f312cbac92ef17e1d3a424c4b1a9959af6e57a] - Container has exited
20/11/2020 05:20:20.968 ERROR - Site: app-PartnerIntegrationService-PROD - [871adc6c257238d53361f530c3f312cbac92ef17e1d3a424c4b1a9959af6e57a] - Container was not ready because it has been cancelled or exited

If your container starts succesfully when trying locally, but fails to start when hosted in App Service for Windows Containers, you can try the following suggestions. Keep in mind that your local environment has many differences when compared to App Service (for example: the underlying Operating System, network conditions, etc.):

  1. Make sure your container responds to HTTP requests on port 80 (or the port specified by the WEBSITE_PORT app setting. If the WEBSITE_PORT is app setting is not present, port 80 is assumed). See Your container must respond to an HTTP ping.

  2. Make sure that port 80 (or the port specified by the WEBSITE_PORT app setting) is exposed in your dockerfile (for example: EXPOSE 80).

  3. Indicate to the platform to skip container configuration by setting the CONTAINER_SKIP_CONFIGURATION app setting to 1 (CONTAINER_SKIP_CONFIGURATION=1). App Service configures containers to enable certain features like Azure Monitor logging as part of the container start up. By setting CONTAINER_SKIP_CONFIGURATION=1 will not attempt such configuration thus discarding any potential issue there.

  4. Make sure your application has a global Try/Catch block in the entry point. Any unhandled exception that bubble all the way up to your entrypoint (for example, Program.cs in a dotnetcore app) will crash the program and cause the container to exit without showing any errors or logs.

  5. Make sure you log all exceptions as part of global your Try/Catch block. Also, make sure you give enough time for logging before exiting the entry point (this is especially important when using a remote/asynchronous logging mechanism like App Insights)

  6. When running locally, make sure you are running your containers using the --isolation=hyperv flag as part of your docker run command

  7. As an ultimate troubleshooting technique, try starting your container with a "safe" entrypoint, which will allow you to discard any potential issue outside of your application code. For example, you could create an init_container.cmd file with the following contents and use it as an entry point:

:Do

    WaitFor SomethingThatIsNeverHappening /t 60 2>nul

GoTo Do

And then use it as the entrypoint of your container in your dockerfile:

ENTRYPOINT ["C:\\app\\init_container.cmd"]

When your container starts, you can go to the App Service console (kudu) and manually run your original entry point:

Run entrypoint from kudu

Best Practices

Do not install components using Win RM PowerShell Session as they will not persist

You can connect, via PowerShell, to your app container using Win-RM and install components. However, when your site is restarted, anything that you install will be gone. Why is that? That's the way Docker works. When your site starts, we run your Docker image and create a Docker container. Your app runs inside of that container, and the file system contains only what is in the Docker image. If your Docker image doesn't install a particular component, it won't be there when your container starts.

If you want to install a particular component, make sure that you do it in a Dockerfile so that the component is included in your Docker image. See this documentation for full information on how to do that.

You should not have SSL support within your container

We terminate SSL at the front-ends. That means that SSL requests never get to your Web App. That's good news for you because it means that you don't need to (and should not) implement any support for SSL into your app. Also as stated above, it's important to understand that the front-ends where SSL is terminated are inside of our Azure data centers. If you use SSL with your site, your traffic across the Internet will always be safely encrypted.

You can only expose one port to the outside world

Web App for Containers currently allows you to expose only one port to the outside world. That means that your container can only listen for HTTP requests on a single port. Some apps need multiple ports. For example, you might have one port that is used for requests into the app and a separate port that is used for a dashboard or admin portal. As of today, that configuration isn't possible in Web App for Containers.

We will attempt to detect which port to bind to your container, but you can also use the WEBSITES_PORT app setting and configure it with a value for the port you want to bind to your container.