মাইএসকিএল সংযোগ প্রস্তুত কিনা ডকার-রচনা পরীক্ষা করুন


91

আমি নিশ্চিত করার চেষ্টা করছি যে আমার অ্যাপ্লিকেশন ধারকটি ডিবি কনটেইনার শুরু না হওয়া অবধি মাইগ্রেশন / আরম্ভ না করে এবং সংযোগগুলি গ্রহণ করার জন্য প্রস্তুত।

সুতরাং আমি স্বাস্থ্য পরীক্ষাটি ব্যবহার করার সিদ্ধান্ত নিয়েছি এবং ডকার কম্পোজ ফাইল ভি 2-র বিকল্পের উপর নির্ভর করে।

অ্যাপটিতে আমার কাছে নিম্নলিখিতগুলি রয়েছে

app:
    ...
    depends_on:
      db:
      condition: service_healthy

অন্যদিকে ডিবিতে নিম্নলিখিত স্বাস্থ্য পরীক্ষা রয়েছে

db:
  ...
  healthcheck:
    test: TEST_GOES_HERE
    timeout: 20s
    retries: 10

আমি কয়েকটি পদ্ধতির চেষ্টা করেছি যেমন:

  1. ডিবি ডিআইআর তৈরি হয়েছে তা নিশ্চিত করে test: ["CMD", "test -f var/lib/mysql/db"]
  2. মাইএসকিএল সংস্করণ পাওয়া: test: ["CMD", "echo 'SELECT version();'| mysql"]
  3. অ্যাডমিনকে পিং করুন (ডিবি কনটেইনারটিকে স্বাস্থ্যকর হিসাবে চিহ্নিত করুন তবে এটি একটি বৈধ পরীক্ষা বলে মনে হচ্ছে না) test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]

কারও কি এর সমাধান আছে?


আপনি একটি ডিবির জন্য একটি ডকার তৈরি করেছেন? আপনার অ্যাপ্লিকেশন স্বাস্থ্যের স্বার্থে আপনার ডেটা এই ধারকটির বাইরে রয়েছে দয়া করে আমাকে বলুন
জর্জি ক্যাম্পোস

বা কমপক্ষে এটি একটি পরীক্ষার ধারক।
হোর্হে ক্যাম্পোস

এটি কেবলমাত্র কেবলমাত্র উদ্দেশ্য জন্য বিকাশ / পরীক্ষার জন্য।
জন করিয়ুকি

4
আমার মনে হয় আপনি সংযোগ এবং মাইএসকিউএল একটি ক্যোয়ারী চালানোর জন্য একটি কমান্ড ব্যবহার করা উচিত, নমুনা কেউই আপনি এই কাজ করতে দেওয়া: ভালো কিছু:mysql -u USER -p PASSWORD -h MYSQLSERVERNAME -e 'select * from foo...' database-name
হোর্হে Campos,

4
@ জোর্জ ক্যাম্পোস ঠিক আছে ধন্যবাদ। সাধারণত আমার কাছে একটি ডিবি কনটেইনার থাকে তবে ডেটা ডিয়ারের জন্য মানচিত্রের মান হয়। যাতে ধারক নেমে গেলে ডেটাটি পরবর্তী তাত্ক্ষণিক চলতে থাকবে।
এস ..

উত্তর:


80
version: "2.1"
services:
    api:
        build: .
        container_name: api
        ports:
            - "8080:8080"
        depends_on:
            db:
                condition: service_healthy
    db:
        container_name: db
        image: mysql
        ports:
            - "3306"
        environment:
            MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
            MYSQL_USER: "user"
            MYSQL_PASSWORD: "password"
            MYSQL_DATABASE: "database"
        healthcheck:
            test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
            timeout: 20s
            retries: 10

ডিবি ধারক সুস্থ না হওয়া পর্যন্ত এপিআই কনটেইনারটি শুরু হবে না (মূলত মাইস্ক্লাডমিন আপ না হওয়া এবং সংযোগগুলি গ্রহণ না করা পর্যন্ত))


