20200928のLinuxに関する記事は7件です。

プロセスとジョブの違い

プロセスとは?

  • Linuxカーネルから見た処理の単位をプロセスと呼ぶ。

  • プロセスはシステム全体で一意の「プロセスID」を持つ。

ジョブとは?

  • シェルから見た処理の単位をジョブと呼ぶ。

  • ジョブはシェルごとに「ジョブ番号」を持つ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

フリーランスとしてアリババクラウドにWebアプリケーションを導入する方法

この記事を通して、私がクラウド上にWebアプリケーションをデプロイする際に使用しているベストプラクティスを共有したいと思います。

本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。

この記事はMedium Blogging Platformでも公開されています。

この記事では、私がウェブアプリケーションをクラウド上にデプロイする際に使用しているベストプラクティスを共有したいと思います。私はフリーランスとして働いていますが、最近、クライアントの一人から小さな組織のためにSuiteCRMのセットアップを依頼されました。私はAlibaba Cloudのチュートリアルを頻繁に書いているので、クライアントには同じクラウドプラットフォームを使うことを勧めました。100人近いユーザーと30人以上の同時使用ユーザーに対して、私が推奨した構成は以下の通りです。

1、PHP-FPMでNginxをインストールするためのvCPU2台、RAM4GBのECSインスタンス。
2、MySQL用のRDSインスタンスにApsaraDB for RDS、コア1GB、RAM1GB、ストレージ10GB。
3、メール送信用のDirect Mail。

私が行った手順は非常にシンプルで、ほぼ全てのPHPベースのアプリケーションに採用することができます。

初めてAlibaba Cloudを利用する方は、こちらのリンクからAlibaba Cloudにサインアップしてください。300米ドル相当の新規ユーザークレジットを無料で取得することができ、これを使って様々なAlibaba Cloud製品を試すことができます。

ECSインスタンスの作成

Alibaba Cloudでは、クラウドプラットフォームの利用を開始するために必要なほぼすべての情報を文書化しています。Alibaba Cloudの利用開始方法については、Getting Started TutorialsTech Share Blogを利用することができます。最もわかりやすい手順はクイックスタートガイドに記載されており、ECSインスタンスを作成する際に使用するベストプラクティスを説明します。

Alibaba Cloudコンソールにログインし、Elastic Compute Serviceインターフェースに移動します。Create Instanceボタンをクリックすると、簡単にインスタンスを作成することができます。注意すべき点は以下の通りです。

1、リージョン:アリババクラウドは世界中にデータセンターを持っているので、アプリケーションのユーザーに地理的に近い地域を常に選択してください。データセンターがユーザーの近くにあると、ネットワークの遅延が少ないため、ウェブサイトの読み込みが非常に速くなります。私の場合、組織がムンバイに拠点を置いていたので、ムンバイ地域を選択しました。
2、課金方法:インスタンスを24時間365日継続的に運用する場合は、月額課金を選択すると、従量課金に比べて価格が半分以下になるため、常に月額課金を選択する必要があります。例えば、2つのvCPUと4GB RAMの共有タイプのECSインスタンスの月額サブスクリプションコストは23ドルですが、同じインスタンスをPay-As-You-Goで利用した場合、1時間あたりのコストは0.103ドルとなります。月間コストは、$0.103*24*30 = $74.16 USDになります。

3、インスタンスタイプ:要件に応じてインスタンスタイプを選択します。必要に応じて後からリソースを増やすことができます。
4、イメージ:ECS インスタンスにインストールしたいアプリケーションを Marketplace イメージで見つけることができますが、常にクリーンな公式イメージで自分でインストールすることをお勧めします。後でアプリケーションにエラーが発生した場合、どこを見ればいいかわかるようになります。
5、ストレージ:システムディスクは ECS インスタンスがリリースされると削除されます。インスタンスが誤って削除されてもディスクは保持されるので、可能な限りデータディスクを使用してください。
私が使用した設定は以下の通りです。

