Jak uzyskać dostęp do API Kubernetes z poziomu kontenera pod?

I used to be able to curl

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

Jako mój bazowy URL, ale w kubernetes 0.18.0 daje mi "nieautoryzowany". Dziwne jest to, że jeśli użyłem zewnętrznego adresu IP maszyny API (http://172.17.8.101:8080/api/v1beta3/namespaces/default/), działa to dobrze.

 73
Author: StephenKing, 2015-06-07

11 answers

W oficjalnej dokumentacji znalazłem to:

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

Najwyraźniej brakowało mi tokena bezpieczeństwa, którego nie potrzebowałem w poprzedniej wersji Kubernetes. Na tej podstawie wymyśliłem coś, co moim zdaniem jest prostszym rozwiązaniem niż uruchamianie proxy lub instalowanie golanga na moim kontenerze. Zobacz ten przykład, który pobiera informacje z api dla bieżącego "kontener": {]}

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

Używam również include a simple binary, jq (http://stedolan.github.io/jq/download/), aby przetworzyć json do użycia w skryptach bash.

 73
Author: tslater,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-17 22:05:39

Każdy pod ma automatycznie przypisane konto usługi, które pozwala mu uzyskać dostęp do serwera apiserver. Konto usługi udostępnia zarówno dane uwierzytelniające klienta, w postaci tokena na okaziciela, jak i certyfikat urzędu certyfikacji, który został użyty do podpisania certyfikatu przedstawionego przez serwer APIs. Dzięki tym dwóm informacjom możesz utworzyć bezpieczne, uwierzytelnione połączenie z API bez użycia 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/
 46
Author: Robert Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-03 06:22:25

Korzystanie z Klienta Pythona kubernetes..

from kubernetes import client, config

config.load_incluster_config()
v1_core = client.CoreV1Api()
 9
Author: rix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-24 16:26:31

Wersja 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
 4
Author: Halil Kaskavalci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-09 10:26:53

Dla każdego, kto korzysta z Google Container Engine (powered by Kubernetes):

Proste wywołanie https://kubernetes z klastra przy użyciu tego klienta kubernetes dla Java działa.

 2
Author: cahen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-26 13:56:40

Serwer API kubernetes może być dostępny bezpośrednio z poziomu pod " https://kubernetes.default ". Domyślnie używa "domyślnego konta usługi" do uzyskiwania dostępu do serwera api.

Tak więc, musimy również przekazać "ca cert" i "default service account token", aby uwierzytelnić się za pomocą serwera api.

Plik certyfikatu jest przechowywany w następującej lokalizacji wewnątrz pod : w tym celu należy wykonać następujące czynności:]}

I domyślne konto usługi token na : w tym celu należy wykonać następujące czynności:]}

Możesz użyć 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);
}
 2
Author: Utkarsh Yeolekar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-16 08:53:55

Napotkałem ten problem podczas próby uzyskania dostępu do API z wnętrza pod za pomocą kodu Go. Poniżej jest to, co zaimplementowałem, aby to działało, jeśli ktoś natknie się na to pytanie, chcąc użyć Go.

Przykład używa zasobu pod, dla którego powinieneś użyć biblioteki client-go, jeśli pracujesz z natywnymi obiektami kubernetes. Kod jest bardziej pomocny dla osób pracujących z 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
 1
Author: KyleHodgetts,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 16:28:43

Najważniejszym dodatkiem do wyżej wymienionych szczegółów jest to, że pod, z którego próbujesz uzyskać dostęp do serwera API, powinien mieć możliwości RBAC, aby to zrobić.

Każdy podmiot w systemie k8s jest identyfikowany przez konto usługi (jak konto użytkownika używane dla użytkowników). Na podstawie możliwości RBAC, Token konta usługi (/var/run/secrets/kubernetes.io/serviceaccount/token) jest wypełniany. Pykube) może przyjąć ten token jako dane wejściowe podczas tworzenia połączenia z serwerami kube-api. Jeśli pod ma odpowiednie możliwości RBAC, pod byłby w stanie nawiązać połączenie z serwerem kube-api.

 1
Author: prabhakar palanivel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-24 15:10:08
curl -v -cacert <path to>/ca.crt --cert <path to>/kubernetes-node.crt --key <path to>/kubernetes-node.key https://<ip:port>

Moja wersja k8s to 1.2.0, a w innych wersjach też ma działać^ ^

 0
Author: Morning Y,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-03 06:22:08

Przy włączonym RBAC domyślne konto usługi nie ma żadnych uprawnień.

Lepiej Utwórz oddzielne konto usługi dla swoich potrzeb i użyj go do utworzenia pod.

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

Jest to dobrze wyjaśnione tutaj https://developer.ibm.com/recipes/tutorials/service-accounts-and-auditing-in-kubernetes/

 0
Author: Pavel Evstigneev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-10 03:48:00

Miałem podobny problem z auth na GKE, gdzie Skrypty Pythona nagle rzucały wyjątki. Rozwiązanie, które zadziałało dla mnie, to dać pods pozwolenie poprzez rolę

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

Aby uzyskać więcej informacji wpisz opis linku tutaj

 0
Author: Rubber Duck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-22 08:44:52