简体   繁体   中英

Access Kubernetes API from a pod in C#

I'm looking for a lightweight way to access the Kubernetes API from a Pod in a C# app.

Kubernetes docs mention two ways of accessing the API from a Pod :

  1. Run kubectl proxy in a sidecar container in the pod, or as a background process within the container

This generally works, and allows for easily hitting an API endpoint with just a line of code or two - example:

using System;
using System.Net;

namespace GetIngresses
{
    class Program
    {
        static void Main(string[] args)
        {
            var apiBaseUrl = "http://127.0.0.1:8001"; // requires kubectl proxy
            Console.WriteLine((new WebClient()).
             DownloadString($"{apiBaseUrl}/apis/networking.k8s.io/v1/ingresses"));
        }
    }
}

However, now there's a running kubectl proxy process to monitor, maintain etc. - this doesn't seem ideal for production.

  1. Use the Go client library, and create a client using the rest.InClusterConfig() and kubernetes.NewForConfig() functions. They handle locating and authenticating to the apiserver.

My app is written in C#, not Go. There's a C# client library which presumably might be able to achieve the same thing. But do I really have to bring a whole client library on board just for a simple GET to a single endpoint?

Ideally, I'd like to just use WebClient , like in the example above. Documentation mentions that

The recommended way to locate the apiserver within the pod is with the kubernetes.default.svc DNS name, which resolves to a Service IP which in turn will be routed to an apiserver.

So, in the example above, can I just do this...

var apiBaseUrl = "http://kubernetes.default.svc"

... and get WebClient to pass the required service account credentials? If yes, how?

Ideally, I'd like to just use WebClient

The Kubernetes is a REST API, so this would work. As shown on Directly accessing the REST API using kubectl proxy it is easy to explore the API using eg curl .

Example with curl and kubectl proxy - response is in json format.

curl http://localhost:8080/api/v1/pods

The complicating factor is that you probably need a private certificate bundle, and it is good practice to properly validate this for security reasons. When accessing the API from a Pod, the client certificate is located on /var/run/secrets/kubernetes.io/serviceaccount/ca.crt and in addition, you need to authenticate using the token located on /var/run/secrets/kubernetes.io/serviceaccount/token

But do I really have to bring a whole client library on board just for a simple GET to a single endpoint?

What you get from a client library is:

  • Implemented authentication using certificates and tokens
  • Typed client access - instead of hand code urls and requests

The dotnet-client example shows how the "Typed client access" looks like, for "listing Pods in the default namespace" (seeauthentication alternatives ):

var config = KubernetesClientConfiguration.InClusterConfig()  // auth from Pod
IKubernetes client = new Kubernetes(config);
Console.WriteLine("Starting Request!");

var list = client.ListNamespacedPod("default");
foreach (var item in list.Items)
{
    Console.WriteLine(item.Metadata.Name);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM