Awx-operator: Вытяните оператор без создания локальной базы данных awx-postgres-0

Созданный на 7 апр. 2021  ·  9Комментарии  ·  Источник: ansible/awx-operator

У меня не было проблем с установкой экземпляра awx k8s с использованием внешней базы данных postgres, локально и в лазурном, но вытаскивание awx-operator.yaml в соответствии с readme все равно создало локальный модуль postgres, даже если он не используется.

awx-postgres-0                 1/1     Running   0          3h20m

Этот модуль занимает ресурсы кластера существующими, я просмотрел документы awx и tower, но я не могу понять, как вытащить оператора, не создавая этот локальный db. Есть ли процедура для решения этой проблемы где-то в документации или вы просто должны удалить ресурсы вручную? Каждый раз, когда я касаюсь капсулы, срабатывает цикл согласования.

Все 9 Комментарий

Оператор должен развертывать Postgres StatefulSet только при очень специфических условиях:

https://github.com/ansible/awx-operator/blob/0043c375d89f27d164519efc4a3bfac641002e39/roles/installer/tasks/database_configuration.yml#L67 -L72

У вас должен быть секрет с именем {{ meta.name }}-postgres-configuration .

Можете ли вы посмотреть на него и увидеть, видите ли вы type: managed ? Если да, удалите этот ключ / значение и посмотрите, что произойдет.

Спасибо за ответ. Управляемый действительно был типом, указание секрета awx-postgres-configuration как в приведенном ниже определении, вызывает только модули awx- и awx-operator- так что это именно то, что я хотел. Контейнер awx-task, похоже, не работает в django с неправильным именем пользователя для моего «управляемого» экземпляра postgres с именем пользователя psqladminun но имя пользователя - psqladminun@awx-external-postgres которым я могу подключиться вне awx.

Я все еще использовал локальную базу данных из-за этого недоразумения. Вы можете видеть путаницу, я принял managed за экземпляр, управляемый облаком, т.е. использовал какой-то sslmode: <required/preferred> и ожидал @ в имени, но это была моя ошибка. Мне пришлось отключить tls в соединении, потому что, похоже, нет способа установить это в awx-postgres-configuration . Я полагаю, это инвентарь? Как только я отключил tls, я получил ошибку имени пользователя. Я подключаюсь как psqladminun только для проверки соединения, но это определенно не имя пользователя.

2021-04-08 13:25:13,818 ERROR    [-] awx.conf.settings Database settings are not available, using defaults.
Traceback (most recent call last):
  File "/var/lib/awx/venv/awx/lib/python3.6/site-packages/django/db/backends/base/base.py", line 217, in ensure_connection
    self.connect()
  File "/var/lib/awx/venv/awx/lib/python3.6/site-packages/django/db/backends/base/base.py", line 195, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/var/lib/awx/venv/awx/lib/python3.6/site-packages/django/db/backends/postgresql/base.py", line 178, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/var/lib/awx/venv/awx/lib/python3.6/site-packages/psycopg2/__init__.py", line 126, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: FATAL:  password authentication failed for user "psqladminun"
FATAL:  password authentication failed for user "psqladminun"
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: awx
  namespace: default
spec:
  tower_hostname: <hostname>
  tower_admin_user: admin
  tower_admin_password_secret: awx-admin-password
  tower_admin_email: <email>
  tower_ingress_type: Ingress
  tower_web_resource_requirements:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 1000m
      memory: 2Gi
  tower_task_resource_requirements:
    requests:
      cpu: 250m
      memory: 500Mi
    limits:
      cpu: 500m
      memory: 1Gi
---
apiVersion: v1
kind: Secret
metadata:
  name: awx-postgres-configuration
  namespace: default
stringData:
  host: "<host>"
  port: "5432"
  database: "awx"
  username: "psqladminun@awx-external-postgres"
  password: "<pass>"
type: Opaque

@ ac-obair не могли бы вы прислать нам информацию, указанную ниже:

  1. Из вашего контейнера awx-task , что у вас есть ниже: (пожалуйста, запутайте pwd)
