web-dev-qa-db-fra.com

Comment accéder à l'API Kubernetes à partir d'un conteneur de pod?

Je pouvais courber 

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

en tant qu'URL de base, mais dans kubernetes 0.18.0, cela me donne "non autorisé". La chose étrange est que si j'utilise l'adresse IP externe de la machine API (http://172.17.8.101:8080/api/v1beta3/namespaces/default/), cela fonctionne très bien.

81
tslater

Dans la documentation officielle, j'ai trouvé ceci: 

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

Apparemment, il me manquait un jeton de sécurité dont je n'avais pas besoin dans une version antérieure de Kubernetes. À partir de cela, j’ai imaginé une solution plus simple que celle d’exécuter un proxy ou d’installer golang sur mon conteneur. Voir cet exemple qui récupère les informations, depuis l’API, pour le conteneur actuel:

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

J'utilise aussi include, un simple binaire, jq ( http://stedolan.github.io/jq/download/ ), pour analyser le json afin de l'utiliser dans les scripts bash.

89
tslater

Chaque pod a un compte de service automatiquement appliqué qui lui permet d’accéder à apiserver. Le compte de service fournit à la fois les informations d'identification du client, sous la forme d'un jeton de support, et le certificat de l'autorité de certification utilisé pour signer le certificat présenté par apiserver. Avec ces deux informations, vous pouvez créer une connexion sécurisée et authentifiée à apisever sans utiliser 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/
51
Robert Bailey

Utilisation du client kubernetes Python ..

from kubernetes import client, config

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

version 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
6
Halil Kaskavalci

Pour quiconque utilise Google Container Engine (optimisé par Kubernetes):

Un simple appel à https://kubernetes depuis le cluster à l’aide de ce client kubernetes pour Java fonctionne.

2
cahen

Depuis le pod, le serveur api kubernetes peut être directement accessible sur " https: //kubernetes.default ". Par défaut, il utilise le "compte de service par défaut" pour accéder au serveur api. 

Donc, nous devons également passer un "ca cert" et un "jeton de compte de service par défaut" pour s'authentifier auprès du serveur api.

le fichier de certificat est stocké à l'emplacement suivant dans le pod: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

et le jeton de compte de service par défaut à l'adresse: /var/run/secrets/kubernetes.io/serviceaccount/token

Vous pouvez utiliser le client 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);
}

2
Utkarsh Yeolekar

L’additif le plus important aux détails déjà mentionnés ci-dessus est que le module à partir duquel vous essayez d’accéder au serveur d’API doit disposer des fonctionnalités RBAC nécessaires.

Chaque entité du système k8s est identifiée par un compte de service (comme un compte d'utilisateur utilisé pour des utilisateurs). Sur la base des capacités RBAC, le jeton de compte de service (/var/run/secrets/kubernetes.io/serviceaccount/token) est rempli. Les liaisons kube-api (par exemple, pykube) peuvent prendre ce jeton comme entrée lors de la création d'une connexion aux serveurs kube-api. Si le pod dispose des capacités RBAC adéquates, il pourra établir la connexion avec le serveur kube-api.

2

J'ai rencontré ce problème lorsque j'essayais d'accéder à l'API depuis un pod en utilisant Go Code. Ci-dessous vous trouverez ce que j’ai mis en place pour que cela fonctionne, si quelqu'un devait répondre à cette question et vouloir utiliser Go 

L'exemple utilise une ressource pod pour laquelle vous devez utiliser la bibliothèque client-go si vous travaillez avec des objets kubernetes natifs. Le code est plus utile pour ceux qui travaillent avec 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
2
KyleHodgetts

J'ai eu un problème d'authentification similaire sur GKE où les scripts python ont soudainement jeté des exceptions. La solution qui a fonctionné pour moi était de donner la permission aux pods via le rôle

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

pour plus d'informations entrez la description du lien ici

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>

La version de mon k8s est 1.2.0, et dans d'autres versions, elle est supposée fonctionner aussi ^^

0
Morning Y

Avec RBAC activé, le compte de service par défaut ne dispose d'aucune autorisation.

Mieux créer un compte de service distinct pour vos besoins et l'utiliser pour créer votre pod.

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

C'est bien expliqué ici https://developer.ibm.com/recipes/tutorials/service-accounts-and-auditing-in-kubernetes/

0
Pavel Evstigneev