faketimeを使用してdocker内の時間を変更し、date:cannot set date:Operation not permittedの問題を解決します.

5583 ワード

dockerは本質的にプロセスであり、システム時間などのホストを使用するリソースがたくさんあります.普通に使うと便利だと思いますが、システムリソースの修正にかかわると、面倒になります.
シーン
dockerを使用してバックエンド・サービスを導入し、システム変更時間をテストする必要があります.ホスト時間を直接変更すると、他のdockerに影響します(ホスト上で変更しても–cap-add SYS_TIMEパラメータを使用してdockerで変更しても).テスト要件を満たし、他のdockerに影響を与えない方法はありませんか?答えはfaketimeを通じてdockerをだまして、この目的を達成することです.
faketime
githubアドレス
https://github.com/wolfcw/libfaketime
インストール
git clone https://github.com/wolfcw/libfaketime
cd libfaketime
make
make install

インストールが完了したら、/usr/local/lib/の下にkaketimeのディレクトリがあります.
使用
例えば、2019-08-12 10:30:22に変更したい場合は、次のコマンドを実行します.
export LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="2019-08-12 10:30:22" 

docker実践
dockerfile
まずUbuntuベースミラーで作られたlaravel用のdockerfileを見てみましょう
FROM ubuntu:16.04

#     
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY php-7.3.0.tar.bz2 php-7.3.0.tar.bz2

#    ,  nginx
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list \
    && sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list \
    && apt-get clean \
    && rm -fR /var/lib/apt/lists/* \
    && mkdir /var/lib/apt/lists/partial \
    && apt-get update  \
    && apt-get upgrade -y \
    && apt-get install -y wget autoconf make gcc nginx procps libfreetype6-dev libpng-dev libzip-dev libcurl3-openssl-dev libbz2-dev libjpeg-dev libxpm-dev libfreetype6-dev libmcrypt-dev libmysql++-dev libxslt1-dev  pkg-config libssl-dev libsslcommon2-dev zip unzip \
    && tar xvf php-7.3.0.tar.bz2 \
    && cd php-7.3.0/ \
    && ./configure  --prefix=/usr/local/php --enable-fpm --enable-sockets --enable-mbstring=all  -enable-mysqlnd  --with-config-file-path=/usr/local/php/etc --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-curl --with-gd  --with-openssl \
    && make \
    && make install \
    && cd ext/zip \
    && /usr/local/php/bin/phpize \
    && ./configure --with-php-config=/usr/local/php/bin/php-config \
    && make ; make install \
    && cd ../../ext/bcmath \
    && /usr/local/php/bin/phpize \
    && ./configure --with-php-config=/usr/local/php/bin/php-config \
    && make ; make install \
    && cd ../../.. ; rm -fr php-7.3.0 ; rm -fr php-7.3.0.tar.bz2 

#    Composer
ENV COMPOSER_HOME /root/composer
COPY composer /usr/bin/composer
COPY composer /usr/local/bin/composer
RUN cp /usr/local/php/bin/php /usr/bin && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

#        
WORKDIR /data
COPY app/ /data/
COPY php.ini /usr/local/etc/php/php.ini
COPY libfaketime/ /data/
RUN echo 'extension=zip.so' >> /usr/local/php/etc/php.ini \
    && echo 'extension=bcmath.so' >> /usr/local/php/etc/php.ini \
    && cd /data/libfaketime && make ; make install \
    && rm -fr /data/libfaketime
COPY php-fpm.conf /usr/local/php/etc/php-fpm.conf
COPY nginx.conf /etc/nginx/nginx.conf
COPY env-example /data/.env

# Write Permission
RUN chmod -R 777 /data && usermod -u 1000 www-data
CMD ["nginx", "-g", "daemon off;"]

説明
  • dockerfileの概要は、基本ツールのインストールと依存性です.コンパイルインストールphp;composer、faketimeをdockerにコピーし、faktimeをコンパイルしてインストールします.プロジェクトコード、nginx構成、php構成をdockerにコピーします.nginxを使用してフロントプロセスでdockerを起動します.
  • PHPではなくUbuntuでdockerベースミラーリングを行う理由は、修正時間をテストするときにphp-fpmを再起動し、PHPのdockerを直接使用するとphp-fpmを再起動するとdockerが再起動し、faketime修正は無効になるためです.
  • dockerでphp-7.3.0.tar.bz 2、composerとfaketimeをダウンロードし、ネットワークが悪いと時間が長くなります.これをダウンロードしてからdockerにコピーしてパッケージ化し、時間を節約します.nginx,php-fpmの構成も事前に準備しておきます.
  • コンパイルインストールphpのため、時間が少し長くなります
  • 使用
    まずこのdockerfileを使ってパッケージを作ります
    docker build -t laravel:v1 .
    

    打ち終わってから運転する
    docker run -itd  -p 9091:80 laravel:v1
    
    docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
    d5fcc8f42bd4        laravel:v1          "nginx -g 'daemon of…"   37 seconds ago      Up 35 seconds       0.0.0.0:9091->80/tcp   trusting_darwin
    

    ドックに入る
    docker exec -it d5fcc8f42bd4 /bin/bash
    root@d5fcc8f42bd4:/data# 
    

    変更日時
    root@d5fcc8f42bd4:/data# date
    Sun Aug 25 15:24:40 Asia 2019
    root@d5fcc8f42bd4:/data# 
    root@d5fcc8f42bd4:/data# export LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="2019-08-12 10:30:22" 
    root@d5fcc8f42bd4:/data# date
    Mon Aug 12 10:30:22 Asia 2019
    

    現在の端末の時間が変更されていることがわかります.現在の端末のphpの時間も変更されたかどうかを見てみましょう.
    root@d5fcc8f42bd4:/data# echo " time.php
    root@d5fcc8f42bd4:/data# echo 'echo "
    ";' >> time.php root@d5fcc8f42bd4:/data# date Mon Aug 12 10:30:22 Asia 2019 root@d5fcc8f42bd4:/data# php time.php 2019-08-12 10:30:22

    修正も見られます.php-fpmの時間を変更します
    pkill php-fpm ; /usr/local/php/sbin/php-fpm 
    

    アクセスhttp://127.0.0.1:9091/time.php を選択すると、現在の運転時間も変更されていることがわかります.しかし、現在php-fpmをテストする有効時間は比較的短く、10秒程度しかありません.その後、元に戻ります.その後、原因を探して改善しています.----------php-fpm時間復元問題の更新php-fpmモードでは、プロファイルにパラメータclear_を追加できます.Env=no、php-fpmを起動すると環境変数が空にならず、変更時間が有効になります.CLIまたはswooleモードではこの問題はなく、時間を変更して再起動すればよい.