You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

229 lines
7.2 KiB

  1. # Tendermint network powered by Kubernetes
  2. ![Tendermint plus Kubernetes](img/t_plus_k.png)
  3. * [QuickStart (MacOS)](#quickstart-macos)
  4. * [QuickStart (Linux)](#quickstart-linux)
  5. * [Usage](#usage)
  6. * [Security](#security)
  7. * [Fault tolerance](#fault-tolerance)
  8. * [Starting process](#starting-process)
  9. This should primarily be used for testing purposes or for tightly-defined
  10. chains operated by a single stakeholder (see [the security
  11. precautions](#security)). If your desire is to launch an application with many
  12. stakeholders, consider using our set of Ansible scripts.
  13. ## QuickStart (MacOS)
  14. [Requirements](https://github.com/kubernetes/minikube#requirements)
  15. ```
  16. curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/kubectl
  17. curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.17.1/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
  18. minikube start
  19. git clone https://github.com/tendermint/tools.git && cd tools/mintnet-kubernetes/examples/basecoin && make create
  20. ```
  21. ## QuickStart (Linux)
  22. [Requirements](https://github.com/kubernetes/minikube#requirements)
  23. ```
  24. curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/kubectl
  25. curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.17.1/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
  26. minikube start
  27. git clone https://github.com/tendermint/tools.git && cd tools/mintnet-kubernetes/examples/basecoin && make create
  28. ```
  29. ### Verify everything works
  30. **Using a shell:**
  31. 1. wait until all the pods are `Running`.
  32. ```
  33. kubectl get pods -w -o wide -L tm
  34. ```
  35. 2. query the Tendermint app logs from the first pod.
  36. ```
  37. kubectl logs -c tm -f tm-0
  38. ```
  39. 3. use [Rest API](https://tendermint.com/docs/internals/rpc) to fetch the
  40. status of the second pod's Tendermint app. Note we are using `kubectl exec`
  41. because pods are not exposed (and should not be) to the outer network.
  42. ```
  43. kubectl exec -c tm tm-0 -- curl -s http://tm-1.basecoin:46657/status | json_pp
  44. ```
  45. **Using the dashboard:**
  46. ```
  47. minikube dashboard
  48. ```
  49. ### Clean up
  50. ```
  51. make destroy
  52. ```
  53. ## Usage
  54. ### (1/4) Setup a Kubernetes cluster
  55. - locally using [Minikube](https://github.com/kubernetes/minikube)
  56. - on GCE with a single click in the web UI
  57. - on AWS using [Kubernetes Operations](https://github.com/kubernetes/kops/blob/master/docs/aws.md)
  58. - on Linux machines (Digital Ocean) using [kubeadm](https://kubernetes.io/docs/getting-started-guides/kubeadm/)
  59. - on AWS, Azure, GCE or bare metal using [Kargo (Ansible)](https://kubernetes.io/docs/getting-started-guides/kargo/)
  60. Please refer to [the official
  61. documentation](https://kubernetes.io/docs/getting-started-guides/) for overview
  62. and comparison of different options. See our guides for [Google Cloud
  63. Engine](docs/SETUP_K8S_ON_GCE.md) or [Digital Ocean](docs/SETUP_K8S_ON_DO.md).
  64. **Make sure you have Kubernetes >= 1.5, because you will be using StatefulSets,
  65. which is a beta feature in 1.5.**
  66. ### (2/4) Create a configuration file
  67. Download a template:
  68. ```
  69. curl -Lo app.yaml https://github.com/tendermint/tools/raw/master/mintnet-kubernetes/app.template.yaml
  70. ```
  71. Open `app.yaml` in your favorite editor and configure your app container
  72. (navigate to `- name: app`). Kubernetes DSL (Domain Specific Language) is very
  73. simple, so it should be easy. You will need to set Docker image, command and/or
  74. run arguments. Replace variables prefixed with `YOUR_APP` with corresponding
  75. values. Set genesis time to now and preferable chain ID in ConfigMap.
  76. Please note if you are changing `replicas` number, do not forget to update
  77. `validators` set in ConfigMap. You will be able to scale the cluster up or down
  78. later, but new pods (nodes) won't become validators automatically.
  79. ### (3/4) Deploy your application
  80. ```
  81. kubectl create -f ./app.yaml
  82. ```
  83. ### (4/4) Observe your cluster
  84. **web UI** <-> https://github.com/kubernetes/dashboard
  85. The easiest way to access Dashboard is to use kubectl. Run the following command in your desktop environment:
  86. ```
  87. kubectl proxy
  88. ```
  89. kubectl will handle authentication with apiserver and make Dashboard available at [http://localhost:8001/ui](http://localhost:8001/ui)
  90. **shell**
  91. List all the pods:
  92. ```
  93. kubectl get pods -o wide -L tm
  94. ```
  95. StatefulSet details:
  96. ```
  97. kubectl describe statefulsets tm
  98. ```
  99. First pod details:
  100. ```
  101. kubectl describe pod tm-0
  102. ```
  103. Tendermint app logs from the first pod:
  104. ```
  105. kubectl logs tm-0 -c tm -f
  106. ```
  107. App logs from the first pod:
  108. ```
  109. kubectl logs tm-0 -c app -f
  110. ```
  111. Status of the second pod's Tendermint app:
  112. ```
  113. kubectl exec -c tm tm-0 -- curl -s http://tm-1.<YOUR_APP_NAME>:46657/status | json_pp
  114. ```
  115. ## Security
  116. Due to the nature of Kubernetes, where you typically have a single master, the
  117. master could be a SPOF (Single Point Of Failure). Therefore, you need to make
  118. sure only authorized people can access it. And these people themselves had
  119. taken basic measures in order not to get hacked.
  120. These are the best practices:
  121. - all access to the master is over TLS
  122. - access to the API Server is X.509 certificate or token based
  123. - etcd is not exposed directly to the cluster
  124. - ensure that images are free of vulnerabilities ([1](https://github.com/coreos/clair))
  125. - ensure that only authorized images are used in your environment
  126. - disable direct access to Kubernetes nodes (no SSH)
  127. - define resource quota
  128. Resources:
  129. - https://kubernetes.io/docs/admin/accessing-the-api/
  130. - http://blog.kubernetes.io/2016/08/security-best-practices-kubernetes-deployment.html
  131. - https://blog.openshift.com/securing-kubernetes/
  132. ## Fault tolerance
  133. Having a single master (API server) is a bad thing also because if something
  134. happens to it, you risk being left without an access to the application.
  135. To avoid that you can [run Kubernetes in multiple
  136. zones](https://kubernetes.io/docs/admin/multiple-zones/), each zone running an
  137. [API server](https://kubernetes.io/docs/admin/high-availability/) and load
  138. balance requests between them. Do not forget to make sure only one instance of
  139. scheduler and controller-manager are running at once.
  140. Running in multiple zones is a lightweight version of a broader [Cluster
  141. Federation feature](https://kubernetes.io/docs/admin/federation/). Federated
  142. deployments could span across multiple regions (not zones). We haven't tried
  143. this feature yet, so any feedback is highly appreciated! Especially, related to
  144. additional latency and cost of exchanging data between the regions.
  145. Resources:
  146. - https://kubernetes.io/docs/admin/high-availability/
  147. ## Starting process
  148. ![StatefulSet](img/statefulset.png)
  149. Init containers (`tm-gen-validator`) are run before all other containers,
  150. creating public-private key pair for each pod. Every `tm` container then asks
  151. other pods for their public keys, which are served with nginx (`pub-key`
  152. container). When `tm` container have all the keys, it forms a genesis file and
  153. starts Tendermint process.
  154. ## TODO
  155. - [ ] run tendermint from tmuser
  156. ```
  157. securityContext:
  158. fsGroup: 999
  159. ```