# cat /etc/tower/conf.d/credentials.py
  1. Все еще в контейнере awx-task , что произойдет, если вы это сделаете:
psql -h "<host>" awx -U 'psqladminun@awx-external-postgres' 

Я просто смотрел на этот файл, он существует как в контейнерах awx-task и в awx-web . Как ни странно, пароль цитируется более одного раза синглами ' внутри двойных " . Конфигурация tls 'sslmode': 'prefer' . Я подключился к postgres db, так как на данный момент я удалил awx db. Цитаты, похоже, вызывают ту же ошибку, что и при трассировке.

# trying with <password>

bash-4.4$ psql -h <host> postgres -U 'psqladminun@awx-external-postgres'
Password for user psqladminun@awx-external-postgres:
psql (12.5, server 11.6)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=> exit

# trying with '<password>'

bash-4.4$ psql -h <host> postgres -U 'psqladminun@awx-external-postgres'
Password for user psqladminun@awx-external-postgres:
psql: error: FATAL:  password authentication failed for user "psqladminun"
FATAL:  password authentication failed for user "psqladminun"
DATABASES = {
    'default': {
        'ATOMIC_REQUESTS': True,
        'ENGINE': 'awx.main.db.profiled_pg',
        'NAME': "awx",
        'USER': "psqladminun@awx-external-postgres",
        'PASSWORD': "'<password>'",
        'HOST': '<host>',
        'PORT': "5432",
        'OPTIONS': { 'sslmode': 'prefer',
                     'sslrootcert': '/etc/pki/tls/certs/ca-bundle.crt',
        },
    }
}

BROADCAST_WEBSOCKET_SECRET = "<some_secret>"

Я повторно развернул с приведенным ниже определением развертывания, используя голую строку, без кавычек, но шаблон credentials.py был таким же, и у меня нет прав для редактирования файла на диске.

apiVersion: v1
kind: Secret
metadata:
  name: awx-postgres-configuration
  namespace: default
stringData:
  host: "<host>"
  port: "5432"
  database: awx
  username: "psqladminun@awx-external-postgres"
  password: <password>
type: Opaque

Оскорбительная линия, кажется, здесь
https://github.com/ansible/awx-operator/blob/9503d3cf485224c90b18f6c514dc3713781eb6e9/roles/installer/templates/credentials.py.j2#L7
В этом файле есть общее сочетание кавычек, которые, я думаю, были предназначены для избежания escape-символов, я не уверен, но файлы .j2 буквально интерпретируют кавычки и шаблонизируют их, я уверен, что это сработает:

 'PASSWORD': {{ awx_postgres_pass | quote }}, 

Я создал новый оператор с указанным выше изменением

TASK [Verify there is one AWX kind] ********************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

TASK [Get AWX Pod data] ********************************************************
ok: [localhost]

TASK [Verify there is one AWX pod] *********************************************
ok: [localhost] => {
    "changed": false,
    "msg": "All assertions passed"
}

Все подключил и работает.

@ ac-obair благодарит за устранение неполадок. Я провел здесь несколько тестов, и ни один из моих паролей secrets был создан с помощью single-quote , но действительно, я могу подтвердить, что добавление quote вызовет ошибку пароля.

Например, вот 2 auto-generated-secrets для экземпляра auto-managed db:

kubectl modify-secret awx-ssl-disable-postgres-configuration
database: awx
host: example4-awx-postgres
password: XyKu8gc65Ks2xd2Bwmx90RUg2NZkO4mS
port: "5432"
type: managed
username: awx
kubectl modify-secret awx-localdb-postgres-configuration
 database: awx 
 host: awx-ssl-disable-postgres
 password: 5puCoNewQEC5xoR2KIUvwrEzvVpKP458
 port: "5432"
 type: managed
 username: awx 

Как вы можете видеть выше, к none строк паролей было добавлено quotes , поскольку мы будем полагаться на шаблон jinja2 чтобы процитировать его для нас.

