Pod内进程访问k8s服务

Pod内进程访问k8s服务

外部服务可以通过kubeconfig访问k8s服务,那k8s集群内部服务(Pos内服务)如何访问k8s?

kubeconfig

用configMap保存kueconfig以及ca,供服务访问。这个比较简单,不扩展。

serviceaccount

sa是给运行在Pod中的进程用的,它为Pod里的进程提供必要的身份证明。

sa中有token、ca.crt以及namespace信息。serviceaccount controller保证了每个namespace下都有一个名为default的sa。

通过sa我们就可以访问k8s服务,以下是k8s.io\client-go\rest\config.go中的方法,描述了如何利用sa进行访问。

// InClusterConfig returns a config object which uses the service account
// kubernetes gives to pods. It's intended for clients that expect to be
// running inside a pod running on kubernetes. It will return an error if
// called from a process not running in a kubernetes environment.
func InClusterConfig() (*Config, error) {
    host, port := os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")
    if len(host) == 0 || len(port) == 0 {
        return nil, fmt.Errorf("unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined")
    }

    token, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/" + api.ServiceAccountTokenKey)
    if err != nil {
        return nil, err
    }
    tlsClientConfig := TLSClientConfig{}
    rootCAFile := "/var/run/secrets/kubernetes.io/serviceaccount/" + api.ServiceAccountRootCAKey
    if _, err := certutil.NewPool(rootCAFile); err != nil {
        glog.Errorf("Expected to load root CA config from %s, but got err: %v", rootCAFile, err)
    } else {
        tlsClientConfig.CAFile = rootCAFile
    }

    return &Config{
        // TODO: switch to using cluster DNS.
        Host:            "https://" + net.JoinHostPort(host, port),
        BearerToken:     string(token),
        TLSClientConfig: tlsClientConfig,
    }, nil
}

本质上,sa就是一个目录/var/run/secrets/kubernetes.io/serviceaccount,k8s创建容器的时候都会将default sa挂载到Pod里。

关于k8s服务地址,默认k8s都会起一个名为kubernetes的服务,供集群内服务调用,并且早期的服务发现都是通过环境变量的方式注入到容器里面的,这些在上面的代码都有体现。

你可能感兴趣的:(Pod内进程访问k8s服务)