20210301のLinuxに関する記事は6件です。

mysqldumpの結果をimportするときに進捗率を知りたい

以下のようにpvコマンドを使うとどれくらいの進捗か分かるので便利。

 pv < dump_result.gz | zcat | mysql -u root database_name -p

 145MiB 0:05:38 [ 776kiB/s] [===========================================>  
                                                     ] 45% ETA 0:06:45 ] 43% ETA 0:07:07                         ] 42% ETA 0:07:09
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

chmodとファイルの権限

前提

今回の記事は、chmodを最近使い始めた私が理解したこと整理するために書いたものです。
この記事でファイルの権限等について、全てが分かるわけではないのでご了承ください。
今回の記事で紹介するのはlinuxコマンドとなります。
使用マシンは"macbookpro(2020) 13インチ"です。

linuxコマンドでファイルの権限を確認する方法

以下のコマンドで確認できます。

ls -l

権限の見方

スクリーンショット 2021-02-21 10.01.29.png

画像は私の環境のものです。
(user名が写っていますが、qiitaのアカウント名と同じなので加工しておりません)

今回は一番左の権限について("drwxr-xr-x"の部分)のみ触れていきます。

  • 文字数
    添付画像を見て分かる通り、全てハイフン含め10文字になっていることがわかります。
    これら10文字の文字列を、1文字-3文字-3文字-3文字に区切って見ていきます。
    -rw-r--r--
    drwxr-xr-x
    drwxr-xr-x

  • 最初の1文字目
    "-(ハイフン)"または、"d"が表示されている部分です。
    これは、
    "-(ハイフン)":ファイル(viで開けるやつだと思います)
    "d":ディレクトリ

  • 2〜4文字目、5〜7文字目、8〜10文字目
    2〜4文字目
     → 所有者の権限を表しています。今回だと、"matsumotoyuutarou"の部分が所有者になります。
    5〜7文字目
     → 所有者グループの権限を表しています。今回だと、staffの部分です?
    8〜10文字目
     → その他(所有者、所有者グループ以外)の権限を表しています。

    r, w, x, - のいずれかが入っていることがわかります。
    2〜4文字目, 5〜7文字目, 8〜10文字目 の文字はそれぞれ必ず以下それぞれの権限があればrwxの順番で表示されることになっています。
    で、権限がない部分は"-"が入るわけです。
    例えば、読み取り可能で、それ以外は不可な場合は"r--"のようになります。
    "r":読み取り可能
    "w":書き込み可能
    "d":実行可能

chmodコマンド

chmod 777 ファイル名

例えば、上記のようなコマンドを入力すると、ファイルの権限を変えることが可能です。
今回は数字の部分(777のところ)を記載します。
前述で出てきたr, w, xには、それぞれ数字があり、以下のような数字が割り振られています。
r:4
w:2
x:1

777の3桁の数字は、以下を表します。
一番左の桁:前述の2〜4文字目の権限
真ん中の桁:前述の5〜7文字目の権限
一番右の桁:前述の8〜10文字目の権限

で、777の3桁それぞれの数字自体は、どの操作が可能なのかを表していて、可能な操作の数字を足した数になっています。
例えば、"7"は読み取り、書き込み、実行全てが可能になります。
読み取りと書き込みだけを可能にする場合は、"6"になるといった感じです。

ファイルaが「所有者の読み取りのみ可能」(r--------)だとします。
これを、「所有者と所有グループが読み込みと書き込み可能、その他が読み込みのみ可能」の状態にしようとすると、以下のようなコマンドになります。

chmod 664 ファイルa

最後に

今回は、最近学んだことを整理するために記事を書きました。
分かりづらい部分や、間違いがありましたらご指摘いただけますと幸いです。

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

自分用 MySQL (& Python3) 基礎勉強ノート

この記事は?(あらすじ)

Python でデータセットを読み込んで色々計算するプログラムを作成していた。
そこから応用して、Web アプリとして実装し、ブラウザから計算実行、結果確認できるものを作った。
で、あるとき思った。「毎度毎度ファイル全部読んでっての、頭悪くね?」
この機会に、データベースの勉強でもしよう。そっちのがきっとスマート。
というわけで、MySQL のコマンドのお勉強を初めた自分であった。

学んだことを、備忘録がてら綴ったものです。
MySQL の基礎的な機能を支障無く使える程度の量になったかなと思っています。
間違いや不正確な情報もあるかもしれませんが、そこはコメントにてご指摘いただければと思います。

環境

項目 バージョン等
OS Linux Mint 20.1 Ulyssa 64bit
MySQL Ver 8.0.23-0ubuntu0.20.04.1 for Linux on x86_64 (Ubuntu)
Python3 3.8.5
Python3 mysql-connector-python 8.0.23
Python3 mysql-connector-python-rf 2.2.2

SQL, MySQL とは?

