docker-composeでローカルでの動作確認用環境を準備したお話

この記事はフラー Advent Calendar 2020 の21日目の記事です。20日目は
@jfurudo さんでApp Clips を試してみる - Qiita でした。


前置き

前回の投稿でチラッとお話した通り、今年7月にフラー株式会社に転職しました。

初めましてのGolangに戸惑いはしたものの、研修内容がしっかりしており、OJTが終わる頃にはそこそこGolangと仲良くなれた気がしました。

OJT期間中のことはこちらの記事に詳しく載ってますので、よろしければ合わせて読んでください。

本記事ではGolang…の話からはちょっと外れた、それでいて私がOJT期間中に四苦八苦したdocer-composeでのローカル動作確認環境の構築の話をしたいと思います。

背景

OJT期間中に作成したのはいわゆる3層アーキテクチャのシステムです。

  • リバースプロキシ(nginx)
  • アプリケーション(goで構築)
  • データベース(mysql

メインで開発していたのはアプリケーションだったのですが、付随してnginxやmysqlを使用する必要がありました。


…ということは、goで作成したアプリケーションを起動させ、動作確認をするためには毎度nginxやmysqlを起動させる必要があります。

「いやいや、PC起動時に自動で起きるように設定していれば毎度ぽちぽちする必要はない!」という意見もあるかと思います。
その通りだと思います。

ただ、そうなると業務で同時に複数のシステムを構築しているときなど、ポートがかち合う不都合が出てきてしまいます。
ソレはちょっと避けたい

そんなこんなでローカルで仮想環境を準備したいのでDocker、特に複数のコンテナを準備するためにdocker-composeを使用することとしました。


また作成したgoアプリケーションは起動時にDBコネクションを作成する設計になっていました。
そのためmysqlサーバが起動完了しDBが準備されるのを待ってから、goアプリケーションを起動させる必要がありました。


面倒くさい…コマンドを一回叩くだけで実施したい…

てなわけで次の章へ↓↓

目指すもの

この記事で目指すのものは次の通りです。

  • nginx、 mysqlgolangで作成したアプリの実行環境を構築する
  • mysqlサーバでDBが準備できてからgoアプリケーションを実行させる
  • コマンドを一回叩くだけで上記が実行できる

頑張った成果物

Dockerfile

goで作成したアプリケーションをwebアプリケーションサーバに載せる仕組みを準備します。
ローカルでgoアプリケーションをojtという名称でコンパイルし、Alpine Linuxのイメージに転送します

FROM alpine:latest

# コンパイルしたアプリケーションを配置するディレクトリ
WORKDIR /app 
# 先のディレクトリニにコンパイルしたアプリケーションをコピー
COPY ojt /app 

# 下のシェルスクリプト で必要なmysql-clientをインストール
RUN apk add --no-cache mysql-client
# DB起動を待つためのシェルスクリプト をコピー
COPY scripts/waitdb.sh /scripts/waitdb.sh

最後の「DB起動を待つための下準備」の詳しい中身は後述します。

docker-compose

リバースプロキシ、webアプリケーション、データベースを同時に起動できるよう、docker-composeを準備します。

version: '3'
services:

    db:
        image: mysql:5.7
        restart: always
        container_name: ojt-db
        ports: 
            - "3306:3306"
        volumes:
            - ./mysql/init:/docker-entrypoint-initdb.d
        environment:
            MYSQL_ROOT_PASSWORD: root
            MYSQL_USER: admin
            MYSQL_PASSWORD: hoge


    web:
        build: .
        container_name: ojt-web
        ports: 
            - "8080:8080"
        depends_on: 
            - db
        # 環境変数の設定
        environment: 
            - GOPATH=/go
            - OJT_DB_HOST=ojt-db
            - OJT_DB_USER=admin
            - OJT_DB_PASS=hoge
        command: sh /scripts/waitdb.sh /app/ojt
    
    proxy:
        build: nginx/.
        container_name: ojt-proxy
        ports: 
            - "8000:80"
        depends_on: 
            - web

起動順は データベース→webアプリケーション→リバースプロキシ の順にしました。
portsで指定しているポート番号をよしなにすれば、他のシステムを同時に扱っていたとしてもポート番号の被りを防ぐことができます。

またcommand: sh /scripts/waitdb.sh /app/ojt によって先DockerfileでCopyをしていたシェルスクリプトを実行します。

waitdb.sh

DBの準備ができてからWebアプリケーションを起動するシェルの中身です。

#! bin/sh
set -e

# 引数からDBホスト名とojtアプリの起動コマンドを受け取る
cmd=$1

echo "Waiting for mysql"

until mysql -h"$OJT_DB_HOST" -u"$OJT_DB_USER" -p"$OJT_DB_PASS" &> /dev/null
do
        >&2 echo -n "."
        sleep 1
done

>&2 echo "MySQL is up - executing command"
exec $cmd

1秒ごとにDB接続を試し、成功したらgoアプリケーションを実行する仕組みにしています。

Makefile

さて、ここまで準備したはいいですが、goアプリケーションをコンパイルしてそれからdocker-compose up -dをするのでは、当初の目的の「コマンドを一回叩くだけ」には微妙に外れてしまっています。
そのためMakefileを準備します。

BINARY_NAME=ojt

build-linux:
	GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o $(BINARY_NAME) main.go
docker-up:
	make build-linux
	docker-compose up -d

build-linuxコンパイル をし、docker-up で先のコマンドとdocker-compose up -dを実施しています

実行

ではコマンドを一つ実行するだけで実現してみせましょう。

% make docker-up     
(略)
Creating ojt-db ... done
Creating ojt-web ... done
Creating ojt-proxy ... done

yoshi

Special Thanks

最後の素敵なイラストは たま子さん が描かれたイラストで、掲載許可をいただきました。ありがとうございます。
坂本たま子 (@sakamototamaco) | Twitter

Block Kitを用いたSlack通知をGoで実装してみる

この記事はフラー Advent Calendar 2020 の8日目の記事です。7日目は
@masaya82
さんで チェックボックスのアクセシビリティ対応をしたお話 - Qiita でした。



今年7月、フラー株式会社へ転職をいたしました。
現在はサーバサイドエンジニアとして働いており、主にGoを用いたウェブアプリケーションの開発を行っております。

その中でつい先日、Slack通知を行う機能を設ける必要が出てきました。
GoでのJSONの扱い方と合わせて諸々知見を得たので、今回はGoで実装するSlack投稿に関して書きたいと思います。

目指してる成果物

新型コロナウイルスの影響で殺伐とした社会になってしまった今だからこそ
Slackに癒し画像を投稿したいと思います。

さてSlackのメッセージを装飾する方法として、現状AttachmentsとBlock Kitの二つがあります。
前者のAttachmentsですが、どうやらレガシーなものになってしまっているようです(See Transforming your legacy message compositions with blocks | Slack)
そんなわけでBlock Kitを用いて構築していこうと思います。

通知は行いたいけどどんな見た目にしようか…?
そもそもどの程度の自由度あるの…?

そんな悩みを簡単に解決する術をSlackさんは提示してくださっております。

その名もBlock Kit Builder

Slack Block Kit を用いた装飾をUIフレームワークを用いて簡単に作成できるものになります。
画面左側でBlockを選択すると、真ん中にイメージが追加され、右側にはJSON形式の出力がされる…うん、便利。


今回目指すべき投稿はこんな感じにしようかと

f:id:inoriko711:20201206144041p:plain
Slack投稿したい内容

いいね、癒されますね。

癒し画像は、私の娘が愛してやまないふわたろうの画像を使用致します。
飼い主のタナイキさんにもご協力いただきました!ありがとうございます!

前準備

投稿先のSlackチャンネルとIncoming Webhookの準備

投稿する先のSlackチャンネルを準備してください。

またそのチャンネルにIncoming Webhookのアプリを追加してください。
該当チャンネルの詳細から「その他」>「アプリを追加する」からIncoming Webhookを選択すればOKです。

追加した際にWebhook URLが提示されるのでこれを使用します。

実装

では実装に入ります

ただ一つの文を送る機能の実装

とりあえず、Block Kit云々言う前に、ひとこと物申す機能を実装しようと思います。
先程取得したWebhook URLにBodyにJSONを持ったPOSTを投げればできます。

肝心のJSONデータはこんな感じ

{
	"username" : "通知上で表示されるユーザ名",
	"icon_url" : "通知上で表示されるユーザ画像",  // icon_emoji で指定するとSlack絵文字が使用できます
	"text" : "通知内容"
}

ではこれを送るコードを実装しましょう

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
)

