Linux」カテゴリーアーカイブ

VPS を再構築した話

VPS の OS が古くなってしまったので作り直した。

作りこんでいたサービスのほとんどはもはや使っていなかったので、とりあえずこの wordpress だけを持ってきた。
次回以降のことを考えて、docker で構築。

はじめに

外部 ↔ フロントエンドコンテナ(nginx) ↔ WordPress コンテナ群(nginx, php-fpm, mysql)という構成。
これだと、サーバ内にリバースプロキシが二つもあって無駄な処理をすることになるが、管理しやすさを考えてこうしてみた。問題があれば変更しよう。

コンテナ間通信ネットワークの作成

まずはコンテナ間通信のためのネットワークを作成し、

$ sudo docker network create --driver bridge shared

WordPress 用コンテナ群の作成

WordPress を提供するためのコンテナ群を作成。
これは nginx + php-fpm で動くようにした。
WordPress をサブディレクトリで動かすために working_dir: を設定するのだが、これに気が付くのに時間を費やした。

version: '3.1'

services:

  rproxy:
    container_name: wp-rproxy
    build:
      context: ./mynginx
      dockerfile: Dockerfile
    restart: always
    volumes:
      - ./wordpress:/var/www/html/blog
      - ./nginx-log:/var/log/nginx
    depends_on:
      - wordpress

  wordpress:
    image: wordpress:6.4.2-php8.3-fpm-alpine
    restart: always
    working_dir: /var/www/html/blog
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wp
      WORDPRESS_DB_PASSWORD: mywordpress
      WORDPRESS_DB_NAME: wp
    volumes:
      - ./wordpress:/var/www/html/blog
      - ./wordpress-log:/var/log
    depends_on:
      - db

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: wp
      MYSQL_USER: wp
      MYSQL_PASSWORD: ***
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - ./db:/var/lib/mysql
      - ./db-log:/var/log

この mynginx は以下の Dockerfile で作成。

FROM nginx:alpine


COPY <<EOF /etc/nginx/conf.d/default.conf
server {
    listen 80;
    server_name localhost;

    root /var/www/html;
    index index.php;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location /blog/ {
        try_files \$uri \$uri/ /index.php?\$args;
    }

    location ~ \.php\$ {
        include fastcgi_params;
        fastcgi_pass wordpress:9000;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        fastcgi_param PATH_INFO \$fastcgi_path_info;
    }
}
EOF

フロントエンドコンテナの作成

今後別のサービスを動かしたくなるかもしれないので、wordpress を提供しているコンテナ群とは独立に一つ nginx を立ててフロントエンドにする。
これは基本的には / にあるファイルの提供と、サブディレクトリに配置したサービスへのリバースプロキシにする。
なので、サービスを追加した際にはこのコンテナ(の default.conf)を適宜更新する。

version: '3.1'

services:

  rproxy:
    container_name: rfront
    build:
      context: ./mynginx
      dockerfile: Dockerfile
    ports:
      - 80:80
    restart: always
    volumes:
      - ./html:/var/www/html
      - ./nginx-log:/var/log/nginx

networks:
  default:
    external:
      name: shared

この mynginx は以下の Dockerfile で作ります。

FROM nginx:alpine

COPY <<EOF /etc/nginx/nginx.conf
user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '\$remote_addr - \$remote_user [\$time_local] "\$request" '
                      '\$status \$body_bytes_sent "\$http_referer" '
                      '"\$http_user_agent" "\$http_x_forwarded_for"';

    log_format upstreamlog '[\$time_local] \$remote_addr \$host \$upstream_addr '
                           '\$upstream_cache_status \$upstream_status '
                           '\$upstream_http_location \$request';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
EOF

COPY <<EOF /etc/nginx/conf.d/default.conf
server {
    listen 80;
    server_name www8281uo.sakura.ne.jp;

    root /var/www/html;
    index index.html index.htm;

    access_log /var/log/nginx/access.log main;
    access_log /var/log/nginx/upstream.log upstreamlog;
    error_log /var/log/nginx/error.log;

    location /blog/ {
        index index.php;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-Host \$host;
        proxy_set_header X-Forwarded-Server \$host;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_pass http://wp-rproxy:80/blog/;
        proxy_redirect default;
    }
}
EOF