image.png

デフォルトで作成されるVPCを選択することができます。その中に4092個のインスタンスを追加することができます。私はECSインスタンスごとに異なるセキュリティグループを使用しているので、個別に設定することができ、未使用のポートが開かれていないことを確認します。

もう一つ重要なのは、パスワードを使うのではなく、キーベースの認証を使うことです。すでにキーペアを持っている場合は、公開キーをAlibaba Cloudに追加します。持っていない場合は、Alibaba Cloudを使って作成することができます。キーは非常に安全な場所に保管し、キー自体はパスフレーズで暗号化されていることを確認してください。

image.png

ECSインスタンスを作成する際の注意点は以上です。

ECSインスタンスの設定

インスタンスを作成してターミナルにログインしたら、ウェブサイトをセットアップする前に考慮すべきことがいくつかあります。

1、コマンドを実行するためにrootアカウントを使用するのではなく、最初の接続にsudoユーザーを設定し、常にコマンドを実行するためにsudoユーザーを使用します。また、あまりにもsudoユーザーのためにキーベースの認証を設定し、完全にrootログインを無効にすることができます。
2、ベースイメージは常に更新しておきましょう。例えば、Ubuntu Serverで以下のようなコマンドを実行します。
3、Alibabaのベースイメージは、必要のない余分なパッケージを持っていません。また、必要のないパッケージをインストールしないことに注意してください。
4、インストール中に調子が悪くなった場合は、システムディスクを変更することで、いつでもインスタンスをリセットすることができます。インスタンスを削除して再作成する必要はありません。

sudo ユーザーを作成し、その中で key based auth を設定しました。ベースイメージを更新し、無人システムのアップグレードを設定しました。Nginx web-serverをインストールするためのチュートリアルに沿って、Nginx web-serverをインストールし、さらに、PHP-FPMを使ってPHP 7.2をインストールしました。PHP 7.2は現時点で入手可能なPHPの最新バージョンです。最新のソフトを使うことで、バグもなく、処理速度も速くなり、安定した運用ができるようになります。最後に、SuiteCRMのアーカイブを公式サイトからダウンロードして、Nginxにデプロイしてみました。

アプリケーションのインストールは、Getting startedのチュートリアルTech Shareの作者が書いたチュートリアルを参考にしてください。

セキュリティグループルールの設定

ECS インスタンスのセキュリティグループでは、未使用のポートを開かないようにすることが非常に重要です。私がSuiteCRMインスタンスに使用したセキュリティグループのルールを見てください。

image.png

すべての ICMP パケットと一緒にポート 22, 80, 443 だけを許可していることがわかります。22番ポートはSSH接続に使われています。ポート80は安全ではないHTTPポートで、私の場合はHTTPSの443番ポートにリダイレクトしています。ICMPパケットは、ホストが生きているかどうかを確認するためのpingに使われます。ICMPパケットを削除しても問題ありませんが、インスタンスへのpingができなくなります。

RDSインスタンスの作成

RDSインスタンスを作成する前に頭に浮かぶ最初の疑問は、なぜそれが必要なのかということです。また、MySQL、MariaDB、PostgreSQL、MongoDBなどのオープンソースのデータベースサーバーをECSインスタンス自体にインストールすることもできます。

この質問に対する答えは、RDSインスタンス用のApsaraDBは速度とセキュリティのために最適化されているということです。デフォルトでは、作成したインスタンスはホワイトリストに登録されたインスタンスのみがアクセス可能です。

ECSインスタンスを作成する際の注意点を見てみましょう。

