github.com/micro/go-micro/examples@v0.0.0-20210105173217-bf4ab679e18b/kubernetes/README.md (about)

     1  # Micro on Kubernetes
     2  
     3  Micro on Kubernetes is a kubernetes native micro service deployment.
     4  
     5  ## Overview
     6  
     7  Micro is a blueprint for microservice development. Kubernetes is a container orchestration system. 
     8  Together they provide the foundations for a microservice platform. Micro on Kubernetes 
     9  provides a kubernetes native runtime to help build micro services.
    10  
    11  ## Features
    12  
    13  - No external dependencies
    14  - K8s native services
    15  - Service mesh integration
    16  - gRPC communication protocol
    17  - Pre-initialised micro images
    18  - Healthchecking sidecar
    19  
    20  ## Getting Started
    21  
    22  - [Installing Micro](#installing-micro)
    23  - [Writing a Service](#writing-a-service)
    24  - [Deploying a Service](#deploying-a-service)
    25  - [Writing a Web Service](#writing-a-web-service)
    26  - [Healthchecking](#healthchecking-sidecar)
    27  - [Load Balancing](#load-balancing)
    28  - [Using Service Mesh](#using-service-mesh)
    29  - [Using Config Map](#using-config-map)
    30  - [Contribute](#contribute)
    31  
    32  ## Installing Micro
    33  
    34  
    35  ```
    36  go get github.com/micro/go-micro/examples/kubernetes/cmd/micro
    37  ```
    38  
    39  or
    40  
    41  ```
    42  docker pull microhq/micro:kubernetes
    43  ```
    44  
    45  For go-micro
    46  
    47  ```
    48  import "github.com/micro/go-micro/examples/kubernetes/go/micro"
    49  ```
    50  
    51  ## Writing a Service
    52  
    53  Write a service as you would any other [go-micro](https://github.com/micro/go-micro) service.
    54  
    55  ```go
    56  import (
    57  	"github.com/micro/go-micro/v2"
    58  	k8s "github.com/micro/go-micro/examples/kubernetes/go/micro"
    59  )
    60  
    61  func main() {
    62  	service := k8s.NewService(
    63  		micro.Name("greeter"),
    64  	)
    65  	service.Init()
    66  	service.Run()
    67  }
    68  ```
    69  
    70  ## Deploying a Service
    71  
    72  Here's an example k8s deployment for a micro service
    73  
    74  ### Create a Deployment
    75  
    76  ```
    77  apiVersion: apps/v1
    78  kind: Deployment
    79  metadata:
    80    namespace: default
    81    name: greeter
    82  spec:
    83    replicas: 1
    84    template:
    85      metadata:
    86        labels:
    87          app: greeter-srv
    88      spec:
    89        containers:
    90          - name: greeter
    91            command: [
    92  		"/greeter-srv",
    93  		"--server_address=0.0.0.0:8080",
    94  		"--broker_address=0.0.0.0:10001"
    95  	  ]
    96            image: microhq/greeter-srv:kubernetes
    97            imagePullPolicy: Always
    98            ports:
    99            - containerPort: 8080
   100              name: greeter-port
   101  ```
   102  
   103  Deploy with kubectl
   104  
   105  ```
   106  kubectl create -f greeter.yaml
   107  ```
   108  
   109  ### Create a Service
   110  
   111  ```
   112  apiVersion: v1
   113  kind: Service
   114  metadata:
   115    name: greeter
   116    labels:
   117      app: greeter
   118  spec:
   119    ports:
   120    - port: 8080
   121      protocol: TCP
   122    selector:
   123      app: greeter
   124  ```
   125  
   126  Deploy with kubectl
   127  
   128  ```
   129  kubectl create -f greeter-svc.yaml
   130  ```
   131  
   132  ## Writing a Web Service
   133  
   134  Write a web service as you would any other [go-micro/web](https://github.com/micro/go-micro/web) service.
   135  
   136  ```go
   137  import (
   138  	"net/http"
   139  
   140  	"github.com/micro/go-micro/v2/web"
   141  	k8s "github.com/micro/go-micro/examples/kubernetes/go/web"
   142  )
   143  
   144  func main() {
   145  	service := k8s.NewService(
   146  		web.Name("greeter"),
   147  	)
   148  
   149  	service.HandleFunc("/greeter", func(w http.ResponseWriter, r *http.Request) {
   150  		w.Write([]byte(`hello world`))
   151  	})
   152  
   153  	service.Init()
   154  	service.Run()
   155  }
   156  ```
   157  
   158  ## Healthchecking Sidecar
   159  
   160  The healthchecking sidecar exposes `/health` as a http endpoint and calls the rpc endpoint `Debug.Health` on a service. 
   161  Every go-micro service has a built in Debug.Health endpoint.
   162  
   163  ### Install
   164  
   165  ```
   166  go get github.com/micro/go-micro/examples/kubernetes/cmd/health
   167  ```
   168  
   169  or
   170  
   171  ```
   172  docker pull microhq/health:kubernetes
   173  ```
   174  
   175  ### Run
   176  
   177  Run e.g healthcheck greeter service with address localhost:9091
   178  
   179  ```
   180  health --server_name=greeter --server_address=localhost:9091
   181  ```
   182  
   183  Call the healthchecker on localhost:8080
   184  
   185  ```
   186  curl http://localhost:8080/health
   187  ```
   188  
   189  ### K8s Deployment
   190  
   191  Add the healthchecking sidecar to a kubernetes deployment
   192  
   193  ```
   194  apiVersion: apps/v1
   195  kind: Deployment
   196  metadata:
   197    namespace: default
   198    name: greeter
   199  spec:
   200    replicas: 1
   201    template:
   202      metadata:
   203        labels:
   204          app: greeter-srv
   205      spec:
   206        containers:
   207          - name: greeter
   208            command: [
   209  		"/greeter-srv",
   210  		"--server_address=0.0.0.0:8080",
   211  		"--broker_address=0.0.0.0:10001"
   212  	  ]
   213            image: microhq/greeter-srv:kubernetes
   214            imagePullPolicy: Always
   215            ports:
   216            - containerPort: 8080
   217              name: greeter-port
   218          - name: health
   219            command: [
   220  		"/health",
   221                  "--health_address=0.0.0.0:8081",
   222  		"--server_name=greeter",
   223  		"--server_address=0.0.0.0:8080"
   224  	  ]
   225            image: microhq/health:kubernetes
   226            livenessProbe:
   227              httpGet:
   228                path: /health
   229                port: 8081
   230              initialDelaySeconds: 3
   231              periodSeconds: 3
   232  ```
   233  
   234  ## Load Balancing
   235  
   236  Micro includes client side load balancing by default but kubernetes also provides Service load balancing strategies. 
   237  In **micro on kubernetes** we offload load balancing to k8s by using the [static selector](https://github.com/micro/go-plugins/tree/master/client/selector/static) and k8s services.
   238  
   239  Rather than doing address resolution, the static selector returns the service name plus a fixed port e.g greeter returns greeter:8080. 
   240  Read about the [static selector](https://github.com/micro/go-plugins/tree/master/client/selector/static).
   241  
   242  This approach handles both initial connection load balancing and health checks since Kubernetes services stop routing traffic to unhealthy services, but if you want to use long lived connections such as the ones in gRPC protocol, a service-mesh like [Conduit](https://conduit.io/), [Istio](https://istio.io) and [Linkerd](https://linkerd.io/) should be prefered to handle service discovery, routing and failure. 
   243  
   244  Note: The static selector is enabled by default.
   245  
   246  ### Usage
   247  
   248  To manually set the static selector when running your service specify the flag or env var 
   249  
   250  Note: This is already enabled by default
   251  
   252  ```
   253  MICRO_SELECTOR=static ./service
   254  ```
   255  
   256  or
   257  
   258  ```
   259  ./service --selector=static
   260  ```
   261  
   262  ### Deployment
   263  
   264  An example deployment
   265  
   266  ```
   267  apiVersion: apps/v1
   268  kind: Deployment
   269  metadata:
   270    namespace: default
   271    name: greeter
   272  spec:
   273    replicas: 1
   274    template:
   275      metadata:
   276        labels:
   277          app: greeter-srv
   278      spec:
   279        containers:
   280          - name: greeter
   281            command: [
   282  		"/greeter-srv",
   283  		"--server_address=0.0.0.0:8080",
   284  		"--broker_address=0.0.0.0:10001"
   285  	  ]
   286            image: microhq/greeter-srv:kubernetes
   287            imagePullPolicy: Always
   288            ports:
   289            - containerPort: 8080
   290              name: greeter-port
   291  ```
   292  
   293  Deploy with kubectl
   294  
   295  ```
   296  kubectl create -f deployment-static-selector.yaml
   297  ```
   298  
   299  ### Service
   300  
   301  The static selector offloads load balancing to k8s services. So ensure you create a k8s Service for each micro service. 
   302  
   303  Here's a sample service
   304  
   305  ```
   306  apiVersion: v1
   307  kind: Service
   308  metadata:
   309    name: greeter
   310    labels:
   311      app: greeter
   312  spec:
   313    ports:
   314    - port: 8080
   315      protocol: TCP
   316    selector:
   317      app: greeter
   318  ```
   319  
   320  Deploy with kubectl
   321  
   322  ```
   323  kubectl create -f service.yaml
   324  ```
   325  
   326  Calling micro service "greeter" from your service will route to the k8s service greeter:8080.
   327  
   328  ## Using Service Mesh
   329  
   330  Service mesh acts as a transparent L7 proxy for offloading distributed systems concerns to an external source.
   331  
   332  See [linkerd2](https://linkerd.io/) for usage.
   333  
   334  ## Using Config Map
   335  
   336  [Go Config](https://github.com/micro/go-micro/config) is a simple way to manage dynamic configuration. We've provided a pre-initialised version 
   337  which reads from environment variables and the k8s config map.
   338  
   339  It uses the `default` namespace and expects a configmap with name `micro` to be present.
   340  
   341  ### Example
   342  
   343  Create a configmap
   344  
   345  ```
   346  // we recommend to setup your variables from multiples files example:
   347  $ kubectl create configmap micro --namespace default --from-file=./testdata
   348  
   349  // verify if were set correctly with
   350  $ kubectl get configmap micro --namespace default
   351  {
   352      "apiVersion": "v1",
   353      "data": {
   354          "config": "host=0.0.0.0\nport=1337",
   355          "mongodb": "host=127.0.0.1\nport=27017\nuser=user\npassword=password",
   356          "redis": "url=redis://127.0.0.1:6379/db01"
   357      },
   358      "kind": "ConfigMap",
   359      "metadata": {
   360          ...
   361          "name": "micro",
   362          "namespace": "default",
   363          ...
   364      }
   365  }
   366  ```
   367  
   368  Import and use the config
   369  
   370  ```go
   371  import "github.com/micro/go-micro/examples/kubernetes/go/config"
   372  
   373  cfg := config.NewConfig()
   374  
   375  // the example above "mongodb": "host=127.0.0.1\nport=27017\nuser=user\npassword=password" will be accessible as:
   376  conf.Get("mongodb", "host") // 127.0.0.1
   377  conf.Get("mongodb", "port") // 27017
   378  ```
   379  
   380  ## Contribute
   381  
   382  We're looking for contributions from the community to help guide the development of Micro on Kubernetes
   383  
   384  ### TODO
   385  
   386  - Fix k8s namespace/service name issue
   387  - Add example multi-service application
   388  - Add k8s CRD for micro apps