DockerとNetwork Namespace

ネットワークを勉強していると、Linuxマシン上で仮想的なネットワークを作成できる、Network Namespaceという機能があることを知った。
色々調べてみると、どうやらこの機能がDockerを構成する技術の1つでもあるらしい。
前々からネットワークやDockerの詳細について深掘りして学習したいと考えていたので、今回はDockerで3つのコンテナを立てたネットワークの状態をNetwork Namespace(以下NS)を使って再現してみようと思う。

今回作成するネットワークの構成図

完成図

Ubuntuのホストマシンの中にns1,ns2,ns3,bridgeというNSを作成し、ns1~ns3がbridgeの中の仮想ブリッジと接続され、外部ネットワークと通信ができる状態を目指す。
ブリッジとはデータリンク層でフレームを転送する機器で、1つのブロードキャストドメインに対して複数のネットワーク機器の接続を提供してくれる。

1. 仮想ノードの作成
ns1,ns2,ns3,bridgeを作成する。

$ sudo ip netns add ns1
$ sudo ip netns add ns2
$ sudo ip netns add ns3
$ sudo ip netns add bridge

これでNSが作成される。NSがきちんと作成されているか確認してみると、

$ ip netns list
bridge
ns3
ns2
ns1

きちんと4つのNSが作成されていた。

2. ノード同士を繋ぐvethインターフェイスを作成
先ほどの構成図では、ns1~ns3がそれぞれbridgeと繋がっていたので、6つのvethインターフェースを作成する必要がある。

$ sudo ip link add ns1-veth0 type veth peer name ns1-br0
$ sudo ip link add ns2-veth0 type veth peer name ns2-br0
$ sudo ip link add ns3-veth0 type veth peer name ns3-br0

作成されているか確認してみる。

$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 02:59:c2:1a:50:f1 brd ff:ff:ff:ff:ff:ff
3: ns1-br0@ns1-veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 72:1b:b5:69:10:c0 brd ff:ff:ff:ff:ff:ff
4: ns1-veth0@ns1-br0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 8a:c9:fa:44:00:6d brd ff:ff:ff:ff:ff:ff
5: ns2-br0@ns2-veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether c6:06:19:58:a3:b5 brd ff:ff:ff:ff:ff:ff
6: ns2-veth0@ns2-br0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 6a:26:33:1a:c8:32 brd ff:ff:ff:ff:ff:ff
7: ns3-br0@ns3-veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 4a:c4:d9:df:f3:b7 brd ff:ff:ff:ff:ff:ff
8: ns3-veth0@ns3-br0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether ba:dd:e3:bf:96:22 brd ff:ff:ff:ff:ff:ff

loとenp0s3はデフォルトで作成されているインターフェースであるので、きちんと作成されていることが確認できる。

3. 作成したvethインターフェースをノードに設定する
現状では全てのインターフェースはホストマシン上に存在し、NSには付与されていない。これをNSに付与する。

$ sudo ip link set ns1-veth0 netns ns1
$ sudo ip link set ns2-veth0 netns ns2
$ sudo ip link set ns3-veth0 netns ns3
$ sudo ip link set ns1-br0 netns bridge
$ sudo ip link set ns2-br0 netns bridge
$ sudo ip link set ns3-br0 netns bridge

付与できているかどうかを確認する。

$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 02:59:c2:1a:50:f1 brd ff:ff:ff:ff:ff:ff

ホストマシン上のインターフェース一覧からは、先ほどNSに付与したものは消えている。

$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 02:59:c2:1a:50:f1 brd ff:ff:ff:ff:ff:ff

代わりにNS上では、付与したインターフェースが表示されるようになる。

$ sudo ip netns exec ns1 ip link show
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
4: ns1-veth0@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 8a:c9:fa:44:00:6d brd ff:ff:ff:ff:ff:ff link-netns bridge

ここまでの状態は下記の画像のようになる。

インターフェースを各NSに配置

4. 作成したvethインターフェースの状態をUPに変更
vethインターフェースはデフォルトの状態ではDOWNであり、UPに変更する必要がある。

$ sudo ip netns exec ns1 ip link show ns1-veth0 | grep state
4: ns1-veth0@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
$ sudo ip netns exec ns1 ip link set ns1-veth0 up
$ sudo ip netns exec ns2 ip link set ns2-veth0 up
$ sudo ip netns exec ns3 ip link set ns3-veth0 up
$ sudo ip netns exec bridge ip link set ns1-br0 up
$ sudo ip netns exec bridge ip link set ns2-br0 up
$ sudo ip netns exec bridge ip link set ns3-br0 up

