Apenas mais uma ferramenta: conhecer a configuração do serviço com a Configuração do estado desejado 

A Configuração do Estado Desejado (DSC) é uma ferramenta de gerenciamento de configuração do servidor. Com ele, você pode configurar o servidor (fazer alterações no registro, copiar arquivos, instalar e remover componentes), monitorar o status atual das configurações e reverter rapidamente para as configurações básicas.

O DSC é interessante para quem segue a abordagem do DevOps. Essa ferramenta se adapta bem à infraestrutura como paradigma de código: os desenvolvedores podem adicionar seus requisitos à configuração e incluí-los no sistema de controle de versão, e as equipes podem implantar o código sem usar processos "manuais".

Juntamente com Stanislav Buldakov, do RaiffeisenbankCombinamos nossa experiência com o mecanismo DSC e dividimos em 2 artigos. No primeiro, analisaremos os princípios básicos do trabalho e nos familiarizaremos com os recursos de uso em exemplos práticos:

  • “Descompacte a caixa” com o mecanismo DSC, veja quais são os recursos por padrão e mostre onde obter recursos adicionais;
  • Vamos ver como descrever a configuração no DSC; 
  • Aprenderemos como o agente de configuração local do agente interno aplica configurações no servidor, mostra como ele é configurado usando meta-configurações;
  • vamos passar para casos de configuração mais complexos: configurações parciais e configurações de stub.



O DSC é um mecanismo leve e rápido. Por exemplo, usando-o, você pode instalar o .NET Framework 3.5 em máquinas virtuais muito mais rapidamente. Aqui está o que o ajuda a acelerar o processo de configuração do serviço:

  • « » Windows PowerShell. 
    DSC PowerShell Windows Management Framework. Linux . , PowerShell. 
  • , . 
    , , , . DSC. 
  • , .
    DSC , . .

As configurações são sempre realizadas seqüencialmente, sem condições e ramificações. Portanto, brevemente, o algoritmo de operação DSC se parece com o seguinte:

  1. Configure o Gerenciador de configuração local (LCM) . Esse é o agente interno responsável pela aplicação das configurações no servidor. Dizemos a ele como as configurações declaradas devem funcionar e em que ordem. 
  2. Se forem necessários recursos adicionais, instale e conecte-os com antecedência.
  3. De forma declarativa, escrevemos a ordem de configuração. 
  4. Nós transmitimos a configuração no formato do arquivo MOF.
  5. Enviamos a configuração para o servidor recém-implantado ou existente de destino.
  6. O LCM recebe a configuração (arquivo MOF), além de instruções para configurar o próprio LCM.
  7. A configuração é aplicada imediatamente por nossa equipe.


Um diagrama simplificado da arquitetura DSC.

Começaremos a conhecer o mecanismo estudando os recursos predefinidos. Em seguida, tente escrever a configuração.

Recursos DSC 


Os recursos DSC são uma espécie de análogo aos módulos do PowerShell. Qualquer servidor Windows já possui um conjunto predefinido de recursos DSC; eles estão no mesmo diretório que os módulos do PowerShell. A lista pode ser obtida através do cmdlet Get-DscResourse. Aqui está a aparência dessa lista no Windows 10 1809:
 
PS C:\windows\system32> Get-DscResource | Sort-Object -Property Name | ft ImplementedAs, Name -a
 
ImplementedAs Name
------------- ----
   PowerShell Archive
   PowerShell Environment
       Binary File
   PowerShell Group
    Composite GroupSet
       Binary Log
   PowerShell Package
   PowerShell PackageManagement
   PowerShell PackageManagementSource
    Composite ProcessSet
   PowerShell Registry
   PowerShell Script
   PowerShell Service
    Composite ServiceSet
       Binary SignatureValidation
   PowerShell User
   PowerShell WaitForAll
   PowerShell WaitForAny
   PowerShell WaitForSome
   PowerShell WindowsFeature
    Composite WindowsFeatureSet
   PowerShell WindowsOptionalFeature
    Composite WindowsOptionalFeatureSet
   PowerShell WindowsPackageCab
   PowerShell WindowsProcess

