Điểm:1

How to start etcd in docker from systemd?

lá cờ jp

I want to start etcd (single node) in docker from systemd, but something seems to go wrong - it gets terminated about 30 seconds after start.

It looks like the service starts in status "activating" but get terminated after about 30 seconds without reaching the status "active". Perhaps there are any missing signalling between docker container and systemd?

Update (see bottom of post): systemd service status reaches failed (Result: timeout) - when I remove the Restart=on-failure instruction.

When I check the status of the etcd service after boot, I get this result:

$ sudo systemctl status etcd● etcd.service - etcd   Loaded: loaded (/etc/systemd/system/etcd.service; enabled; vendor preset: disabled)
   Active: activating (auto-restart) (Result: exit-code) since Wed 2021-08-18 20:13:30 UTC; 4s ago
  Process: 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)
 Main PID: 2971 (code=exited, status=125)

I run this on an Amazon Linux 2 machine, with a user data script to run at launch. I have confirmed that docker.service and docker_ecr_login.service run successfully.

And short after launch of the machine, I can see that the etcd is running:

 sudo systemctl status etcd
● etcd.service - etcd
   Loaded: loaded (/etc/systemd/system/etcd.service; enabled; vendor preset: disabled)
   Active: activating (start) since Wed 2021-08-18 20:30:07 UTC; 1min 20s ago
 Main PID: 1573 (docker)
    Tasks: 9
   Memory: 24.3M
   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...

Aug 18 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"}
Aug 18 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"}
Aug 18 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"}
Aug 18 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...
Aug 18 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"}
Aug 18 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"}
Aug 18 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"}
Aug 18 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"}
Aug 18 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"}
Aug 18 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"}
Hint: Some lines were ellipsized, use -l to show in full.

I get the same behavior wether etcd listen to the Node IP (10.0.0.11) or 127.0.0.1.

I can run etcd locally, started from command line (and it does not terminate after 30 seconds), with:

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

The parameters to etcd is similar to Running a single node etcd - ectd 3.5 documentation.

This is the relevant part of the startup script that is intended to launch etcd:

sudo docker volume create --name etcd-data

cat <<EOF | sudo tee /etc/systemd/system/etcd.service
[Unit]
Description=etcd
After=docker_ecr_login.service

[Service]
Type=notify
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=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable etcd
sudo systemctl start etcd

When listing all containers on the machine, I can see that it has been running:

sudo docker ps -a
CONTAINER ID   IMAGE                                                       COMMAND                  CREATED          STATUS                      PORTS                          NAMES
a744aed0beb1   my-aws-account.dkr.ecr.eu-north-1.amazonaws.com/etcd:v3.5.0   "/usr/local/bin/etcd…"   25 minutes ago   Exited (0) 24 minutes ago                          etcd

but I suspect that it cannot be restarted since the container name already exists.

Why does the etcd container get terminated after ~30 seconds, when started from systemd? It appears like it successfully start, but systemd only shows it in status "activating" but never in status "active" and it seem to be terminated after about 30 seconds. Is there some missing signalling from the etcd docker container to systemd? If so, how do I get that signalling correct?


UPDATE:

After removing the Restart=on-failure instruction in the service unit file, I now get status: failed (Result: timeout):

$ sudo systemctl status etcd
● etcd.service - etcd
   Loaded: loaded (/etc/systemd/system/etcd.service; enabled; vendor preset: disabled)
   Active: failed (Result: timeout) since Wed 2021-08-18 21:35:54 UTC; 5min ago
  Process: 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)
 Main PID: 1567 (code=exited, status=0/SUCCESS)

