Kubernetes Deployment

This doc provides a guide to running micro on kubernetes.

Getting Started

Dependencies

On kubernetes we would recommend running etcd and nats.

  • Etcd is used for highly scalable service discovery
  • NATS is used for asynchronous messaging

To install etcd (instructions)

  1. helm install --name my-release --set customResources.createEtcdClusterCRD=true stable/etcd-operator
  2. # to later uninstall etcd
  3. helm delete my-release

To install nats (instructions)

  1. kubectl apply -f https://github.com/nats-io/nats-operator/releases/latest/download/00-prereqs.yaml
  2. kubectl apply -f https://github.com/nats-io/nats-operator/releases/latest/download/10-deployment.yaml

You should now have the required dependencies.

Install Micro

Use the below docker image

  1. micro/micro

Or use go-micro for development

  1. github.com/micro/go-micro

Writing a Service

Write a service as you would any other go-micro service.

  1. import (
  2. "github.com/micro/go-micro/v2"
  3. )
  4. func main() {
  5. service := micro.NewService(
  6. micro.Name("greeter")
  7. )
  8. service.Init()
  9. service.Run()
  10. }

Deploying a Service

Here’s an example k8s deployment for a micro service

  1. apiVersion: extensions/v1beta1
  2. kind: Deployment
  3. metadata:
  4. namespace: default
  5. name: greeter
  6. spec:
  7. replicas: 1
  8. selector:
  9. matchLabels:
  10. name: greeter-srv
  11. micro: service
  12. template:
  13. metadata:
  14. labels:
  15. name: greeter-srv
  16. micro: service
  17. spec:
  18. containers:
  19. - name: greeter
  20. command: [
  21. "/greeter-srv",
  22. ]
  23. image: yourimage/yourservice
  24. imagePullPolicy: Always
  25. ports:
  26. - containerPort: 8080
  27. name: greeter-port
  28. env:
  29. - name: MICRO_SERVER_ADDRESS
  30. value: "0.0.0.0:8080"
  31. - name: MICRO_BROKER
  32. value: "nats"
  33. - name: MICRO_BROKER_ADDRESS
  34. value: "nats-cluster"
  35. - name: MICRO_REGISTRY
  36. value: "etcd"
  37. - name: MICRO_REGISTRY_ADDRESS
  38. value: "etcd-cluster-client"

Deploy with kubectl

  1. kubectl apply -f greeter.yaml

Healthchecking Sidecar

The healthchecking sidecar exposes /health as a http endpoint and calls the rpc endpoint Debug.Health on a service. Every go-micro service has a built in Debug.Health endpoint.

Install healthchecker

  1. go get github.com/micro/cmd/health

or

  1. docker pull microhq/health

Run healtchecker

Run e.g healthcheck greeter service with address localhost:9091

  1. health --server_name=greeter --server_address=localhost:9091

Call the healthchecker on localhost:8080

  1. curl http://localhost:8080/health

K8s Deployment

Add to a kubernetes deployment

  1. apiVersion: extensions/v1beta1
  2. kind: Deployment
  3. metadata:
  4. namespace: default
  5. name: greeter
  6. spec:
  7. replicas: 1
  8. selector:
  9. matchLabels:
  10. name: greeter-srv
  11. micro: service
  12. template:
  13. metadata:
  14. labels:
  15. name: greeter-srv
  16. micro: service
  17. spec:
  18. containers:
  19. - name: greeter
  20. command: [
  21. "/greeter-srv",
  22. ]
  23. image: yourimage/yourservice
  24. imagePullPolicy: Always
  25. ports:
  26. - containerPort: 8080
  27. name: greeter-port
  28. env:
  29. - name: MICRO_SERVER_ADDRESS
  30. value: "0.0.0.0:8080"
  31. - name: MICRO_BROKER
  32. value: "nats"
  33. - name: MICRO_BROKER_ADDRESS
  34. value: "nats-cluster"
  35. - name: MICRO_REGISTRY
  36. value: "etcd"
  37. - name: MICRO_REGISTRY_ADDRESS
  38. value: "etcd-cluster-client"
  39. - name: health
  40. command: [
  41. "/health",
  42. "--health_address=0.0.0.0:8081",
  43. "--server_name=greeter",
  44. "--server_address=0.0.0.0:8080"
  45. ]
  46. image: microhq/health
  47. livenessProbe:
  48. httpGet:
  49. path: /health
  50. port: 8081
  51. initialDelaySeconds: 3
  52. periodSeconds: 3

