Puncte:1

Cum să porniți etcd în docker de la systemd?

drapel jp

Vreau să pornesc etcd (un singur nod) în docker de la systemd, dar ceva pare să nu meargă greșit - se termină la aproximativ 30 de secunde după pornire.

Se pare că serviciul începe în stare "activare" dar terminați după aproximativ 30 de secunde fără a ajunge la starea "activ". Poate că lipsește vreo semnalizare între containerul docker și systemd?

Actualizați (vezi partea de jos a postării): starea serviciului systemd ajunge a eșuat (Rezultat: expirare) - când scot Restart=la eșec instrucție.

Când verific starea serviciului etcd după pornire, obțin acest rezultat:

$ sudo systemctl status etcdâ etcd.service - etcd Loaded: încărcat (/etc/systemd/system/etcd.service; activat; prestabilit furnizor: dezactivat)
   Activ: se activează (repornire automată) (Rezultat: cod de ieșire) din miercuri 2021-08-18 20:13:30 UTC; acum 4s
  Proces: 2971 ExecStart=/usr/bin/docker run -p 2380:2380 -p 2379:2379 --volume=etcd-data:/etcd-data --name etcd my-aws-account.dkr.ecr.eu- north-1.amazonaws.com/etcd:v3.5.0 /usr/local/bin/etcd --data-dir=/etcd-data --name etcd0 --advertise-client-urls http://10.0.0.11: 2379 --listen-client-urls http://0.0.0.0:2379 --initial-advertise-peer-urls http://10.0.0.11:2380 --listen-peer-urls http://0.0.0.0: 2380 --initial-cluster etcd0=http://10.0.0.11:2380 (code=exited, status=125)
 PID principal: 2971 (cod=ieșit, stare=125)

Rulez acest lucru pe o mașină Amazon Linux 2, cu un script de date utilizator care să ruleze la lansare. Am confirmat asta docker.serviciu și docker_ecr_login.service rulează cu succes.

Și la scurt timp după lansarea mașinii, pot vedea că etcd rulează:

 sudo systemctl status etcd
â etcd.service - etcd
   Încărcat: încărcat (/etc/systemd/system/etcd.service; activat; prestabilit furnizor: dezactivat)
   Activ: se activează (începe) din miercuri 2021-08-18 20:30:07 UTC; acum 1 min 20 de secunde
 PID principal: 1573 (docker)
    Sarcini: 9
   Memorie: 24,3 M
   CGroup: /system.slice/etcd.service
           ââ1573 /usr/bin/docker run -p 2380:2380 -p 2379:2379 --volume=etcd-data:/etcd-data --name etcd my-aws-account.dkr.ecr. eu-north-1.amazonaws.com...

18 august 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.690Z","logger":"raft","caller":"...rm 2"}
18 august 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.691Z","caller":"etcdserver/serve..."3.5"}
18 august 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.693Z","caller":"membership/clust..."3.5"}
18 august 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.693Z","caller":"etcdserver/server.go:2...
18 august 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.693Z","caller":"api/capability.g..."3.5"}
18 august 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.693Z","caller":"etcdserver/serve..."3.5"}
18 august 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.693Z","caller":"embed/serve.go:9...ests"}
18 august 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.695Z","caller":"etcdmain/main.go...emon"}
18 august 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.695Z","caller":"etcdmain/main.go...emon"}
18 august 20:30:17 ip-10-0-0-11.eu-north-1.compute.internal docker[1573]: {"level":"info","ts":"2021-08-18T20 :30:17.702Z","caller":"embed/serve.go:1...2379"}
Sugestie: Unele linii au fost elipsate, utilizați -l pentru a le afișa în întregime.

Obțin același comportament dacă etcd ascultă Node IP (10.0.0.11) sau 127.0.0.1.

Pot rula etcd local, pornit de la linia de comandă (și nu se termină după 30 de secunde), cu:

sudo docker run -p 2380:2380 -p 2379:2379 --volume=etcd-data:/etcd-data --name etcd-local \
my-aws-account.dkr.ecr.eu-north-1.amazonaws.com/etcd:v3.5.0 \
/usr/local/bin/etcd --data-dir=/etcd-data \
--name etcd0 \
--advertise-client-urls http://127.0.0.1:2379 \
--listen-client-urls http://0.0.0.0:2379 \
--initial-advertise-peer-urls http://127.0.0.1:2380 \
--listen-peer-urls http://0.0.0.0:2380 \
--initial-cluster etcd0=http://127.0.0.1:2380

Parametrii pentru etcd este similar cu Rularea unui singur nod etcd - documentația ectd 3.5.

Aceasta este partea relevantă a scriptului de pornire care are scopul de a lansa etcd:

sudo docker volume create --name etcd-data

pisica <<EOF | sudo tee /etc/systemd/system/etcd.service
[Unitate]
Descriere=etcd
După=docker_ecr_login.service

[Serviciu]
Tip = notificare
ExecStart=/usr/bin/docker run -p 2380:2380 -p 2379:2379 --volume=etcd-data:/etcd-data \
 --name etcd my-aws-account.dkr.ecr.eu-north-1.amazonaws.com/etcd:v3.5.0 \
 /usr/local/bin/etcd --data-dir=/etcd-data \
 --name etcd0 \
 --advertise-client-urls http://10.0.0.11:2379 \
 --listen-client-urls http://0.0.0.0:2379 \
 --initial-advertise-peer-urls http://10.0.0.11:2380 \
 --listen-peer-urls http://0.0.0.0:2380 \
 --initial-cluster etcd0=http://10.0.0.11:2380
Restart=la eșec
RestartSec=5

[Instalare]
WantedBy=multi-user.target
EOF

sudo systemctl enable etcd
sudo systemctl start etcd

Când listăm toate containerele de pe mașină, pot vedea că a funcționat:

sudo docker ps -a
CONTAINER ID IMAGINE COMANDA CREAȚĂ STAREA PORTURI NUMELE
a744aed0beb1 my-aws-account.dkr.ecr.eu-north-1.amazonaws.com/etcd:v3.5.0 „/usr/local/bin/etcd⦔ 25 minute în urmă Ieșit (0) 24 minute în urmă etcd

dar bănuiesc că nu poate fi repornit deoarece numele containerului există deja.

De ce containerul etcd se termină după ~ 30 de secunde, când este pornit de la systemd? Se pare că a pornit cu succes, dar systemd îl arată doar în starea „activare”, dar niciodată în starea „activ” și pare să fie terminat după aproximativ 30 de secunde.Lipsește o semnalizare de la containerul docker etcd către systemd? Dacă da, cum pot corecta semnalizarea?


ACTUALIZAȚI:

După îndepărtarea Restart=la eșec instrucțiuni în fișierul unității de service, acum primesc starea: a eșuat (Rezultat: expirare):

$ sudo systemctl status etcd
â etcd.service - etcd
   Încărcat: încărcat (/etc/systemd/system/etcd.service; activat; prestabilit furnizor: dezactivat)
   Activ: eșuat (Rezultat: expirare) de miercuri 2021-08-18 21:35:54 UTC; acum 5 minute
  Proces: 1567 ExecStart=/usr/bin/docker run -p 2380:2380 -p 2379:2379 --volume=etcd-data:/etcd-data --name etcd my-aws-account.dkr.ecr.eu- north-1.amazonaws.com/etcd:v3.5.0 /usr/local/bin/etcd --data-dir=/etcd-data --name etcd0 --advertise-client-urls http://127.0.0.1: 2379 --listen-client-urls http://0.0.0.0:2379 --initial-advertise-peer-urls http://127.0.0.1:2380 --listen-peer-urls http://0.0.0.0: 2380 --initial-cluster etcd0=http://127.0.0.1:2380 (code=exited, status=0/SUCCESS)
 PID principal: 1567 (cod=ieșit, stare=0/SUCCESS)