1、リージョン:ECSインスタンスが作成されるデータベースインスタンスを作成する際には、必ず同じリージョンを選択してください。また、両者が同じVPC内にあることを確認してください。これにより、同じネットワーク内のホスト間で無料のイントラネットデータ転送を活用することができます。もう一つの利点は、ECSインスタンスのプライベートIPアドレスのみをホワイトリスト化する必要があることです。これにより、データベースのセキュリティが大幅に向上します。
2、課金:繰り返しになりますが、毎月のサブスクリプションのコストは、Pay-As-You-Go方式よりも低くなっています。ニーズに応じて選択してください。
3、容量:あなたは、1コア、1 GBのインスタンス、および5 GBのストレージなどのローエンドの構成で開始することができます。後で要件には、リソースを増やすことができます。
4、アカウント:MySQL 5.6 インスタンスのマスターアカウントは、必要な場合を除き、絶対に作成しないでください。データベースごとにデータベースとデータベースユーザを作成します。
以下は私がSuiteCRMで使用したRDSの設定です。

image.png

MySQL RDSインスタンスが有効になったら、インスタンスのセキュリティタブからECSインスタンスをホワイトリストにしました。IPアドレスをホワイトリスト化するとすぐに、RDSインスタンスのホスト名とポート番号を取得しましたが、これはMySQLのデフォルトポート "3306 "でした。「suitecrm」という名前のデータベースと「suitecrm」という名前のデータベースユーザを作成し、そのユーザに読み書きのアクセス権を与えました。

HTTPSの使用

インターネットの発達に伴い、毎日のように多くのウェブサイトが追加されています。Let's Encrypt証明書局がSSL証明書を無料で提供するようになってからは、すべてのWebサイトでSSLを利用することがトレンドになりました。セキュリティを確保するためには、WebアプリケーションでSSLを利用することは非常に重要です。やりとりされているデータが暗号化されていないと、ネットワークの中を盗み聞きされて機密情報を抜き取られてしまう可能性があります。

Alibaba CloudもSSL証明書を提供していますが、私の感覚ではかなり高額です。しかし、高価なものには余分な保証がつきものです。Alibaba Cloudが提供するSSL証明書は、企業ユーザーに適しています。

SuiteCRMの導入では、SuiteCRMのWebアプリケーションのセキュリティを確保するために、Let's Encryptの無料SSLも利用しました。Let's Encrypt CAのクライアントアプリケーションであるCertbotで証明書を生成するには、ドメインをサーバーに向ける必要があります。

アリババクラウドでは、ドメイン名を無料のwhois保護付きで非常にリーズナブルな料金で提供しています。私の場合、クライアントは既に他所から購入したドメイン名を持っていました。私はサブドメインを作成し、そのドメインをECSインスタンスに向けました。Certbotをインストールして、簡単に証明書を生成することができました。証明書の有効期限が3ヶ月ごとに切れているので、証明書を自動的に更新するためのcronジョブを設定することを忘れないでください。

ダイレクトメールの設定

エンタープライズグレードのウェブサーバーを作成するには、専門知識と時間が必要であり、維持するためのコストが非常に高くなるため、自分でメールサーバーを設定することは避けるべきです。ちょっとした設定ミスでメールが直接スパムフォルダに入ってしまうこともあります。

アリババクラウドダイレクトメールサービスは、SMTPを使用してアプリケーションからメールを送信する安価な方法を提供しています。毎日最初の200通までは無料です。私の場合は1日200通で十分で、無料枠を超えたメールも激安です。ダイレクトメールに新しいメールサブドメインを追加してみました。ドメインを追加した際に、DNSの更新を求められました。指示通りにやってみましたが、DNSの検証に時間がかかりました。一度完了したら、送信者アドレスを追加して、SMTPサーバをアプリケーションで使用できるようにしました。

ウェブベースのインストール

ようやく、すべての準備が整いました。ECSでホストされているSuiteCRMアプリケーション。データベースサーバーはRDS用のApsaraDBでホストされています。ソフトウェアをインストールするためのウェブベースのインストールを簡単に行うことができました。

以下は、SuiteCRMのWebベースのインストール中にデータベースサーバーに提供した設定です。

