k8s Elixir Client

repository·develop·Indexed 43 days ago

https://github.com/coryodaniel/k8s

A Kubernetes API client for Elixir providing a human-friendly API for interacting with clusters. It features automatic discovery of resources, CRDs, and groups, and supports multiple authentication methods including service accounts, kubeconfig files, and pluggable providers. Version 2.0 supports sub-resource operations like eviction and scaling, as well as asynchronous operations across multiple clusters.

Tokens
12.9K
Snippets
47
Records
62
Agent score
55%

What's inside k8s

  1. What is K8s Middleware and how is it structured?

    develop

    Middleware in this project is associated with a K8s.Conn. It is used to intercept and modify requests as they move through the stack.

    By default, every connection uses a K8s.Middleware.Stack containing the following request middleware:

    • K8s.Middleware.Request.Initialize
    • K8s.Middleware.Request.EncodeBody
  2. How Watch and Stream operations changed in version 2.0.0+

    develop
    In versions prior to 2.0.0, K8s.Client.watch/N was used to run a :list operation and watch it. In version 2.0.0 and later, K8s.Client.watch/N creates a :watch operation, which must then be passed to K8s.Client.stream/N to actually perform the streaming.
  3. How authentication strategies work in K8s

    develop

    The k8s library uses a pluggable authentication system where multiple strategies are attempted in a specific order. The first strategy that successfully authenticates the connection and returns an {:ok, K8s.Conn.Auth} struct is selected for the connection. If a strategy cannot authenticate the connection, it must return :skip to allow the next strategy in the chain to be attempted.

    By default, the library attempts these 5 strategies in this order:

    1. K8s.Conn.Auth.Certificate: Certificate-based authentication.
    2. K8s.Conn.Auth.Token: Token-based authentication.
    3. K8s.Conn.Auth.AuthProvider: Implements Kubernetes config file auth-provider functionality (allows shell calls to provide a Bearer Token).
    4. K8s.Conn.Auth.Exec: Implements Kubernetes config file exec functionality.
    5. K8s.Conn.Auth.BasicAuth: Username/password basic authentication.
  4. How K8s.Conn works

    develop
    A K8s.Conn is an abstraction that encapsulates all necessary cluster information and authentication required to interact with a Kubernetes API. It serves as the primary object used to establish identity and connectivity to a specific cluster. Connections can be derived from local files (kubeconfig), environment variables, service accounts (standard for in-cluster workloads), or built manually as a struct for dynamic, multi-tenant environments.
  5. How Discovery works in K8s

    develop

    The k8s library uses just-in-time discovery to identify cluster APIs and resource kinds. This allows the library to support various Kubernetes versions, CRDs, and enabled APIs without requiring pre-generated code from Swagger files.

    Discovery is handled automatically during HTTP requests, but you can also interact with the K8s.Discovery module directly. The system is pluggable via drivers, allowing you to swap how discovery information is retrieved.

  6. Configure a cluster connection

    develop

    Use the K8s.Conn module to establish connections to Kubernetes clusters. You can load connections from a kubeconfig file or from an in-cluster service account.

    • From a kubeconfig file: Use K8s.Conn.from_file/1 to use the current context, or K8s.Conn.from_file/2 to specify a :user, :cluster, or :context via a keyword list.
    • In-cluster: Use K8s.Conn.from_service_account/1 by providing the path to the service account directory.
    # Using a specific kubeconfig file with default context
    {:ok, conn} = K8s.Conn.from_file("path/to/kubeconfig.yaml")
    
    # Using a kubeconfig file with specific context/user/cluster
    {:ok, conn} = K8s.Conn.from_file("path/to/kubeconfig.yaml", context: "my-context")
    
    # Using in-cluster service account
    {:ok, conn} = K8s.Conn.from_service_account("/path/to/service-account/directory")
  7. Change a connection's middleware stack

    develop

    To replace the default middleware stack for a specific connection, create a new K8s.Middleware.Stack struct and assign it to the middleware field of your K8s.Conn struct. Note that this replaces the entire stack; if you want to add to the existing stack, you must include the default middlewares in your new list.

    {:ok, conn} = K8s.Conn.from_service_account()
    # Define a new stack with specific request middlewares
    new_stack = K8s.Middleware.Stack{request: [MyFirstMiddleware, MySecondMiddleware]}
    # Update the connection with the new stack
    conn_with_new_middleware = %K8s.Conn{conn | middleware: new_stack}
  8. Create a Deployment from a YAML file with interpolation

    develop

    Use K8s.Resource.from_file!/2 to parse a YAML file. This function supports ERB-style interpolation (e.g., <%= name %>). Pass an options map as the second argument to provide values for the interpolated variables. Once the resource is loaded, use K8s.Client.create/1 and K8s.Client.run/2 to deploy it.

    # Assuming priv/deployment.yaml contains interpolated fields like <%= name %>
    opts = [namespace: "default", name: "nginx", image: "nginx:1.7.9"]
    resource = K8s.Resource.from_file!("priv/deployment.yaml", opts)
    
    operation = K8s.Client.create(resource)
    {:ok, conn} = K8s.Conn.from_file("path/to/kubeconfig.yaml")
    {:ok, deployment} = K8s.Client.run(conn, operation)
  9. Enable structured logging with K8s.Sys.Logger

    develop

    To capture and log telemetry events produced by the library, you must attach the K8s.Sys.Logger telemetry handler. Once attached, K8s.Sys.Logger watches all telemetry events and logs them with :measurements and :metadata entries. All logs produced by the library include library: :k8s in their metadata, which can be used for filtering in structured logging systems.

    # In your application.ex
    K8s.Sys.Logger.attach()
  10. Work with Custom Resource Definitions (CRDs)

    develop

    Custom resources are discovered using the same mechanism as standard Kubernetes resources. You can list them by providing the API group/version and the resource kind.

    Example: Listing Greeting resources from the hello-operator.example.com/v1 API group in the default namespace.

    operation = K8s.Client.list("hello-operator.example.com/v1", :greeting, [namespace: "default"])
    {:ok, greeting} = K8s.Client.run(operation, :dev)
  11. Manage multiple Kubernetes clusters

    develop

    You can manage multiple clusters by creating separate connection objects using K8s.Conn. Common methods include:

    • K8s.Conn.from_file/1: Load configuration from a kubeconfig file (e.g., ~/.kube/config).
    • K8s.Conn.from_service_account/0: Use the service account credentials available within a pod.

    To move workloads between clusters, you can list resources from one connection and use K8s.Client.async/2 to create them on another connection.

    # 1. Register staging cluster
    {:ok, staging_conn} = K8s.Conn.from_file("~/.kube/config")
    
    # 2. Register prod cluster
    {:ok, prod_conn} = K8s.Conn.from_service_account()
    
    # 3. Get deployments from prod
    operation = K8s.Client.list("apps/v1", :deployment, namespace: "default")
    {:ok, deployments} = K8s.Client.run(prod_conn, operation)
    
    # 4. Map deployments to create operations for staging
    operations = Enum.map(deployments, fn(deployment) -> K8s.Client.create(deployment) end)
    
    # 5. Execute creation asynchronously on staging
    K8s.Client.async(staging_conn, operations)