18 august 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.332Z","caller":"osutil/interrupt...ated"}
18 august 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.333Z","caller":"embed/etcd.go:36...379"]}
Aug 18 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: AVERTISMENT: 2021/08/18 21:35:54 [core] grpc: addrConn. createTransport a eșuat...ing...
18 august 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.335Z","caller":"etcdserver/serve...6a6c"}
18 august 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.337Z","caller":"embed/etcd.go:56...2380"}
18 august 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.338Z","caller":"embed/etcd.go:56...2380"}
18 august 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal docker[1567]: {"level":"info","ts":"2021-08-18T21 :35:54.339Z","caller":"embed/etcd.go:36...379"]}
18 august 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal systemd[1]: Nu s-a pornit etcd.
18 august 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal systemd[1]: Unitatea etcd.service a intrat în stare eșuată.
18 august 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal systemd[1]: etcd.service failed.
Sugestie: Unele linii au fost elipsate, utilizați -l pentru a le afișa în întregime.
Puncte:1
drapel cn

Actualizare: postarea datelor de testare și integrarea actualizărilor pe baza comentariilor primite. docker -d nu este necesar pentru integrarea systemd, așa cum se credea inițial. Setarea Type= așa cum a indicat Michael pare să fie din experiența mea, mai importantă decât descărcarea stării demonizate a unui serviciu în docker. Problema OP părea la primul fard de obraz să fie un efect secundar al lipsei de fundal, așa cum am explicat inițial. Acest fundal pare irelevant după ce l-am testat în continuare.

Rețineți că imaginea Amazon AWS utilizată în OP nu este ceva ce pot testa sau depana direct. Un exemplu contrastant pentru etcd și systemd sunt prezentate aici pentru a ajuta la configurarea sistemului endpoint similar cu al meu. Detalii sistem:

  • Ubuntu 20.04 LTS
  • docker 20.10.7
  • etcd 3.5.0

configurație systemd

Am ajuns cu următorul fișier de serviciu systemd. Rețineți că Type=simple, datorită faptului că Michael a sugerat să clarifice acest punct din răspuns (și, aparent, propria mea înțelegere a acestei piese a puzzle-ului). Puteți afla mai multe despre tipurile systemd aici:

https://www.freedesktop.org/software/systemd/man/systemd.service.html

Tipul contează; Mai mult, înțelegerea mea inițială a simplului ca tip era concentrată miopic pe lipsa de comunicare înapoi la systemd, ceea ce m-a făcut să ignor comportament a ceea ce face setarea tip ca reacție la răspunsurile din aplicația apelată (în acest caz docker).

Eliminarea tipului sau adăugarea tipului la simplu va avea ca rezultat același comportament, indiferent. Următoarea configurație din testul meu a funcționat în mod fiabil, la fel ca -d fiind prezent sau nu în comanda docker run:

[Unitate]
Descriere=Docker container-etcd.service
Documentation=man:docker
Necesită=docker.service
Wants=network.target
După=network-online.target

[Serviciu]
ExecStartPre=- /usr/bin/docker stop etcd
ExecStartPre=- /usr/bin/docker rm etcd
ExecStart=docker run --rm -d -p 2379:2379 -p 2380:2380 --volume=/home/user/etcd-data:/etcd-data --name etcd quay.io/coreos/etcd:v3. 5.0 /usr/local/bin/etcd --data-dir=/etcd-data --name etcd --initial-advertise-peer-urls http://10.4.4.132:2380 --listen-peer-urls http: //0.0.0.0:2380 --advertise-client-urls http://10.4.4.132:2379 --listen-client-urls http://0.0.0.0:2379 --initial-cluster etcd=http:// 10.4.4.132:2380
ExecStop=/usr/bin/docker stop etcd -t 10
ExecRestart=/usr/bin/docker restart etcd
KillMode=niciunul
RemainAfterExit=1
Restart=la eșec
Tip=simplu

