Comment accéder à l’API Kubernetes depuis un conteneur pod?

Je pouvais boucler

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

comme mon URL de base, mais dans kubernetes 0.18.0 il me donne “non autorisé”. La chose étrange est que si j’ai utilisé l’adresse IP externe de la machine API ( http://172.17.8.101:8080/api/v1beta3/namespaces/default/ ), cela fonctionne très bien.

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 précédente de Kubernetes. À partir de là, j’ai imaginé une solution plus simple que l’utilisation d’un proxy ou l’installation de golang sur mon conteneur. Voir cet exemple qui obtient les informations, à partir de l’API, pour le conteneur actuel:

 KUBE_TOKEN=$( 

J'utilise également include un simple binary, jq ( http://stedolan.github.io/jq/download/ ), pour parsingr le json à utiliser dans les scripts bash.

Chaque pod dispose d’un compte de service automatiquement appliqué lui permettant d’accéder à l’apiserver. Le compte de service fournit à la fois les informations d’identification du client, sous la forme d’un jeton de support, et le certificate de l’autorité de certificateion utilisé pour signer le certificate présenté par l’apiserver. Avec ces deux informations, vous pouvez créer une connexion sécurisée et authentifiée à l’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/ 

Utilisation du client python kubernetes ..

 from kubernetes import client, config config.load_incluster_config() v1_core = client.CoreV1Api() 

version wget:

 KUBE_TOKEN=$( 

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 .

De l’intérieur du pod, le serveur api Kubernetes peut être accessible directement 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 certificate est stocké à l’emplacement suivant dans le conteneur: /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').toSsortingng(), auth: { bearer: fs.readFileSync('/var/run/secrets/kubernetes.io/serviceaccount/token').toSsortingng(), }, timeout: 1500 }; } let initK8objs = () =>{ k8obj = getRequestInfo(); k8score = new Api.Core(k8obj), k8s = new Api.Api(k8obj); } 
 curl -v -cacert /ca.crt --cert /kubernetes-node.crt --key /kubernetes-node.key https:// 

Ma version de k8s est 1.2.0, et dans d’autres versions, elle est censée fonctionner aussi ^^

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

Mieux vaut 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/

J’ai rencontré ce problème en essayant d’accéder à l’API depuis un pod à l’aide de Go Code. Vous trouverez ci-dessous ce que j’ai mis en place pour que cela fonctionne, si quelqu’un rencontrait cette question en souhaitant utiliser Go.

L’exemple utilise une ressource pod, pour laquelle vous devez utiliser la bibliothèque client-go si vous travaillez avec des objects natifs de kubernetes. 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.Ssortingng(), 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", ssortingng(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 

J’ai eu un problème d’authentification similaire sur GKE où les scripts python ont soudainement lancé 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

L’addenda le plus important aux détails déjà mentionnés ci-dessus est que le pod à partir duquel vous essayez d’accéder au serveur API doit avoir les capacités RBAC pour le faire.

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