12
mysqladmin pingসার্ভার চলমান থাকলেও সংযোগগুলি গ্রহণ না করে যদি একটি মিথ্যা ইতিবাচক ফিরিয়ে দেয়।
হাফপাস্টফোর.কম

53
2017 সালের লোকদের জন্য কেবল এফওয়াইআই: এর conditionঅধীনে depends_on3+ সংস্করণে সমর্থিত নয়
পুদিনা

@ BobKruithof আমি একই সমস্যার মুখোমুখি হয়েছি ... আশেপাশে কোনও কাজ আছে, আবার চেষ্টা করার জন্য ঘুম বা প্রস্থান স্থিতির মতো
মুকেশ আগরওয়াল

4
@dKen নীচের আমার উত্তর দেখার stackoverflow.com/a/45058879/279272 , আশা করি এটা আপনার জন্য আরো কাজ করবে।
মুকেশ আগরওয়াল

4
পাসওয়ার্ড ব্যবহার করে এটি পরীক্ষা করতে: test: ["CMD", 'mysqladmin', 'ping', '-h', 'localhost', '-u', 'root', '-p$$MYSQL_ROOT_PASSWORD' ]- আপনি MYSQL_ROOT_PASSWORDযদি environmentsবিভাগে সংজ্ঞায়িত হন ।
লাইমিসন

22

আপনি Docker-রচনা ব্যবহার করে থাকেন v3 এর + + , conditionএকজন বিকল্প হিসাবে depends_onহয়েছে মুছে

প্রস্তাবিত পথ ব্যবহার করতে বরং হয় wait-for-it, dockerizeঅথবা wait-for। আপনার docker-compose.ymlফাইলে, আপনার আদেশটি হতে হবে:

command: sh -c 'bin/wait-for db:3306 -- bundle exec rails s'

আমি ব্যক্তিগতভাবে পছন্দ করি wait-forযেহেতু এটি আল্পাইন পাত্রে চালিত হতে পারে ( shসামঞ্জস্যপূর্ণ, এর উপর কোনও নির্ভরতা নেই bash)। ত্রুটি এটি নির্ভর করে যে netcatতাই এটি ব্যবহার করার সিদ্ধান্ত নিলে আপনি netcatধারকটিতে ইনস্টল করেছেন কিনা তা নিশ্চিত করুন বা এটি আপনার ডকফাইফিলে ইনস্টল করেছেন, উদাহরণস্বরূপ:

RUN apt-get -q update && apt-get -qy install netcat

আমি প্রকল্পটিও কাঁটাযুক্তwait-for করেছি যাতে এটি স্বাস্থ্যকর HTTP স্থিতি পরীক্ষা করতে পারে (এটি ব্যবহার করে wget)। তারপরে আপনি এর মতো কিছু করতে পারেন:

command: sh -c 'bin/wait-for http://api/ping -- jest test'

PS: প্রকল্পের সেই ক্ষমতা যুক্ত করতে একটি পিআরও সংহত হওয়ার জন্য প্রস্তুতwait-for


13

এটি যথেষ্ট হওয়া উচিত

version: '2.1'
services:
  mysql:
    image: mysql
    ports: ['3306:3306']
    environment:
      MYSQL_USER: myuser
      MYSQL_PASSWORD: mypassword
    healthcheck:
      test: mysqladmin ping -h 127.0.0.1 -u $$MYSQL_USER --password=$$MYSQL_PASSWORD

4
দ্বিগুণ কিসের $জন্য?
ইনসপ

4
@ আইএনএসওপি বিশেষ সিনট্যাক্স আপনাকে এনভির ভেরিয়েবলগুলি থেকে বেরিয়ে আসার জন্য স্বাস্থ্য পরীক্ষা পরীক্ষা কমান্ডটি ব্যবহার করতে হবে with, অর্থাৎ Y এমওয়াইএসকিউএলএপিএসওয়ার্ডের ফলস্বরূপ $ এমওয়াইএসকিউএলএপিএসওয়ার্ড হবে, যা নিজেই এই কংক্রিটের উদাহরণে মাইপাসওয়ার্ডে পরিণত হবে
মাকসিম কোস্ট্রোমিন

