20201017のLinuxに関する記事は4件です。

Linux: 強制ロック(mandatory lock)

Linuxでファイルの強制ロック(mandatory lock)をする方法です。

強制ロックとは

  • アドバイザリロックとは異なり、Linux固有の機能。POSIXやUNIXにはない。
  • ロックを掛けたプロセス以外からの、read()やwrite()をできなくする。
  • race conditionが発生する可能性があったりして、ロックの信頼性は高くない。ロックと同時にreadやwriteが獲得されると、ロック中なのに読み書きできてしまうらしい。

強制ロックが有効になる環境を作る

強制ロックを有効にするには、2つの条件を満たす必要があります。

  1. ロックされるファイルは-o mandでマウントされたファイルシステムでないとならない。
  2. ロックされるファイルは、set-group-IDビットがOnで、group-executeビットがOffでないとならない。
mkdir dir
mount -t tmpfs -o mand,size=1m tmpfs ./dir
chmod g+s,g-x dir/lockfile
echo hello > dir/lockfile

強制ロックを発動する

強制ロックを発動するために、システムコールを呼び出すPythonスクリプトを作ります。

lock.py
#!/usr/bin/env python
import fcntl, os, time, sys
f = open(sys.argv[1], "r+")
fcntl.lockf(f, fcntl.LOCK_EX)
print(f.readlines())
time.sleep(10)

このlock.pyは、10秒間dir/lockfileを排他的強制ロックします。lock.pyを実行している10秒間の間に、他のプロセスからdir/lockfileを読み込もうとすると、pythonのプロセスが終了するまで待たされます。

# ロックする
./lock.py

# 別ターミナルで
cat dir/lockfile # 10秒程度待たされる

この10秒間に、lslocks/proc/locksを確認すると、ロックが掛かっている事がわかります。

root@vagrant:~/dir# lslocks
COMMAND           PID  TYPE SIZE MODE  M START END PATH
lvmetad           463 POSIX   4B WRITE 0     0   0 /run/lvmetad.pid
cron              866 FLOCK   4B WRITE 0     0   0 /run/crond.pid
atd               848 POSIX   4B WRITE 0     0   0 /run/atd.pid
lxcfs             849 POSIX   4B WRITE 0     0   0 /run/lxcfs.pid
iscsid           1135 POSIX   5B WRITE 0     0   0 /run/iscsid.pid
python           1818 POSIX   0B WRITE 1     0   0 /dev/pts/0
☝?ここ

root@vagrant:~/dir# cat /proc/locks
1: POSIX  MANDATORY WRITE 1818 00:2c:3 0 EOF ??ここ
2: POSIX  ADVISORY  WRITE 1135 00:13:1503 0 EOF
3: POSIX  ADVISORY  WRITE 849 00:13:1498 0 EOF
4: POSIX  ADVISORY  WRITE 848 00:13:1487 0 EOF
5: FLOCK  ADVISORY  WRITE 866 00:13:1485 0 EOF
6: POSIX  ADVISORY  WRITE 463 00:13:1258 0 EOF

参考

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

Ubuntu 20.04にSambaを使用してファイルサーバを立てる

Ubuntuに、Sambaを使ってゲストアカウントで接続できるファイルサーバをたてます。

環境

Ubuntu 20.04を使いました。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.1 LTS
Release:    20.04
Codename:   focal

1. sambaのインストール

apt installでSambaをインストールします

$ sudo apt install samba

version 4.11がインストールされました。

$ samba -V
Version 4.11.6-Ubuntu

2. 共有するディレクトリの作成

任意の場所に共有用のディレクトリを作成します。

$ cd /home
$ mkdir share
$ chmod 777 share

3. sambaサーバの設定

$ sudo vi /etc/samba/smb.conf

この辺はよく分かっていないので、ネットにある記事を参考に設定しました。

[global]
    unix charset = UTF-8
    dos charset = CEP932
    display charset = UTF-8

    bind interface only = yes
    map to guest = Bad User

[public]
    comment = public
    path = /home/share
    public = yes
    writable = yes
    printable = no
    create mode = 0777
    directory mode = 0777

4. サーバの起動

$ sudo service smbd start

5. 自動起動設定

必要に応じて自動起動の設定をしておきます。

$ sudo sytemctl enable smbd

5. macからの接続

