diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..520b5a6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +# syntax=docker/dockerfile:1 + +FROM golang:1.16-alpine + +WORKDIR /app + +COPY go.mod ./ +COPY go.sum ./ +RUN go get github.com/prometheus/client_golang/prometheus/promhttp +RUN go mod download + +COPY *.go ./ + +RUN go build -o /go-app +EXPOSE 8080 + +CMD [ "/go-app" ] \ No newline at end of file diff --git a/README.md b/README.md index dd49286..d2bd1ae 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,45 @@ # Devops Test -### Overview -This is an application that is a dummy webservice that returns the -last update time. The last updated time is cached in redis and -resets every 5 seconds. It has a single '/' endpoint. The redis -address is passed in through the environment. - -NOTE: The following tasks should take no more than 1 hour total. - -### Tasks -1. create Dockerfile for this application -2. create docker-compose.yaml to replicate a full running environment -so that a developer can run the entire application locally without having -to run any dependencies (i.e. redis) in a separate process. -3. explain how you would monitor this application in production. Please -write code to do the monitoring. - -Please fork this repository and make a pull request with your changes. +### Preparation +1. Rename file .env and change IP address +2. Add IP from Vault or change in the file _prometheus/prometheus.yml_ + +### Run monitoring resources +1. We need to create infrastructure with to commands +Create __Prometheus__, __Prometheus gateway__, __Grafana__ +~~~ +# sudo docker-compose -f gocker-compose.yml up -d +~~~ +Create __Go application__ +~~~ +# sudo docker-compose -f go-compose.yml up -d +~~~ + +2. Check installation +__Prometheus__ {IP address}:9090 +__Prometheus gateway__ {IP address}:9091 +__Grafana__ {IP address}:3000 +__Go application__ {IP address}:8080 + +3. Check targets +Go to __Prometheus -> targets__ +```State = UP``` - it is normal +For __Go application__ ```State = Down``` - also normal, if error ```strconv.ParseFloat: parsing "world:": invalid syntax``` + +![Targets](img/prom_targets.jpg) + +4. Check __Prometheus pushgatway__ +Sent from console of PC +~~~ +echo -e 'job_successful 100.0\njob_failed 0.0' | curl --data-binary @- http://localhost:9091/metrics/job/go_app_job +~~~ + +5. Grafana + +![Targets](img/Grafana_dash.jpg) + + +### P.S. What next? + +We could proceed to add blackbox for the monitoring of the web (like Go application too) +Can add alertmanager and setup Jenkins for starting of jobs for a schedule. We could add at this job some variables which send to the pushgateway info about application status, failes and a start/end time of job diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..47e5f1a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,65 @@ +version: "3" +services: + mongodb: + image: mongo + ports: + - "27017:27017" + container_name: bookmark-mongodb + networks: + - monitornet + node: + image: node:8-alpine + networks: + - monitornet + volumes: + - ./web:/web + - /tmp:/tmp + grafana: + image: grafana/grafana:5.1.0 + volumes: + - grafana_data:/var/lib/grafana + environment: + - GF_SECURITY_ADMIN_USER=admin + - GF_SECURITY_ADMIN_PASSWORD=adminpass + ports: + - "3000:3000" + container_name: bookmark-grafana + networks: + - monitornet + depends_on: + - prometheus + - prometheus-pushgateway + prometheus: + image: prom/prometheus + ports: + - "9090:9090" + command: + - --config.file=/etc/prometheus/prometheus.yml + volumes: + - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro + container_name: bookmark-prometheus + networks: + - monitornet + prometheus-pushgateway: + image: prom/pushgateway + container_name: bookmark-pushgateway + expose: + - 9091 + ports: + - "9091:9091" +# cadvisor: +# image: gcr.io/cadvisor/cadvisor:v0.43.0 +# volumes: +# - '/:/rootfs:ro' +# - '/var/run:/var/run:rw' +# - '/sys:/sys:ro' +# - '/var/lib/docker/:/var/lib/docker:ro' +# ports: +# - "8080:8080" + +volumes: + grafana_data: + +networks: + monitornet: + driver: bridge \ No newline at end of file diff --git a/env b/env new file mode 100644 index 0000000..4a62e32 --- /dev/null +++ b/env @@ -0,0 +1 @@ +IP_HOST=172.26.232.6 \ No newline at end of file diff --git a/go-compose.yml b/go-compose.yml new file mode 100644 index 0000000..0b3b36b --- /dev/null +++ b/go-compose.yml @@ -0,0 +1,19 @@ +version: "3" +services: + go_app: + build: + dockerfile: go_app/Dockerfile + context: . + networks: + - monitornet + expose: + - 8080 + ports: + - "8080:8080" + container_name: bookmark-go-app + environment: + - APP_PUSH_GATEWAY=http://${IP_HOST}:9091 + +networks: + monitornet: + driver: bridge \ No newline at end of file diff --git a/go_app/Dockerfile b/go_app/Dockerfile new file mode 100644 index 0000000..d37231b --- /dev/null +++ b/go_app/Dockerfile @@ -0,0 +1,17 @@ +# syntax=docker/dockerfile:1 + +FROM golang:1.16-alpine + +WORKDIR /app + +COPY go_app/go.mod ./ +COPY go_app/go.sum ./ +RUN go get github.com/prometheus/client_golang/prometheus/promhttp +RUN go mod download + +COPY go_app/*.go ./ + +RUN go build -o /go-app +EXPOSE 8080 + +CMD [ "/go-app" ] \ No newline at end of file diff --git a/go.mod b/go_app/go.mod similarity index 100% rename from go.mod rename to go_app/go.mod diff --git a/go.sum b/go_app/go.sum similarity index 100% rename from go.sum rename to go_app/go.sum diff --git a/main.go b/go_app/main.go similarity index 99% rename from main.go rename to go_app/main.go index 8e50be4..ac585ba 100644 --- a/main.go +++ b/go_app/main.go @@ -40,6 +40,7 @@ func main() { logger.Info("server started on port 8080") log.Fatal(http.ListenAndServe(":8080", router)) + } func (s *server) indexHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { diff --git a/img/Grafana_dash.jpg b/img/Grafana_dash.jpg new file mode 100644 index 0000000..f1c9920 Binary files /dev/null and b/img/Grafana_dash.jpg differ diff --git a/img/prom_targets.jpg b/img/prom_targets.jpg new file mode 100644 index 0000000..09c18c3 Binary files /dev/null and b/img/prom_targets.jpg differ diff --git a/prometheus/prometheus.yml b/prometheus/prometheus.yml new file mode 100644 index 0000000..d49125b --- /dev/null +++ b/prometheus/prometheus.yml @@ -0,0 +1,58 @@ +# my global config +global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + +# Alertmanager configuration +alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 + + +# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. +rule_files: + +# A scrape configuration containing exactly one endpoint to scrape: +# Here it's Prometheus itself. +scrape_configs: + - job_name: go-app + metrics_path: / + scheme: http + scrape_interval: 10s + static_configs: + - targets: + - 172.26.232.6:8080 + labels: + group: 'applications' + + - job_name: prometheus + metrics_path: /metrics + scrape_interval: 10s + static_configs: + - targets: + - 172.26.232.6:9090 + - 172.26.232.6:9115 + + - job_name: promgateway + metrics_path: /metrics + scrape_interval: 10s + static_configs: + - targets: + - 172.26.232.6:9091 + + - job_name: blackbox + metrics_path: /probe + params: + module: [http_2xx] + static_configs: + - targets: + - 172.26.232.6:8080 + relabel_configs: + - source_labels: [__address__] + target_label: __param_target + - source_labels: [__param_target] + target_label: instance + - target_label: __address__ + replacement: 172.26.232.6:9115 \ No newline at end of file