[Instalare]
WantedBy=multi-user.target default.target

Note

  • RemainAfterExit a fost adăugat, deoarece systemd va considera serviciul părăsit după pornire dacă nu este prezent; Lipsa acestui boolean creează o situație aparent eronată în care docker ps arată containerul în funcțiune, dar systemctl status container-etcd a arătat ieșit și inactiv.
  • Fișierul unitar systemd este oarecum incorect din punct de vedere sintactic. %n este folosit de obicei pentru liniile Exec pentru a se referi la numele serviciului (ca în ...docker restart %n); Nu am vrut să introduc mai multe confuzii în timp ce încercam să rezolv problema OP. Ca să nu mai spun că am folosit etcd ca nume de container docker, față de container-etcd, ca nume de serviciu al unității.
  • ExecStart a fost restrâns la o comandă cu o singură linie. Sintaxa \ standard nu a funcționat pentru mine, nici citarea comenzii de apel etcd în container. Testele mele de ieri păreau să fi funcționat bine, dar configurația de azi nu s-a comportat la fel ca ieri. Așa că am refăcut testul și configurațiile pentru a găsi ceea ce părea a fi cel mai stabil pentru mine.
  • Evident, dacă vei folosi docker rm în orice moment, tu trebuie sa sau foarte puternic ar trebui să utilizați suporturi de legătură, așa cum este menționat în OP și aici cu --volume. Personal, folosesc locații de cale completă, toate stocate sub /srv, și apoi leagă montarea în container. Astfel am un folder de backup, iar starea containerelor, prezente sau nu, este irelevantă.

Confirmare

După ce am actualizat fișierul de serviciu systemd, am făcut o reîncărcare a demonului etc., am intrat în container și am rulat o comandă de testare împotriva etcd:

  • docker exec -it etcd sh
  • etcdctl --endpoints=http://10.4.4.132:2379 lista de membri

Rezultat

9a552f9b95628384, început, etcd, http://10.4.4.132:2380, http://10.4.4.132:2379, fals
Michael Hampton avatar
drapel cz
De ce să demonizeze docker în loc să folosești doar `Type=simple` (implicit)? Ce avantaj oferă această schimbare?
drapel cn
@MichaelHampton De ce ai vrea să folosești Type=simple ?? ai citit documentatia?? Citat: „Rețineți că acest lucru înseamnă că liniile de comandă systemctl start pentru servicii simple vor raporta succes chiar dacă binarul serviciului nu poate fi invocat cu succes”. Deci, motivul 1 pentru a nu folosi acest tip; Este atât ineficient și ar putea cauza probleme persoanelor dependente de serviciu.În al doilea rând, utilizarea -d cu docker run este modalitatea principală de a rula containerele demonizate. În al treilea rând, dockerd controlează containerele, nu systemctl. Acesta din urmă cheamă pur și simplu demonul, care îi controlează. Deci, cel puțin 3 motive.
Michael Hampton avatar
drapel cz
Ideea nu a fost nivelul meu de cunoștințe, ci să vă ajut să vă îmbunătățiți răspunsul. Acestea sunt informații bune și ar trebui incluse, astfel încât persoanele mai puțin experimentate care ar putea avea aceeași idee să știe și de ce nu ar trebui.
drapel jp
Acest lucru nu a funcționat, serviciul etcd systemd a eșuat cu: `Activ: eșuat (Rezultat: protocol)`.
drapel cn
@MichaelHampton Scuze. Tonul nu se traduce bine în text, așa că am presupus că este cel mai rău. Nu numai că, întrebarea ta inițială a fost de fapt care a ajuns să fie răspunsul corect din experiența mea. Enervant că încă nu mi-am gândit la ceea ce făcea de fapt valoarea câmpului Tip; Scuze și pentru asta. Am actualizat textul, pentru ambele comentarii aici cu alte date și constatări. Sperăm că Jonas această versiune vă va aduce undeva mai aproape de funcționarea dorită.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.