Итак, я считаю, что проблема была связана с природой внешнего secret созданного вручную, если пользователь добавляет quotes в сам secret , тогда он закончится с quotes дважды, как вы упомянули. Итак, посмотрите на тест ниже:

#  kubectl iexec localdb /bin/bash
Namespace: default | Pod: ✔ awx-localdb-b9748fd44-qs8zk
Container: ✔ awx-localdb-web
bash-4.4$ cat /etc/tower/conf.d/credentials.py 
DATABASES = {
    'default': {
        'ATOMIC_REQUESTS': True,
        'ENGINE': 'awx.main.db.profiled_pg',
        'NAME': "awx",
        'USER': "awx",
        'PASSWORD': "CXZtSTuyJoAH0M4rASSG0EYpFCh6p0c8",  <=== added quotes by jinja2 
        'HOST': 'awx-localdb-postgres',
        'PORT': "5432",
        'OPTIONS': { 'sslmode': 'prefer',
                     'sslrootcert': '/etc/pki/tls/certs/ca-bundle.crt',
        },
    }
}

BROADCAST_WEBSOCKET_SECRET = "SZyZxQSk8vwFMljjMTE5mVRdzJCE6Awq"

Пытаюсь подключиться:

bash-4.4$ PGPASSWORD="CXZtSTuyJoAH0M4rASSG0EYpFCh6p0c8" psql -h awx-localdb-postgres -U awx
psql (12.5, server 12.6 (Debian 12.6-1.pgdg100+1))
Type "help" for help.

awx=# \q
bash-4.4$ PGPASSWORD="'CXZtSTuyJoAH0M4rASSG0EYpFCh6p0c8'" psql -h awx-localdb-postgres -U awx
psql: error: FATAL:  password authentication failed for user "awx"

Чтобы попытаться избежать этой проблемы в будущем, я добавил https://github.com/ansible/awx-operator/pull/199, чтобы предупредить об этой проблеме.

@tchellomello У меня был type: managed postgres-0, работающий с моей исходной конфигурацией. Я установил контейнер postgres локально на своем ноутбуке за пределами k8s, чтобы имитировать внешнее соединение, и это тоже сработало. Я также перестроил свою текущую настройку с подключением к лазурному серверу с паролем без кавычек, и это был шаблон с двойными кавычками, что привело к той же проблеме.

Каждый раз с кавычками или без них без проблем, пока не запускал экземпляр db в лазурном, тогда возникала проблема. Теперь, когда я лучше знаком с кодом, я не понимаю, как это может происходить, если он работает локально. Я дважды проверю эти результаты сегодня вечером и подтвердю, но, похоже, есть очень конкретное условие, которое вызывает это, независимо от того, цитируется ли мой пароль, указанный пользователем, или нет, поскольку даже если это _не_ jinja в этой строке, _ будет _ обернуть его дважды.
https://github.com/ansible/awx-operator/blob/9503d3cf485224c90b18f6c514dc3713781eb6e9/roles/installer/templates/credentials.py.j2#L7
Если только что-то не удаляет внешнюю цитату для type: managed .

@tchellomello Как я и подозревал, это не имеет ничего общего с тем, закомментировано ли значение yaml для ключа password: изначально или нет. Исправление для jinja, которое я предоставил выше, было правильным для шаблона строки, когда требуются кавычки. Я не уверен, почему ! нарушает шаблон, но это определенно так. При создании пароля для базы данных postgres в лазурном режиме требуются специальные символы. Я предполагаю, что из вашего примера автоматически сгенерированные пароли являются буквенно-цифровыми, и этот случай пароля не проверяется.

Вот мой секретный yaml снова с проверенными случаями паролей, за которыми следует шаблонный результат credentials.py . Я использовал лазурный пароль LetjIma1o3uQYbs2cq1GJYkI! . Эти тесты были запущены для локального экземпляра docker postgres, за пределами k8s, в котором awx работает для имитации внешнего соединения, поэтому хост - kubernetes.docker.internal .

apiVersion: v1
kind: Secret
metadata:
  name: awx-postgres-configuration
  namespace: default