もう一度インターフェースの状態を確認すると、UPに変更されている。

$ sudo ip netns exec ns1 ip link show ns1-veth0 | grep state
4: ns1-veth0@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state UP mode DEFAULT group default qlen 1000

5. NS側のvethインターフェースにIPアドレスを付与
各NSのインターフェースにIPアドレスを付与する。

$ sudo ip netns exec ns1 ip address add 192.0.2.1/24 dev ns1-veth0
$ sudo ip netns exec ns2 ip address add 192.0.2.2/24 dev ns2-veth0
$ sudo ip netns exec ns3 ip address add 192.0.2.3/24 dev ns3-veth0

インターフェースにIPが付与されていることが確認できる。

$ sudo ip netns exec ns1 ip addr
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
4: ns1-veth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 8a:c9:fa:44:00:6d brd ff:ff:ff:ff:ff:ff link-netns bridge
    inet 192.0.2.1/24 scope global ns1-veth0
       valid_lft forever preferred_lft forever
    inet6 fe80::88c9:faff:fe44:6d/64 scope link 
       valid_lft forever preferred_lft forever

6. ネットワークブリッジを作成
現状ではNS bridgeには4つのインターフェースが存在する。

$ sudo ip netns exec bridge 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
3: ns1-br0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 72:1b:b5:69:10:c0 brd ff:ff:ff:ff:ff:ff link-netns ns1
5: ns2-br0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether c6:06:19:58:a3:b5 brd ff:ff:ff:ff:ff:ff link-netns ns2
7: ns3-br0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 4a:c4:d9:df:f3:b7 brd ff:ff:ff:ff:ff:ff link-netns ns3

各NSが外部ネットワークやお互いのNSと相互通信できるようにするために、仮想ネットワークブリッジを作成する。

$ sudo ip netns exec bridge ip link add dev br0 type bridge
$ sudo ip netns exec bridge ip link set br0 up

実際にブリッジが作成されていることがわかる。

$ sudo ip netns exec bridge 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: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/ether 06:93:fb:99:50:41 brd ff:ff:ff:ff:ff:ff
3: ns1-br0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 72:1b:b5:69:10:c0 brd ff:ff:ff:ff:ff:ff link-netns ns1
5: ns2-br0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether c6:06:19:58:a3:b5 brd ff:ff:ff:ff:ff:ff link-netns ns2
7: ns3-br0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 4a:c4:d9:df:f3:b7 brd ff:ff:ff:ff:ff:ff link-netns ns3

7. bridge側のvethインターフェースをブリッジに接続
NS bridgeに配置されているvethインターフェースを仮想ブリッジに接続する

$ sudo ip netns exec bridge ip link set ns1-br0 master br0
$ sudo ip netns exec bridge ip link set ns2-br0 master br0
$ sudo ip netns exec bridge ip link set ns3-br0 master br0

実際に接続されていることを確認する。

$ sudo ip netns exec bridge ip link show master br0
3: ns1-br0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
    link/ether 72:1b:b5:69:10:c0 brd ff:ff:ff:ff:ff:ff link-netns ns1
5: ns2-br0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
    link/ether c6:06:19:58:a3:b5 brd ff:ff:ff:ff:ff:ff link-netns ns2
7: ns3-br0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
    link/ether 4a:c4:d9:df:f3:b7 brd ff:ff:ff:ff:ff:ff link-netns ns3

ここまでの状態は下記の図のようになる。

NS同士相互通信できる状態

8. ノードns1からノードns2,ns3へ通信してみる
ns1からns2に通信してみる。

$ sudo ip netns exec ns1 ping -c 3 192.0.2.2 -I 192.0.2.1
PING 192.0.2.2 (192.0.2.2) from 192.0.2.1 : 56(84) bytes of data.
64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.052 ms
64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.045 ms
64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.045 ms

--- 192.0.2.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2026ms
rtt min/avg/max/mdev = 0.045/0.047/0.052/0.003 ms

きちんと通信できている。ns1からns3に通信してみる。

