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.

320 lines
8.7 KiB

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