diff --git a/Makefile b/Makefile index a3147eb..294011d 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,99 @@ -.DEFAULT_GOAL := build - +$(VERBOSE).SILENT: +.DEFAULT_GOAL := _default +CUR_DIR := $(PWD) +export DOCKER_BUILDKIT=1 +platform := $(shell uname -p) +checkarm := arm EXECUTABLE=dns-inventory VERSION=$(shell git describe --tags --always) -build-windows: +Color_Off:=\033[0m +# Regular Colors +Black:=\033[0;30m +Red:=\033[0;31m +Green:=\033[0;32m +Yellow:=\033[0;33m +Blue:=\033[0;34m +Purple:=\033[0;35m +Cyan:=\033[0;36m +White:=\033[0;37m + + +define greeting + @clear + @echo "$(Yellow)" + @echo " ___ _ __ __ ____ __ " + @echo " / | ____ _____(_) /_ / /__ / _/___ _ _____ ____ / /_____ _______ __" + @echo " / /| | / __ \/ ___/ / __ \/ / _ \______ / // __ \ | / / _ \/ __ \/ __/ __ \/ ___/ / / /" + @echo " / ___ |/ / / (__ ) / /_/ / / __/_____// // / / / |/ / __/ / / / /_/ /_/ / / / /_/ / " + @echo "/_/ |_/_/ /_/____/_/_.___/_/\___/ /___/_/ /_/|___/\___/_/ /_/\__/\____/_/ \__, / " + @echo " /____/ " + @echo "$(Color_Off)" +endef + +define cleanup + @COMPOSE_PROFILES=dns,etcd docker compose -f docker/docker-compose.yml down + @rm -rf ./$(EXECUTABLE)_$(VERSION)_* +endef + +_init: + $(call greeting) + +build-windows: ## Make Windows binary env GOOS=windows GOARCH=amd64 go build -ldflags "-s -w -X 'github.com/NeonSludge/ansible-dns-inventory/internal/build.Version=$(VERSION)' -X 'github.com/NeonSludge/ansible-dns-inventory/internal/build.Time=$(shell date -u +%Y%m%dT%H%M%SZ)'" -o ./$(EXECUTABLE)_$(VERSION)_amd64_windows.exe ./cmd/$(EXECUTABLE) -build-darwin: +build-darwin: ## Make Darwin binary (ARM/AMD64) env GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w -X 'github.com/NeonSludge/ansible-dns-inventory/internal/build.Version=$(VERSION)' -X 'github.com/NeonSludge/ansible-dns-inventory/internal/build.Time=$(shell date -u +%Y%m%dT%H%M%SZ)'" -o ./$(EXECUTABLE)_$(VERSION)_amd64_darwin ./cmd/$(EXECUTABLE) env GOOS=darwin GOARCH=arm64 go build -ldflags "-s -w -X 'github.com/NeonSludge/ansible-dns-inventory/internal/build.Version=$(VERSION)' -X 'github.com/NeonSludge/ansible-dns-inventory/internal/build.Time=$(shell date -u +%Y%m%dT%H%M%SZ)'" -o ./$(EXECUTABLE)_$(VERSION)_arm64_darwin ./cmd/$(EXECUTABLE) -build-linux: +build-linux: ## Make Linux binary (ARM/AMD64) env GOOS=linux GOARCH=amd64 go build -ldflags "-s -w -X 'github.com/NeonSludge/ansible-dns-inventory/internal/build.Version=$(VERSION)' -X 'github.com/NeonSludge/ansible-dns-inventory/internal/build.Time=$(shell date -u +%Y%m%dT%H%M%SZ)'" -o ./$(EXECUTABLE)_$(VERSION)_amd64_linux ./cmd/$(EXECUTABLE) env GOOS=linux GOARCH=arm64 go build -ldflags "-s -w -X 'github.com/NeonSludge/ansible-dns-inventory/internal/build.Version=$(VERSION)' -X 'github.com/NeonSludge/ansible-dns-inventory/internal/build.Time=$(shell date -u +%Y%m%dT%H%M%SZ)'" -o ./$(EXECUTABLE)_$(VERSION)_arm64_linux ./cmd/$(EXECUTABLE) -build: build-linux build-darwin build-windows +build: build-linux build-darwin build-windows ## Make all binaries + +test-dns: _init build ## Run DNS tests + @echo " " + @COMPOSE_PROFILES=dns docker compose -f docker/docker-compose.yml up -d + @sleep 5 + @chmod +x ./$(EXECUTABLE)_$(VERSION)_* + @echo " " + @echo "------------- RUN TESTS------------------" + @docker compose -f docker/docker-compose.yml exec -it multitool-dns /bin/bash -c "/app/$(EXECUTABLE)_$(VERSION)_$(platform)64_linux -tree" + $(call cleanup) + +test-etcd: _init build ## Run etcd tests + @echo " " + @COMPOSE_PROFILES=etcd docker compose -f docker/docker-compose.yml up -d + @sleep 5 + @chmod +x ./$(EXECUTABLE)_$(VERSION)_* + @chmod +x docker/config/etcd/init.sh + @bash docker/config/etcd/init.sh + @echo " " + @echo "------------- RUN TESTS------------------" + @docker compose -f docker/docker-compose.yml exec -it multitool-etcd /bin/bash -c "/app/$(EXECUTABLE)_$(VERSION)_$(platform)64_linux -tree" + $(call cleanup) + +test: test-dns test-etcd ## Run all tests + +image: build ## Build image + @echo " " + +help: + $(call greeting) + grep -E '(^[a-z].*[^:]\s*##)|(^##)' $(MAKEFILE_LIST) | \ + perl -pe "s/Makefile://" | perl -pe "s/^##\s*//" | \ + awk ' \ + BEGIN { FS = ":.*##" } \ + $$2 { printf "\033[32m%-30s\033[0m %s\n", $$1, $$2 } \ + !$$2 { printf " \033[33m%-30s\033[0m\n", $$1 } \ + ' + +## make exec="command": ## Выполнить команду в контейнере +_default: + if [ '$(exec)' ]; then \ + COMPOSE_PROFILES=tools docker compose -f docker/docker-compose.yml up -d; \ + docker compose exec -it -f docker/docker-compose.yml multitool-dns -v "$(CUR_DIR):/app" exec -it -c '$(exec)'; \ + else \ + make help; \ + fi \ No newline at end of file diff --git a/docker/Dockerfile.bind9 b/docker/Dockerfile.bind9 new file mode 100644 index 0000000..4be5aa9 --- /dev/null +++ b/docker/Dockerfile.bind9 @@ -0,0 +1,18 @@ +#Base Bind9 Image +FROM internetsystemsconsortium/bind9:9.18 + +#Install required tools and dependencies +RUN apt update && apt install -y \ + bind9-doc \ + dnsutils \ + geoip-bin \ + mariadb-server \ + net-tools + +# Expose Ports +EXPOSE 53/tcp +EXPOSE 53/udp +EXPOSE 953/tcp + +# Start the Name Service +CMD ["/usr/sbin/named", "-g", "-c", "/etc/bind/named.conf", "-u", "bind"] \ No newline at end of file diff --git a/docker/config/dns/ansible-dns-inventory.infra.local b/docker/config/dns/ansible-dns-inventory.infra.local new file mode 100644 index 0000000..0d0be70 --- /dev/null +++ b/docker/config/dns/ansible-dns-inventory.infra.local @@ -0,0 +1,59 @@ +$TTL 1d +; +;default expiration time (in seconds) of all RRs without their own +;TTL value +@ IN SOA ns1.infra.local. root.infra.local. ( + 10 ; Serial + 1d ; Refresh + 1h ; Retry + 1w ; Expire + 1h) ; Negative Cache TTL +; name servers - NS records IN + NS ns1.infra.local. ; name servers - A records +ns1 A 172.38.0.5 + TXT "OS=linux;ENV=dev;ROLE=platform;SRV=nameservers;VARS=NS=first,START=true" +etcd-1 A 172.38.0.8 + TXT "OS=linux;ENV=dev;ROLE=platform;SRV=dbs;VARS=ETCD_VARS=first,START=true" +etcd-2 A 172.38.0.9 + TXT "OS=linux;ENV=dev;ROLE=platform;SRV=dbs;VARS=ETCD_VARS=second,START=true" +etcd-3 A 172.38.0.10 + TXT "OS=linux;ENV=dev;ROLE=platform;SRV=dbs;VARS=ETCD_VARS=third,START=true" +bastion A 172.38.0.20 + TXT "OS=linux;ENV=dev;ROLE=platform;SRV=tools;VARS=key1=value1,key2=value2" +master-1 A 172.38.0.21 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=controlplane;VARS=key1=value1,key2=value2" +master-2 A 172.38.0.22 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=controlplane;VARS=key1=value1,key2=value2" +master-3 A 172.38.0.23 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=controlplane;VARS=key1=value1,key2=value2" +ingress-1 A 172.38.0.25 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=ingresses;VARS=key1=value1,key2=value2" +ingress-2 A 172.38.0.26 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=ingresses;VARS=key1=value1,key2=value2" +ingress-3 A 172.38.0.27 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=ingresses;VARS=key1=value1,key2=value2" +worker-1 A 172.38.0.30 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=workers;VARS=key1=value1,key2=value2" +worker-2 A 172.38.0.31 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=workers;VARS=key1=value1,key2=value2" +worker-3 A 172.38.0.32 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=workers;VARS=key1=value1,key2=value2" +worker-4 A 172.38.0.33 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=workers;VARS=key1=value1,key2=value2" +worker-5 A 172.38.0.34 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=workers;VARS=key1=value1,key2=value2" +observability-1 A 172.38.0.50 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=observability;VARS=key1=value1,key2=value2" +observability-2 A 172.38.0.51 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=observability;VARS=key1=value1,key2=value2" +observability-3 A 172.38.0.52 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=observability;VARS=key1=value1,key2=value2" +logging-1 A 172.38.0.100 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=logs;VARS=key1=value1,key2=value2" +logging-2 A 172.38.0.101 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=logs;VARS=key1=value1,key2=value2" +logging-3 A 172.38.0.102 + TXT "OS=linux;ENV=dev;ROLE=k8s;SRV=logs;VARS=key1=value1,key2=value2" +multitool A 172.38.0.250 + TXT "OS=linux;ENV=dev;ROLE=platform;SRV=tools;VARS=key1=value1,key2=value2" + diff --git a/docker/config/dns/named.conf.local b/docker/config/dns/named.conf.local new file mode 100644 index 0000000..42ef92a --- /dev/null +++ b/docker/config/dns/named.conf.local @@ -0,0 +1,4 @@ +zone "infra.local" { +type master; +file "/etc/bind/zones/ansible-dns-inventory.infra.local"; +}; \ No newline at end of file diff --git a/docker/config/dns/named.conf.options b/docker/config/dns/named.conf.options new file mode 100644 index 0000000..ca97338 --- /dev/null +++ b/docker/config/dns/named.conf.options @@ -0,0 +1,9 @@ +options { + directory "/var/cache/bind"; + recursion yes; + listen-on { any; }; + forwarders { + 8.8.8.8; + 8.8.4.4; + }; +}; \ No newline at end of file diff --git a/docker/config/etcd/init.sh b/docker/config/etcd/init.sh new file mode 100755 index 0000000..3fcd8dc --- /dev/null +++ b/docker/config/etcd/init.sh @@ -0,0 +1,31 @@ +#!/bin/bash +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./ns1.infra.local/0 "OS=linux;ENV=dev;ROLE=platform;SRV=nameservers;VARS=NS=first,START=true" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./etcd-1.infra.local/0 "OS=linux;ENV=dev;ROLE=platform;SRV=dbs;VARS=ETCD_VARS=first,START=true" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./etcd-2.infra.local/0 "OS=linux;ENV=dev;ROLE=platform;SRV=dbs;VARS=ETCD_VARS=first,START=true" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./etcd-3.infra.local/0 "OS=linux;ENV=dev;ROLE=platform;SRV=dbs;VARS=ETCD_VARS=first,START=true" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./bastion.infra.local/0 "OS=linux;ENV=dev;ROLE=platform;SRV=tools;VARS=key1=value1,key2=value2" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./master-1.infra.local/0 "OS=linux;ENV=dev;ROLE=k8s;SRV=controlplane;VARS=key1=value1,key2=value2" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./master-2.infra.local/0 "OS=linux;ENV=dev;ROLE=k8s;SRV=controlplane;VARS=key1=value1,key2=value2" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./master-3.infra.local/0 "OS=linux;ENV=dev;ROLE=k8s;SRV=controlplane;VARS=key1=value1,key2=value2" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./ingress-1.infra.local/0 "OS=linux;ENV=dev;ROLE=k8s;SRV=ingresses;VARS=key1=value1,key2=value2" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./ingress-2.infra.local/0 "OS=linux;ENV=dev;ROLE=k8s;SRV=ingresses;VARS=key1=value1,key2=value2" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./ingress-3.infra.local/0 "OS=linux;ENV=dev;ROLE=k8s;SRV=ingresses;VARS=key1=value1,key2=value2" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./worker-1.infra.local/0 "OS=linux;ENV=dev;ROLE=k8s;SRV=workers;VARS=key1=value1,key2=value2" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./worker-2.infra.local/0 "OS=linux;ENV=dev;ROLE=k8s;SRV=workers;VARS=key1=value1,key2=value2" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./observability-1.infra.local/0 "OS=linux;ENV=dev;ROLE=k8s;SRV=observability;VARS=key1=value1,key2=value2" +docker compose -f docker/docker-compose.yml exec -it etcd-1 \ + etcdctl put ANSIBLE_INVENTORY/infra.local./logging-1.infra.local/0 "OS=linux;ENV=dev;ROLE=k8s;SRV=logs;VARS=key1=value1,key2=value2" \ No newline at end of file diff --git a/docker/config/inventory/ansible-dns-inventory.yaml b/docker/config/inventory/ansible-dns-inventory.yaml new file mode 100644 index 0000000..220458a --- /dev/null +++ b/docker/config/inventory/ansible-dns-inventory.yaml @@ -0,0 +1,45 @@ +# Datasource type. Environment variable: ADI_DATASOURCE +datasource: "dns" +dns: + # DNS datasource configuration. + server: "172.38.0.5:53" + timeout: "120s" + zones: + - infra.local. +etcd: + endpoints: + - 172.38.0.8:2379 + - 172.38.0.9:2379 + - 172.38.0.10:2379 + tls: + insecure: true +# Host record parsing configuration. +txt: + # Key/value pair parsing configuration. + kv: + # Separator between k/v pairs found in TXT records. Environment variable: ADI_TXT_KV_SEPARATOR + separator: ";" + # Separator between a key and a value. Environment variable: ADI_TXT_KV_EQUALSIGN + equalsign: "=" + # Host variables parsing configuration. + vars: + # Enable host variables support. Environment variable: ADI_TXT_VARS_ENABLED + enabled: false + # Separator between k/v pairs found in the host variables attribute. Environment variable: ADI_TXT_VARS_SEPARATOR + separator: "," + # Separator between a key and a value. Environment variable: ADI_TXT_VARS_EQUALSIGN + equalsign: "=" + # Host attributes parsing configuration. + keys: + # Separator between elements of an Ansible group name. Environment variable: ADI_TXT_KEYS_SEPARATOR + separator: "_" + # Key name of the attribute containing the host operating system identifier. Environment variable: ADI_TXT_KEYS_OS + os: "OS" + # Key name of the attribute containing the host environment identifier. Environment variable: ADI_TXT_KEYS_ENV + env: "ENV" + # Key name of the attribute containing the host role identifier. Environment variable: ADI_TXT_KEYS_ROLE + role: "ROLE" + # Key name of the attribute containing the host service identifier. Environment variable: ADI_TXT_KEYS_SRV + srv: "SRV" + # Key name of the attribute containing the host variables. Environment variable: ADI_TXT_KEYS_VARS + vars: "VARS" diff --git a/docker/config/inventory/ansible-etcd-inventory.yaml b/docker/config/inventory/ansible-etcd-inventory.yaml new file mode 100644 index 0000000..ba8a8ef --- /dev/null +++ b/docker/config/inventory/ansible-etcd-inventory.yaml @@ -0,0 +1,50 @@ +# Datasource type. Environment variable: ADI_DATASOURCE +datasource: "etcd" +dns: + # DNS datasource configuration. + server: "172.38.0.5:53" + timeout: "120s" + zones: + - infra.local. +etcd: + endpoints: + - 172.38.0.8:2379 + - 172.38.0.9:2379 + - 172.38.0.10:2379 + prefix: "ANSIBLE_INVENTORY" + zones: + - infra.local. + tls: + enabled: false + insecure: true + +# txt: +# # Key/value pair parsing configuration. +# kv: +# # Separator between k/v pairs found in TXT records. Environment variable: ADI_TXT_KV_SEPARATOR +# separator: ";" +# # Separator between a key and a value. Environment variable: ADI_TXT_KV_EQUALSIGN +# equalsign: "=" +# # Host variables parsing configuration. +# vars: +# # Enable host variables support. Environment variable: ADI_TXT_VARS_ENABLED +# enabled: false +# # Separator between k/v pairs found in the host variables attribute. Environment variable: ADI_TXT_VARS_SEPARATOR +# separator: "," +# # Separator between a key and a value. Environment variable: ADI_TXT_VARS_EQUALSIGN +# equalsign: "=" +# # Host attributes parsing configuration. +# keys: +# # Separator between elements of an Ansible group name. Environment variable: ADI_TXT_KEYS_SEPARATOR +# separator: "_" +# # Key name of the attribute containing the host operating system identifier. Environment variable: ADI_TXT_KEYS_OS +# os: "OS" +# # Key name of the attribute containing the host environment identifier. Environment variable: ADI_TXT_KEYS_ENV +# env: "ENV" +# # Key name of the attribute containing the host role identifier. Environment variable: ADI_TXT_KEYS_ROLE +# role: "ROLE" +# # Key name of the attribute containing the host service identifier. Environment variable: ADI_TXT_KEYS_SRV +# srv: "SRV" +# # Key name of the attribute containing the host variables. Environment variable: ADI_TXT_KEYS_VARS +# vars: "VARS" + diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..d5c4328 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,134 @@ +version: '3.9' + +x-logging: &default-local + options: + max-size: "30M" + max-file: "5" + labels: "development" + driver: "json-file" + +x-variables: + multitool_settings: &multitool_settings + container_name: multitool + image: wbitt/network-multitool + volumes: + - ../:/app + flag_initial_cluster_token: &flag_initial_cluster_token '--initial-cluster-token=mys3cr3ttok3n' + common_settings: &common_settings + image: quay.io/coreos/etcd:v3.5.9 + profiles: ["etcd"] + entrypoint: /usr/local/bin/etcd + ports: + - 2379 + +networks: + public: + driver: bridge + ipam: + config: + - subnet: 172.38.0.0/24 + gateway: 172.38.0.1 + + +services: + dns-server: + platform: linux/amd64 + container_name: dns-server + build: + context: . + dockerfile: Dockerfile.bind9 + profiles: ["dns"] + image: local-bind9-server:1.0 + restart: always + logging: *default-local + volumes: + - ./config/dns/named.conf.options:/etc/bind/named.conf.options + - ./config/dns/named.conf.local:/etc/bind/named.conf.local + - ./config/dns/ansible-dns-inventory.infra.local:/etc/bind/zones/ansible-dns-inventory.infra.local + networks: + public: + ipv4_address: 172.38.0.5 + + multitool-dns: + <<: *multitool_settings + profiles: ["dns", "tools"] + networks: + public: + ipv4_address: 172.38.0.250 + environment: + - HTTP_PORT=1180 + - HTTPS_PORT=11443 + - ADI_CONFIG_FILE=/app/docker/config/inventory/ansible-dns-inventory.yaml + + multitool-etcd: + <<: *multitool_settings + profiles: ["etcd", "tools"] + networks: + public: + ipv4_address: 172.38.0.249 + environment: + - HTTP_PORT=1180 + - HTTPS_PORT=11443 + - ADI_CONFIG_FILE=/app/docker/config/inventory/ansible-etcd-inventory.yaml + + + etcd-1: + <<: *common_settings + container_name: etcd-1 + logging: *default-local + command: + - '--name=etcd-1' + - '--initial-advertise-peer-urls=http://etcd-1:2380' + - '--listen-peer-urls=http://0.0.0.0:2380' + - '--listen-client-urls=http://0.0.0.0:2379' + - '--advertise-client-urls=http://etcd-1:2379' + - '--heartbeat-interval=250' + - '--election-timeout=1250' + - '--initial-cluster=etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380' + - '--initial-cluster-state=new' + - *flag_initial_cluster_token + networks: + public: + ipv4_address: 172.38.0.8 + + etcd-2: + <<: *common_settings + container_name: etcd-2 + logging: *default-local + command: + - '--name=etcd-2' + - '--initial-advertise-peer-urls=http://etcd-2:2380' + - '--listen-peer-urls=http://0.0.0.0:2380' + - '--listen-client-urls=http://0.0.0.0:2379' + - '--advertise-client-urls=http://etcd-2:2379' + - '--heartbeat-interval=250' + - '--election-timeout=1250' + - '--initial-cluster=etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380' + - '--initial-cluster-state=new' + - *flag_initial_cluster_token + networks: + public: + ipv4_address: 172.38.0.9 + + etcd-3: + <<: *common_settings + container_name: etcd-3 + logging: *default-local + command: + - '--name=etcd-3' + - '--initial-advertise-peer-urls=http://etcd-3:2380' + - '--listen-peer-urls=http://0.0.0.0:2380' + - '--listen-client-urls=http://0.0.0.0:2379' + - '--advertise-client-urls=http://etcd-3:2379' + - '--heartbeat-interval=250' + - '--election-timeout=1250' + - '--initial-cluster=etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380' + - '--initial-cluster-state=new' + - *flag_initial_cluster_token + networks: + public: + ipv4_address: 172.38.0.10 + + +# docker compose exec -it etcd-1 etcdctl --cluster=true endpoint health +