SystemD는 서비스를 다시 로드하고 다시 시작할 때까지 ExecStartPre를 실행하지 않습니다.

SystemD는 서비스를 다시 로드하고 다시 시작할 때까지 ExecStartPre를 실행하지 않습니다.

/usr/lib/systemd/system/docker.service환경 파일로 확장하기 위해 시작 스크립트를 재정의하고 있습니다 . 구성 파일을 /etc/systemd/system/docker.service.d/docker.conf다음과 같이 정의했습니다 .

test -d /etc/systemd/system/docker.service.d || \
    mkdir /etc/systemd/system/docker.service.d

cat > /etc/systemd/system/docker.service.d/docker.conf <<EOF
[Service]
EnvironmentFile=/etc/sysconfig/docker
ExecStartPre=-/usr/local/sbin/generate-docker-config
ExecStart=
ExecStart=/usr/bin/docker daemon -H fd:// --dns=\${LOCAL_IPV4}
EOF

systemctl daemon-reload

위의 스크립트를 실행 중입니다.포장기AMI 빌드 단계.

AMI를 시작하면 Docker 서비스에 대한 SystemD에 다음과 같은 상태 출력이 표시됩니다.

● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/docker.service.d
           └─docker.conf
   Active: active (running) since Mon 2016-03-28 21:16:11 UTC; 6min ago
     Docs: https://docs.docker.com
 Main PID: 858 (docker)
   CGroup: /system.slice/docker.service
           ├─ 858 /usr/bin/docker daemon -H fd:// --dns=10.224.4.178 --log-driver=syslog --log-opt tag={{.ImageName}}

ExecStartPre출력에 표시된 대로 아직 실행되지 않았습니다. 내가 다음을 수행하면, 나는하다이제 시작 스크립트가 실행되었는지 확인하세요.

# systemctl daemon-reload && systemctl restart docker.service && \
    systemctl status docker.service
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/docker.service.d
           └─docker.conf
   Active: active (running) since Mon 2016-03-28 22:05:24 UTC; 24ms ago
     Docs: https://docs.docker.com
  Process: 1873 ExecStartPre=/usr/local/sbin/generate-docker-config (code=exited, status=0/SUCCESS)
 Main PID: 1876 (docker)
   CGroup: /system.slice/docker.service
           └─1876 /usr/bin/docker daemon -H fd:// --dns=10.224.4.178 --log-driver=syslog --log-opt tag={{.ImageName}}

ExecStartPre이제 상태 출력에 어떻게 표시되는지 확인하세요.

daemon-reloadSystemD가 새로운 서비스 구성 파일과 스크립트를 로드하고 실행하도록 하는 것 외에도 ExecStartPrePacker 빌드에서 명령을 실행해야 합니까? Packer 빌드의 서비스를 사용해야 합니까 restart, 아니면 이 문제에 대해 더 좋고 적합한 솔루션이 있습니까?

참고: 내 스크립트에는 ExecStartPreEC2 인스턴스 태그에 사용 가능한 네트워크가 필요합니다. curlDocker 서비스 파일은 이를 지정 After=network.target docker.socket하므로 네트워크가 가동된 후에 실행될 것이라고 가정합니다.

답변1

음, 이는 예상된 동작입니다. docker 유닛 파일을 덮어쓴 후 docker 서비스를 다시 시작하려면 스크립트에서 after를 호출해야 합니다 systemctl restart docker.service. systemctl daemon-reloaddokett가 이미 실행 중인 경우에만 다시 시작하려면 대신 dokett를 호출하세요 systemctl try-restart docker.service.

명령의 목적 은 데몬에게 모든 구성을 다시 로드하고, 단위 파일을 다시 로드하고, 서비스 종속성 트리를 다시 생성하도록 systemctl daemon-reload지시하는 것입니다 . systemd그러나 디스크의 유닛 파일이 변경되더라도 시스템의 다른 서비스에는 영향을 미치지 않습니다.

답변2

네트워크가 network.service"온라인"이면 100% 신뢰할 수 없다고 가정합니다. 그렇기 때문에 하나가 있습니다 network-online.target.

컬에 의존하고 서비스가 시작되기 전에 네트워크가 작동 중인지, DNS가 작동하는지 등을 절대적으로 확인하고 싶다면 이를 서비스에 추가하는 docker.conf것이 도움이 될 수 있습니다 .

[Unit]
After=network-online.target

...그리고 이러한 모든 출시 후 작업을 수행하므로 새 기능이 ExecStartPre제대로 작동하려면 Packer 빌드 스크립트에 또는 를 추가해야 합니다 systemctl daemon-reload && systemctl restart docker.service. systemctl stop docker.service && systemctl daemon-reload && systemctl start docker.service후자가 가장 신뢰할 수 있습니다.

수정 및 daemon-reload완료 전에 서비스를 중지하면 전체 장치가 지정된 대로 다시 로드됩니다. 제공 한 출력의 세 번째 비트에서 볼 수 있습니다 ExecStart.docker.service아니요Packer 빌드 스크립트에 지정한 매개변수가 포함되어 있습니다. 이는 systemctl restart docker.service(중지, 데몬 재로드 및 시작 포함) 때문입니다.

관련 정보