brand new note

ジャズ屋が技術の話をするところ

オブジェクトキャッシュってなに

webサーバで使われるキャッシュの話をしたく。

memcacheredis が有名

Redis とMemcached | AWS

memcached.org

redis.io

これらはオープンソースのインメモリデータストア(ディスクではなくメモリ内にキャッシュする技術)。有効化することによってディスクベースのDBよりも迅速にデータを読み込むことができる。 redis, memcachedを利用する際にはwordpresプラグイン等ができている場合には有効化のスイッチを押すだけでいいんだけど、もしそうでなく自前で利用したい場合には少々コードを書く必要がある。が、最小限で動くように設計されてはいる。 データを複数ノードに分散することもできる(おそらく別々のメモリに同時にデータをキャッシュしても正しく動作するように設計されているという意味だと思われる)。つまりスケールアウトが可能。

JavaPythonPHP、C、C++C#JavaScript、Node.js、Ruby、Goなどで動かせる。加えてredisは、String に加えて、List、Set、Sorted Set、Hash、Bit Array、HyperLogLog をサポートしている。一方でmemcachedはマルチスレッドであるため、コアを複数使ってより多くの操作を処理できるメリットがある。

その他にも機能や長所短所はあるらしいので詳しくは上のリンクを読んでみてください。

wordpressでの実装について

LS cache pluginの場合は構築しているサーバ上でMemcachedとredisがそれぞれ利用可能なのかがステータスとして表示されている。使える場合にはボタンスイッチで有効化できる。ホスト、ポート、キャッシュされたオブジェクトのデフォルトのTTL(メモリに残存する時間)、ユーザ名、パスワード、redisの場合データベースID、NWレベルでキャッシュされたグループ(いくつかある)のキャッシュの選択、キャッシュしないグループの選択、wp-adminのキャッシュ、キープアライブ機能を使ったmemcachedの高速化などを利用することができる。

topコマンドの込み入った使い方

topって見るだけで終わりやすいのでいじって何ができるのか試してみた。

画像で見比べる記事が欲しかったので書いた所もある。

f:id:frazz:20210605102244p:plain

1

CPUコアごとの使用率を表示できる。

f:id:frazz:20210605102453p:plain

2

NUMAをサポートしている場合NUMAノードごとの使用率を表示できる*1

f:id:frazz:20210605104148p:plain

z

カラーマッピングの設定をONにする。見やすいね(?)

f:id:frazz:20210605114253p:plain

Zで設定を変更できるのでもう少し見やすくできそうではある。

b

bold。running tasksの訳が微妙にわからないけど、今CPUが処理しているプロセスにマーカーを引くってことだろうか。よく適当にbを押して自分出来てる感を演出したくなるのでこれはしっかり理解しておきたいところ。

f:id:frazz:20210605114823p:plain

B

boldをenableにする。マーカーだけだと思ってたら単に太字にする機能もあるらしい。こっちのがシンプルだしこれありきのマーカーなんだろうね。マーカーはmanでは"bold"と記載してるので、そういうことだとおもう。

f:id:frazz:20210605115733p:plain

f

Filelds management。これびっくりしたんだけど、いつも見ている出力はもっと自分が見やすくしたいようにカスタムできるらしい。試しに説明の通りCOMMANDを一番上に持っていくと、こんな感じになった。

f:id:frazz:20210605120215p:plain f:id:frazz:20210605120226p:plain

全部有効化してみる

ああ〜

f:id:frazz:20210605120952p:plain

見切れるくらいなら最初から/proc見ればいいんじゃないかという気持ちになった。

ちなみに

こんな遊び方をしても一回デタッチすると元の出力に戻るので安心してほしい。でも、遊びじゃなくとも恒久的に出力を自分好みにするための編集ファイルがあるほうがなにかと便利なはずだ。探してみた。

haydenjames.io

When you save using W, notice top will display the path to the file it creates to save custom settings.

これだ。Wで保存する。

f:id:frazz:20210605124141p:plain

いえす!ファイルを確認する。

ekp@ekp-ThinkPad-X1-Carbon-3rd ~/.c/procps> head toprc
top's Config File (Linux processes with windows)
Id:i, Mode_altscr=0, Mode_irixps=1, Delay_time=2.0, Curwin=0
Def fieldscur=�������ķ��Ŧ���������������������������������������������_`abcdefghij
    winflags=193844, sortindx=18, maxtasks=0, graph_cpus=0, graph_mems=0
    summclr=1, msgsclr=1, headclr=3, taskclr=1
Job fieldscur=�����(��Ļ�@<��)*+,-./012568>?ABCFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghij
    winflags=193844, sortindx=0, maxtasks=0, graph_cpus=0, graph_mems=0
    summclr=6, msgsclr=6, headclr=7, taskclr=6
Mem fieldscur=���<�����MBN�D34��&'()*+,-./0125689FGHIJKLOPQRSTUVWXYZ[\]^_`abcdefghij
    winflags=193844, sortindx=21, maxtasks=0, graph_cpus=0, graph_mems=0

うーんなんか若干文字化けしてるけどこれは別問題。

意外と簡素にまとまっていて、filelds managementでいじれる設定がこれを見る限りだとわからない。アルファベットが順に続いてるのはおそらく押して設定変更ができるキーのことを指してるんじゃないかと思う。このファイルをいじってカスタムするよりかは、topの実行中に好き勝手にやってみていいところで保存してくださいってことだろう。ともあれこれでtopを再度使っても自分好みの設定が持ち越されるようになった。デフォルトに戻したかったらファイルを消すだけだ。

s

脱線した。デフォルトでは3秒間隔でもろもろ出力されるけど、このインターバルはsで変更できる。きりがいいのでデータ取るときは1秒とかにすることがある。

f:id:frazz:20210605125915p:plain

n

デフォルトでは動作するすべてのプロセスを表示するようになっているけど、上位だけ表示することもできる。出力が減ると何が割りを食っているのか確認しやすい上に、ファイルに出力するときのデータサイズが軽くなるといったメリットがある。15から10にするときはこんな感じ。デフォルトは0、すなわち無制限である。

f:id:frazz:20210605130827p:plain

V

プロセスをツリー状に表示する。apacheとか使うとこの恩恵が多少わかるかもしれない。なんでVかと言われれば木っぽいからである(覚えられればいい)

f:id:frazz:20210605133940p:plain

m

メモリ使用率をバーで表示する。ここをどうするかは、ちゃんと使用量のデータを数値で取りたいか、その場で直感的に理解したいかで決めればよいと思う。普段使いならこっちのほうがかっこいいよね。

f:id:frazz:20210605131151p:plain

まあかっこよさだけならhtop使えって話ではあるんだけど。

最後に

こういう「出力が見えてから特定のコマンドを打ち込む操作」を「インタラクティブコマンド=対話コマンド」というらしい。manを見つけたので整形して再アップしてみた。テキスト探すの面倒じゃないみなさんはman読んでくれれば十分なんで、これが意味のある仕事かといわれればnoですけど、個人的に編集してて楽しかったので、型は今後につながるんじゃないかなあ、くらいに思ってます。

github.com

ubuntuにdockerをインストール - 2

前回:ubuntuにdockerをインストール - brand new note

先日半分までやってみて後半をやっていなかったのでやりながらメモ。

Ubuntu 20.04へのDockerのインストールおよび使用方法 | DigitalOcean

参考はこれ。まず前回作ったubuntuのコンテナイメージにログイン。

ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker run -it ubuntu
root@b2421f52ba91:/# 

アプリケーションのインストール

ここでは例としてnodejsをインストールしてる。
何に使うんですかと言われると困る。

root@b2421f52ba91:/# apt install nodejs
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package nodejs
root@b2421f52ba91:/# sudo apt update
bash: sudo: command not found
root@b2421f52ba91:/# 

あれ?コンテナはsudoないんだね。いらないねよく考えたら

root@b2421f52ba91:/# apt update
Get:1 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]
Get:2 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB]
Get:3 http://security.ubuntu.com/ubuntu focal-security/restricted amd64 Packages [297 kB]
root@b2421f52ba91:/# apt install nodejs

これで入った。途中でタイムゾーンを聞かれたのでtokyoとした。
バージョンを確認する。

root@b2421f52ba91:/# node -v           
v10.19.0

コンテナの管理

ログアウト。docker psで実行中のコンテナイメージが確認できる。

root@b2421f52ba91:/# exit
exit
ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

普通にexitするとコンテナはシャットダウンするようになってるのでここではなにも出力されてない。-aを追加すると未実行のコンテナイメージも含めてイメージの状態を確認できる。

ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker ps -a
CONTAINER ID   IMAGE         COMMAND       CREATED          STATUS                      PORTS     NAMES
83ef15493b01   ubuntu        "/bin/bash"   10 seconds ago   Exited (0) 4 seconds ago              exciting_einstein
b2421f52ba91   ubuntu        "/bin/bash"   22 minutes ago   Exited (0) 8 minutes ago              nifty_wright
e09ccc2414db   ubuntu        "/bin/bash"   29 minutes ago   Exited (0) 29 minutes ago             admiring_sanderson
6d9d8508a9ca   ubuntu        "/bin/bash"   30 minutes ago   Exited (0) 30 minutes ago             charming_swartz
5f9574e596e0   ubuntu        "/bin/bash"   30 minutes ago   Exited (0) 30 minutes ago             admiring_chaplygin
ca738446dafa   ubuntu        "/bin/bash"   6 days ago       Exited (127) 6 days ago               epic_feynman
63ab6e895499   ubuntu        "/bin/bash"   6 days ago       Exited (0) 6 days ago                 recursing_ramanujan
937c1efdf209   ubuntu        "/bin/bash"   6 days ago       Exited (0) 6 days ago                 confident_wu
ab2f5e6adf0e   hello-world   "/hello"      6 days ago       Exited (0) 6 days ago                 flamboyant_mclaren

