123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- import * as awsx from '@pulumi/awsx'
- import * as eks from '@pulumi/eks'
- import * as pulumi from '@pulumi/pulumi'
- import * as k8s from '@pulumi/kubernetes'
- import { configMapFromFile } from './configMap'
- import { CaddyServiceDeployment } from 'pulumi-common'
- import { getSubkeyContainers } from './utils'
- import { ValidatorServiceDeployment } from './validator'
- import { NFSServiceDeployment } from './nfsVolume'
- // const { exec } = require('child_process')
- const config = new pulumi.Config()
- const awsConfig = new pulumi.Config('aws')
- const isMinikube = config.getBoolean('isMinikube')
- export let kubeconfig: pulumi.Output<any>
- let provider: k8s.Provider
- if (isMinikube) {
- provider = new k8s.Provider('local', {})
- } else {
- // Create a VPC for our cluster.
- const vpc = new awsx.ec2.Vpc('joystream-node-vpc', { numberOfAvailabilityZones: 2 })
- // Create an EKS cluster with the default configuration.
- const cluster = new eks.Cluster('eksctl-node-network', {
- vpcId: vpc.id,
- subnetIds: vpc.publicSubnetIds,
- desiredCapacity: 2,
- maxSize: 2,
- instanceType: 't2.medium',
- providerCredentialOpts: {
- profileName: awsConfig.get('profile'),
- },
- })
- provider = cluster.provider
- // Export the cluster's kubeconfig.
- kubeconfig = cluster.kubeconfig
- }
- const resourceOptions = { provider: provider }
- const name = 'node-network'
- // Create a Kubernetes Namespace
- const ns = new k8s.core.v1.Namespace(name, {}, resourceOptions)
- // Export the Namespace name
- export const namespaceName = ns.metadata.name
- const appLabels = { appClass: name }
- const networkSuffix = config.get('networkSuffix') || '8129'
- const numberOfValidators = config.getNumber('numberOfValidators') || 1
- const chainDataPath = '/chain-data'
- const chainSpecPath = `${chainDataPath}/chainspec-raw.json`
- const nodeImage = config.get('nodeImage') || 'joystream/node:latest'
- const encryptKey = config.get('encryptionKey') || '1234'
- const subkeyContainers = getSubkeyContainers(numberOfValidators, chainDataPath)
- let pvcClaimName: pulumi.Output<any>
- if (isMinikube) {
- const pvc = new k8s.core.v1.PersistentVolumeClaim(
- `${name}-pvc`,
- {
- metadata: {
- labels: appLabels,
- namespace: namespaceName,
- name: `${name}-pvc`,
- },
- spec: {
- accessModes: ['ReadWriteMany'],
- resources: {
- requests: {
- storage: `1Gi`,
- },
- },
- },
- },
- resourceOptions
- )
- const pv = new k8s.core.v1.PersistentVolume(`${name}-pv`, {
- metadata: {
- labels: { ...appLabels, type: 'local' },
- namespace: namespaceName,
- name: `${name}-pv`,
- },
- spec: {
- accessModes: ['ReadWriteMany'],
- capacity: {
- storage: `1Gi`,
- },
- hostPath: {
- path: '/mnt/data/',
- },
- },
- })
- pvcClaimName = pvc.metadata.apply((m) => m.name)
- } else {
- const nfsVolume = new NFSServiceDeployment('nfs-server', { namespace: namespaceName }, resourceOptions)
- pvcClaimName = nfsVolume.pvc.metadata.apply((m) => m.name)
- }
- const jsonModifyConfig = new configMapFromFile(
- 'json-modify-config',
- {
- filePath: 'json_modify.py',
- namespaceName: namespaceName,
- },
- resourceOptions
- ).configName
- const chainDataPrepareJob = new k8s.batch.v1.Job(
- 'chain-data',
- {
- metadata: {
- namespace: namespaceName,
- },
- spec: {
- backoffLimit: 0,
- template: {
- spec: {
- containers: [
- ...subkeyContainers,
- {
- name: 'builder-node',
- image: nodeImage,
- command: ['/bin/sh', '-c'],
- args: [
- `/joystream/chain-spec-builder generate -a ${numberOfValidators} \
- --chain-spec-path ${chainDataPath}/chainspec.json --deployment live \
- --endowed 1 --keystore-path ${chainDataPath}/data > ${chainDataPath}/seeds.txt`,
- ],
- volumeMounts: [
- {
- name: 'config-data',
- mountPath: chainDataPath,
- },
- ],
- },
- {
- name: 'json-modify',
- image: 'python',
- command: ['python'],
- args: [
- '/scripts/json_modify.py',
- '--path',
- `${chainDataPath}`,
- '--prefix',
- networkSuffix,
- '--validators',
- `${numberOfValidators}`,
- ],
- volumeMounts: [
- {
- mountPath: '/scripts/json_modify.py',
- name: 'json-modify-script',
- subPath: 'fileData',
- },
- {
- name: 'config-data',
- mountPath: chainDataPath,
- },
- ],
- },
- {
- name: 'raw-chain-spec',
- image: nodeImage,
- command: ['/bin/sh', '-c'],
- args: [`/joystream/node build-spec --chain ${chainDataPath}/chainspec.json --raw > ${chainSpecPath}`],
- volumeMounts: [
- {
- name: 'config-data',
- mountPath: chainDataPath,
- },
- ],
- },
- {
- name: '7z',
- image: 'danielwhatmuff/7z-docker',
- command: ['/bin/sh', '-c'],
- args: [`7z a -p${encryptKey} ${chainDataPath}/chain-data.7z ${chainDataPath}/*`],
- volumeMounts: [
- {
- name: 'config-data',
- mountPath: chainDataPath,
- },
- ],
- },
- ],
- volumes: [
- {
- name: 'json-modify-script',
- configMap: {
- name: jsonModifyConfig,
- },
- },
- {
- name: 'config-data',
- persistentVolumeClaim: {
- claimName: pvcClaimName,
- },
- },
- ],
- restartPolicy: 'Never',
- },
- },
- },
- },
- { ...resourceOptions }
- )
- // Create N validator service deployments
- const validators = []
- for (let i = 1; i <= numberOfValidators; i++) {
- const validator = new ValidatorServiceDeployment(
- `node-${i}`,
- { namespace: namespaceName, index: i, chainSpecPath, dataPath: chainDataPath, pvc: pvcClaimName, nodeImage },
- { ...resourceOptions, dependsOn: chainDataPrepareJob }
- )
- validators.push(validator)
- }
- const deployment = new k8s.apps.v1.Deployment(
- `rpc-node`,
- {
- metadata: {
- namespace: namespaceName,
- labels: appLabels,
- },
- spec: {
- replicas: 1,
- selector: { matchLabels: appLabels },
- template: {
- metadata: {
- labels: appLabels,
- },
- spec: {
- initContainers: [],
- containers: [
- {
- name: 'rpc-node',
- image: nodeImage,
- ports: [
- { name: 'rpc-9944', containerPort: 9944 },
- { name: 'rpc-9933', containerPort: 9933 },
- { name: 'rpc-30333', containerPort: 30333 },
- ],
- args: [
- '--chain',
- chainSpecPath,
- '--ws-external',
- '--rpc-cors',
- 'all',
- '--pruning',
- 'archive',
- '--ws-max-connections',
- '512',
- '--telemetry-url',
- 'wss://telemetry.joystream.org/submit/ 0',
- '--telemetry-url',
- 'wss://telemetry.polkadot.io/submit/ 0',
- ],
- volumeMounts: [
- {
- name: 'config-data',
- mountPath: chainDataPath,
- },
- ],
- },
- ],
- volumes: [
- {
- name: 'config-data',
- persistentVolumeClaim: {
- claimName: pvcClaimName,
- },
- },
- ],
- },
- },
- },
- },
- { ...resourceOptions, dependsOn: validators }
- )
- // Export the Deployment name
- export const deploymentName = deployment.metadata.name
- // Create a Service for the RPC Node
- const service = new k8s.core.v1.Service(
- name,
- {
- metadata: {
- labels: appLabels,
- namespace: namespaceName,
- name: 'node-network',
- },
- spec: {
- type: isMinikube ? 'NodePort' : 'ClusterIP',
- ports: [
- { name: 'port-1', port: 9944 },
- { name: 'port-2', port: 9933 },
- ],
- selector: appLabels,
- },
- },
- resourceOptions
- )
- // Export the Service name and public LoadBalancer Endpoint
- export const serviceName = service.metadata.name
- const lbReady = config.get('isLoadBalancerReady') === 'true'
- const caddyEndpoints = [
- `/ws-rpc {
- reverse_proxy node-network:9944
- }`,
- `/http-rpc {
- reverse_proxy node-network:9933
- }`,
- ]
- export let endpoint1: pulumi.Output<string>
- export let endpoint2: pulumi.Output<string>
- if (!isMinikube) {
- const caddy = new CaddyServiceDeployment(
- 'caddy-proxy',
- { lbReady, namespaceName: namespaceName, isMinikube, caddyEndpoints },
- resourceOptions
- )
- endpoint1 = pulumi.interpolate`${caddy.primaryEndpoint}`
- endpoint2 = pulumi.interpolate`${caddy.secondaryEndpoint}`
- }
|