Compatibilidade de versão do contêiner do Windows

Aplica-se a: Windows Server 2022, Windows Server 2019 e Windows Server 2016

O Windows Server 2016 e a Atualização de Aniversário do Windows 10 (ambas versões 14393) foram as primeiras versões do Windows que desenvolveram e executaram os contêineres do Windows Server. Os contêineres desenvolvidos com essas versões podem ser executados nas versões mais recentes, mas você precisa estar a par de algumas informações antes de começar.

A arquitetura do Windows é muito diferente do Linux. O Linux tem um kernel monolítico, enquanto no Windows os modos Usuário e Kernel são mais fortemente ligados. Até a introdução dos contêineres, os modos Usuário e Kernel do Windows eram disparados em sincronia, resultando em requisitos de compatibilidade de contêiner no Windows que diferiam da norma no Linux.

O desacoplamento do limite de Usuário/Kernel no Windows é uma tarefa monumental e não é nem um pouco trivial, no entanto, estamos trabalhando muito para estabilizar esse limite em todos os Windows e fornecer aos nossos clientes a flexibilidade de executar contêineres de baixo nível. A partir do Windows 11 e Windows Server 2022, estamos possibilitando a execução de contêineres WS2022 isolados do processo em hosts do Windows 11. Fizemos o melhor possível para capturar as áreas que poderiam romper o limite, mas agora queremos abrir o recurso para desenvolvedores no Windows 11 para comentários. Queremos muito habilitar essa experiência para você, portanto, conte-nos quando você se deparar com problemas.

Para outros cenário em que haja uma incompatibilidade no host/convidado, a compatibilidade do controle de versão do Windows entre o modo Usuário/Kernel é possível, mas não é garantida e, portanto, a imagem de contêiner será impedida de ser executada no host. Para qualquer versão incompatível, a execução com o isolamento do Hyper-V fornecerá ao contêiner um conjunto de binários de Kernel correspondentes e não dependerá da versão do host. Confira as tabelas abaixo para ver uma matriz de compatibilidade detalhada.

Compatibilidade do sistema operacional do host do Windows Server

Versão do sistema operacional da imagem base de contêiner Dá suporte eu isolamento do Hyper-V Dá suporte ao isolamento do processo
Windows Server 2022
Windows Server 2019
Windows Server 2016

Compatibilidade do sistema operacional do host do Windows Client

Versão do sistema operacional da imagem base de contêiner Dá suporte eu isolamento do Hyper-V Dá suporte ao isolamento do processo
Windows Server 2022 ✔(versão prévia)
Windows Server 2019
Windows Server 2016

Observação

O Windows 10 versão 1809 e o Windows Server 2019 tinham o mesmo número de build no momento da GA. Desde então, eles receberam atualizações independentes, resultando em incompatibilidade no número de build. O isolamento de processo no cliente Windows está disponível em versão prévia para o Windows 11 com imagens do Windows Server 2022, com a incompatibilidade no número de build. Caso você tenha um requisito para executar contêineres isolados no processo no Windows 10, informe-nos nos problemas do GitHub.

Correspondência de versão do host do contêiner com versões de imagens do contêiner

Contêineres do Windows Server

Número de build (nova versão do Windows)

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. O número de build só é alterado quando novas versões do sistema operacional são publicadas e o número de revisão é atualizado conforme as atualizações do Windows são aplicadas.

Com exceção do WS2022 e do Windows 11, os contêineres do Windows Server 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 do contêiner tiver a versão 10.0.14393.* (Windows Server 2016) e você tentar executar um contêiner com uma versão de imagem 10.0.16299.* (Windows Server, versão 1709), o serviço de computação do sistema operacional retornará um erro de incompatibilidade de versão.

Restrições do Windows Server 2016

Contêineres baseados no Windows Server 2016 não serão executados em um sistema em que os números de revisão do host do contêiner e da imagem de contêiner forem diferentes. Por exemplo, se o host do contêiner for da versão 10.0.14393.1914 (Windows Server 2016 com KB4051033 aplicado) e a imagem de contêiner for da versão 10.0.14393.1944 (Windows Server 2016 com KB4053579 aplicado), a imagem poderá não ser iniciada.

Para os hosts ou as imagens que usam o Windows Server, versão 1809 e posterior, essa regra não se aplica: o host e a imagem de contêiner não precisam ter revisões correspondentes.

Observação

É altamente recomendável que você atualize o host e os contêineres com os patches e atualizações mais recentes para que eles permaneçam seguros e compatíveis. Para obter diretrizes importantes sobre como atualizar contêineres do Windows, consulte Atualizar contêineres do Windows Server.

Aplicação prática

Exemplo 1: o host do contêiner está executando o Windows Server 2016 com o KB4041691 aplicado. Qualquer contêiner do Windows Server implantado nesse host deve ser baseado nas imagens base do contêiner versão 10.0.14393.1770. Se você aplicar a KB4053579 ao contêiner de host, também deverá atualizar as imagens para verificar se o contêiner de host dá suporte a elas.

Exemplo 2: O host do contêiner está executando o Windows Server versão 1809 com a KB4534273 aplicada. Qualquer contêiner do Windows Server implantado nesse host deve ser baseado em uma imagem base de contêiner do Windows Server versão 1809 (10.0.17763), mas não precisa corresponder à KB do host. Se a KB4534273 for aplicada ao host, as imagens de contêiner ainda terão suporte, mas recomendamos atualizá-las para solucionar possíveis problemas de segurança.