সুতরাং এই im কনটেইনার ভিতরে env পরিবর্তনশীল অ্যাক্সেস সঙ্গে? $হোস্ট থেকে এনভ ভেরিয়েবলটি অ্যাক্সেস করা একক ইম দিয়ে আমি অনুমান করি? ধন্যবাদ আপনাকে ধন্যবাদ!
ইনসপ

10

আপনি যদি মাইএসকিএল প্রস্তুত হওয়ার জন্য অপেক্ষা করার জন্য ধারকটি পরিবর্তন করতে পারেন তবে এটি করুন।

আপনি যে ধারকটির সাথে ডাটাবেসটি সংযোগ করতে চান তার যদি নিয়ন্ত্রণ না থাকে তবে আপনি নির্দিষ্ট বন্দরটির জন্য অপেক্ষা করার চেষ্টা করতে পারেন।

সেই উদ্দেশ্যে, আমি অন্য একটি ধারক দ্বারা উদ্ভূত নির্দিষ্ট বন্দরটির জন্য অপেক্ষা করতে একটি ছোট স্ক্রিপ্ট ব্যবহার করছি।

এই উদাহরণে, myserver পোর্টের জন্য অপেক্ষা করবে 3306 এর mydb ধারক পৌঁছানো যাবে।

# Your database
mydb:
  image: mysql
  ports:
    - "3306:3306"
  volumes:
    - yourDataDir:/var/lib/mysql

# Your server
myserver:
  image: myserver
  ports:
    - "....:...."
  entrypoint: ./wait-for-it.sh mydb:3306 -- ./yourEntryPoint.sh

আপনি স্ক্রিপ্ট অপেক্ষার-জন্য-এটা ডকুমেন্টেশন জানতে পারেন এখানে


আমি এর wait-for-it.sh আগে ব্যবহার করার চেষ্টা করেছি কিন্তু এটি ডকফাইফিলকে ডিফল্টর উপরে ফেলে দেয়? এন্ট্রিপয়েন্ট.শ দেখতে কেমন?
জন কারিওকি

এন্ট্রিপয়েন্ট আপনার চিত্রের উপর নির্ভর করে। আপনি ডকার পরিদর্শন <চিত্র আইডি> দিয়ে এটি পরীক্ষা করতে পারেন। পরিষেবাটি উপলব্ধ হওয়ার জন্য এটি অপেক্ষা করা উচিত এবং আপনার এন্ট্রি পয়েন্টটিতে কল করুন।
ননো

ঠিক আছে ? তুমি কি বুঝতে পেরেছো?
ননো

ধারণা তৈরী কর. হ্যাঁ
জন কারিওকি

6
সতর্কতা: মাইএসকিউএল 5.5 (সম্ভবত আরও নতুন সংস্করণগুলি) এখনও শুরু করার সময় প্রতিক্রিয়া জানাতে পারে।
ব্লাইজ করুন

8

ডকার-রচনা v2.1 ব্যবহার করে একটি সাধারণ স্বাস্থ্য পরীক্ষার জন্য হাই , আমি ব্যবহার করেছি:

/usr/bin/mysql --user=root --password=rootpasswd --execute \"SHOW DATABASES;\"

মূলত এটি ব্যবহারকারীর ডাটাবেজে পাসওয়ার্ডের উদাহরণ হিসাবে ব্যবহার করে একটি সাধারণ mysqlকমান্ড চালায় ।SHOW DATABASES;rootrootpasswd

কমান্ডটি সফল হলে ডিবি প্রস্তুত এবং তাই স্বাস্থ্য পরীক্ষার পথ। intervalবিরতিতে এটি পরীক্ষা করে তাই আপনি এটি ব্যবহার করতে পারেন ।