Finderでサーバへ接続を開く、もしくはCmd + kし、サーバアドレスに

smb://<ip address or hostnanme>

と、入力すれば接続できます。

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

Raspberry Pi 4にCentOS7をインストール&設定

ラズパイ4を購入したので、Raspbianではなく一般的なサーバーとしてよく使われるCentOSを入れてみたいと思います!!

ただし、実用的じゃないので自分はすぐにRaspbianに戻しました(笑)

参考にさせて頂いたサイト

Raspberry Pi 4 で CentOS 7 を動かす
CentOSにntpサーバを入れて、日本標準時刻に自動的に合わせるためのメモ
CentOS 7 NTP設定・・・ちょっと待て!?

Raspberry Pi Imagerの準備

こちらは、microSDのフォーマットやOSの書き込みなどを自動で行ってくれるソフトです!

Raspberry Pi Downloads - Software for the Raspberry Pi

ここから、任意のOSを選択してダウンロード&インストールをしましょう!
私は、microSDの書き込みをWindowsで行ました。

image.png

ディスクイメージのダウンロード

上記のサイトだと、CentOSをデフォルトでサポートしていないので、下記のリンクからラズパイ4用のCentOS7のディスクイメージをダウンロードしましょう。

ダウンロード

Raspberry Pi Imagerを使って、microSDに書き込む

ディスクイメージのダウンロードが終わったら、インストールしたRaspberry Pi Imagerを使って、microSDに書き込みます。

  • Operating System:ダウンロードしたディスクイメージ
  • SD Card:PCに挿している書き込みたいSDカード

2つ指定すると、「WRITE」が押せるようになるので押して書き込みましょう。
image.png

しばらく待って、この画面がでたら書き込みが完了!!

image.png

ラズパイに有線LANを挿して、SSHで接続する

書き込みが終了したら、書き込んだSDカードをラズパイに挿して起動しましょう!
起動したら、デフォルトの以下のユーザーでログインして、IPアドレスを確認します。

ユーザ名:root
パスワード:centos

ログインできたら、以下のコマンドを打って、IPアドレスを確認しましょう !

ip a | grep 192

そうすると、192から始まるIPアドレスが取得できます。

[root@localhost ~]# ip a | grep 192
    inet 192.168.0.2/24 brd 192.168.0.255 scope global noprefixroute dynamic eth0

ここから分かるとおり、このラズパイのIPアドレスは「192.168.0.2」ということが分かりましたので、別のPC(今回はmac)からSSHでログインします。
(Windowsの方はTera TermというソフトをDLをしてそこからログインします。)

まずは、ターミナルで以下のコマンドをうち、ラズパイでログインした通りにここでもログインしましょう。

ssh root@調べたラズパイのIPアドレス

私の場合だと、以下のようなコマンドになります。

ssh root@192.168.0.2

そしたら、このようになるのでyesと入力します。

The authenticity of host '192.168.0.2 (192.168.0.2)' can't be established.
ECDSA key fingerprint is SHA256:mOsYHnXBZPXZIAs0bzk7eOv3hZ4Rt2mJKfzlZiylR3o.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

次は、パスワードが求められるので「centos」と入力してEnterを押します。

Warning: Permanently added '192.168.0.2' (ECDSA) to the list of known hosts.
root@192.168.0.2's password:

このような状態になれば、ログインは成功です!!

Last login: Tue Apr 21 17:23:37 2020 from 192.168.0.7
[root@localhost ~]#

ここまでをまとめると、このような感じになるはずです

image.png

rootのパスワードを変更する

初期状態だと、誰でもログインできてしまうので以下のコマンドを打って、任意のパスワードへ変更しましょう。

passwd root

すると、新しいパスワードの入力と確認が求められるので2回入力します。

image.png

「passwd: すべての認証トークンが正しく更新できました。」
と表示されたら完了です!!!

パーティションの拡張を行う

まず、以下のコマンドを打ってください。

df -h

そうするとこのような結果が表示されると思います。

[root@localhost ~]# df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/root        1.4G  1.2G  211M   85% /
devtmpfs         1.9G     0  1.9G    0% /dev
tmpfs            2.0G     0  2.0G    0% /dev/shm
tmpfs            2.0G   17M  1.9G    1% /run
tmpfs            2.0G     0  2.0G    0% /sys/fs/cgroup
/dev/mmcblk0p1   286M   52M  235M   18% /boot
tmpfs            391M     0  391M    0% /run/user/0