Os nomes dos recursos dão uma compreensão do que eles trabalham: 

  • Arquivo - com embalagem e descompactação de arquivos;
  • Ambiente - com variáveis ​​de ambiente;
  • Arquivo - com arquivos;
  • Grupo - com grupos de usuários locais;
  • Log - com logs;
  • Pacote - com pacotes de software;
  • Registro - com chaves do registro e seu status;
  • Serviço - com serviços e seu status;
  • Usuário - com contas de usuário local;
  • WindowsFeature — Windows Server;
  • WindowsProcess — Windows;
  • Script —  PowerShell- . 3 : SetScript — -, TestScript — , , GetScript — .

Na maioria das vezes, os recursos DSC prontos para uso não são suficientes . Nesse caso, você pode escrever seus próprios scripts para tudo que vai além do módulo padrão. Para não reinventar a roda, você pode usar os recursos DSC escritos por outros desenvolvedores. Por exemplo, aqui https://github.com/PowerShell/DscResources ou na PSGallery
 
Como instalar recursos adicionais . Usamos o cmdlet Install-Module . Instalar recursos é simplesmente copiar arquivos de recursos ao longo de um dos caminhos na variável de ambiente $ env: PSModulePath . Os recursos instalados não são conectados automaticamente durante a compilação; portanto, mais tarde, os conectaremos adicionalmente na própria configuração.

Para usar um recurso, você precisa instalá-lo localmente e no servidor de destino. Nas infra-estruturas locais, uma política de segurança normalmente proíbe o acesso à Internet para servidores. Nesse caso, o servidor DSC não poderá carregar recursos adicionais de fontes externas. Para publicar arquivos com módulos, implantamos um repositório NuGet local ou um servidor da web comum. Você pode instalar recursos adicionais para o servidor da Web descompactando o módulo no diretório C: \ Arquivos de Programas \ WindowsPowerShell \ Modules \.
É exatamente isso que o cmdlet Install-Module faz.

No segundo artigo, examinaremos mais de perto a diferença entre a configuração dos modos Push e Pull. 

Análise de configuração simples


A configuração é uma descrição simples e consistente do que precisa ser feito no servidor. É assim que uma configuração simples do DSC se parece: 

Configuration EnvironmentVariable_Path
{
param ()
Import-DscResource -ModuleName 'PSDscResources'
Node localhost
    {
        Environment CreatePathEnvironmentVariable
        {
            Name = 'TestPathEnvironmentVariable'
            Value = 'TestValue'
            Ensure = 'Present'
            Path = $true
            Target = @('Process', 'Machine')
        }
    }
}
EnvironmentVariable_Path -OutputPath:"C:\EnvironmentVariable_Path"

Para o exemplo dela, vamos ver em que consiste a configuração.

O bloco de configuração é um tipo especial de função do PowerShell que descreve o que queremos obter. 

Dentro do bloco contém: 

  • bloco param com parâmetros que podem ser usados ​​internamente; 
  • bloquear com chamadas adicionais do PowerShell. Aqui, no início da configuração, sempre executamos Import-Resource para conectar recursos adicionais;
  • blocos com configurações para servidores específicos do $ servername. 

Dentro do bloco , indicamos quais recursos em um servidor específico iremos configurar. No exemplo acima, isso está criando uma variável de ambiente usando um recurso de ambiente regular.

Vamos analisar um pouco mais e analisar a sintaxe de um recurso específico através do comando Get-DscResource -Name Environment -Syntax:
 

PS C:\windows\system32> Get-DscResource -Name Environment -Syntax
Environment [String] #ResourceName
{
    Name = [string]
    [DependsOn = [string[]]]
    [Ensure = [string]{ Absent | Present }]
    [Path = [bool]]
    [PsDscRunAsCredential = [PSCredential]]
    [Value = [string]]
}

Neste exemplo: 

  • Nome - o nome da variável de ambiente.
  • Em DependsOn, especificamos a dependência de outros recursos. É importante lembrar que a operação não será executada até que o recurso especificado aqui seja concluído. 
  • Em Garantir, especificamos as condições de configuração. Se essa variável estiver ausente, nós a criaremos; se estiver presente, esse recurso não será configurado.
  • O caminho especifica se a variável de ambiente contém um caminho. 
  • Em PsDscRunAsCredential, credenciais especificadas.
  • Valor - o valor da variável de ambiente. 
  • O alvo pode ser indicado em relação a quem a configuração é aplicada.

Como iniciar a compilação . Apenas chamamos a configuração pelo nome com os parâmetros necessários. O resultado será um arquivo mof, que é usado posteriormente pelo mecanismo DSC para configurar um servidor específico:
 
PS C:\windows\system32> EnvironmentVariable_Path -OutputPath:"C:\EnvironmentVariable_Path"
 
    Directory: C:\EnvironmentVariable_Path
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       25.02.2020     14:05           2172 localhost.mof

Configurar o Gerenciador de configuração local


O gerenciador de configuração local é responsável por aplicar as configurações que compilamos nos arquivos mof. É ele quem monitora a preservação do estado definido na configuração. Se o sistema sair desse estado, o LCM chamará o código nos recursos para restaurar o estado especificado. 

Vamos ver as configurações do gerenciador de configuração local por meio de Get-DscLocalConfigurationManager:
 
PS C:\windows\system32> Get-DscLocalConfigurationManager
 
ActionAfterReboot              : ContinueConfiguration
AgentId                        : 1FB3A2EE-57C9-11EA-A204-58A023EF3A48
AllowModuleOverWrite           : False
CertificateID                  :
ConfigurationDownloadManagers  : {}
ConfigurationID                :
ConfigurationMode              : ApplyAndMonitor
ConfigurationModeFrequencyMins : 15
Credential                     :
DebugMode                      : {NONE}
DownloadManagerCustomData      :
DownloadManagerName            :
LCMCompatibleVersions          : {1.0, 2.0}
LCMState                       : Idle
LCMStateDetail                 :
LCMVersion                     : 2.0
StatusRetentionTimeInDays      : 10
SignatureValidationPolicy      : NONE
SignatureValidations           : {}
MaximumDownloadSizeMB          : 500
PartialConfigurations          :
RebootNodeIfNeeded             : False
RefreshFrequencyMins           : 30
RefreshMode                    : PUSH
ReportManagers                 : {}
ResourceModuleManagers         : {}
PSComputerName                 :

  • O RefreshMode contém o modo de operação LCM - Push ou Pull. Falaremos mais sobre os modos no segundo artigo.
  • ConfigurationMode mostra o modo de aplicativo de configuração atual. No nosso caso, é o ApplyAndMonitor - aplique e rastreie as alterações. Os modos ApplyOnly também estão disponíveis (o LCM não rastreará alterações na configuração) e os modos ApplyAndAutocorrect (o LCM não rastreará apenas as alterações, mas também as reverterá para a configuração base).
  • RebootNodeIfNeeded - pode reiniciar o servidor após a conclusão da configuração, se necessário, para aplicar as configurações. 
  • ConfigurationModeFrequencyMins - Corrige a frequência com que o LCM verifica as alterações na configuração.

Altere as configurações do LCM na meta-configuração. Aqui está o exemplo dela:
 

Configuration LCMConfiguration
{
   Node Localhost
   {
       LocalConfigurationManager
       {
           RebootNodeIfNeeeded = $True
       }
   }
}
LCMConfiguration

