- 投稿日:2021-12-03T20:39:31+09:00
Linuc101メモ
systemdについて systemd:linuxの起動順で言う最後の箇所(カーネルの次) Unit:サービスを管理する単位、設定ファイルの事
- 投稿日:2021-12-03T18:25:17+09:00
Jetson XavierNXにNVMe SSDを増設し高速化する手順
Jetson Xavier NX を SSD で動作させる Jetson xavierNXはM.2に対応しており、NVMe SSD を使用できます。 NVMe SSDを用いることで、実行プログラムをSSD上で全て実行できるため高速化を行うことができます。 Jetson Hacksにあるスクリプトを利用することで、現状の環境を簡単にSSDに移すことができます。 手順を紹介します。 SSDの取り付け 今回は以下の500GBのSSDをJetson XavierNXに拡張しました。 WESTERNDIGITAL ウエスタンデジタル 内蔵SSD 500GB 取り付けた外部SSDが正しく認識していることを確認します。 fdisk -l /devnvme0n1に500GBのSSDがマウントされていることが確認できます。 もしここで表示されていない場合は、取り付けがうまくできていないので確認してみてください。 SSDのパテーションの作成 SSDをetxt4でフォーマットし、パテーションを作成していきます。 パテーション作成しておくことで、予備の領域を残しておきます。 後に実行するコマンドは、パテーションを作成することを前提としています。 そのまま実行したい場合は必ずパテーションを作成しておく必要があります。 ここからはGUI上で操作していきます。 まずdiskアプリを起動します。 500GBのディスクが確認できます。 右上の設定項目からFormat Dsikを選択 compatible with modern systems..に設定 確認されるので、formatを選択 パテーションの作成 +マークを選択し、パテーションのサイズを作成 今回はとりあえず16GBに設定 作成するvolumeの好きな名前を決める 今回はxaviernx500で入力し、create パスワードを聞かれたら入力 以下のようにできていれば成功 SSDへの移行 次にgithubのrootOnNVMe を使用します。 https://github.com/jetsonhacks/rootOnNVMe 以下のコマンドを実行するだけで、 SDカードのルート以下にある全てのファイルをSSDに移動させる。 サービスのセットアップを行う。これにより、.serviceファイルが正しい場所にコピーされ、起動スクリプトがインストールされてrootがSSDに設定されます。 git clone https://github.com/jetsonhacks/rootOnNVMe cd rootOnNVMe ./copy-rootfs-ssd.sh ./setup-service.sh sudo reboot 実行途中の画面 128GBを移行するのにだいたい40分くらいかかりました。 これで、再起動を行うと/dev/nvme0n1p1がルートディレクトリになっています。 /dev/mmcblk0にSDカードが認識されています。 性能確認 hdparmでメモリの読み出し速度を確認したところ10倍以上の速度がでていることが確認できます。 まとめ 簡単にSDカードからSSD上に移行することができました。
- 投稿日:2021-12-03T18:25:17+09:00
XavierNXにSSDを増設して高速化する
Jetson Xavier NX を SSD で動作させる Jetson xavierNxはM.2に対応しており、NVMe SSD を使用できます。 NVMe SSDを用いることで、実行プログラムをSSD上で全て実行できるため高速化を行うことができます。 Jetson Hacksにあるスクリプトを利用することで、現状の環境を簡単にSSDに移すことができます。 SSDの取り付け 今回は以下の500GBのSSDをJetson XavierNXに拡張しました。 WESTERNDIGITAL ウエスタンデジタル 内蔵SSD 500GB 取り付けた外部SSDが正しく認識していることを確認します。 fdisk -l /devnvme0n1に500GBのSSDがマウントされていることが確認できます。 もしここで表示されていない場合は、取り付けがうまくできていないので確認してみてください。 SSDのパテーションの作成 SSDをetxt4でフォーマットし、パテーションを作成していきます。 パテーション作成しておくことで、予備の領域を残しておきます。 後に実行するコマンドは、パテーションを作成することを前提としています。 そのまま実行したい場合は必ずパテーションを作成しておく必要があります。 ここからはGUI上で操作していきます。 まずdiskアプリを起動します。 500GBのディスクが確認できます。 右上の設定項目からFormat Dsikを選択 compatible with modern systems..に設定 確認されるので、formatを選択 パテーションの作成 +マークを選択し、パテーションのサイズを作成 今回はとりあえず16GBに設定 作成するvolumeの好きな名前を決める 今回はxaviernx500で入力し、create パスワードを聞かれたら入力 以下のようにできていれば成功 SSDへの移行 次にgithubのrootOnNVMe を使用します。 https://github.com/jetsonhacks/rootOnNVMe 以下のコマンドを実行するだけで、 SDカードのルート以下にある全てのファイルをSSDに移動させる。 サービスのセットアップを行う。これにより、.serviceファイルが正しい場所にコピーされ、起動スクリプトがインストールされてrootがSSDに設定されます。 git clone https://github.com/jetsonhacks/rootOnNVMe cd rootOnNVMe ./copy-rootfs-ssd.sh ./setup-service.sh sudo reboot 実行途中の画面 128GBを移行するのにだいたい40分くらいかかりました。 これで、再起動を行うと/dev/nvme0n1p1がルートディレクトリになっています。 /dev/mmcblk0にSDカードが認識されています。 性能確認 hdparmでメモリの読み出し速度を確認したところ10倍以上の速度がでていることが確認できます。 まとめ 簡単にSDカードからSSD上に移行することができました。
- 投稿日:2021-12-03T17:45:38+09:00
通信状況が悪いネットワーク環境で名前解決の通信をもなくして負荷軽減を図る
はじめに 少々特殊ではありますが、以下の図のようなネットワーク構成を持つ環境があったとします。 「管理施設」にプロバイダからの終端装置やメインとなるルーター(GW/DHCP/DNS/WiFi AP)がある。 少し離れた位置に「リモートエリアA、B」があり、「管理施設」~「リモートエリアA」~「リモートエリアB」はWiFi APでブリッジ接続している。 各リモートエリアにはIPカメラが存在している。(リモートエリアAには「IPカムA」、リモートエリアBには「IPカムB」) IPカメラからは定期的にクラウド側(上図からは省いています)のAPIを呼び出している。 この環境においてWiFiの状況が少し不安定な状況下ということもあり、上記No4のAPI呼び出しが失敗することがあります。 API呼び出しの失敗にはHTTP通信エラー(タイムアウト)などがありますが、URLに含まれるホスト名の名前解決(正引き)が失敗することもありました。 API呼び出しそのものが失敗すること自体も解決したいところですが、まずはAPI呼び出し前に発生している名前解決が失敗することがあることをどうにかしたいなと思い、その対策について記載していきたいと思います。 解決案 解決案を模索する中で思いつたのが、 DNSキャッシュのTTLを延ばす。 Proxyを立てる。 hostsファイル名にホスト名とIPアドレスを記載し、名前解決にDNSを使わないようにする。 の3つでした。 DNSキャッシュのTTLを延ばす DNSサーバー側で設定しているTTLが5分程度でしたので、これを1日にするなどすれば日中は名前解決を行わなくなります。ただLet's Encrypt+ワイルドカードを利用している関係もあって更新時にその時だけTTLを5分に戻す、などが少々面倒なので却下。(ここでその詳細については省きます) Proxyを立てる 「管理施設」にフォワードProxyを立てれば、名前解決はProxy側で行ってくれますのでIPカメラ自身が名前解決する必要がなくなります(ここも詳細については省きます)ので、IPカメラ自身が名前解決しなくて済むという目的は達成できます。 ただし、 管理施設内に専用の機器が必要。(実はArmadilloやRaspberryPiがあるのでできなくはなかった) フォワードProxyの環境構築が必要。(これも本案を断念した理由の1つ) IPカメラ側にProxy設定が必要。(これも諸事情あり本案を断念した理由の1つ) ということで却下。 hostsファイル名にホスト名とIPアドレスを記載し、名前解決にDNSを使わないようにする この案を実現するためには、 名前解決 hosts作成 hosts転送(配置) が必要になりますが、 名前解決および↑の実現はスクリプトで実施すればよく、管理施設内にはArmadilloやRaspberryPiがありますのでそこで実行すればOK。(既に別のスクリプトも動かしているし) hosts転送だけなら転送量も微々たるもの(数十バイト)で、間隔を数時間~1日などにすれば転送のための通信コストも許容できるのでOK。 IPカメラへ手を加える必要がない。(/etc/hostsを置き換えるだけで即座に解決) ということで諸事情を踏まえこれがベストな案と判断しました。 ただし本案の懸念事項は名前解決順です。 Windows、Mac、Linuxでも名前解決をする優先順序(hostsを使うかDNSを使うか)が決まっています。 名前解決にDNSを優先する設定になっていた場合、その優先順を変更する対応も必要になってきます。(前述した「IPカメラ側にProxy設定が必要。(これも諸事情あり本案を断念した理由の1つ)」相当に近い対応が必要になりそうなので避けたかった) さてIPカメラはどうでしょう? 幸いにも今回のIPカメラはLinuxライクなOSを持つデバイスで、UNIX系OSで各種情報の解決を行うName Service Switch(nss)が利用されていました。そこで /etc/nsswitch.conf を確認してみます。 名前解決順(/etc/nsswitch.confから抜粋) hosts: files mdns4_minimal [NOTFOUND=return] dns mdns 他のLinuxディストリビューションと同じでhostsファイルが優先的に使わているようです。(ここでは"files"が"dns"よりも先に記載されている==hostsファイルが優先的に使われる、とご理解ください) 1口メモ これまでにも /etc/nsswitch.conf を見る機会はありましたが、ふとmdisってなんじゃらほい?と思い立ち調べてみました。 マルチキャストDNSの略のようで、それ自体の仕組みを理解できたのはもとより、Apple謹製のソフトを入れると見かけるソフト/プロセスの名前を見かけ、そういうことかーと納得する場面も。 是非みなさんも調べてみてください。(ということで上記 /etc/nsswitch.conf の内容についても省きます) ということで本案を採用&進めるにあたり懸念点も払拭できましたので実装を進めます。 できたスクリプトが以下です。 スクリプト deploy_hosts.sh #!/bin/bash WORKDIR="/home/pi/tools/deploy_hosts" MAXRETRY=10 # ------------------------------------------------------------------------------ # ホスト(FQDN)リスト # ------------------------------------------------------------------------------ HOSTLIST=( "api-a.secual-inc.com" "api-b.secual-inc.com" ) # ------------------------------------------------------------------------------ # IPカメラリスト # ------------------------------------------------------------------------------ TARGETLIST=( "IpCamA 192.168.1.11" "IPCamB 192.168.1.12" ) # ------------------------------------------------------------------------------ # 二重起動防止 # ------------------------------------------------------------------------------ LOCKFILE=$WORKDIR"/deploy_hosts.lock" if [ -f $LOCKFILE ]; then echo "Already exist lock file. ["$LOCKFILE"]" exit 9 fi trap '{ rm $LOCKFILE; }' EXIT touch $LOCKFILE # ------------------------------------------------------------------------------ # 名前解決とhosts生成と配置 # ------------------------------------------------------------------------------ HOSTS_ORG=$WORKDIR/"hosts" # base hosts HOSTS_NEW=$WORKDIR/"hosts.new" # for work. RESOLVETIME=0 for TARGET in "${TARGETLIST[@]}"; do # ------------------------------------------------------------------------------ # 名前解決とhosts生成 # ------------------------------------------------------------------------------ NOWTIME=`date +%s` echo "RESOLVE="$((RESOLVETIME + 3600))", NOW="$NOWTIME if [ $((RESOLVETIME + 3600)) -le $NOWTIME ]; then echo "UPDATE HOSTS" cp $HOSTS_ORG $HOSTS_NEW for HOST in "${HOSTLIST[@]}"; do RESULT_HOST=`host -4 -R 3 -s $HOST | grep "has address" | sed -e "s/.* has address //g"` NEW_HOST_ENTRY="" for IP in $RESULT_HOST; do echo $IP" "$HOST >> $HOSTS_NEW # use only first entry. ex) 5x.1xx.6x.2x2. break done done RESOLVETIME=`date +%s` else echo "DO NOT UPDATE HOSTS" fi # ------------------------------------------------------------------------------ # 配置 # ------------------------------------------------------------------------------ TARGETMAP=(${TARGET[@]}) TARGETNAME=${TARGETMAP[0]} TARGETIP=${TARGETMAP[1]} echo "##### TARGETNAME="$TARGETNAME", TARGETIP="$TARGETIP ssh-keygen -f "/home/pi/.ssh/known_hosts" -R $TARGETIP > /dev/null 2>&1 ERRCOUNT=0 # deploy while [ $ERRCOUNT -lt $MAXRETRY ] do sshpass -f /home/pi/.ssh/pass_ipcam scp -o "StrictHostKeyChecking no" $HOSTS_NEW root@$TARGETIP:/etc/hosts RESULT_SCP=$? if [ $RESULT_SCP -eq 0 ]; then ERRCOUNT=0 break else ERRCOUNT=$(($ERRCOUNT+1)) fi sleep 30s done done それでは各ロジックについて解説していきます。 各ロジックの解説 ホスト(FQDN)リスト HOSTLIST=( "api-a.secual-inc.com" "api-b.secual-inc.com" ) IPカメラが利用するホスト(FQDN)を列挙しておきます。 IPカメラリスト TARGETLIST=( "IpCamA 192.168.1.11" "IPCamB 192.168.1.12" ) 対象となるIPカメラのIPアドレスを列挙しておきます。 二重起動防止 詳細は以下をご覧ください。 名前解決とhosts生成 # ------------------------------------------------------------------------------ # 名前解決とhosts生成 # ------------------------------------------------------------------------------ ここは分けて解説します。 再解決 NOWTIME=`date +%s` echo "RESOLVE="$((RESOLVETIME + 3600))", NOW="$NOWTIME if [ $((RESOLVETIME + 3600)) -le $NOWTIME ]; then ・ ・ ・ RESOLVETIME=`date +%s` else echo "DO NOT UPDATE HOSTS" fi 冒頭で「WiFiの状況が少し不安定」と書きました。 ひょっとするとhostsの配置がスムーズに上手くいかず、リトライしている間にIPアドレスが変わってしまう可能性があるかもしれませんので、それを視野に入れてある程度時間が経ってしまった場合は再度名前解決するようにしました。 ということで、上記ロジックはその判定です。 名前解決とhosts生成 cp $HOSTS_ORG $HOSTS_NEW for HOST in "${HOSTLIST[@]}"; do RESULT_HOST=`host -4 -R 3 -s $HOST | grep "has address" | sed -e "s/.* has address //g"` NEW_HOST_ENTRY="" for IP in $RESULT_HOST; do echo $IP" "$HOST >> $HOSTS_NEW # use only first entry. ex) 5x.1xx.6x.2x2. break done done 名前解決の方法としてhostコマンドを利用しました。 hostコマンドの結果は以下のようになりますので、その結果からIPアドレスだけを取り出し\$HOSTS_NEWに出力しています。 hostの結果 # ex) result of host command. root@raspberrypi:/srv/deploy_hosts# host api-xxx.secual-inc.com api-xxx.secual-inc.com has address 5x.1xx.6x.2x2 api-xxx.secual-inc.com has address 5x.6x.9x.2x4 複数のIPアドレスが返却される可能性もあるので、1行目を優先的に利用するようにbreakしています。 配置 # ------------------------------------------------------------------------------ # 配置 # ------------------------------------------------------------------------------ ここも分けて解説します。 署名削除 ssh-keygen -f "/home/pi/.ssh/known_hosts" -R $TARGETIP > /dev/null 2>&1 このIPカメラはFW更新でホストのフィンガープリントが変わり、次のsshやscpで警告が出る場合があります。 それを回避するために事前にknown_hostsから該当エントリ(フィンガープリント、公開鍵)を削除しています。 配置 # deploy while [ $ERRCOUNT -lt $MAXRETRY ] do sshpass -f /home/pi/.ssh/pass_ipcam scp -o "StrictHostKeyChecking no" $HOSTS_NEW root@$TARGETIP:/etc/hosts RESULT_SCP=$? if [ $RESULT_SCP -eq 0 ]; then ERRCOUNT=0 break else ERRCOUNT=$(($ERRCOUNT+1)) fi sleep 30s done 生成したhostsを無条件にIPカメラに配置しています。 またリモートエリアを繋ぐブリッジ接続のWiFi APの故障やIPカメラの故障を視野に入れ、ここはリトライ回数に制限を設けることで回避しました。 またここで、 \$HOSTS_LASTと\$HOSTS_NEWを比較し、異なる場合のみ配置したのでいいのでは? IPカメラのhostsと比較して、違いがある場合だけ配置したのでいいのでは? という疑問もでるかもしれません。 前者については、リトライとリトライの中断にも関係しますが、成功するまでリトライをし続けている訳ではありませんので、IPカメラのhostsファイルが\$HOSTS_NEW に更新されていないことを視野に入れる必要があります。また\$HOSTS_LASTと\$HOSTS_NEW に違いが出るまで配置処理が走らないことにも視野に入れる必要があります。 また後者については、IPカメラ側のhostsとローカルの\$HOSTS_NEWとを比較する通信コストを考えた場合、そもそも\$HOSTS_NEW のサイズは数十KB でもあるので一律無条件に配置してしまった方が通信コストは低い、と判断したためです。ですのでここは \$HOSTLIST のエントリ数に応じて変更する必要が出てくるかもしれません。 補足 必要に応じてIPカメラのhostsをバックアップした方がよいケースもあるかと思います。 IPカメラのhostsバックアップ # backup while [ $ERRCOUNT -lt $MAXRETRY ] do RESULT=`sshpass -f /home/pi/.ssh/pass_ipcam ssh -o "StrictHostKeyChecking no" root@$TARGETIP "[ ! -e /etc/hosts.org ] && cp -rp /etc/hosts /etc/hosts.org || ls -la /etc/hosts*"` RESULT_SSH=$? # echo "SSH="$RESULT_SSH if [ $RESULT_SSH -eq 0 ]; then ERRCOUNT=0 break else ERRCOUNT=$(($ERRCOUNT+1)) fi sleep 30s done その場合は、上記に記載のスクリプトの ERRCOUNT=0 # deploy の "ERRCOUNT=0" と "# deploy" の間に上記のバックアップロジックを入れ、 ERRCOUNT=0 # backup while [ $ERRCOUNT -lt $MAXRETRY ] do ・ ・ ・ done # deploy とするとよいです。 定期実行(cron) 最後にcronに以下の設定を行い定期的に実施するようにします。 例1(1時間毎) 0 */1 * * * /home/pi/tools/deploy_hosts/deploy_hosts.sh 例2(4:00と14:00の1日2回) 0 4 * * * /home/pi/tools/deploy_hosts/deploy_hosts.sh 0 14 * * * /home/pi/tools/deploy_hosts/deploy_hosts.sh
- 投稿日:2021-12-03T16:16:09+09:00
systemd環境でMySQL8のrootパスワードを初期化する方法
Amazon Linux2で、MySQL8を運用していて軽くハマったので備忘録 rootのパスワードが分からなくなってリセットしようとググると、ほとんどの記事が「mysqld_safeで起動しなおして云々」というモノなのだが、systemdを採用しているディストリビューションだと「mysqld_safe」がインストールされないらしい。 そこで、もうちょっと調べて見つけた解決方法。 [root@hostname ~]# systemctl set-environment MYSQLD_OPTS="--skip-grant-tables" [root@hostname ~]# systemctl restart mysqld [root@hostname ~]# mysql -u root これでrootでログイン出来るので、rootのパスワードを削除します。 mysql> use mysql Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> UPDATE user SET authentication_string=null WHERE User='root'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> 次に、パスワードの再設定を行いますが、先程の「--skip-grant-tables」が設定されたままだと、パスワードの再設定が許可されていません。 なので、環境変数を削除した後にmysqldを再起動します。 mysql> exit Bye [root@hostname ~]# systemctl unset-environment MYSQLD_OPTS [root@hostname ~]# systemctl restart mysqld [root@hostname ~]# 再起動完了後に、再びmysqldに接続しパスワードを再設定します。 [root@hostname ~]# mysql -u root mysql> ALTER USER 'root'@'localhost' identified BY '設定するパスワード'; Query OK, 0 rows affected (0.00 sec) mysql> パスワード変更コマンドを実行した時に、 Your password does not satisfy the current policy requirements とエラーが出た場合は、パスワードポリシーが厳しいので怒られています。 おそらく「最短8文字、ローマ字小文字、ローマ字大文字、数字、記号、すべて混在」というポリシーになっているかと思います(頑張ってください)。 これで、systemd環境のMySQL8でルートのパスワード変更が出来ると思います。
- 投稿日:2021-12-03T13:11:59+09:00
bash実行結果をvimで開く
なにかのコマンドをbashで実行した結果を編集したい場合、一旦結果をリダイレクションなどでファイルに保存し、そのファイルをvimで開いて編集していたが、なんかもう面倒くさくなったので、結果をそのままvimで開くスクリプトを書いた。 もうすでにあって、盛大に車輪の再発明をしている感はナキニシモアラズなのだが、自分の備忘録としてポエムとして残しておく。 #!/usr/bin/env bash if [ "$1" = "" ]; then echo "Usage:" echo `basename $0`" [execute command]" exit 1 fi CMD="" for c in $@; do CMD=$CMD" "$c done vim <($CMD)
- 投稿日:2021-12-03T13:11:59+09:00
bashコマンド実行結果をvimで開く
なにかのコマンドをbashで実行した結果を編集したい場合、一旦結果をリダイレクションなどでファイルに保存し、そのファイルをvimで開いて編集していたが、なんかもう面倒くさくなったので、結果をそのままvimで開くスクリプトを書いた。 もうすでにあって、盛大に車輪の再発明をしている感はナキニシモアラズなのだが、自分の備忘録としてポエムとして残しておく。 ※ コメントで遠回りを指摘していただいたので修正。 #!/usr/bin/env bash if [ "$1" = "" ]; then echo "Usage:" echo `basename $0`" [execute command]" exit 1 fi vim <("$@")
- 投稿日:2021-12-03T09:22:16+09:00
Dockerを支えるLinuxのコンテナ技術
はじめに こんにちは、最近パラパラチャーハンが作れるようになりました。コツは「ご飯の量と同じくらいみじん切りにした野菜を入れて誤魔化す」です。 はい、ということで今回はDockerはどうやって作られているのか気になって調べたことをまとめていきたいと思います。実際の細かい動きはどうしても図とかないと分かりにくいと思うので、その辺は参考になった記事を紹介していきます。 前提知識 Dockerは Linux が提供するコンテナの技術を使用して実現しているため、前提知識としてLinuxの基本的な知識が必要です。今回はその説明は省きますが、以下の本がすごく分かりやすかったので是非読んでみてください。忙しい人は、自分がこの本を読んでまとめていたものがあったのでもし興味があればそちらをご覧ください。 最初に読むといい感じの本 個人的にまとめたもの 余談ですが次に読むといい感じの本も紹介しておきます。Linuxについて調べれば調べるほどC言語と仲良くなれると思うので、C言語に苦手意識のある方はLinuxから入るといいかもしれないです。(C言語が書けるようになる訳ではないですが、確実にC言語に対するイメージが変わると思います。) 次に読むといい感じの本 コンテナの実態 コンテナは名前からしてもよく箱のようなイメージを持つことが多いですが、実際は任意の範囲でプロセスやNamespaceなどを区切って、その区切った範囲でどのくらいのリソースを利用できるのか設定しています。コンピュータ内で論理的(仮想的)に環境を区切って(隔離して)おくことで例えば以下のようなことができます。 自分のパソコンの環境を汚さなくて済む 簡単に環境を構築したり、破棄したりできる 上記で隔離という用語が出てきましたが、具体的に何を隔離していて、何を設定しているのか定番のやつを紹介します。 補足)自分のPCの環境をホストと呼び、PCの環境を論理的に区切った範囲内のことをコンテナと呼ぶようにします。あと、隔離=「(論理的に)区切る」と読み変えると分かりやすいかもしれないです。 UTS名前空間 ホスト名、ドメイン名。これを隔離することでホストから見たホスト名とコンテナから見た方ホスト名を別のものにすることができます。言い方を変えるとホスト側とコンテナ側のホスト名を別々に設定できます。 PID名前空間 PIDとはプロセスIDのことです。通常、プロセスIDはプロセスが生成されるごとにカーネルにより一意の数値が割り当てられますが、隔離をすることでホストとコンテナそれぞれでそれぞれのPIDを割り当てることができます。そのため、ホストとコンテナで重複する値を設定することができたりします。例えば、コンテナのあるプロセスのPIDが3でもホストから見るとそのプロセスのPIDは8に設定されているみたいなことになっています。 ネットワークインターフェース 基本的にコンテナごとに仮想的なネットワークインターフェースを付与しておきます。ネットワークインターフェースとはインターネットの入り口で、有線LANポートとかWi-Fiが入ってくる入り口をイメージするといいと思います。このインターフェースによってコンテナでパケットを受信(ネット接続)することができます。 コンピュータのリソース プロセスなどを隔離したら、その隔離した範囲でどのくらいのリソース(メモリ、CPU)を使えるのか設定をします。コンテナ1ではメモリを1GB使えて、コンテナ2ではメモリを2GB使えるみたいなことができます。 ファイルシステムの分離 基本的に一つのコンテナにつき一つのルートディレクトリを持っています。docker exec -it コンテナ名 bashとかしてdockerでコンテナに入ったときに、シェルのプロンプト変わりますよね。あれです。あれはルートが変わっていて、シェルの設定ファイルがないためにプロンプトに色とかがついていないです。コンテ内でpwdコマンドを実行してみてもホストとは違う結果が得られるのもルートが変わっているからです。でも、Dockerファイルで指定した作業ディレクトリとかアプリケーションの動作に必要なファイル(nodejsとか)とかはありますよね。ルートを変えることでルートディレクトリの構造を必要最低限ごっそり持ってきてそこに必要なファイルのみを置いていくことができます。また、コンテナを破棄するときもそのコンテナのルートディレクトリを削除するだけで綺麗さっぱり、コンテナ内のアプリの動作環境に必要なファイルたちを消すことができます。 Linuxのコンテナ技術 コンテナの実態がなんとなく掴めたところで、次はそれを実際にどうやって実現しているのか気になってくると思います。答えは、Linuxから提供される機能を使ってコンピュータ内で環境を区切っています。 NameSpace: UTS、PID、ネットワークなどの名前空間を分離します。 ControlGroupe: リソースを設定します。 FileSystem: 必要なファイルをマウントします。 Chroot: ルートディレクトリを変更します。 具体的なLinuxの機能の説明はこちらの記事をご覧ください。(丸投げ笑) 実際にどうやって実装してくのか気になって調べたら以下の記事たちを見つけました。 Containers From Scratch • Liz Rice • GOTO 2018 ライブコーディングでGoによりdockerを作っています。これを見るとなんとなくコンテナの実装イメージができると思います。この動画の日本語の解説がありました↓ 【Go言語】自作コンテナ沼。スクラッチでミニDockerを作ろう - カミナシ開発者ブログ docker内でLinux環境を作り、そこで自作Dockerを体験することができます。 Fewbytes/rubber-docker pythonでdockerを作るワークショップらしいいです。難しめ。がっつり作っていく感じ。 OverlayFS OverlayFSというLinuxが提供してくれるファイルシステムをdockerでは使っているみたいです。このファイルシステムを使うことでコンテナのファイルを効率よく管理できます。OverlayFSは何者でdockerでどうやって使われているかは以下の記事がわかりやすかったです。タイトル通り世界一わかりみが深いと思います。 【連載】世界一わかりみが深いコンテナ & Docker入門 〜 その6:Dockerのファイルシステムってどうなってるの? 〜 | SIOS Tech. Lab Network 以下の記事ではdockerコンテナがどうやってネット接続しているのか解説してくれています。仮想スイッチとか仮想NICとかはLinuxの機能で用意していることになります。僕たちが Docker for Macをインストールしたときには自動で物理NICから仮想スイッチまでの経路は用意してくれているみたいですね。またdockerでコンテナを作った時はそのコンテナにくっつける仮想NICを生成して仮想スイッチに接続するみたいなことを透過的にやってくれてるみたいです。 【連載】世界一わかりみが深いコンテナ & Docker入門 〜 その5:Dockerのネットワークってどうなってるの? 〜 | SIOS Tech. Lab 最後に 今回自分は 「docker自作したい => Linuxを調べる => C言語いいかもしれない」 みたいな感じで今まで苦手意識のあったC言語に興味を持つことができました。自分があまり興味を持てない部分は自分の知識不足で発生するパターンがあるんだなと思いました。興味を持てる範囲から少しずつ知識を増やしていこうと思います!最後に書くことが思いつかなくて大学の実験レポートくらいの真面目度になってしまいましたが、最後まで読んでいただきありがとうございました!
- 投稿日:2021-12-03T04:49:14+09:00
ユーザー名を日本語にしてしまったときにjupyter-notebookを使えるようにする/WindowsでLinuxを使うとき
経緯 僕は素人なので、長期的にパソコンを使っていた時、画面全体が点滅して使えなくなってしまった。 なので初期化した。 すると、(やっぱり素人なので)、色々インストールしたものが消えてしまい、トラブルに直面したときにちょちょいと調べて解決したことの後追いをしなくてはならなくなった。 例えば ・Anacondaの環境構築はどうやってたっけ? ・jupyternotebookってどう使ってたっけ? というトラブルにあった。 jupyter notebook jupyternotebookはオープンソース上で、pythonコードなどを実行できるWebツールである。 セルブロックごとにコードを書くことができる。 特に出力がセルブロックで表示できるので見やすい。 ただし、ユーザー名を日本語にすると、エンコードの関係か?、 Bad file descriptor (bundled\zeromq\src\epoll.cpp:100) とか表示されてKernelの起動(?)が停止される。 (そもそもユーザー名を日本語にしてしまうのが、すごくセンスのないことらしい。トホホ・・・) 解決方法としては・・・ 解決方法としては、新しいユーザーを作ってしまうのが1つ。 ところが、jupyter notebookを使うためだけにユーザーアカウント1つ作るのもなあ・・・ ということで「前は上手く使ってたはず・・・、どうやってやってたっけ」と思考を巡らす そうだ。Ubuntu上で起動してたっけ。 UbuntuというOSはUNIXからLinux、Debianと派生してDebianを元に作られたOSです。 まあUbuntuはWindowsでLinuxコマンドを使えるようにするためのオペレーションシステム(OS)です。 そこならディレクトリがLinux用なので、ホームディレクトリを新たにアルファベット指定でjupyter notebookが起動できる。 僕の様に初期化した場合 Windowsコマンドを押してubuntuと入力して開くと、 「開けないから、なんかキーを押して閉じてね」(意訳) と表示される。 あれれ~、おかしいぞ~ ということでアンインストールして再インストール... 結果は同じ。 ちゅうことで調べなおし。 Windows for Linux 要は、もう一つ橋渡しが必要ということらしく、wslというモジュールをインストールする必要がある。 皮がUbuntuで実がWSLってことかな(多分。) wsl: Windows sunsystem for Linux conda install wsl もしくは pip install wsl 引用 仮想マシンというものは、Windows 10マシン上で別のPCを動かしているようなイメージです。Linuxを動かすために別のPCを用意するような形となり、起動や動作に時間がかかります。また、仮想マシンは別のPCと同様に扱うため、Windows 10側のアプリケーションとはネットワークなどを介してやりとりを行います。WSLは仮想マシンを使わずWindows 10上で直接Linuxを実行することができるため、起動や動作にかかる負荷が少なく済みます。 また、WSLを使用すると、Windows 10の全てのファイルやフォルダにアクセスができます。 WSL 1は「サブシステム」という、異なるOS環境を実現するための仕組みを使用しています。このサブシステムがLinuxのカーネルへのファンクションコールをWindowsのカーネルファンクションコールに変換して疑似的なLinux環境を実現しています。WSL 1では、Linux実行環境をLinuxカーネルではなく、サブシステムの「LXCore」によって実装しているため、一部のLinuxアプリケーションやユーザーファイルシステムなどを動かすことができません。 Windowsの機能の有効化 左下の検索窓からコントロールパネルと入力、プログラム、Windowsの機能の有効化または無効化とクリック そして Windows subsystem for Linux もしくは Linux用のWindowsサブシステム 仮想マシンのプラットフォーム のチェックボックスにチェックを入れる。 再起動を求められるので、再起動します。 WSLのデフォルトバージョンをWSL2にする(オプション) 今後インストールするLinuxディストリビューションのデフォルトをWSL2にするには、コマンドライン(PowerShellまたはコマンドプロンプト)で以下のコマンドを実行します。 PowerShell wsl --set-default-version 2 そして 初回起動時は少し待つと初期設定が始まるので、ユーザー名とパスワードを入力する。ユーザー名とパスワードを入力後、Linuxの実行環境して使用できる。 次に python sudo apt update sudo apt upgrade ※もしもエラーが生じたら以下の記事を参考に。 https://qiita.com/koara-local/items/e63b7e4ff3cea803bdea http://inside-my-box.hatenablog.com/entry/2015/05/29/013008 $ sudo rm /var/lib/apt/lists/lock $ sudo rm /var/lib/dpkg/lock ※終わり jupyter notebookを起動 sudo apt install python3-pip python3-pandas python3-sklearn sudo apt install jupyter-notebook #Jupyter Notebookの起動(自動的にブラウザが立ち上がりJupyter Notebookが起動する) $ jupyter-notebook 日本語化の手順 \\ 日本語パッケージを導入 $sudo apt install language-pack-ja-base language-pack-ja ibus-mozc \\ 文字セットを日本語に変更 $ localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja" $ source /etc/default/locale