func main() {
	// 投稿先SlackURL
	slack := "https://投稿先SlackURL" 

	// BodyのJSONの準備
	bodyJSON, err := json.Marshal(map[string]interface{}{
		"username": "inoriko711",
		"icon_url": "https://iconURL",
		"text":     "テスト",
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	// POST通信の実施
	resp, err := http.Post(slack, "application/json", bytes.NewReader(bodyJSON))
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()

	// responce Bodyを最後まで読んでエラーがないことの確認
	if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
		fmt.Println(err)
	}
}

go run [ファイル名].go で実行!
…でけた

f:id:inoriko711:20201206231658p:plain

Block Kitの箇所を準備する

Block Kit Builderで作成されたJSONですが、思いの外複雑な上、必須パラメータが欠けると問答無用で投稿できなくなります。
(Blockが欠けるとかじゃないです。全て投稿できなくなるんです。)

さらに、私、自慢じゃないですけどtypoが多いです。いちいちJSONのキー名を手打ちするのはしんどいです。

そのため各Block毎に構造体を作成して、その構造体に沿ってさえいれば問題なく投稿できるような仕組みを準備します。

HeaderのBlockを準備する

Header部分はこちら

f:id:inoriko711:20201206214013p:plain
Header画像

該当JSONはこんな感じです。

{
	"type": "header",
	"text": {
		"type": "plain_text",
		"text": ":star2:癒しタイム:star2:",
		"emoji": true
	}
}

Headerの要素に関する詳しい説明はこちらReference: Layout blocks | Slackに書かれてあります。
Fieldとしてはtypeとtextが必須、block_idは任意。型としてはtypeとblock_idはstring、textはオブジェクトです。

そのためGoコードとしては以下の型を準備します。

type HeaderBlock struct {
	Type    string      `json:"type"`
	Text    interface{} `json:"text"`
	BlockID string      `json:"block_id,omitempty"`
}

`json:"キー名"で入力しておくことで、Go側でよしなにしてくれます。便利。
またomitemptyを付与しておくことでコード上で何も指定されなかった(nilの)際、JSONに直すときにキー毎省いてくれます。とっても便利。

先程textの値の型はオブジェクトだって申し上げた舌の根も乾かぬうちにアレですが、よくよく読むと値はTextObjectしか持たないようです。

と言うわけで
TextObjectの型を準備して、先程準備したHeaderBlockのTextの型を*TextObjectにしてしまいましょう。

type TextObject struct {
	Type     string `json:"type"`
	Text     string `json:"text"`
	Emoji    bool   `json:"emoji,omitempty"`
	Verbatim bool   `json:"verbatim,omitempty"`
}
type HeaderBlock struct {
	Type    string      `json:"type"`
	Text    *TextObject `json:"text"`
	BlockID string      `json:"block_id,omitempty"`
}

今回は特にBlockIDやVerbatimを使用する予定はないのですが、今後のことを考えて実装してしまいます。

以下同じようなことを繰り返すので、十分わかったよって人は飛ばしちゃってください。

Sectionのplain textブロックを準備する

「本日の癒し」の箇所です。シンプルそうですね。
こちらを参考に作ります

type SectionBlocks struct {
	Type      string      `json:"type"`
	Text      *TextObject `json:"text"`
	BlockID   string      `json:"block_id,omitempty"`
	Fields    string      `json:"fields,omitempty"`
	Accessory interface{} `json:"accessory,omitempty"`
}

…あまりシンプルじゃなかった

Imageのnotilteブロックを準備する

お待ちかねのふわたろうの画像の箇所です!
こちらを参考に作ります

type ImageBlock struct {
	Type     string      `json:"type"`
	ImageURL string      `json:"image_url"`
	AltText  string      `json:"alt_text"`
	Title    *TextObject `json:"title,omitempty"`
	BlockID  string      `json:"block_id,omitempty"`
}
ActionsのButtonブロックを準備する

↓この箇所です。ボタンを押すとそれぞれのTwitterへ遷移します。
f:id:inoriko711:20201206233527p:plain

こちらを参考に作ります。

type ActionBlock struct {
	Type     string        `json:"type"`
	Elements []interface{} `json:"elements"`
	BlockID  string        `json:"block_id,omitempty"`
}

またelementsとしてButton elementを使用するため、こちらの構造体も準備します。

type ButtonElement struct {
	Type     string      `json:"type"`
	Text     interface{} `json:"text"`
	ActionId string      `json:"action_id,omitempty"`
	URL      string      `json:"url,omitempty"`
	Value    string      `json:"value,omitempty"`
	Style    string      `json:"style,omitempty"`
	Confirm  interface{} `json:"confirm,omitempty"`
	}
Contextのtext and imagesブロックを準備する

一番下のブロックです。
f:id:inoriko711:20201206233643p:plain

こちらを参考に作ります。

type ContextBlock struct {
	Type     string        `json:"type"`
	Elements []interface{} `json:"elements"`
	BlockID  string        `json:"block_id,omitempty"`
}
準備した構造体に値を突っ込む

長々と準備しました構造体に値をセットします。

func buildBlocks() []interface{} {
	return []interface{}{
		&HeaderBlock{
			Type: "header",
			Text: &TextObject{
				Type: "plain_text",
				Text: ":star2:癒しタイム:star2:",
			},
		},
		&SectionBlocks{
			Type: "section",
			Text: &TextObject{
				Type: "mrkdwn",
				Text: "本日の癒し",
			},
		},
		&ImageBlock{
			Type:     "image",
			ImageURL: "https://imageURL",
			AltText:  "fuwataro",
		},
		&ActionBlock{
			Type: "actions",
			Elements: []interface{}{
				&ButtonElement{
					Type: "button",
					Text: &TextObject{
						Type:  "plain_text",
						Text:  "ふわたろう",
						Emoji: true,
					},
					URL:   "https://twitter.com/huwataro_",
					Value: "fuwataro Twitter",
				},
				&ButtonElement{
					Type: "button",
					Text: &TextObject{
						Type:  "plain_text",
						Text:  "inoriko",
						Emoji: true,
					},
					URL:   "https://twitter.com/inoriko711",
					Value: "inoriko Twitter",
				},
				&ButtonElement{
					Type: "button",
					Text: &TextObject{
						Type:  "plain_text",
						Text:  "Fuller, Inc.",
						Emoji: true,
					},
					URL:   "https://twitter.com/fuller_inc",
					Value: "fuller  Twitter",
				},
			},
		},
		&ContextBlock{
			Type: "context",
			Elements: []interface{}{
				&ImageBlock{
					Type:     "image",
					ImageURL: "https://imageURL",
					AltText:  "inoriko711",
				},
				&TextObject{
					Type:  "plain_text",
					Text:  "Author: inoriko711",
					Emoji: true,
				},
			},
		},
	}
}
実行してみる

body JSONにblocks要素を付与。

// BodyのJSONの準備
bodyJSON, err := json.Marshal(map[string]interface{}{
	"username": "inoriko711",
	"icon_url": "https://iconURL",
	"text":     "癒し画像のお届け",
	"blocks":   blocks,
	})

go run 実行!!!!
f:id:inoriko711:20201205152512p:plain
投稿できました。


投稿内容を可変にする

折角作った投稿機能、より汎用性を高めるべく、以下の値を可変にしようと思います。

  • Slack通知先
  • 通知アプリアイコン画
  • 通知アプリユーザ名

また毎度同じ内容を投稿し続けるのも気が引けます。
そのため以下の値も可変にしようと思います。

  • 通知本文
  • 癒し画像
  • 癒し画像タイトル
  • 投稿者画像
  • 投稿者画像タイトル
  • 投稿者名

実装

本当であれば編集画面を準備してあれこれやりたいのですが、残念ながら今回そんな余力はありませんでした。
今回のところは可変データを保持するJSONファイルを準備して、それを読み込んであれこれするに留めておきます。

準備したJSONデータ

{
    "slack_url": "投稿先SlackURL",
    "username": "可変テストユーザ名",
    "icon_url": "通知で用いるアイコン",
    "slack_notice_data": {
        "text": "通知本文",
        "healing_image_url": "癒し画像URL",
        "healing_image_text": "癒し画像タイトル",
        "author_image_url": "投稿者画像URL",
        "author_image_text": "投稿者画像タイトル",
        "author_name": "投稿者名"
    }
}


JSONを扱うので、例によって構造体の準備

// Slack通知可変箇所のデータ構造体
type SlackApp struct {
	SlackURL            string           `json:"slack_url"`
	Username            string           `json:"username"`
	IconURL             string           `json:"icon_url"`
	SlackNoticeDataType *SlackNoticeData `json:"slack_notice_data"`
}

// Slack投稿内容可変箇所のデータ構造体
type SlackNoticeData struct {
	Text             string `json:"text"`
	HealingImageURL  string `json:"healing_image_url"`
	HealingImageText string `json:"healing_image_text"`
	AuthorImageURL   string `json:"author_image_url"`
	AuthorImageText  string `json:"author_image_text"`
	AuthorName       string `json:"author_name"`
}

そしてJSONファイルを読み込んで値を取得する箇所

	// ファイルから読み込む
	dataJSON, err := ioutil.ReadFile("./data/data.json")
	if err != nil {
		fmt.Println(err)
		return
	}

	// ファイルから読み込んだデータをSlackApp型で持つ
	var data SlackApp
	err = json.Unmarshal(dataJSON, &data)
	if err != nil {
		fmt.Println(err)
		return
	}

あとは可変にしたい箇所に、読み込んだ値を充てていけば完成です!


実行

良き

f:id:inoriko711:20201206230239p:plain

最後に

今回作成したコードは以下で公開してます
GitHub - inoriko711/slack_notice


おまけ

今日お誕生日の人、おめでとうございます。
f:id:inoriko711:20201206224947p:plain

VLANってなんだっけ

背景

先日唐突に、「VLANって何?」と訊ねられました。

咄嗟に「Virtual LANだよ」と言おうと思ったのですが、これでは説明したとは言えない。
かといって全てのVLANの種類を列挙する?…のは正気じゃない。
パケットの中身を説明する?いやいや思い出せない。

とパニパニしてしまったので、まとめておきます。

VLANってVirtual LANだよね

どういう事よ?

Virtual な LAN
つまり仮想的(論理的)なLAN(Local Area Network)てことです
これで理解できたなら天才。

VirtualなLANの何がいいの?

「VLANの何がいいの?」の答えは「物理的な繋がりとは異なるネットワーク(ブロードキャストドメイン)を構成できます!」が一番わかりやすいかと思います。

例えば会社で、来客スペースと執務スペースが同フロアにあるような時、ゲストと社員が同じネットワークを使用するのはセキュリティ的に問題あることは何となくでも感じ取れるかと思います。

踏み込んだ言い方をするのであれば
同じネットワーク…ブロードキャストドメインに属しているとARPが届いてしまいます。
このARPを不正に応答することで、割と容易になりすましができます。(ARPスプーフィング)

そのためVLANによってネットワークを分割することはとても大事なことになります。

そのほかにも
「ネットワーク回線の混雑を防ぎたい」ときにも輝くはずです。きっと多分そうでしょう。

VLANってどう実現するの?

物理的にはVLANを構成しようがしなかろうが、やることは一緒(のはず)です。
LANケーブルをスイッチングハブにさすんです。パチッと!!

大事なのはその後、スイッチングハブの設定をいじる必要があります。
スイッチの管理画面を開いて、スイッチのベンダーの指示している通りに設定しましょう。
ちなみに管理画面への接続用IPアドレスも、VLANの設定で他のネットワークから切り離すような設定にしましょう。
誰かに書き換えられちゃったら元も子もないです。

VLANの正体見たり!

先でも少し書いた通り、VLANは種類がとても多いです。
ここではその中でも特に知られている「ポートベースVLAN」「タグVLAN」に関して書きます。

ポートベースVLAN

ポートベースVLANって何

スイッチングハブの物理的なポート(LANケーブルを指した場所)毎にVLANグループを設定する方法になります。
逆に言うと、複数のVLANグループを作りたい場合は、それだけ多くのポートを使用することになります。
例)N個のVLANグループを作成したいなら、使用するポートはN個以上必要

スイッチングハブはポートを見てルーティングを決めることになります。

タグVLAN

タグVLANって何

タグVLANは、ポートベースVLANと異なり、一つのポートに対して複数のVLANを設定することができます。
これはタグVLANではパケットにタグVLANフレームを埋め込んで通信をすることで実現しております。

スイッチングハブはこのVLANフレームを見てルーティングを決めることになります。

パケット詳細

パケットの構造(先頭から)

  • 宛先MACアドレス(6バイト)
  • 送信元MACアドレス(6バイト)
  • VLANタグ(4バイト)
  • タイプ(2バイト)
  • データ(46〜1500バイト)


VLANタグの構成

  • TPID(2バイト)
  • TCI(2バイト)

正直な話、TPIDとTCIに関しては私自身詳しくは分かっておりません😇
TCIのなかにVLAN ID(タグVLANにおける、どのVLANに属するかの情報)があるのは確か。

このVLAN IDは12ビットで構成されることは覚えて置いた方が良いかもしれません。
つまり、VLAN IDとして2^{12}=4096とることができます。
ただし0,4095は使用できず、1~4094が使用できます。

まとめ

VLANでネットワークを分割することができ、セキュリティ面を高められるよ
VLANにはポートベースVLANとタグVLANがあるよ

キャンプ(テント泊)初体験記

2020年10月某日、同僚から突然キャンプに誘われました。

右も左もわからず、四苦八苦しながら乗り切った、そんな私の体験をしたためておきます。


 

女やで
キャンプは小学・中学生の頃にしたことがあるものの、カレーを作ったくらいで他の経験は皆無(キャンプとは何なのか問題)
テント泊の経験なし
焚き火キャンプファイヤーの経験あり
 

時期・場所・人

10月下旬

新潟県某所

参加人数18人?くらいのなかなかな人数で参加しました。

日頃からキャンプしている人3人、キャンプ得意そうな装いの人1人、他初心者の構成になります。

 

タイムスケジュール

いつか書く

準備したもの と 実際のところどうなの問題

テントや寝袋、調理台等はレンタルできると聞いていたので、要は防寒具をメインに持っていけば良い状態でした。



でもな、これな、一番困ってん。


 
まず10月下旬の新潟なので、そこそこ寒いんじゃないかなって印象はあったんです。

ただ実際キャンプ場がどれだけ寒いのか想像がつかなかったんですよ。

Googleさんに尋ねると該当地域の最近の気温がわかっても、キャンプ場はちょっと標高の高いとこにあると聞いてたのもあって、参考にしていいのかイマイチ分からない。

GIVE ME キャンプ場の気温情報。

 
以下実際に持っていったものと、持っていってどうだったか(私だけの、今回限りの感想です)

持っていったもの 感想 持ってってどうだったか
コンタクト 私にとっては生活必需品
吸入器 私にとっては生活必需品
化粧品・鏡 正直なくても平気
メガネ あれば便利レベル
ペン 使う気がしただけだった ×
パソコン WiFi微弱すぎた ×
充電器 Pixel5の電池の持ち、すごくよかった
モバイルバッテリー兼ライト カバンから出ることなかった ×
石鹸セット シャワー場はあれど石鹸はなかったので必須!
歯ブラシセット 要るな
下着 そりゃいるわ
ICカード 現地にたどり着くのに必要
ティッシュ 年中鼻炎だけど何故か当日は出なかった
お金 カードで何とかなってしまった
スマホ ライトとしても、行方不明者の確認のためにも大活躍
カイロ 一切使わなかった ×
タオル 炊事した後やシャワー後などで活躍
靴下 厚手の2セットで寒さ対策・濡れ対策
新潟は雨がよう降るし当日も夜中降った
ネックウォーマー 私の首は強かった ×
レギンス上下 多分コレのおかげでめちゃ暖かかった
ベスト いらなかったなぁ ×
太めのズボン 着込めた!空気の層作れた!
インナーマット 女性用テントはマットがあったので使用しなかった、けど貸した
翌日の服 前日の服は汚れるし濡れてた
マスク コロナ時代のエチケット
湯たんぽ 質の良いテントと寝袋だったのでなくても暖かかった ×
雨用の靴 雨が降らなくても露で芝が濡れまくってた!
焚き火に耐えられる上着 化学繊維は焚き火の火の粉で燃え上がる恐れがあるらしい
焚き火に耐えられる毛布 寒いから焚き火に当たりながら毛布に包まった!

逆に持って行かなかったことを後悔したものたち

  • サンダル
  • 虫(ブヨ)対策のあれこれ
  • 濡れても大丈夫なカバン

詳しくは後述します。

テントを張った感想

テントはレンタルしました。
レンタル品と一緒に取り扱い説明書(写真付き組み立て方法?)がついて来てました。
メンバーの一人が説明書を見ながら指示を出し、それに従って他のメンバーが組み立てるような形で最初は進みました。


それが案外あかんの。


指示者「まずA型のフレームを…」
作業者(A型ってどれなん)


結果都度都度集まって指示書を見ることに。


それでもあかんの。


ペグってどの方向で刺すの?
なんかフレームとテントの布の長さが合わないんだけど?
引っ張ったらフレーム抜けたわ


そんなこんなで何とか1つ張ったところ、見かねたガイドの方が助言にやってきてくれました。


学んだこと↓

  • テントは「張る」のだから、ちゃんと布を伸ばす
  • フレームは引いちゃダメ、押す
  • ペグは斜めに刺す。踏んで押し込んで良い。何なら叩かない
  • 風が吹いた時、テントの布に力がかからないように、ちゃんとフレームに接続させる


おかげで何とか2つ目を組み立てることができました。


結論↓

  • 組み立て動画が欲しい。
  • それかガイドの人が必ずいて欲しい。
  • 暗くなるとテント張るのがより一層大変→明るいうちに完成させよう

テント(寝袋)に泊まってみた感想

キャンプするって決まった時から一番怖かったのがここ、寝られるか問題。
寒くて寝られないのではないか、地面が硬くて眠れないのではないか
それが怖かったです。

でもそんなの優秀なキャンプ用品が解決してくれました。


テントに入ってすぐに気がつきました。なんかあったかい!
イメージより圧倒的に密室空間になるんですね。
コロナ感染者がいたら一発でアウトなんだろうなぁ


次に寝袋!
−8℃まで使用できる?とかいう謳い文句の寝袋だったんですけど、めちゃ暖かい!むしろ暑い!
準備した防寒具をちょっと脱ぎました。
寝心地も抜群。寝袋のイメージが180度(正しくは135度くらい?)変わりましたわ
もはや布団だわ

最後にテントとセットのインナーマット!
別で個人で所有していたインナーマットを持っていってたんですけど、テント付属ので十分でした。
まぁ私は床でも寝れるタイプなので、実はいらなかった説もあるけど


さぁ寝るぞ!となった直後ドドドと雨が降り、風がビュンビュン吹いてきました。
正直「テント大丈夫かな?」「足元に置いた荷物が濡れるのでは?」と不安でした。
でもそんな心配はいらなかったです。翌朝も何ら変わらない状態でした。

朝起きた瞬間もあったかい!何なら暑い!
数人で泊まれば、人間の熱もあって暖かさ倍増!


そんなわけで、十分すぎるくらい熟睡できました。
めでたしめでたし。

焚き火の感想

準備も火の面倒も見てないのですが、それなりに思ったことを書き溜めます。

薪の区別がつかない

よく燃えるやつ
そんなに燃えないやつ
何かしらの違いがあるらしいんですけど、全くわからない!

思ってたよりも薪を使う!

夜、最後の方は段ボールを燃やしたり着火剤を燃やしたりとクレイジーでした。
翌朝食用の薪がない!となったときは笑えました(笑えない)

火に空気を送る謎の道具がある

メンバーの一人が持ってきてたんですけど、コレがあると死にそうな火が復活するんですわ。
すごいすごい、超便利、何だコレ
 

その他

キャンプ用品は、キャンプに行く話が出た時点で揃えはじめよう

私、石原さとみと身長同じなんです

キャンプに行く直前の土日、慌てて道具・服を揃えに行ったのですけど、尽くメンズばかり。
ウィメンズ用品が少ない…というより、まずなかったです。
メンズSサイズでどうかなとも思ったのですが、それでもデカイ。超ぶかぶか。巨人の多い世界だわ。

そう、キャンプ用品はチビ向きの物が少ない


いろいろ四苦八苦した結果、Kidsの160が一番しっくりきました。
一生の不覚…

もっと早くから揃え始めて、ネット購入も視野に入るように動くべきでした

ブヨ対策

時期が時期なので蚊はいないな、虫対策いらないな、と思ってたのが運の尽き。

大量のブヨがおりました。

こやつ勝手に刺してくるねん、その瞬間は痛くないねん。
ふと見ると血が出てる、実はそれ噛まれた後です。みたいな状態。
人によっては後から腫れます
痒みがきます
私は謎の痣ができました。1週間以上経った今でも、時々痒みがあります。
普通の虫除けではあかんらしく、ハッカ油?的なものが役立つらしいです。
この情報もっと早く知りたかった。まじで。

シャワーあるやん

キャンプ場ってシャワーなんてないイメージやったんですよ。
それが案外しっかりあるやないですか。しかもめちゃ綺麗。ドライヤーまである。
多分今回行ったキャンプ場がすごくいいところだったので、他のキャンプ場にこのレベルを期待してはダメなんだと思います。
次キャンプ行く時もコレくらい設備が整ってて綺麗なところがいいです。

サンダル持ってくればよかった

朝、訳あって他のメンバーより早く起きて電話しなくてはいけなかったんですけど
そっとテントを出る為に、靴をのこのこ履いてる暇ない!絶対他のメンバーを起こす!!
めっちゃ焦りました。

まぁそうでなくても、テントと外を行き来するのにサンダルあったほうが圧倒的に楽ですわ。
まじで持ってけばよかった…

めっちゃ露が降りるやん

日が落ちた瞬間から気温がグングン下がると同時に、露が降りました。
急いで荷物をテントに避難させることに。
テントは日中に張ろう!そしてさっさと荷物を避難させよう!

後、寝る際に気がついたのですけど、荷物がテントの中(寝室部)にあると寝る時邪魔なんですよね。
キャンプ上級者のメンバーはキャリーケースのような防水性の高い鞄を持ってきており、テントの中の寝室部の外(何て言うんだ?)に置いてました。
次は私もそうしよう。

寝袋って意外と小さくまとめられる

ぎゅーーーーっと押し潰して、エイって専用の袋に入れると、とても小さくまとまりました。
本当にあの布団寝袋入ってるの?と思うくらい。
災害(避難)時用にいくつか持っていても、そんなに場所取らないしいいのでは??とか何とか思いました。
前向きに購入検討中…

借りたものはその場でチェックをしよう

キャンプ終わって、さー荷物まとめて帰ろう!となった際、お借りしたキャンプ用品の一つが足りてないことに気がつきました…
どんなに探してもない!
誰の荷物にも紛れてない!
となった時、そういえば借りたものを最初に確認してないな、もしや最初からなかったんじゃないか?と思い始めました。

小学校で、借りたものは最初に確認するよう教わった記憶はあるのですが、テンション上がっててそれどころではなかったです。
反省。

ちゃんと借りたものは最初に確認しよう
それか全ての貸し出し品にMAMORIOがついてて欲しい

焚き火台の片付け方法なんて知らなかった

灰を流さずに片付ける必要がある話とか
どれくらい綺麗にすればいいとか
気が向いたら書きます。
当日はキャンプ玄人に助けてもらいました。

DHCPとは

DHCPに関してざっくり解説します

ざっくりDHCP 

DHCPとは

DHCP:Dynamic Host Configration Protocol

直訳すると「動的ホスト構成プロトコル」でしょうか...

プロトコル=手順、ホストはざっくりコンピュータと考えると、「動的にコンピュータを構成するための手順」になりますね。

 

さて、構成って何のことでしょう?

 

皆さんもう感覚で分かっているでしょうが、現在コンピュータはネットワークでつながって、情報をやり取りしていることが殆どです。

ネットワークにつながるためには、自分のIPアドレスを取得する必要があります。

IPアドレスは1コンピュータに1個与えられているわけではなく、ネットワークにつなげる際に付与されます。

その付与を行うためのプロトコル(手順)がDHCPになります。

ちなみに付与を行う者はDHCPサーバです。そう、名の通りDHCPのためのサーバです。

メリット

DHCPサーバを利用することのメリットを挙げます。

 

1.IPアドレスの設定が楽

さあ、パソコンを立ちあげて遊ぼう!となった際、自分でIPアドレスを設定するのは至難の業です。

PC初心者の方がいきなりプロパティを開くだけでも相当苦労するでしょう。

カフェにPCを持ち込んで作業を行おうとする際にも、いちいち手作業で設定を行っているようだとめんどくさい!!

でもDHCPに任せると、それらを自動で担ってくれます。

 

2.IPアドレスの管理が楽

IPアドレスは重複すると通信障害を起こします。

手動でIPアドレスを付与する際に、どのIPアドレスが使用されており、どのIPアドレスが使用されていないかを調べるのは七面倒ですよね。

DHCPサーバに任せることで、この面倒にはおさらばができます!!

 - DHCPサーバは前もってIPアドレスをプールして(蓄えて)います。

 - ホストから要求を受けると、プールしているIPアドレスの中から未使用のアドレスを自動的にホストに割り当てます

 

3.IPアドレスが有効利用できる

先述した通り、DHCPサーバは前もってIPアドレスをプールしています。

払いだしたIPアドレスのうち、使用されなくなったもの・リース期限の切れたものは再度プールします。

これによって1台につき1IPアドレスのようなIPアドレスの浪費をしなくて済むようになります。

 

DHCPサーバから受け取る情報

DHCPサーバからは以下のような、ネットワークにつながるのに必要な情報を受け取ります。

 

参考

ネットワークに関してちょっと知識のある方は、こちらがわかりやすくておすすめです

ネスペの基礎力 -プラス20点の午後対策 (情報処理技術者試験)

ネスペの基礎力 -プラス20点の午後対策 (情報処理技術者試験)

 

 

ブログ始めます

こんにちは、いのりこと申します。

とあるIT企業でエンジニア的なお仕事をしています。

 

2018年秋にネットワークスペシャリストに合格しました。

これを機にアウトプットとしてネットワークやセキュリティ(たまに経営系のお話)に関してあれこれ書いていければいいなと思っております。

 

わかり辛いことや、質問、間違いなどありましたらコメントいただけると幸いです。

 

それではよろしくお願いいたします。