diff --git a/.circleci/config.yml b/.circleci/config.yml index 58fb87c..3f8a302 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -64,10 +64,14 @@ jobs: command: docker login -u ${DOCKER_USER} -p ${DOCKER_PASS} - run: name: docker build - command: docker build -t nicholasjackson/fake-service:${CIRCLE_TAG} . + command: | + docker build -t nicholasjackson/fake-service:${CIRCLE_TAG} . + docker build -t nicholasjackson/fake-service:vm-${CIRCLE_TAG} -f Dockerfile-VM . - run: name: docker push - command: docker push nicholasjackson/fake-service:${CIRCLE_TAG} + command: | + docker push nicholasjackson/fake-service:${CIRCLE_TAG} + docker push nicholasjackson/fake-service:vm-${CIRCLE_TAG} publish-github-release: docker: diff --git a/Dockerfile-VM b/Dockerfile-VM new file mode 100644 index 0000000..4594693 --- /dev/null +++ b/Dockerfile-VM @@ -0,0 +1,25 @@ +# This image contains Fake Service Consul and Envoy, it can be used to simulate a Virtual Machine containing the Consul Agent +# and Envoy running as Daemon processes. +FROM nicholasjackson/consul-envoy:v1.6.1-v0.10.0 + +# Setup bash and supervisord etc +RUN apk add --update bash supervisor curl vim jq +RUN sed -i 's/\/bin\/ash/\/bin\/bash/g' /etc/passwd + +RUN mkdir -p /etc/supervisor.d/ + +COPY entrypoint.sh /entrypoint.sh + +# Setup the supervisor d file +COPY fake-service.ini /etc/supervisor.d/fake-service.ini +RUN chmod +x /entrypoint.sh + +# Run supervisord +RUN sed -i 's/;nodaemon=false/nodaemon=true/g' /etc/supervisord.conf + +# add fake service +RUN mkdir app +COPY ./bin/fake-service-linux /app/fake-service + +ENTRYPOINT ["/usr/bin/supervisord"] +CMD ["-c", "/etc/supervisord.conf"] diff --git a/Makefile b/Makefile index aa2dde5..abf76f3 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -version=v0.7.1 +version=v0.7.5 protos: protoc -I grpc/protos/ grpc/protos/api.proto --go_out=plugins=grpc:grpc/api @@ -20,6 +20,7 @@ build_local: build_ui build_docker: build_linux docker build -t nicholasjackson/fake-service:${version} . + docker build -t nicholasjackson/fake-service:vm-${version} -f Dockerfile-VM . run_downstream: TRACING_ZIPKIN=/dev/null NAME=web HTTP_CLIENT_KEEP_ALIVES=false UPSTREAM_WORKERS=2 UPSTREAM_URIS="http://localhost:9091,grpc://localhost:9093" go run main.go diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..4392478 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +# Wait until Consul can be contacted +until consul members; do + echo "Waiting for Consul to start" + sleep 1 +done + +# If we do not need to register a service just run the command +if [ ! -z "$SERVICE_CONFIG" ]; then + # register the service with consul + echo "Registering service with consul $SERVICE_CONFIG" + consul services register ${SERVICE_CONFIG} + + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo "### Error writing service config: $file ###" + cat $file + echo "" + exit 1 + fi +fi + +# register any central config from individual files +if [ ! -z "$CENTRAL_CONFIG" ]; then + IFS=';' read -r -a configs <<< ${CENTRAL_CONFIG} + + for file in "${configs[@]}"; do + echo "Writing central config $file" + consul config write $file + + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo "### Error writing central config: $file ###" + cat $file + echo "" + exit 1 + fi + done +fi + +# register any central config from a folder +if [ ! -z "$CENTRAL_CONFIG_DIR" ]; then + for file in `ls -v $CENTRAL_CONFIG_DIR/*`; do + echo "Writing central config $file" + consul config write $file + echo "" + + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo "### Error writing central config: $file ###" + cat $file + echo "" + exit 1 + fi + done +fi diff --git a/examples/docker-compose-consul/central_config/api-defaults.hcl b/examples/docker-compose-consul/central_config/api-defaults.hcl new file mode 100644 index 0000000..a6d67bb --- /dev/null +++ b/examples/docker-compose-consul/central_config/api-defaults.hcl @@ -0,0 +1,8 @@ +Kind = "service-defaults" +Name = "api" + +Protocol = "http" + +MeshGateway = { + mode = "local" +} diff --git a/examples/docker-compose-consul/central_config/web-defaults.hcl b/examples/docker-compose-consul/central_config/web-defaults.hcl new file mode 100644 index 0000000..1e79d94 --- /dev/null +++ b/examples/docker-compose-consul/central_config/web-defaults.hcl @@ -0,0 +1,8 @@ +Kind = "service-defaults" +Name = "web" + +Protocol = "http" + +MeshGateway = { + mode = "local" +} diff --git a/examples/docker-compose-consul/consul_config/config.hcl b/examples/docker-compose-consul/consul_config/config.hcl new file mode 100644 index 0000000..1bb938a --- /dev/null +++ b/examples/docker-compose-consul/consul_config/config.hcl @@ -0,0 +1,23 @@ +data_dir = "/tmp/" +log_level = "DEBUG" + +datacenter = "dc1" + +server = true + +bootstrap_expect = 1 +ui = true + +bind_addr = "0.0.0.0" +client_addr = "0.0.0.0" + +ports { + grpc = 8502 +} + +connect { + enabled = true +} + +advertise_addr = "10.5.0.2" +enable_central_service_config = true diff --git a/examples/docker-compose-consul/docker-compose.yml b/examples/docker-compose-consul/docker-compose.yml new file mode 100644 index 0000000..a003957 --- /dev/null +++ b/examples/docker-compose-consul/docker-compose.yml @@ -0,0 +1,60 @@ +--- + +version: "3.3" + +services: + + consul: + image: consul:1.6.1 + command: ["consul", "agent", "-config-file=/config/config.hcl", "-config-dir=/config"] + volumes: + - "./consul_config:/config" + ports: + - 8500:8500 + networks: + vpcbr: + ipv4_address: 10.5.0.2 + + # Define web service and envoy sidecar proxy + web: + image: nicholasjackson/fake-service:vm-v0.7.5 + environment: + LISTEN_ADDR: 0.0.0.0:9090 + UPSTREAM_URIS: "http://localhost:9091" + MESSAGE: "Hello World" + NAME: "web" + SERVER_TYPE: "http" + CONSUL_SERVER: 10.5.0.2 + CENTRAL_CONFIG_DIR: /central + SERVICE_ID: "web-v1" + volumes: + - "./service_config/web_v1.hcl:/config/web_v1.hcl" + - "./central_config:/central" + ports: + - "9090:9090" + networks: + vpcbr: + ipv4_address: 10.5.0.3 + + # Define web service and envoy sidecar proxy + api: + image: nicholasjackson/fake-service:vm-v0.7.5 + environment: + LISTEN_ADDR: 0.0.0.0:9090 + MESSAGE: "Hello World" + NAME: "api" + SERVER_TYPE: "http" + CONSUL_SERVER: 10.5.0.2 + SERVICE_ID: "api-v1" + volumes: + - "./service_config/api_v1.hcl:/config/api_v1.hcl" + networks: + vpcbr: + ipv4_address: 10.5.0.4 + +networks: + vpcbr: + driver: bridge + ipam: + config: + - subnet: 10.5.0.0/16 diff --git a/examples/docker-compose-consul/service_config/api_v1.hcl b/examples/docker-compose-consul/service_config/api_v1.hcl new file mode 100644 index 0000000..16561c1 --- /dev/null +++ b/examples/docker-compose-consul/service_config/api_v1.hcl @@ -0,0 +1,11 @@ +service { + name = "api" + id = "api-v1" + port = 9090 + + # Required in order to allow registration of a sidecar + connect { + sidecar_service { + } + } +} diff --git a/examples/docker-compose-consul/service_config/web_v1.hcl b/examples/docker-compose-consul/service_config/web_v1.hcl new file mode 100644 index 0000000..0d40da0 --- /dev/null +++ b/examples/docker-compose-consul/service_config/web_v1.hcl @@ -0,0 +1,18 @@ +service { + name = "web" + id = "web-v1" + port = 9090 + + connect { + sidecar_service { + + proxy { + upstreams { + destination_name = "api" + local_bind_address = "127.0.0.1" + local_bind_port = 9091 + } + } + } + } +} diff --git a/fake-service.ini b/fake-service.ini new file mode 100644 index 0000000..9df7bdf --- /dev/null +++ b/fake-service.ini @@ -0,0 +1,21 @@ +[program:consul] +command=/usr/local/bin/consul agent -config-dir /config -client 0.0.0.0 -retry-join %(ENV_CONSUL_SERVER)s -bind 0.0.0.0 -grpc-port=8502 -data-dir /tmp -hcl "enable_central_service_config = true" +autorestart=true +priority=100 + +[program:envoy] +command=/bin/bash -c "/usr/local/bin/consul connect envoy -sidecar-for %(ENV_SERVICE_ID)s -envoy-binary /usr/local/bin/envoy" +autorestart=true +startretries=300 +priority=200 + +[program:fake-service] +command=/app/fake-service +autorestart=true +startretries=300 +priority=300 + +[program:register-service] +command=/entrypoint.sh +autorestart=false +priority=400