おわりに

WordPress くらい有名なサービスだとたくさん情報があるので調べればすぐにいろいろ出てくる。
Docker を使うことで、php-fpm を使った高速なサイト構築が簡単に出来るというのはすごいことだ。

Docker コンテナでホストと同じユーザ・グループを利用する方法

/etc/passwd, /etc/group. /etc/shadow でユーザとグループを管理している場合の話。
忘れそうだったのでメモ。

今回、JupyterHub の構築をしていて、docker イメージ使うと簡単そうだったので利用したのだけど、ホストのユーザが JupyterHub を使えるようにしたかったので、いろいろ試行錯誤した。

結論としては以下のようにするのがよさそう。

  • ユーザ管理(追加、削除など)はホスト側で行う
  • Docker コンテナはホストの /etc/{passwd,group,shadow} を Read-Only で参照
    docker run -v src:dst:ro を使う
  • ユーザ管理コマンドで /etc/{passwd,group,shadow} の i-node が変わっても良いようにする
    → ディレクトリ単位でバインドする、ただし、Docker コンテナの /etc をホストの /etc で上書きしてしまうのは困るので、どちらの内容が見えるかはファイルごとに制御したい

そのために、

  • /import/etc/ を作成する
  • イメージにもともとある /etc/{passwd,group,shadow}/import/etc/ に移動する
  • cd /etc; ln -s /import/etc/{passwd,group,shadow} してシンボリックリンクする
  • docker run -v /etc:/import/etc:ro -v /home:/home としてディレクトリごとマウントする

多分、これでOK。

Petalinux v2018.3 をインストールするときのメモ

  • Ubuntu の場合は 16.04
  • sudo apt-get install -y gcc git make net-tools libncurses5-dev tftpd zlib1g-dev libssl-dev flex bison libselinux1 gnupg wget diffstat chrpath socat xterm autoconf libtool tar unzip texinfo zlib1g-dev gcc-multilib build-essential libsdl1.2-dev libglib2.0-dev zlib1g:i386 screen pax gzip
  • 上記だけではダメで、sudo apt-get install gawk が必要

KCU1500 環境のセットアップ方法のメモ

KCU1500 は近々 discon になると思うので今更書き残しておく意味があるかよくわからないが・・・。

  • Ubuntu を使う場合は 16.04 LTS を使う。
    • KCU1500 用のドライバが対応した Linux カーネルを動かせるのが 16.04 LTS までだから。
    • 最新の PC を使おうとすると、Ethernet ドライバがなくてはじめインターネットにつながらないかもしれない。その場合は手動でドライバをインストールする必要がある。
  • HWE には対応していないので、4.4 系のカーネルにする。
    • KCU1500 用のドライバが対応した Linux カーネルのバージョン制約
  • SDAccel は 2018.2 をインストールする

この組み合わせじゃないといけないことに気づくまでに結構試行錯誤が必要だった。

ここまでできると、あとはインストラクション通りにドライバをインストールできる。ドライバが入ると KCU1500 のファン制御が有効になって静かになる。

PYNQ ならではなスタートアッププログラムを止める方法

PYNQ  はスタートアップ時に Jupyter Notebook が起動するように設定されている。

それを止めるためには、以下のサービスを systemctl を使って止めればよい。

  • pl_server
  • pynq-x11
  • jupyter

グラフィカルなログインを止めるには、

$ sudo systemctl set-default multi-user.target

Ultra96v2 で PYNQ イメージを動かす

Ultra96v2 で PYNQ の Linux イメージを動かすまでのメモ。

WiFi のアクセスポイントに接続するようにあらかじめ設定を変更しておく。

手順

  1. PYNQ イメージをダウンロード
  2. イメージを microSD に書き込み
  3. WiFi 接続設定
  4. 起動確認

1.PYNQ イメージをダウンロード

http://avnet.me/ultra96-pynq-image-v2.4_v2 からダウンロードする。
結構時間かかる上に、チェックサムが公開されていないのでデータが壊れていないか確認できない。

2.イメージを microSD に書き込み

SD カードが /dev/sdb だったとして、

# dd bs=4M if=/path/to/ultra96v2_v2.4.img of=/dev/sdb