/def/rootを見てみると、microSDは32GBのものを使用しているのに、うまく使いきれていません…

なので、以下のコマンドを入力して拡張しましょう!

/usr/bin/rootfs-expand

そうすると、最後にDone.と表示されると成功です

image.png

なので、もう一度df -hと入力すると拡張されていることが分かります。

image.png

vimエディタのインストール

以下のコマンドを入力して、vimというエディタをインストールしましょう。

sudo yum install vim -y

NTPサーバーを入れて日本の標準時に合わせる

/etc/chrony.confを編集して、NTPサーバーの指定しましょう!
デフォルトでは以下のようになっているので

/etc/chrony.conf
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst

このserver から始まる行が、海外の時刻を提供しているサーバーらしいので、全部コメントアウトして、以下の行を追加します。

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
### ↓ここからコメントアウト
# server 0.centos.pool.ntp.org iburst
# server 1.centos.pool.ntp.org iburst
# server 2.centos.pool.ntp.org iburst
# server 3.centos.pool.ntp.org iburst
######## ↑ここまでコメントアウト

### ↓ここから追加
# 日本標準時を提供しているNTPサーバー(stratum 1)
server ntp.nict.jp iburst
# 上記サーバーと直接同期しているNTPサーバー(stratum 2)
server ntp.jst.mfeed.ad.jp iburst
####### ↑ここまで追加

今回は、時刻補正のためのNTPなので、以下の行を追加してサーバーとしては使わないようにする。

port 0

海外のNTPサーバーと大幅にずれていると設定出来ないらしいので、以下のコマンドで手動設定しましょう。

chronyc makestep

以下のコマンドを入力して、NTPサーバーの再起動と起動時に自動で実行するようにします。

systemctl restart chronyd
systemctl enable chronyd

dateコマンドを入力して見ます。

2020年  4月 23日 木曜日 16:23:00 UTC

JSTになってない!!!!

ちゃんとJSTになって時刻が日本時間になっているかたは、以上です、お疲れ様でした。

なので、timedatectlコマンド入力して見ます。

      Local time: 水 2020-04-22 16:23:51 UTC
  Universal time: 水 2020-04-22 16:23:51 UTC
        RTC time: n/a
       Time zone: UTC (UTC, +0000)
     NTP enabled: yes
NTP synchronized: yes
 RTC in local TZ: no
      DST active: n/a

!?!?!?!?
そもそも、タイムゾーンがUTCだったのでいくらやってもUTC時刻に補正されちゃうんですね….???

なので、以下のコマンドでタイムゾーンを東京に変更して、もう一度NTPサーバーの再起動を行い、dateで時間を確認します。

timedatectl set-timezone Asia/Tokyo
systemctl restart chronyd
date

すると….

2020年  4月 23日 木曜日 01:24:14 JST

ちゃんとJSTの時刻が設定されました!!!!

ちなみに、ラズパイを再起動して確認してみても

[root@localhost ~]# date
2020年  4月 23日 木曜日 01:39:05 JST

うまく設定できてることが確認できました???

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

Dockerのコマンドまとめ

はじめに

Dockerは多くのIT開発企業で導入されている環境構築を楽にする技術です。
Dockerのコマンドをまとめます。

今回のDockerコマンド

  • docker login
  • docker pull
  • docker images
  • docker run
  • docker run --name
  • docker run --rm
  • docker ps -a
  • docker restart
  • docker exec -it (コンテナID)or(コンテナ名) bash
  • docker commit (コンテナID)or(コンテナ名) (新しいimage名)
  • docker tag (source) (target)
  • docker push
  • docker rmi
  • docker stop
  • docker rm
  • docker system prune

詳細

docker login

Dockerにログインするコマンド。
Dockerを使用する場合は最初に行う。

ターミナル
% docker login
Username: => Dockerに登録したユーザー名を入力
Password: => Dockerに登録したパスワードを入力

=> ユーザー名、パスワードが合っていれば、ログインする。(Login Succeededと表示される)

docker pull

Docker imageをdockerhubからホストにダウンロードするコマンド。

ターミナル
例)hello-worldというimageをダウンロードする時

% docker pull hello-world
=> hello-worldがダウンロードされる

=> ユーザー名、パスワードが合っていれば、ログインする。(Login Succeededと表示される)