$ sudo ip netns exec ns1 ping -c 3 192.0.2.3 -I 192.0.2.1
PING 192.0.2.3 (192.0.2.3) from 192.0.2.1 : 56(84) bytes of data.
64 bytes from 192.0.2.3: icmp_seq=1 ttl=64 time=0.039 ms
64 bytes from 192.0.2.3: icmp_seq=2 ttl=64 time=0.034 ms
64 bytes from 192.0.2.3: icmp_seq=3 ttl=64 time=0.039 ms

--- 192.0.2.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2052ms
rtt min/avg/max/mdev = 0.034/0.037/0.039/0.002 ms

9. ノードから外部と通信してみる

$ sudo ip netns exec ns1 ping 8.8.8.8
ping: connect: Network is unreachable

ここで外部ネットワークと通信を試みるが、できない。
それもそのはず、外部ネットワークと通信する経路はまだ用意できていない。

10. ノードからブリッジ経由で外部と通信できるようにする
まずはブリッジとホストを繋ぐインターフェースを作成する。

$ sudo ip link add name rt-veth type veth peer name rt-br0
$ sudo ip link set rt-veth up

次に、ホスト側のインターフェースにIPを付与する。

$ sudo ip addr add 192.0.2.100/24 dev rt-veth

NS bridge側のインタフェースを仮想ブリッジに接続する。

$ sudo ip link set rt-br0 netns bridge
$ sudo ip netns exec bridge ip link set dev rt-br0 master br0
$ sudo ip netns exec bridge ip link set rt-br0 up

各NSにデフォルトゲートウェイを設定する。

$ sudo ip netns exec ns1 ip route add default via 192.0.2.100
$ sudo ip netns exec ns2 ip route add default via 192.0.2.100
$ sudo ip netns exec ns3 ip route add default via 192.0.2.100

ホスト側でIP転送を有効化する。

$ sudo sysctl net.ipv4.ip_forward=1

ホスト側のインターフェースにNATを設定する。

$ sudo iptables -t nat \
               -A POSTROUTING \
               -s 192.0.2.0/24 \
               -o enp0s3 \
               -j MASQUERADE

11. もう一度ノードから外部と通信してみる

$ sudo ip netns exec ns1 ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=61 time=4.36 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=61 time=4.82 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=61 time=5.09 ms

--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 4.364/4.759/5.089/0.299 ms

外部と通信できた!
これで最初に示した完成図と同じネットワーク構成を作ることができた。

完成図

Dockerを使うと
NSを使ってネットワークを構築する場合、上記のようにたくさんのコマンドを叩く必要があったが、Dockerの場合同じようなネットワーク構成を実現するにはコンテナを3つ立ち上げるだけで済む。

1. Dockerが入っていない状態でインターフェースを確認する
現状ではloとenp0s3の2つだけが存在している。

$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 02:59:c2:1a:50:f1 brd ff:ff:ff:ff:ff:ff

2. Dockerをインストールする

Dockerをインストールしただけの状態で、もう一度インターフェースの一覧を見る。

$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 02:59:c2:1a:50:f1 brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500

docker0というインターフェースが新規で作成されている。
IPアドレスを見てみると、

$ ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 02:59:c2:1a:50:f1 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
       valid_lft 85874sec preferred_lft 85874sec
    inet6 fe80::59:c2ff:fe1a:50f1/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:8e:4a:45:a1 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

172.17.0.1/16というIPが割り振られているのがわかる。

3. コンテナを立てる
先ほどのNSの時と同じ状態に近づけるために、コンテナを3つ立てる。

$ sudo docker run -it -d --name ubuntu01 ubuntu:latest
$ sudo docker run -it -d --name ubuntu02 ubuntu:latest
$ sudo docker run -it -d --name ubuntu03 ubuntu:latest

コンテナを作ると、コンテナに対応するインターフェースが作成されている。

$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 02:59:c2:1a:50:f1 brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default 
    link/ether 02:42:8e:4a:45:a1 brd ff:ff:ff:ff:ff:ff
5: veth7203d86@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether 72:52:16:04:2f:77 brd ff:ff:ff:ff:ff:ff link-netnsid 0
7: vetha29d336@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether d6:84:ad:10:be:a5 brd ff:ff:ff:ff:ff:ff link-netnsid 1
9: veth0ba49e1@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether 1a:aa:47:69:f1:bf brd ff:ff:ff:ff:ff:ff link-netnsid 2

上記のインターフェースはdocker0に接続されていることがわかる。