データベースでは、データをテーブル (表) の形で管理している。テーブルから必要なデータをすぐ応答してくれるのがデータベースシステム。
MySQL というのは、データベース管理システムの一つ。SQL というのは、データベース操作をするコマンド。
軽く調べると、MySQL の他にも SQLite というものも有名みたい。自分が見つけた情報を超ざっくりまとめると、

  • MySQL
    • サーバソフト
    • 大規模向け
    • オープンソース, 非商用なら無料, 商用利用にはライセンスが必要らしい
  • SQLite
    • こちらはサーバソフトではなくライブラリ
    • 中, 小規模向け
    • オープンソース (パブリックドメイン), 商用・非商用問わず誰でも使い放題
    • セキュリティについては少々注意が必要らしい?

別に言うほど大規模な開発というわけではないが、興味本位で MySQL を使ってみる。

MySQL では、OS とかにログインするのと同じように、ユーザやパスワード設定があり、ファイルパーミッションと同じように、データのアクセス権限設定なんかがある。

SQL データベースでは、システムの中にデータベースが、データベースの中にテーブル (表) が、テーブルの中にキーと値 (レコード) がある。
MySQL では専用の Shell があり、シェルにログインしてコマンドを打つと、色々と操作ができる。言語ライブラリを用いることで、SQL コマンドを自作プログラムから実行し、データの操作ができる。

MySQL-Draw.png

インストールと初期設定

MySQL 本体のインストールは、APT でこの 2つのパッケージを入れてやるだけで多分ヨシ。

sudo apt install mysql-server mysql-client

mysql-serverは、MySQL を提供するサーバソフトのパッケージ。
mysql-clientは、MySQL へアクセスするクライアントソフトのパッケージ。
サーバマシンとクライアントマシンが別々なら片方ずつのインストールでも多分良いが、ここでは一つのマシン上で練習をするので、両方ともインストール。

続いては MySQL サーバのセットアップ。どうやら、このコマンド一つでセキュリティ関連の初期設定ができるらしい。

sudo mysql_secure_installation

コマンドを実行すると、設定ウィザードが始まる。rootユーザのパスワード設定とか、匿名ユーザやテストデータベースの削除とか、遠隔でのrootログイン拒否設定とかができる様子。

MySQL サーバの起動・停止

Apache とか Samba とかの他のサーバソフトと同様に、Linux Mint (Ubuntu 系)ではsystemctlコマンドで起動・停止を制御できる。

# 起動
sudo systemctl start mysql
# 停止
sudo systemctl stop mysql
# 自動起動オン
sudo systemctl enable mysql
# 自動起動オフ
sudo systemctl disable mysql

MySQL シェルログイン・ログアウト

# root ユーザでログイン
sudo mysql

# 他のユーザでログイン
mysql -u <Username> -p
Enter password: <パスワード入力>

# OS のユーザ名と MySQL のユーザ名が同じときは以下でも可
mysql -p
Enter password: <パスワード入力>

# 他のホスト、ポートを指定
mysql -u <Username> -h <Host> -P <Port> -p
Enter password: <パスワード入力>
  • -u: ユーザ名指定 (未指定なら OS のログイン中のユーザ名)
  • -h: ホスト名指定 (未指定なら localhost)
  • -P: ポート指定 (未指定なら 3306)
  • -p: パスワードを入力してログイン

localhostは、簡単に言えば操作中のマシン自身のこと。ネットワーク経由で別マシンからの操作ではなく、サーバマシン上で操作をしているなら、ホストはlocalhostとすれば良いハズ。
初期設定のままでは、mysql -u root -pではログインできないようになっている。ログインできるようにする方法もあるみたいだが、多分sudoでログインの方が早い気がする。

ログインできると、プロンプトが変わる。

mysql>

この状態になったら、色々と SQL コマンドを打って操作ができる。
コマンドは、大文字でも全て小文字でもどちらで打っても良い。ヘルプとかのリファレンスでは全て大文字で打たれている。

MySQL シェルを終了するには、exitquitコマンド。どちらを入力しても終了できる。また、後述の SQL コマンドはセミコロン;で 1行のコマンドの終わりを示す文法だが、exitquit等一部のコマンドは;が不要。

# どちらでも同じ
mysql> exit
mysql> quit

ユーザとパスワードの管理

デフォルトではrootユーザとシステムユーザだけ存在。システムユーザでの人力ログインは普通しない (多分できない)。rootユーザは全権限を持つため、簡易的なテストやメンテナンス等を除いて常時利用するのはよろしくない。

# ユーザの作成 ('<Password>' には登録するパスワードを入れる)
mysql> create user <Username>@<Host> identified by '<Password>';

# ユーザのパスワードの変更 ('NewPassword' には新規登録するパスワードを入れる)
mysql> set password for <Username>@<Host> = 'NewPassword';
## MySQL バージョンが 5.x のときは PASSWORD('NewPassword') だったが
## 8.x だと PASSWORD() が廃止され、このの書き方で良いらしい

# ユーザの削除
mysql> drop user <Username>@<Host>;

MySQL では、システム側でmysqlというデータベースが生成されており、その中のuserというテーブルからユーザ情報を確認することができる。(テーブルデータの呼び出しのコマンドについて詳しくは後述。) 以下のコマンドで登録されているユーザを確認できる。

mysql> select Host, User from mysql.user;

権限の管理

# 権限の確認
mysql> show grants for <Username>@<Host>;

# 権限の付与 (コンマ区切りで複数の権限を指定)
## 特定のデータベース内のテーブル
mysql> grant <AuthType>, ... on <Database>.<Table> to <Username>@<Host>;
## 特定のデータベース内のテーブル全て (* はワイルドカードと言われる)
mysql> grant <AuthType>, ... on <Database>.* to <Username>@<Host>;
## 全てのデータベースとその中のテーブル全て
mysql> grant <AuthType>, ... on *.* to <Username>@<Host>;

# 権限の削除
## ワイルドカードについては上記同様
mysql> revoke <AuthType>, ... on <Database>.<Table> from <Username>@<Host>;
mysql> revoke <AuthType>, ... on <Database>.* from <Username>@<Host>;
mysql> revoke <AuthType>, ... on *.* from <Username>@<Host>;

主な権限 (<AuthType>)

権限名 内容
SELECT レコードやコラムの表示
INSERT レコードの追加
UPDATE レコードの更新
DELETE レコードの削除
CREATE テーブルやデータベースの作成
ALTER テーブルやデータベースの構造等更新
DROP テーブルやデータベースの削除

この他にも色々な権限があるっぽいが、ひとまずこれが分かっていれば困ることは無さそう。

データベースの管理

# データベースの作成
mysql> create database <Database>;

# データベースの確認
mysql> show databases;

# データベースの削除
mysql> drop database <Database>;

テーブルの管理

テーブル本体の管理

# テーブルの作成
mysql> create table <Database>.<Table> (<ColumnName> <DataType> [Option], ...);
## <ColumnName> <DataType> [Option] をコンマ区切りで続けると、複数のカラムを作成できる
## (カラムの追加も同様)

# データベース内のテーブルの表示
mysql> show tables from <Database>;

# テーブルの削除
mysql> drop table <Table>;

MySQL で使えるデータ型 (<DataType>)

データ型 内容 備考
int 整数 [tiny/small/medium/big] intという型もあり、扱える整数の範囲が変わってくる。
float / double 小数 単精度と倍精度。doublerealと打っても良い。
bit(M) ビット M はビット数。1にすれば、いわゆるブール型に。コマンド上から値を入れるにはb'0001', B'0001', 0b0001と表記。
text 文字列 最大文字数を任意に定めるならchar / varchar型。
blob バイナリ 最大サイズを任意に定めるならbinary / varbinary型。

とりあえず、自分が使いそうなものだけ。他の型や、より詳しい説明は、以下の参照元を。

参照元:
MySQLのデータ型 | MySQLの使い方
MySQLデータ型一覧 (詳細) - Miuran Business Systems

データカラムのオプション (レコード制約) ([Option])

オプション 意味
primary key 同一キー内のレコードを重複できなくなり、NULL を入れることができなくなる。
unique key 同一キー内のレコードを重複できなくなる。
not null キーのレコードに NULL を入れることができなくなる。
default <Value> レコード追加時、値が未指定だったときのデフォルト値を<Value>にする。未指定なら NULL がデフォルトに。

primary keyは、ユーザアカウントID のように、値が無かったり重複されたりしては困るものによく使うと思う。
これも、とりあえず自分が使いそうなものだけ。

参照元: SQLの制約の種類とその指定方法 - Qiita

テーブルカラムの管理

# テーブルのカラムの表示 (どちらでも同じ結果)
mysql> show desc <Database>.<Table>;
mysql> show columns from <Database>.<Table>;

# テーブルのカラムの詳細表示
mysql> show full columns from <Database>.<Table>;

# テーブルのカラムの追加
mysql> alter table <Table> add (<ColumnName> <DataType> [Option], ...);

# テーブルのカラムの追加 (位置指定)
## 位置指定をするときは、カラム数は 1個でないと不可
mysql> alter table <Table> add <ColumnName> <DataType> [Option] [Position];

# テーブルのカラムの削除
## 複数同時指定は不可?
mysql> alter table <Table> drop column <ColumnName>;

カラム追加位置の指定 ([Position])

コマンド 意味
無し 最後尾に挿入
first 最初に挿入
after <Key> <Key>の後に挿入

レコードの呼び出し

全表示

# 指定のテーブルの全てのカラムのレコードを確認
mysql> select * from <Database>.<Table>;

カラム指定 (表示列指定)

# 指定のテーブルの特定のカラムのレコードを確認
## 複数のキーのレコードを表示するには、カラム名をコンマ区切りで記述
mysql> select <Column1>, <Column2>, ... from <Database>.<Table>;

条件式指定 (表示行指定)

# <条件式> に 合ったレコードだけ表示される
mysql> select * from <Database>.<Table> where <条件式>;

条件式 (<条件式>)

意味
<Column> = <Value> 指定のカラムの値が<Value>に等しい。
<Column> != <Value> 指定のカラムの値が<Value>に等しくない。
<Column> < <Value> 指定のカラムの値が<Value>よりも低い。
>, <=, >=
<条件式1> and <条件式2> <条件式1>, <条件式2>両方を満たしている。
<条件式1> or <条件式2> <条件式1>, <条件式2 >いずれかを満たしている。
not <条件式> <条件式>を満たしていない。

例えば、user_id が 3 のデータのみを取得したいときはwhere user_id=3。演算子の両端はkey=3key = 3のように、スペースを入れても入れなくても良い。
whereは、レコードの変更や削除等で特定のレコードを指定するのにも利用する。

レコードの操作

# レコードの追加
mysql> insert into <Database>.<Table> values ("<Value>", ...);
## テーブルのカラム数と values () への指定データ数が合っていないとエラー

# レコードの変更
mysql> update <Database>.<Table> set <Collumn>="<Value>" where <条件式>;
## where 未指定で全レコードの当該キー変更

# レコードの削除
mysql> delete from <Database>.<Table> where <条件式>;
## where 未指定で全レコード削除

その他メモ

文字データの入力

mysql> insert into <Database>.<Table> values (1, 'any string');
mysql> insert into <Database>.<Table> values (1, "any string");

mysql> show grants for user@localhost;
mysql> show grants for 'user'@'localhost';
mysql> show grants for "user"@"localhost";
mysql> show grants for `user`@`localhost`;

文字列のデータ入力では、", 'が無いとエラー。整数や実数であれば無くても良い。
ユーザとホストは、無し, ", ', `でもどれでも良い。

操作先データベース・テーブルの指定

# データベース名から直接テーブルを指定
mysql> any_command <Database>.<Table>;

# Use コマンドを使ってテーブル指定
mysql> use <Database>;
mysql> any_command <Table>;

SH コマンドで言えば、上の方法は絶対パスで操作先指定、下の方法は相対パスで操作先指定する感じ。useコマンドは、いわゆるcdコマンド的な役割。一つのデータベースに対していくつも操作をするというときには、useコマンドを使うと、打ち込む文字数が減って少し楽になる。
この記事では、全て<Database>.<Table>の形で記述。

カラムとかキーとか

記事内でカラムとキーとで言葉が混合していたが、示すものは同じ。表のヘッド部分、つまりその列のデータの意味を示すもの。MySQL のコマンドでも、Key と呼ぶことと Column と呼ぶこととある。
データ自体はデータとかレコードとか呼ぶが、こちらも 2者の意味はほぼ同じ。

キー (カラム) 1 キー (カラム) 2
レコード 1-1 レコード 1-2
レコード 2-1 レコード 2-2
... ...

pager コマンドを使うと幸せになれる

データ量が大規模なテーブルを表示させたとき、横幅が足りなくて変に改行が入って見え辛かったり、縦にめちゃめちゃ長かったりするとき、以下のコマンドを使うことで、矢印キーで表示移動できる。(このコマンドはセミコロン不要。)

# 矢印キー移動表示へ切り替え (less コマンドを使って表示)
mysql> pager less -S

# 解除する (stdout 出力へ戻す)
mysql> nopager

参照元: よく使うMySQLコマンド集 - Qiita

パスワードのポリシーに弾かれるとき

MySQL では、パスワードのポリシーの設定ができる。パスワードのポリシー (条件) を満たしていない、弱いパスワードは登録することができないようにできる。rootユーザからの設定だからポリシー回避、というようなことも無い。テスト動作等のために一時的にポリシーの条件を下げたいというときは、以下のコマンド。

# MySQL内環境変数? (パスワードポリシー設定) を確認
mysql> show variables like 'validate_password%';

# ポリシーを変更
mysql> set global validate_password.policy = LOW;
## MySQL 5.x だと validate_password_policy らしい
## 8.x で変わったらしい

MySQL 内にも独自で環境変数的なものがある。MySQL サーバを再起動すると、設定は元に戻される。永続的に設定するには、これとは別の方法を行う必要があるっぽい。
パスワードポリシーについて、より詳しい話は以下の参照元記事にて。

参照元: Mysql 5.7* パスワードをPolicyに合わせるとめんどくさい件について - Qiita

Python3 から動かしてみる

準備

Python3 から MySQL へアクセスするには、以下の 2つのパッケージを使うそう。

# 必要に応じて、適宜仮想環境を構築してから実行
python3 -m pip install mysql-connector-python
python3 -m pip install mysql-connector-python-rf

MySQL では、デフォルトでcaching_sha2_passwordという認証方式が動いている。しかし、Python のこのモジュールでは、この認証方式に対応していないらしい。mysql_native_passwordだったら対応しているみたいなので、MySQL サーバの認証方式を変更する。

# 認証方式の設定
mysql> alter user <User>@<Host> identified with mysql_native_password by '<Password>';

# 全ユーザの認証方式の表示
mysql> select Host, User, plugin from mysql.user;

データ取得

importする際のモジュール名はmysql。データベースとテーブルは事前に作成。

data-read.py
# coding=UTF-8

# Module import 
import mysql.connector

# Connection start
conn = mysql.connector.connect(host="<Host>", user="<User>", password="<Password>", auth_plugin='mysql_native_password')
# dictionary=True とすると辞書型で、無ければタプルで取得される
#csr = conn.cursor(dictionary=True)
csr = conn.cursor()

# Commands execute
csr.execute("select * from plantinfo.dataset")
data = csr.fetchall()
print(data)
#conn.commit() # データの操作が無いときは、commit はしなくても良い

# Quit
conn.close()

データ追加

data-add.py
# coding=UTF-8

# Module import
import mysql.connector

# Connection start
conn = mysql.connector.connect(host="<Host>", user="<User>", password="<Password>", auth_plugin='mysql_native_password')
csr = conn.cursor(dictionary=True)

# Commands execute
csr.execute("insert into plantinfo.dataset values (%d, '%s')" % (1, "desc"))
#data = csr.fetchall() # データの呼び出しでないときは、fetchall するとエラー
#print(data)
conn.commit()

# Quit
conn.close()

おしまいに

ここには書き切れないほどもっと多彩な機能がありますが、MySQL を理解し、最低限使うにはこの程度を知っていれば十分かと思います。以上、僕の勉強ノートでした。

参考

MySQL基本コマンド一覧まとめ - Qiita
よく使うMySQLコマンド集 - Qiita
[MySQL]権限の確認と付与 - Qiita
MySQLのデータ型 | MySQLの使い方
MySQLデータ型一覧 (詳細) - Miuran Business Systems
MySQLでカラムを追加する「ALTER TABLE ~ ADD」 | UX MILK
Mysql 5.7* パスワードをPolicyに合わせるとめんどくさい件について - Qiita

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

Namespace の学習

Linux の Namespace を学んだときの自分用ログ。実施しているきっかけは、Kubernetes のネットワーク周りをしっかり勉強しようと思ったのだけど、そのためには Docker のネットワークをしっかり学ぶ必要があり、Docker といえば Namespace だよね!ということで、壮大なヤクの毛狩りの結果、ちゃんと根本から勉強しようと腹をくくることにしました。

実際は超素晴らしい ip netnsコマンドの使い方(ネットワークの実験の幅が広がるなぁ~を WSL2 で流して実験するだけなので、素晴らしい元記事を読んでいいねしてくださるとよいと思います。

基本的には、ip コマンドを使って、Namespace を使ったり、ネットワークを作ってみたりします。

ip コマンド

私の Linux の知識が古すぎて ifconfig とばかり思っていましたが、現在では ip コマンドです。様々なことが出来るので見ていきましょう。

$ ip help
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
       ip [ -force ] -batch filename
where  OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
                   tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
                   netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
                   vrf | sr | nexthop }
       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
                    -h[uman-readable] | -iec | -j[son] | -p[retty] |
                    -f[amily] { inet | inet6 | mpls | bridge | link } |
                    -4 | -6 | -I | -D | -M | -B | -0 |
                    -l[oops] { maximum-addr-flush-attempts } | -br[ief] |
                    -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
                    -rc[vbuf] [size] | -n[etns] name | -N[umeric] | -a[ll] |
                    -c[olor]}

環境

ただし、環境は、Windows 10 の WSL2 です。最近面倒なのでこの環境を使うことが多いですが、制限がないかちょっと心配。

$ cat /etc/os-release   # or lsb-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

オプション一覧

ip netns がネットワーク関連のネームスペース関連のコマンドです。ネームスペースを指定することによって、プロセスや、ユーザーや、ネットワークを隔離して管理することができます。このネームスペースや、cgroupをうまく使っているのが Docker のようなコンテナ技術です。この記事がわかりやすかったです。第2回 コンテナの仕組みとLinuxカーネルのコンテナ機能[1]名前空間とは? そして 第3回 Linuxカーネルのコンテナ機能[2] ─cgroupとは?(その1)も cgroupの概要をつかむための良い記事でした。

$ ip netns help
Usage:  ip netns list
        ip netns add NAME
        ip netns attach NAME PID
        ip netns set NAME NETNSID
        ip [-all] netns delete [NAME]
        ip netns identify [PID]
        ip netns pids NAME
        ip [-all] netns exec [NAME] cmd ...
        ip netns monitor
        ip netns list-id [target-nsid POSITIVE-INT] [nsid POSITIVE-INT]
NETNSID := auto | POSITIVE-INT

ネームスペースの追加

WSL2 の環境では、sudo が必要でした。

$ sudo ip netns add test1
[sudo] password for ushio: 
$ sudo ip netns add test2

ネームスペースのリスト

$ ip netns list
test2
test1

ネームスペースの削除

すべてのネームスペースの削除

$ sudo ip -all netns del

個別の削除

$ sudo ip netns delete test1

ネームスペース内でのプロセスの実行

ネームスペース内でbash を実行してみます。ネットワークのインターフェイスも母艦とは別のものになっています。

$ sudo ip netns exec test1 bash# ps
  PID TTY          TIME CMD
31284 pts/3    00:00:00 sudo
31285 pts/3    00:00:00 bash
# ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0

プロセス関連のコマンド

ターミナル1で、bash を実行して、nc コマンドを実行してみます。nc はネットワークの調査で便利なコマンドで、下記のはポート11111でリッスンしています。-l は、リッスンするオプションであり、他の場合は、メッセージを送信します。-k は、コネクションがクローズした後も、次のコネクションを待ち受けます。

ターミナル1
$ tty
/dev/pts/3
$ sudo ip netns exec test1 bash
# nc -kl 11111

違うターミナルからこのプロセスを見てみます。tty は現在使っているターミナルに割り当てられているデバイスファイルを表示しています。ps -C nc で、nc コマンドを実行しているプロセスを表示します。別のネームスペースで実行しているプロセスでも、ps aux 等であれば見ることが出来ます。

ターミナル2
$ tty
/dev/pts/5
$ ps -C nc
  PID TTY          TIME CMD
31343 pts/3    00:00:00 nc

ちなみにネームスペースから、aux コマンドを実行しても結果は同じです。この辺は docker と違いを感じます。

ターミナル2
$ sudo ip netns exec test1 bash
# ps
  PID TTY          TIME CMD
31416 pts/5    00:00:00 sudo
31417 pts/5    00:00:00 bash
31424 pts/5    00:00:00 ps
# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0    896   576 ?        Sl   Feb27   0:00 /init
root        11  0.0  0.0    896    88 ?        S    Feb27   0:00 /init
root     27172  0.3  2.5 9125368 156384 ?      Sl   Feb27   5:35 /usr/bin/dockerd -p /var/run/docker.pid
root     27194  0.3  0.9 2369808 56864 ?       Ssl  Feb27   5:37 containerd --config /var/run/docker/containerd/containerd.toml --log-level info
root     27677  0.0  0.0    904    88 ?        Ss   07:14   0:00 /init
root     27678  0.0  0.0    904    96 ?        S    07:14   0:00 /init
ushio    27679  0.0  0.0   2608   540 pts/1    Ss+  07:14   0:00 sh -c "$VSCODE_WSL_EXT_LOCATION/scripts/wslServer.sh" 622cb03f7e070a9670c94bae1a45d78d7181fbd4 stable .vscode-server 0  
ushio    27680  0.0  0.0   2608  1796 pts/1    S+   07:14   0:00 sh /mnt/c/Users/tsushi/.vscode/extensions/ms-vscode-remote.remote-wsl-0.53.4/scripts/wslServer.sh 622cb03f7e070a9670c94bae1a45d78d7181fbd4 stable .vs
ushio    27685  0.0  0.0   2608   596 pts/1    S+   07:14   0:00 sh /home/ushio/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/server.sh  --port=0 --use-host-proxy --enable-remote-auto-shutdown --print
ushio    27687  0.1  1.2 1022480 76736 pts/1   Rl+  07:14   0:23 /home/ushio/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/node /home/ushio/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/
ushio    27723  0.0  0.6 856768 40184 pts/1    Sl+  07:14   0:00 /home/ushio/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/node /home/ushio/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/
ushio    27777  0.0  1.3 943272 83604 pts/1    Sl+  07:14   0:08 /home/ushio/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/node /home/ushio/.vscode-server/bin/622cb03f7e070a9670c94bae1a45d78d7181fbd4/
ushio    27784  0.0  0.0  10128  5036 pts/3    Ss   07:14   0:00 /bin/bash
ushio    31210  0.0  0.0  10132  5328 pts/5    Ss   10:08   0:00 /bin/bash
root     31317  0.0  0.0  11008  4520 pts/3    S    10:14   0:00 sudo ip netns exec test1 bash
root     31318  0.0  0.0   8960  3908 pts/3    S    10:14   0:00 bash
root     31343  0.0  0.0   3252   764 pts/3    S+   10:20   0:00 nc -kl 11111
ushio    31346  0.0  0.0  10236  5308 pts/6    Ss   10:21   0:00 /bin/bash
ushio    31395  0.0  0.0   8788  3924 pts/6    S+   11:14   0:00 man nc
ushio    31405  0.0  0.0   7596  2232 pts/6    S+   11:14   0:00 pager
root     31416  0.0  0.0  11008  4592 pts/5    S    11:19   0:00 sudo ip netns exec test1 bash
root     31417  0.0  0.0   8960  4000 pts/5    S    11:19   0:00 bash
root     31425  0.0  0.0  10600  3256 pts/5    R+   11:19   0:00 ps aux