docker images

ホストの中にあるdocker imageのリストを表示するコマンド。

ターミナル
例)hello-worldというimageをダウンロードした後

% docker images
=> REPOSITORY      TAG      IMAGE ID      CREATED      SIZE
   hello-world     latest   (自動作成のID)  (作成した時)   (データサイズ)

docker run

コンテナを作るコマンド。

ターミナル
例)hello-worldというimageをダウンロードした後

% docker run hello-world
=> hello-worldのコンテナが作成され、実行される。

% docker run -it ubuntu bash
=> ubuntu(OSの名前、dockerhubに存在するdocker image)のコンテナが作成され、bashというプログラムを実行させる。
(bashはshellの名前。ubuntuのデフォルトのコマンドをbashに上書きして実行している。ちなみにubuntuのデフォルトのコマンドはbashなので、今回はdocker -it run ubuntuでも同じ。)

docker run --name

名前をつけてコンテナを作るコマンド。

ターミナル
% docker run --name sample ubuntu
=> sampleという名前のコンテナがubuntuというdocker imageから作成される。

docker run --rm

コンテナを起動した後、すぐにコンテナを削除コマンド。

ターミナル
% docker run --rm hello-world
=> hello-worldというdocker imageからコンテナを作成し、実行した後、すぐにコンテナが削除される。
(一度しか使わないコンテナは残さないために、すぐに削除する。)

docker ps -a

全てのコンテナを表示するコマンド。

ターミナル
% docker ps -a
=> 全てのコンテナが表示される。

% docker ps
=> 実行中のコンテナのみされる。

docker restart

一度実行したコンテナをリスタートするコマンド。

ターミナル
% docker restart (コンテナID)or(コンテナ名)
=> コンテナIDで指定したコンテナがリスタートされる。(STATUSがUPとなる)

docker exec -it (コンテナID)or(コンテナ名) bash

リスタートしたコンテナにプログラムを実行させるコマンド。(bashの部分は適宜、実行したいプログラムに置き換える)

ターミナル
% docker exec -it (コンテナID)or(コンテナ名) bash
=> リスタートしたコンテナの中に入ることができる。(bashにより)

docker commit (コンテナID)or(コンテナ名) (新しいimage名)

更新したコンテナを新しいDocker imageとして保存するコマンド。

ターミナル
% docker commit (コンテナID)or(コンテナ名) (新しいimage名)
=> docker imageが保存され、IDが表示される。

docker tag (source) (target)

docker imageのimage名を変更するコマンド。
docker imageをdockerhubにpushする前に、ホストのimageのリポジトリ名とpush先の自身のdockerhubのリポジトリ名を同じにするために使う。(dockerhubのリポジトリはdockerhubで作成しておく必要がある)

ターミナル
% docker tag (ホストのdocker imageのリポジトリ名:タグ名) (dockerのユーザー名/リポジトリ名)
=> docker imageのリポジトリ名がdockerhubのリポジトリ名と同じになる。(タグ名は指定しなければ、latestとなる。)

docker push

docker imageを自分のリポジトリに作成するコマンド。

ターミナル
% docker push (image名)
=> dockerhubにdocker imageがpushされる。(image名はdockerのユーザー名/リポジトリ名と同じにしておく)

docker rmi

docker imageを削除するコマンド。(image名はdockerのユーザー名/リポジトリ名と同じにしておく)

ターミナル
% docker rmi (image名)or(image id)
=> 指定したdocker imageが削除される

docker stop

実行中のコンテナをストップするコマンド。(STATUSをUP→EXITEDにする)

ターミナル
% docker stop (コンテナ名)or(コンテナID)
=> 指定したコンテナがストップされる。

docker rm

コンテナを削除するコマンド。

ターミナル
% docker rm (コンテナ名)or(コンテナID)
=> 指定したコンテナが削除される

docker system prune

ストップしているコンテナ全てを一括で削除するコマンド。

ターミナル
% docker system prune
=> ストップしているコンテナが全て削除される

参考

Udemy

かめれおん講師 「米国AI開発者がゼロから教えるDocker講座」

https://www.udemy.com/share/103aTRAEAdd1pTTHoC/

有料ですが、初学者の私にも非常に理解しやすかったです。

最後に

本投稿が初学者の復習の一助となればと幸いです。

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