如何从pod容器中访问Kubernetes api?

tsl*_*ter 103 kubernetes

我曾经能够卷曲

https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1beta3/namespaces/default/
Run Code Online (Sandbox Code Playgroud)

作为我的基本URL,但在kubernetes 0.18.0中它给了我"未经授权".奇怪的是,如果我使用API​​机器的外部IP地址(http://172.17.8.101:8080/api/v1beta3/namespaces/default/),它就可以正常工作.

tsl*_*ter 109

在官方文档中我发现了这个:

https://kubernetes.io/docs/tasks/administer-cluster/access-cluster-api/#accessing-the-api-from-a-pod

显然我错过了一个我在之前版本的Kubernetes中不需要的安全令牌.从那时起,我设计了一个比运行代理或在容器上安装golang更简单的解决方案.请参阅此示例,该示例从api获取当前容器的信息:

KUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -sSk -H "Authorization: Bearer $KUBE_TOKEN" \
      https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/default/pods/$HOSTNAME
Run Code Online (Sandbox Code Playgroud)

我还使用包含一个简单的二进制文件jq(http://stedolan.github.io/jq/download/)来解析json以用于bash脚本.

  • 请注意,此curl命令会将*insecurely*连接到apiserver(使得中间人可以拦截持有者令牌),因此只有当pod和apiserver之间的网络完全无法使用时才应使用它值得信赖的.否则,您应该将`--cacert`标志传递给curl,以便curl验证apiserver提供的证书. (6认同)
  • 对于最近部署的集群,您可能希望将"v1beta3"更改为"v1" (5认同)

Rob*_*ley 67

每个pod都有一个自动应用的服务帐户,允许它访问apiserver.服务帐户以持有者令牌的形式提供客户端凭证,以及用于签署由许可者提供的证书的证书颁发机构证书.使用这两条信息,您可以创建与apisever的安全,经过身份验证的连接,而无需使用curl -k(aka curl --insecure):

curl -v --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc/
Run Code Online (Sandbox Code Playgroud)

  • 我从具有不同命名空间的pod访问API服务器.因此我不得不使用`https:// kubernetes.default /`作为主持人 (7认同)
  • 应该注意的是,为了使cacert和token都存在于服务帐户中,复制控制器在启动时必须被赋予`--root-ca-file =`参数.(这在大多数kubernetes安装程序中自动处理).有关详细信息,请参阅此处的讨论:https://github.com/kubernetes/kubernetes/issues/10265 (2认同)

rix*_*rix 13

使用Python kubernetes客户端..

from kubernetes import client, config

config.load_incluster_config()
v1_core = client.CoreV1Api()
Run Code Online (Sandbox Code Playgroud)


Hal*_*lci 8

wget版本:

KUBE_TOKEN=$(</var/run/secrets/kubernetes.io/serviceaccount/token)    
wget -vO- --ca-certificate /var/run/secrets/kubernetes.io/serviceaccount/ca.crt  --header "Authorization: Bearer $KUBE_TOKEN" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/default/pods/$HOSTNAME
Run Code Online (Sandbox Code Playgroud)


Utk*_*kar 7

从 pod 内部,可以直接在“ https://kubernetes.default ”上访问 kubernetes api 服务器。默认情况下,它使用“默认服务帐户”来访问 api 服务器。

所以,我们还需要传递一个“ca cert”和“default service account token”来与api服务器进行身份验证。

证书文件存储在 pod 内的以下位置:/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

以及位于以下位置的默认服务帐户令牌:/var/run/secrets/kubernetes.io/serviceaccount/token

您可以使用nodejs kubbernetes godaddy 客户端

let getRequestInfo = () => {
    return {
        url: "https://kubernetes.default",
        ca:   fs.readFileSync('/var/run/secrets/kubernetes.io/serviceaccount/ca.crt').toString(),
        auth: {
            bearer: fs.readFileSync('/var/run/secrets/kubernetes.io/serviceaccount/token').toString(),
        },
        timeout: 1500
    };
}

let initK8objs = () =>{
    k8obj = getRequestInfo();
    k8score = new Api.Core(k8obj),
    k8s = new Api.Api(k8obj);
}
Run Code Online (Sandbox Code Playgroud)


pr-*_*pal 6

上面已经提到的细节的最重要的附录是,您尝试从中访问 API 服务器的 pod 应该具有 RBAC 功能来这样做。

k8s 系统中的每个实体都由一个服务帐户标识(例如用户帐户用于用户)。根据 RBAC 功能,填充服务帐户令牌 (/var/run/secrets/kubernetes.io/serviceaccount/token)。在创建与 kube-api-servers 的连接时,kube-api 绑定(例如 pykube)可以将此令牌作为输入。如果 pod 具有正确的 RBAC 功能,则 pod 将能够与 kube-api 服务器建立连接。


Kyl*_*tts 5

我在尝试使用 Go Code 从 pod 内部访问 API 时遇到了这个问题。下面是我实现的工作,如果有人遇到这个问题也想使用 Go。

该示例使用 pod 资源,client-go如果您使用原生 kubernetes 对象,您应该使用该库。该代码对那些使用 CustomResourceDefintions 的人更有帮助。

serviceHost := os.GetEnv("KUBERNETES_SERVICE_HOST")
servicePort := os.GetEnv("KUBERNETES_SERVICE_PORT")
apiVersion := "v1" // For example
namespace := default // For example
resource := "pod" // For example
httpMethod := http.MethodGet // For Example

url := fmt.Sprintf("https://%s:%s/apis/%s/namespaces/%s/%s", serviceHost, servicePort, apiVersion, namespace, resource)

u, err := url.Parse(url)
if err != nil {
  panic(err)
}
req, err := http.NewRequest(httpMethod, u.String(), bytes.NewBuffer(payload))
if err != nil {
    return err
}

caToken, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/token")
if err != nil {
    panic(err) // cannot find token file
}

req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", string(caToken)))

caCertPool := x509.NewCertPool()
caCert, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/ca.crt")
if err != nil {
    return panic(err) // Can't find cert file
}
caCertPool.AppendCertsFromPEM(caCert)

client := &http.Client{
  Transport: &http.Transport{
    TLSClientConfig: &tls.Config{
        RootCAs: caCertPool,
    },
  },
}

resp, err := client.Do(req)
if err != nil {
    log.Printf("sending helm deploy payload failed: %s", err.Error())
    return err
}
defer resp.Body.Close()

// Check resp.StatusCode
// Check resp.Status
Run Code Online (Sandbox Code Playgroud)


Rub*_*uck 5

我在 GKE 上遇到了类似的身份验证问题,其中 python 脚本突然抛出异常。对我有用的解决方案是通过角色授予 Pod 权限

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: fabric8-rbac
subjects:
  - kind: ServiceAccount
  # Reference to upper's `metadata.name`
  name: default
  # Reference to upper's `metadata.namespace`
  namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
Run Code Online (Sandbox Code Playgroud)

欲了解更多信息,请在此处输入链接描述


fgu*_*gul 5

This is from the 库伯内特斯在行动 book.

\n\n

您需要注意身份验证。API 服务器本身表示您\xe2\x80\x99 无权访问它,因为 它\xe2\x80\x99 不知道您是谁

\n\n

要进行身份验证,您需要身份验证令牌。幸运的是,令牌是通过前面提到的默认令牌 Secret提供的,并存储在机密卷中的令牌文件中。

\n\n

您\xe2\x80\x99将使用令牌访问 API 服务器。首先,将令牌加载到环境变量中:

\n\n
root@myhome:/# TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\n
Run Code Online (Sandbox Code Playgroud)\n\n

该令牌现在存储在TOKEN 环境 变量中。您可以在向 API 服务器发送请求时使用它:

\n\n
root@curl:/# curl -H "Authorization: Bearer $TOKEN"  https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/default/pods/$HOSTNAME\n   {  "paths": \n      [    \n        "/api",    \n        "/api/v1",   \n        "/apis",    \n        "/apis/apps",    \n        "/apis/apps/v1beta1",    \n        "/apis/authorization.k8s.io",        \n         ...    \n        "/ui/",    \n        "/version"  \n      ]\n  }\n
Run Code Online (Sandbox Code Playgroud)\n