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.

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