{"id":21699680,"url":"https://github.com/cage1016/ms-demo","last_synced_at":"2025-07-17T03:04:37.190Z","repository":{"id":148246801,"uuid":"308239445","full_name":"cage1016/ms-demo","owner":"cage1016","description":"gokit microservice demo","archived":false,"fork":false,"pushed_at":"2022-10-21T15:27:48.000Z","size":376,"stargazers_count":8,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-12T13:14:06.067Z","etag":null,"topics":["go-kit","golang","istio","kubernetes","microservice"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cage1016.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-29T06:37:09.000Z","updated_at":"2022-10-21T15:27:52.000Z","dependencies_parsed_at":"2023-05-25T05:00:25.972Z","dependency_job_id":null,"html_url":"https://github.com/cage1016/ms-demo","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cage1016%2Fms-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cage1016%2Fms-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cage1016%2Fms-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cage1016%2Fms-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cage1016","download_url":"https://codeload.github.com/cage1016/ms-demo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248571840,"owners_count":21126522,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go-kit","golang","istio","kubernetes","microservice"],"created_at":"2024-11-25T20:10:54.155Z","updated_at":"2025-04-12T13:14:11.641Z","avatar_url":"https://github.com/cage1016.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gokit microservice demo\n\n[![Continuous Integration - Master/Release](https://github.com/cage1016/ms-demo/actions/workflows/ci-master.yml/badge.svg)](https://github.com/cage1016/ms-demo/actions/workflows/ci-master.yml)\n\n| Service | Description           |\n| ------- | --------------------- |\n| add     | Expose Sum method     |\n| tictac  | Expose Tic/Tac method |\n\n## Features\n\n- **[Kubernetes](https://kubernetes.io)/[GKE](https://cloud.google.com/kubernetes-engine/):**\n  The app is designed to run on Kubernetes (both locally on \"Docker for\n  Desktop\", as well as on the cloud with GKE).\n- **[gRPC](https://grpc.io):** Microservices use a high volume of gRPC calls to\n  communicate to each other.\n- **[Istio](https://istio.io):** Application works on Istio service mesh.\n- **[Skaffold](https://skaffold.dev):** Application\n  is deployed to Kubernetes with a single command using Skaffold.\n- **[go-kit/kit](https://github.com/go-kit/kit):** Go kit is a programming toolkit for building microservices (or elegant monoliths) in Go. We solve common problems in distributed systems and application architecture so you can focus on delivering business value.\n- **[kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx/)**: ingress-nginx is an Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer\n- **[Jaeger](https://www.jaegertracing.io/)**: open source, end-to-end distributed tracing. Monitor and troubleshoot transactions in complex distributed systems\n- **[Telepresence](https://www.telepresence.io/)**: Local development against a remote Kubernetes or OpenShift cluster\n\n## Install\n\nthis demo support [Kubernetes service](.#kubernetes-service) or [nginx ingress](.#nginx-ingress) and [Istio](.#istio) three ways to access\n\n### Kubernetes Service\n\n1. Run ms-demo kubernetes cluster\n    ```sh\n    skaffold run --default-repo=\u003cyour-repo\u003e\n    ```\n\n    or \n\n    ```sh\n    kubectl apply -f https://raw.githubusercontent.com/cage1016/ms-demo/master/release/kubernetes-manifests-all.yaml\n    ```\n\n### LoadBalancer\n\n1. Apply LoadBalancer yaml\n\n    ```bash\n    kubectl apply -f https://raw.githubusercontent.com/cage1016/ms-demo/master/release/lb-all.yaml\n    ```\n\n1. We expose `add`, `tictac` service with TWO external service (LoadBalancer)\n1. Set the `ADD_HTTP_EXTERNAL_URL/ADD_GRPC_EXTERNAL_URL`\n    ```sh\n    ADD_HTTP_EXTERNA_PORT=$(kubectl get service add-external -o jsonpath='{.spec.ports[?(@.name==\"http\")].port}')\n    ADD_GRPC_EXTERNA_PORT=$(kubectl get service add-external -o jsonpath='{.spec.ports[?(@.name==\"grpc\")].port}')\n    ADD_EXTERNA_HOST=$(kubectl get service add-external -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')\n    # ADD_EXTERNA_HOST=$(kubectl get service add-external -o jsonpath='{.status.loadBalancer.ingress[0].ip}') # unmark if necessary\n    ADD_HTTP_EXTERNA_URL=$ADD_EXTERNA_HOST:$ADD_HTTP_EXTERNA_PORT\n    ADD_GRPC_EXTERNA_URL=$ADD_EXTERNA_HOST:$ADD_GRPC_EXTERNA_PORT\n    echo $ADD_HTTP_EXTERNA_URL\n    echo $ADD_GRPC_EXTERNA_URL\n    ```\n\n1. Set the `TICTAC_HTTP_EXTERNAL_URL/TICTAC_GRPC_EXTERNAL_URL`\n\n    ```sh\n    TICTAC_HTTP_EXTERNAL_PORT=$(kubectl get service tictac-external -o jsonpath='{.spec.ports[?(@.name==\"http\")].port}')\n    TICTAC_GRPC_EXTERNAL_PORT=$(kubectl get service tictac-external -o jsonpath='{.spec.ports[?(@.name==\"grpc\")].port}')\n    TICTAC_EXTERNAL_HOST=$(kubectl get service tictac-external -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')\n    # TICTAC_EXTERNAL_HOST=$(kubectl get service tictac-external -o jsonpath='{.status.loadBalancer.ingress[0].ip}') # unmark if necessary\n    TICTAC_HTTP_EXTERNAL_URL=$TICTAC_EXTERNAL_HOST:$TICTAC_HTTP_EXTERNAL_PORT\n    TICTAC_GRPC_EXTERNAL_URL=$TICTAC_EXTERNAL_HOST:$TICTAC_GRPC_EXTERNAL_PORT\n    echo $TICTAC_HTTP_EXTERNAL_URL\n    echo $TICTAC_GRPC_EXTERNAL_URL\n    ```\n\n2. Access by command\n   \n    **sum** restful method \n    ```sh\n    curl -X POST $ADD_HTTP_EXTERNA_URL/sum -d '{\"a\": 1, \"b\":1}'\n    ```\n    \n    **sum** grpc mwthod\n    ```sh\n    grpcurl -d '{\"a\": 1, \"b\":1}' -plaintext -proto ./pb/add/add.proto $ADD_GRPC_EXTERNA_URL pb.Add.Sum\n    ```\n    \n    **tic** restful method\n    ```sh\n    curl -X POST $TICTAC_HTTP_EXTERNAL_URL/tic\n    ```\n\n    **tic** grpc method\n    ```sh\n    grpcurl -plaintext -proto ./pb/tictac/tictac.proto $TICTAC_GRPC_EXTERNAL_URL pb.Tictac.Tic\n    ```\n    \n    **tac** restful method\n    ```sh\n    curl $TICTAC_HTTP_EXTERNAL_URL/tac\n    ```\n\n    **tac** grpc method\n    ```sh  \n    grpcurl -plaintext -proto ./pb/tictac/tictac.proto $TICTAC_GRPC_EXTERNAL_URL pb.Tictac.Tac\n    ```\n\n3. Remove LoadBalancer\n\n    ```bash\n    kubectl delete -f https://raw.githubusercontent.com/cage1016/ms-demo/master/deployments/lb-all.yaml\n    ```\n\n### Nginx ingress\n\n1. setup nginx ingress\n\n    ```sh\n    kubectl create ns ingress-nginx\n    helm install ingress-nginx -n ingress-nginx ingress-nginx/ingress-nginx\n    ```\n\n1. Prepare tls for nginx ingress GRPC for two grpc test domain `tictac.localhost` \u0026 `add.localhost`\n    - create RSA private key and certificate\n        ```sh\n        sh tls/generate.sh\n        ```\n    - set ingress tls\n        ```sh\n        sh tls/tls.sh\n        ```\n\n1. Setup nginx ingress \n    ```\n    kubectl apply -f https://raw.githubusercontent.com/cage1016/ms-demo/master/release/nginx-ingress-all.yaml\n    ```\n\n1. Set up `ADD_NGINX_INGRESS_GRPC_URL` \u0026 `TICTAC_NGINX_INGRESS_GRPC_URL`\n\n    ```sh\n    ADD_NGINX_INGRESS_GRPC_URL=$(kubectl get ingress add-grpc-ingress -o jsonpath='{.spec.tls[0].hosts[0]}'):443\n    TICTAC_NGINX_INGRESS_GRPC_URL=$(kubectl get ingress tictac-grpc-ingress -o jsonpath='{.spec.tls[0].hosts[0]}'):443\n    echo ${ADD_NGINX_INGRESS_GRPC_URL}\n    echo ${TICTAC_NGINX_INGRESS_GRPC_URL}\n    ```\n\n2. Access by command\n\n    **sum** restful method \n    ```sh\n    curl --insecure -X POST -d '{\"a\": 1, \"b\":1}' https://localhost/api/v1/add/sum\n    ```\n\n    **sum** grpc method\n    ```sh\n    grpcurl --insecure -d '{\"a\": 1, \"b\":1 }' ${ADD_NGINX_INGRESS_GRPC_URL}  pb.Add.Sum\n    ```\n    \n    **tic** restful method\n    ```sh\n    curl --insecure -X POST https://localhost/api/v1/tictac/tic\n    ```\n\n    **tic** grpc method\n    ```sh\n    grpcurl --insecure ${TICTAC_NGINX_INGRESS_GRPC_URL} pb.Tictac.Tic\n    ```\n    \n    **tac** restful method\n    ```sh\n    curl --insecure https://localhost/api/v1/tictac/tac\n    ```\n\n    **tac** grpc method\n    ```sh  \n    grpcurl --insecure ${TICTAC_NGINX_INGRESS_GRPC_URL} pb.Tictac.Tac\n    ```\n\n3. Clean up Nnginx\n\n    ```sh\n    kubectl delete -f https://raw.githubusercontent.com/cage1016/ms-demo/master/deployments/nginx-ingress-all.yaml\n\n    kubectl delete secret add-tls-secret\n    kubectl delete secret tictac-tls-secret\n    ```\n### Istio\n\n1. You should have a Kubernetes cluster with Istio already.\n2. Apply Istio manifests\n\n    ```sh\n    kubectl apply -f https://raw.githubusercontent.com/cage1016/ms-demo/master/release/istio-manifests-all.yaml\n    ```\n3. Set the `GATEWAY_HTTP_URL/GATEWAY_GRPC_URL` environment variable in your shell to the public IP/port of the Istio Ingress gateway.\n    ```sh\n    export INGRESS_HTTP_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name==\"http2\")].port}')\n    export INGRESS_GRPC_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name==\"https\")].port}')\n    export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')\n    export GATEWAY_HTTP_URL=$INGRESS_HOST:$INGRESS_HTTP_PORT\n    export GATEWAY_GRPC_URL=$INGRESS_HOST:$INGRESS_GRPC_PORT\n    echo $GATEWAY_HTTP_URL\n    echo $GATEWAY_GRPC_URL\n    ```\n4. Access by command\n    **sum** restful method \n    ```sh\n    curl -X POST $GATEWAY_HTTP_URL/api/v1/add/sum -d '{\"a\": 1, \"b\":1}'\n    ```\n\n    **sum** grpc method\n    ```sh\n    grpcurl -d '{\"a\": 1, \"b\":1}' -plaintext -proto ./pb/add/add.proto $GATEWAY_GRPC_URL pb.Add.Sum\n    ```\n    \n    **tic** restful method\n    ```sh\n    curl -X POST $GATEWAY_HTTP_URL/api/v1/tictac/tic\n    ```\n\n    **tic** grpc method\n    ```sh\n    grpcurl -plaintext -proto ./pb/tictac/tictac.proto $GATEWAY_GRPC_URL pb.Tictac.Tic\n    ```\n    \n    **tac** restful method\n    ```sh\n    curl $GATEWAY_HTTP_URL/api/v1/tictac/tac\n    ```\n\n    **tac** grpc method\n    ```sh  \n    grpcurl -plaintext -proto ./pb/tictac/tictac.proto $GATEWAY_GRPC_URL pb.Tictac.Tac\n    ```\n\n1. CleanUp Istio\n\n    ```sh\n    kubectl delete -f https://raw.githubusercontent.com/cage1016/ms-demo/master/release/istio-manifests-all.yaml\n    ```\n\n## Jaeger (Optional)\n\n1. Install Jaeger to Kubernetes cluster. Please visit [Jaeger: open source, end-to-end distributed tracing](https://www.jaegertracing.io/) to check more detail information\n\n    ```bash\n    kubectl create namespace observability\n    kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/crds/jaegertracing.io_jaegers_crd.yaml\n    kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/service_account.yaml\n    kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role.yaml\n    kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/role_binding.yaml\n    kubectl create -n observability -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/master/deploy/operator.yaml\n    ```\n\n1. Setup Jaeger sample config \n\n    ```\n    kubectl apply -f https://raw.githubusercontent.com/cage1016/ms-demo/master/release/with-sampling.yaml\n    ```\n\n1. patch `add` \u0026 `tictac` env to connect Jaeger agent\n\n    ```sh\n    kubectl set env deployment/add QS_JAEGER_URL=with-sampling-agent.observability.svc.cluster.local:6831\n    kubectl set env deployment/tictac QS_JAEGER_URL=with-sampling-agent.observability.svc.cluster.local:6831\n    ```\n\n1. Do some restful or grpc requests as above steps that Jeager could collect some data\n1. port-forward Jaeger UI and access\n\n    ```\n    kubectl -n observability port-forward svc/with-sampling-query 16686\n    ```\n\n1. visit https://localhost:16686\n   ![](./ms-sample-jaeger.png)\n\n1. CleanUP jaeger\n\n    ```sh\n    kubectl delete ns observability\n    ```\n## CleanUP claster\n\n```sh\nskaffold delete\n```\n\nor \n\n```sh\nkubectl delete -f https://raw.githubusercontent.com/cage1016/ms-demo/master/release/kubernetes-manifests-all.yaml\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcage1016%2Fms-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcage1016%2Fms-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcage1016%2Fms-demo/lists"}