🐳

【Docker】コンテナの勉強会まとめ #3 -ポートフォワーディングの実施-

2023/07/29に公開

前回の記事

コンテナの勉強会まとめ #2 -Dockerの基礎からコンテナのデプロイまで-

本記事でのゴール:ポートフォワーディングを実施する

以下の本をベースに、ポートフォワーディングを実施する。
対応ページ:p.38~46
https://www.amazon.co.jp/Docker-Kubernetes-実践コンテナ開発入門-山田-明憲/dp/4297100339/ref=sr_1_1?__mk_ja_JP=カタカナ&crid=2O1TR1IVGXC7O&keywords=Docker%2FKubernetes+実践コンテナ入門&qid=1689260001&sprefix=docker%2Fkubernetes+実践コンテナ入門%2Caps%2C183&sr=8-1

実際にやってみる

事前準備

p.38~44の手順を実施する。

  1. main.goというファイル名で簡易アプリケーションを作成する。
package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        log.Println("received request")
        fmt.Fprintf(w, "Hello Docker!!")
    })

    log.Println("start server")
    server := &http.Server{Addr: ":8080"}
    if err := server.ListenAndServe(); err != nil {
        log.Println(err)
    }
}
  1. Dockerfileを作成する。
FROM golang:1.9

RUN mkdir /echo
COPY main.go /echo

CMD ["go", "run", "/echo/main.go"]
  1. Dockerイメージのビルドをする。
docker image build -t example/echo:latest .
名前空間とは?

p.41に「名前空間=衝突回避につける文字列」といったような文言があるが、それがどういうことか理解するために、Docker Hubで例を見てみる。
※Docker Hubとは、Docker社が提供している、Dockerイメージの共有サイト。

以下画像のようにDocker Hubで「todoapi」と検索をすると、400以上の大量のDockerイメージが抽出される。すると、どれも「todoapi」の前に何かしらの文字列(=名前空間)が付与されているのがわかる。
このように、同じDockerイメージ名が大量に生成される場合は、名前の姓の部分のような形で名前空間を付け、Duckerイメージを区別させることがある。

  1. Dockerコンテナを実行する。
docker container run example/echo:latest
  1. Docker container lsで実行中のコンテナを確認する。
docker container ls

CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS     NAMES
5c189f940994   example/echo:latest   "go run /echo/main.go"   17 seconds ago   Up 16 seconds             gallant_banach

ポートフォワーディング実践

p.45で示されている通り、このままGETリクエストを送信していても、以下画像のような状態でのリクエストになるためFailed to connectが発生する。

そのため、Dockerコンテナの実行時に以下のように-pオプションを追加する。

-p {ホスト側のポート}:{コンテナポート}

docker container run -p 9000:8080 example/echo:latest

上記コマンドで実行されることを図にすると、以下のようになる。

以上のことを踏まえて、改めてubuntuでcurlコマンドを使ってリクエストを送信してみる。

curl http://localhost:9000/
Hello Docker!!

レスポンスが無事に返ってきた。

補足

docker container ls コマンドを叩き、PORTSの列を見ると、ポートフォワーディングが行われていることが確認できる。

docker container ls
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                    NAMES
3e6430f4585b   example/echo:latest   "go run /echo/main.go"   4 seconds ago   Up 3 seconds   0.0.0.0:9000->8080/tcp   heuristic_dewdney

また、コマンドプロンプトでnetstatコマンドを叩くと、httpへの通信が確立されていることも確認できた。

netstat

TCP    XX.XX.XXX.XXX:49909    202.90.14.10:http      TIME_WAIT

所感

ポートフォワーディングの話で、改めてターミナル上で見えている世界と、コンピュータで行われていることの違いが鮮明になり、理解するのに少々時間がかかった。しかし学習をなおざりにしなかったおかげで徐々にコンピュータの世界のことを理解できている実感が湧き、嬉しい。

Discussion