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的服务,供集群内服务调用,并且早期的服务发现都是通过环境变量的方式注入到容器里面的,这些在上面的代码都有体现。
网友评论