O mesmo para a versão mais recente do WMF com comentários:


 
[DSCLocalConfigurationManager()]
Configuration LCMConfiguration
{
   param
   (
       [string[]]$Server = "localhost"
   )

 

#  LCM:
#  ,  
# : PUSH
#    30 
   Node $Server
   {
       Settings
       {
           RebootNodeIfNeeded = $True
           RefreshMode        = 'Push'
           RefreshFrequencyMins = 30
       }
   }
}


#   
LCMConfiguration -Server "localhost" -OutputPath "C:\DSC\MetaConfigurations\EnvironmentVariable_Path\"

Apresenta metaconfiguração . Ao escrever uma metaconfiguração, usamos os mesmos blocos que para uma configuração DSC regular. A exceção é o bloco interno LocalConfigurationManager (v4) ou o atributo DSCLocalConfigurationManager (v5) para um servidor específico. Eles descrevem todas as configurações necessárias. 

A metaconfiguração também é compilada em um arquivo mof, mas para usá-lo, o cmdlet Set-DSCLocalConfigurationManager é usado, e não o Start-DSCConfiguration.
 
PS C:\windows\system32> LCMConfiguration -OutputPath C:\EnvironmentVariable_Path\
 
    Directory: C:\EnvironmentVariable_Path
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       26.02.2020     20:05           1016 Localhost.meta.mof

 

PS C:\windows\system32> Set-DscLocalConfigurationManager -Path C:\EnvironmentVariable_Path\
PS C:\windows\system32> Get-DscLocalConfigurationManager
 
RebootNodeIfNeeded             : True

Teoricamente, nada nos impede de combinar a configuração do LCM e recursos convencionais dentro da mesma configuração. Mas, para simplificar, é recomendável que a ortografia e a aplicação da configuração e da metaconfiguração sejam separadas.

Configurações Parciais 


Configurações parciais - várias configurações que são executadas seqüencialmente uma após a outra. Eles são úteis quando várias equipes trabalham no serviço. Cada um dos comandos indica as configurações para sua parte do serviço, e a configuração parcial aplica todas as configurações sequencialmente. Nas configurações do LCM, especificamos configurações parciais em PartialConfigurations

Em configurações parciais, devemos considerar a lógica direta do DSC. O mecanismo não permite ramificação; portanto, são necessários recursos adicionais para atender a várias condições. Vamos analisar isso com alguns exemplos. 

Suponha que desejamos entregar com segurança a configuração ao servidor e prosseguir de acordo com o seguinte algoritmo:

  1. Primeiro, verifique se os módulos necessários estão instalados no servidor.
  2. Realizamos a configuração, que trará o servidor para o estado desejado.

Veja como é uma metaconfiguração com várias configurações consecutivas dentro:


#   
[DSCLocalConfigurationManager()]
configuration MetaPushConfig
{
param
   (
       [ValidateNotNullOrEmpty()]
       [string] $NodeName = 'localhost'
   )

 

   Node $NodeName
   {
 	
 #      LCM,    
       PartialConfiguration ModulesDownloadConfig
       {
               Description = 'Download and install modules'
               RefreshMode = 'Push'
       }

 

       #        
       PartialConfiguration ServerOSConfig
       {
               DependsOn = "[PartialConfiguration]ModulesDownloadConfig"
               Description = 'Configuration'
               RefreshMode = 'Push'
       }

 

       #   LCM
       Settings
       {
               RefreshMode        = 'Push'
               RefreshFrequencyMins = 30
               RebootNodeIfNeeded = $true
       }
   }
}

 
 

#  
MetaPushConfig -NodeName "NewServer.contoso.com" -OutputPath c:\DSC\MetaConfigurations

 

#      
$cred = (Get-Credential -UserName Administrator -Message "Enter admin credentials")

 

#  LCM   
Set-DscLocalConfigurationManager -ComputerName "NewServer.contoso.com" -Credential $cred -Path "c:\DSC\MetaConfigurations" -Verbose -Force

 

#  
Publish-DscConfiguration c:\DSC\Configurations\ModulesDownloadConfig -ComputerName "NewServer.contoso.com" -Credential $cred -Force
Publish-DscConfiguration c:\DSC\Configurations\ServerOSConfig -ComputerName "NewServer.contoso.com" -Credential $cred -Force

 