$ ip link show master docker0
5: veth7203d86@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether 72:52:16:04:2f:77 brd ff:ff:ff:ff:ff:ff link-netnsid 0
7: vetha29d336@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether d6:84:ad:10:be:a5 brd ff:ff:ff:ff:ff:ff link-netnsid 1
9: veth0ba49e1@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 
    link/ether 1a:aa:47:69:f1:bf brd ff:ff:ff:ff:ff:ff link-netnsid 2

各コンテナのデフォルトゲートウェイは172.17.0.1を向いていることがわかる。

$ sudo docker inspect --format '{{.NetworkSettings.Gateway}}' ubuntu01
172.17.0.1

$ docker inspect --format '{{.NetworkSettings.Gateway}}' ubuntu02
172.17.0.1

$ sudo docker inspect --format '{{.NetworkSettings.Gateway}}' ubuntu03
172.17.0.1

Dockerの場合のネットワーク構成図は下記のようになる。

Dockerのネットワーク構成図

まとめ
Linuxマシン上で一から自分でネットワークを構築してみた。手続き的にたくさんのコマンドを打つ必要があったが、Dockerを使うことでLinuxマシン上に簡単にネットワーク構成を作ることができる。
普段なんとなく使っているものを、こうやって深掘りして調べてみると勉強になることがたくさんあることがわかった。

手を動かしながらTCP/IPに入門したお話

エンジニアに転職して4年が過ぎたが、いまだにネットワーク周りに不安があり、転職活動の時に支障が出そうだったので本腰を入れて勉強してみることにした。

TCP/IPを学ぶ本と言えばマスタリングTCP/IP 入門編が王道ではあるが、初学者が読む上では結構難しい…
なのでまずは簡単に読める本から始めてみることにした

[改訂新版] 3分間ネットワーク基礎講座
https://amzn.asia/d/h4MUgo1

この戦略は結構良かったみたいで、OSI参照モデルの全7層のうち1~4層まではざっくりと理解できた。
 
この調子でマスタリングTCP/IPに戻ってみて読み進めたんだがやっぱりまだ難しい…
ネットワークは抽象的な概念なのでハンズオン形式で進めていった方がよさそう。
と思っている時にであったのがこちらの本

Linuxで動かしながら学ぶTCP/IPネットワーク入門
https://amzn.asia/d/7SlXJyj

ちょうど自分のニーズに合っていたので買ってみたが、確かにハンズオン形式でネットワーク機器とかを購入せずに学習を進められるので結構良い。
LinuxのNetwork Namespaceの説明からVagrantを使った環境構築、Network Namespace同士の通信など基礎から丁寧に解説してくれている。
これからこの本で学んだ内容をできるだけアウトプットしてみようと思う。

正月にもくもく会開催して超集中出来た話

年末年始と言えば帰省、同窓会、初詣、etc... 予定がたくさん入りがち。かと言って決して忙しいわけではないが集中して勉強できるわけもなくぐうたら寝正月を過ごしてしまう。 というわけで、今年の正月は帰省の予定を入れずにもくもく会を企画してガッツリ勉強してみた。

メンバー

メンバーは自分を含めて4人。みんなTECH::EXPERTを卒業してエンジニアとしてのキャリアを歩み始めたひよこばかり。 1人以外はTwitterで繋がった人たち。Twitter偉大。 同じプログラミングスクール卒ということもあって割と最初から打ち解けて話せました。 当日は1人は来れなくなったので、zoomでもくもくしてました。 f:id:t1gerk1ngd0m:20200104175830j:plain

コンセプト

せっかく自分主催のもくもく会をやるんだし、ということで参加者にどんな価値提供を出来るか考えて企画を作ってみた。 - 2人一組でのポートフォリオ開発 - slackワークスペースでtimesチャンネルを作って困っていることなど共有しやすいように - もくもく会の最初と終わりに1日のやる事と進捗報告 - 当日現地に来れなかったメンバーとzoom繋いでオンラインもくもく

自分としては2人一組でのポートフォリオ作成をやり切ってみたかった。 なぜなら、ポートフォリオは1人で作ろうとするとしんどくてどうしても作りきれないことが多い。 そこで2人一組だったらいけんじゃね?ってことで、以前からVueをやりたいと言っていたメンバーの1人にVueアプリを作ることを提案した。 役割としては自分がPO(プロダクトオーナー)、相手が開発。 この3日間ではVueがなんとなくこんな風に動くんだ、という感触を持ってもらえたので自分的には成功!

これからやりたいこと

