web-dev-qa-db-de.com

Wie kann ich aus einem Pod-Container auf das Kubernetes-API zugreifen?

Ich konnte früher locken 

https://$KUBERNETES_SERVICE_Host:$KUBERNETES_PORT_443_TCP_PORT/api/v1beta3/namespaces/default/

als meine Basis-URL, aber in kubernetes 0.18.0 gibt es "unautorisiert". Das Merkwürdige ist, dass es gut funktioniert, wenn ich die externe IP-Adresse der API-Maschine (http://172.17.8.101:8080/api/v1beta3/namespaces/default/) verwendet habe.

81
tslater

In der offiziellen Dokumentation habe ich folgendes gefunden: 

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

Anscheinend fehlte mir ein Sicherheitstoken, das ich in einer früheren Version von Kubernetes nicht benötigte. Daraus habe ich herausgefunden, was meiner Meinung nach eine einfachere Lösung ist, als einen Proxy auszuführen oder Golang auf meinem Container zu installieren. In diesem Beispiel werden die Informationen aus der API für den aktuellen Container abgerufen:

KUBE_TOKEN=$(</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

Ich verwende auch ein einfaches binäres jq ( http://stedolan.github.io/jq/download/ ), um den Json für die Verwendung in Bash-Skripten zu analysieren.

89
tslater

Jeder Pod hat automatisch ein Servicekonto, über das er auf den Apiserver zugreifen kann. Das Dienstkonto stellt sowohl Client-Anmeldeinformationen in Form eines Trägertokens als auch das Zertifikat der Zertifizierungsstelle bereit, das zum Signieren des vom Apiserver vorgelegten Zertifikats verwendet wurde. Mit diesen beiden Informationen können Sie eine sichere, authentifizierte Verbindung zum Benutzer herstellen, ohne curl -k (aka curl --insecure) zu verwenden:

curl -v --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes/
51
Robert Bailey

Verwenden des Python-kubernetes-Clients ..

from kubernetes import client, config

config.load_incluster_config()
v1_core = client.CoreV1Api()
9
rix

wget version:

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
6

Für wen auch immer Google Container Engine (powered by Kubernetes) verwendet:

Ein einfacher Aufruf von https://kubernetes aus dem Cluster heraus mit diesem kubernetes-Client für Java funktioniert.

2
cahen

Der kubernetes api-Server kann innerhalb des Pods direkt unter " https: //kubernetes.default " aufgerufen werden. Standardmäßig verwendet es das "Standard-Dienstkonto" für den Zugriff auf den API-Server. 

Daher müssen wir auch ein "ca cert" und ein "Standard-Service-Account-Token" übergeben, um sich beim API-Server zu authentifizieren.

die Zertifikatsdatei wird an folgendem Ort im Pod gespeichert: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

und das Standard-Dienstkonto-Token unter: /var/run/secrets/kubernetes.io/serviceaccount/token

Sie können den nodejs kubbernetes godaddy client verwenden.

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);
}

2

Der wichtigste Zusatz zu den oben bereits erwähnten Details besteht darin, dass der Pod, von dem aus Sie auf den API-Server zugreifen möchten, über die RBAC-Funktionen verfügen sollte.

Jede Entität im k8s-System wird durch ein Dienstkonto identifiziert (z. B. das Benutzerkonto, das für Benutzer verwendet wird). Basierend auf den RBAC-Funktionen wird das Dienstkonto-Token (/var/run/secrets/kubernetes.io/serviceaccount/token) aufgefüllt. Die kube-api-Bindungen (z. B. pykube) können dieses Token als Eingabe verwenden, wenn eine Verbindung zu den kube-api-Servern hergestellt wird. Wenn der Pod über die richtigen RBAC-Funktionen verfügt, kann der Pod die Verbindung zum kube-api-Server herstellen.

2

Ich habe dieses Problem festgestellt, als ich mit Go Code aus einem Pod heraus auf die API zugreifen wollte. Nachfolgend finden Sie die Umsetzung, die ich implementiert habe, falls jemand auf diese Frage stoßen sollte, die auch Go verwenden möchte. 

Das Beispiel verwendet eine Pod-Ressource, für die Sie die client-go-Bibliothek verwenden sollten, wenn Sie mit nativen kubernetes-Objekten arbeiten. Der Code ist für diejenigen hilfreich, die mit CustomResourceDefintions arbeiten.

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
2
KyleHodgetts

Ich hatte ein ähnliches Auth-Problem bei GKE, bei dem Python-Skripts plötzlich Ausnahmen auslösten. Die Lösung, die für mich funktionierte, bestand darin, den Pods die Erlaubnis zu erteilen

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

weitere Informationen Linkbeschreibung hier eingeben

1
Rubber Duck
curl -v -cacert <path to>/ca.crt --cert <path to>/kubernetes-node.crt --key <path to>/kubernetes-node.key https://<ip:port>

Meine k8s-Version ist 1.2.0 und in anderen Versionen sollte es auch funktionieren ^^

0
Morning Y

Wenn RBAC aktiviert ist, verfügt das Standarddienstkonto nicht über Berechtigungen.

Erstellen Sie ein separates Dienstkonto für Ihre Anforderungen und verwenden Sie es zur Erstellung Ihres Pods.

spec:
  serviceAccountName: secret-access-sa
  containers:
    ...

Es ist hier gut erklärt https://developer.ibm.com/recipes/tutorials/service-accounts-and-auditing-in-kubernetes/

0