Micro API

To deploy the micro api use the following config. Note the ENABLE_ACME env var where you want Let’s Encrypt SSL by default.

Create the api service

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: micro-api
  5. namespace: default
  6. labels:
  7. name: micro-api
  8. micro: service
  9. spec:
  10. ports:
  11. - name: https
  12. port: 443
  13. targetPort: 443
  14. selector:
  15. name: micro-api
  16. micro: service
  17. type: LoadBalancer

Create the deployment

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. namespace: default
  5. name: micro-api
  6. labels:
  7. micro: service
  8. spec:
  9. replicas: 3
  10. selector:
  11. matchLabels:
  12. name: micro-api
  13. micro: service
  14. strategy:
  15. rollingUpdate:
  16. maxSurge: 0
  17. maxUnavailable: 1
  18. template:
  19. metadata:
  20. labels:
  21. name: micro-api
  22. micro: service
  23. spec:
  24. containers:
  25. - name: api
  26. env:
  27. - name: MICRO_ENABLE_STATS
  28. value: "true"
  29. - name: MICRO_BROKER
  30. value: "nats"
  31. - name: MICRO_BROKER_ADDRESS
  32. value: "nats-cluster"
  33. - name: MICRO_REGISTRY
  34. value: "etcd"
  35. - name: MICRO_REGISTRY_ADDRESS
  36. value: "etcd-cluster-client"
  37. - name: MICRO_REGISTER_TTL
  38. value: "60"
  39. - name: MICRO_REGISTER_INTERVAL
  40. value: "30"
  41. - name: MICRO_ENABLE_ACME
  42. value: "true"
  43. args:
  44. - api
  45. image: micro/micro
  46. imagePullPolicy: Always
  47. ports:
  48. - containerPort: 443
  49. name: api-port

Micro Web

To deploy the micro web use the following config. Note the ENABLE_ACME env var where you want Let’s Encrypt SSL by default.

Create the service

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: micro-web
  5. namespace: default
  6. labels:
  7. name: micro-web
  8. micro: service
  9. spec:
  10. ports:
  11. - name: https
  12. port: 443
  13. targetPort: 443
  14. selector:
  15. name: micro-web
  16. micro: service
  17. type: LoadBalancer

Create the deployment

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. namespace: default
  5. name: micro-web
  6. labels:
  7. micro: service
  8. spec:
  9. replicas: 1
  10. selector:
  11. matchLabels:
  12. name: micro-web
  13. micro: service
  14. template:
  15. metadata:
  16. labels:
  17. name: micro-web
  18. micro: service
  19. spec:
  20. containers:
  21. - name: web
  22. env:
  23. - name: MICRO_BROKER
  24. value: "nats"
  25. - name: MICRO_BROKER_ADDRESS
  26. value: "nats-cluster"
  27. - name: MICRO_ENABLE_STATS
  28. value: "true"
  29. - name: MICRO_REGISTRY
  30. value: "etcd"
  31. - name: MICRO_REGISTRY_ADDRESS
  32. value: "etcd-cluster-client"
  33. - name: MICRO_ENABLE_ACME
  34. value: "true"
  35. - name: MICRO_ACME_PROVIDER
  36. value: certmagic
  37. args:
  38. - web
  39. image: micro/micro
  40. imagePullPolicy: Always
  41. ports:
  42. - containerPort: 443
  43. name: web-port

Full Deployment

For the full deployment config used by micro.mu for the cloud platform see:

https://github.com/micro/micro/tree/master/network/config/kubernetes

Some of this config is specific to the needs of Micro itself including the use of CloudFlare.