Балансировщик нагрузки поддерживает использование собственного SSL-сертификата, загруженного из Kubernetes-секрета типа kubernetes.io/tls.
Для настройки необходимо создать TLS-секрет с сертификатом и приватным ключом, а затем указать его в аннотациях балансировщика.
При настройке сертификата через балансировщик нельзя использовать самоподписанные сертификаты. Необходимо использовать сертификат, выпущенный доверенным центром сертификации.
Создание секрета
Скачайте файлы сертификата. Создайте TLS-секрет в том же неймспейсе, где находится балансировщик:
kubectl -n <namespace> create secret tls my-app-tls \ --cert=crt.crt \ --key=key.key
Проверить тип секрета можно командой:
kubectl -n <namespace> get secret my-app-tls -o yaml
В выводе должно присутствовать:
type: kubernetes.io/tls
Настройка сервиса
Добавьте аннотации для использования собственного сертификата в манифесте балансировщика:
apiVersion: v1
kind: Service
metadata:
name: my-app
annotations:
k8s.timeweb.cloud/attached-loadbalancer-ssl: "true"
k8s.timeweb.cloud/attached-loadbalancer-ssl-type: "custom"
k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn: "example.com"
k8s.timeweb.cloud/attached-loadbalancer-ssl-secret-name: "my-app-tls"
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- name: https
port: 443
targetPort: 80
appProtocol: k8s.timeweb.cloud/proto-https
Параметры:
-
k8s.timeweb.cloud/attached-loadbalancer-ssl— включает использование SSL-сертификата. -
k8s.timeweb.cloud/attached-loadbalancer-ssl-type— определяет тип сертификата. Для собственного сертификата используйте значениеcustom. -
k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn— доменное имя, для которого выпущен сертификат. -
k8s.timeweb.cloud/attached-loadbalancer-ssl-secret-name— имя TLS-секрета, содержащего сертификат и приватный ключ.
Примените изменения:
kubectl apply -f service.yaml
Проверка сертификата
Проверить сертификат, который использует балансировщик, можно командой:
echo | openssl s_client \
-connect example.com:443 \
-servername example.com \
2>/dev/null | openssl x509 -noout -subject -issuer -dates
Пример успешного результата:
subject=CN=example.com issuer=C=BE, O=GlobalSign nv-sa, CN=GlobalSign GCC R6 AlphaSSL CA 2025
Также можно проверить HTTPS-соединение через curl:
curl -kv https://example.com
В выводе должно присутствовать:
SSL certificate verify ok.
Также в выводе должна быть информация о вашем сертификате:
subject: CN=example.com
Если вместо этого отображается сертификат вида:
subject: CN=empty
— значит, балансировщик не смог применить указанный сертификат и использует сертификат по умолчанию.
Обновление сертификата
Для замены сертификата обновите существующий секрет:
kubectl -n <namespace> create secret tls my-app-tls \ --cert=new.crt \ --key=new.key \ --dry-run=client -o yaml | kubectl apply -f -
После обновления секрета необходимо запустить повторную настройку балансировщика, изменив любую аннотацию сервиса:
kubectl -n <namespace> annotate svc my-app \
k8s.timeweb.cloud/rotate-ts="$(date +%s)" \
--overwrite
После этого CCM повторно прочитает сертификат и обновит его на балансировщике.
Практический пример
В этом примере настроим собственный SSL-сертификат для тестового приложения Nginx.
Перед началом убедитесь, что у вас есть домен и выпущенный для него сертификат от доверенного центра сертификации.
Создание неймспейса
Создайте отдельный неймспейс для тестирования:
kubectl create namespace test-namespace
Создание тестового приложения
Создайте файл nginx-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: test-namespace
spec:
replicas: 1
selector:
matchLabels:
app: nginx-custom-cert-test
template:
metadata:
labels:
app: nginx-custom-cert-test
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Примените манифест:
kubectl apply -f nginx-deployment.yaml
Убедитесь, что под успешно запущен:
kubectl get pods -n test-namespace
Создание балансировщика нагрузки
Создайте файл nginx-loadbalancer.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx-loadbalancer
namespace: test-namespace
spec:
type: LoadBalancer
selector:
app: nginx-custom-cert-test
ports:
- name: https
port: 443
targetPort: 80
appProtocol: k8s.timeweb.cloud/proto-https
Примените манифест:
kubectl apply -f nginx-loadbalancer.yaml
Дождитесь появления внешнего IP-адреса:
kubectl get svc nginx-loadbalancer -n test-namespace -w
Пример вывода:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) nginx-loadbalancer LoadBalancer 10.101.130.253 203.0.113.10 443:31826/TCP
Настройка DNS-записи
Создайте A-запись для домена и направьте ее на внешний IP-адрес балансировщика.
Проверьте, что домен указывает на IP-адрес балансировщика:
dig +short example.com
Результат должен содержать IP-адрес балансировщика.
Создание TLS-секрета
Создайте TLS-секрет в том же неймспейсе, где находится сервис:
kubectl -n test-namespace create secret tls my-app-tls \ --cert=crt.crt \ --key=key.key
Проверьте, что секрет создан корректно:
kubectl -n test-namespace get secret my-app-tls -o yaml
В выводе должно присутствовать:
type: kubernetes.io/tls
При необходимости можно проверить сертификат непосредственно из секрета:
kubectl -n test-namespace get secret my-app-tls \
-o jsonpath='{.data.tls\.crt}' \
| base64 -d \
| openssl x509 -noout -subject -issuer -dates
Подключение сертификата к балансировщику
Добавьте аннотации для использования собственного сертификата в манифест сервиса nginx-loadbalancer.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx-loadbalancer
namespace: test-namespace
annotations:
k8s.timeweb.cloud/attached-loadbalancer-ssl: "true"
k8s.timeweb.cloud/attached-loadbalancer-ssl-type: "custom"
k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn: "example.com"
k8s.timeweb.cloud/attached-loadbalancer-ssl-secret-name: "my-app-tls"
spec:
type: LoadBalancer
selector:
app: nginx-custom-cert-test
ports:
- name: https
port: 443
targetPort: 80
appProtocol: k8s.timeweb.cloud/proto-https
Примените обновленный манифест:
kubectl apply -f nginx-loadbalancer.yaml
Проверьте настройки сервиса:
kubectl -n test-namespace get svc nginx-loadbalancer -o yaml
В аннотациях должны присутствовать:
k8s.timeweb.cloud/attached-loadbalancer-ssl: "true"
k8s.timeweb.cloud/attached-loadbalancer-ssl-type: custom
k8s.timeweb.cloud/attached-loadbalancer-ssl-fqdn: example.com
k8s.timeweb.cloud/attached-loadbalancer-ssl-secret-name: my-app-tls
После успешной обработки сертификата появится служебная аннотация:
k8s.timeweb.cloud/attached-loadbalancer-ssl-cert-hash: ...
Это означает, что CCM успешно прочитал сертификат из секрета.
Проверка работы приложения
Обратитесь к домену в браузере. Если сертификат успешно применен, браузер установит защищенное HTTPS-соединение без предупреждений о недоверенном сертификате.
Также можно проверить доступность приложения с помощью curl:
curl -I https://example.com
Успешный ответ означает, что:
-
сертификат загружен на балансировщик;
-
HTTPS-соединение устанавливается корректно;
-
балансировщик передает запросы в приложение, работающее в Kubernetes.
Удаление тестового окружения
После завершения проверки удалите тестовый неймспейс:
kubectl delete namespace test-namespace
Будут удалены все созданные ресурсы, включая Deployment, Service и TLS-секрет.