今気がついたんだけどrunはイメージを新規作成するコマンドなのでubuntuが大量生成されていた。同じものを指定して再利用するには二回目以降で別のコマンドを使わなきゃいけない。凡ミス。

さっきnodejsを入れたコンテナイメージを指定して立ち上げる。docker start。確認するとログインはできていないが立ち上がりはしている。

ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker start b2421f52ba91
b2421f52ba91
ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker ps
CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
b2421f52ba91   ubuntu    "/bin/bash"   27 minutes ago   Up 28 seconds             nifty_wright

ログインにはdocker execを使うようだ。さっきnodejsを入れたイメージを指定して本当に当該イメージに入れているか確認する。

ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker exec -it b2421f52ba91 /bin/bash
root@b2421f52ba91:/# node -v           
v10.19.0

よさそうなので今度は立ち上がっているイメージを落とすdocker stopを試す。のだが、このままexitするとそのタイミングで落ちてしまうのでデタッチをする。

Dockerのコンテナにログインする際は例えば以下のように実行します。 このあと、 ctrl + d で抜けるとコンテナは終了してしまいます。 コンテナを終了せずにログアウト(デタッチ)するには ctrl + p + ctrl + q を実行します。

root@b2421f52ba91:/# read escape sequence
ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ [1]> 

これでいいはず。落ちていないことを確認。

CONTAINER ID   IMAGE     COMMAND       CREATED          STATUS          PORTS     NAMES
b2421f52ba91   ubuntu    "/bin/bash"   41 minutes ago   Up 14 minutes             nifty_wright

ここからdocker stop

ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker stop b2421f52ba91
b2421f52ba91
ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

大丈夫そうだね。

作ったイメージを削除するにはdocker rm

ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker rm b2421f52ba91
b2421f52ba91
ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker ps -a
CONTAINER ID   IMAGE         COMMAND       CREATED          STATUS                      PORTS     NAMES
83ef15493b01   ubuntu        "/bin/bash"   21 minutes ago   Exited (0) 21 minutes ago             exciting_einstein
e09ccc2414db   ubuntu        "/bin/bash"   51 minutes ago   Exited (0) 51 minutes ago             admiring_sanderson
6d9d8508a9ca   ubuntu        "/bin/bash"   51 minutes ago   Exited (0) 51 minutes ago             charming_swartz
5f9574e596e0   ubuntu        "/bin/bash"   51 minutes ago   Exited (0) 51 minutes ago             admiring_chaplygin
ca738446dafa   ubuntu        "/bin/bash"   6 days ago       Exited (127) 6 days ago               epic_feynman
63ab6e895499   ubuntu        "/bin/bash"   6 days ago       Exited (0) 6 days ago                 recursing_ramanujan
937c1efdf209   ubuntu        "/bin/bash"   6 days ago       Exited (0) 6 days ago                 confident_wu
ab2f5e6adf0e   hello-world   "/hello"      6 days ago       Exited (0) 6 days ago                 flamboyant_mclaren

これでnodejsを入れたb2421f52ba91が削除された。

コンテナ内の変更をセーブして新しいイメージを作る

前回いろんなイメージの中から選択して好きなイメージをダウンロードしたけど、逆も可能で、自分が変更を加えたイメージを新たなイメージとして新規生成してdockerhubにアップロードすることもできる。まずdocker commitコマンドを使う。

ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker commit -m "ekp commit" -a "ekp" 83ef15493b01 spsyk103/new_ubuntu
sha256:1551dcbc8d23045ea00b00d33c5e109ea85f538f5691fbaaaaccbe9950a4560b

-mはメッセージで-aはauthor、作者。ここは任意だと思う。イメージのidと新しい名前を書いて、docker imagesで新しいイメージが手元に作成できたか確認する。

ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
spsyk103/new_ubuntu   latest    1551dcbc8d23   2 minutes ago   72.7MB
ubuntu                latest    7e0aa2d69a15   5 weeks ago     72.7MB
hello-world           latest    d1165f221234   3 months ago    13.3kB

dockerhubに作ったイメージをアップロード

