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.

288 lines
7.9 KiB

  1. ---
  2. # Single pod installation (see basecoin for distributed setup)
  3. apiVersion: v1
  4. kind: Service
  5. metadata:
  6. annotations:
  7. service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
  8. name: localchain
  9. labels:
  10. app: localchain
  11. spec:
  12. ports:
  13. - port: 46656
  14. name: p2p
  15. - port: 46657
  16. name: rpc
  17. clusterIP: None
  18. selector:
  19. app: tm
  20. ---
  21. apiVersion: v1
  22. kind: ConfigMap
  23. metadata:
  24. name: tm-config
  25. data:
  26. validators: "tm-0"
  27. validator.power: "10"
  28. genesis.json: |-
  29. {
  30. "genesis_time": "2016-03-24T23:29:20.457Z",
  31. "chain_id": "chain-iqwZgb",
  32. "validators": [],
  33. "app_hash": ""
  34. }
  35. pub_key_nginx.conf: |-
  36. server {
  37. listen 80 default_server;
  38. listen [::]:80 default_server ipv6only=on;
  39. location /pub_key.json { root /usr/share/nginx/; }
  40. location /app_pub_key.json { root /usr/share/nginx/; }
  41. }
  42. ---
  43. apiVersion: v1
  44. kind: ConfigMap
  45. metadata:
  46. name: app-config
  47. data:
  48. genesis.json: |-
  49. [
  50. "base/chainID",
  51. "test_chain_id",
  52. "base/account",
  53. {
  54. "pub_key": ["tm-0"],
  55. "coins": [
  56. {"denom":"CITI/USD","amount":1000},
  57. {"denom":"UBS/EURO","amount":1000}
  58. ]
  59. }
  60. ]
  61. ---
  62. apiVersion: policy/v1beta1
  63. kind: PodDisruptionBudget
  64. metadata:
  65. name: tm-budget
  66. spec:
  67. selector:
  68. matchLabels:
  69. app: tm
  70. minAvailable: 2
  71. ---
  72. apiVersion: apps/v1beta1
  73. kind: StatefulSet
  74. metadata:
  75. name: tm
  76. spec:
  77. serviceName: localchain
  78. replicas: 1
  79. template:
  80. metadata:
  81. labels:
  82. app: tm
  83. annotations:
  84. pod.beta.kubernetes.io/init-containers: '[{
  85. "name": "tm-gen-validator",
  86. "image": "tendermint/tendermint:0.9.0",
  87. "imagePullPolicy": "IfNotPresent",
  88. "command": ["bash", "-c", "
  89. set -ex\n
  90. if [ ! -f /tendermint/priv_validator.json ]; then\n
  91. tendermint gen_validator > /tendermint/priv_validator.json\n
  92. # pub_key.json will be served by pub-key container\n
  93. cat /tendermint/priv_validator.json | jq \".pub_key\" > /tendermint/pub_key.json\n
  94. fi\n
  95. "],
  96. "volumeMounts": [
  97. {"name": "tmdir", "mountPath": "/tendermint"}
  98. ]
  99. },
  100. {
  101. "name": "app-gen-key",
  102. "image": "tendermint/basecoin:latest",
  103. "imagePullPolicy": "IfNotPresent",
  104. "command": ["bash", "-c", "
  105. set -ex\n
  106. if [ ! -f /app/key.json ]; then\n
  107. basecoin key new > /app/key.json\n
  108. # pub_key.json will be served by app-pub-key container\n
  109. cat /app/key.json | jq \".pub_key\" > /app/pub_key.json\n
  110. fi\n
  111. "],
  112. "volumeMounts": [
  113. {"name": "appdir", "mountPath": "/app"}
  114. ]
  115. }]'
  116. spec:
  117. containers:
  118. - name: tm
  119. imagePullPolicy: IfNotPresent
  120. image: tendermint/tendermint:0.9.0
  121. ports:
  122. - containerPort: 46656
  123. name: p2p
  124. - containerPort: 46657
  125. name: rpc
  126. env:
  127. - name: VALIDATOR_POWER
  128. valueFrom:
  129. configMapKeyRef:
  130. name: tm-config
  131. key: validator.power
  132. - name: VALIDATORS
  133. valueFrom:
  134. configMapKeyRef:
  135. name: tm-config
  136. key: validators
  137. - name: TMROOT
  138. value: /tendermint
  139. command:
  140. - bash
  141. - "-c"
  142. - |
  143. set -ex
  144. # copy template
  145. cp /etc/tendermint/genesis.json /tendermint/genesis.json
  146. # fill genesis file with validators
  147. IFS=',' read -ra VALS_ARR <<< "$VALIDATORS"
  148. fqdn_suffix=$(echo $(hostname -f) | sed 's#[^.]*\.\(\)#\1#')
  149. for v in "${VALS_ARR[@]}"; do
  150. # wait until validator generates priv/pub key pair
  151. set +e
  152. curl -s "http://$v.$fqdn_suffix/pub_key.json" > /dev/null
  153. ERR=$?
  154. while [ "$ERR" != 0 ]; do
  155. sleep 5
  156. curl -s "http://$v.$fqdn_suffix/pub_key.json" > /dev/null
  157. ERR=$?
  158. done
  159. set -e
  160. # add validator to genesis file along with its pub_key
  161. curl -s "http://$v.$fqdn_suffix/pub_key.json" | jq ". as \$k | {pub_key: \$k, amount: $VALIDATOR_POWER, name: \"$v\"}" > pub_validator.json
  162. cat /tendermint/genesis.json | jq ".validators |= .+ [$(cat pub_validator.json)]" > /tendermint/genesis.json
  163. rm pub_validator.json
  164. done
  165. tendermint node --moniker="`hostname`" --proxy_app="unix:///socks/app.sock"
  166. volumeMounts:
  167. - name: tmdir
  168. mountPath: /tendermint
  169. - mountPath: /etc/tendermint/genesis.json
  170. name: tmconfigdir
  171. subPath: genesis.json
  172. - name: socksdir
  173. mountPath: /socks
  174. - name: app
  175. imagePullPolicy: IfNotPresent
  176. image: tendermint/basecoin:latest
  177. workingDir: /app
  178. command:
  179. - bash
  180. - "-c"
  181. - |
  182. set -ex
  183. # replace "tm-N" with public keys in genesis file
  184. cp /etc/app/genesis.json genesis.json
  185. fqdn_suffix=$(echo $(hostname -f) | sed 's#[^.]*\.\(\)#\1#')
  186. # for every "base/account"
  187. i=3
  188. length=$(cat genesis.json | jq ". | length")
  189. while [ $i -lt $length ]; do
  190. # extract pod name ("tm-0")
  191. pod=$(cat genesis.json | jq -r ".[$i].pub_key[0]")
  192. # wait until pod starts to serve its pub_key
  193. set +e
  194. curl -s "http://$pod.$fqdn_suffix/app_pub_key.json" > /dev/null
  195. ERR=$?
  196. while [ "$ERR" != 0 ]; do
  197. sleep 5
  198. curl -s "http://$pod.$fqdn_suffix/app_pub_key.json" > /dev/null
  199. ERR=$?
  200. done
  201. set -e
  202. # get its pub_key
  203. curl -s "http://$pod.$fqdn_suffix/app_pub_key.json" | jq "." > k.json
  204. # replace pod name with it (["tm-0"] => "[1, XXXXXXXXXXXXXXXXXXXX]")
  205. cat genesis.json | jq ".[$i].pub_key = $(cat k.json | jq '.')" > genesis.json
  206. rm -f k.json
  207. i=$((i+2)) # skip "base/account" field itself
  208. done
  209. rm -f /socks/app.sock # remove old socket
  210. basecoin start --address="unix:///socks/app.sock"
  211. volumeMounts:
  212. - name: appdir
  213. mountPath: /app
  214. - mountPath: /etc/app/genesis.json
  215. name: appconfigdir
  216. subPath: genesis.json
  217. - name: socksdir
  218. mountPath: /socks
  219. - name: pub-key
  220. imagePullPolicy: IfNotPresent
  221. image: nginx:latest
  222. ports:
  223. - containerPort: 80
  224. name: pub-key
  225. command:
  226. - bash
  227. - "-c"
  228. - |
  229. set -ex
  230. # fixes 403 Permission Denied (open() "/tendermint/pub_key.json" failed (13: Permission denied))
  231. # => we cannot serve from /tendermint, so we copy the file
  232. mkdir -p /usr/share/nginx
  233. cp /tendermint/pub_key.json /usr/share/nginx/pub_key.json
  234. cp /app/pub_key.json /usr/share/nginx/app_pub_key.json
  235. nginx -g "daemon off;"
  236. volumeMounts:
  237. - name: tmdir
  238. mountPath: /tendermint
  239. - name: appdir
  240. mountPath: /app
  241. - mountPath: /etc/nginx/conf.d/pub_key.conf
  242. name: tmconfigdir
  243. subPath: pub_key_nginx.conf
  244. volumes:
  245. - name: tmconfigdir
  246. configMap:
  247. name: tm-config
  248. - name: appconfigdir
  249. configMap:
  250. name: app-config
  251. - name: socksdir
  252. emptyDir: {}
  253. volumeClaimTemplates:
  254. - metadata:
  255. name: tmdir
  256. annotations:
  257. volume.alpha.kubernetes.io/storage-class: anything
  258. spec:
  259. accessModes: [ "ReadWriteOnce" ]
  260. resources:
  261. requests:
  262. storage: 2Gi
  263. - metadata:
  264. name: appdir
  265. annotations:
  266. volume.alpha.kubernetes.io/storage-class: anything
  267. spec:
  268. accessModes: [ "ReadWriteOnce" ]
  269. resources:
  270. requests:
  271. storage: 12Mi