2015-04-15 19 views
5

Tôi cố gắng triển khai docker với ansible. Tôi có một vùng chứa cơ sở dữ liệu docker và trong vùng chứa khác là ứng dụng web của tôi và tôi cố gắng liên kết hai vùng chứa này. Vấn đề là thùng chứa cơ sở dữ liệu không có thời gian để cấu hình chính nó và một thùng chứa web đã được bắt đầu. Playbook ansible của tôi trông giống như:docker với sự chờ đợi an toàn cho cơ sở dữ liệu

... 
- name: run mysql in docker container 
    docker: 
    image: "mysql:5.5" 
    name: database 
    env: "MYSQL_ROOT_PASSWORD=password" 
    state: running 

- name: run application containers 
    docker: 
    name: "application" 
    image: "myapp" 
    ports: 
     - "8080:8080" 
    links: 
     - "database:db" 
    state: running 

Cách xác định xem cơ sở dữ liệu có bắt đầu không? Tôi thử với module wait_for, nhưng điều đó không hiệu quả. Tôi không muốn thiết lập thời gian chờ, nó không phải là lựa chọn tốt cho tôi.

Trả lời

1

Sử dụng mô-đun wait_for. Tôi không có chuyên gia về MySQL nhưng tôi giả định sẽ có một số cổng hoặc sự tồn tại của tập tin hoặc tin nhắn trong một số tập tin đăng nhập vv bạn có thể kiểm tra để tìm hiểu xem DB là lên hay không.

Dưới đây là ví dụ về wait_for được sao chép từ liên kết ở trên.

# wait 300 seconds for port 8000 to become open on the host, don't start checking for 10 seconds 
- wait_for: port=8000 delay=10 

# wait 300 seconds for port 8000 of any IP to close active connections, don't start checking for 10 seconds 
- wait_for: host=0.0.0.0 port=8000 delay=10 state=drained 

# wait 300 seconds for port 8000 of any IP to close active connections, ignoring connections for specified hosts 
- wait_for: host=0.0.0.0 port=8000 state=drained exclude_hosts=10.2.1.2,10.2.1.3 

# wait until the file /tmp/foo is present before continuing 
- wait_for: path=/tmp/foo 

# wait until the string "completed" is in the file /tmp/foo before continuing 
- wait_for: path=/tmp/foo search_regex=completed 

# wait until the lock file is removed 
- wait_for: path=/var/lock/file.lock state=absent 

# wait until the process is finished and pid was destroyed 
- wait_for: path=/proc/3466/status state=absent 

# wait 300 seconds for port 22 to become open and contain "OpenSSH", don't assume the inventory_hostname is resolvable 
# and don't start checking for 10 seconds 
- local_action: wait_for port=22 host="{{ ansible_ssh_host | default(inventory_hostname) }}" search_regex=OpenSSH delay=10 
+0

Trong khi tôi tin rằng '' 'wait_for''' là câu trả lời đúng, điều này dẫn đến một vấn đề khác: Cách tìm ra địa chỉ IP của vùng chứa docker? Vùng chứa cơ sở dữ liệu không liên kết với một cổng trên máy chủ cục bộ để đợi nó khởi động, chúng ta sẽ cần địa chỉ IP được gán cho vùng chứa bởi docker. Tôi hiện đang nhận IP bằng cách sử dụng '' 'docker inspection''' nhưng điều này vẫn chưa cung cấp kết quả. –

+0

@Tobias có lẽ đăng một câu hỏi mới với các chi tiết thích hợp sẽ giúp ích. – Kashyap

10

wait_for không làm việc cho container Docker MySQL bởi vì nó chỉ kiểm tra rằng cổng khả năng kết nối (đó là sự thật ngay lập tức cho các thùng chứa Docker). Tuy nhiên, wait_for không kiểm tra xem dịch vụ bên trong thùng chứa có lắng nghe cổng và gửi phản hồi cho khách hàng hay không.

Đây là cách tôi đang chờ đợi trong playbook ansible cho dịch vụ MySQL trở thành hoạt động đầy đủ bên trong container Docker:

- name: Start MySQL container 
    docker: 
    name: some-name 
    image: mysql:latest 
    state: started 
    ports: 
    - "8306:3306" # it's important to expose the port for waiting requests 
    env: 
     MYSQL_ROOT_PASSWORD: "{{ mysql_root_password }}" 

- template: mode="a+rx,o=rwx" src=telnet.sh.j2 dest=/home/ubuntu/telnet.sh 

# wait while MySQL is starting 
- action: shell /home/ubuntu/telnet.sh 
    register: result 
    until: result.stdout.find("mysql_native_password") != -1 
    retries: 10 
    delay: 3 

Và telnet.sh.j2 được

#!/bin/bash -e 

telnet localhost 8306 || true 
+1

Bất kỳ lý do nào bạn đang chạy lệnh telnet trong một tập lệnh riêng biệt? – dirk

2

Để tránh sh và tôi thường không có telnet cài đặt ...

- name: Wait for database to be available 
    shell: docker run --rm --link mysql:mysql mysql sh -c 'mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p{{mysql_password}} || true' 
    register: result 
    until: result.stderr.find("Can't connect to MySQL") == -1 
    retries: 10 
    delay: 3 
+0

Điều này làm việc tốt cho tôi và tôi thích rằng nó tránh một kịch bản hoặc telnet. Tôi đang sử dụng một biến thể với 'mysqladmin ping' và' docker exec'. Tôi sử dụng module 'command' với' docker exec {{container_name}} mysqladmin ping' và sau đó 'until' trở thành' result.rc == 0'. –

1

Điều này làm việc cho tôi jus t fine:

- name: get mariadb IP address 
    command: "docker inspect --format '{''{ .NetworkSettings.IPAddress }''}' mariadb-container" 
    register: mariadb_ip_address 
    - name: wait for mariadb to become ready 
    wait_for: 
     host: "{{ mariadb_ip_address.stdout }}" 
     port: 3306 
     state: started 
     delay: 5 
     connect_timeout: 15 
     timeout: 30 
Các vấn đề liên quan