我正在尝试将我的 python 网络应用程序与 vault 和 postgres 连接起来。我完全不知道如何进一步进行。任何帮助将不胜感激

问题描述 投票:0回答:0

这是我的 docker-compose 文件:

version: "3.9"
services:

  app:
    build: ./app/
    environment:
      MY_ADDRESS:                   :8080
      VAULT_ADDRESS:                http://127.0.0.1:8200
      VAULT_APPROLE_ROLE_ID:        sample_app
      VAULT_APPROLE_SECRET_ID_FILE: /tmp/secret
      VAULT_DATABASE_CREDS_PATH:    database/creds/dev-readonly
      VAULT_API_KEY_PATH:           api-key
      VAULT_API_KEY_MOUNT_PATH:     kv-v2
      VAULT_API_KEY_FIELD:          api-key-field
      DATABASE_HOSTNAME:            database
      DATABASE_PORT:                5432
      DATABASE_NAME:                postgres
      DATABASE_TIMEOUT:             10
      SECURE_SERVICE_ADDRESS:       http://secure-service/api
    volumes:
      - type:   volume
        source: trusted-orchestrator-volume
        target: /tmp
    ports:
      - "8080:8080"
    depends_on:
      vault-server:
        condition: service_healthy
      trusted-orchestrator:
        condition: service_healthy
      database:
        condition: service_healthy
      secure-service:
        condition: service_healthy

  vault-server:
    build: ./docker-compose-setup/vault-server/
    cap_add:
      - IPC_LOCK
    environment:
      VAULT_DEV_ROOT_TOKEN_ID: root
      APPROLE_ROLE_ID:         sample_app
      ORCHESTRATOR_TOKEN:      insecure-token
      DATABASE_HOSTNAME:       database
      DATABASE_PORT:           5432
      API_KEY_PATH:            kv-v2/api-key
      API_KEY_FIELD:           api-key-field
    ports:
      - "8200:8200"
    depends_on:
      database:
        condition: service_healthy

  trusted-orchestrator:
    build: ./docker-compose-setup/trusted-orchestrator
    environment:
      VAULT_ADDRESS:      http://vault-server:8200
      ORCHESTRATOR_TOKEN: insecure-token
    volumes:
      - type:   volume
        source: trusted-orchestrator-volume
        target: /tmp
    depends_on:
      vault-server:
        condition: service_healthy

  database:
    image: postgres:15
    environment:
      PGUSER: postgres
      POSTGRES_PASSWORD: root
    volumes:
      - type:   bind
        source: ./docker-compose-setup/database/
        target: /docker-entrypoint-initdb.d/
    ports:
      - "5432:5432"
    healthcheck:
      test:         [ "CMD", "/usr/bin/pg_isready" ]
      start_period: 1s
      interval:     1s
      timeout:      1s
      retries:      30

  # a simulated 3rd party service that requires a specific header to get a 200 response
  secure-service:
    image: nginx:latest
    environment:
      EXPECTED_API_KEY: my-secret-key # sets the expected value for incoming requests' header X-API-KEY
    volumes:
      - type:   bind
        source: ./docker-compose-setup/secure-service/default.conf.template
        target: /etc/nginx/templates/default.conf.template
    ports:
      - "1717:80"
    healthcheck:
      test:         curl --fail -s http://localhost/healthcheck || exit 1
      start_period: 1s
      interval:     1s
      timeout:      1s
      retries:      30

  # a dummy service which blocks "docker compose up -d" from returning until all services are up & healthy
  app-healthy:
    image: alpine:latest
    command: [ "echo", "all services are up & healthy" ]
    depends_on:
      app:
        condition: service_healthy

volumes:
  trusted-orchestrator-volume:

app.py

from flask import Flask, jsonify
import os
import hvac
import psycopg2

app = Flask(__name__)


