2015-06-07 33 views
53

ho usato per essere in grado di arricciareCome accedere alla API di Kubernetes da un contenitore di pod?

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

come il mio URL di base, ma in kubernetes 0.18.0 Mi dà "non autorizzato". La cosa strana è che se ho usato l'indirizzo IP esterno della macchina API (http://172.17.8.101:8080/api/v1beta3/namespaces/default/), funziona perfettamente.

+0

dove corri il cluster (GCE, AWS, ecc) e l'utilizzo di quello di base del sistema operativo (Debian, CoreOS, ecc)? –

+0

Vagrant/CoreOS ... lo sposterò infine in AWS/CoreOS – tslater

+0

Da dove provengono le variabili '$ KUBERNETES_SERVICE_HOST' e' $ KUBERNETES_PORT_443_TCP_PORT'? – ruediste

risposta

58

Nella documentazione ufficiale ho trovato questo:

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

A quanto pare mi mancava un token di protezione che non ho bisogno di una versione precedente di kubernetes. Da quello, ho escogitato quello che penso sia una soluzione più semplice di un proxy o l'installazione di golang sul mio contenitore. Vedere questo esempio che ottiene le informazioni, dalla api, per il contenitore corrente:

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 

Io uso anche includere un semplice binario, JQ (http://stedolan.github.io/jq/download/), per analizzare il JSON per l'uso in script bash.

+5

Per i cluster implementati di recente, è possibile modificare 'v1beta3' in' v1' –

+4

Si noti che questo comando arricciamento si collegherà * non strettamente * all'apiserver (rendendo possibile che un man-in-the-middle intercetti il ​​token bearer) , quindi dovresti usarlo solo se la rete tra il pod e l'apiserver è completamente affidabile. Altrimenti, dovresti passare il flag '--cacert' in modo che il ricciolo convalidi il certificato presentato dal server degli apis. –

+0

Ho dovuto usare 'KUBERNETES_SERVICE_HOST = kubernetes.default',' $ KUBERNETES_443_TCP_PORT = 443', NAMESPACE == $ ( ruediste

39

Ogni pod ha un account di servizio automaticamente applicato che consente di accedere al server di apis. L'account di servizio fornisce entrambe le credenziali del client, sotto forma di token al portatore, e il certificato dell'autorità di certificazione utilizzato per firmare il certificato presentato dal server di apis. Con queste due informazioni, è possibile creare una connessione sicura autenticato al apisever senza utilizzare 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/ 
+2

Va notato che, per far sì che il cacert e il token esistano entrambi nell'account del servizio, al momento del comando il controller di replica deve ricevere un argomento '--root-ca-file ='. (questo viene gestito automaticamente nella maggior parte degli installer di kubernetes). Vedi la discussione qui per maggiori dettagli: https://github.com/kubernetes/kubernetes/issues/10265 – JKnight

+3

Stavo accedendo al server API da un pod con un namespace diverso. Così ho dovuto usare 'https: // kubernetes.default /' come host – ruediste

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

La mia versione è 1.2.0 K8S, e in altre versioni che si suppone lavorare troppo^^

+0

Quanto sopra è corretto se hai webhooks o qualche altro RBAC abilitato. Questo è particolarmente vero> 1.2 di k8s –

1

per chi sta utilizzando Google Container Engine (powered by kubernetes):

Una semplice chiamata al https://kubernetes dall'interno del cluster utilizzando this kubernetes client for Java opere.

2

Dall'interno del pod, il server di kubernetes api può essere accessibile direttamente su "https://kubernetes.default". Per impostazione predefinita usa "account di servizio predefinito" per accedere al server API.

Quindi, è necessario anche passare un "ca cert" e "token account di servizio predefinito" per l'autenticazione con il server api.

file del certificato viene memorizzato nella seguente posizione all'interno del baccello: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

e l'account token di servizio predefinito in: /var/run /secrets/kubernetes.io/serviceaccount/token

È possibile utilizzare lo nodejs kubbernetes godaddy client.

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

4

Utilizzando client Python kubernetes ..

from kubernetes import client, config 

config.load_incluster_config() 
v1_core = client.CoreV1Api() 
+0

Grazie! Ecco un piccolo [repo] (https://github.com/omerlh/pod_kube_api_demo) con un esempio, basato sulla tua risposta, per semplificare la riproduzione di questo codice. –

1

versione 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 
Problemi correlati