Aug 18 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"}
Aug 18 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]: WARNING: 2021/08/18 21:35:54 [core] grpc: addrConn.createTransport failed ...ing...
Aug 18 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"}
Aug 18 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"}
Aug 18 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"}
Aug 18 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"]}
Aug 18 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal systemd[1]: Failed to start etcd.
Aug 18 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal systemd[1]: Unit etcd.service entered failed state.
Aug 18 21:35:54 ip-10-0-0-11.eu-north-1.compute.internal systemd[1]: etcd.service failed.
Hint: Some lines were ellipsized, use -l to show in full.
Điểm:1
lá cờ cn

Cập nhật: Đăng dữ liệu thử nghiệm và tích hợp các bản cập nhật dựa trên nhận xét nhận được. docker -d không cần thiết để tích hợp systemd, như suy nghĩ ban đầu. Loại = cài đặt như Michael đã chỉ ra dường như theo kinh nghiệm của tôi, quan trọng hơn là giảm tải trạng thái daemonized của một dịch vụ cho docker. Vấn đề OP ban đầu dường như là một tác dụng phụ của việc không có nền, như tôi đã giải thích ban đầu. Nền này có vẻ không liên quan sau khi đã thử nghiệm thêm.

Lưu ý rằng hình ảnh Amazon AWS được sử dụng trong OP, không phải là thứ mà tôi có thể kiểm tra hoặc khắc phục sự cố trực tiếp. Một ví dụ tương phản cho etcd và systemd được hiển thị ở đây để giúp định cấu hình hệ thống điểm cuối tương tự như của tôi. Chi tiết hệ thống:

  • Ubuntu 20.04 LTS
  • docker 20.10.7
  • v.v. 3.5.0

cấu hình hệ thống

Tôi đã kết thúc với tệp dịch vụ systemd sau. Lưu ý rằng Loại=đơn giản, do Michael đề nghị làm rõ điểm này trong câu trả lời (và rõ ràng là hiểu biết của riêng tôi về mảnh ghép này). Bạn có thể tìm hiểu thêm về các loại systemd tại đây:

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

Loại vấn đề; Thêm vào đó, hiểu biết ban đầu của tôi về loại đơn giản, đã tập trung một cách thiển cận vào việc thiếu liên lạc trở lại systemd, điều này khiến tôi bỏ qua phần áp dụng cư xử về những gì cài đặt loại thực hiện trong phản ứng với các phản hồi từ ứng dụng được gọi (trong trường hợp này là docker).

Việc xóa loại hoặc thêm loại vào đơn giản sẽ dẫn đến cùng một hành vi bất kể. Cấu hình sau trong thử nghiệm của tôi hoạt động đáng tin cậy, cũng như -d có hoặc không có trong docker run lệnh:

[Đơn vị]
Mô tả=Docker container-etcd.service
Tài liệu = người đàn ông: docker
Yêu cầu = docker.service
Muốn=mạng.mục tiêu
Sau=mạng-online.đích

[Dịch vụ]
ExecStartPre=- /usr/bin/docker stop etcd
ExecStartPre=- /usr/bin/docker rm vvd
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 khởi động lại vvd
KillMode=không có
RemainafterExit=1
Khởi động lại = khi thất bại
Loại = đơn giản

[Cài đặt]
WantedBy=đa người dùng.đích mặc định.đích

