Skip to content

Commit f0b0bb4

Browse files
author
Uzziah Eyee
committed
Closes eyeezzi#1
The problem was a version incompatibility. fluentd v1.4-2 now requires specifying a ‘root’ user in the log-shipper Dockerfile. Also updated readmes for clarity.
1 parent 3960768 commit f0b0bb4

File tree

6 files changed

+90
-45
lines changed

6 files changed

+90
-45
lines changed

README.md

+16-14
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,40 @@ Monitoring containerized microservices with a centralized logging architecture.
44

55
## Dependencies
66

7-
- Docker Compose v1.22.0
7+
- Docker Compose v1.23.2
88

99
## Setup
1010

11-
1. For each microservice, rename `example.env` to `.env` and supply the needed secrets.
11+
1. Signup with an ELK SaaS provider like [Logz.io](logz.io) to obtain an authentication token. Then for each microservice, rename `example.env` to `.env` and supply the needed secrets.
1212

13-
docker-compose up -d
14-
15-
2. Then log into [Logz.io](logz.io) or your preferred ELK SaaS to view your microservices logs.
13+
2. Run the following commands.
1614

15+
docker-compose build --pull
16+
docker-compose up -d --force-recreate
17+
18+
3. Then log into your ELK SaaS and view your microservices logs.
1719

1820
## Project Documentation
1921

2022
### System Architecture
2123

2224
![](docs/container-architecture.svg)
2325

