{"id":19933009,"url":"https://github.com/kontena/k8s-client","last_synced_at":"2025-04-06T13:10:46.099Z","repository":{"id":48106230,"uuid":"139999816","full_name":"kontena/k8s-client","owner":"kontena","description":"Ruby Kubernetes API client","archived":false,"fork":false,"pushed_at":"2022-09-28T18:32:04.000Z","size":326,"stargazers_count":76,"open_issues_count":21,"forks_count":26,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-30T11:11:11.496Z","etag":null,"topics":["kubernetes","ruby"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/kontena.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":"2018-07-06T15:13:52.000Z","updated_at":"2024-02-07T12:48:03.000Z","dependencies_parsed_at":"2022-08-12T18:40:55.015Z","dependency_job_id":null,"html_url":"https://github.com/kontena/k8s-client","commit_stats":null,"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kontena%2Fk8s-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kontena%2Fk8s-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kontena%2Fk8s-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kontena%2Fk8s-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kontena","download_url":"https://codeload.github.com/kontena/k8s-client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247485287,"owners_count":20946398,"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","ruby"],"created_at":"2024-11-12T23:12:18.913Z","updated_at":"2025-04-06T13:10:46.061Z","avatar_url":"https://github.com/kontena.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# K8s::Client\n\n[![Build Status](https://travis-ci.com/kontena/k8s-client.svg?branch=master)](https://travis-ci.com/kontena/k8s-client)\n[![Gem Version](https://badge.fury.io/rb/k8s-client.svg)](https://badge.fury.io/rb/k8s-client)\n[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://www.rubydoc.info/github/kontena/k8s-client/master)\n\n\nRuby client library for the Kubernetes (1.9+) API\n\n## Highlights\n\n* Clean API for dynamic Kubernetes API Groups / Resources\n* Fast API requests using HTTP connection keepalive\n* Fast API discovery and resource listings using pipelined HTTP requests\n* Typed errors with useful debugging information\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'k8s-client'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install k8s-client\n\nAnd then load the code using:\n\n```ruby\nrequire 'k8s-client'\n```\n\nTo use the [yajl-ruby](https://github.com/brianmario/yajl-ruby) JSON parser backend, add `yalj-ruby` to your Gemfile:\n\n```ruby\ngem 'yajl-ruby'\ngem 'k8s-client'\n```\n\nAnd then load the code using:\n\n```ruby\nrequire 'k8s-client'\nrequire 'k8s/json_parser/yajl'\n```\n\n## Usage\n\n### Overview\nThe top-level `K8s::Client` provides access to separate `APIClient` instances for each Kubernetes API Group (`v1`, `apps/v1`, etc.), which in turns provides access to separate `ResourceClient` instances for each API resource type (`nodes`, `pods`, `deployments`, etc.).\n\nIndividual resources are returned as `K8s::Resource` instances, which provide attribute access (`resource.metadata.name`). The resource instances are returned by methods such as `client.api('v1').resource('nodes').get('foo')`, and passed as arguments for `client.api('v1').resource('nodes').create_resource(res)`. Resources can also be loaded from disk using `K8s::Resource.from_files(path)`, and passed to the top-level methods such as `client.create_resource(res)`, which lookup the correct API/Resource client from the resource `apiVersion` and `kind`.\n\nThe different `K8s::Error::API` subclasses represent different HTTP response codes, such as `K8s::Error::NotFound` or `K8s::Error::Conflict`.\n\n### Creating a client\n\n#### Unauthenticated client\n\n```ruby\nclient = K8s.client('https://localhost:6443', ssl_verify_peer: false)\n```\n\nThe keyword options are [Excon](https://github.com/excon/excon/) options.\n\n#### Client from kubeconfig\n\n```ruby\nclient = K8s::Client.config(\n  K8s::Config.load_file(\n    File.expand_path '~/.kube/config'\n  )\n)\n```\n\n#### Supported kubeconfig options\n\nNot all kubeconfig options are supported, only the following kubeconfig options work:\n\n* `current-context`\n* `context.cluster`\n* `context.user`\n* `cluster.server`\n* `cluster.insecure_skip_tls_verify`\n* `cluster.certificate_authority`\n* `cluster.certificate_authority_data`\n* `user.client_certificate` + `user.client_key`\n* `user.client_certificate_data` + `user.client_key_data`\n* `user.token`\n\n##### With overrides\n\n```ruby\nclient = K8s::Client.config(K8s::Config.load_file('~/.kube/config'),\n  server: 'http://localhost:8001',\n)\n```\n\n#### In-cluster client from pod envs/secrets\n\n```ruby\nclient = K8s::Client.in_cluster_config\n```\n\n### Logging\n\n#### Quiet\n\nTo supress any warning messages:\n\n```ruby\nK8s::Logging.quiet!\nK8s::Transport.quiet!\n```\n\nThe `K8s::Transport` is quiet by default, but other components may log warnings in the future.\n\n#### Debugging\n\nLog all API requests\n\n```ruby\nK8s::Logging.debug!\nK8s::Transport.verbose!\n```\n\n```\nI, [2018-08-09T14:19:50.404739 #1]  INFO -- K8s::Transport: Using config with server=https://167.99.39.233:6443\nI, [2018-08-09T14:19:50.629521 #1]  INFO -- K8s::Transport\u003chttps://167.99.39.233:6443\u003e: GET /version =\u003e HTTP 200: \u003cK8s::Resource\u003e in 0.224s\nI, [2018-08-09T14:19:50.681367 #1]  INFO -- K8s::Transport\u003chttps://167.99.39.233:6443\u003e: GET /api/v1 =\u003e HTTP 200: \u003cK8s::Resource\u003e in 0.046s\nI, [2018-08-09T14:19:51.018740 #1]  INFO -- K8s::Transport\u003chttps://167.99.39.233:6443\u003e: GET /api/v1/pods =\u003e HTTP 200: \u003cK8s::Resource\u003e in 0.316s\n```\n\nUsing `K8s::Transport.debug!` will also log request/response bodies. The `EXCON_DEBUG=true` env will log all request/response attributes, including headers.\n\n### Prefetching API resources\n\nOperations like mapping a resource `kind` to an API resource URL require knowledge of the API resource lists for the API group. Mapping resources for multiple API groups would require fetching the API resource lists for each API group in turn, leading to additional request latency. This can be optimized using resource prefetching:\n\n```ruby\nclient.apis(prefetch_resources: true)\n```\n\nThis will fetch the API resource lists for all API groups in a single pipelined request.\n\n### Listing resources\n\n```ruby\nclient.api('v1').resource('pods', namespace: 'default').list(labelSelector: {'role' =\u003e 'test'}).each do |pod|\n  puts \"namespace=#{pod.metadata.namespace} pod: #{pod.metadata.name} node=#{pod.spec.nodeName}\"\nend\n```\n\n### Updating resources\n\n```ruby\nnode = client.api('v1').resource('nodes').get('test-node')\n\nnode[:spec][:unschedulable] = true\n\nclient.api('v1').resource('nodes').update_resource(node)\n```\n\n### Deleting resources\n\n```ruby\npod = client.api('v1').resource('pods', namespace: 'default').delete('test-pod')\n```\n\n```ruby\npods = client.api('v1').resource('pods', namespace: 'default').delete_collection(labelSelector: {'role' =\u003e 'test'})\n```\n\n### Creating resources\n\n#### Programmatically defined resources\n```ruby\nservice = K8s::Resource.new(\n  apiVersion: 'v1',\n  kind: 'Service',\n  metadata: {\n    namespace: 'default',\n    name: 'test',\n  },\n  spec: {\n    type: 'ClusterIP',\n    ports: [\n      { port: 80 },\n    ],\n    selector: {'app' =\u003e 'test'},\n  },\n)\n\nlogger.info \"Create service=#{service.metadata.name} in namespace=#{service.metadata.namespace}\"\n\nservice = client.api('v1').resource('services').create_resource(service)\n```\n\n#### From file(s)\n\n```ruby\nresources = K8s::Resource.from_files('./test.yaml')\n\nfor resource in resources\n  resource = client.create_resource(resource)\nend\n```\n\n### Patching resources\n\n```ruby\nclient.api('apps/v1').resource('deployments', namespace: 'default').merge_patch('test', {\n    spec: { replicas: 3 },\n})\n```\n\n### Watching resources\n\n```ruby\nclient.api('v1').resource('pods', namespace: 'default').watch(labelSelector: {'role' =\u003e 'test'}) do |watch_event|\n  puts \"type=#{watch_event.type} pod=#{watch_event.resource.metadata.name}\"\nend\n```\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/kontena/k8s-client.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkontena%2Fk8s-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkontena%2Fk8s-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkontena%2Fk8s-client/lists"}