দৃশ্যমানতার জন্য অন্য ক্ষেত্রটি সরিয়ে ফেলা হচ্ছে, এটি আপনার ক্ষেত্রে কেমন দেখাচ্ছে docker-compose.yaml

version: '2.1'

  services:
    db:
      ... # Other db configuration (image, port, volumes, ...)
      healthcheck:
        test: "/usr/bin/mysql --user=root --password=rootpasswd --execute \"SHOW DATABASES;\""
        interval: 2s
        timeout: 20s
        retries: 10

     app:
       ... # Other app configuration
       depends_on:
         db:
         condition: service_healthy

4
সতর্কতা: রচনা ফাইলের "সংস্করণ 3" সহ, "শর্ত" সমর্থন আর উপলভ্য নয়। Docs.docker.com/compose/compose-file/#d depends_on
বার্তোসজেকে

4
আপনি অপেক্ষা- for-it.sh স্ক্রিপ্টের সাথে একসাথে কমান্ড বৈশিষ্ট্যটি ব্যবহার করা উচিত । আমি এটি এইভাবে করছি:command: ["/home/app/jswebservice/wait-for-it.sh", "maria:3306", "--", "node", "webservice.js"]
বার্তোসকেকে

@ বার্টোসকিআই এটি বুঝতে পারে না। আপনি কি দয়া করে বিশদ সহ একটি সম্পূর্ণ উত্তর যুক্ত করতে পারেন? আমি ঠিক একই সমস্যার মুখোমুখি, তবে আমি এটি কাজ করতে পারি না।
থাদেউ আন্তোনিও ফেরেরিরা মেলো 4'19

নিশ্চিত হয়ে নিন যে আপনি v2.1 ব্যবহার করছেন, অন্যথায় v3.0 এবং উপরের জন্য নতুন নির্দেশিকা অনুসরণ করুন।
সিলেরে

4
--execute \"SHOW DATABASES;\"অ্যাপ্লিকেশন অ্যাক্সেস করার জন্য ডাটাবেস উপলব্ধ না হওয়া পর্যন্ত এটি আমার জন্য অপেক্ষা করেছিল
tsuz

6

আমি docker-compose.ymlনিম্নলিখিত উদাহরণ অনুসারে পরিবর্তন করেছি এবং এটি কাজ করে।

  mysql:
    image: mysql:5.6
    ports:
      - "3306:3306"
    volumes:       
      # Preload files for data
      - ../schemaAndSeedData:/docker-entrypoint-initdb.d
    environment:
      MYSQL_ROOT_PASSWORD: rootPass
      MYSQL_DATABASE: DefaultDB
      MYSQL_USER: usr
      MYSQL_PASSWORD: usr
    healthcheck:
      test:  mysql --user=root --password=rootPass -e 'Design your own check script ' LastSchema

আমার ক্ষেত্রে ../schemaAndSeedDataএকাধিক স্কিমা এবং ডেটা সিডিং এসকিউএল ফাইল রয়েছে। Design your own check scriptনিম্নলিখিত অনুরূপ হতে পারে select * from LastSchema.LastDBInsert

ওয়েব নির্ভরশীল ধারক কোড ছিল

depends_on:
  mysql:
    condition: service_healthy

এটি আপনার পক্ষে কাজ করতে পারে তবে এটি সমস্ত মাইএসকিউএল ইঞ্জিনে সমর্থিত কিনা তা আমি নিশ্চিত নই।
হাফপাস্টফোর.কম

আমি ইনোডিবি, মাইআইএসএএম ইত্যাদির মতো ডাটাবেস ইঞ্জিনগুলির বিষয়ে কথা বলছি কি LastSchema.LastDBInsertকোনও মাইএসকিউএল ডিফল্ট বা ডাটাবেস ইঞ্জিন নির্দিষ্ট?
হাফপাস্টফোর.কম

