Как получить доступ к api Kubernetes из контейнера pod?


я использовал, чтобы быть в состоянии свернуться

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

как мой базовый URL, но в kubernetes 0.18.0 он дает мне "несанкционированный". Странно то, что если я использовал внешний IP-адрес машины API (http://172.17.8.101:8080/api/v1beta3/namespaces/default/), он работает просто отлично.

11 73

11 ответов:

в официальной документации я нашел это:

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

по-видимому, мне не хватало маркера безопасности, который мне не нужен в предыдущей версии Kubernetes. Из этого я разработал то, что я думаю, является более простым решением, чем запуск прокси или установка golang на моем контейнере. См. этот пример, который получает информацию из API, для текущего контейнер:

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

Я также использую включить простой двоичный файл, jq (http://stedolan.github.io/jq/download/), чтобы проанализировать json для использования в скриптах bash.

каждый модуль имеет учетную запись службы автоматически применяется, что позволяет ему получить доступ к apiserver. Учетная запись службы предоставляет как учетные данные клиента в виде маркера носителя, так и сертификат центра сертификации, который использовался для подписи сертификата, представленного сервером apiserver. С помощью этих двух частей информации вы можете создать безопасное аутентифицированное соединение с apisever без использования curl -k (Он же 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/

С помощью клиента Python kubernetes..

from kubernetes import client, config

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

версия 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

для тех, кто использует Google Container Engine (работает на Kubernetes):

простой вызов https://kubernetes из кластера с помощью этот клиент kubernetes для Java строительство.

изнутри модуля сервер api kubernetes может быть доступен непосредственно на "https://kubernetes.по умолчанию". По умолчанию он использует "учетную запись службы по умолчанию" для доступа к серверу api.

Итак, нам также нужно передать "сертификат ca" и "токен учетной записи службы по умолчанию" для аутентификации на сервере api.

файл сертификата хранится в следующем месте внутри модуля : в /var/работа/секреты/kubernetes.Ио/с помощью параметра serviceaccount/Калифорния.ЭЛТ

и токен учетной записи службы по умолчанию на : в /var/работа/секреты/kubernetes.Ио/с помощью параметра serviceaccount/маркер

можно использовать 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);
}

я столкнулся с этой проблемой при попытке получить доступ к API изнутри модуля с помощью кода Go. Ниже то, что я реализовал, чтобы получить эту работу, если кто-то столкнется с этим вопросом, желая использовать Go тоже.

в примере используется pod ресурс, для которого вы должны использовать client-go библиотека, Если вы работаете с собственными объектами kubernetes. Код более полезен для тех, кто работает с 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

наиболее важным дополнением к деталям, уже упомянутым выше, является то, что модуль, из которого вы пытаетесь получить доступ к серверу API, должен иметь возможности RBAC для этого.

каждая сущность в системе k8s идентифицируется учетной записью службы (например, учетная запись пользователя, используемая для пользователей). На основе на основе возможностей, учетная запись службы маркера (в/var/работа/секреты/kubernetes.Ио/с помощью параметра serviceaccount/маркер) заполняется. На Кубе-API для привязки (например, pykube) может принять этот знак как вход при создании подключения к kube-api-серверам. Если модуль имеет правильные возможности RBAC, модуль сможет установить соединение с сервером kube-api.

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

моя версия k8s-1.2.0, и в других версиях она тоже должна работать^ ^

при включенном RBAC учетная запись службы по умолчанию не имеет никаких разрешений.

лучше создать отдельную учетную запись службы для ваших нужд и использовать ее для создания вашего модуля.

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

это хорошо объяснено здесь https://developer.ibm.com/recipes/tutorials/service-accounts-and-auditing-in-kubernetes/

У меня была аналогичная проблема auth на GKE, где скрипты python внезапно выбрасывали исключения. Решение, которое сработало для меня, состояло в том, чтобы дать разрешение стручков через role

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

для получения дополнительной информации Введите описание ссылки здесь