これをアップロードしてみる。dockerhubはgithubみたいなもので、個人アカウントを作って自分で作ったイメージをインターネット上に保存して管理できる。ログインをした後docker pushを使う。その後、少し待つ。

ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker login -u spsyk103
Password: 
WARNING! Your password will be stored unencrypted in /home/ekp/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
ekp@ekp-ThinkPad-X1-Carbon-3rd ~/デスクトップ> docker push spsyk103/new_ubuntu
Using default tag: latest
The push refers to repository [docker.io/spsyk103/new_ubuntu]
0ea9b9f8f036: Pushed 
2f140462f3bc: Mounted from library/ubuntu 
63c99163f472: Mounted from library/ubuntu 
ccdbb80308cc: Mounted from library/ubuntu 
latest: digest: sha256:1f9dfa9100dba94515b4c030beb98cee2b78a552647cee1fc230f57e4b604f6e size: 1150

※dockerhubアカウントの開設は割愛します。簡単なのでこの辺を見てください。

Docker Hub アカウントとリポジトリの作成 — Docker-docs-ja 1.13.RC ドキュメント

自分のdockerhubにアップロードできたことを確認。

f:id:frazz:20210605012417p:plain

以上

今回はここまでです。おつかれさまでした!

ubuntuにdockerをインストール

前回:dockerのバインドマウント時のエラー - brand new note

udemyを見ながらものすごい時間をかけてwindowsのPCにdockerをインストールして基礎をやっていたんだけど、GUIがあるといまいちどれが大事なのかわからないとか、一回やっただけじゃ覚えてないよねとか、ubuntuのマシン上でも同じようにいじれたら楽しいよねとか、結果あんまり情報見なくてもコンテナ扱えるようになるんじゃないのとか、そういう動機でやった。相手は誰でも良かった。

Ubuntu 20.04へのDockerのインストールおよび使用方法 | DigitalOcean

これを見ながら同じことしているだけ。頭痛くしながら動画を見て学んだ後だと、このページが如何にきれいに内容を圧縮しているかがよくわかる。すばらしいまとめだとおもいます。たぶんここに書いてないことは一旦大事じゃないことだと思って気にしないで心を軽くしておいたほうがいいのかもしれない。本当は公式ドキュメントとかね、読めるといいんだけどね…5回目くらいで参照しようかな…

http://docs.docker.jp/index.html

こうなると多分あとは回数こなして覚えるのがよいので、最初から全部読むんじゃなくて、何をやってるかの流れを理解できるところだけ理解して、そこそこのところまでやって、壊して、2回目をやって、1回目でわからなかったところを補強して覚えてく、みたいな感じでやればいいのかもしれない。

というわけでメモは適当ですが、勘所をおさえるような書き方をしたつもり。

dockerインストール

下準備としてパッケージのリストを更新しておく(任意)

sudo apt update

apt install docker で入ると思ったけどそんな安直じゃなかった。ちょっと準備がいる。

dockerはコンテナイメージのテンプレみたいなやつをネット上から落として自分の環境をローカルでカスタムして遊ぶ使い方がメインになっているので、aptがhttps経由で使えるようにしておかないと動作しない(と今は解釈している)。そういうパッケージを入れる。

sudo apt install apt-transport-https ca-certificates curl software-properties-common

公式dockerリポジトリ(aptしてソフトウェアをローカルに落としてくるための宛先)を登録するためにGPGキーをダウンロードしてローカルに登録する。

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

GPGキーってなんだっていう話はここを見てください。

GPGについて学んだことを整理してみる - Qiita

今の所twitterの公式アカウントの認証マークみたいなものだと思っている。あると安心というか。仕組みはたぶん使ってれば覚えるのでまだ深堀りはしない。

sources.listにリポジトリのURLを追加する。別にファイルに手書きしなくてもコマンドから追加ができることをここで知る。

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"

再度パッケージリストを更新しておく。これはなんでかわかりますよね?

sudo apt update

ubuntuのデフォのリポジトリからじゃなくて本当にdockerのリポジトリからDLしてるんですか??という確認がしたければこれを打つ。

apt-cache policy docker-ce

あーそうなんだーと思えればそれでOK。

ここでdockerをインストール。

sudo apt install docker-ce

ceっていうのはコミュニティエディションのこと。エンタープライズエディションもある(ee)。一般市民はceでだいじょうぶ。

sudo systemctl status docker