#    
Start-DscConfiguration -UseExisting -ComputerName "NewServer.contoso.com" -Credential $cred -Force -Verbose

A primeira parte da configuração diz Baixar e instalar os módulos : baixe e instale os recursos necessários. A segunda parte do ServerOSConfig leva o servidor ao estado desejado. Quais são as nuances da franqueza da DSC aqui: 

  1. Se a primeira parte da configuração retornou inicialmente FALSE e foi concluída completamente, o LCM não irá para a segunda configuração. De acordo com a lógica do DSC, primeiro você precisa trazer o servidor para o primeiro estado descrito. 
    Como tratar: execute a configuração duas vezes ou automatize todo o processo em um script.
  2. Se o servidor após a instalação de qualquer componente exigir uma reinicialização, a configuração não irá além até que nós mesmos reiniciemos o servidor. Mesmo se dissermos ao LCM que RebootNodeIfNeeeded = $ True, o agente aguardará nossa solução durante a configuração.
    Como tratar: o recurso xPendingReboot chega ao resgate , que controla a chave do Registro após a reinicialização. Este recurso reinicia o servidor para nós.

Aqui está um exemplo de configuração para baixar e instalar recursos no cenário "sangrenta empresa", quando o servidor não tem acesso à Internet. Ele pressupõe a presença de um servidor da Web, onde os recursos pré-baixados estão disponíveis para todos por meio do protocolo http.


Configuration ModulesDownloadConfig
{
   param
   (
       [string[]]$Server
   )

 

   #   
   Import-DscResource -ModuleName "PSDesiredStateConfiguration"

 

   #  
   Node $Server
   {
       #  IE Security
       Registry DisableIEESC-Admin {
           Key = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
           ValueName = "IsInstalled"
           Ensure = "Present"
           ValueData = 0
           ValueType = "DWORD"
       }

 

       Registry DisableIEESC-User {
           Key = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
           ValueName = "IsInstalled"
           Ensure = "Present"
           ValueData = "0"
           ValueType = "DWORD"
       }

 

	
 #    ,    
       File CreateDistribDir {
           Ensure          = "present"
           DestinationPath = "C:\Install\PSModules"
           Type            = "Directory"
       }

 

	
 #   NetworkingDsc (<a href="https://www.powershellgallery.com/packages/NetworkingDsc/8.0.0-preview0004">https://www.powershellgallery.com/packages/NetworkingDsc/8.0.0-preview0004</a>),      
       Script NetworkingDscDownLoad {
           SetScript = { Invoke-WebRequest -Uri "http://repo.contoso.com/repo/modules/NetworkingDsc.zip" -OutFile "C:\Install\PSModules\NetworkingDsc.zip" }
           GetScript = { return @{ Result = Test-Path "C:\Install\PSModules\NetworkingDsc.zip"
               GetScript = $GetScript; SetScript = $SetScript; TestScript = $TestScript
               }
           }
           TestScript = { Test-Path "C:\Program Files\WindowsPowerShell\Modules\NetworkingDsc" }
       }

 

 #   NetworkingDsc  C:\Program Files\WindowsPowerShell\Modules
       Archive UnpackNetworkingDsc {
           Ensure = "Present"
           DependsOn = "[Script]NetworkingDscDownLoad"
           Path = "C:\Install\PSModules\NetworkingDsc.zip"
           Destination = "C:\Program Files\WindowsPowerShell\Modules\"
       }

 

 #   ComputerManagementDsc (<a href="https://www.powershellgallery.com/packages/ComputerManagementDsc/8.2.1-preview0001">https://www.powershellgallery.com/packages/ComputerManagementDsc/8.2.1-preview0001</a>),      
       Script ComputerManagementDscDownLoad {
           SetScript = { Invoke-WebRequest -Uri "http://repo.contoso.com/repo/modules/ComputerManagementDsc.zip" -OutFile "C:\Install\PSModules\ComputerManagementDsc.zip" }
           GetScript = { return @{ Result = Test-Path "C:\Install\PSModules\ComputerManagementDsc.zip"
               GetScript = $GetScript; SetScript = $SetScript; TestScript = $TestScript
               }
           }
           TestScript = { Test-Path "C:\Program Files\WindowsPowerShell\Modules\ComputerManagementDsc" }
       }

 

	
 #   ComputerManagementDsc  C:\Program Files\WindowsPowerShell\Modules
       Archive UnpackComputerManagementDsc {
           Ensure = "Present"
           DependsOn = "[Script]ComputerManagementDscDownLoad"
           Path = "C:\Install\PSModules\ComputerManagementDsc.zip"
           Destination = "C:\Program Files\WindowsPowerShell\Modules\"
       }

 

	
 #   xPendingReboot (<a href="https://www.powershellgallery.com/packages/xPendingReboot/0.4.0.0">https://www.powershellgallery.com/packages/xPendingReboot/0.4.0.0</a>),      
       Script xPendingRebootDownLoad {
           SetScript = { Invoke-WebRequest -Uri "http://repo.contoso.com/repo/modules/xPendingReboot.zip" -OutFile "C:\Install\PSModules\xPendingReboot.zip" }
           GetScript = { return @{ Result = Test-Path "C:\Install\PSModules\xPendingReboot.zip"
               GetScript = $GetScript; SetScript = $SetScript; TestScript = $TestScript
               }
           }
           TestScript = { Test-Path "C:\Program Files\WindowsPowerShell\Modules\xPendingReboot" }
       }

 

	
 #   xPendingReboot  C:\Program Files\WindowsPowerShell\Modules
       Archive UnpackxPendingReboot {
           Ensure = "Present"
           DependsOn = "[Script]xPendingRebootDownLoad"
           Path = "C:\Install\PSModules\xPendingReboot.zip"
           Destination = "C:\Program Files\WindowsPowerShell\Modules\"
       }
   }
}

