Skip to content
This repository has been archived by the owner on Jun 24, 2024. It is now read-only.

Commit

Permalink
Added kubernetes deployment (#6)
Browse files Browse the repository at this point in the history
* Added kubernetes deployment etc

Added logic for health and readiness checks

* Renamed gateway and server images

Updated readme for building project locally for using inside kubernetes

* Corrected import paths

Removed imports which pointed out to internal repo

* Fixed healthcheck probes for gateway
  • Loading branch information
Vitaly Karpenko authored and Evgeniy-L committed Apr 20, 2018
1 parent ce264a2 commit 7d0a608
Show file tree
Hide file tree
Showing 14 changed files with 375 additions and 74 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
bin
.vscode
debug
41 changes: 23 additions & 18 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 0 additions & 5 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@
# go-tests = true
# unused-packages = true


[[constraint]]
name = "github.com/Infoblox-CTO/ngp.api.toolkit"
version = "0.0.3"

[[constraint]]
branch = "master"
name = "github.com/golang/protobuf"
Expand Down
21 changes: 19 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ IMAGE_VERSION ?= $(USERNAME)-dev-$(GIT_COMMIT)
SERVER_BINARY := $(BUILD_PATH)/server
SERVER_PATH := $(PROJECT_ROOT)/cmd/server
SERVER_IMAGE := atlas-contacts-app:$(IMAGE_VERSION)
SERVER_DOCKERFILE := $(DOCKERFILE_PATH)/Dockerfile.server
SERVER_DOCKERFILE := $(DOCKERFILE_PATH)/Dockerfile.contacts-server

GATEWAY_BINARY := $(BUILD_PATH)/gateway
GATEWAY_PATH := $(PROJECT_ROOT)/cmd/gateway
GATEWAY_IMAGE := atlas-contacts-app-gateway:$(IMAGE_VERSION)
GATEWAY_DOCKERFILE := $(DOCKERFILE_PATH)/Dockerfile.gateway
GATEWAY_DOCKERFILE := $(DOCKERFILE_PATH)/Dockerfile.contacts-gateway

GO_PATH := /go
SRCROOT_ON_HOST := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))
Expand Down Expand Up @@ -90,3 +90,20 @@ vendor:
.PHONY: vendor-update
vendor-update:
$(BUILDER) dep ensure

.PHONY: image
image:
docker build -f docker/Dockerfile.contacts-server -t infoblox/contacts-server:v1.0 .
docker build -f docker/Dockerfile.contacts-gateway -t infoblox/contacts-gateway:v1.0 .

.PHONY: image-clean
image-clean:
docker rmi -f infoblox/contacts-server:v1.0 infoblox/contacts-gateway:v1.0

.PHONY: up
up:
kubectl apply -f kube/kube.yaml

.PHONY: down
down:
kubectl delete -f kube/kube.yaml
90 changes: 56 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,67 +10,89 @@ These instructions will get you a copy of the project up and running on your loc

### Prerequisites

#### Local setup:
Need `mysql` or `mariadb` installed.
Install go dep

E.g.

Install database engine:
```
$ sudo dnf install mariadb mariadb-server
``` sh
go get -u github.com/golang/dep/cmd/dep
```

Start database server:
```
$ systemctl start mariadb
```
Need `postgresql` installed locally or running inside docker container within `contacts` database created.
You can change the name of database in `dsn` parameter in `server` app.
Table creation in this example is omitted as it will be done autmotically by `gorm`.

Create `atlas-contacts-app` database:
### Installing

```
$ mysql -u root
```
#### Build the project

```
MariaDB [(none)]> CREATE DATABASE atlas-contacts-app;
``` sh
make vendor
make
```

Create necessary table:
```
$ mysql -u root atlas-contacts-app < ./migrations/0001_contacts.sql
```
If this process finished with errors it's likely that docker doesn't allow to mount host directory in its container.
Therefore you are proposed to run `su -c "setenforce 0"` command to fix this issue.

#### Local setup

### Installing
Please note that you should have the following ports opened on you local workstation: `:8080 :9090 :8088 :8089`.
If they are busy - please change them via corresponding parameters of `gateway` and `server` binaries.

#### Local setup:
Run GRPC server:

Build the project.
```
make
``` sh
./bin/server -dsn "host=localhost port=5432 user=postgres password=postgres sslmode=disable dbname=contacts"
```

Run GRPC gateway:
```

``` sh
./bin/gateway
```