image.png

同様に、必要な情報をすべて記入し、SMTPサーバの詳細を提供しました。

image.png

最終的に、私のアプリケーションはAlibaba Cloud上にデプロイされました。さらに、ApsaraDB for Memcacheを使用してSuiteCRMのセッションキャッシュを保存し、WAFを使用して侵入してくる脅威からアプリケーションを保護することをクライアントに提案しました。しかし、クライアントは、月々の請求額が増えることを理由に、これらの提案の実装を拒否しました。しかし、クライアントはアリババクラウドプラットフォーム上のアプリケーションのパフォーマンスを見て非常に満足していました。

私はAlibaba Cloud Tech Shareプラットフォームで技術ブログを頻繁に書いています。以下のリンクにアクセスして、私が書いたチュートリアルを見つけてください。また、私はAlibaba Cloud Tech Shareプラットフォーム上のUbuntu 16.04にSuiteCRMをインストールするために私が従っている実行するための手順とコマンドの詳細なガイドを書きます。

アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

webカメラを複数台挿した時、どれが/dev/video?? なのかを確認する方法

問題

webカメラを1台だけ挿すのなら、通常は/dev/video0に繋げばいいと思う

$ fswebcam -d /dev/video0 a.jpg
# またはデフォルトで/dev/video0なので
$ fswebcam a.jpg

しかし、2台以上だとどのカメラが/dev/video0なのか2なのか何なのかわからなくなる。

解決方法

v4l2-ctlを使うとこういうリストが出力できる。

raspberryPiでの例
$ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
    /dev/video10
    /dev/video11
    /dev/video12

bcm2835-isp (platform:bcm2835-isp):
    /dev/video13
    /dev/video14
    /dev/video15
    /dev/video16

BUFFALO BSW32KM03 USB PC Camera (usb-20980000.usb-1.3):
    /dev/video0
    /dev/video1

UVC Camera (046d:0825) (usb-20980000.usb-1.5):
    /dev/video2
    /dev/video3

ここで注目するのは、カメラには(usb-20980000.usb-1.5)的なのがついているということ。
そしてこのusb-1.5の部分は物理的なUSBポートに紐付けられている(参考)。

なので、webカメラを常時挿したままであれば、そのカメラのここで言うUSB番号が固定されるので、その下に書いてある最初のパス(/dev/video*)を使うとカメラの画像が取れる(もう一方はメタデータ?らしい)。

これらを踏まえての簡単なrubyスクリプト

require "./video_paths"
VideoPaths.paths # => {"1.3"=>"/dev/video0", "1.5"=>"/dev/video2"}
video_paths.rb
require "memoist"
require "active_support/core_ext/object/blank"

class VideoPaths
  USB_NUMBER_REG = /\.usb\-([\d\.]+)/

  class << self
    extend Memoist
    def paths
      new.to_h
    end
    memoize :paths
  end

  def initialize
    @output = clean_output(`v4l2-ctl --list-devices`)
  end

  def to_h
    camera_names.to_h do |camera_name|
      key, valid_path, *other_paths = group_by_device[camera_name]
      [extract_usb_number(camera_name), valid_path]
    end
  end

  private

  attr_reader :output

  def group_by_device
    key = :not_yet
    output.group_by do |line|
      key = line if line.end_with?(":")
      key
    end
  end

  # BUFFALO BSW32KM03 USB PC Camera (usb-20980000.usb-1.3):
  #                         ^^^^^^^^
  def camera_names
    group_by_device.keys.select { |key| key.match?(/camera/i) }
  end

  # BUFFALO BSW32KM03 USB PC Camera (usb-20980000.usb-1.3):
  #                                               ^^^^^^^^
  def extract_usb_number(camera_name)
    camera_name.match(USB_NUMBER_REG)[1]
  end

  def clean_output(text)
    text.lines.collect(&:strip).delete_if(&:blank?)
  end
