5.3.2. Аутентификация
Ниже два рабочих сценария подключения worker-ноды к кластеру. Первый дает полный контроль над bootstrap-процессом, второй повторяет привычный путь через
kubeadm join.
- Bootstrap Token (Hard Way)
- Kubeadm
Это ручной сценарий: создаем
bootstrap-kubelet.conf, запускаем kubelet и при необходимости сами проводим CSR через Kubernetes API. Подходит, если хотите видеть весь путь TLS Bootstrap без автом атикиkubeadm.
В примере ниже используется статичный bootstrap-токен для всех worker-узлов. Для production-среды лучше выпускать отдельный токен на каждую ноду и задавать ему ограниченный срок жизни.
Создание bootstrap-токена
Bootstrap-токен хранится в Secret в namespace
kube-systemи дает новой ноде право начать bootstrap-процесс. Ниже два способа его создать.
- Вручную
- kubeadm token create
Команды ниже выполняются на мастер-ноде или на хосте с kubeconfig, имеющим права на создание Secret в namespace kube-system.
Переменные окружения
export AUTH_EXTRA_GROUPS="system:bootstrappers:kubeadm:default-node-token"
export DESCRIPTION="kubeadm bootstrap token"
export EXPIRATION=$(date -d '24 hours' "+%Y-%m-%dT%H:%M:%SZ")
export TOKEN_ID="fjt9ex"
export TOKEN_SECRET="lwzqgdlvoxtqk4yw"
export USAGE_BOOTSTRAP_AUTHENTIFICATION="true"
export USAGE_BOOTSTRAP_SIGNING="true"
Создание Secret
kubectl \
--kubeconfig=/etc/kubernetes/super-admin.conf \
apply -f - <<EOF
---
apiVersion: v1
kind: Secret
metadata:
name: bootstrap-token-${TOKEN_ID}
namespace: kube-system
data:
auth-extra-groups: $(echo -n "$AUTH_EXTRA_GROUPS" | base64)
description: $(echo -n "$DESCRIPTION" | base64)
expiration: $(echo -n "$EXPIRATION" | base64)
token-id: $(echo -n "$TOKEN_ID" | base64)
token-secret: $(echo -n "$TOKEN_SECRET" | base64)
usage-bootstrap-authentication: $(echo -n "$USAGE_BOOTSTRAP_AUTHENTIFICATION" | base64)
usage-bootstrap-signing: $(echo -n "$USAGE_BOOTSTRAP_SIGNING" | base64)
type: bootstrap.kubernetes.io/token
EOF
Команда выполняется на мастер-ноде или на хосте с kubeconfig, имеющим права на управление bootstrap-токенами.
kubeadm token create \
--kubeconfig=/etc/kubernetes/super-admin.conf \
--print-join-command \
--ttl 24h
kubeadm join api.my-first-cluster.example.com:6443 \
--token <generated-token> \
--discovery-token-ca-cert-hash sha256:<hash>
Полученный токен можно использовать при создании
bootstrap-kubelet.confили передать в конфигурациюkubeadm join.
Создание bootstrap-kubelet.conf
Все команды данного этапа выполняются на worker-ноде.
На worker-ноде файл ca.crt еще отсутствует. CA-данные получаем из публичного ConfigMap cluster-info
в namespace kube-public, доступного анонимно через kube-apiserver.
Переменные окружения
export BOOTSTRAP_TOKEN=fjt9ex.lwzqgdlvoxtqk4yw
export API_SERVER="https://api.my-first-cluster.example.com:6443"
Рабочая директория
mkdir -p /etc/kubernetes
Получение CA из cluster-info
export CA_DATA=$(curl -sk "${API_SERVER}/api/v1/namespaces/kube-public/configmaps/cluster-info" | \
jq -r '.data.kubeconfig' | \
grep 'certificate-authority-data' | \
awk '{print $2}')
Сохранение CA-сертификата
mkdir -p /etc/kubernetes/pki
echo "${CA_DATA}" | base64 -d > /etc/kubernetes/pki/ca.crt
Генерация kubeconfig
cat <<EOF > /etc/kubernetes/bootstrap-kubelet.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ${CA_DATA}
server: ${API_SERVER}
name: my-first-cluster
contexts:
- context:
cluster: my-first-cluster
user: tls-bootstrap-token-user
name: tls-bootstrap-token-user@kubernetes
current-context: tls-bootstrap-token-user@kubernetes
kind: Config
preferences: {}
users:
- name: tls-bootstrap-token-user
user:
token: ${BOOTSTRAP_TOKEN}
EOF
Kubernetes CSR (имитация TLS Bootstrap)
Ниже показан тот же поток, который kubelet обычно проходит сам во время TLS Bootstrap: ключи генерируются на worker-ноде, CSR отправляются через Kubernetes API, а подпись подтверждает администратор на мастер-ноде. Приватный ключ CA на worker-ноде для этого не нужен.
Kubelet Client Certificate (CSR)
● Обязателен к применению
Kubelet Client Certificate (CSR)
● Обязателен к применению
Назначение: Клиентский сертификат kubelet для подключения к kube-apiserver.
1. Генерация ключа и CSR
Все команды данного этапа выполняются на worker-ноде.
export HOST_NAME=worker-1
export CLUSTER_NAME="my-first-cluster"
export BASE_DOMAIN="example.com"
export FULL_HOST_NAME="${HOST_NAME}.${CLUSTER_NAME}.${BASE_DOMAIN}"
mkdir -p /var/lib/kubelet/pki
mkdir -p /etc/kubernetes/openssl/csr
cat <<EOF > /etc/kubernetes/openssl/kubelet-client.conf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
[ dn ]
CN = system:node:${FULL_HOST_NAME}
O = system:nodes
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=clientAuth
EOF
openssl genrsa \
-out /var/lib/kubelet/pki/kubelet-client-key.pem 2048
openssl req -new \
-key /var/lib/kubelet/pki/kubelet-client-key.pem \
-out /etc/kubernetes/openssl/csr/kubelet-client.csr \
-config /etc/kubernetes/openssl/kubelet-client.conf
2. Отправка CSR в Kubernetes API
Worker-нода аутентифицируется bootstrap-токеном через bootstrap-kubelet.conf.
export HOST_NAME=worker-1
export CSR_NAME="${HOST_NAME}-kubelet-client"
export CSR_CONTENT=$(cat /etc/kubernetes/openssl/csr/kubelet-client.csr | base64 | tr -d '\n')
kubectl \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \
apply -f - <<EOF
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: ${CSR_NAME}
spec:
request: ${CSR_CONTENT}
signerName: kubernetes.io/kube-apiserver-client-kubelet
usages:
- digital signature
- key encipherment
- client auth
EOF
3. Утверждение CSR
Утверждение CSR выполняется на мастер-ноде. Укажите имя worker-ноды, для которой утверждается CSR.
export HOST_NAME=worker-1
export CSR_NAME="${HOST_NAME}-kubelet-client"
kubectl \
--kubeconfig=/etc/kubernetes/super-admin.conf \
certificate approve ${CSR_NAME}
4. Получение подписанного сертификата
Сертификат получаем на worker-ноде с использованием bootstrap-kubelet.conf.
export HOST_NAME=worker-1
export CSR_NAME="${HOST_NAME}-kubelet-client"
kubectl \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \
get csr ${CSR_NAME} \
-o jsonpath='{.status.certificate}' | base64 -d > /var/lib/kubelet/pki/kubelet-client.pem
cat /var/lib/kubelet/pki/kubelet-client.pem /var/lib/kubelet/pki/kubelet-client-key.pem > /var/lib/kubelet/pki/kubelet-client-$(date '+%Y-%m-%d-%H-%M-%S').pem
ln -sf /var/lib/kubelet/pki/kubelet-client-$(date '+%Y-%m-%d-%H-%M-%S').pem /var/lib/kubelet/pki/kubelet-client-current.pem
Kubelet Server Certificate (CSR)
● Обязателен к применению
Kubelet Server Certificate (CSR)
● Обязателен к применению
Назначение: Серверный сертификат kubelet для TLS на порту 10250.
1. Генерация ключа и CSR
Все команды данного этапа выполняются на worker-ноде.
export HOST_NAME=worker-1
export CLUSTER_NAME="my-first-cluster"
export BASE_DOMAIN="example.com"
export FULL_HOST_NAME="${HOST_NAME}.${CLUSTER_NAME}.${BASE_DOMAIN}"
export MACHINE_LOCAL_ADDRESS="$(ip -4 addr show scope global | awk '/inet/ {print $2; exit}' | cut -d/ -f1)"
mkdir -p /var/lib/kubelet/pki
mkdir -p /etc/kubernetes/openssl/csr
cat <<EOF > /etc/kubernetes/openssl/kubelet-server.conf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = req_ext
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = localhost
DNS.2 = ${HOST_NAME}
DNS.3 = ${FULL_HOST_NAME}
IP.1 = 127.0.0.1
IP.2 = 0:0:0:0:0:0:0:1
IP.3 = ${MACHINE_LOCAL_ADDRESS}
[ dn ]
CN = system:node:${FULL_HOST_NAME}
O = system:nodes
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth
subjectAltName=@alt_names
EOF
openssl genrsa \
-out /var/lib/kubelet/pki/kubelet-server-key.pem 2048
openssl req -new \
-key /var/lib/kubelet/pki/kubelet-server-key.pem \
-out /etc/kubernetes/openssl/csr/kubelet-server.csr \
-config /etc/kubernetes/openssl/kubelet-server.conf
2. Отправка CSR в Kubernetes API
Worker-нода аутентифицируется bootstrap-токеном через bootstrap-kubelet.conf.
export HOST_NAME=worker-1
export CSR_NAME="${HOST_NAME}-kubelet-server"
export CSR_CONTENT=$(cat /etc/kubernetes/openssl/csr/kubelet-server.csr | base64 | tr -d '\n')
kubectl \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \
apply -f - <<EOF
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: ${CSR_NAME}
spec:
request: ${CSR_CONTENT}
signerName: kubernetes.io/kubelet-serving
usages:
- digital signature
- key encipherment
- server auth
EOF
3. Утверждение CSR
Утверждение CSR выполняется на мастер-ноде. Укажите имя worker-ноды, для которой утверждается CSR.
export HOST_NAME=worker-1
export CSR_NAME="${HOST_NAME}-kubelet-server"
kubectl \
--kubeconfig=/etc/kubernetes/super-admin.conf \
certificate approve ${CSR_NAME}
4. Получение подписанного сертификата
Сертификат получаем на worker-ноде с использованием bootstrap-kubelet.conf.
export HOST_NAME=worker-1
export CSR_NAME="${HOST_NAME}-kubelet-server"
kubectl \
--kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf \
get csr ${CSR_NAME} \
-o jsonpath='{.status.certificate}' | base64 -d > /var/lib/kubelet/pki/kubelet-server.pem
cat /var/lib/kubelet/pki/kubelet-server.pem /var/lib/kubelet/pki/kubelet-server-key.pem > /var/lib/kubelet/pki/kubelet-server-$(date '+%Y-%m-%d-%H-%M-%S').pem
ln -sf /var/lib/kubelet/pki/kubelet-server-$(date '+%Y-%m-%d-%H-%M-%S').pem /var/lib/kubelet/pki/kubelet-server-current.pem
Здесь почти все делает
kubeadm join: получаетcluster-info, стартует kubelet и проводит TLS Bootstrap. Это самый близкий к стандартной установке путь.
Получение токена
Если токен не был создан заранее или истек, сгенерируйте новый.
Команда выполняется на мастер-ноде или на хосте с kubeconfig, имеющим права на управление bootstrap-токенами.
kubeadm token create \
--kubeconfig=/etc/kubernetes/super-admin.conf \
--print-join-command \
--ttl 24h
kubeadm join api.my-first-cluster.example.com:6443 \
--token <generated-token> \
--discovery-token-ca-cert-hash sha256:<hash>
Конфигурация kubeadm
Полученный токен можно подставить в конфиг
kubeadmили передать прямо в командной строке.
Перед запуском убедитесь, что у вас уже готов файл kubeadm.yaml из раздела
Настройка ПО (DP).
Использование статичного конфига
kubeadm join \
--config=/var/run/kubeadm/kubeadm.yaml
Использование токена из командной строки
kubeadm join \
api.my-first-cluster.example.com:6443 \
--token <generated-token> \
--discovery-token-ca-cert-hash sha256:<hash>