Run GRPC server:
```
./bin/server -dsn root:@tcp/atlas-contacts-app
#### Try atlas-contacts-app

``` sh
curl http://localhost:8080/atlas-contacts-app/v1/contacts -d '{"first_name": "Mike", "email_address": "[email protected]"}'
```

Try atlas-contacts-app:
``` sh
curl http://localhost:8080/atlas-contacts-app/v1/contacts -d '{"first_name": "Bob", "email_address": "[email protected]"}'
```
curl http://localhost:8080/atlas-contacts-app/v1/contacts -d '{"first_name": "Mike", "email_address": "[email protected]"}'

``` sh
curl http://localhost:8080/atlas-contacts-app/v1/contacts?_filter='first_name=="Mike"'

#### Local Kubernetes setup

Open a seperate terminal session where execute `eval $(minikube docker-env)`. This is needed to make these images available for local kubernetes without pushing them to global repo.

Then:

``` sh
make image
make up
```

To shutdown and cleanup:

``` sh
make down
make image-clean
rm -rf bin
```
curl http://localhost:8080/atlas-contacts-app/v1/contacts -d '{"first_name": "Bob", "email_address": "[email protected]"}'

#### Try local Kubernetes atlas-contacts-app

``` sh
curl http://$(minikube ip):31500/atlas-contacts-app/v1/contacts -d '{"first_name": "Mike", "email_address": "[email protected]"}'
```

``` sh
curl http://$(minikube ip):31500/atlas-contacts-app/v1/contacts -d '{"first_name": "Bob", "email_address": "[email protected]"}'
```
curl http://localhost:8080/atlas-contacts-app/v1/contacts?_filter='first_name=="Mike"'

``` sh
curl http://$(minikube ip):31500/atlas-contacts-app/v1/contacts?_filter='first_name=="Mike"'
```

## Deployment
Expand Down
2 changes: 2 additions & 0 deletions cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package config

const (
SERVER_ADDRESS = "0.0.0.0:9090"
HEALTH_ADDRESS = "0.0.0.0:8088"
SERVER_HEALTH = "0.0.0.0:8089"
GATEWAY_ADDRESS = "0.0.0.0:8080"
GATEWAY_URL = "/atlas-contacts-app/v1/"
SWAGGER_DIR = "./proto"
Expand Down
38 changes: 34 additions & 4 deletions cmd/gateway/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,27 @@ package main
import (
"context"
"flag"
"fmt"
"log"
"net/http"
"path"
"time"

"github.com/grpc-ecosystem/grpc-gateway/runtime"

"github.com/Infoblox-CTO/ngp.api.toolkit/gw"
"github.com/infobloxopen/atlas-app-toolkit/gw"
"github.com/infobloxopen/atlas-app-toolkit/health"
"github.com/infobloxopen/atlas-contacts-app/cmd/config"
)

const readinessTimeout = time.Second * 10

var (
ServerAddr string
GatewayAddr string
SwaggerDir string
ServerAddr string
HealthAddress string
ServerHealth string
GatewayAddr string
SwaggerDir string
)

func main() {
Expand All @@ -35,14 +43,36 @@ func main() {
mux := http.NewServeMux()
mux.Handle("/atlas-contacts-app/v1/", serverHandler)
mux.HandleFunc("/swagger/", SwaggerHandler)

healthChecker := health.NewChecksHandler("/healthz", "/ready")
healthChecker.AddReadiness("app ready check", isAppReady)
go http.ListenAndServe(HealthAddress, healthChecker.Handler())

// serve handlers on the gateway address
http.ListenAndServe(GatewayAddr, mux)
}

func init() {
// default gateway values; optionally configured via command-line flags
flag.StringVar(&ServerAddr, "server", config.SERVER_ADDRESS, "address of the gRPC server")
flag.StringVar(&HealthAddress, "health", config.HEALTH_ADDRESS, "address of readiness check endpoint")
flag.StringVar(&ServerHealth, "shealth", config.SERVER_HEALTH, "address of readiness check endpoint")
flag.StringVar(&GatewayAddr, "gateway", config.GATEWAY_ADDRESS, "address of the gateway server")
flag.StringVar(&SwaggerDir, "swagger-dir", config.SWAGGER_DIR, "directory of the swagger.json file")
flag.Parse()
}

func isAppReady() error {
client := &http.Client{
Timeout: readinessTimeout,
}

resp, err := client.Get("http://" + path.Join(ServerHealth, "ready"))
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("Readiness check failed: %s", resp.Status)
}
return nil
}
Loading

0 comments on commit 7d0a608

Please sign in to comment.