Solução de problemas de contêineres do Windows em hosts do Windows
Para começar, analisaremos as ferramentas fornecidas pela Microsoft que ajudam a solucionar problemas de contêineres do Windows.
Logs de aplicativo e contêiner
Quando se trata de padrões, os logs do contêiner e de aplicativo são baseados na saída padrão (STDOUT/STDERR). Esse não é o caso de alguns aplicativos do Windows e do sistema operacional Windows. Tradicionalmente, os logs de aplicativos do Windows e do sistema operacional vão para outros locais, como EventLogs, EventTraces e arquivos de log personalizados. Por conta dessa discrepância, as ferramentas que procuram logs de contêiner e aplicativo no STDOUT não conseguem ver os logs de aplicativos do Windows em contêineres. Para resolver isso, a Microsoft criou a ferramenta chamada LogMonitor para preencher essa lacuna e agregar todos os logs no contêiner do Windows ao STDOUT.
Para usar o LogMonitor, você precisa adicioná-lo à imagem de contêiner por meio do Dockerfile. Lembre-se que um Dockerfile é o método para criar um contêiner. Em um Dockerfile, há várias diretivas, incluindo FROM, ADD, ENTRYPOINT etc. ENTRYPOINT é PID 1 do contêiner e o contêiner é encerrado quando o processo ENTRYPOINT é encerrado. Para capturar o STDOUT/STDERR do contêiner, o LogMonitor funciona como um wrapper do aplicativo. Portanto, o ENTRYPOINT tem esta aparência:
ENTRYPOINT ["C:\\LogMonitor\\LogMonitor.exe", "C:\\MyApp.exe", "myparameter"]
Ao usar o LogMonitor, você pode tratar os contêineres do Windows como os do Linux, usando o comando docker logs para buscar a saída. Outras soluções de registro em log, como o Azure Monitor, também podem capturar os logs do contêiner.
O LogMonitor também precisa de um arquivo de configuração que indique quais eventos/arquivos ele deve agregar ao ser executado dentro do contêiner.
Veja abaixo um exemplo de configuração JSON e um Dockerfile para uma instância do IIS:
"LogConfig": {
"sources": [
{
"type": "EventLog",
"startAtOldestRecord": true,
"eventFormatMultiLine": false,
"channels": [
{
"name": "application",
"level": "Warning"
},
{
"name": "application",
"level": "Error"
}
]
},
{
"type": "File",
"directory": "c:\\inetpub\\logs",
"filter": "*.log",
"includeSubdirectories": true
},
{
"type": "ETW",
"eventFormatMultiLine": false,
"providers": [
{
"providerName": "IIS: WWW Server",
"providerGuid": "3A2A4E84-4C21-4981-AE10-3FDA0D9B0F83",
"level": "Information"
},
{
"providerName": "Microsoft-Windows-IIS-Logging",
"providerGuid": "7E8AD27F-B271-4EA2-A783-A47BDE29143B",
"level": "Information"
}
]
}
]
}
}
Esse JSON de exemplo coleta os logs de aplicativo do EventLog que são marcados como Aviso ou Erros. Ele também captura os logs de C:\inetpu\logs folder
(que é o log padrão do IIS). Por fim, ele também captura os logs ETW (Rastreamento de Eventos para Windows) provenientes dos provedores do IIS.
Veja aqui um Dockerfile de exemplo para monitorar um aplicativo Web em execução no IIS:
FROM mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2022
WORKDIR /LogMonitor
COPY LogMonitorConfig.json .
RUN powershell.exe -command wget -uri https://github.com/microsoft/windows-container-tools/releases/download/v1.1/LogMonitor.exe -outfile LogMonitor.exe
# Change the startup type of the IIS service from Automatic to Manual
RUN sc config w3svc start=demand
# Enable ETW logging for Default Web Site on IIS
RUN c:\windows\system32\inetsrv\appcmd.exe set config -section:system.applicationHost/sites /"[name='Default Web Site'].logFile.logTargetW3C:"File,ETW"" /commit:apphost
EXPOSE 80
# Start "C:\LogMonitor\LogMonitor.exe C:\ServiceMonitor.exe w3svc"
ENTRYPOINT ["C:\\LogMonitor\\LogMonitor.exe", "C:\\ServiceMonitor.exe", "w3svc"]
Esse exemplo cria uma imagem de contêiner com base na imagem de contêiner do IIS, copia o arquivo JSON do exemplo anterior e baixa a última versão do LogMonitor. Em seguida, ele configura o IIS e define o LogMonitor como o Ponto de Entrada, monitorando o serviço do IIS.
Agora que os logs do aplicativo e do IIS estão indo para STDOUT, você pode obter os logs com:
docker logs <container_name>
Conectar-se ao contêiner do Windows por meio de HCSDiag.exe
A colocação de uma sessão do PowerShell dentro do contêiner pode ser uma poderosa ferramenta de depuração para identificar um problema. Você pode usar hcsdiag.exe
(Diagnóstico do Serviço de Computação de Host) para interagir com o HCS. Lembre-se que o HCS é uma API de baixo nível para gerenciar os contêineres. Hcsdiag.exe
é uma ferramenta para interagir diretamente com a API. Com ele, você pode executar comandos para listar, executar, ler, gravar e abrir um console e muito mais.
Para colocar um console dentro do contêiner:
hcsdiag.exe list
hcsdiag.exe console -uvm <id>
O comando lista os contêineres (e as VMs) disponíveis no sistema. Em seguida, você pode especificar a ID do contêiner para o qual deseja abrir uma sessão do PowerShell.
Verificar logs do runtime do contêiner
Às vezes, pode haver problemas com a configuração do runtime. Para verificar os logs do runtime, você pode fazer o seguinte:
Daemon do Docker
Para obter os logs do Daemon do Docker, você pode verificar o Visualizador de Eventos. Você pode fazer isso no PowerShell:
Get-EventLog -LogName Application -Source Docker -After (Get-Date).AddMinutes(-5) | Sort-Object Time
O comando retorna os logs do Daemon do Docker. Se você quiser habilitar o nível de log de depuração, primeiro modifique os parâmetros de serviço do dockerd:
sc.exe config docker binpath= "\"C:\Program Files\Docker\dockerd.exe\" --run-service -D" sc.exe stop docker sc.exe start docker
Remova o sinalizador
-D
depois de concluir a depuração, pois isso corromperá os logs.Logs em contêineres
Normalmente, os logs em contêiner para
C:/logs/containerd.log
. Você também pode habilitar o nível de depuração configurando o serviço com–log-level debug
emsc.exe
. Adicione apenas o nível de log e não altere nenhum outro sinalizador. Saiba que os parâmetros de inicialização em contêiner podem ser diferentes devido ao desenvolvimento ativo no projeto.sc.exe config containerd binpath= "C:\containerd\bin\containerd.exe --log-level=debug --log-file=C:/logs/containerd.log" sc.exe stop containerd sc.exe start containerd
Logs do serviço de computação de host
O Daemon do Docker e o contêiner dependem do HCS. Ao solucionar problemas, você pode recuperar os logs do HCS com o PowerShell:
Get-WinEvent -LogName Microsoft-Windows-Hyper-V-Compute-Admin Get-WinEvent -LogName Microsoft-Windows-Hyper-V-Compute-Operational
Incompatibilidade de versão da imagem
Ao usar contêineres do Windows, você precisa prestar atenção à versão do Windows da imagem de contêiner e do host. O sistema operacional Windows tem quatro níveis de controle de versão: principal, secundário, build e revisão. Por exemplo, a versão 10.0.14393.103 teria uma versão principal de 10, uma versão secundária de 0, um número de build de 14393 e um número de revisão de 103.
Com exceção dos contêineres do Windows Server 2022 e do Windows 11, os contêineres do Windows são impedidos de iniciar quando o número de build entre o host do contêiner e a imagem de contêiner são diferentes. Por exemplo, quando o host de contêiner é a versão 10.0.14393.* (Windows Server 2016) e você tenta executar um contêiner com uma imagem versão 10.0.16299.* (Windows Server versão 1709), o serviço de computação do sistema operacional retorna um erro de incompatibilidade de versão.
Para contêineres do Windows em execução com isolamento de processo, o número de build precisa corresponder exatamente ao host. Para contêineres do Hyper-V, o número de build da imagem de contêiner pode ser menor que o host do contêiner. Por exemplo: você pode executar uma imagem de contêiner do Windows Server 2019 em um host do Windows Server 2022 usando o isolamento do Hyper-V.
Script de depuração do PowerShell
Como você viu nas seções anteriores, há muitas partes móveis ao executar contêineres do Windows que exigem configuração adequada. Agora você sabe como analisar os componentes do Windows quando algo der errado. A Microsoft criou um script do PowerShell para tentar capturar algumas configurações incorretas básicas para facilitar ainda mais as coisas. Você pode usar esse script com o PowerShell:
Invoke-WebRequest https://aka.ms/Debug-ContainerHost.ps1 -UseBasicParsing | Invoke-Expression
O script acima executa vários testes no sistema automaticamente. Todas as falhas estão em vermelho e há um resumo de aprovação/falha no final. Você pode usar essas informações para solucionar mais problemas do sistema.