このプロセスIDがどのネームスペースに所属しているか見てみます。

ターミナル2
$ sudo ip netns identify 31343
test1

Bash の実行状況を観ます。tty のパートでわかるように、ターミナル1で動いているbash は2つあって、一つが、ネームスペースで実行したものです。

ターミナル2
$ ps -C bash -o comm,pid,lstart,tty
COMMAND           PID                  STARTED TT
bash            27784 Sun Feb 28 07:14:05 2021 pts/3
bash            31210 Sun Feb 28 10:08:49 2021 pts/5
bash            31318 Sun Feb 28 10:14:36 2021 pts/3
bash            31346 Sun Feb 28 10:21:08 2021 pts/6

それは次の比較でわかります。

ターミナル2
$ sudo ip netns identify 31318
test1
$ sudo ip netns identify 27784

ホスト、ルーターの環境構築

実際やりたかったのはこのパートです。WSL2 で動くかな?もともと CKA のコースを受けていた時に、このコマンドの紹介があったのですが、その通りに WSL2 で動かなかったので気になってここでやっている感じです。まずは元のブログ通りの環境を作ってみます。

image.png

ネームスペースの作成

$ sudo ip netns add host1
$ sudo ip netns add host2
$ sudo ip netns add router
$ sudo ip netns list
router
host2
host1

インターフェイスの作成

仮想のネットワークインターフェイスを作成して、対向のネットワークインターフェイスを指定します。もちろん最初なので、DOWN したままです。

$ sudo ip link add name veth-h1 type veth peer name veth1-rt
$ sudo ip link add name veth-h2 type veth peer name veth2-rt
$ sudo ip link | grep veth
76: veth1-rt@veth-h1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
77: veth-h1@veth1-rt: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
78: veth2-rt@veth-h2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
79: veth-h2@veth2-rt: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000

ネームスペースをネットワークインターフェイスに割り当てる

host, host2, router にインターフェスを割り当てます。

$ sudo ip link set veth-h1 netns host1
$ sudo ip link set veth-h2 netns host2
$ sudo ip link set veth1-rt netns router
$ sudo ip link set veth2-rt netns router

IP アドレスの割り当て

$ sudo ip netns exec host1 ip addr add 192.168.100.10/24 dev veth-h1
$ sudo ip netns exec host2 ip addr add 192.168.200.10/24 dev veth-h2
$ sudo ip netns exec router ip addr add 192.168.100.20/24 dev veth1-rt
$ sudo ip netns exec router ip addr add 192.168.200.20/24 dev veth2-rt

インターフェイスの UP

$ sudo ip netns exec host1 ip link set veth-h1 up
$ sudo ip netns exec host2 ip link set veth-h2 up
$ sudo ip netns exec router ip link set veth1-rt up
$ sudo ip netns exec router ip link set veth2-rt up

確認すると、正しく設定されています。

$ sudo ip netns exec host1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0
77: veth-h1@if76: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether aa:9c:34:e9:11:2f brd ff:ff:ff:ff:ff:ff link-netns router
    inet 192.168.100.10/24 scope global veth-h1
       valid_lft forever preferred_lft forever
    inet6 fe80::a89c:34ff:fee9:112f/64 scope link 
       valid_lft forever preferred_lft forever
$ sudo ip netns exec host2 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0
79: veth-h2@if78: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether e6:d6:9a:c7:0e:60 brd ff:ff:ff:ff:ff:ff link-netns router
    inet 192.168.200.10/24 scope global veth-h2
       valid_lft forever preferred_lft forever
    inet6 fe80::e4d6:9aff:fec7:e60/64 scope link 
       valid_lft forever preferred_lft forever
$ sudo ip netns exec router ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/sit 0.0.0.0 brd 0.0.0.0
76: veth1-rt@if77: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 2e:8d:45:ae:d7:b4 brd ff:ff:ff:ff:ff:ff link-netns host1
    inet 192.168.100.20/24 scope global veth1-rt
       valid_lft forever preferred_lft forever
    inet6 fe80::2c8d:45ff:feae:d7b4/64 scope link 
       valid_lft forever preferred_lft forever
78: veth2-rt@if79: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 9e:80:da:c0:3c:2f brd ff:ff:ff:ff:ff:ff link-netns host2
    inet 192.168.200.20/24 scope global veth2-rt
       valid_lft forever preferred_lft forever
    inet6 fe80::9c80:daff:fec0:3c2f/64 scope link 
       valid_lft forever preferred_lft forever