24-
I wrote an accompanying [Medium article]() detailing the rationale for this architecture.
26+
I wrote an accompanying [article](https://hackernoon.com/monitoring-containerized-microservices-with-a-centralized-logging-architecture-ba6771c1971a) explaining this architecture.
2527

26-
## Developer Notes
28+
## Notes
2729

2830
### Docker Networking
2931

30-
Containers run isolated by default. For them to comunicate with one another, you need to place them on the same network. We do this using Docker Compose
32+
By default each containerized process runs in an isolated network namespace. For inter-container communication, place them in the same network namespace...as seen in *docker-compose.yml*.
3133

3234
### Best practices
3335

34-
1. You can pass secrets for a microservice using the `env_file` attribute in `docker-compose.yml`
35-
2. Microservices can communicate using their service names if they are in the same docker `network`
36+
1. You can pass secrets for a microservice using the `env_file` attribute in *docker-compose.yml*.
37+
2. Microservices can communicate using their service names if they are in the same docker network.
38+
39+
### Improvement Considerations
3640

37-
### Known issues
41+
1. **Name Duplication:** The value of the `API_SERVER_ADDRESS` variable in *user-simulator/.env* depends on the service name `api-server` specified in *docker-compose.yml*. If we rename the service, we must also change the variable. Is there a way to make this DRY?
3842

39-
1. Some values like service hostnames are specified in 2 places: the docker-compose file, and the service-specific .env file (like for the API BaseURL)
40-
2. You have to install a plugin for the ELK-service (logz.io) in the fluentd shipper container
41-
3. Then you have to configure fluentd plugin with your credentials from the ELK service.
43+
2. In the log-shipper container, I had to install a logz.io-specific plugin. Can't this step be eliminated since fluentd is capable of connecting to https endpoints without plugins?

api-server/README.md

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
## Commands for running app in container
1+
## Running app in standalone container
22

3-
1. Build image from *Dockerfile*
3+
1. Build and run image.
44

5-
docker build -t eyeezzi/horus-api-server .
6-
7-
2. Start container from image. Note the *public:internal* port mapping
5+
docker build --no-cache -t eyeezzi/horus-api-server .
6+
docker run -d --env-file=.env -p 5000:80 eyeezzi/horus-api-server
87

9-
docker run -d -p 5000:80 eyeezzi/horus-api-server
8+
> Note: The server runs on port `80`, but we expose it as `5000` on the host in order to avoid privilege issues with binding to low number ports. Knowledge bit: [port-mapping cannot be set in dockerfile.](https://stackoverflow.com/questions/36153025/is-it-possible-to-set-docker-port-mappings-to-host-in-dockerfile)
109

11-
3. Get the container ID and verify port mapping
10+
2. View the logs generated by the app
1211

1312
docker ps
13+
docker logs -f <container-name>
1414

15-
4. Tail the logs from the container
16-
17-
docker logs -f <CONTAINER_ID>
15+
# From another terminal on the host machine, test the server
16+
curl http://localhost:5000/api/v1/tokens

log-shipper/Dockerfile

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
# Aparently the onbuild variant is better for customization, sadly, it is errors on build.
2-
FROM fluent/fluentd:v0.12
1+
FROM fluent/fluentd:v1.4-2
32

4-
# We need to install a plugin for logz.io output :(
5-
RUN apk add --update --virtual .build-deps \
3+
# Use root account to use apk
4+
USER root
5+
6+
# We need to install a plugin for logz.io output
7+
RUN apk add --no-cache --update --virtual .build-deps \
68
sudo build-base ruby-dev \
79
&& sudo gem install \
810
fluent-plugin-logzio \
@@ -13,5 +15,8 @@ RUN apk add --update --virtual .build-deps \
1315

1416
# Then copy-over our custom config file
1517
COPY fluentd.conf /fluentd/etc/
18+
ENV FLUENTD_CONF="fluentd.conf"
19+
20+
USER fluent
1621

17-
ENV FLUENTD_CONF="fluentd.conf"
22+
# reference: https://hub.docker.com/r/fluent/fluentd

log-shipper/README.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## Notes
2+
3+
### Local setup
4+
5+
1. Build and run the container.
6+
7+
docker build --no-cache -t eyeezzi/horus-log-shipper .
8+
docker run -d --env-file=.env eyeezzi/horus-log-shipper
9+
// tail the logs to see any incoming messages
10+
docker logs -f <container-name>
11+
12+
2. From another terminal test sending logs to the shipper. You should see the new incoming message in the log tail and also on your ELK SaaS dashboard.
13+
14+
curl -X POST -H "Content-Type: application/json" -d '{"msg":"this is a test message"}' http://localhost:24224

log-shipper/fluentd.conf

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616
output_include_tags true
1717
http_idle_timeout 10
1818
<buffer>
19-
@type memory
20-
flush_thread_count 4
21-
flush_interval 3s
22-
chunk_limit_size 16m # Logz.io bulk limit is decoupled from chunk_limit_size. Set whatever you want.
23-
queue_limit_length 4096
19+
@type memory
20+
flush_thread_count 4
21+
flush_interval 3s
22+
chunk_limit_size 16m # Logz.io bulk limit is decoupled from chunk_limit_size. Set whatever you want.
23+
queue_limit_length 4096
2424
</buffer>
2525
</match>
2626

27-
# # Output every log stream tagged with a 'docker.' prefix to stdout
27+
# Output every log stream tagged with a 'docker.' prefix to stdout
2828
# <match docker.*>
2929
# @type stdout
3030
# </match>

user-simulator/README.md

+35-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,42 @@
1-
## Commands for running app in container
1+
## Running app in standalone container
22

3-
1. Build image from *Dockerfile*
3+
1. Rename *example.env* to *.env* and supply the `API_SERVER_ADDRESS`. Then run the following commands
44

5-
docker build -t eyeezzi/horus-user-simulator .
6-
7-
2. Start container from image. Note the *public:internal* port mapping
5+
> If the API Server is running in another local container with an exposed port, then run this container in the `host` network so it can access the API Server.
86

9-
docker run -d eyeezzi/horus-user-simulator
7+
docker build --no-cache -t eyeezzi/horus-user-simulator .
8+
docker run -d --env-file=.env eyeezzi/horus-user-simulator
9+
10+
# if api server is running on localhost:5000
11+
docker run -d --env-file=.env --network=host eyeezzi/horus-user-simulator
1012

11-
3. Get the container ID and verify port mapping
13+
2. Verify that this container is generating logs.
1214

13-
docker ps
15+
docker ps
16+
docker logs -f <container-name>
1417

15-
4. Tail the logs from the container
18+
## Notes
1619

17-
docker logs -f <CONTAINER_ID>
20+
### Useful Commands
21+
22+
- To see all networks on the host
23+
24+
docker network ls
25+
26+
- To see which network a container is on
27+
28+
docker inspect <container-name> -f "{{json .NetworkSettings.Networks }}"
29+
30+
- To disconnect a container from a network
31+
32+
docker network disconnect <network-name> <container-name>
33+
34+
- To connect a container to a network
35+
36+
docker network connect <network-name> <container-name>
37+
38+
> Docker seems to have a bug where a container cannot be connected to the `host` network. See this [issue](https://github.com/awslabs/aws-sam-cli/issues/669).
39+
40+
- To list all the containers on a network.
41+
42+
docker network inspect <network-name> -f "{{json .Containers }}"

0 commit comments

Comments
 (0)