end
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PowerDNS Cache削除

現在のDNS Cacheのdump

rec_control dump-cache /tmp/the-cache

削除コマンド

rec_control wipe-cache 【削除ドメイン名】
  • レコードタイプを指定して削除する wipe-cache-typed コマンドもあるようだ。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

linuxで新しいコマンドを作ってみる

  • linuxで新しいコマンドを作ってみようの巻です。

新しいコマンドがどういうことかというと、
newfileコマンドを打てば、「newfile.txt」ファイルを作成させることが出来るのです。

  • どういう仕組み?

aliasコマンドを使用します。
1. newfileコマンドを打てば
2. 裏でtouch newfile.txtを裏で実行させ
3. 「newfile.txt」ファイルを作成させているのです。

  • 登録のコマンド
alias 別名のコマンド='コマンド'
  • 削除のコマンド
unalias 別名のコマンド

コマンドを登録する

※注意

aliasは、ターミナルの画面を閉じたり、ログアウトしたりするとリセットされるので注意が必要です。

一時的に登録

  • 登録
alias newfile='touch newfile.txt'
  • 登録の確認
$ alias | grep newfile
==========
alias newfile='touch newfile.txt'
==========

登録できていました!

  • 実行
$ ls
(何も返ってこなかった)

$ newfile

$ ls
newfile.txt

newfile.txt出来ていました!

永続的に登録

  • 登録
vi  ~/.bashrc
==========
追加
alias newfile='touch newfile.txt'
==========
  • ログインし直す
exit
  • 登録の確認
$ alias | grep newfile
==========
alias newfile='touch newfile.txt'
==========

登録できていました!

  • 実行
$ ls
(何も返ってこなかった)

$ newfile

$ ls
newfile.txt

newfile.txt出来ていました!

コマンドを削除する

一時的に登録した場合の削除

  • 登録の確認
$ alias | grep newfile
==========
alias newfile='touch newfile.txt'
==========
  • 削除
unalias newfile
  • 削除の確認
$ alias | grep newfile
(何も返ってこない)

永続的に登録した場合の一時削除

  • 登録の確認
$ alias | grep newfile
==========
alias newfile='touch newfile.txt'
==========
  • 一時削除
unalias newfile
  • 削除の確認
$ alias | grep newfile
(何も返ってこない)

※ただし、ログインし直しなどしたらコマンドは使えるようになっています。

永続的に登録した場合の永続的削除

  • 登録の確認
$ alias | grep newfile
==========
alias newfile='touch newfile.txt'
==========
  • 削除
vi  ~/.bashrc
==========
削除
alias newfile='touch newfile.txt'
==========
  • ログインし直す
exit
  • 削除の確認
$ alias | grep newfile
(何も返ってこない)

※こちらは、改めてログインし直ししてもコマンドは削除されたままになります。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

パーティションを作成してから Raspberry Pi OS をインストールする

Raspberry Pi 4 Model B で USB ブート」では microSD 用のイメージを USB マスストレージにそのまま書き込んで、その後でパーティションのサイズを変更する手順を記した。
しかし実のところ、USB マスストレージにはシステムのファイルが配置されてさえいればよく、Raspberry Pi Imager や dd コマンドを使って厳密にコピーを行わなければならないわけではない。
ここでは最初にパーティションを作成し、次にファイルをコピーする手順を紹介する。

パーティションの作成

インストールイメージのパーティションを確認する

Raspberry Pi OS (64bit) のインストールイメージのパーティションは gdisk コマンドで調べることができる。

$ unzip 2020-08-20-raspios-buster-arm64.zip
$ gdisk -l 2020-08-20-raspios-buster-arm64.img
GPT fdisk (gdisk) version 1.0.5

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: not present


***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format
in memory. 
***************************************************************
:
Number  Start (sector)    End (sector)  Size       Code  Name
   1            8192          532479   256.0 MiB   0700  Microsoft basic data
   2          532480         7380991   3.3 GiB     8300  Linux filesystem