起動していることを確認。

 docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2021-05-29 14:12:30 JST; 1h 1min ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 10012 (dockerd)
      Tasks: 14
     Memory: 148.1M
     CGroup: /system.slice/docker.service
             └─10012 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

 529 14:12:29 ekp-ThinkPad-X1-Carbon-3rd dockerd[10012]: time="2021-05-29T14:12:29.521127697+09:00" level=info msg="Loading containers: start."
 529 14:12:29 ekp-ThinkPad-X1-Carbon-3rd dockerd[10012]: time="2021-05-29T14:12:29.887873134+09:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option>
 5月 29 14:12:30 ekp-ThinkPad-X1-Carbon-3rd dockerd[10012]: time="2021-05-29T14:12:30.091194153+09:00" level=info msg="Loading containers: done."
 5月 29 14:12:30 ekp-ThinkPad-X1-Carbon-3rd dockerd[10012]: time="2021-05-29T14:12:30.158930938+09:00" level=info msg="Docker daemon" commit=8728dd2 graphdriver(s)=overlay2 version=20.10.6
 5月 29 14:12:30 ekp-ThinkPad-X1-Carbon-3rd dockerd[10012]: time="2021-05-29T14:12:30.159126637+09:00" level=info msg="Daemon has completed initialization"
 5月 29 14:12:30 ekp-ThinkPad-X1-Carbon-3rd systemd[1]: Started Docker Application Container Engine.
 5月 29 14:12:30 ekp-ThinkPad-X1-Carbon-3rd dockerd[10012]: time="2021-05-29T14:12:30.355188471+09:00" level=info msg="API listen on /run/docker.sock"
 5月 29 14:17:36 ekp-ThinkPad-X1-Carbon-3rd dockerd[10012]: time="2021-05-29T14:17:36.173564183+09:00" level=info msg="ignoring event" container=ab2f5e6adf0e8c096a3767585e774482ab2c262318f445e347471f2f6d>
 5月 29 14:21:00 ekp-ThinkPad-X1-Carbon-3rd dockerd[10012]: time="2021-05-29T14:21:00.229592870+09:00" level=info msg="ignoring event" container=937c1efdf209c7c764aaa09db01df5cd8511cbd5c8543cbe4551495602>
 5月 29 15:13:41 ekp-ThinkPad-X1-Carbon-3rd dockerd[10012]: time="2021-05-29T15:13:41.321834203+09:00" level=info msg="ignoring event" container=63ab6e89549918b16f6c56be87bedb121d5e1394398718b85d9243d3f5>

dockerイメージインストール〜ログイン

ここまでやったら一連のdockerコマンドを使えるようになってる。何が使えるかはこれで確認。

docker

あとはなにができんのかなとか言いながら公式ドキュメント調べるとかすればいいとおもう。適宜。

dockerのシステム全体の情報はこれで確認。

docker info
ekp@ekp-ThinkPad-X1-Carbon-3rd ~> docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Build with BuildKit (Docker Inc., v0.5.1-docker)
  scan: Docker Scan (Docker Inc., v0.7.0)

Server:
 Containers: 3
  Running: 0
  Paused: 0
  Stopped: 3
 Images: 2
 Server Version: 20.10.6
 Storage Driver: overlay2
  Backing Filesystem: extfs

…以下略

