Thank you for reading this post, don't forget to subscribe!
Мы распределяем кластера Kubernetes по следующей схеме — кластер для каждого проекта и каждой среды, это позволяет сперва оттестировать что-то новое на дев среде, потом перетащить на стейдж и уже после внедрять на продакшене. И вот из-за такого подхода количество сервисов стало стремительно расти. Поэтому в качестве Single-Sing-On (SSO) был выбран Keycloak.
Почему Keycloak? Во-первых это opensource проект курируемый RedHat. Во-вторых продукт бесплатный, не скажу, что кто-то ограничивал бюджет, но если есть возможность сэкономить — почему бы и да.
Схема установки была выбрана достаточна простая — базу будем использовать RDS PostgreSQL 13, а сам сервис разместим на EC2 инстансе. От лоадбалансера AWS также решено отказаться — поэтому терменировать сертификат будем на Traefik, который будет так же выступать как reverse-proxy. Из полезного замечу то, что у Traefik есть провайдер Route53, поэтому в нашем случае требуется создать IAM Policy для доступа к зоне в Route53, пример:
route53_le_policy_example.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Action": [ "route53:GetChange", "route53:ChangeResourceRecordSets", "route53:ListResourceRecordSets" ], "Resource": [ "arn:aws:route53:::hostedzone/*", "arn:aws:route53:::change/*" ] }, { "Sid": "", "Effect": "Allow", "Action": "route53:ListHostedZonesByName", "Resource": "*" } ] } |
Собственно для визуализации прикрепляю схему как оно выглядит

Запуск Keycloak
Ниже приведен файл docker-compose для запуска Keycloak, в качестве провайдера для получения сертификата от Let’s Encrypt можно использовать любой доступный из доки Traefik:
docker-compose.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
version: '3.9' services: traefik: image: traefik:2.6 container_name: traefik restart: unless-stopped volumes: - ./acme.json:/acme.json:rw - /var/run/docker.sock:/var/run/docker.sock networks: - keycloak labels: - 'traefik.enable=true' - 'traefik.http.routers.api.rule=Host(`traefik.${DOMAIN}`)' - 'traefik.http.routers.api.entrypoints=https' - 'traefik.http.routers.api.service=api@internal' - 'traefik.http.routers.api.tls=true' - 'traefik.http.routers.api.tls.certresolver=route53' - "traefik.http.middlewares.my-whitelist-in-docker.ipwhitelist.sourcerange=1.1.1.1/32" # we declare our middleware - "traefik.http.routers.api.middlewares=my-whitelist-in-docker@docker" # we apply our middleware ports: - 80:80 - 443:443 command: - '--api' - '--providers.docker=true' - '--experimental.http3=true' - '--providers.docker.exposedByDefault=false' - '--entrypoints.http=true' - '--entrypoints.http.address=:80' - '--entrypoints.http.http.redirections.entrypoint.to=https' - '--entrypoints.http.http.redirections.entrypoint.scheme=https' - '--entrypoints.https=true' - '--entrypoints.https.address=:443' - '--certificatesResolvers.route53.acme.storage=/acme.json' - '--certificatesResolvers.route53.acme.caServer=https://acme-v02.api.letsencrypt.org/directory' - '--certificatesresolvers.route53.acme.dnschallenge.provider=route53' - '--certificatesresolvers.route53.acme.dnschallenge.delaybeforecheck=0' - '--certificatesresolvers.route53.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53' - '--log=true' - '--log.level=INFO' keycloak: container_name: keycloak environment: DB_VENDOR: postgres DB_ADDR: ${POSTGRESQL_HOST} DB_DATABASE: ${POSTGRESQL_DB} DB_USER: ${POSTGRESQL_USER} DB_PASSWORD: ${POSTGRESQL_PASS} PROXY_ADDRESS_FORWARDING: "true" KEYCLOAK_LOGLEVEL: "INFO" image: jboss/keycloak:${KEYCLOAK_VERSION} restart: unless-stopped command: ["-b", "0.0.0.0", "-Dkeycloak.profile.feature.docker=enabled"] networks: - keycloak labels: - 'traefik.enable=true' - 'traefik.http.routers.keycloak.rule=Host(`${DOMAIN}`)' - 'traefik.http.routers.keycloak.entrypoints=https' - 'traefik.http.routers.keycloak.tls=true' - 'traefik.http.routers.keycloak.tls.certresolver=route53' - 'traefik.http.routers.keycloak.service=keycloak' - 'traefik.http.services.keycloak.loadbalancer.server.port=8080' networks: keycloak: |
Из правок данного файла, нужно изменить на свои параметры 1.1.1.1/32 — прописываем свои IP для доступа в дашборд Traefik
Также в директории с файлом docker-compose.yaml создаем файл .env в котором прописываем данные подключения к базе, домен для Traefik
1 2 3 4 5 6 7 8 |
KEYCLOAK_VERSION=16.1.1 # Указываем актуальную версию контейнера PORT_KEYCLOAK=8080 # Порт Keycloak POSTGRESQL_USER=your_keycloak_user POSTGRESQL_PASS=strong_db_password_here POSTGRESQL_DB=your_keycloak_db POSTGRESQL_HOST=database_host DOMAIN=my-auth-domain.net # Домен для Traefik |
Если необходимо развернуть локально и базу, то стоит добавить в docker-compose.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
... postgres: image: postgres:13 restart: unless-stopped volumes: - pgdata:/var/lib/postgresql/data environment: POSTGRES_DB: ${POSTGRESQL_DB} POSTGRES_USER: ${POSTGRESQL_USER} POSTGRES_PASSWORD: ${POSTGRESQL_PASS} networks: - keycloak volumes: pgdata: ... |
Запустим данный проект командой:
docker-compose -f docker-compose.yaml up -d
Создание учетной записи администратора
После запуска docker-compose, мы можем перейти на страницу авторизации Keycloak, для этого перейдем по адресу https://YOUR_DOMAIN/auth/
Если запуска прошел успешно, то мы должны увидеть следующее:
Как указано на скриншоте — для дальнейшего использования понадобится создать пользователя-администратора, для этого необходимо выполнить команду:
1 2 3 |
docker exec keycloak /opt/jboss/keycloak/bin/add-user-keycloak.sh -u YOUR_USERNAME -p YOUR_PASSWORD docker restart keycloak |
где YOUR_USERNAME имя администратора, а YOUR_PASSWORD его пароль.
Полезные ссылки
Настройка Grafana:
https://janikvonrotz.ch/2020/08/27/grafana-oauth-with-keycloak-and-how-to-validate-a-jwt-token/
Настройка ArgoCD:
https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/keycloak/