{"id":37153570,"url":"https://github.com/zizon/kbasectl","last_synced_at":"2026-01-14T18:02:18.571Z","repository":{"id":146281165,"uuid":"299924361","full_name":"zizon/kbasectl","owner":"zizon","description":"tools to create deployments with cephfs mount on kubenetes","archived":true,"fork":false,"pushed_at":"2020-11-13T07:33:06.000Z","size":65,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-03-23T21:52:19.174Z","etag":null,"topics":["ceph","cephfs","kubernets"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zizon.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-30T13:15:39.000Z","updated_at":"2024-06-19T09:14:32.657Z","dependencies_parsed_at":"2024-06-19T09:14:29.949Z","dependency_job_id":null,"html_url":"https://github.com/zizon/kbasectl","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/zizon/kbasectl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zizon%2Fkbasectl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zizon%2Fkbasectl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zizon%2Fkbasectl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zizon%2Fkbasectl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zizon","download_url":"https://codeload.github.com/zizon/kbasectl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zizon%2Fkbasectl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28429373,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T16:38:47.836Z","status":"ssl_error","status_checked_at":"2026-01-14T16:34:59.695Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["ceph","cephfs","kubernets"],"created_at":"2026-01-14T18:02:17.785Z","updated_at":"2026-01-14T18:02:18.563Z","avatar_url":"https://github.com/zizon.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kbasectl\nKubernetes config generator for ceph base deployment. \n\n# Prerequirement\n- A running `CephFS` Cluster(optional if Pod/Deploymnet not mouting a cephfs), with a moutable auth token\n- A running `Kubernets` Cluster, with an `ServiceAccount` bindto `cluster-admin` `ClusterRole` (not strictly required.)\n  - ReadWrite of Namespace (for creation of seperated namespace of each deployment)\n  - ReadWrite of PersistenVolume (for pv creation of each deployment namesapce)\n  - ReadWrite of PersistenVolumeClaim (for pvc creation of each deployment namesapce)\n  - ReadWrite of Secrets (ceph token creation if not exists,can be revoke if surealy exists)\n  - ReadWrite of ConfigMaps (config maps associated with each deployment)\n  \n# Setup\ninit a Config file located at ~/.kbasectl/config.yaml\n```yaml\nrest:\n  bearertoken: $(service-account-token)\n  host: $(k8s-api-server)\n  tlsclientconfig:\n    insecure: true \nceph:\n  monitors: \n    - $(cpeh-monitor-1-ip)\n    - $(ceph-monitor-2-ip)\n  user: $(ceph-auth-token-owner)\n  token: $(ceph-token)\n```\n- $(service-account-token) token of service account that has ability describel above\n- $(k8s-api-server) Kubernetes API Server\n- $(cpeh-monitor-n-ip) Ceph Monitor nodes. Better to have an DNS name, Since Ceph Cluster can change its monitor groups.  \nIn case of all `old` monitors are removed, Ceph PersistenVolumes assoicalted with this monitors maybe dyfunctional.  \nWith DNS resolvalbe name help overcome this situations.\n- $(ceph-auth-token-owner) users that initial mount for each ceph container volume.(default to admin)\n- $(ceph-token) tokens that use to authenticate $(ceph-auth-token-owner).(default ot admin-token)\n\n# Example\nSaid, \n1. you want to create a deployment in namesapce `test-namespace`,assining name `test-deploy` for reference.  \n2. user docker.io/golang:v15.2 as single container image in pod of this deployment.  \n  - bring ins env: `hello`:`kitty` as contaienr exexcution enviroment variable\n  - /work as working dir and /work/entrypoint.sh as startup script\n  - resource requiremnts are:\n    - CPU 1\n    - Memory 100m\n    - Network Ingress/Outgress: 60/50 mbps\n  - runas root(uid=0)\n3. mounting ceph path /cephfs/template/some-binary to contaienr path /work/bin/some-binary unmodifiable.\n4. also you may want to map local config file `./some-config.xml` to be mounted to `/configmaps/default.xml`\n5. and may be label this deployment with label just:test\n6. finnlay run 5 replca of this kind of pod  \n\nGiven config files bellow can satisfied above.\n```yaml template.yaml\nnamespace: test-namespace\nname: test-deploy\nlabels:\n  just: test\nenvs:\n  hello: kitty\nrunas: 0\nentrypoint: \"/bin/bash /work/entrypoint.sh\"\nworkdir: \"/work\"\nimage: docker.io/golang:v15.2\ncpu: 1\nmemorymb: 100\ningressmb: 60\negressmb: 50\nconfigfiles:\n- from: ./some-config.xml\n  maptokey: default.xml\nreplica: 5\ncephbind:\n- from: /cephfs/template\n  to: /work/bin/\n  readonly: true\n  capacitymb: 65536\n  filter:\n  - some-binary\n```\n\nWith simple command\n```bash\n./kbasectl gen -f template.yaml\n```\n\nWill Generate Kubernetes/kubectp apply usable configs\n```yaml\n---\napiVersion: v1\nkind: Namespace\nmetadata:\n  creationTimestamp: null\n  name: test-namespace\nspec: {}\nstatus: {}\n...\n---\napiVersion: v1\nkind: Namespace\nmetadata:\n  creationTimestamp: null\n  name: kbase\nspec: {}\nstatus: {}\n...\n---\napiVersion: v1\nkind: Secret\nmetadata:\n  creationTimestamp: null\n  name: ceph-kbase-token\n  namespace: kbase\nstringData:\n  $(ceph-auth-token-owner): $(ceph-token)\n...\n---\napiVersion: v1\ndata:\n  default.xml: |\n    \u003cexample-config/\u003e\nkind: ConfigMap\nmetadata:\n  creationTimestamp: null\n  name: test-deploy-configmap\n  namespace: test-namespace\n...\n---\napiVersion: v1\nkind: PersistentVolume\nmetadata:\n  creationTimestamp: null\n  name: ceph-volume-read--cephfs-template\nspec:\n  accessModes:\n  - ReadWriteMany\n  - ReadOnlyMany\n  capacity:\n    storage: 65536M\n  cephfs:\n    monitors:\n    - $(ceph-monitor-1-ip)\n    - $(ceph-monitor-2-ip)\n    path: /cephfs/template\n    secretRef:\n      name: ceph-kbase-token\n      namespace: kbase\n    user: admin\n  persistentVolumeReclaimPolicy: Retain\nstatus: {}\n...\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n  creationTimestamp: null\n  name: ceph-volume-read--cephfs-template\n  namespace: test-namespace\nspec:\n  accessModes:\n  - ReadOnlyMany\n  resources:\n    requests:\n      storage: 65536M\n  volumeName: ceph-volume-read--cephfs-template\nstatus: {}\n...\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  creationTimestamp: null\n  labels:\n    just: test\n    kbase-pod: test-deploy\n  name: test-deploy\n  namespace: test-namespace\nspec:\n  replicas: 5\n  selector:\n    matchLabels:\n      just: test\n      kbase-pod: test-deploy\n  strategy:\n    rollingUpdate:\n      maxSurge: 1\n      maxUnavailable: 1\n  template:\n    metadata:\n      creationTimestamp: null\n      labels:\n        just: test\n        kbase-pod: test-deploy\n      name: test-deploy\n      namespace: test-namespace\n    spec:\n      containers:\n      - command:\n        - /bin/bash /work/entrypoint.sh\n        env:\n        - name: CONTAINER_ID\n          valueFrom:\n            fieldRef:\n              fieldPath: metadata.name\n        - name: CONTAINER_NAMESPACE\n          valueFrom:\n            fieldRef:\n              fieldPath: metadata.namespace\n        - name: CONTAINER_HOST_IP\n          valueFrom:\n            fieldRef:\n              fieldPath: status.hostIP\n        - name: CONTAINER_IP\n          valueFrom:\n            fieldRef:\n              fieldPath: status.podIP\n        - name: hello\n          value: kitty\n        image: docker.io/golang:v15.2\n        name: test-deploy\n        resources:\n          requests:\n            cpu: \"1\"\n            memory: 100M\n        volumeMounts:\n        - mountPath: /work/bin/some-binary\n          name: ceph-volume-read--cephfs-template\n          readOnly: true\n          subPathExpr: some-binary\n        - mountPath: /configmaps\n          name: test-deploy-configmap\n          readOnly: true\n        workingDir: /work\n      hostNetwork: true\n      securityContext:\n        runAsGroup: 0\n        runAsUser: 0\n      volumes:\n      - name: ceph-volume-read--cephfs-template\n        persistentVolumeClaim:\n          claimName: ceph-volume-read--cephfs-template\n          readOnly: true\n      - configMap:\n          name: test-deploy-configmap\n        name: test-deploy-configmap\nstatus: {}\n...\n```\n\n# Without Ceph\nTake for example,to setup a `IPFS` node\n```yaml ipfs.yaml\nnamespace: ipfs\nname: ipfs-daemon\nrunas: 0\nentrypoint: /bin/sh /configmaps/ipfs.sh \nenvs:\n  IPFS_PATH: /work \nworkdir: \"/work\"\nimage: docker.io/ipfs/go-ipfs:v0.7.0\ncpu: 1\nmemorymb: 10\ningressmb: 1\negressmb: 1\nconfigfiles:\n  - from: ./config\n    maptokey: config\n  - from: ./ipfs.sh\n    maptokey: ipfs.sh\nreplica: 1 \n```\nWhile config are IPFS config, and `ipfs.sh` start script are looks like below.   \n```sh ipfs.sh\n#!/bin/sh\n/usr/local/bin/ipfs daemon --init --init-config /configmaps/config\n```\n\nUsing \n```bash\nkbasectl gen -f ipfs.yaml \u003e ipfs-k8s.yaml\n```\n\nGenreate\n```yaml\n---\napiVersion: v1\nkind: Namespace\nmetadata:\n  creationTimestamp: null\n  name: ipfs\nspec: {}\nstatus: {}\n...\n---\napiVersion: v1\ndata:\n  config: |\n    {\n      \"API\": {\n        \"HTTPHeaders\": {}\n      },\n      \"Addresses\": {\n        \"API\": \"/ip4/127.0.0.1/tcp/5001\",\n        \"Announce\": [],\n        \"Gateway\": \"/ip4/127.0.0.1/tcp/8080\",\n        \"NoAnnounce\": [],\n        \"Swarm\": [\n          \"/ip4/0.0.0.0/tcp/4001\",\n          \"/ip6/::/tcp/4001\",\n          \"/ip4/0.0.0.0/udp/4001/quic\",\n          \"/ip6/::/udp/4001/quic\"\n        ]\n      },\n      \"AutoNAT\": {},\n      \"Bootstrap\": [\n        \"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa\",\n        \"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb\",\n        \"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt\",\n        \"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ\",\n        \"/ip4/104.131.131.82/udp/4001/quic/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ\",\n        \"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN\"\n      ],\n      \"Datastore\": {\n        \"BloomFilterSize\": 0,\n        \"GCPeriod\": \"1h\",\n        \"HashOnRead\": false,\n        \"Spec\": {\n          \"mounts\": [\n            {\n              \"child\": {\n                \"path\": \"blocks\",\n                \"shardFunc\": \"/repo/flatfs/shard/v1/next-to-last/2\",\n                \"sync\": true,\n                \"type\": \"flatfs\"\n              },\n              \"mountpoint\": \"/blocks\",\n              \"prefix\": \"flatfs.datastore\",\n              \"type\": \"measure\"\n            },\n            {\n              \"child\": {\n                \"compression\": \"none\",\n                \"path\": \"datastore\",\n                \"type\": \"levelds\"\n              },\n              \"mountpoint\": \"/\",\n              \"prefix\": \"leveldb.datastore\",\n              \"type\": \"measure\"\n            }\n          ],\n          \"type\": \"mount\"\n        },\n        \"StorageGCWatermark\": 90,\n        \"StorageMax\": \"100MB\"\n      },\n      \"Discovery\": {\n        \"MDNS\": {\n          \"Enabled\": true,\n          \"Interval\": 10\n        }\n      },\n      \"DontCheckOSXFUSE\": false,\n      \"Experimental\": {\n        \"FilestoreEnabled\": true,\n        \"GraphsyncEnabled\": false,\n        \"Libp2pStreamMounting\": true,\n        \"P2pHttpProxy\": false,\n        \"ShardingEnabled\": false,\n        \"StrategicProviding\": false,\n        \"UrlstoreEnabled\": true\n      },\n      \"Gateway\": {\n        \"APICommands\": [],\n        \"HTTPHeaders\": {\n          \"Access-Control-Allow-Headers\": [\n            \"X-Requested-With\",\n            \"Range\",\n            \"User-Agent\"\n          ],\n          \"Access-Control-Allow-Methods\": [\n            \"GET\"\n          ],\n          \"Access-Control-Allow-Origin\": [\n            \"*\"\n          ]\n        },\n        \"NoDNSLink\": false,\n        \"NoFetch\": false,\n        \"PathPrefixes\": [],\n        \"PublicGateways\": null,\n        \"RootRedirect\": \"\",\n        \"Writable\": false\n      },\n      \"Identity\": {\n        \"PeerID\": \"\",\n        \"PrivKey\": \"\"\n      },\n      \"Ipns\": {\n        \"RecordLifetime\": \"\",\n        \"RepublishPeriod\": \"\",\n        \"ResolveCacheSize\": 128\n      },\n      \"Mounts\": {\n        \"FuseAllowOther\": false,\n        \"IPFS\": \"~/ipfs\",\n        \"IPNS\": \"~/ipns\"\n      },\n      \"Peering\": {\n        \"Peers\": null\n      },\n      \"Plugins\": {\n        \"Plugins\": null\n      },\n      \"Provider\": {\n        \"Strategy\": \"\"\n      },\n      \"Pubsub\": {\n        \"DisableSigning\": false,\n        \"Router\": \"\"\n      },\n      \"Reprovider\": {\n        \"Interval\": \"12h\",\n        \"Strategy\": \"all\"\n      },\n      \"Routing\": {\n        \"Type\": \"dht\"\n      },\n      \"Swarm\": {\n        \"AddrFilters\": null,\n        \"ConnMgr\": {\n          \"GracePeriod\": \"60s\",\n          \"HighWater\": 300,\n          \"LowWater\": 50,\n          \"Type\": \"basic\"\n        },\n        \"DisableBandwidthMetrics\": false,\n        \"DisableNatPortMap\": false,\n        \"EnableAutoRelay\": false,\n        \"EnableRelayHop\": false,\n        \"Transports\": {\n          \"Multiplexers\": {},\n          \"Network\": {\n            \"TCP\": false,\n            \"Websocket\": false\n          },\n          \"Security\": {}\n        }\n      }\n    }\n  ipfs.sh: |\n    #!/bin/bash\n    /usr/local/bin/ipfs daemon --init --init-config /configmaps/config\nkind: ConfigMap\nmetadata:\n  creationTimestamp: null\n  name: ipfs-daemon-configmap\n  namespace: ipfs\n...\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  creationTimestamp: null\n  labels:\n    kbase-pod: ipfs-daemon\n  name: ipfs-daemon\n  namespace: ipfs\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      kbase-pod: ipfs-daemon\n  strategy:\n    rollingUpdate:\n      maxSurge: 1\n      maxUnavailable: 1\n  template:\n    metadata:\n      creationTimestamp: null\n      labels:\n        kbase-pod: ipfs-daemon\n      name: ipfs-daemon\n      namespace: ipfs\n    spec:\n      containers:\n      - command:\n        - /bin/sh\n        - /configmaps/ipfs.sh\n        env:\n        - name: CONTAINER_ID\n          valueFrom:\n            fieldRef:\n              fieldPath: metadata.name\n        - name: CONTAINER_NAMESPACE\n          valueFrom:\n            fieldRef:\n              fieldPath: metadata.namespace\n        - name: CONTAINER_HOST_IP\n          valueFrom:\n            fieldRef:\n              fieldPath: status.hostIP\n        - name: CONTAINER_IP\n          valueFrom:\n            fieldRef:\n              fieldPath: status.podIP\n        - name: IPFS_PATH\n          value: /work\n        image: docker.io/ipfs/go-ipfs:v0.7.0\n        name: ipfs-daemon\n        resources:\n          requests:\n            cpu: \"1\"\n            memory: 10M\n        volumeMounts:\n        - mountPath: /configmaps\n          name: ipfs-daemon-configmap\n          readOnly: true\n        workingDir: /work\n      hostNetwork: true\n      securityContext:\n        runAsGroup: 0\n        runAsUser: 0\n      volumes:\n      - configMap:\n          name: ipfs-daemon-configmap\n        name: ipfs-daemon-configmap\nstatus: {}\n...\n\n```\n\n# Know Issues\n1. PVs can not be modified after creation.  \n  Repeatly apply the sampe config gen above will cause kubectl to complain. To workaround, simple add an -m(inmal) flag to check if a resource already exits in k8s.  \n  If so, hide it in generated config\n2. PV/PVC capacity is currently meaning less\n3. Container use host network\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzizon%2Fkbasectl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzizon%2Fkbasectl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzizon%2Fkbasectl/lists"}