dockerコンテナは様々なdockerイメージを使用することができる。コンテナがモンスターボールだったらイメージはポケモンなんですよ。そうすっと僕なんかはずっと山行って虫取りしちゃうんです(養老孟司

docker run hello-world

runコマンドはイメージを新規作成および起動させるコマンドで、ローカルになければdockerhub(インターネット上)から取ってくる。hello-worldイメージは最初に動作確認するためには最適なイメージなのでだいたいこれ入れる。

docker search ubuntu

ubuntuのコンテナ使いたいんだけどなんかある?ってdockerhubに聞きに行ってみる。ubuntu上でubuntuのコンテナを動かす意味があるのか。

ekp@ekp-ThinkPad-X1-Carbon-3rd ~> docker search ubuntu
NAME                                                      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
ubuntu                                                    Ubuntu is a Debian-based Linux operating sys…   12302     [OK]       
dorowu/ubuntu-desktop-lxde-vnc                            Docker image to provide HTML5 VNC interface …   535                  [OK]
websphere-liberty                                         WebSphere Liberty multi-architecture images …   273       [OK]       
rastasheep/ubuntu-sshd                                    Dockerized SSH service, built on top of offi…   251                  [OK]
consol/ubuntu-xfce-vnc                                    Ubuntu container with "headless" VNC session…   240                  [OK]
ubuntu-upstart                                            Upstart is an event-based replacement for th…   110       [OK]       
1and1internet/ubuntu-16-nginx-php-phpmyadmin-mysql-5      ubuntu-16-nginx-php-phpmyadmin-mysql-5          50                   [OK]
open-liberty                                              Open Liberty multi-architecture images based…   45        [OK]       
ubuntu-debootstrap                                        debootstrap --variant=minbase --components=m…   44        [OK]       
i386/ubuntu                                               Ubuntu is a Debian-based Linux operating sys…   25                   
1and1internet/ubuntu-16-apache-php-5.6                    ubuntu-16-apache-php-5.6                        14                   [OK]
1and1internet/ubuntu-16-apache-php-7.0                    ubuntu-16-apache-php-7.0                        13                   [OK]
1and1internet/ubuntu-16-nginx-php-phpmyadmin-mariadb-10   ubuntu-16-nginx-php-phpmyadmin-mariadb-10       11                   [OK]
1and1internet/ubuntu-16-nginx-php-5.6-wordpress-4         ubuntu-16-nginx-php-5.6-wordpress-4             9                    [OK]
1and1internet/ubuntu-16-nginx-php-5.6                     ubuntu-16-nginx-php-5.6                         8                    [OK]
1and1internet/ubuntu-16-apache-php-7.1                    ubuntu-16-apache-php-7.1                        7                    [OK]
1and1internet/ubuntu-16-nginx-php-7.0                     ubuntu-16-nginx-php-7.0                         4                    [OK]
pivotaldata/ubuntu                                        A quick freshening-up of the base Ubuntu doc…   4                    
1and1internet/ubuntu-16-nginx-php-7.1-wordpress-4         ubuntu-16-nginx-php-7.1-wordpress-4             3                    [OK]
pivotaldata/ubuntu16.04-build                             Ubuntu 16.04 image for GPDB compilation         2                    
1and1internet/ubuntu-16-php-7.1                           ubuntu-16-php-7.1                               1                    [OK]
1and1internet/ubuntu-16-sshd                              ubuntu-16-sshd                                  1                    [OK]
pivotaldata/ubuntu-gpdb-dev                               Ubuntu images for GPDB development              1                    
smartentry/ubuntu                                         ubuntu with smartentry                          1                    [OK]
pivotaldata/ubuntu16.04-test                              Ubuntu 16.04 image for GPDB testing             0                    

いっぱいある。好きなイメージをえらぶんじゃ

プレーンなやつにしよう。ダウンロードはpullコマンド。

docker pull ubuntu

ここまでやるとふたつイメージがダウンロードできたことが確認できる。imagesコマンド。

docker images
ekp@ekp-ThinkPad-X1-Carbon-3rd ~> docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
ubuntu        latest    7e0aa2d69a15   5 weeks ago    72.7MB
hello-world   latest    d1165f221234   2 months ago   13.3kB

ubuntuに入ってみる。起動のrunコマンドに-itオプションをつけると対話シェルを取ってこれるので、これをログイン操作としている。

docker run -it ubuntu
ekp@ekp-ThinkPad-X1-Carbon-3rd ~> docker run -it ubuntu
root@ca738446dafa:/# 

※あとで気づきましたが毎回runすると同じubuntuイメージが毎回新規作成されます。idが違うのを見落としてました。runではなくexecを使いましょう。

rootでログインされるのがデフォなのでユーザ作成からは各自好きなようにやってください。イメージはidで識別できるので最初のホスト名はidになってる。

以上

今回はここまで。リンク後半の内容は以下からどうぞ。

次回:ubuntuにdockerをインストール - 2 - brand new note

ubuntuにnginxをインストール

nginxでWebサーバを構築してみよう | YAZ技術ブログ

基本だけどやったメモをのこしておく。

sudo apt install nginx net-tools

net-toolsはnetstatが使えなかったので入れただけ。他人のやってみたを真似してると「その後半のやつ入れる必要ある?」みたいな気持ちによくなるので書いとく。

設定ファイルは/etc/nginx/nginx.confconf.ddefault.confを作成。

なんで設定ファイルが分かれるんだろうと思ってたけど、デーモンで動かすときとフォアグラウンドで動かすときとでは設定ファイルを変えるのがスタンダードらしい。となるとconf.ddはデーモンなのかな。

server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ /\.ht {
        deny  all;
    }
}

/usr/share/nginx/htmlも確認。

ekp@ekp-ThinkPad-X1-Carbon-3rd /u/share> cd nginx/
ekp@ekp-ThinkPad-X1-Carbon-3rd /u/s/nginx> ls
html/  modules@  modules-available/
ekp@ekp-ThinkPad-X1-Carbon-3rd /u/s/nginx> cd html/
ekp@ekp-ThinkPad-X1-Carbon-3rd /u/s/n/html> ls
index.html
ekp@ekp-ThinkPad-X1-Carbon-3rd /u/s/n/html> cat index.html 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

特にファイアウォールもないのでブラウザからこのページが見えるか確認。

f:id:frazz:20210527233715p:plain

コンテナ上でnginxを立ち上げたことはあったけど、あれはコンテナの勉強だったので改めて分離してやってみた。確かにwelcomeページは見たことがあるので外側の箱は関係ないんだね(当たり前)。0歩目なのでいずれ必ず深堀りしないといけない。気が向くまでは一旦他のことをする。

ubuntuにfishをインストール

fish shellが結構良かった話 - Qiita

大昔にtwitterで流行ってたのを見ていたので今更使いたくなった。

sudo apt install fish
curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish
chsh -s $(which fish)

f:id:frazz:20210527225656p:plain