インストールイメージでは MBR によるパーティション管理がされていることがわかる。
なお1つ目のパーティションは /boot、2つ目のパーティションは / に割り当てられる。

パーティションを作成する

gdisk コマンドで以下のようなパーティションを作成する。

$ sudo gdisk -l /dev/sdb
GPT fdisk (gdisk) version 1.0.5

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.
:
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048          526335   256.0 MiB   0700  Microsoft basic data
   2          526336      5860533134   2.7 TiB     8300  Linux filesystem

使用した USB マスストレージの容量は 3TB なので、GPT を選択した。2TB 未満(かつ 1 sector が 512 bytes 以下)なら MBR でも問題ないだろう。
USB マスストレージが HDD なら、ここで swap パーティションを作成してもいい。

パーティションのフォーマット

/bootvfat/ext4 でフォーマットする。

$ sudo mkfs -t vfat /dev/sdb1
$ sudo mkfs -t ext4 /dev/sdb2

ファイルのコピー

インストールイメージ、USB マスストレージをマウントし、内容をコピーする。

$ mkdir img_boot img_root

# イメージ内の /boot, / パーティションを loop デバイスに割り当てる
$ sudo losetup -Pr --show -f 2020-08-20-raspios-buster-arm64.img /dev/loop20
$ sudo mount /dev/loop20p1 img_boot
$ sudo mount /dev/loop20p2 img_root

# ファイルをコピーするため、USB マスストレージのパーティションをマウント
$ mkdir boot root
$ sudo mount /dev/sdb1 boot
$ sudo mount /dev/sdb2 root

# ファイルコピー
$ sudo cp -a img_boot/* boot/
$ sudo cp -a img_root/* root/

# インストールイメージの後片付け
$ sudo umount img_boot img_root
$ sudo losetup -d /dev/loop20
$ rmdir img_boot img_root

設定変更

cmdline.txtfstab のパーティション情報を更新する。

# パーティションの PARTUUID を確認する
$ sudo blkid /dev/sdb?
/dev/sdb1: SEC_TYPE="msdos" UUID="C7EE-35DE" TYPE="vfat" PARTLABEL="Microsoft basic data" PARTUUID="09468d30-111e-4028-8f37-16f65e497c25"
/dev/sdb2: UUID="8aff8673-0851-45af-a8cd-8c31614b9632" TYPE="ext4" PARTLABEL="Linux filesystem" PARTUUID="9522d40d-e6df-422a-a5f6-26195aa7e074"

# root=PARTUUID= の値を上記の /dev/sdb2 の PARTUUID に書き換える
$ cat boot/cmdline.txt
console=serial0,115200 console=tty1 root=PARTUUID=9522d40d-e6df-422a-a5f6-26195aa7e074 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.sh splash plymouth.ignore-serial-consoles

# /boot と / の PARTUUID= に /dev/sdb1 と /dev/sdb2 のものをセットする
# swap など他のパーティションも作成した場合はここで追加しておく
$ cat root/etc/fstab
proc            /proc           proc    defaults          0       0
PARTUUID=ee96d62f-2fe6-44c0-abcf-f70569772297  /boot           vfat    defaults          0       2
PARTUUID=035df15c-ccbe-45c0-9e9a-f97096bd3ee9  /               ext4    defaults,noatime  0       1

# 後片付け
$ sudo umount boot root
$ rmdir boot root

あとはこの USB マスストレージを Raspberry Pi 4 に接続すれば起動できる。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

bashで、「ファイルが存在する場合は削除」する。

rm exist.txt 2> /dev/null

もし存在しないならこのコードは標準エラー出力になります。
そして標準エラー出力の2を/dev/nullに捨てます。

参考
https://qiita.com/i35_267/items/158cd20ed26f73a3d894

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む