netcat을 사용하지 않고 oneliner 명령을 사용하여 쉘에서 연결을 어떻게 확인할 수 있습니까?

netcat을 사용하지 않고 oneliner 명령을 사용하여 쉘에서 연결을 어떻게 확인할 수 있습니까?

Docker 이미지에서는 진입점 스크립트에서 데이터베이스 연결을 핑하기 위해 netcat을 설치하지 않으려고 합니다.

/bin/sh

MOODLE_DB_HOST="xxxx"
MOODLE_DB_PORT=80

function pingdb {
    OK=0
    for count in {1..100}; do
      echo "Pinging database attempt ${count} into ${MOODLE_DB_HOST}:${MOODLE_DB_PORT}" 
      if  $(nc -z ${MOODLE_DB_HOST} ${MOODLE_DB_PORT}) ; then
        echo "Can connect into database"
        OK=1
        break
      fi
      sleep 5
    done

    echo "Is ok? "$OK

    if [ $OK -eq 1 ]; then
      echo "Database type: "${MOODLE_DB_TYPE}
      echo "DB Type: "${MOODLE_DB_TYPE}
    else
      echo >&2 "Can't connect into database"
      exit 1
    fi
}

nc하지만 대신에 도커 이미지에서 실행되는 진입점 스크립트 대신 PHP를 사용하고 싶습니다 .

다른 옵션이 있나요?

내가 이 작업을 수행하려는 이유는 Debian 기반과 Alpine 기반의 Dockerfile이 2개 있기 때문입니다.

Debian 기반 PHP 이미지:

ARG PHP_VERSION="7.4"
FROM  php:${PHP_VERSION}-fpm as base

RUN --mount=type=bind,from=mlocati/php-extension-installer:latest,source=/usr/bin/install-php-extensions,target=/usr/local/bin/install-php-extensions \
    /usr/local/bin/install-php-extensions xmlrpc mbstring zip xml intl soap gd opcache &&\
    echo "PHP_EXTENTION_DIR="$(php -i | grep extension_dir  | cut -d " " -f 5) >> /etc/environment &&\
    cat /etc/environment &&\
    apt-get update &&\
    apt-get install -y netcat &&\
    apt-get autopurge -y &&\
    apt-get autoremove -y &&\
    apt-get autoclean &&\
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* cache/* /var/lib/log/* &&\
    echo "max_input_vars=5000" > ${PHP_INI_DIR}/conf.d/moodle.ini

COPY ./scripts/entrypoint.sh /usr/local/bin/entrypoint.sh

RUN chown root:root /usr/local/bin/entrypoint.sh &&\
    chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT ["/bin/sh","/usr/local/bin/entrypoint.sh"]
CMD ["php-fpm"]

산 기준:


ARG PHP_VERSION="7.4"
FROM  php:${PHP_VERSION}-fpm-alpine as base

RUN --mount=type=bind,from=mlocati/php-extension-installer:latest,source=/usr/bin/install-php-extensions,target=/usr/local/bin/install-php-extensions \
    /usr/local/bin/install-php-extensions xmlrpc mbstring zip xml intl soap gd opcache &&\
    apk update &&\
    apk add netcat-openbsd &&\
     rm -rf /var/cache/apk/* /var/tmp/* cache/* /var/lib/log/* &&\
    echo "max_input_vars=5000" > ${PHP_INI_DIR}/conf.d/moodle.ini

COPY ./scripts/entrypoint.sh /usr/local/bin/entrypoint.sh

RUN chown root:root /usr/local/bin/entrypoint.sh &&\
    chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT ["/bin/sh","/usr/local/bin/entrypoint.sh"]
CMD ["php-fpm"]

때로는 매개변수에 따라 PHP_VERSIONnetcat 설치용 패키지가 존재하거나 존재하지 않을 수도 있습니다(또는 다른 이름으로 존재할 수도 있습니다). 또한 빌드 시간 apk addapt-get크게 늘어납니다.

그럼 대안이 있나요?

답변1

바로 여기에:

function pingdb {
    OK=0
    for i in $(seq 1 100); do
      echo "Pinging database attempt ${count} into ${MOODLE_DB_HOST}:${MOODLE_DB_PORT}" 
      if  $(php -r "is_resource(@fsockopen(\"${MOODLE_DB_HOST}\",intval(\"${MOODLE_DB_PORT}\")))?exit(0):exit(1);") ; then
        echo "Can connect into database"
        OK=1
        break
      fi
      sleep 5
    done


    if [ $OK -eq 1 ]; then
      echo "Database type: "${MOODLE_DB_TYPE}
      echo "DB Type: "${MOODLE_DB_TYPE}
    else
      echo >&2 "Can't connect into database"
      exit 1
    fi
}

보시다시피 nc다음이 대체됩니다.

php -r "is_resource(@fsockopen(\"${MOODLE_DB_HOST}\",intval(\"${MOODLE_DB_PORT}\")))?exit(0):exit(1);"

2개의 매개변수가 필요합니다 fsockopen.

  • host
  • port

내가 하는 일은 PHP에서 소켓을 열고 소켓이 열려 있는지 확인하는 것입니다. 그렇다면 0상태 코드로 종료하고, 그렇지 않으면 로 종료합니다 1. 각 매개변수는 쉘 스크립트의 문자열을 사용하여 전달되므로 값을 PHP 문자열로 변환하기 위해 "문자를 사용하여 인코딩합니다 .\

vars를 사용하지 않고도 다음을 수행할 수 있습니다.

php -r "is_resource(@fsockopen(\"google.com",80)))?exit(0):exit(1);"

하지만 안전을 위해 bash 매개변수를 사용하는 버전의 intval을 사용했습니다.

관련 정보