POSIX準拠じゃないらしいけど、PCは私物だし込み入ったことをしているわけでもないので今の所困る予定はない。コマンド補完が効くのかっこいい。

コンパイルをもう一度理解する

ちゃんとわからないといけなくなったので調べ直した。

Inside Linux Software オープンソースソフトウェアのからくりとしくみ

コンパイルを含め、開発を覚えようと思ったらこの本が詳しい。

Inside Linux Softwareを読んだ - brand new note

過去にエントリも書いたけど、これもかなり前のレビューなので参考になるかはちょっとわからない。途中までしか感想を書けていない。

記事の前半部は試行錯誤になってるので伝えたいことの本意ではない。読む意味があるかどうかは人それぞれだと思う。この記事の後半から、この本を使ってコンパイルの仕組みを簡単にまとめている。

目次

まず簡単に

コンパイルって何? |【エン転職】

コンパイルとは、プログラミング言語で書かれた文字列(ソースコード)を、コンピュータ上で実行可能な形式(オブジェクトコード)に変換することです。 コンパイルを行うソフトウェアをコンパイラといい、変換されるプログラミング言語コンパイラ型言語と呼びます。

「変換されるプログラミング言語コンパイラ型言語と呼びます。 」これは論理的には合ってるけど、じゃあ言語の数だけコンパイラがあるんだなと納得するとそれは間違い。コンパイラを必要としないインタプリタ言語もあるよという話になるんだけど、用語説明としてはここでは省かれるべきなのでそれは書かれていないらしい。

f:id:frazz:20210513130008p:plain

世のあらゆる技術者は当たり前のようにコンパイルのことやコンパイラのことについて言及してる。これらを全て読んだら本質的なコンパイルコンパイラの意味を文脈から理解することはできるけど、関連する1000も10000もある文章を全て読み漁るのはフルスタックエンジニアになることと同義だ。そんな時間はかけられない。

コンパイルの流れをざっくり掴んでいく - Qiita

WebAssemblyは言語ではない。でも今揚げ足を取っても仕方がない。自分も嘘は書く。善意なのも痛いほどわかる。寄り道してごめん。

コンパイルの流れ

f:id:frazz:20210513132700j:plain

本に戻ってこれを理解していく。

ソースファイルとヘッダファイル

raw_tcp_socket/raw_tcp_socket.c at master · rbaron/raw_tcp_socket · GitHub

とりあえず昔読もうとして挫折したソースコードを引っ張ってきた。内容はともかくとしてこの.cで書かれたもの(raw_tcp_socket.c)をソースファイルといい、内部の以下のような記述を「ヘッダファイル(.hで書かれたファイル)をインクルードする」という。ヘッダファイルが何なのかについてはコンパイルの流れとは別の話なので最後に書く。ソースファイルは紹介するものの言語がCだから今回.cなだけであって、他の言語でもいい。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h> //memset()
#include <unistd.h> //sleep()

f:id:frazz:20210513134120p:plain

ライブラリはどんなアプリケーションを開発するときにも使われるとても普遍的な概念であるから、機能のまとまりというふうに覚えておけばいいと思う。なんでまとまりなのかと言われればまとめておいた方が便利だからである。ライブラリは自身の環境にあらかじめインストールされていれば画像の部分にわざわざ同梱する必要はない。とりあえず開発環境は各々用意するものであって、コンパイラコンパイラ型言語を扱うのであれば、そのなかの道具の一つとして使うべきであることを改めて確認した。

なんでわざわざこんなことを書いているのかというと、理解のプロセスを経るのが下手くそすぎて4年前から脳機能が停止しているからである。自分は優秀だとでも思っていたのだろうか。

コンパイルとビルドの違い - brand new note

ビルドに関してはもう少し実際のアプリケーションの構成を目で見ないとイメージしにくいかもしれません。少し前まで、他人のgithubとかを見て「なんでひとつのアプリケーションは複数のファイルで構成されているんだろう、readmeとかよくあるし、どうやって連動して動作しているんだろう」と思っていました。自分はそこまで書けないので。

今見ると目も当てられない。うーんまあでも今もあんまり変わってないのか。

プリプロセス

絵の解読に戻る。

プリプロセス→(狭義の)コンパイル→最適化→アセンブル→リンク

この流れがgcc(GNU Compiler Collection)内部で起きている広義のコンパイル処理である。

プリプロセスは直訳すると事前処理となるけれど、文字通りソースファイルはコンパイラに直接突っ込んでもいけないことがここでわかると思う。正しくコンパイラに入力するためには"プリプロセス済みソースファイル"を生成する必要がある。

この過程でプリプロセッサはこんなことをしている。

  • コメントの除去
  • マクロの展開
  • #includeで指定されたファイルの取り込み
  • プリプロセッサに対する条件指定の処理

