Kubernetes надає API certificates.k8s.io, який дозволяє вам отримувати TLS сертифікати, підписані Центром Сертифікації (CA), який ви контролюєте. Ці CA та сертифікати можуть використовуватися вашими робочими навантаженнями для встановлення довіри.
API certificates.k8s.io використовує протокол, подібний до чернетки ACME.
certificates.k8s.io, підписуються
спеціальним CA. Можливо налаштувати ваш кластер так, щоб використовувати кореневий кластерний CA для цієї мети, але не слід на це покладатися. Не припускайте, що ці сертифікати будуть перевірятися кореневим кластерним CA.Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Вам потрібен інструмент cfssl. Ви можете завантажити cfssl з
https://github.com/cloudflare/cfssl/releases.
Деякі кроки на цій сторінці використовують інструмент jq. Якщо у вас його немає, ви можете встановити його через джерела програмного забезпечення вашої операційної системи або завантажити з https://jqlang.github.io/jq/.
Довіра до власного CA з боку застосунків, що працюють як Podʼи, зазвичай вимагає додаткової конфігурації. Вам потрібно додати пакет сертифікатів CA до списку сертифікатів CA, яким довіряє TLS клієнт або сервер. Наприклад, ви можете зробити це за допомогою налаштування TLS в Golang, проаналізувавши ланцюжок сертифікатів і додавши проаналізовані сертифікати до поля RootCAs в структурі tls.Config.
kube-root-ca.crt), не слід використовувати цей центр сертифікації для будь-якої мети, окрім перевірки внутрішніх точок доступу Kubernetes. Прикладом внутрішньої точки доступу Kubernetes є
Service з іменем kubernetes в просторі імен default. Якщо ви хочете використовувати власний центр сертифікації для ваших робочих навантажень, слід створити цей CA окремо та розповсюдити його сертифікат CA за допомогою ConfigMap, до якого ваші Podʼи мають доступ для читання.Наступний розділ демонструє, як створити TLS сертифікат для Kubernetes сервісу, до якого звертаються через DNS.
Згенеруйте приватний ключ і запит на підписання сертифіката (або CSR), виконавши наступну команду:
cat <<EOF | cfssl genkey - | cfssljson -bare server
{
"hosts": [
"my-svc.my-namespace.svc.cluster.local",
"my-pod.my-namespace.pod.cluster.local",
"192.0.2.24",
"10.0.34.2"
],
"CN": "my-pod.my-namespace.pod.cluster.local",
"key": {
"algo": "ecdsa",
"size": 256
}
}
EOF
Де 192.0.2.24 — це кластерний IP Serviceʼу, my-svc.my-namespace.svc.cluster.local — це DNS-імʼя Serviceʼу, 10.0.34.2 —це IP Podʼа, а my-pod.my-namespace.pod.cluster.local — це DNS-імʼя Podʼа. Ви повинні побачити вивід подібний до:
2022/02/01 11:45:32 [INFO] generate received request
2022/02/01 11:45:32 [INFO] received CSR
2022/02/01 11:45:32 [INFO] generating key: ecdsa-256
2022/02/01 11:45:32 [INFO] encoded CSR
Ця команда генерує два файли; server.csr, що містить PEM закодований PKCS#10 запит на сертифікат, і server-key.pem, що містить PEM закодований ключ до сертифіката, який ще потрібно створити.
Згенеруйте маніфест CSR (у форматі YAML) і надішліть його на сервер API. Ви можете зробити це, виконавши наступну команду:
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: my-svc.my-namespace
spec:
request: $(cat server.csr | base64 | tr -d '\n')
signerName: example.com/serving
usages:
- digital signature
- key encipherment
- server auth
EOF
Зверніть увагу, що файл server.csr, створений на кроці 1, кодується base64 та зберігається в полі .spec.request. Ви також запитуєте сертифікат з використанням ключів "digital signature", "key encipherment" і "server auth", підписаний підписувачем example.com/serving. Повинен бути запитаний конкретний signerName. Перегляньте документацію для підтримуваних імен підписувачів для отримання додаткової інформації.
CSR тепер має бути видимий з API у стані Pending. Ви можете побачити це, виконавши:
kubectl describe csr my-svc.my-namespace
Name: my-svc.my-namespace
Labels: <none>
Annotations: <none>
CreationTimestamp: Tue, 01 Feb 2022 11:49:15 -0500
Requesting User: yourname@example.com
Signer: example.com/serving
Status: Pending
Subject:
Common Name: my-pod.my-namespace.pod.cluster.local
Serial Number:
Subject Alternative Names:
DNS Names: my-pod.my-namespace.pod.cluster.local
my-svc.my-namespace.svc.cluster.local
IP Addresses: 192.0.2.24
10.0.34.2
Events: <none>
Схвалення запиту на підписання сертифіката виконується або автоматичною процедурою схвалення, або одноразово адміністратором кластера. Якщо у вас є дозвіл на схвалення запиту на сертифікат, ви можете зробити це вручну за допомогою kubectl; наприклад:
kubectl certificate approve my-svc.my-namespace
certificatesigningrequest.certificates.k8s.io/my-svc.my-namespace approved
Ви тепер повинні побачити наступне:
kubectl get csr
NAME AGE SIGNERNAME REQUEST
OR REQUESTEDDURATION CONDITION
my-svc.my-namespace 10m example.com/serving yourname@example.com <none> Approved
Це означає, що запит на сертифікат був схвалений і чекає на підписання запрошеним підписувачем.
Далі ви зіграєте роль підписувача сертифікатів, видасте сертифікат і завантажите його в API.
Підписувач зазвичай спостерігає за API CertificateSigningRequest для обʼєктів з його signerName, перевіряє, що вони були схвалені, підписує сертифікати для цих запитів, і оновлює статус обʼєкта API з виданим сертифікатом.
Вам потрібен центр сертифікації, щоб забезпечити цифровий підпис нового сертифікату.
Спочатку створіть підписний сертифікат, виконавши наступне:
cat <<EOF | cfssl gencert -initca - | cfssljson -bare ca
{
"CN": "My Example Signer",
"key": {
"algo": "rsa",
"size": 2048
}
}
EOF
Ви повинні побачити вивід подібний до:
2022/02/01 11:50:39 [INFO] generating a new CA key and certificate from CSR
2022/02/01 11:50:39 [INFO] generate received request
2022/02/01 11:50:39 [INFO] received CSR
2022/02/01 11:50:39 [INFO] generating key: rsa-2048
2022/02/01 11:50:39 [INFO] encoded CSR
2022/02/01 11:50:39 [INFO] signed certificate with serial number 263983151013686720899716354349605500797834580472
Це створює файл ключа центру сертифікації (ca-key.pem) і сертифікат (ca.pem).
{
"signing": {
"default": {
"usages": [
"digital signature",
"key encipherment",
"server auth"
],
"expiry": "876000h",
"ca_constraint": {
"is_ca": false
}
}
}
}Використовуйте конфігурацію для підпису server-signing-config.json та файл ключа центру сертифікації та сертифікат для підпису запиту на сертифікат:
kubectl get csr my-svc.my-namespace -o jsonpath='{.spec.request}' | \
base64 --decode | \
cfssl sign -ca ca.pem -ca-key ca-key.pem -config server-signing-config.json - | \
cfssljson -bare ca-signed-server
Ви повинні побачити вивід подібний до:
2022/02/01 11:52:26 [INFO] signed certificate with serial number 576048928624926584381415936700914530534472870337
Це створює файл підписаного серверного сертифіката, ca-signed-server.pem.
Нарешті, вкажіть підписаний сертифікат у статусі обʼєкта API:
kubectl get csr my-svc.my-namespace -o json | \
jq '.status.certificate = "'$(base64 ca-signed-server.pem | tr -d '\n')'"' | \
kubectl replace --raw /apis/certificates.k8s.io/v1/certificatesigningrequests/my-svc.my-namespace/status -f -
jq для заповнення вмісту, закодованого base64, в поле .status.certificate. Якщо у вас немає jq, ви також можете зберегти вивід JSON у файл, вручну заповнити це поле і завантажити отриманий файл.Після схвалення CSR і завантаження підписаного сертифіката, виконайте:
kubectl get csr
Вивід буде подібним до:
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
my-svc.my-namespace 20m example.com/serving yourname@example.com <none> Approved,Issued
Тепер, як запитувач, ви можете завантажити виданий сертифікат і зберегти його у файл server.crt, виконавши наступне:
kubectl get csr my-svc.my-namespace -o jsonpath='{.status.certificate}' \
| base64 --decode > server.crt
Тепер ви можете заповнити server.crt і server-key.pem у Секрет, який ви можете пізніше монтувати в Pod (наприклад, для використання з вебсервером,
який обслуговує HTTPS).
kubectl create secret tls server --cert server.crt --key server-key.pem
secret/server created
Нарешті, ви можете заповнити ca.pem у ConfigMap і використовувати його як кореневий довірчий сертифікат для перевірки серверного сертифіката:
kubectl create configmap example-serving-ca --from-file ca.crt=ca.pem
configmap/example-serving-ca created
Адміністратор Kubernetes (з відповідними дозволами) може вручну схвалювати
(або відхиляти) CertificateSigningRequests за допомогою команд kubectl certificate approve та kubectl certificate deny. Однак, якщо ви плануєте активно використовувати цей API, варто розглянути можливість написання автоматизованого контролера сертифікатів.
Можливість схвалювати CSR вирішує, хто кому довіряє у вашому середовищі. Це повноваження не слід надавати широко або легковажно.
Слід переконатися, що ви впевнено розумієте як вимоги щодо перевірки, так і наслідки видачі конкретного сертифіката перед тим, як надати дозвіл на approve.
Чи це буде машина або людина, яка використовує kubectl, роль схвалювача полягає у перевірці, що CSR відповідає двом вимогам:
Якщо і тільки якщо ці дві вимоги виконані, схвалювач повинен схвалити CSR інакше він повинен відхилити CSR.
Для отримання додаткової інформації про схвалення сертифікатів та контроль доступу, прочитайте сторінку довідника Запити на підписання сертифікатів.
Ця сторінка припускає, що підписувач налаштований для обслуговування API сертифікатів. Менеджер контролерів Kubernetes надає стандартну реалізацію підписувача. Щоб увімкнути його, передайте параметри --cluster-signing-cert-file та --cluster-signing-key-file до менеджера контролерів з шляхами до пари ключів вашого центру сертифікації.