とする。RootFS のパーティションが小さいので、SDカードの容量に余裕があれば、パーティションを拡張後、resize2fs してファイルシステムの容量を拡張しておくとよい。

3.WiFi 接続設定

確認したところ、 Ubuntu 18.04 ベースなので、本来なら、network-manager をインストールして netplan を使って WiFi 接続設定するのだけど、インストールされていないので、別の方法で設定する。

まず、SDカードの第2パーティションを /path/to/mountpoint にマウントする。

/path/to/mountpoint/etc/wpa_supplicant.conf 作成

country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="<SSID名>"
    psk="<パスフレーズ>"
}

(パスフレーズを平文で書きたくない人は別途調べるとやり方が出てくる。)

/path/to/mountpoint/etc/network/interfaces.d/wlan0 編集、wlan0 が自動で UP されるよう以下の内容にする

auto wlan0
iface wlan0 inet dhcp
    wireless_mode managed
    wireless_essid any
    wpa-driver wext
    wpa-conf /etc/wpa_supplicant.conf

4.起動確認

電源と、microSD、micro-USB ケーブルを接続する。

PYNQ サイトには、micro-USB ケーブルで接続すると Ethernet デバイスが認識されて、192.168.3.1 でアクセスできると書いてあるがこれはどうもうまくいかなかった。

その代わり、シリアルデバイスとしては認識されてターミナルソフトからアクセスできる。

$ ip a して wlan0 が接続できていればOK。

http://<wlan0 の IP アドレス> にブラウザでアクセスすれば Jupyter Notebook の画面が見られるはず。ちなみにパスワードは xilinx

また、この IP アドレスに SSH でもアクセスできるはず。ユーザとパスワードはともに xilinx

参考サイト

  • PYNQ 公式サイト:http://www.pynq.io/board.html
  • ドキュメント:https://ultra96-pynq.readthedocs.io/en/latest/getting_started.html#opening-a-usb-serial-terminal

mdadm + LVM の RAID1 をディスク交換して容量を増やす

概要

3 TB HDD × 2 で構築していた RAID1 を 8 TB HDD × 2 に交換した記録。

前提と作業内容

今回は、/dev/sdb1 と /dev/sdc1 の2パーティションで RAID1 (/dev/md0) を構成している前提。
ファイルシステムは XFS を使用。

手順としては、RAID 再構築 → RAID 拡張 → LVM 拡張 → ファイルシステム拡張の4ステップ。

8 TB のドライブの使い方として、 3 TB + 5 TB に分けて2つの RAID1 を作成して LVM でまとめることもできるけど、今回は 8 TB の大きなアレイを作成することにした。

手順

1.ディスク交換

1-1.1本目のディスクを故障状態にして RAID から外す

# mdadm /dev/md0 --fail /dev/sdb1
# mdadm /dev/md0 --remove /dev/sdb1
# shutdown -h now

1-2.物理的に1本目のディスクを交換

1-3.1本目のディスクのパーティション作成

今回は 8TB 全体を使う1のパーティション (/dev/sdb1) を作った。
パーティションのタイプは Linux RAID (29) を指定する。

# fdisk /dev/sdb

1-4.1本目の同期

3 TB 領域を同期する。大体5時間かかった。

# mdadm /dev/md0 --add /dev/sdb1

1-5.2本目のディスクを故障状態にして RAID から外す

# mdadm /dev/md0 --fail /dev/sdc1
# mdadm /dev/md0 --remove /dev/sdc1
# shutdown -h now

1-6.物理的に2本目のディスクを交換

1-7.2本目のディスクのパーティション作成

# fdisk /dev/sdc

1-8.2本目の同期

# mdadm /dev/md0 --add /dev/sdc1

2.RAID 領域の拡張

このままだと前の容量の 3 TB しか使えないので、RAID 領域を拡張する。
残りの 5 TB 分の同期に8時間ほどかかった。
RAID1 なので、 --assume-clean しても良かったと思うけど、今回は同期しておいた。

# mdadm --grow /dev/md0 -z max

3.LVM の拡張

Physical Volume の拡張

# pvresize /dev/md0

LV に設定する PE 数の確認(Total PE)

# pvdisplay

LV の拡張

