Много работаю с GCP и зачастую приходится иметь дело с несколькими проектами одновременно и переключаться между ними в течении дня. Случаются досадные ситуации когда команда была выполнена не в том проекте или не в том GKE кластере. Последнее особенно коварно, т.к. в корпоративной среде обычно один и тот же пользователь имеет доступ в разные кластера в разных проектах и переключение профиля gcloud не влияет на kubectl.
Заметки о Linux, системном администрировании, программировании, электронике и не только
среда, 30 ноября 2022 г.
пятница, 25 ноября 2022 г.
Bitnami Sealed Secrets
Чтобы управлять Kubernetes секретами в духе GitOps нужно их шифровать перед фиксацией в Git и расшифровывать на стороне Kubernetes. Для CI я раньше использовал Mozilla SOPS, а для Kubernetes решил попробовать Bitnami Sealed Secrets.
В Sealed Secrets используется ассиметричная криптография и расшифровать секреты без доступа к приватному ключу не получится - можно коммитить даже в публичный репозитарий, хотя я бы не рекомендовал так делать.
понедельник, 21 ноября 2022 г.
Частичное зеркалирование данных по SFTP
Появилась необходимость зеркалировать часть данных с системы, которая позволяет их скачать только по SFTP протоколу. Все файлы с данными имеют шаблон имени в который входит определенный идентификатор. На сервере таких идентификаторов - несколько тысяч, но для наших целей нам нужно зеркалировать только некоторые их них. Поскольку мы ограничены протоколом SFTP, то решения вроде Rsync не подходят.
В общем случае клиент должен подключиться к серверу и получить список директорий верхнего уровня, а затем в зависимости от максимально разрешенного уровня вложенности обойти нужные директории и свериться со списоком файлов, которые уже есть локально, скачать недостающие и удалить файлы, которых уже нет на исходном SFTP сервере (там хранятся данные только за несколько дней).
Для решения этой задачи подошла утилитка lftp, которая поддерживает много протоколов включая SFTP. Список шаблонов для синхронизации записали в файлик, который служит аргументом для --include-glob-from
. Закачка самих файлов идет в несколько потоков (--parallel
) с удалением тех файлов, которых больше нет на источнике (--delete
).
#!/bin/bash LFTP_PROTOCOL=sftp LFTP_HOST=sftp.example.com LFTP_PORT=22 LFTP_USERNAME=sftpuser SFTP_PASSWORD=sftppass REMOTE_DIR=/remote/path LOCAL_DIR=/local/path INCLUDE_LIST=$(dirname $(readlink -f $0))/sftp-mirror.include lftp -u ${LFTP_USERNAME},${LFTP_PASSWORD} ${LFTP_PROTOCOL}://${LFTP_HOST}:${LFTP_PORT} <<_EOF_ cd ${REMOTE_DIR} lcd ${LOCAL_DIR} mirror --recursion=always --no-empty-dirs --delete --parallel=8 --include-glob-from=${INCLUDE_LIST} close _EOF_
Файл sftp-mirror.include
с шаблонами имен по одному на строку, которые нужно зеркалировать
*Element=ABA090*.xml.gz *Element=BAC105*.xml.gz *Element=DOM288*.xml.gz
Расчет разницы и выкачивание новых файлов происходит очень быстро.
пятница, 18 ноября 2022 г.
Nginx запрашивает / вместо /.well-known/openid-configuration
Настраиваю workload identity federation между on-prem GitLab и GCP согласно документации. Сделал настройки в GCP, взял готовый пример пайплайна, но джоба падает с ошибкой
$ gcloud auth print-access-token ERROR: (gcloud.auth.print-access-token) ("Error code invalid_grant: Parsing error for OIDC discovery document: [Line 0, column 0: Unexpected end of stream : expected '{']", '{"error":"invalid_grant","error_description":"Parsing error for OIDC discovery document: [Line 0, column 0: Unexpected end of stream : expected \'{\']"}')
Смотрю что выдаёт https://GITLAB/.well-known/openid-configuration
и вижу 302 редирект на /users/sign_in
- это неожиданное поведение. На этот запрос должно возвращать JSON вида
$ curl -s https://gitlab.com/.well-known/openid-configuration {"issuer":"https://gitlab.com","authorization_endpoint":"https://gitlab.com/oauth/authorize","token_endpoint":"https://gitlab.com/oauth/token","revocation_endpoint":"https://gitlab.com/oauth/revoke","introspection_endpoint":"https://gitlab.com/oauth/introspect","userinfo_endpoint":"https://gitlab.com/oauth/userinfo","jwks_uri":"https://gitlab.com/oauth/discovery/keys","scopes_supported":["api","read_api","read_user","read_repository","write_repository","read_registry","write_registry","sudo","openid","profile","email"],"response_types_supported":["code"],"response_modes_supported":["query","fragment"],"grant_types_supported":["authorization_code","password","client_credentials","refresh_token"],"token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["RS256"],"claim_types_supported":["normal"],"claims_supported":["iss","sub","aud","exp","iat","sub_legacy","name","nickname","email","email_verified","website","profile","picture","groups","groups_direct","https://gitlab.org/claims/groups/owner","https://gitlab.org/claims/groups/maintainer","https://gitlab.org/claims/groups/developer"]}
Нужно разобраться откуда у меня берется этот редирект.
воскресенье, 13 ноября 2022 г.
Spinnaker - день второй
Второй день изучения Spinnaker (почитать про первый день можно тут). На сегодня в планах построить минимальную инфраструктуру вокруг Spinnaker и задеплоить приложение в отдельный GKE кластер.
Spinnaker у меня крутится в VirtualBox, поэтому нужно создать ключ для IAM сервис аккаунта, который будет использоваться для доступа в GCS, GCR и Pub/Sub. Для подключения к GKE я сгенерировал отдельный kubeconfig.
При составлении пайплайна для Spinnaker я пользовался репозитарием spinnaker-for-gcp. Сам туториал у меня не завелся из-за недоступности управления IAM в Cloud Playground.
среда, 9 ноября 2022 г.
Binary grep
В базе материализовалась запись, которая приводит к ошибкам вида org.postgresql.util.PSQLException: ERROR: invalid byte sequence for encoding "UTF8": 0xed 0x70 0x69
. Возникает такое когда кто-то сделал изменение в таблице, но при этом соединение с базой не было настроено на UTF-8.
По прошлому опыту, данные вставили в кодировке latin1 и там будут символы вроде "í", "é", "á" или им подобные. Можно записать байтики в файлик и использовать его как паттерн для grep, но захотелось возможности грепать сразу в виде байтов.
понедельник, 7 ноября 2022 г.
Spinnaker - день первый
Первый раз я узнал про Spinnaker от коллеги года четыре назад. Тогда я немного покликал по интерфейсу, посмотрел архитектурную диаграмму и успешно забыл про него. Позже он еще несколько раз всплывал в "байках" с полей от коллег, но пересечься более не довелось.
Недели две назад Spinnaker снова появился на радаре в виде презентации от заказчика и вопросом стоит ли его использовать. Нутро подсказывало что не стоит с ним связываться, но четких аргументов я сформулировать тогда не смог т.к. практического опыта не было. Ради обоснованных аргументов я и решился на близкое знакомство со Spinnaker в рамках прошедших выходных.