class Environment:
    def __init__(self):
        self.my_address = os.getenv('MY_ADDRESS', ':8080')
        self.vault_address = os.getenv('VAULT_ADDRESS', '127.0.0.1:8200')
        self.vault_approle_role_id = os.getenv('VAULT_APPROLE_ROLE_ID')
        self.vault_approle_secret_id_file = os.getenv(
            'VAULT_APPROLE_SECRET_ID_FILE', '/tmp/secret')
        self.vault_api_key_path = os.getenv('VAULT_API_KEY_PATH', 'api-key')
        self.vault_api_key_mount_path = os.getenv(
            'VAULT_API_KEY_MOUNT_PATH', 'kv-v2')
        self.vault_api_key_field = os.getenv(
            'VAULT_API_KEY_FIELD', 'api-key-field')
        self.vault_database_creds_path = os.getenv(
            'VAULT_DATABASE_CREDS_PATH', 'database/creds/dev-readonly')
        self.database_hostname = os.getenv('DATABASE_HOSTNAME')
        self.database_port = os.getenv('DATABASE_PORT', '5432')
        self.database_name = os.getenv('DATABASE_NAME', 'postgres')
        self.database_timeout = int(os.getenv('DATABASE_TIMEOUT', '10'))
        self.secure_service_address = os.getenv('SECURE_SERVICE_ADDRESS')


def get_vault_client(env):
    client = hvac.Client(url=f'http://{env.vault_address}')
    with open(env.vault_approle_secret_id_file, 'r') as f:
        secret_id = f.read().strip()
    response = client.auth.approle.login(
        env.vault_approle_role_id, secret_id=secret_id)
    if not response['auth']:
        raise Exception('unable to authenticate with Vault')
    client.token = response['auth']['client_token']
    return client


def get_database_connection(env, vault_client):
    database_credentials = vault_client.read(
        env.vault_database_creds_path)['data']
    conn = psycopg2.connect(
        host=env.database_hostname,
        port=env.database_port,
        dbname=env.database_name,
        user=database_credentials['username'],
        password=database_credentials['password'],
        connect_timeout=env.database_timeout
    )
    return conn


@app.route('/')
def hello():
    return jsonify({'message': 'hello'})


if __name__ == '__main__':
    env = Environment()
    vault_client = get_vault_client(env)
    conn = get_database_connection(env, vault_client)
    app.run(host='0.0.0.0', port=int(env.my_address.split(':')[1]))

Dockerfile


FROM python:3.7 AS build
COPY   . /app
WORKDIR /app
RUN python -m pip install -r requirements.txt

EXPOSE 8080
CMD python app.py runserver

HEALTHCHECK \
    --start-period=1s \
    --interval=1s \
    --timeout=1s \
    --retries=30 \
    CMD curl --fail -s http://localhost:8080/healthcheck || exit 1

错误:

2023-03-15 22:45:58 Traceback (most recent call last):
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/urllib3/connection.py", line 175, in _new_conn
2023-03-15 22:45:58     (self._dns_host, self.port), self.timeout, **extra_kw
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/urllib3/util/connection.py", line 72, in create_connection
2023-03-15 22:45:58     for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/socket.py", line 752, in getaddrinfo
2023-03-15 22:45:58     for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
2023-03-15 22:45:58 socket.gaierror: [Errno -2] Name or service not known
2023-03-15 22:45:58 
2023-03-15 22:45:58 During handling of the above exception, another exception occurred:
2023-03-15 22:45:58 
2023-03-15 22:45:58 Traceback (most recent call last):
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 710, in urlopen
2023-03-15 22:45:58     chunked=chunked,
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 398, in _make_request
2023-03-15 22:45:58     conn.request(method, url, **httplib_request_kw)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/urllib3/connection.py", line 244, in request
2023-03-15 22:45:58     super(HTTPConnection, self).request(method, url, body=body, headers=headers)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/http/client.py", line 1281, in request
2023-03-15 22:45:58     self._send_request(method, url, body, headers, encode_chunked)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/http/client.py", line 1327, in _send_request
2023-03-15 22:45:58     self.endheaders(body, encode_chunked=encode_chunked)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/http/client.py", line 1276, in endheaders
2023-03-15 22:45:58     self._send_output(message_body, encode_chunked=encode_chunked)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/http/client.py", line 1036, in _send_output
2023-03-15 22:45:58     self.send(msg)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/http/client.py", line 976, in send
2023-03-15 22:45:58     self.connect()
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/urllib3/connection.py", line 205, in connect
2023-03-15 22:45:58     conn = self._new_conn()
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/urllib3/connection.py", line 187, in _new_conn
2023-03-15 22:45:58     self, "Failed to establish a new connection: %s" % e
2023-03-15 22:45:58 urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7fee879ffad0>: Failed to establish a new connection: [Errno -2] Name or service not known
2023-03-15 22:45:58 
2023-03-15 22:45:58 During handling of the above exception, another exception occurred:
2023-03-15 22:45:58 
2023-03-15 22:45:58 Traceback (most recent call last):
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 499, in send
2023-03-15 22:45:58     timeout=timeout,
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 788, in urlopen
2023-03-15 22:45:58     method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/urllib3/util/retry.py", line 592, in increment
2023-03-15 22:45:58     raise MaxRetryError(_pool, url, error or ResponseError(cause))
2023-03-15 22:45:58 urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='http', port=80): Max retries exceeded with url: //127.0.0.1:8200/v1/auth/approle/login (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fee879ffad0>: Failed to establish a new connection: [Errno -2] Name or service not known'))
2023-03-15 22:45:58 
2023-03-15 22:45:58 During handling of the above exception, another exception occurred:
2023-03-15 22:45:58 
2023-03-15 22:45:58 Traceback (most recent call last):
2023-03-15 22:45:58   File "app.py", line 63, in <module>
2023-03-15 22:45:58     vault_client = get_vault_client(env)
2023-03-15 22:45:58   File "app.py", line 35, in get_vault_client
2023-03-15 22:45:58     env.vault_approle_role_id, secret_id=secret_id)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/hvac/api/auth_methods/approle.py", line 509, in login
2023-03-15 22:45:58     json=params,
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/hvac/adapters.py", line 194, in login
2023-03-15 22:45:58     response = self.post(url, **kwargs)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/hvac/adapters.py", line 123, in post
2023-03-15 22:45:58     return self.request("post", url, **kwargs)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/hvac/adapters.py", line 372, in request
2023-03-15 22:45:58     response = super().request(*args, **kwargs)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/hvac/adapters.py", line 336, in request
2023-03-15 22:45:58     **_kwargs
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 587, in request
2023-03-15 22:45:58     resp = self.send(prep, **send_kwargs)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 701, in send
2023-03-15 22:45:58     r = adapter.send(request, **kwargs)
2023-03-15 22:45:58   File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 565, in send
2023-03-15 22:45:58     raise ConnectionError(e, request=request)
2023-03-15 22:45:58 requests.exceptions.ConnectionError: HTTPConnectionPool(host='http', port=80): Max retries exceeded with url: //127.0.0.1:8200/v1/auth/approle/login (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fee879ffad0>: Failed to establish a new connection: [Errno -2] Name or service not known'))

除 2 个外,所有容器都已启动并运行。在这一点上,在我看来,我已尝试一切来解决问题,但无法解决。任何帮助都意义重大。

一些容器日志-

POSTGRES - PostgreSQL init process complete; ready for start up.
SECURE-SERVICE - THE OUTPUT KEEPS ON REPEATING. - "GET /healthcheck HTTP/1.1" 200 16 "-" "curl/7.74.0" "-"
TRUSTED ORCHESTRATOR - 2023-03-15 23:42:02 18:12:02: requesting new secret id
2023-03-15 23:42:02 18:12:02: 0
2023-03-15 23:42:02 18:12:02: wrote wrapped secret id to /tmp/secret
2023-03-15 23:43:02 18:13:02: requesting new secret id
2023-03-15 23:43:02 18:13:02: 0
2023-03-15 23:43:02 18:13:02: wrote wrapped secret id to /tmp/secret
VAULT SERVER HAS A LOT OF OUTPUT AND FINALLY SAYS THIS - Success! Enabled the database secrets engine at: database/

上面提到的应用程序容器输出 THIS IS MY TERMINAL

python docker hashicorp-vault vault
© www.soinside.com 2019 - 2024. All rights reserved.