# lvextend -l [PE数] [LV path]

4.ファイルシステムの拡張

# xfs_growfs [マウントポイント]

論文執筆を GitHub + 継続的インテグレーションで環境レス化する

概要

LaTeX での論文を Git で管理し、GitHub と継続的インテグレーション (CI) ツール を使って論文を pdf 化し、GitHub の Release ページから見られるようにすることで論文執筆を効率化する話(ただし、論文執筆速度が速くなっているかは別の話)。

これが実現したらもはや手元の環境には LaTeX 処理系はなくても論文執筆が可能なので、タイトルに「環境レス化」を入れた。手元に全く環境を持たないのは難しいとしても、複数の LaTeX 処理系を使い分けたりは格段にしやすくなる。

GitHub を使った論文執筆

論文を Git リポジトリで管理して、GitHub を用いて共著者間で共有している。主な活用法としては以下のような感じ。

  • 研究テーマ単位でリポジトリを作る。論文は papers/xxx みたいにディレクトリを掘って配置
  • Issue 機能を使って執筆上の課題を明確化し、共著者間の議論の場を作る
  • 議論に対応したコミットを Issue に結び付けることで議論が論文にどう反映されたか明確化
  • 査読対応にも Issue 機能を活用

動機

ところが、共著者の中には論文を読んでチェックできればいい、という人がいる。そういう人にとっては、わざわざ論文 pull してコンパイルする作業が面倒だったりする。.latexmkrc を書いて latexmk main するだけにしても「pdf ファイルをメールで送ってください」となるのがオチだった。

ならば、GitHub に push したら CI で自動 pdf 化できるようにしたらいいのかな、と思ってやってみた。幸い、参考になるサイト(下記)があったので、大いに参考にした。

前提

  • LaTeX 文書のコンパイルには TeXLive 環境を使う。
  • LaTeX 文書のコンパイル支援には latexmk を使用、コンパイル手順は .latexmkrc に記述し、リポジトリに含む
  • 論文のコンパイル対象は main.tex とする。
  • 一つのリポジトリに複数の論文が含まれる。papers/xxx など、ディレクトリを掘って格納する
  • CI ツールには CircleCI を使用。論文のコンパイル(pdf化)を行う。どのディレクトリをコンパイルするかは CircleCI の設定で決定

現在のところ、CircleCI は無料で月間 1000 分ジョブを実行できる。LaTeX 文書の量によるが一度に必要な時間は2分程度。したがって、CircleCI を他の用途に使っていなければ月に 500 回くらいは論文をコンパイルできる計算になる。個人的な感覚としては十分な計算時間が利用できると思う。

目標とする動作

以下のような動作を目指す。特に、自動で pdf 化された論文が Release ページに登録されるのは使い勝手が良いと思う。これができるようになれば、手元の LaTeX 環境をセットアップしなくてもクラウド論文執筆が可能。(ただし、変更をリポジトリに push してからコンパイル結果が出力されるまでに2分かかる、ほとんどは Docker 環境の立ち上げに要する時間。)

  • GitHub に論文の更新を push したときにコンパイルが通るかチェック
  • GitHub に X.X.X 形式で tag を設定または更新したときに pdf ファイルを GitHub の Release としてアップロード

CircleCI の設定

今回は、CircleCI 2.0 を使う。必要な手順は以下の3つ。

GitHub リポジトリへの CircleCI 用設定ファイルの配置

CircleCI 2.0 では、.circleci/config.yml に YAML 形式の設定を記述する。以下の例は、 build, publish-github-release の2つのジョブからなっている。また、tag に応じた処理を行うために main ワークフローを設定している。このテストは teruo41/latex-circleci-test に置いてある。

[prism field=”circleci-latex-config” language=”YAML”]

build ジョブ内で papers/${TARGET_DIR} ディレクトリに移動して latexmk main を実行する。TeXLive を利用するための Docker イメージは Docker Hub の teruo41/ubuntu-texlive:latest を利用。Docker イメージについては後述。

publish-github-release ジョブはコンパイルした pdf ファイルを GitHub の Release ページに登録するためのジョブ。これには、cibuilds/github:0.10 の Docker イメージを利用。
複数のジョブ間で実行結果を受け渡すには、先行ジョブ(ここでは build)で persistent_to_workspace を指定する必要があり、後続ジョブ(ここでは publish-github-release)で attach_workspace を指定する必要がある。

