Подтвердить что ты не робот

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

Раньше я мог зависнуть

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/), он отлично работает.

4b9b3361

Ответ 1

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

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

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

KUBE_TOKEN=$(cat /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

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

Ответ 2

Каждый модуль имеет автоматически примененную учетную запись службы, которая позволяет ему получить доступ к серверу. Учетная запись службы предоставляет как учетные данные клиента в виде токена на предъявителя, так и сертификат центра сертификации, который использовался для подписи сертификата, представленного сервером 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.default.svc/

Ответ 3

Использование клиента Python kubernetes..

from kubernetes import client, config

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

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

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

файл сертификата хранится в следующем месте внутри контейнера: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

и маркер учетной записи службы по умолчанию: /var/run/secrets/kubernetes.io/serviceaccount/token

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

Ответ 8

Я столкнулся с этой проблемой при попытке получить доступ к 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

Ответ 9

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

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

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

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

Ответ 10

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

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: fabric8-rbac
subjects:
  - kind: ServiceAccount
  # Reference to upper 'metadata.name'
  name: default
  # Reference to upper 'metadata.namespace'
  namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

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

Ответ 11

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, а в других версиях она тоже должна работать ^ ^