タイトルの通りです。 例えば.bibファイルで以下の様にurlパッケージを使っていた場合、
@misc{dockerhub, title = {Docker Hub}, note = {\url{https://hub.docker.com/}} }
.texファイル中で以下のようにusepackageしなくて引用が「?」になりました。
\usepackage{url}
低レイヤー系大学院生のブログ
「車輪の再実装」って言葉が好き(実践はできてない)
paramikoは、SSHの為のPythonライブラリです。 paramikoを使うことで、認証情報の管理、接続、そしてリモートでのコマンドの実行等を行うことができます。
例えば以下のようにすることで、リモートでコマンドを実行できます
from paramiko import SSHClient client = SSHClient() client.load_system_host_keys() client.connect('ssh.example.com') stdin, stdout, stderr = client.exec_command('sleep 1000') # この実行自体はすぐに返る
細かい使い方は公式ドキュメント等を参考にしてください。
さて、上記様なコマンドを途中で中断、終了するためにはどうすれば良いでしょうか? まず、最も簡単なのは、clientをcloseすることです。
しかし、何らかの方法でclientをcloseしたくない場合、以下のようにしてCtrl+cを実現できます 以下の2つが要点になるのでそれぞれ見ていきます。
\x03
)の送信疑似端末を取得(割当)することで、通常ターミナルを使って作業するときのようにプロセスを振る舞わせる事ができます。 こうすることで、Ctrl+C(相当の値)を受け付けるようになります。
具体的には exec_command
時に get_pty=True
を付与することでできます。
stdin, stdout, stderr = client.exec_command('sleep 1000', get_pty=True)
\x03
)の送信以下のようにすれば可能です。
print('\x03', file=stdin, end='')
上記の例では SSHClient
クラスを用いた例を示しましたが、
その内部で使われているChannel
クラスを用いた場合も要点は同じです。
ただし、具体的には以下のような手順を踏む事になります。
chan.get_pty() # オプションとしてではなく、独立したコマンドとしてptyを取得 chan.exec_command(...) 中略 chan.send('\x03') # ファイルオブジェクトに対してではなく、直接データ送信
この記事は、東京大学 品川研究室 Advent Calendar 2020及びDocker Advent Calendar 2020の2日目の記事として書かれました。
Docker Advent Calendar のネタですが、Dockerは使わないという若干本末転倒気味な小ネタです。 (あまり埋まってない様子だったので、これでも許されるはず...)
閑話休題、僕はコンテナイメージを研究対象としているとしているのですが、時々コンテナランタイムなしでコンテナイメージをマウントしたくなることがあります。
moby プロジェクトで公開されている download-frozen-image-v2.sh というシェルスクリプトを使うと、 docker image save
で出力されるtarを展開した形で、コンテナイメージをDockerHubから取得する事ができますが、これだと若干不便です。
というのも、この形式でダウンロードできるのは、それぞれのレイヤーやコンフィグ、マニフェスト等をまとめたもで、直接ファイルを触ることができないのです。
マニフェストの中身を元に、各レイヤー(tarball)を展開し、mount
コマンドを使って overlayfs としてマウントすればやりたいことはできるのですが、面倒です。
というわけで以下のようなpythonスクリプトを書いてみました。
使い方はこんな感じです↓
$ wget https://raw.githubusercontent.com/moby/moby/master/contrib/download-frozen-image-v2.sh $ chmod +x download-frozen-image-v2.sh $ wget https://gist.githubusercontent.com/progrunner17/5337c83a799dc5baa9fd4bd6f5ce1170/raw/5e6dbddc2da32bf7136a13f29553f53e2f799625/stack_layers.py $ chmod +x stack_layers.py $ ./download-frozen-image-v2.sh nginx_dir nginx:latest $ cd nginx_dir $ ../stack_layers.py mnt image nginx:latest was mounted on /path/to/workdir/nginx_dir/mnt $ ls ./mnt/docker-entrypoint.d 10-listen-on-ipv6-by-default.sh* 20-envsubst-on-templates.sh*
スクリプトを読むと分かることですが、--workdir
と --upperdir
を指定すると書き込み可能になったり、
-v
オプションを付けると、内部で実行しているコマンドが表示されたりします。
mountコマンドかoverlayfsの仕様なのか?lowerdirが1つでかつupperdir等が設定されていないとマウントに失敗したり、 procfs等がマウントされていなかったりと不便はありますが、少ない依存で動くので重宝しています。
download-frozen-image-v2.sh なしで、pythonスクリプトだけで完結させたいなーとは思っていますが、 それもそれで若干の手間なので、しばらくこのままキメラ的に使う状況は続きそう...
Ubuntu18.04で python3
パッケージをインストールするとデフォルトでは python3.6
が入ります。
ただ諸事情で新しいバージョンを使いたくなったので、python3.8
パッケージをインストールして、 update-alternatives
を使って python3
コマンドを使った際に呼び出されるバージョンを変更してみたところ、後述のようにaptが壊れてしまいました。
デフォルト以外バージョンのpythonを使いたいときは、おおちゃくせずにpyenvとかを使いましょうという教訓。
前述のようにpython3のバージョンを変えて使っていたら、以下のように「apt_pkgモジュールが無いよ。」とaptに怒られました。
$ sudo apt update 中略 Traceback (most recent call last): File "/usr/lib/cnf-update-db", line 8, in <module> from CommandNotFound.db.creator import DbCreator File "/usr/lib/python3/dist-packages/CommandNotFound/db/creator.py", line 11, in <module> import apt_pkg ModuleNotFoundError: No module named 'apt_pkg' 後略
というわけで、 python3-apt
をインストールしたら以下のようにエラーが...
$ sudo apt install python3-apt 中略 Setting up python3-apt (1.6.5ubuntu0.3) ... /usr/lib/python3.8/subprocess.py:838: RuntimeWarning: line buffering (buffering=1) isn't supported in binary mode, the default buffer size will be used self.stdin = io.open(p2cwrite, 'wb', bufsize) 後略
どうやら標準パッケージである io
の挙動が変化したらしい?
雑にpyenvを使うとコンパイルに時間がかかって面倒だったので update-alternatives
を使いましたが、
おとなしくpyenvを使うことにして問題を回避しました。
...というタイトルのものの、実際は既存のlinuxブリッジにlibvirtの仮想マシンをつなげる方法です。
特に設定をしていなければdocker0
のはずですが、
以下の様にして調べても大丈夫だと思います。
docker network inspect <ネットワーク名>
以下の様にすれば取得できます. ただし、defaultの部分はVagrantfileで定義(していれば)した名前になるはず。
virsh domname $(cat .vagrant/machines/default/libvirt/id)
virsh edit 取得した名前
で、仮想マシンの定義ファイルを開き
<interface type='bridge'> <source bridge='dockeのブリッジ名'/> ... </interface>
とすると、仮想マシンに新たなインターフェースが追加されます。 (もしかすると、VMの再起動が必要かも?)
前の手順でつないだインターフェースにはアドレスが割り振られ無いので、 仮想マシン内部で自分でIPアドレスを設定します。(172.17.0.100等)
デフォルトルートもコンテナのネットワークと同じ様にすればいい感じで使えそう。
まず、あらかじめ入りたいコンテナのIDか名前を取得しておき、以下の様な手順で入れる。
pid=$(docker inspect <コンテナのIDか名前> --format '{{.State.Pid}}') sudo mkdir -p /var/run/netns sudo mount --bind /proc/${pid}/ns/net /var/run/netns/<名前(任意)> sudo ip netns exec <名前> bash
基本的にホストのソフトをそのまま使えるので、ipやping等をそのまま使えて便利。
ただし、自分でunmountし無い限り、docker上でコンテナを消しても名前空間が残り続けるので注意。
ちなみに、残っている場合は、
sudo ip netns list
とすると、自分で指定した名前が見えるはず。
www.mankier.com デフォルトでついているページ内検索が優秀だったり、デザインが一番モダンな感じで個人的に一番好き。対応しているページも多い気がする。 ただSEOの問題か、google検索してこのサイトに飛ぶことは少ない。
linux.die.net ちょっとマニアックなページをgoogle で検索すると出てくるイメージ
man7.org おそらく一番オーソドックスなページ。
manpages.ubuntu.com
Ubuntuのmanページ。
おそらく、各バージョンに対応したページが出てくるはず。
たまに、新しいmanを参照していて実際の挙動と違う...みたいなことがあると、このページで対応したバージョンを見る。