ルーティングテーブルの設定

この手順が前に試したときに抜けていたと思います。ip_forward の設定をしないと、デフォルトでは、IPフォワードをしない設定になっています。

$ sudo ip netns exec host1 ip route add 192.168.200.0/24 via 192.168.100.20 dev veth-h1
$ sudo ip netns exec host2 ip route add 192.168.100.0/24 via 192.168.200.20 dev veth-h2
$ sudo ip netns exec router sysctl -w net.ipv4.ip_forward=1
net.ipv4.ip_forward = 1

Ping

きっちり動作しています。

$ sudo ip netns exec host1 ping  192.168.200.10
PING 192.168.200.10 (192.168.200.10) 56(84) bytes of data.
64 bytes from 192.168.200.10: icmp_seq=1 ttl=63 time=0.055 ms
64 bytes from 192.168.200.10: icmp_seq=2 ttl=63 time=0.065 ms
64 bytes from 192.168.200.10: icmp_seq=3 ttl=63 time=0.056 ms
64 bytes from 192.168.200.10: icmp_seq=4 ttl=63 time=0.057 ms

ルーター機能の確認

tcpdump を使ってルーター機能が正常に動いているか確認します。

ターミナル1
$ sudo ip netns exec router tcpdump -i veth1-rt icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth1-rt, link-type EN10MB (Ethernet), capture size 262144 bytes

Ping を1回送ります。

ターミナル2
$sudo ip netns exec host1 ping -c 1 192.168.200.10

しっかりと、tcpdump で観察できます。

ターミナル1
$sudo ip netns exec router tcpdump -i veth1-rt icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth1-rt, link-type EN10MB (Ethernet), capture size 262144 bytes
11:54:38.197299 IP 192.168.100.10 > 192.168.200.10: ICMP echo request, id 31512, seq 1, length 64

次に、iptable を使って確認します。router の IPテーブルに icmp をフォワードします。

ターミナル1
$ sudo ip netns exec router bash
# iptables -A FORWARD -p icmp
# iptables -nvL FORWARD
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0            icmp --  *      *       0.0.0.0/0            0.0.0.0/0      

1回Pingを送ると、値が変わります。

ターミナル2
$ sudo ip netns exec host1 ping -c 1 192.168.200.10
ターミナル1
# iptables -nvL FORWARD
Chain FORWARD (policy ACCEPT 2 packets, 168 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    2   168            icmp --  *      *       0.0.0.0/0            0.0.0.0/0           

同じブログの方が素晴らしいブログを書いてくれています。iptable や tpcdump についても学ばねばですが、先にもとにやってたことに戻ります。ネットワークはマジ奥深い。コントロール配下に置きたいところ。

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

【3ステップで解説】LinuCレベル1(102試験)に合格するための勉強方法

こちらのURLに移動しました。

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

fishでPowerlineをwsl2上で設定する方法,

fish install

まずはfishをinstallする.ubuntuなら,

sudo apt upgrade 
sudo apt update
sudo apt install fish

次にinstallしたらfishのパスを確認し,デフォルトのシェルに変更する.

which fish
chsh -s /user/bin/fish

設定ファイルなどは以下のディレクトリにある.

.config/fish

パッケージマネージャのinstall

fishermanの場合

curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish

プラグインpeco と zを入れてる.

fisher install oh-my-fish/plugin-peco
fisher install jethrokuan/z
~/.config/fish/config.fish
# ---
# peco
# ---
function fish_user_key_bindings
    bind \cr peco_select_history
end

Powerlineのプラグインを入れてみる.

fisher add oh-my-fish/theme-bobthefish

これを入れるとコンソールの見た目が変わる.ところが,文字化けが発生するためPwerline-fontsをインストールする必要がある.

任意の場所でフォントをインストールする.

git clone https://github.com/powerline/fonts.git
cd fonts
./install.sh
cd ../
rm -r ./fonts

(注意)
これでフォントが設定できるになるはずだが,うまくいかないならgit-hubに公開されているPowerline-fontをダウンロードして右クリでインストールすれば,おなじみのWSLフォント設定画面から設定できます.Notoなど様々なフォントがある.

ブランチを表示させる設定を明示する.

~/.config/fish/config.fish
set -g theme_display_git_master_branch yes

を追記して,fishを再起動させる,

そのほかにも

# ----------
# bobthefish config
# ----------
set -g fish_prompt_pwd_dir_length 0  # ディレクトリ省略しない
set -g theme_newline_cursor yes  # プロンプトを改行した先に設ける
set -g theme_display_git_master_branch yes  # git の branch 名を表示
set -g theme_color_scheme dracula
set -g theme_display_date no  # 時刻を表示しないように設定
set -g theme_display_cmd_duration no  # コマンド実行時間の非表示

参考

以下のサイトを参考にしました.

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