Как получить доступ к 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/
), он отлично работает.
Ответы
Ответ 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);
}
Ответ 7
Для тех, кто использует Google Container Engine (работает на Kubernetes):
Простой вызов https://kubernetes
из кластера с помощью работает этот клиент kubernetes для Java.
Ответ 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, а в других версиях она тоже должна работать ^ ^