না এটি মাইএসকিএল-তে কোনও ডিফল্ট নয়। এটি ছিল মাত্র একটি নমুনা। একটি ডামি ক্যোয়ারী
মুকেশ আগরওয়াল

4
সতর্কতা: রচনা ফাইলের "সংস্করণ 3" সহ, "শর্ত" সমর্থন আর উপলভ্য নয়। Docs.docker.com/compose/compose-file/#d depends_on
বার্তোসজেকে

4

আমার একই সমস্যা ছিল, আমি এই উদ্দেশ্যে একটি বাহ্যিক বাশ স্ক্রিপ্ট তৈরি করেছি (এটি ম্যাক্সিমাম উত্তর দ্বারা অনুপ্রাণিত)। mysql-container-nameআপনার মাইএসকিউএল ধারকটির নাম এবং পাসওয়ার্ড / ব্যবহারকারীর নাম দ্বারা প্রতিস্থাপন করুন :

বিন / অপেক্ষার জন্য- mysql.sh :

#!/bin/sh
until docker container exec -it mysql-container-name mysqladmin ping -P 3306 -proot | grep "mysqld is alive" ; do
  >&2 echo "MySQL is unavailable - waiting for it... 😴"
  sleep 1
done

আমার মেকফাইলে, আমি আমার কল করার ঠিক পরে এই স্ক্রিপ্টটি docker-composeকল করি:

wait-for-mysql: ## Wait for MySQL to be ready
    bin/wait-for-mysql.sh

run: up wait-for-mysql reload serve ## Start everything...

তারপরে আমি ত্রুটি না করেই অন্যান্য কমান্ডগুলিতে কল করতে পারি:

ড্রাইভারে একটি ব্যতিক্রম ঘটেছিল: এসকিউএলস্টেট [এইচওয়াই 1000] [2006] মাইএসকিউএল সার্ভার চলে গেছে

আউটপুট উদাহরণ:

docker-compose -f docker-compose.yaml up -d
Creating network "strangebuzzcom_default" with the default driver
Creating sb-elasticsearch ... done
Creating sb-redis              ... done
Creating sb-db                 ... done
Creating sb-app                ... done
Creating sb-kibana             ... done
Creating sb-elasticsearch-head ... done
Creating sb-adminer            ... done
bin/wait-for-mysql.sh
MySQL is unavailable - waiting for it... 😴
MySQL is unavailable - waiting for it... 😴
MySQL is unavailable - waiting for it... 😴
MySQL is unavailable - waiting for it... 😴
MySQL is unavailable - waiting for it... 😴
MySQL is unavailable - waiting for it... 😴
MySQL is unavailable - waiting for it... 😴
MySQL is unavailable - waiting for it... 😴
mysqld is alive
php bin/console doctrine:cache:clear-metadata
// Clearing all Metadata cache entries
[OK] Successfully deleted cache entries.

স্বাস্থ্য পরীক্ষাটি এখন এই পদ্ধতির সাথে অকেজো হওয়ায় আমি এটি মুছে ফেলেছি।


3

স্বাস্থ্য চেক পদ্ধতির জন্য একটি আপডেট সমাধান যুক্ত করা। সাধারণ স্নিপেট:

healthcheck:
  test: out=$$(mysqladmin ping -h localhost -P 3306 -u foo --password=bar 2>&1); echo $$out | grep 'mysqld is alive' || { echo $$out; exit 1; }

ব্যাখ্যা : যেহেতু mysqladmin pingমিথ্যা ধনাত্মক grepপ্রত্যাশা (বিশেষত ভুল পাসওয়ার্ডের জন্য), তাই আমি আউটপুটটিকে একটি অস্থায়ী ভেরিয়েবলে সংরক্ষণ করছি, তারপরে প্রত্যাশিত আউটপুট ( mysqld is alive) ব্যবহার করে। যদি এটি পাওয়া যায় তবে এটি 0 টি ত্রুটি কোডটি ফিরিয়ে দেবে। যদি এটি না পাওয়া যায় তবে আমি পুরো বার্তাটি মুদ্রণ করছি এবং 1 টি ত্রুটি কোডটি ফিরিয়ে দিচ্ছি।