Sobre segurança


O mínimo de gordura do DSC no terreno é a falta de Contas Executar como. Esse mecanismo armazena com segurança as contas na forma de nome de usuário + "hash sal da senha" e as transfere para o serviço, responsável pela autenticação. Sem ele, o DSC não pode gerenciar contas em nome de outro serviço. E se precisarmos nos autenticar em uma conta com privilégios especiais, o processo de automação será muito complicado. Por exemplo, esse será o caso ao inserir o servidor no domínio.

Tudo à nossa disposição:

  • credenciais são armazenadas em texto sem formatação,
  • credenciais criptografadas funcionam apenas no PC onde foram geradas.

Na prática, existem várias soluções. 


"Stubs" são bons quando a previsibilidade do comportamento do servidor deve ser garantida.
Fazemos um "stub" após a configuração do servidor em vários casos, se usamos:

  • reboot (recurso xPendingReboot) 
  • transferência de credenciais 
  • outros recursos que podem afetar o desempenho do servidor em relação a reinicializações ou segurança não planejadas.

Para fazer isso, crie e republique configurações SEM blocos contendo o recurso xPendingReboot e configurações com credenciais.

Essa abordagem se aplica apenas ao cenário Push, pois o Pull é bastante direto e não implica uma alteração de configuração em tempo real. No próximo artigo deBuldakovExaminaremos mais de perto as configurações e os recursos de trabalho nos modos Push e Pull.

E também discutimos as nuances da tecnologia DSC e os limites de sua aplicação em 28 de maio, às 18h00, na primeira reunião on-line da comunidade Raiffeisenbank DGTL Communications. Também na reunião, falaremos sobre como fazer amigos do ELK e do Exchange e o que o Microsoft Endpoint Manager pode fazer no gerenciamento de dispositivos. Aqui está o registro para o mitap .

All Articles