もっともくもく会や勉強会など主催していきたい。 普通のもくもく会だとなんかおもんないので、自分のようなスクール卒のエンジニア向けに色々企画を作ってみてどういう企画が人気あるのかを知っていきたい。

Arduinoで誰でも出来る電子工作「Lチカ」をやってみた

普段WebエンジニアとしてRailsを使った開発をしているが、せっかくなので正月の暇な時に電子工作をやってみた。 最初は漠然と「IoT関連で何か作れたら面白そうだな〜」などと考えていたが、そもそも簡単な電子工作すらやったことなかったのでLEDチカチカからやってみることにした。

Arduinoってなに?

よくわかってないけど素人でも簡単に電子工作が出来る基盤らしい。 素人でも電子工作が出来て、作成した物を簡単なプログラムを書くことで動かすことが出来る。 そして色々な追加モジュールが販売されているので、それなりの完成度の物を短時間で作れるようになるという代物。

Arduinoを使って「Lチカ」をやってみた

「Lチカ」とはLEDをチカチカさせること。 Arduinoではたったそれだけのものなら一瞬で組み上げて実現することが出来る。 その成果がこちら。

Arduinoで出来る物

Arduinoを使えば日常生活に関わる様々なことに使える物を作ることが出来る。 百葉箱、ドローン、温度計、エアコン遠隔操作リモコンなどだ。 普段Webのことしかしていないから、Lチカをやってみただけで色々妄想が捗るぜええええ。

参考サイト

Arduinoの作成に当たってこちらのサイトにお世話になった。これからも暇をみてはいろんな物を作ってみよう!

deviceplus.jp

Railsの開発段階で配信メールを確認したい

やりたいことはタイトルの通り。
Railsのmailerでメール送信機能を実装すると、本番環境での確認の前に開発環境での確認を行いたい。
そんな時は`letter_opener_web`を使えば送信メールをブラウザ上で確認出来る。

f:id:t1gerk1ngd0m:20190905214659p:plain

# 導入方法
Gemfileに'letter_opener_web'を記述後、`bundle install`
```
Gemfile

group :development do

gem 'letter_opener_web'

end
```

development.rbを編集する。
```
config/environments/development.rb

config.action_mailer.perform_caching = true # falseをtrueに修正
config.action_mailer.default_url_options = { host: 'localhost:3000' } # 追加
config.action_mailer.delivery_method = :letter_opener_web # 追加
```

ルーティングを設定する。これでブラウザ上でメールを確認出来る。
```
config/routes.rb

if Rails.env.development?
mount LetterOpenerWeb::Engine, at: '/letter_opener'
end

```

サーバを再起動し、`localhost:3000/letter_opener`にアクセス出来たら完了。

deviseのパスワードの最低文字数を変更する

とても簡単です。

  1. configを編集する 恐らくこれが一番シンプルなやり方。 下記の6..128は「6文字〜128文字の間」という意味なので、6を別の数字にすれば良い。
~/config/initializers/devise.rb

config.password_length = 6..128

ちなみに、ここで最低文字数を変えると、deviseのデフォルトで定義されている@minimum_password_lengthというインスタンス変数に格納されている値も変化する。

  1. モデルに直接記述する deviseを使用しているモデル(例えばuser.rb)に、
devise :validatable, password_length: 6..128 

と記述しても良い。 なお、validates :password, length: { maximum: 8 }という書き方はせずに、必ずdeviseと関連付けないといけない。

環境変数はどう設定してる?Railsで簡単に設定できるdotenvの使い方

Railsに限らずDB設定値やAWSのアクセスキーなど、アプリケーションを作る上で定数で持たせたい値が存在する。 こういった値はコードに直書きするのでは無く、環境変数として設定するのが基本的な考え方。 そこで今回は環境変数を設定する上でとても便利なgem、dotenvを紹介する。

仕組み

ルートディレクトリに.envというファイルを作成し、その中に環境変数を書き込むと、ENVからその値を取り出すことが出来る。

/.env

AWS_ACCESS_KEY_ID="hogehoge"
AWS_SECRET_ACCESS_KEY="mogamoga"


ENV['AWS_ACCESS_KEY_ID'] => "hogehoge"
ENV['AWS_SECRET_ACCESS_KEY'] => "mogamoga"

使い方

Gemfileにgemを追加

gem 'dotenv-rails'

以上で終わり! とても簡単に使えるので、是非導入してみてください!!