これはCの勉強も絡むけど、#ifとか#ifdefとかいうのはプリプロセッサが処理する条件コンパイルというやつで、広義のコンパイルの流れからすると比較的序盤に処理されることがわかる。詳細についてはここでは触れない。それと、#includeはCコンパイラが処理できるんだったら何をincludeしてきてもいいらしい。へえ。

(狭義の)コンパイル

プリプロセス済みのCソースコードコンパイラによってコンパイルされる。コンパイルをした後、出力先にはCPUがいるので、そのCPUに向けたアセンブリ言語のプログラムをコンパイラは吐き出す。最適化に関しては、明示的に指定すればやってくれる。これはアセンブリ言語の内容を操作して、よりプログラムを軽量あるいは高速にする作業である。

ここで生成される、アセンブリ言語が保存されたファイルには.sという拡張子がつく。

アセンブル

コンパイラが吐き出したアセンブリ言語のプログラムは、アセンブラによってアセンブルされる。つまりここで機械語のプログラムに変換される。.sだったファイルは機械語のコードのファイルとなり.oに変わる。これはオブジェクトのoで、オブジェクトファイルとも呼ばれる。

リンク

ソースコードから機械語のオブジェクトファイルを生成したが、まだこのままでは実行できない。ライブラリを使用する場合にはライブラリとの紐付けをしなければならない。また、大きなソースコードを一度にコンパイルするケースもあり、どこでミスが起きて失敗するのかソースコードから見分けるのが大変だという場合には、分割コンパイルという手法も存在しており、分割した場合には最後に結合をしなければならない。このような作業のことをファイルのリンクと呼ぶ。リンクを行うツールをリンカと呼ぶ。ldコマンドはその一例である。

ld - コマンド (プログラム) の説明 - Linux コマンド集 一覧表

リンカによってライブラリや分割ファイルのリンクが完了すると、晴れて実行可能形式のファイルが完成する。

ライブラリ

冒頭とここで出てきたライブラリについては、静的ライブラリと共有ライブラリがあり、それぞれ.a、.soという拡張子がつく。何が違うかというと読み込まれるタイミングが違う。静的ライブラリはリンク時にリンクされる。共有ライブラリはその後で、実行時に実行ファイルから読み込まれる。

歴史的に言うと先にできたのは静的ライブラリだけど、デメリットとして同じ機能を何度も繰り返してリンク時に読み出す形態は、完成する実行可能形式のファイルサイズをどんどん膨張させてしまうため、後から共有ライブラリという概念が生まれた。

共有ライブラリは静的ライブラリと違い、オブジェクトファイルではなく元から実行可能形式である。そのためメモリ上に展開することができる。実行可能形式のプログラムが実行されるとき、そのタイミングでメモリ上にすでに展開されている共有ライブラリを参照しに行くことで、静的ライブラリより無駄なくプログラムを動作させられる。静的ライブラリ使用時と比べると、アップデートがあった場合にも共有ライブラリと実行ファイルは独立してアップデートできるため、修正の手間も減る。

ライブラリとは何なのか? - Qiita

ここに詳しく書いてあるけれど、ライブラリは「これはライブラリです」と言い張ればどんなに小さなものでもライブラリである。生成する時に拡張子や静的/動的の指定、サーチパスの指定などをして適切な場所に置きつつ、メインとなる実行ファイルにそれを使用する旨が書かれていれば良い。

ヘッダファイル

Cの場合ヘッダファイルの中身は以下。関数の定義は含まないのがポイント。

  • マクロ定義
  • 関数のプロトタイプ宣言
  • 大域変数の宣言
#DEFINE NULL_VALUE "NULL"
#DEFINE PROGRAM_NAME "SAMPLE"

int get_value();
double calc(int n);

char *env_val;

値は適当だけど例えるとこんなのらしい。マクロは指示した文字列を別の文字列に置き換える仕組み。値の定義を1箇所に集中できるから後からコードを管理しやすい。

事前にこんな関数をmain()内で使いますよということも言っておかなければならない。これがプロトタイプ宣言。関数名、関数が受け取る値、関数が返す値、値の型を言っておく。書いとかないとコンパイラが親切心から型が間違ってるよっていうエラーを返してくれなくなる。

変数はわざわざ説明しないけど全ての関数から参照、変更できる変数を大域変数という。グローバル変数とも。後で「どこでこの値コレになったんだっけ」ってなるからあんまり使わない方がいい。

おわり

座学にならないようにしようと思ったけど座学になっちゃった。

過去の自分はクソ真面目だったので、「こういう方がいいじゃん」という思想の混じった"合理性のある知識”が一切体に入ってこなかった。コードなんてものは別世界の天才が書いているのだと思ってた。今まとめると納得できるけど、相変わらず基礎だ。