{"id":15146937,"url":"https://github.com/cirocosta/monero-operator","last_synced_at":"2025-10-24T01:31:17.495Z","repository":{"id":57614573,"uuid":"363493084","full_name":"cirocosta/monero-operator","owner":"cirocosta","description":"A Kubernetes-native way of deploying Monero nodes and even whole networks: express your intention and let Kubernetes run it for you.","archived":false,"fork":false,"pushed_at":"2021-06-06T11:48:49.000Z","size":2311,"stargazers_count":24,"open_issues_count":15,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-30T22:35:41.861Z","etag":null,"topics":["kubernetes","monero","monerod"],"latest_commit_sha":null,"homepage":"https://www.getmonero.org/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cirocosta.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-01T19:40:00.000Z","updated_at":"2025-01-16T04:56:14.000Z","dependencies_parsed_at":"2022-08-27T03:24:15.827Z","dependency_job_id":null,"html_url":"https://github.com/cirocosta/monero-operator","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cirocosta%2Fmonero-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cirocosta%2Fmonero-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cirocosta%2Fmonero-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cirocosta%2Fmonero-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cirocosta","download_url":"https://codeload.github.com/cirocosta/monero-operator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237901406,"owners_count":19384384,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kubernetes","monero","monerod"],"created_at":"2024-09-26T12:20:52.841Z","updated_at":"2025-10-24T01:31:10.946Z","avatar_url":"https://github.com/cirocosta.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# monero-operator\n\nA [Kubernetes]-native way of deploying [Monero] nodes, networks, and miners:\nexpress your intention and let Kubernetes run it for you.\n\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n\u003e **you:** _\"Hi, I'd like two public nodes, and three miners please\"._\n\u003e\n\u003e **k8s**: _\"Sure thing\"_\n\u003e\n\u003e **k8s**: _\"It looks like you want two public nodes, but I see 0 running - let me create them for you.\"_\n\u003e\n\u003e **k8s**: _\"It looks like you want three miners, but I see 0 running - let me create them for you.\"_\n\u003e\n\u003e **you:** _\"Actually, I changed my mind - I don't want to mine on `minexmr`, I want `cryptonode.social`\"._\n\u003e\n\u003e **k8s**: _\"Good choice, pool concentration sucks - let me update your miners for you :)\"_\n\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n\nSee [./docs](./docs) for detailed documentation about each resource.\n\n\u003cbr /\u003e\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n\n- [Example](#example)\n  - [Full node](#full-node)\n  - [Mining cluster](#mining-cluster)\n  - [Private network](#private-network)\n- [Install](#install)\n- [License](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n\n\u003cbr /\u003e\n\n## Example\n\n### Full node\n\nTo run a single full node, all you need to do is create a single-replica [`MoneroNodeSet`].\n\n```yaml\nkind: MoneroNodeSet\napiVersion: utxo.com.br/v1alpha1\nmetadata:\n  name: full-node\nspec:\n  replicas: 1\n```\n\nWith a `MoneroNodeSet` you express the intention of having a set of [`monerod`]\nnodes running with a particular configuration: you express your intent, and\n`monero-operator` takes care of making it happen.\n\nFor instance, with [kubectl-tree](https://github.com/ahmetb/kubectl-tree) we\ncan see that the operator took care of instantiating a\n[StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/)\n\n\n```console\n$ kubectl  tree moneronodeset.utxo.com.br full-node\nNAMESPACE  NAME                                         READY\ndefault    MoneroNodeSet/full-node                      True \ndefault    ├─Service/full-node                          -    \ndefault    │ └─EndpointSlice/full-node-d2crv            -    \ndefault    └─StatefulSet/full-node                      -    \ndefault      ├─ControllerRevision/full-node-856644d54d  -    \ndefault      └─Pod/full-node-0                          True \n```\n\nwith a pre-configured set of flags \n\n\n```console\n$ kubectl get pod full-node-0 -ojsonpath={.spec.containers[*].command} | jq '.'\n[\n  \"monerod\",\n  \"--data-dir=/data\",\n  \"--log-file=/dev/stdout\",\n  \"--no-igd\",\n  \"--no-zmq\",\n  \"--non-interactive\",\n  \"--p2p-bind-ip=0.0.0.0\",\n  \"--p2p-bind-port=18080\",\n  \"--rpc-restricted-bind-ip=0.0.0.0\",\n  \"--rpc-restricted-bind-port=18089\"\n]\n```\n\nand a\n[PersistentVolumeClaim](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)\nattached with enough disk space for it.\n\n```\n$ kubectl get pvc\nkubectl get pvc\nNAME               STATUS   VOLUME                                     CAPACITY\ndata-full-node-0   Bound    pvc-1c60e835-d5f9-41c9-8509-b0e4b3b71f6b   200Gi    \n```\n\nWith that all being declarative, updating our node is a matter of expressing\nour new intent by updating the [`MoneroNodeSet`] definition, and letting the\noperator take care of updating things behind the scene.\n\nFor instance, assuming we want to now make it public, accepting lots of peers,\nhaving a higher bandwidth limit and using dns blocklist and checkpointing, we'd\npatch the object with the following:\n\n\n```yaml\nkind: MoneroNodeSet\napiVersion: utxo.com.br/v1alpha1\nmetadata:\n  name: full-set\nspec:\n  replicas: 1\n\n  monerod:\n    args:\n      - --public\n      - --enable-dns-blocklist\n      - --enforce-dns-checkpointing\n      - --out-peers=1024\n      - --in-peers=1024\n      - --limit-rate=128000\n```\n\nWhich would then lead to an update to the node (Kubernetes takes care of\nsignalling the `monerod`, waiting for it to finish gracefully - did I mention\nthat it has properly set readiness probes too? -, detaching the disk, etc etc).\n\n\n### Mining cluster\n\nSimilar to [`MoneroNodeSet`], with a [`MoneroMiningNodeSet`] you express the\nintention of having a cluster o _x_ replicas running, and then the operator\ntakes care of making that happen.\n\nFor instance, to run a set of 5 miners spread across different Kubernetes\nnodes:\n\n```yaml\nkind: MoneroMiningNodeSet\napiVersion: utxo.com.br/v1alpha1\nmetadata:\n  name: miners\nspec:\n  replicas: 5\n  hardAntiAffinity: true\n\n  xmrig:\n    args:\n      - -o\n      - cryptonote.social:5556\n      - -u\n      - 891B5keCnwXN14hA9FoAzGFtaWmcuLjTDT5aRTp65juBLkbNpEhLNfgcBn6aWdGuBqBnSThqMPsGRjWVQadCrhoAT6CnSL3.node-$(id)\n      - --tls\n```\n\n_ps.: `$(id)` is indeed a thing - wherever you put it, it's going to be interpolated with an integer that identifies the replica_\n_pps.: `xmrig` is used under the hood_\n\n\n### Private network\n\nWith a [`MoneroNetwork`] you express the intention of having a network of\ninter-connected Monero nodes, taking care of not only bringing `monerod` up for\nyou, but also providing the proper flags for each daemon so that they are\nexclusive nodes of themselves.\n\nFor instance, consider the following private regtest setup:\n\n```yaml\nkind: MoneroNetwork\napiVersion: utxo.com.br/v1alpha1\nmetadata:\n  name: regtest\nspec:\n  replicas: 3\n\n  template:\n    spec:\n      monerod:\n        args:\n          - --regtest\n          - --fixed-difficulty=1\n```\n\nUnder the hood, the following tree of objects gets formed:\n\n```console\n$ kubectl tree moneronetwork.utxo.com.br regtest\n\n  NAME                                          \n  MoneroNetwork/regtest                         \n  ├─MoneroNodeSet/regtest-0                     \n  │ ├─Service/regtest-0                         \n  │ │ └─EndpointSlice/regtest-0-plf9m           \n  │ └─StatefulSet/regtest-0                     \n  │   ├─ControllerRevision/regtest-0-6dc6799f4b \n  │   └─Pod/regtest-0-0                         \n  ├─MoneroNodeSet/regtest-1                     \n  │ ├─Service/regtest-1                         \n  │ │ └─EndpointSlice/regtest-1-7sd9z           \n  │ └─StatefulSet/regtest-1                     \n  │   ├─ControllerRevision/regtest-1-5b5c6b7b8d \n  │   └─Pod/regtest-1-0                         \n  └─MoneroNodeSet/regtest-2                     \n    ├─Service/regtest-2                         \n    │ └─EndpointSlice/regtest-2-rhmd9           \n    └─StatefulSet/regtest-2                     \n      ├─ControllerRevision/regtest-2-7fdbcdb57b \n      └─Pod/regtest-2-0                         \n\n```\n\nwith each node with the flags properly set so that they are interconnected:\n\n```console\n$ kubectl get pods -ojsonpath={.items[*].spec.containers[*].command} | jq '.'\n[\n  \"monerod\",\n  \"--add-exclusive-node=regtest-1\",\n  \"--add-exclusive-node=regtest-2\",\n  \"--fixed-difficulty=1\",\n...\n]\n[\n  \"monerod\",\n  \"--add-exclusive-node=regtest-0\",\n  \"--add-exclusive-node=regtest-2\",\n  \"--fixed-difficulty=1\",\n...\n]\n[\n  \"monerod\",\n  \"--add-exclusive-node=regtest-0\",\n  \"--add-exclusive-node=regtest-1\",\n  \"--fixed-difficulty=1\",\n...\n]\n```\n\n\n## Install\n\n1. install\n\n```bash\n# submit the customresourcedefinition objects, deployment, role-base access\n# control configs, etc.\n#\nkubectl apply -f ./config/release.yaml\n```\n\n\n## License\n\nSee [./LICENSE](./LICENSE)\n\n\n[Monero]: https://www.getmonero.org/\n[`monerod`]: https://monerodocs.org/interacting/monerod-reference/\n[Kubernetes]: https://kubernetes.io\n[`MoneroNodeSet`]: /cirocosta/monero-operator/tree/master/docs#moneronodeset\n[`MoneroMiningNodeSet`]: /cirocosta/monero-operator/tree/master/docs#monerominingnodeset\n[`MoneroNetwork`]: /cirocosta/monero-operator/tree/master/docs#moneronetwork\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcirocosta%2Fmonero-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcirocosta%2Fmonero-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcirocosta%2Fmonero-operator/lists"}