Recarregando o systemd-journald config

3

Não sei por que isso está acontecendo. Eu tenho um serviço de teste registrando algum texto arbitrário para stdout a cada 10 segundos. Aqui está o meu arquivo de serviço /etc/systemd/system/samplego.service:

[Unit]
Description=Sample go app
After=network.target

[Service]
SyslogIdentifier=my-samplego
ExecStart=/opt/samplego/samplego
Restart=on-failure

[Install]
WantedBy=multi-user.target 

Isso funciona bem e eu posso ver essas linhas de log usando journalctl.

No entanto, se eu alterar uma configuração em /etc/systemd/journald.conf forwardtosyslog = sim. Em seguida, emita systemctl restart systemd-journald - meu aplicativo para o logging e não consigo ver as atualizações no journalctl -f até que o systemctl reinicie o samplego. Você precisa reiniciar todos os serviços após o reinício do journald?

    
por W Khan 18.07.2017 / 16:21

1 resposta

10

Uma das principais inovações dos daemontools em meados dos anos 90 foi a ideia de logging confiável . O supervisor do daemon correu dois daemons, o daemon principal e um daemon log . Ele abriu um pipe antes de invocar qualquer um, passando a extremidade de gravação do pipe como a saída padrão do main processo do daemon e a extremidade de leitura do pipe como o log processo do daemon ' entrada padrão. Ele também manteve os descritores de arquivos abertos em ambas as extremidades do pipe. Assim, se o servidor de logs morresse, ou fosse terminado, e depois reiniciado, os dados de log gravados no pipe seriam preservados e disponíveis para serem lidos e registrados pela instância recém-reiniciada do servidor de logs, porque o pipe não seria fechado. / p>

Os designers do systemd não aprenderam com esse design.

systemd organiza os processos de serviço gerados, quando configurados, para que suas saídas padrão sejam enviadas por um soquete para um processo de diário. Mas, em vez de, como no caso dos daemontools, abrir um pipe e organizar cada processo para herdar a extremidade apropriada do pipe, systemd usa um soquete de fluxo AF_LOCAL em /run/systemd/journal/stdout . Processos principais se conectam como clientes; o processo de registro escuta como um servidor.

Isso significa que a conexão de dados tem semântica de soquete cliente-servidor em vez de semântica de pipe herdado. Se o servidor morre, a conexão desaparece. Todos os dados de log em buffer são perdidos, e todos os dados mais escritos pelo daemon principal vão para um socket fechado e são perdidos. (Isto é em parte porque o systemd tem uma configuração IgnoreSIGPIPE que por padrão é verdadeira. Escrever a saída do log em um socket fechado também faz com que o kernel tente matar o daemon que está gravando o log.)

Portanto, se você eliminar o processo systemd-journald , a saída do processo fechará as conexões do soquete com todos os processos do daemon cujas saídas ele está registrando, e todas as saídas adicionais serão perdidas. Não há como recuperá-lo e reconectar as saídas do processo principal ao processo de registro. É preciso reiniciar todos os processos principais, para que systemd reabra uma conexão do cliente new com o servidor de log (recém-criado).

O pessoal do systemd fez um bodge para trabalhar em torno disso em 2016. Ele envolvia adicionar a capacidade de processos para enviar descritores de arquivos abertos arbitrários de sua própria escolha para o processo # 1 e puxá-los mais tarde. systemd-journald faz isso com as conexões de extremidade do servidor com os clientes que está registrando, de forma que eles permaneçam abertos durante a reinicialização do próprio servidor de registro.

O problema com este mecanismo é que ele precisa de muito mais trabalho para torná-lo seguro, e as pessoas do sistema não têm um bom histórico quando se trata de projetar as coisas para serem seguras, como os eventos só neste ano demonstraram. Ele precisa de muito mais trabalho porque quem pode empurrar o que e quantos abrem os descritores de arquivo no processo # 1 e por quanto tempo precisa ter acesso controlado e limitado. Caso contrário, há uma grande quantidade de possíveis explorações. (No design do daemontools, o próprio processo do gerenciador de serviços é o que abre os descritores de arquivos, portanto, ele tem controle absoluto sobre quais descritores de arquivos está mantendo aberto para processos filho. Ele não pode ser enganado, abusado ou inundado.)

No s6 de Laurent Bercot, s6-svscan faz o usual daemontools com o pipe entre os serviços principal e de log. Ele também possui um mecanismo para manter descritores de arquivos arbitrários abertos. Isso não é feito por código executado com privilégios de superusuário dentro do gerenciador de serviços no processo # 1, como no systemd. Isso é feito por um processo totalmente sem privilégios que é executado separadamente do gerenciador de serviços.

Leitura adicional

por 19.07.2017 / 15:00