stringData:
  host: kubernetes.docker.internal
  port: "5432"
  database: awx
  username: awx
  password: "1234!"    # <--         'PASSWORD': "'1234!'",  templating broken by ! 
  password: "1234"     # <--         'PASSWORD': "1234",     templating fine
  password: 1234!      # <--         'PASSWORD': "'1234!'",  templating broken by !
  password: "12!34"    # <--          'PASSWORD': "'12!34'",  templating broken by !
  password: 1234       # <--          cannot convert int64 to string -- (so needs to be quoted)
  password: '1234!'    # <--         'PASSWORD': "'1234!'",  templating broken by ! 
  password: '1234'     # <--         'PASSWORD': "1234",     templating fine
  password: "LetjIma1o3uQYbs2cq1GJYkI!"   # <--         'PASSWORD': "'LetjIma1o3uQYbs2cq1GJYkI!'",  templating broken by ! 
  password: "LetjIma1o3uQYbs2cq1GJYkI"    # <--         'PASSWORD': "LetjIma1o3uQYbs2cq1GJYkI",   templating fine
type: Opaque

По крайней мере, для моей доступной версии поведение фильтра quote согласовано.

ansible 2.10.7
  config file = None
  configured module search path = ['/Users/<user>/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/<user>/opt/anaconda3/lib/python3.8/site-packages/ansible
  executable location = /Users/<user>/opt/anaconda3/bin/ansible
  python version = 3.8.5 (default, Sep  4 2020, 02:22:02) [Clang 10.0.0 ]

Более интересным, на мой взгляд, является результат 12!34 который показывает, что не имеет значения, где находится ! , просто то, что оно есть. Дальнейшее тестирование с использованием этого шаблона и playbook

'PASSWORD': "{{ awx_postgres_pass_with_bang | quote }}",
'PASSWORD': "{{ awx_postgres_pass_without_bang | quote }}",
---
# ansible-playbook test-playbook.yaml
- hosts: localhost
  gather_facts: no
  name:  test playbook
  tasks:
    - name: set awx_postgres_pass facts
      set_fact:
        awx_postgres_pass_with_bang: hello, world!
        awx_postgres_pass_without_bang: hello, world
    - name: test quote filter
      template:
        src:  credentials.py.j2
        dest: credentials.py



md5-a66fe6ad03852a76d0ccc5ecdf9438fd



'PASSWORD': "'hello, world!'",
'PASSWORD': "'hello, world'",



md5-415db485468708c87aba306e83a47d72



'PASSWORD': {{ awx_postgres_pass_with_bang | quote }},
'PASSWORD': {{ awx_postgres_pass_without_bang | quote }},

@ ac-obair Я попробовал и настроил 2 экземпляра, используя внешнюю базу данных. Посмотрите секреты ниже:

  1. Создание пользователей и базы данных
postgres=# create user awx_special password 's3cret@!_p4ss';
CREATE ROLE
postgres=# create user awx_complex password 's3cret<strong i="8">@_p4ss</strong>';
CREATE ROLE

postgres=# create database "awx_special" owner "awx_special";
CREATE DATABASE
postgres=# create database "awx_complex" owner "awx_complex";
CREATE DATABASE
  1. Создание secret для специального экземпляра
$ kubectl create secret generic awx-special-postgres-configuration  \
    --from-literal=username=awx_special \
    --from-literal=database=awx_special \
    --from-literal=host=toca.pgo.svc \
    --from-literal=port=5432\
    --from-literal=password='s3cret@!_p4ss'\
    --dry-run -o yaml
apiVersion: v1
data:
  database: YXd4X3NwZWNpYWw=
  host: dG9jYS5wZ28uc3Zj
  password: czNjcmV0QCFfcDRzcw==
  port: NTQzMg==
  username: YXd4X3NwZWNpYWw=
kind: Secret
metadata:
  creationTimestamp: null
  name: awx-special-postgres-configuration
  1. Создание secret для экземпляра awx-complex
kubectl create secret generic awx-complex-postgres-configuration \
    --from-literal=username=awx_complex \
    --from-literal=database=awx_complex \
    --from-literal=host=toca.pgo.svc \
    --from-literal=port=5432 \
    --from-literal=password='s3cret<strong i="21">@_p4ss</strong>' \
    --dry-run -o yaml
apiVersion: v1
data:
  database: YXd4X2NvbXBsZXg=
  host: dG9jYS5wZ28uc3Zj
  password: czNjcmV0QF9wNHNz
  port: NTQzMg==
  username: YXd4X2NvbXBsZXg=
kind: Secret
metadata:
  name: awx-complex-postgres-configuration
  1. Запускаем awx-complex и тестируем
$ kubectl get awx awx-complex -o yaml | kubectl neat 
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  labels:
    app.kubernetes.io/component: awx
    app.kubernetes.io/managed-by: awx-operator
    app.kubernetes.io/name: awx-complex
    app.kubernetes.io/part-of: awx-complex
  name: awx-complex
  namespace: default
spec:
  tower_admin_user: admin
  tower_create_preload_data: true
  tower_garbage_collect_secrets: true
  tower_image: quay.io/ansible/awx:19.0.0
  tower_image_pull_policy: IfNotPresent
  tower_loadbalancer_port: 80
  tower_loadbalancer_protocol: http
  tower_postgres_sslmode: prefer
  tower_projects_persistence: false
  tower_projects_storage_access_mode: ReadWriteMany
  tower_projects_storage_size: 8Gi
  tower_replicas: 1
  tower_route_tls_termination_mechanism: Edge
  tower_task_privileged: false

4.1 - Проверка связи с базой данных

kubectl iexec awx-complex /bin/bash      22:32:39
Container: ✔ awx-complex-web
bash-4.4$ cat /etc/tower/conf.d/credentials.py 
DATABASES = {
    'default': {
        'ATOMIC_REQUESTS': True,
        'ENGINE': 'awx.main.db.profiled_pg',
        'NAME': "awx_complex",
        'USER': "awx_complex",
        'PASSWORD': "s3cret@_p4ss",
        'HOST': 'toca.pgo.svc',
        'PORT': "5432",
        'OPTIONS': { 'sslmode': 'prefer',
                     'sslrootcert': '/etc/pki/tls/certs/ca-bundle.crt',
        },
    }
}

BROADCAST_WEBSOCKET_SECRET = "kVvROthFVdR9L0gP0oFrCJdzYNoutEPe"

---- testing db (works)
bash-4.4$ awx-manage  dbshell
psql (12.5, server 13.1)
WARNING: psql major version 12, server major version 13.
         Some psql features might not work.
Type "help" for help.

awx_complex=> 
  1. Запуск awx-special и его тестирование
$ kubectl iexec awx /bin/bash                                                                                              
Namespace: default | Pod: ✔ awx-special-67bddbf5f8-xlkkl
Container: ✔ awx-special-web
bash-4.4$ cat /etc/tower/conf.d/credentials.py 
DATABASES = {
    'default': {
        'ATOMIC_REQUESTS': True,
        'ENGINE': 'awx.main.db.profiled_pg',
        'NAME': "awx_special",
        'USER': "awx_special",
        'PASSWORD': "'s3cret@!_p4ss'",
        'HOST': 'toca.pgo.svc',
        'PORT': "5432",
        'OPTIONS': { 'sslmode': 'prefer',
                     'sslrootcert': '/etc/pki/tls/certs/ca-bundle.crt',
        },
    }
}

BROADCAST_WEBSOCKET_SECRET = "loYNDzQ8bwnzYWWwAnriodrEjLhUlM8I"

----- testing db
bash-4.4$ awx-manage dbshell
psql: error: FATAL:  password authentication failed for user "awx_special"
password retrieved from file "/tmp/tmptrs1zxpo"
Traceback (most recent call last):
  File "/usr/bin/awx-manage", line 8, in <module>
    sys.exit(manage())
  File "/var/lib/awx/venv/awx/lib64/python3.8/site-packages/awx/__init__.py", line 164, in manage
    execute_from_command_line(sys.argv)
  File "/var/lib/awx/venv/awx/lib64/python3.8/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/var/lib/awx/venv/awx/lib64/python3.8/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/var/lib/awx/venv/awx/lib64/python3.8/site-packages/django/core/management/base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/var/lib/awx/venv/awx/lib64/python3.8/site-packages/django/core/management/base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "/var/lib/awx/venv/awx/lib64/python3.8/site-packages/django/core/management/commands/dbshell.py", line 22, in handle
    connection.client.runshell()
  File "/var/lib/awx/venv/awx/lib64/python3.8/site-packages/django/db/backends/postgresql/client.py", line 71, in runshell
    DatabaseClient.runshell_db(self.connection.get_connection_params())
  File "/var/lib/awx/venv/awx/lib64/python3.8/site-packages/django/db/backends/postgresql/client.py", line 61, in runshell_db
    subprocess.check_call(args)
  File "/usr/lib64/python3.8/subprocess.py", line 364, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['psql', '-U', 'awx_special', '-h', 'toca.pgo.svc', '-p', '5432', 'awx_special']' returned non-zero exit status 2.

---- as we can see the problem is with the `double-quotes` combined with the `single-quotes` as mentioned
bash-4.4$ PGPASSWORD='s3cret@!_p4ss' psql  -h toca.pgo.svc -U awx_special awx_special
psql (12.5, server 13.1)
WARNING: psql major version 12, server major version 13.
         Some psql features might not work.
Type "help" for help.

awx_special=> 

Чтобы проверить это, я удалил тег quotes из шаблона и снова протестировал его.

$ kubectl iexec awx /bin/bash               23:15:48
Namespace: default | Pod: ✔ awx-special-67bddbf5f8-6vwd4
Container: ✔ awx-special-web
bash-4.4$ cat /etc/tower/conf.d/credentials.py 
DATABASES = {
    'default': {
        'ATOMIC_REQUESTS': True,
        'ENGINE': 'awx.main.db.profiled_pg',
        'NAME': "awx_special",
        'USER': "awx_special",
        'PASSWORD': "s3cret@!_p4ss",
        'PASSWORD2': "'s3cret@!_p4ss'",    <=== this one still the old code 
        'HOST': 'toca.pgo.svc',
        'PORT': "5432",
        'OPTIONS': { 'sslmode': 'prefer',
                     'sslrootcert': '/etc/pki/tls/certs/ca-bundle.crt',
        },
    }
}

BROADCAST_WEBSOCKET_SECRET = "qsTbVzCBTzrIxK0GpVEmdlnRaqaliKDw"

---- testing db 
bash-4.4$ awx-manage  dbshell
psql (12.5, server 13.1)
WARNING: psql major version 12, server major version 13.
         Some psql features might not work.
Type "help" for help.

awx_special=> 
diff --git a/roles/installer/templates/credentials.py.j2 b/roles/installer/templates/credentials.py.j2
index 986ebe6..9a64551 100644
--- a/roles/installer/templates/credentials.py.j2
+++ b/roles/installer/templates/credentials.py.j2
@@ -4,7 +4,8 @@ DATABASES = {
         'ENGINE': 'awx.main.db.profiled_pg',
         'NAME': "{{ awx_postgres_database }}",
         'USER': "{{ awx_postgres_user }}",
-        'PASSWORD': "{{ awx_postgres_pass | quote }}",
+        'PASSWORD': "{{ awx_postgres_pass }}",
+        'PASSWORD2': "{{ awx_postgres_pass | quote }}",
         'HOST': '{{ awx_postgres_host }}',
         'PORT': "{{ awx_postgres_port }}",
         'OPTIONS': { 'sslmode': '{{ pg_sslmode|default("prefer") }}',

Так что да, похоже, нам нужно будет отбросить кавычки фильтра jinja2. @shanemcd @Spredzy есть мысли?

Обсудили проблему с quotes . Отправка PR в ближайшее время! : +1:

Была ли эта страница полезной?
0 / 5 - 0 рейтинги