main ワークフローは、X.X.X 形式のタグが GitHub 上で更新されたときに buildpublish-github-release ジョブを実行する。これにより、tag に対応した pdf ファイルが GitHub の Release ページにアップロードされる。

Circle CI 用 Docker イメージの準備

動かせればよい人は、teruo41/ubuntu-texlive:latest の使用を推奨。これは、Ubuntu リポジトリに登録されている TeXLive をインストール済みの Docker イメージ。Ubuntu がサポートしているバージョンのそれぞれについてイメージを作る(予定)。

自前で環境を作りたい人は、Dockerfile を作って手元で docker build して Docker hub に push するか、GitHub か BitBucket に Dockerfile を格納したリポジトリを作って、Docker hub 上で Automated build するかどちらかで作ることができる。ちなみに、この例で使っているイメージは Automated build で作成している。それに使用している GitHub リポジトリは teruo41/ubuntu-texlive

Circle CI 上での設定

以下の設定をする必要がある。

  • Circle CI のアカウントを作成して GitHub アカウントに接続する
  • Circle CI の環境変数を設定する。例の .circleci/config.yml で必要な変数は、 GITHUB_TOKENTARGET_DIR の2つ。

GITHUB_TOKEN は GitHub の Personal Access Token を設定する。リポジトリの Release ページに書き込むためには GitHub から適切な権限設定が必要。Public リポジトリか Private リポジトリかで必要な権限が変わる。詳しくはここを参照。

TARGET_DIR はコンパイルする論文のディレクトリを設定。papers/${TARGET_DIR} ディレクトリに移動した後 latexmk main が実行される。

テスト

ここまで設定したら使える状態のはず。論文のリポジトリを更新して push したらコンパイル可否がコミットページに表示される。また、tag を設定して push すれば、コンパイル結果の pdf ファイルが GitHub の Release ページに追加される。

tag を設定して GitHub に push する git コマンドの例。branch と同様に tag も push できる。

$ git tag -a 0.0.1 -m "Created tag 0.0.0"
$ git push origin 0.0.1

一度設定した tag を更新するためには、-f オプションを使えばOK。

$ git tag -af 0.0.1 -m "Updated tag 0.0.0"
$ git push -f origin 0.0.1

参考

HP ProLiant MicroServer gen7 Remote Access Card の KVM に Java SE 8 からつなぐ

少し前から接続できなくなって困っていたけど、今日解決方法を発見した。

733 不明なデバイスさん2018/05/05(土) 21:07:06.67ID:7Er95jKL >>734
>>729
jre1.8.0_171\lib\security\java.securityのjdk.tls.disabledAlgorithmsから3DES_EDE_CBCを削除したらつながったよ。
力技だけど…

https://mevius.5ch.net/test/read.cgi/hard/1468533309/733

試したところ、見事解決した。

tmux に接続し直した時に ssh-agent につなぎ直す方法

調べると色々出ては来るけど、環境変数 SSH_AUTH_SOCK の中身を有効な内容に上書きすれば OK。

自分の .bashrc には以下のように記述した。

[prism field=”bashrc-ssh-agent” language=”bash”]

ポイントは以下。

  • $SSH_CONNECTION の中身を見て、 SSH 接続されたシェルかどうかをチェック。
    • $SSH_CONNECTION が空の場合、クライアントであるとみなして、ssh-agent を起動する。
      • 起動時に、PID 等の設定をファイルにリダイレクトして、シェルを複数起動した場合に一つの ssh-agent を共有可能にする。
      • ssh-agent 起動後、$HOME/.ssh/ 内の鍵を ssh-add して追加する。
    • $SSH_CONNECTION が空でない場合、サーバであるとみなして、ssh-agent をシェルから利用できるようにする。
      • $SSH_AUTH_SOCK の値自体は固定したいので、$HOME/.ssh/agent としておき、実体へのシンボリックリンクとする。
      • こうしておくと、tmux に対して別の SSH セッションで接続し直した場合でも、$SSH_AUTH_SOCK の参照先を差し替えることができ、ssh agent を利用することが可能。