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.

253 lines
7.6 KiB

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