Executando um aplicativo .NET como um serviço no Linux com Systemd (2023)

Nesta postagem, veremos como você pode executar um aplicativo .NET Core / .NET 5 como um serviço no Linux. nós vamos usarSystemdNamepara integrar nosso aplicativo com o sistema operacional e possibilitar iniciar e parar nosso serviço e obter logs dele.

Para construir o meuataque à cadeia de suprimentos com .NET, eu precisava hospedar um servidor DNS para capturar os nomes de host enviados para mim. Vamos usar isso como exemplo!

Criando um aplicativo .NET para ser executado como um serviço

Um serviço .NET precisará fazer uso doMicrosoft.Extensions.Hostingmodelo de hospedagem. Isso significa que qualquer aplicativo ASP.NET Core funcionará, assim como projetos criados usando oServiço do Trabalhadormodelo (dotnet novo trabalhador). eu vou usarCavaleiroaqui.

Executando um aplicativo .NET como um serviço no Linux com Systemd (1)

Em seguida, você precisará instalar um pacote NuGet:Microsoft.Extensions.Hosting.Systemd. Este pacote fornece a infraestrutura de hospedagem .NET para serviços Systemd. Em outras palavras: contém a infraestrutura para trabalhar com o daemon Systemd no Linux.

Só falta uma coisa: registrar as extensões de hospedagem do Systemd em nosso aplicativo. EmProgram.cs, você precisará adicionar.UseSystemd()no construtor de host:

público aula Programa{ // ... público estático IHostBuilder CriarHostBuilder(corda[] argumentos) => Hospedar.CreateDefaultBuilder(argumentos) .UseSystemd() // Adicione isso .ConfigurarServiços((hostContext, Serviços) => { Serviços.AddHostedService<Trabalhador>(); });}

Com isso instalado, nosso aplicativo pode ser executado como um serviço Systemd no Linux! Bem, quase… Restam duas coisas a fazer:

  • Implemente o aplicativo
  • Registre o aplicativo com o Systemd

Vamos começar com o primeiro e implementar um servidor DNS que executaremos como um serviço.

Implementar um servidor DNS .NET como um serviço

O servidor DNSmencionei no meu post anterioré construído em .NET usandoO excelente pacote de DNS de Mirza Kapetanovic, e hospedado como um serviço no Linux, usando Systemd.

Vamos construir um serviço DNS simples que retorne a hora atual como umTXTregistro.

Observação: você pode pular esta seção se quiser apenas aprender como registrar aplicativos .NET como serviços Systemd.

Primeiro, instale oDNSpacote. Ele vem com um servidor DNS quase pronto, de modo que precisamos apenas conectá-lo e implementar a lógica do servidor.

(Video) Criando serviços em Linux

OTrabalhadorA classe que foi criada pelo modelo de serviço do trabalhador é uma boa base para começar. Nele, você pode usar injeção de construtor para obter acesso a quaisquer serviços disponíveis em nosso aplicativo. Iremos com umILogger(já presente no modelo), eIConfigurationpara obter acesso aappsettings.json/variáveis ​​de ambiente/argumentos de linha de comando. se estendeServiço de plano de fundo, que tem umExecuteAsyncmétodo que executará nosso serviço. Aqui está um esqueletoTrabalhador:

público aula Trabalhador : Serviço de plano de fundo{ privado somente leitura ILogger<Trabalhador> _logger; privado somente leitura IConfiguration _configuração; público Trabalhador(ILogger<Trabalhador> registrador, IConfiguration configuração) { _logger = registrador; _configuração = configuração; } protegido sobrepor assíncrono Tarefa ExecuteAsync(CancellationToken stopToken) { // ... a lógica vai aqui ... }}

Agora vamos conectar o próprio servidor DNS. NoExecuteAsyncmétodo, adicione o seguinte:

protegido sobrepor assíncrono Tarefa ExecuteAsync(CancellationToken stopToken){ era servidor = novo Servidor dns(novo SampleRequestResolver()); servidor.Audição += (_, _) => _logger.LogInformation("O servidor DNS está escutando..."); servidor.Requeridos += (_, e) => _logger.LogInformation("Solicitação: {Domínio}", e.Solicitar.Questões.Primeiro().Nome); servidor.Errou += (_, e) => { _logger.LogError(e.Exceção, "Um erro ocorreu"); se (e.Exceção é ResponseException responseError) { _logger.LogError("Resposta: {Resposta}", responseError.Resposta); } }; aguardam Tarefa.Quando Qualquer(novo[] { servidor.Ouvir( porta: int.TryParse(_configuração["Porta"], fora era porta) ? porta : 53531, ip: Endereço de IP.Qualquer), Tarefa.Atraso(-1, stopToken) });}

Hora de desembrulhar!

  • Estamos configurando oServidor dns, que resolverá registros usando umSampleRequestResolver(que precisaremos construir).
  • Estamos assinando alguns eventos expostos peloServidor dns, para que possamos ver os logs de solicitações recebidas e ver sempre que algo dá errado.
  • Por fim, começamos a ouvir as solicitações recebidas.

OExecuteAsyncé passado umCancellationToken, que será usado quando o Systemd solicitar que nosso serviço seja encerrado. Desde oDNSbiblioteca em si não tem suporte paraCancellationToken, Estou a usarTask.WhenAnyaqui para iniciar o servidor DNS, para que possamos desligar nosso serviço quando o cancelamento for solicitado.

O próprio servidor escutará na porta definida na configuração e, quando ela não estiver presente, o padrão é53531.

Resta uma coisa: queSampleRequestResolveraula. Tem que implementarIRequestResolvere crie uma resposta para as consultas de DNS recebidas. Como esse não é o escopo real desta postagem do blog, aqui está uma implementação rápida que retorna a data e hora atuais para qualquerTXTregistro solicitado e retorna um erro para outras solicitações:

público aula SampleRequestResolver : IRequestResolver{ público Tarefa<IResponse> Resolver(Eu peço solicitar, CancellationToken token de cancelamento = novo CancellationToken()) { IResponse resposta = Resposta.FromRequest(solicitar); para cada (era pergunta em resposta.Questões) { se (pergunta.Tipo == Tipo de Registro.TXT) { resposta.Registros de resposta.Adicionar(novo TextResourceRecord( pergunta.Nome, Cadeia de caracteres.FromString(Data hora.UtcNow.Para sequenciar("O")))); } outro { resposta.Código de resposta = Código de resposta.Recusou; } } retornar Tarefa.Do resultado(resposta); }}

Se você executar o serviço localmente, verá que funciona! Você pode usar ferramentas comonslookupeescavaçãopara experimentá-lo.

(Video) Creating systemd Service Files

Executando um aplicativo .NET como um serviço no Linux com Systemd (2)

Verifica aREADME.mddo projeto DNSpara mais exemplos, e tenha cuidado para não construir acidentalmente umabra o resolvedor de DNSse você explorar a construção de seu próprio DNS.

Criar configuração de unidade de serviço

Vamos hospedar nosso serviço no Linux! Systemd usaconfiguração da unidade de serviçoarquivos que definem o que um serviço faz, se deve ser reiniciado e tudo mais.

Você precisará criar um.serviçoarquivo na máquina Linux que você deseja registrar e executar o serviço. Em sua forma mais simples, um arquivo de serviço se parece com isto:

[Unit]Description=DNS Server[Service]Type=notifyExecStart=/usr/sbin/DnsServer --port=53[Install]WantedBy=multi-user.target

O[Unidade]A seção descreve informações mais genéricas sobre nosso aplicativo. O Systemd pode executar mais do que apenas serviços e[Unidade]é uma seção comum para todos os tipos de aplicativos que podem ser executados. Eu adicionei apenas oDescrição, mas hámuito mais opções disponíveis aqui.

No[Serviço]seção, definimos detalhes sobre nosso aplicativo. Para aplicativos .NET, oTipovai sernotificar, para que possamos notificar o Systemd quando o host for iniciado ou interrompido - oMicrosoft.Extensions.Hosting.Systemdpacote cuida disso.ExecStartdefine o caminho onde nosso binário de inicialização do serviço está localizado. No exemplo acima, usarei um aplicativo .NET independente e direi a ele em qual porta escutar como um argumento de linha de comando.

finalmente, o[Instalar]A seção define quais destinos de sistema operacional podem iniciar nosso serviço. Nesse caso,multiusuário.alvopermite iniciar o serviço sempre que estivermos em um ambiente multiusuário (quase sempre). Você também pode definir isso paragráfico.alvoentão você precisará de um ambiente gráfico carregado para iniciar este serviço.

Crie um aplicativo .NET independente

Nosso próprio serviço precisará estar disponível na máquina Linux de destino, onde definimos que o Systemd pode encontrá-lo (comExecStart):/usr/sbin/DnsServer.

A última coisa que eu queria fazer era implantar o .NET na máquina de destino, então decidi construir umaplicativo independente, como um único arquivo – o tempo de execução .NET e todas as dependências necessárias são agrupadas em um único arquivo executável. Eu usei o seguinte comando para criar o aplicativo:

dotnet publish -c Release -r linux-x64 --self-contained=true -p:PublishSingleFile=true -p:GenerateRuntimeConfigurationFiles=true -o artefatos
(Video) How to Deploy .Net Core Web Application to Ubuntu Linux

Isso cria umServidor dnsexecutável de aproximadamente 62 MB (contém o necessário do runtime .NET). Copie para/usr/sbin/DnsServerna máquina Linux e verifique se ele é executável (sudo chmod 0755 /usr/sbin/DnsServer).

Instalando e executando o serviço no Linux

O.serviçoarquivo que criamos (eu o nomeeidnsserver.service) precisa existir no/etc/systemd/system/diretório da máquina Linux na qual o serviço será implantado.

Em seguida, execute o seguinte comando para que o Systemd carregue este novo arquivo de configuração:

sudo systemctl daemon-reload

Isso agora deve possibilitar a visualização do status do nosso serviço de servidor DNS:

sudo systemctl status dnsserver.service

Executando um aplicativo .NET como um serviço no Linux com Systemd (3)

Existem alguns outros comandos que podem ser úteis:

  • Inicie e pare o serviço:

    sudo systemctl start dnsserver.servicesudo systemctl stop dnsserver.servicesudo systemctl restart dnsserver.service
    (Video) Creating background .NET Core services on Linux
  • Certifique-se de que o serviço seja iniciado quando a máquina Linux for iniciada:

    sudo systemctl habilitar dnsserver.service

Parabéns, agora temos uma aplicação .NET rodando como um serviço, no Linux!

O que está acontecendo no meu serviço?

Quando um serviço está em execução, você também pode se interessar pelo que ele está fazendo. Podemos inspecionar as últimas entradas de log que nosso aplicativo emite, usando o seguinte comando:

sudo systemctl status dnsserver.service

Podemos ver que nosso serviço está em execução, obter detalhes sobre o ID do processo e ver as entradas de log mais recentes.

Executando um aplicativo .NET como um serviço no Linux com Systemd (4)

Se você realmente precisa de logs, você pode usarjornalctle obtenha todos os logs da unidade (-você) que é o nosso servidor DNS:

sudo journalctl -u dnsserver.service

O que é legal é que, graças aoMicrosoft.Extensions.Hosting.Systemdpacote, obtemos códigos de cores e severidades de log aqui:

(Video) s01e11 - .NET Worker Service applications (EN)

Executando um aplicativo .NET como um serviço no Linux com Systemd (5)

Conclusão

Nesta postagem, vimos como executar um aplicativo .NET como um serviço Systemd no Linux, usando oMicrosoft.Extensions.Hosting.Systemdpacote. Nós apenas arranhamos a superfície, no entanto. Há muito mais opções que você pode fornecer ao Systemd, você pode filtrar os níveis de log comjornalctl, e mais. recomendo dar uma olhadablog de Niels Swimberghepara mais alguns exemplos disso.

FAQs

Como instalar o .NET no Linux? ›

Instalação no Linux (Ubuntu)
  1. wget https://packages.microsoft.com/config/ubuntu/19. ...
  2. sudo apt-get update sudo apt-get install apt-transport-https sudo apt-get update sudo apt-get install dotnet-sdk-3.1.
  3. dotnet --version.
  4. dotnet --list-sdks.
  5. dotnet new console -o MeuConsoleApp -f net5. ...
  6. mkdir myapp cd myapp dotnet new console.

Como habilitar um serviço no Linux? ›

Habilitando e desabilitando serviços

Para iniciar um serviço na inicialização, use o comando enable : sudo systemctl enable application .

Como verificar serviços rodando no Linux? ›

Para listar todos os serviços que estão instalados no sistema, e o status de cada serviço, utilize o comando svcs com a opção -a . Este comando exibe todos os serviços, incluindo aqueles que estão desativados.

Como instalar o dotnet no Debian? ›

Isso é usado no comando sudo apt-get install a seguir. Isso representa a versão de distribuição em que você está. Isso é usado no comando wget abaixo. A versão de distribuição é o valor numérico, como 20.04 no Ubuntu ou 10 no Debian.

Videos

1. Running .net core as systemd service on ubuntu 14
(Roel Van de Paar)
2. ASP.NET 6 BACKGROUND WORKER SERVICES - What you need to know and how to setup one.
(tutorialsEU - C#)
3. Tips for working with web services on Ubuntu WSL #WSL #Ubuntu #Linux
(Canonical Ubuntu)
4. Comando cron - Agendar tarefas para execução recorrente no Linux
(Bóson Treinamentos)
5. Montando um Ambiente de Desenvolvimento ASP.NET e .NET 5 no Linux: Minicurso Gratuito Completo!
(Erudio)
6. O jeito mais fácil de subir uma aplicação NODE.JS para um servidor DE GRAÇA! | AWS EC2.
(Lucas Medeiros Dev)

References

Top Articles
Latest Posts
Article information

Author: Merrill Bechtelar CPA

Last Updated: 07/29/2023

Views: 5765

Rating: 5 / 5 (70 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Merrill Bechtelar CPA

Birthday: 1996-05-19

Address: Apt. 114 873 White Lodge, Libbyfurt, CA 93006

Phone: +5983010455207

Job: Legacy Representative

Hobby: Blacksmithing, Urban exploration, Sudoku, Slacklining, Creative writing, Community, Letterboxing

Introduction: My name is Merrill Bechtelar CPA, I am a clean, agreeable, glorious, magnificent, witty, enchanting, comfortable person who loves writing and wants to share my knowledge and understanding with you.