প্রসারিত স্নিপেট:

version: "3.8"
services:
  db:
    image: linuxserver/mariadb
    environment:
      - FILE__MYSQL_ROOT_PASSWORD=/run/secrets/mysql_root_password
      - FILE__MYSQL_PASSWORD=/run/secrets/mysql_password
    secrets:
      - mysql_root_password
      - mysql_password
    healthcheck:
      test: out=$$(mysqladmin ping -h localhost -P 3306 -u root --password=$$(cat $${FILE__MYSQL_ROOT_PASSWORD}) 2>&1); echo $$out | grep 'mysqld is alive' || { echo $$out; exit 1; }

secrets:
  mysql_root_password:
    file: ${SECRETSDIR}/mysql_root_password
  mysql_password:
    file: ${SECRETSDIR}/mysql_password

ব্যাখ্যা : আমি এনভির ভেরিয়েবলের পরিবর্তে ডকার সিক্রেট ব্যবহার করছি (তবে এটি নিয়মিত এনভ ভার্সের মাধ্যমেও অর্জন করা যেতে পারে)। এর ব্যবহার $$হ'ল আক্ষরিক $চিহ্নের জন্য যা পাত্রে পাস করার সময় কেটে নেওয়া হয়।

docker inspect --format "{{json .State.Health }}" db | jqবিভিন্ন উপলক্ষে আউটপুট :

সব ঠিক আছে:

{
  "Status": "healthy",
  "FailingStreak": 0,
  "Log": [
    {
    {
      "Start": "2020-07-20T01:03:02.326287492+03:00",
      "End": "2020-07-20T01:03:02.915911035+03:00",
      "ExitCode": 0,
      "Output": "mysqld is alive\n"
    }
  ]
}

ডিবি আপ নেই (এখনও):

{
  "Status": "starting",
  "FailingStreak": 1,
  "Log": [
    {
      "Start": "2020-07-20T01:02:58.816483336+03:00",
      "End": "2020-07-20T01:02:59.401765146+03:00",
      "ExitCode": 1,
      "Output": "\u0007mysqladmin: connect to server at 'localhost' failed error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2 \"No such file or directory\")' Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!\n"
    }
  ]
}

ভুল গুপ্তশব্দ:

{
  "Status": "unhealthy",
  "FailingStreak": 13,
  "Log": [
    {
      "Start": "2020-07-20T00:56:34.303714097+03:00",
      "End": "2020-07-20T00:56:34.845972979+03:00",
      "ExitCode": 1,
      "Output": "\u0007mysqladmin: connect to server at 'localhost' failed error: 'Access denied for user 'root'@'localhost' (using password: YES)'\n"
    }
  ]
}

3

পুনরায় চালু করুন ব্যর্থতা

যেহেতু v3 condition: service_healthyআর উপলভ্য নয়। ধারণাটি হ'ল বিকাশকারীকে অ্যাপের মধ্যেই ক্র্যাশ পুনরুদ্ধারের জন্য প্রক্রিয়া প্রয়োগ করতে হবে। তবে সাধারণ ব্যবহারের ক্ষেত্রে এই সমস্যাটি সমাধান করার একটি সহজ উপায় হ'ল restartবিকল্পটি ব্যবহার করা ।

যদি মাইএসকিএল পরিষেবার স্থিতি আপনার অ্যাপ্লিকেশনটির কারণ হয়ে থাকে exited with code 1আপনি restartউপলব্ধ নীতি বিকল্পগুলির একটি ব্যবহার করতে পারেন । যেমন,on-failure

version: "3"

services:

    app:
      ...
      depends_on:
        - db:
      restart: on-failure
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.