Consultando a versão

Método 1: Introduzido na versão 1709, o prompt cmd e o comando ver agora retornam os detalhes da revisão.

Microsoft Windows [Version 10.0.16299.125]
(c) 2017 Microsoft Corporation. All rights reserved.

C:\>ver

Microsoft Windows [Version 10.0.16299.125]

Método 2: Modifique a seguinte chave do registro: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion

Por exemplo:

C:\>reg query "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion" /v BuildLabEx
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS C:\Users\Administrator> (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\').BuildLabEx
14393.321.amd64fre.rs1_release_inmarket.161004-2338

Para saber qual versão sua imagem base usa, examine as marcas no hub do Docker ou a tabela de hash de imagem fornecida na descrição da imagem. O histórico de atualização do Windows 10 indica quando cada build e cada revisão foi lançada.

Isolamento do Hyper-V para contêineres

Você pode executar os contêineres do Windows com ou sem o isolamento do Hyper-V. O isolamento do Hyper-V cria um limite seguro em torno do contêiner com uma VM otimizada. Ao contrário dos contêineres do Windows padrão, que compartilham o kernel entre os contêineres e o host, cada contêiner isolado do Hyper-V tem sua própria instância do kernel do Windows. Isso significa que você pode ter diferentes versões de sistema operacional no host e na imagem do contêiner (para obter mais informações, consulte a matriz de compatibilidade a seguir).

Para executar um contêiner com isolamento do Hyper-V, basta adicionar a marca --isolation=hyperv ao seu comando docker run.

Erros gerados por versões incompatíveis

Se você tentar executar uma combinação sem suporte, receberá o seguinte erro:

docker: Error response from daemon: container b81ed896222eb87906ccab1c3dd2fc49324eafa798438f7979b87b210906f839 encountered an error during CreateContainer: failure in a Windows system call: The operating system of the container does not match the operating system of the host. (0xc0370101) extra info: {"SystemType":"Container","Name":"b81ed896222eb87906ccab1c3dd2fc49324eafa798438f7979b87b210906f839","Owner":"docker","IsDummy":false,"VolumePath":"\\\\?\\Volume{2443d38a-1379-4bcf-a4b7-fc6ad4cd7b65}","IgnoreFlushesDuringBoot":true,"LayerFolderPath":"C:\\ProgramData\\docker\\windowsfilter\\b81ed896222eb87906ccab1c3dd2fc49324eafa798438f7979b87b210906f839","Layers":[{"ID":"1532b584-8431-5b5a-8735-5e1b4fe9c2a9","Path":"C:\\ProgramData\\docker\\windowsfilter\\b2b88bc2a47abcc682e422507abbba9c9b6d826d34e67b9e4e3144cc125a1f80"},{"ID":"a64b8da5-cd6e-5540-bc73-d81acae6da54","Path":"C:\\ProgramData\\docker\\windowsfilter\\5caaedbced1f546bccd01c9d31ea6eea4d30701ebba7b95ee8faa8c098a6845a"}],"HostName":"b81ed896222e","MappedDirectories":[],"HvPartition":false,"EndpointList":["002a0d9e-13b7-42c0-89b2-c1e80d9af243"],"Servicing":false,"AllowUnqualifiedDNSQuery":true}.

Há três maneiras de resolver esse erro:

  • Recompile o contêiner com base na versão correta do mcr.microsoft.com/microsoft-windows-nanoserver ou do mcr.microsoft.com/windows/servercore
  • Se o host for mais recente, execute docker run --isolation=hyperv ...
  • Tente executar o contêiner em um host diferente com a mesma versão do Windows

Escolha a versão do sistema operacional do contêiner a ser usada

Observação

A partir de 16 de abril de 2019, a marca “mais recente” não é mais publicada ou mantida para as imagens de contêiner do sistema operacional base do Windows. Declare uma marca específica ao extrair ou fazer referência a imagens desses repositórios.

Você deve saber qual versão precisa usar para seu contêiner. Por exemplo, se você quiser o Windows Server versão 1809 como seu sistema operacional de contêiner e quiser ter os patches mais recentes para ele, use a marca 1809 ao especificar qual versão das imagens de contêiner do sistema operacional de base você deseja, desta forma:

FROM mcr.microsoft.com/windows/nanoserver:1809
...

No entanto, se você quiser um patch específico do Windows Server 1809, poderá especificar o número da KB na marca. Por exemplo, para obter uma imagem de contêiner do sistema operacional base do Nano Server do Windows Server versão 1809 com a KB4493509 aplicada a ela, você deve especificá-la da seguinte forma:

FROM mcr.microsoft.com/windows/nanoserver:1809-KB4493509
...

Você também pode especificar os patches exatos necessários com o esquema que usamos anteriormente, especificando a versão do sistema operacional na marca:

FROM mcr.microsoft.com/windows/nanoserver:10.0.17763.437
...

As imagens base do Server Core baseadas no Windows Server 2022 e no Windows Server 2019 são versões do LTSC (Canal de Manutenção em Longo Prazo). Se você, por exemplo, quiser o Windows Server 2019 como o sistema operacional do contêiner da sua imagem do Server Core e desejar ter os patches mais recentes para ele, você poderá especificar as versões do LTSC desta forma:

FROM mcr.microsoft.com/windows/servercore:ltsc2019
...

Fazendo a correspondência de versões usando o Docker Swarm

Atualmente, o Docker Swarm não tem uma maneira interna de fazer correspondência da versão do Windows que um contêiner usa para um host com a mesma versão. Se você atualizar o serviço para usar um contêiner mais recente, ele será executado com êxito.

Se você precisar executar várias versões do Windows por um longo período de tempo, há duas abordagens que podem ser adotadas: configure os hosts do Windows para sempre usar o isolamento do Hyper-V ou usar restrições de rótulo.

Localizando um serviço que não será iniciado

Se um serviço não for iniciado, você verá que MODE será replicated, mas REPLICAS não sairá de 0. Para saber se o problema está na versão do SO, execute os comandos a seguir:

Execute docker service ls para localizar o nome do serviço:

ID                  NAME                MODE                REPLICAS            IMAGE                                             PORTS
xh6mwbdq2uil        angry_liskov        replicated          0/1                 windows/servercore/iis

Execute docker service ps (nome do serviço) para obter o status e as últimas tentativas:

C:\Program Files\Docker>docker service ps angry_liskov
ID                  NAME                 IMAGE                                             NODE                DESIRED STATE       CURRENT STATE               ERROR                              PORTS
klkbhn742lv0        angry_liskov.1       windows/servercore/iis   WIN-BSTMQDRQC2E     Ready               Ready 3 seconds ago
y5blbdum70zo         \_ angry_liskov.1   windows/servercore/iis   WIN-BSTMQDRQC2E     Shutdown            Failed 24 seconds ago       "starting container failed: co…"
yjq6zwzqj8kt         \_ angry_liskov.1   windows/servercore/iis   WIN-BSTMQDRQC2E     Shutdown            Failed 31 seconds ago       "starting container failed: co…"

ytnnv80p03xx         \_ angry_liskov.1   windows/servercore/iis   WIN-BSTMQDRQC2E     Shutdown            Failed about a minute ago   "starting container failed: co…"
xeqkxbsao57w         \_ angry_liskov.1   windows/servercore/iis   WIN-BSTMQDRQC2E     Shutdown            Failed about a minute ago   "starting container failed: co…"

Se você vir starting container failed: ..., poderá ver o erro completo com docker service ps --no-trunc (nome do contêiner) :

C:\Program Files\Docker>docker service ps --no-trunc angry_liskov
ID                          NAME                 IMAGE                                                                                                                     NODE                DESIRED STATE       CURRENT STATE                     ERROR                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          PORTS
dwsd6sjlwsgic5vrglhtxu178   angry_liskov.1       windows/servercore/iis@sha256:868bca7e89e1743792e15f78edb5a73070ef44eae6807dc3f05f9b94c23943d5   WIN-BSTMQDRQC2E     Running             Starting less than a second ago
y5blbdum70zoh1f6uhx5nxsfv    \_ angry_liskov.1   windows/servercore/iis@sha256:868bca7e89e1743792e15f78edb5a73070ef44eae6807dc3f05f9b94c23943d5   WIN-BSTMQDRQC2E     Shutdown            Failed 39 seconds ago             "starting container failed: container e7b5d3adba7e510569c18d8e55f7c689d7cb92be40a516c91b363e27f84604d0 encountered an error during CreateContainer: failure in a Windows system call: The operating system of the container does not match the operating system of the host. (0xc0370101) extra info: {"SystemType":"Container","Name":"e7b5d3adba7e510569c18d8e55f7c689d7cb92be40a516c91b363e27f84604d0","Owner":"docker","VolumePath":"\\\\?\\Volume{2443d38a-1379-4bcf-a4b7-fc6ad4cd7b65}","IgnoreFlushesDuringBoot":true,"LayerFolderPath":"C:\\ProgramData\\docker\\windowsfilter\\e7b5d3adba7e510569c18d8e55f7c689d7cb92be40a516c91b363e27f84604d0","Layers":[{"ID":"bcf2630f-ea95-529b-b33c-e5cdab0afdb4","Path":"C:\\ProgramData\\docker\\windowsfilter\\200235127f92416724ae1d53ed3fdc86d78767132d019bdda1e1192ee4cf3ae4"},{"ID":"e3ea10a8-4c2f-5b93-b2aa-720982f116f6","Path":"C:\\ProgramData\\docker\\windowsfilter\\0ccc9fa71a9f4c5f6f3bc8134fe3533e454e09f453de662cf99ab5d2106abbdc"},{"ID":"cff5391f-e481-593c-aff7-12e080c653ab","Path":"C:\\ProgramData\\docker\\windowsfilter\\a49576b24cd6ec4a26202871c36c0a2083d507394a3072186133131a72601a31"},{"ID":"499cb51e-b891-549a-b1f4-8a25a4665fbd","Path":"C:\\ProgramData\\docker\\windowsfilter\\fdf2f52c4323c62f7ff9b031c0bc3af42cf5fba91098d51089d039fb3e834c08"},{"ID":"1532b584-8431-5b5a-8735-5e1b4fe9c2a9","Path":"C:\\ProgramData\\docker\\windowsfilter\\b2b88bc2a47abcc682e422507abbba9c9b6d826d34e67b9e4e3144cc125a1f80"},{"ID":"a64b8da5-cd6e-5540-bc73-d81acae6da54","Path":"C:\\ProgramData\\docker\\windowsfilter\\5caaedbced1f546bccd01c9d31ea6eea4d30701ebba7b95ee8faa8c098a6845a"}],"HostName":"e7b5d3adba7e","HvPartition":false,"EndpointList":["298bb656-8800-4948-a41c-1b0500f3d94c"],"AllowUnqualifiedDNSQuery":true}"

Esse é o mesmo erro que CreateContainer: failure in a Windows system call: The operating system of the container does not match the operating system of the host. (0xc0370101).

Corrigir - Atualizar o serviço para usar uma versão compatível

Duas considerações devem ser feitas para Docker Swarm. Se você tiver um arquivo Compose com um serviço que usa uma imagem que você não criou, será necessário atualizar a referência apropriadamente. Por exemplo:

version: '3'

services:
  YourServiceName:
    image: windows/servercore:1709
...

Outra questão que deve ser levada em consideração é se a imagem que você está indicando foi criada por você (por exemplo, contoso/myimage):

version: '3'

services:
  YourServiceName:
    image: contoso/myimage
...

Nesse caso, você deve usar o método descrito em Erros de versões incompatíveis para modificar esse dockerfile em vez da linha docker-compose.

Mitigação - Use o isolamento do Hyper-V com o Docker Swarm

Os contêineres do Windows dão suporte ao uso do isolamento do Hyper-V por contêiner, o que exige a alteração da configuração do serviço do Docker e a reinicialização do mecanismo do Docker.

  1. Editar C:\ProgramData\docker\config\daemon.json

  2. Adicionar uma linha com "exec-opts":["isolation=hyperv"]

    Observação

    O arquivo daemon.json não existe por padrão. Se você achar que isso está acontecendo ao fazer a espionagem do diretório, crie o arquivo. Depois, você copiará o seguinte:

    {
        "exec-opts":["isolation=hyperv"]
    }
    
  3. Feche e salve o arquivo, em seguida, reinicie o mecanismo do Docker executando os seguintes cmdlets no PowerShell:

    Stop-Service docker
    Start-Service docker
    
  4. Depois de reiniciar o serviço, inicie os contêineres. Quando eles estiverem em execução, verifique o nível de isolamento de um contêiner inspecionando o contêiner com o seguinte cmdlet:

    docker inspect --format='{{json .HostConfig.Isolation}}' $instanceNameOrId
    

Ele retornará "process" ou "hyperv". Se você tiver modificado e definido daemon.json conforme descrito acima, ele mostrará o último.

Mitigação - Use rótulos e restrições

Veja como usar rótulos e restrições para fazer correspondências de versões:

  1. Adicionar etiquetas a cada nó.

    Em cada nó, adicione dois rótulos: OS e OsVersion. Isso pressupõe que você está em uma execução local, mas pode ser modificado para defini-las em um host remoto.

    docker node update --label-add OS="windows" $ENV:COMPUTERNAME
    docker node update --label-add OsVersion="$((Get-ComputerInfo).OsVersion)" $ENV:COMPUTERNAME
    

    Posteriormente, você pode verificá-los executando o comando docker node inspect, que deve mostrar os rótulos adicionados recentemente:

           "Spec": {
                "Labels": {
                   "OS": "windows",
                   "OsVersion": "10.0.16296"
               },
                "Role": "manager",
                "Availability": "active"
            }
    
  2. Adicione uma restrição de serviço.

    Depois de rotular cada nó, você pode atualizar as restrições que determinam o posicionamento dos serviços. No exemplo a seguir, substitua “contoso_service” pelo nome do serviço real:

    docker service update \
        --constraint-add "node.labels.OS == windows" \
        --constraint-add "node.labels.OsVersion == $((Get-ComputerInfo).OsVersion)" \
        contoso_service
    

    Isso reforça e limita o local onde um nó pode ser executado.

Para saber mais sobre como usar restrições de serviço, confira a referência de criação de serviço.

Fazendo a correspondência de versões usando Kubernetes

O mesmo problema descrito em Fazendo a correspondência de versões usando o Docker Swarm pode ocorrer quando os pods estão agendados no kubernetes. Esse problema pode ser evitado com estratégias similares:

  • Recompile o contêiner com base na mesma versão do sistema operacional em desenvolvimento e produção. Para saber como, consulte Escolha a versão do sistema operacional do contêiner a ser usada.
  • Use etiquetas de nó e nodeSelectors para garantir que os pods sejam agendados em nós compatíveis se os nós do Windows Server 2016 e do Windows Server 1709 estiverem no mesmo cluster.
  • Usar clusters separados com base na versão do SO

Falha ao localizar pods em caso de incompatibilidade do SO

Nesse caso, uma implantação incluiu um pod que foi agendado em um nó com uma versão de sistema operacional incompatível e sem isolamento do Hyper-V habilitado.

O mesmo erro é mostrado nos eventos listados com kubectl describe pod <podname>. Após várias tentativas, o status do pod provavelmente será CrashLoopBackOff.

$ kubectl -n plang describe pod fabrikamfiber.web-789699744-rqv6p

Name:           fabrikamfiber.web-789699744-rqv6p
Namespace:      plang
Node:           38519acs9011/10.240.0.6
Start Time:     Mon, 09 Oct 2017 19:40:30 +0000
Labels:         io.kompose.service=fabrikamfiber.web
                pod-template-hash=789699744
Annotations:    kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"plang","name":"fabrikamfiber.web-789699744","uid":"b5062a08-ad29-11e7-b16e-000d3a...
Status:         Running
IP:             10.244.3.169
Created By:     ReplicaSet/fabrikamfiber.web-789699744
Controlled By:  ReplicaSet/fabrikamfiber.web-789699744
Containers:
  fabrikamfiberweb:
    Container ID:       docker://eab0151378308315ed6c31adf4ad9e31e6d65fd300e56e742757004a969a803a
    Image:              patricklang/fabrikamfiber.web:latest
    Image ID:           docker-pullable://patricklang/fabrikamfiber.web@sha256:562741016ce7d9a232a389449a4fd0a0a55aab178cf324144404812887250ead
    Port:               80/TCP
    State:              Waiting
      Reason:           CrashLoopBackOff
    Last State:         Terminated
      Reason:           ContainerCannotRun
      Message:          container eab0151378308315ed6c31adf4ad9e31e6d65fd300e56e742757004a969a803a encountered an error during CreateContainer: failure in a Windows system call: The operating system of the container does not match the operating system of the host. (0xc0370101) extra info: {"SystemType":"Container","Name":"eab0151378308315ed6c31adf4ad9e31e6d65fd300e56e742757004a969a803a","Owner":"docker","IsDummy":false,"VolumePath":"\\\\?\\Volume{037b6606-bc9c-461f-ae02-829c28410798}","IgnoreFlushesDuringBoot":true,"LayerFolderPath":"C:\\ProgramData\\docker\\windowsfilter\\eab0151378308315ed6c31adf4ad9e31e6d65fd300e56e742757004a969a803a","Layers":[{"ID":"f8bc427f-7aa3-59c6-b271-7331713e9451","Path":"C:\\ProgramData\\docker\\windowsfilter\\e206d2514a6265a76645b9d6b3dc6a78777c34dbf5da9fa2d564651645685881"},{"ID":"a6f35e41-a86c-5e4d-a19a-a6c2464bfb47","Path":"C:\\ProgramData\\docker\\windowsfilter\\0f21f1e28ef13030bbf0d87cbc97d1bc75f82ea53c842e9a3250a2156ced12d5"},{"ID":"4f624ca7-2c6d-5c42-b73f-be6e6baf2530","Path":"C:\\ProgramData\\docker\\windowsfilter\\4d9e2ad969fbd74fd58c98b5ab61e55a523087910da5200920e2b6f641d00c67"},{"ID":"88e360ff-32af-521d-9a3f-3760c12b35e2","Path":"C:\\ProgramData\\docker\\windowsfilter\\9e16a3d53d3e9b33344a6f0d4ed34c8a46448ee7636b672b61718225b8165e6e"},{"ID":"20f1a4e0-a6f3-5db3-9bf2-01fd3e9e855a","Path":"C:\\ProgramData\\docker\\windowsfilter\\7eec7f59f9adce38cc0a6755da58a3589287d920d37414b5b21b5b543d910461"},{"ID":"c2b3d728-4879-5343-a92a-b735752a4724","Path":"C:\\ProgramData\\docker\\windowsfilter\\8ed04b60acc0f65f541292a9e598d5f73019c8db425f8d49ea5819eab16a42f3"},{"ID":"2973e760-dc59-5800-a3de-ab9d93be81e5","Path":"C:\\ProgramData\\docker\\windowsfilter\\cc71305d45f09ce377ef497f28c3a74ee027c27f20657d2c4a5f157d2457cc75"},{"ID":"454a7d36-038c-5364-8a25-fa84091869d6","Path":"C:\\ProgramData\\docker\\windowsfilter\\9e8cde1ce8f5de861a5f22841f1ab9bc53d5f606d06efeacf5177f340e8d54d0"},{"ID":"9b748c8c-69eb-55fb-a1c1-5688cac4efd8","Path":"C:\\ProgramData\\docker\\windowsfilter\\8e02bf5404057055a71d542780a2bb2731be4b3707c01918ba969fb4d83b98ec"},{"ID":"bfde5c26-b33f-5424-9405-9d69c2fea4d0","Path":"C:\\ProgramData\\docker\\windowsfilter\\77483cedfb0964008c33d92d306734e1fab3b5e1ebb27e898f58ccfd108108f2"},{"ID":"bdabfbf5-80d1-57f1-86f3-448ce97e2d05","Path":"C:\\ProgramData\\docker\\windowsfilter\\aed2ebbb31ad24b38ee8521dd17744319f83d267bf7f360bc177e27ae9a006cf"},{"ID":"ad9b34f2-dcee-59ea-8962-b30704ae6331","Path":"C:\\ProgramData\\docker\\windowsfilter\\d44d3a675fec1070b61d6ea9bacef4ac12513caf16bd6453f043eed2792f75d8"}],"HostName":"fabrikamfiber.web-789699744-rqv6p","MappedDirectories":[{"HostPath":"c:\\var\\lib\\kubelet\\pods\\b50f0027-ad29-11e7-b16e-000d3afd2878\\volumes\\kubernetes.io~secret\\default-token-rw9dn","ContainerPath":"c:\\var\\run\\secrets\\kubernetes.io\\serviceaccount","ReadOnly":true,"BandwidthMaximum":0,"IOPSMaximum":0}],"HvPartition":false,"EndpointList":null,"NetworkSharedContainerName":"586870f5833279678773cb700db3c175afc81d557a75867bf39b43f985133d13","Servicing":false,"AllowUnqualifiedDNSQuery":false}
      Exit Code:        128
      Started:          Mon, 09 Oct 2017 20:27:08 +0000
      Finished:         Mon, 09 Oct 2017 20:27:08 +0000
    Ready:              False
    Restart Count:      10
    Environment:        <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-rw9dn (ro)
Conditions:
  Type          Status
  Initialized   True
  Ready         False
  PodScheduled  True
Volumes:
  default-token-rw9dn:
    Type:       Secret (a volume populated by a Secret)
    SecretName: default-token-rw9dn
    Optional:   false
QoS Class:      BestEffort
Node-Selectors: beta.kubernetes.io/os=windows
Tolerations:    <none>
Events:
  FirstSeen     LastSeen        Count   From                    SubObjectPath                           Type            Reason                  Message
  ---------     --------        -----   ----                    -------------                           --------        ------                  -------
  49m           49m             1       default-scheduler                                               Normal          Scheduled               Successfully assigned fabrikamfiber.web-789699744-rqv6p to 38519acs9011
  49m           49m             1       kubelet, 38519acs9011                                           Normal          SuccessfulMountVolume   MountVolume.SetUp succeeded for volume "default-token-rw9dn"
  29m           29m             1       kubelet, 38519acs9011   spec.containers{fabrikamfiberweb}       Warning         Failed                  Failed to pull image "patricklang/fabrikamfiber.web:latest": rpc error: code = 2 desc = Error response from daemon: {"message":"Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io: no such host"}
  49m           3m              12      kubelet, 38519acs9011   spec.containers{fabrikamfiberweb}       Normal          Pulling                 pulling image "patricklang/fabrikamfiber.web:latest"
  33m           3m              11      kubelet, 38519acs9011   spec.containers{fabrikamfiberweb}       Normal          Pulled                  Successfully pulled image "patricklang/fabrikamfiber.web:latest"
  33m           3m              11      kubelet, 38519acs9011   spec.containers{fabrikamfiberweb}       Normal          Created                 Created container
  33m           2m              11      kubelet, 38519acs9011   spec.containers{fabrikamfiberweb}       Warning         Failed                  Error: failed to start container "fabrikamfiberweb": Error response from daemon: {"message":"container fabrikamfiberweb encountered an error during CreateContainer: failure in a Windows system call: The operating system of the container does not match the operating system of the host. (0xc0370101) extra info: {\"SystemType\":\"Container\",\"Name\":\"fabrikamfiberweb\",\"Owner\":\"docker\",\"IsDummy\":false,\"VolumePath\":\"\\\\\\\\?\\\\Volume{037b6606-bc9c-461f-ae02-829c28410798}\",\"IgnoreFlushesDuringBoot\":true,\"LayerFolderPath\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\fabrikamfiberweb\",\"Layers\":[{\"ID\":\"f8bc427f-7aa3-59c6-b271-7331713e9451\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\e206d2514a6265a76645b9d6b3dc6a78777c34dbf5da9fa2d564651645685881\"},{\"ID\":\"a6f35e41-a86c-5e4d-a19a-a6c2464bfb47\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\0f21f1e28ef13030bbf0d87cbc97d1bc75f82ea53c842e9a3250a2156ced12d5\"},{\"ID\":\"4f624ca7-2c6d-5c42-b73f-be6e6baf2530\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\4d9e2ad969fbd74fd58c98b5ab61e55a523087910da5200920e2b6f641d00c67\"},{\"ID\":\"88e360ff-32af-521d-9a3f-3760c12b35e2\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\9e16a3d53d3e9b33344a6f0d4ed34c8a46448ee7636b672b61718225b8165e6e\"},{\"ID\":\"20f1a4e0-a6f3-5db3-9bf2-01fd3e9e855a\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\7eec7f59f9adce38cc0a6755da58a3589287d920d37414b5b21b5b543d910461\"},{\"ID\":\"c2b3d728-4879-5343-a92a-b735752a4724\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\8ed04b60acc0f65f541292a9e598d5f73019c8db425f8d49ea5819eab16a42f3\"},{\"ID\":\"2973e760-dc59-5800-a3de-ab9d93be81e5\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\cc71305d45f09ce377ef497f28c3a74ee027c27f20657d2c4a5f157d2457cc75\"},{\"ID\":\"454a7d36-038c-5364-8a25-fa84091869d6\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\9e8cde1ce8f5de861a5f22841f1ab9bc53d5f606d06efeacf5177f340e8d54d0\"},{\"ID\":\"9b748c8c-69eb-55fb-a1c1-5688cac4efd8\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\8e02bf5404057055a71d542780a2bb2731be4b3707c01918ba969fb4d83b98ec\"},{\"ID\":\"bfde5c26-b33f-5424-9405-9d69c2fea4d0\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\77483cedfb0964008c33d92d306734e1fab3b5e1ebb27e898f58ccfd108108f2\"},{\"ID\":\"bdabfbf5-80d1-57f1-86f3-448ce97e2d05\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\aed2ebbb31ad24b38ee8521dd17744319f83d267bf7f360bc177e27ae9a006cf\"},{\"ID\":\"ad9b34f2-dcee-59ea-8962-b30704ae6331\",\"Path\":\"C:\\\\ProgramData\\\\docker\\\\windowsfilter\\\\d44d3a675fec1070b61d6ea9bacef4ac12513caf16bd6453f043eed2792f75d8\"}],\"HostName\":\"fabrikamfiber.web-789699744-rqv6p\",\"MappedDirectories\":[{\"HostPath\":\"c:\\\\var\\\\lib\\\\kubelet\\\\pods\\\\b50f0027-ad29-11e7-b16e-000d3afd2878\\\\volumes\\\\kubernetes.io~secret\\\\default-token-rw9dn\",\"ContainerPath\":\"c:\\\\var\\\\run\\\\secrets\\\\kubernetes.io\\\\serviceaccount\",\"ReadOnly\":true,\"BandwidthMaximum\":0,\"IOPSMaximum\":0}],\"HvPartition\":false,\"EndpointList\":null,\"NetworkSharedContainerName\":\"586870f5833279678773cb700db3c175afc81d557a75867bf39b43f985133d13\",\"Servicing\":false,\"AllowUnqualifiedDNSQuery\":false}"}
  33m           11s             151     kubelet, 38519acs9011                                           Warning         FailedSync              Error syncing pod
  32m           11s             139     kubelet, 38519acs9011   spec.containers{fabrikamfiberweb}       Warning         BackOff                 Back-off restarting failed container

Mitigação — Usando etiquetas de nó e NodeSelector

Execute kubectl get node para obter uma lista de todos os nós. Depois disso, você pode executar kubectl describe node (nome do nó) para obter mais detalhes.

No exemplo a seguir, dois nós do Windows estão executando versões diferentes:

$ kubectl get node

NAME                        STATUS    AGE       VERSION
38519acs9010                Ready     21h       v1.7.7-7+e79c96c8ff2d8e
38519acs9011                Ready     4h        v1.7.7-25+bc3094f1d650a2
k8s-linuxpool1-38519084-0   Ready     21h       v1.7.7
k8s-master-38519084-0       Ready     21h       v1.7.7

$ kubectl describe node 38519acs9010

Name:                   38519acs9010
Role:
Labels:                 beta.kubernetes.io/arch=amd64
                        beta.kubernetes.io/instance-type=Standard_D2_v2
                        beta.kubernetes.io/os=windows
                        failure-domain.beta.kubernetes.io/region=westus2
                        failure-domain.beta.kubernetes.io/zone=0
                        kubernetes.io/hostname=38519acs9010
Annotations:            node.alpha.kubernetes.io/ttl=0
                        volumes.kubernetes.io/controller-managed-attach-detach=true
Taints:                 <none>
CreationTimestamp:      Fri, 06 Oct 2017 01:41:02 +0000

...

System Info:
 Machine ID:                    38519acs9010
 System UUID:
 Boot ID:
 Kernel Version:                10.0 14393 (14393.1715.amd64fre.rs1_release_inmarket.170906-1810)
 OS Image:
 Operating System:              windows
 Architecture:                  amd64
 ...

$ kubectl describe node 38519acs9011
Name:                   38519acs9011
Role:
Labels:                 beta.kubernetes.io/arch=amd64
                        beta.kubernetes.io/instance-type=Standard_DS1_v2
                        beta.kubernetes.io/os=windows
                        failure-domain.beta.kubernetes.io/region=westus2
                        failure-domain.beta.kubernetes.io/zone=0
                        kubernetes.io/hostname=38519acs9011
Annotations:            node.alpha.kubernetes.io/ttl=0
                        volumes.kubernetes.io/controller-managed-attach-detach=true
Taints:                 <none>
CreationTimestamp:      Fri, 06 Oct 2017 18:13:25 +0000
Conditions:
...

System Info:
 Machine ID:                    38519acs9011
 System UUID:
 Boot ID:
 Kernel Version:                10.0 16299 (16299.0.amd64fre.rs3_release.170922-1354)
 OS Image:
 Operating System:              windows
 Architecture:                  amd64
...

Vamos usar este exemplo para mostrar como fazer correspondência de versões:

  1. Anote o nome de cada nó e Kernel Version a partir das informações do sistema.

    Em nosso exemplo, as informações terão a seguinte aparência:

    Nome Versão
    38519acs9010 14393.1715.amd64fre.rs1_release_inmarket.170906-1810
    38519acs9011 16299.0.amd64fre.rs3_release.170922-1354
  2. Adicionar uma etiqueta a cada nó chamado beta.kubernetes.io/osbuild. O Windows Server 2016 precisa de versões principais e secundárias (14393.1715 neste exemplo) para obter suporte sem o isolamento do Hyper-V. O Windows Server, versão 1709, precisa apenas da versão principal (16299 neste exemplo) para fazer correspondência.

    Neste exemplo, o comando para adicionar os rótulos tem esta aparência:

    $ kubectl label node 38519acs9010 beta.kubernetes.io/osbuild=14393.1715
    
    
    node "38519acs9010" labeled
    $ kubectl label node 38519acs9011 beta.kubernetes.io/osbuild=16299
    
    node "38519acs9011" labeled
    
    
  3. Verifique se os rótulos estão lá executando kubectl get nodes --show-labels.

    Neste exemplo, a saída terá esta aparência:

    $ kubectl get nodes --show-labels
    
    NAME                        STATUS                     AGE       VERSION                    LABELS
    38519acs9010                Ready,SchedulingDisabled   3d        v1.7.7-7+e79c96c8ff2d8e    beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=Standard_D2_v2,beta.kubernetes.io/os=windows,beta.kubernetes.io/osbuild=14393.1715,failure-domain.beta.kubernetes.io/region=westus2,failure-domain.beta.kubernetes.io/zone=0,kubernetes.io/hostname=38519acs9010
    38519acs9011                Ready                      3d        v1.7.7-25+bc3094f1d650a2   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=Standard_DS1_v2,beta.kubernetes.io/os=windows,beta.kubernetes.io/osbuild=16299,failure-domain.beta.kubernetes.io/region=westus2,failure-domain.beta.kubernetes.io/zone=0,kubernetes.io/hostname=38519acs9011
    k8s-linuxpool1-38519084-0   Ready                      3d        v1.7.7                     agentpool=linuxpool1,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=Standard_D2_v2,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=westus2,failure-domain.beta.kubernetes.io/zone=0,kubernetes.io/hostname=k8s-linuxpool1-38519084-0,kubernetes.io/role=agent
    k8s-master-38519084-0       Ready                      3d        v1.7.7                     beta.kubernetes.io/arch=amd64,beta.kubernetes.io/instance-type=Standard_D2_v2,beta.kubernetes.io/os=linux,failure-domain.beta.kubernetes.io/region=westus2,failure-domain.beta.kubernetes.io/zone=0,kubernetes.io/hostname=k8s-master-38519084-0,kubernetes.io/role=master
    
  4. Adicione seletores de nó às implantações. Neste caso de exemplo, adicionaremos um nodeSelector à especificação do contêiner com beta.kubernetes.io/os = windows e beta.kubernetes.io/osbuild = 14393.* ou 16299 para fazer a correspondência do sistema operacional base usado pelo contêiner.

    Este é um exemplo completo da execução de um contêiner criado para o Windows Server 2016:

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      annotations:
        kompose.cmd: kompose convert -f docker-compose-combined.yml
        kompose.version: 1.2.0 (99f88ef)
      creationTimestamp: null
      labels:
        io.kompose.service: fabrikamfiber.web
      name: fabrikamfiber.web
    spec:
      replicas: 1
      strategy: {}
      template:
        metadata:
          creationTimestamp: null
          labels:
            io.kompose.service: fabrikamfiber.web
        spec:
          containers:
          - image: patricklang/fabrikamfiber.web:latest
            name: fabrikamfiberweb
            ports:
            - containerPort: 80
            resources: {}
          restartPolicy: Always
          nodeSelector:
            "beta.kubernetes.io/os": windows
            "beta.kubernetes.io/osbuild": "14393.1715"
    status: {}
    

    Agora, o pod pode ser iniciado com a implantação atualizada. Os seletores de nó também são mostrados em kubectl describe pod <podname> para que você possa executar esse comando para verificar se eles foram adicionados.

    A saída do nosso exemplo é a seguinte:

    $ kubectl -n plang describe po fa
    
    Name:           fabrikamfiber.web-1780117715-5c8vw
    Namespace:      plang
    Node:           38519acs9010/10.240.0.4
    Start Time:     Tue, 10 Oct 2017 01:43:28 +0000
    Labels:         io.kompose.service=fabrikamfiber.web
                    pod-template-hash=1780117715
    Annotations:    kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"plang","name":"fabrikamfiber.web-1780117715","uid":"6a07aaf3-ad5c-11e7-b16e-000d3...
    Status:         Running
    IP:             10.244.1.84
    Created By:     ReplicaSet/fabrikamfiber.web-1780117715
    Controlled By:  ReplicaSet/fabrikamfiber.web-1780117715
    Containers:
      fabrikamfiberweb:
        Container ID:       docker://c94594fb53161f3821cf050d9af7546991aaafbeab41d333d9f64291327fae13
        Image:              patricklang/fabrikamfiber.web:latest
        Image ID:           docker-pullable://patricklang/fabrikamfiber.web@sha256:562741016ce7d9a232a389449a4fd0a0a55aab178cf324144404812887250ead
        Port:               80/TCP
        State:              Running
          Started:          Tue, 10 Oct 2017 01:43:42 +0000
        Ready:              True
        Restart Count:      0
        Environment:        <none>
        Mounts:
          /var/run/secrets/kubernetes.io/serviceaccount from default-token-rw9dn (ro)
    Conditions:
      Type          Status
      Initialized   True
      Ready         True
      PodScheduled  True
    Volumes:
      default-token-rw9dn:
        Type:       Secret (a volume populated by a Secret)
        SecretName: default-token-rw9dn
        Optional:   false
    QoS Class:      BestEffort
    Node-Selectors: beta.kubernetes.io/os=windows
                    beta.kubernetes.io/osbuild=14393.1715
    Tolerations:    <none>
    Events:
      FirstSeen     LastSeen        Count   From                    SubObjectPath                           Type            Reason                  Message
      ---------     --------        -----   ----                    -------------                           --------        ------                  -------
      5m            5m              1       default-scheduler                                               Normal          Scheduled               Successfully assigned fabrikamfiber.web-1780117715-5c8vw to 38519acs9010
      5m            5m              1       kubelet, 38519acs9010                                           Normal          SuccessfulMountVolume   MountVolume.SetUp succeeded for volume "default-token-rw9dn"
      5m            5m              1       kubelet, 38519acs9010   spec.containers{fabrikamfiberweb}       Normal          Pulling                 pulling image "patricklang/fabrikamfiber.web:latest"
      5m            5m              1       kubelet, 38519acs9010   spec.containers{fabrikamfiberweb}       Normal          Pulled                  Successfully pulled image "patricklang/fabrikamfiber.web:latest"
      5m            5m              1       kubelet, 38519acs9010   spec.containers{fabrikamfiberweb}       Normal          Created                 Created container
      5m            5m              1       kubelet, 38519acs9010   spec.containers{fabrikamfiberweb}       Normal          Started                 Started container