Как связать dockerized python скрипт с mysql docker контейнером для загрузки данных на тот же хост? - PullRequest
0 голосов
/ 31 марта 2020

У меня есть два docker контейнера, работающих на машине с Ubuntu 16.04, один docker имеет сервер mysql, другой контейнер содержит dockerized сценарий python, настроенный для запуска задания cron каждую минуту, который загружается данные в mysql. Как мне соединить эти два устройства для загрузки данных через скрипт python в контейнер mysql? У меня появляется сообщение об ошибке: Вот мои соответствующие команды:

MYSQL контейнер работает без проблем:

docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=yourPassword --name icarus -d mysql_docker_image

CONTAINER ID        IMAGE                             COMMAND                  CREATED             STATUS                    PORTS                               NAMES
927e50ca0c7d        mysql_docker_image                "docker-entrypoint.s…"   About an hour ago   Up About an hour          0.0.0.0:3306->3306/tcp, 33060/tcp   icarus

Второй контейнер содержит cron и python script:

 #build the container without issue    
    sudo docker run -t -i -d docker-cron

    #exec into it to check logs
    sudo docker exec -i -t container_id /bin/bash

    #check logs
    root@b149b5e7306d:/# cat /var/log/cron.log

Ошибка:

появляется следующая ошибка, которая, по моему мнению, связана с неправильным адресом хоста:

Caught this error: OperationalError('(pymysql.err.OperationalError) (2003, "Can\'t connect to MySQL server on \'localhost\' ([Errno 99] Cannot assign requested address)")',)

Python Сценарий:

from traffic.data import opensky
from sqlalchemy import create_engine
#from sqlalchemy_utils import database_exists, create_database
import sqlalchemy
import gc


#connection and host information
host = 'localhost'
db='icarus'
engine = create_engine('mysql+pymysql://root:password@'+ host+ ':3306/'+ db) #create engine connection
version= sys.version_info[0]

#functions to upload data
def upload(df,table_name):
    df.to_sql(table_name,con=engine,index=False,if_exists='append')
    engine.dispose()
    print('SUCCESSFULLY LOADED DATA INTO STAGING...')

#pull data drom api
sv = opensky.api_states()
final_df = sv.data
#quick column clean up 
print(final_df.head())
final_df=final_df.rename(columns = {'timestamp':'time_stamp'})


#insert data to staging
try:
    upload(final_df, 'flights_stg')
except Exception as error:
        print('Caught this error: ' + repr(error))
del(final_df)
gc.collect()

Я предполагаю, что в качестве адреса используется localhost? Как бы я go решил что-то подобное?

Дополнительная информация:

MYSQL Dockerfile:

FROM mysql
COPY init.sql /docker-entrypoint-initdb.d

Python Dockerfile:

FROM ubuntu:latest

WORKDIR /usr/src/app

#apt-get install -y build-essential -y  python python-dev python-pip python-virtualenv libmysqlclient-dev curl&& \

RUN \
  apt-get update && \
  apt-get install -y build-essential -y git -y  python3.6 python3-pip libproj-dev proj-data proj-bin libgeos++-dev libmysqlclient-dev python-mysqldb curl&& \
  rm -rf /var/lib/apt/lists/*

COPY requirements.txt ./
RUN pip3 install --upgrade pip && \
    pip3 install --no-cache-dir -r requirements.txt

RUN pip3 install --upgrade setuptools
RUN pip3 install git+https://github.com/xoolive/traffic

COPY . .

# Install cron
RUN apt-get update
RUN apt-get install cron

# Add crontab file in the cron directory
ADD crontab /etc/cron.d/simple-cron

# Add shell script and grant execution rights
ADD script.sh /script.sh
RUN chmod +x /script.sh

# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/simple-cron

# Create the log file to be able to run tail
RUN touch /var/log/cron.log

# Run the command on container startup
CMD cron && tail -f /var/log/cron.log

Ответы [ 2 ]

0 голосов
/ 31 марта 2020

Похоже, что определяемый пользователем сетевой мост был путем к go здесь, как рекомендовано. Решена проблема:

docker network create my-net

docker create --name mysql \
  --network my-net \
  --publish 3306:3306 \
  -e MYSQL_ROOT_PASSWORD=password \
  mysql:latest


docker create --name docker-cron \
  --network my-net \
  docker-cron:latest

docker запустить каждый из них и использовать --name в качестве хоста.

0 голосов
/ 31 марта 2020

Можете ли вы поделиться своим докер-файлом или составить файл из MySQL контейнера. Да, проблема связана с использованием localhost в качестве хоста. Вы должны использовать docker имя сервиса в качестве хоста. Так в docker имя сервиса работает как DNS. Например, если ваша docker -композиция выглядит так:

services:
mydb:
 image: mysql:5.7
 command: --default-authentication-plugin=mysql_native_password
 restart: always
 environment:
   MYSQL_ROOT_PASSWORD:root
   MYSQL_USER: root
   MYSQL_PASSWORD: root
   MYSQL_DATABASE: root

Вы должны использовать mydb вместо localhost

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...