ghi chú

  • Đã thêm RemainafterExit, vì systemd sẽ coi dịch vụ đã thoát sau khi bắt đầu nếu không xuất hiện; Việc thiếu boolean này tạo ra một tình huống có vẻ sai lầm khi docker ps hiển thị vùng chứa đang chạy, nhưng thùng chứa trạng thái systemctl-etcd hiển thị đã thoát và không hoạt động.
  • Tệp đơn vị systemd hơi sai về mặt cú pháp. %n thường được sử dụng cho các dòng Exec để chỉ tên dịch vụ (như trong ...docker restart %n); Tôi không muốn gây thêm nhầm lẫn trong khi cố gắng giải quyết vấn đề của OP. Chưa kể tôi đã sử dụng etcd làm tên bộ chứa docker, so với container-etcd, làm tên dịch vụ đơn vị.
  • ExecStart đã được thu gọn thành lệnh một dòng. \ cú pháp tiêu chuẩn không hoạt động đối với tôi, cũng như không trích dẫn lệnh gọi etcd cho vùng chứa. Các bài kiểm tra của tôi ngày hôm qua dường như đã hoạt động tốt, nhưng cấu hình của ngày hôm nay không hoạt động giống như ngày hôm qua. Vì vậy, tôi đã thực hiện lại bài kiểm tra và cấu hình để tìm ra thứ có vẻ ổn định nhất đối với tôi.
  • Rõ ràng, nếu bạn định sử dụng docker rm vào bất kỳ thời điểm nào, bạn phải hoặc rất mạnh mẽ Nên sử dụng gắn kết liên kết, như đã nêu trong OP và ở đây với --volume. Cá nhân tôi sử dụng các vị trí đường dẫn đầy đủ, tất cả được lưu trữ trong/srv, sau đó liên kết gắn kết vào vùng chứa. Bằng cách đó, tôi có một thư mục để sao lưu và trạng thái của các vùng chứa, hiện tại hay không là không liên quan.

xác nhận

Sau khi cập nhật tệp dịch vụ systemd, thực hiện tải lại daemon, v.v., tôi đã thực thi vào vùng chứa và chạy lệnh kiểm tra đối với etcd:

  • docker exec -it vvd sh
  • etcdctl --endpoints=http://10.4.4.132:2379 danh sách thành viên

Kết quả

9a552f9b95628384, đã bắt đầu, v.v., http://10.4.4.132:2380, http://10.4.4.132:2379, sai
Michael Hampton avatar
lá cờ cz
Tại sao daemonize docker thay vì chỉ sử dụng `Type=simple` (mặc định)? Sự thay đổi này mang lại lợi ích gì?
lá cờ cn
@MichaelHampton Tại sao bạn muốn sử dụng Type=simple ?? Bạn đã đọc tài liệu chưa ?? Trích dẫn: "Lưu ý rằng điều này có nghĩa là các dòng lệnh khởi động systemctl cho các dịch vụ đơn giản sẽ báo cáo thành công ngay cả khi nhị phân của dịch vụ không thể được gọi thành công". Vì vậy, lý do 1 không sử dụng loại này; Nó vừa không hiệu quả vừa có thể gây ra sự cố cho những người phụ thuộc vào dịch vụ.Thứ hai, sử dụng -d với docker run là cách chính để chạy các container được daemon hóa. Thứ ba, dockerd kiểm soát các thùng chứa, không phải systemctl. Cái sau chỉ đơn giản là gọi daemon, điều khiển chúng. Vì vậy, ít nhất 3 lý do.
Michael Hampton avatar
lá cờ cz
Vấn đề không phải là trình độ hiểu biết của tôi là gì, mà là để giúp bạn cải thiện câu trả lời của mình. Đây là thông tin tốt và nên được đưa vào để những người ít kinh nghiệm hơn có thể có cùng ý tưởng cũng biết tại sao họ không nên làm như vậy.
lá cờ jp
Điều này không hoạt động, dịch vụ systemd etcd không thành công với: `Hoạt động: không thành công (Kết quả: giao thức)`.
lá cờ cn
@MichaelHampton Xin lỗi. Giai điệu không dịch tốt trong văn bản, vì vậy tôi cho rằng điều tồi tệ nhất. Không chỉ vậy, câu hỏi ban đầu của bạn thực sự là câu trả lời đúng theo kinh nghiệm của tôi. Bực mình vì tôi vẫn chưa hiểu giá trị của trường Loại thực sự đang làm gì; Xin lỗi cho điều đó là tốt. Tôi đã cập nhật văn bản cho cả hai nhận xét ở đây cùng với các dữ liệu và phát hiện khác. Hy vọng Jonas phiên bản này sẽ giúp bạn tiến gần hơn đến hoạt động như mong muốn.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.