Skip to content

A Kubernetes-native way of deploying Monero nodes and even whole networks: express your intention and let Kubernetes run it for you.

License

Notifications You must be signed in to change notification settings

cirocosta/monero-operator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

monero-operator

A Kubernetes-native way of deploying Monero nodes, networks, and miners: express your intention and let Kubernetes run it for you.



you: "Hi, I'd like two public nodes, and three miners please".

k8s: "Sure thing"

k8s: "It looks like you want two public nodes, but I see 0 running - let me create them for you."

k8s: "It looks like you want three miners, but I see 0 running - let me create them for you."

you: "Actually, I changed my mind - I don't want to mine on minexmr, I want cryptonode.social".

k8s: "Good choice, pool concentration sucks - let me update your miners for you :)"



See ./docs for detailed documentation about each resource.



Example

Full node

To run a single full node, all you need to do is create a single-replica MoneroNodeSet.

kind: MoneroNodeSet
apiVersion: utxo.com.br/v1alpha1
metadata:
  name: full-node
spec:
  replicas: 1

With a MoneroNodeSet you express the intention of having a set of monerod nodes running with a particular configuration: you express your intent, and monero-operator takes care of making it happen.

For instance, with kubectl-tree we can see that the operator took care of instantiating a StatefulSet

$ kubectl  tree moneronodeset.utxo.com.br full-node
NAMESPACE  NAME                                         READY
default    MoneroNodeSet/full-node                      True 
default    ├─Service/full-node                          -    
default    │ └─EndpointSlice/full-node-d2crv            -    
default    └─StatefulSet/full-node                      -    
default      ├─ControllerRevision/full-node-856644d54d  -    
default      └─Pod/full-node-0                          True 

with a pre-configured set of flags

$ kubectl get pod full-node-0 -ojsonpath={.spec.containers[*].command} | jq '.'
[
  "monerod",
  "--data-dir=/data",
  "--log-file=/dev/stdout",
  "--no-igd",
  "--no-zmq",
  "--non-interactive",
  "--p2p-bind-ip=0.0.0.0",
  "--p2p-bind-port=18080",
  "--rpc-restricted-bind-ip=0.0.0.0",
  "--rpc-restricted-bind-port=18089"
]

and a PersistentVolumeClaim attached with enough disk space for it.

$ kubectl get pvc
kubectl get pvc
NAME               STATUS   VOLUME                                     CAPACITY
data-full-node-0   Bound    pvc-1c60e835-d5f9-41c9-8509-b0e4b3b71f6b   200Gi    

With that all being declarative, updating our node is a matter of expressing our new intent by updating the MoneroNodeSet definition, and letting the operator take care of updating things behind the scene.

For instance, assuming we want to now make it public, accepting lots of peers, having a higher bandwidth limit and using dns blocklist and checkpointing, we'd patch the object with the following:

kind: MoneroNodeSet
apiVersion: utxo.com.br/v1alpha1
metadata:
  name: full-set
spec:
  replicas: 1

  monerod:
    args:
      - --public
      - --enable-dns-blocklist
      - --enforce-dns-checkpointing
      - --out-peers=1024
      - --in-peers=1024
      - --limit-rate=128000

Which would then lead to an update to the node (Kubernetes takes care of signalling the monerod, waiting for it to finish gracefully - did I mention that it has properly set readiness probes too? -, detaching the disk, etc etc).

Mining cluster

Similar to MoneroNodeSet, with a MoneroMiningNodeSet you express the intention of having a cluster o x replicas running, and then the operator takes care of making that happen.

For instance, to run a set of 5 miners spread across different Kubernetes nodes:

kind: MoneroMiningNodeSet
apiVersion: utxo.com.br/v1alpha1
metadata:
  name: miners
spec:
  replicas: 5
  hardAntiAffinity: true

  xmrig:
    args:
      - -o
      - cryptonote.social:5556
      - -u
      - 891B5keCnwXN14hA9FoAzGFtaWmcuLjTDT5aRTp65juBLkbNpEhLNfgcBn6aWdGuBqBnSThqMPsGRjWVQadCrhoAT6CnSL3.node-$(id)
      - --tls

ps.: $(id) is indeed a thing - wherever you put it, it's going to be interpolated with an integer that identifies the replica pps.: xmrig is used under the hood

Private network

With a MoneroNetwork you express the intention of having a network of inter-connected Monero nodes, taking care of not only bringing monerod up for you, but also providing the proper flags for each daemon so that they are exclusive nodes of themselves.

For instance, consider the following private regtest setup:

kind: MoneroNetwork
apiVersion: utxo.com.br/v1alpha1
metadata:
  name: regtest
spec:
  replicas: 3

  template:
    spec:
      monerod:
        args:
          - --regtest
          - --fixed-difficulty=1

Under the hood, the following tree of objects gets formed:

$ kubectl tree moneronetwork.utxo.com.br regtest

  NAME                                          
  MoneroNetwork/regtest                         
  ├─MoneroNodeSet/regtest-0                     
  │ ├─Service/regtest-0                         
  │ │ └─EndpointSlice/regtest-0-plf9m           
  │ └─StatefulSet/regtest-0                     
  │   ├─ControllerRevision/regtest-0-6dc6799f4b 
  │   └─Pod/regtest-0-0                         
  ├─MoneroNodeSet/regtest-1                     
  │ ├─Service/regtest-1                         
  │ │ └─EndpointSlice/regtest-1-7sd9z           
  │ └─StatefulSet/regtest-1                     
  │   ├─ControllerRevision/regtest-1-5b5c6b7b8d 
  │   └─Pod/regtest-1-0                         
  └─MoneroNodeSet/regtest-2                     
    ├─Service/regtest-2                         
    │ └─EndpointSlice/regtest-2-rhmd9           
    └─StatefulSet/regtest-2                     
      ├─ControllerRevision/regtest-2-7fdbcdb57b 
      └─Pod/regtest-2-0                         

with each node with the flags properly set so that they are interconnected:

$ kubectl get pods -ojsonpath={.items[*].spec.containers[*].command} | jq '.'
[
  "monerod",
  "--add-exclusive-node=regtest-1",
  "--add-exclusive-node=regtest-2",
  "--fixed-difficulty=1",
...
]
[
  "monerod",
  "--add-exclusive-node=regtest-0",
  "--add-exclusive-node=regtest-2",
  "--fixed-difficulty=1",
...
]
[
  "monerod",
  "--add-exclusive-node=regtest-0",
  "--add-exclusive-node=regtest-1",
  "--fixed-difficulty=1",
...
]

Install

  1. install
# submit the customresourcedefinition objects, deployment, role-base access
# control configs, etc.
#
kubectl apply -f ./config/release.yaml

License

See ./LICENSE

About

A Kubernetes-native way of deploying Monero nodes and even whole networks: express your intention and let Kubernetes run it for you.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published