本章では、ローカル環境にてGo言語で書かれたアプリを使用し、Docker/GitHub Packages/Kubernetesの一連の流れを実践しながら、基本操作についておさらいしていきます。
- 目次
- 3-1 Dockerの基本操作をおさらいする
- build-ship-runの流れを確認します。
- 3-2 GitHub Packagesの基本操作をおさらいする
- トークン生成、DockerイメージPushの流れを確認します。
- 3-3 Kubernetesの基本操作をおさらいする
- DockerイメージPull、ポッド起動の流れを確認します。
- 3-1 Dockerの基本操作をおさらいする
ここでは、Goアプリを使って、Dockerイメージのビルドから起動までの操作を確認します。
リポジトリの作成で、GitHubからcloneしたローカル環境のリポジトリへカレントディレクトリを変更します。
$ cd cicd-handson-2021-code/apps
Dockerイメージのビルドに必要な、以下ディレクトリが存在することを確認します。
cicd-handson-2021-code/apps/server
Dockerfileは、Dockerイメージのビルド時に、事前に実施しておきたい操作をコードとして記述したファイルです。
主に、OSやミドルウェア、コマンド実行、デーモン実行、環境変数などの設定を記述することが可能で、
Dockerfileを使ってイメージをビルドすることで、その設定をコードとして柔軟に管理することができます。
cicd-handson-2021-code/apps
配下に、以下のDockerfileを作成します。
※ここでは、コンテナ内ポート9090で公開するサーバ側アプリをビルドするためのDockerfileを作成します。
- ファイル名:
Dockerfile
# ベースイメージ指定
FROM golang:latest
# ワークディレクトリを指定
WORKDIR /app
# ホストOSのapps内全てをWORKDIRにコピー
COPY . ./
# ビルド
RUN go build -o ./server-run ./server
# コンテナのポートを9090で公開
EXPOSE 9090
# アプリ実行
CMD [ "./server-run" ]
cicd-handson-2021-code/apps
配下に、Dockerfileが配置されていることを確認します。
作成したDockerfileを使用して、Dockerイメージをビルドします。
-t
:"名前:タグ"形式で名前とオプションのタグを指定します。
$ docker image build -t go-image:base .
※Docker v1.13 以降では、 旧docker build
⇒新docker image build
コマンドが推奨されています。
[+] Building 20.2s (10/10) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 365B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/golang:1.16 2.9s
=> [auth] library/golang:pull token for registry-1.docker.io 0.0s
=> [1/4] FROM docker.io/library/golang:1.16@sha256:87cbbe43ece5024f0745be543c81ae6bf7b88291 15.8s
=> => resolve docker.io/library/golang:1.16@sha256:87cbbe43ece5024f0745be543c81ae6bf7b88291a 0.0s
=> => sha256:0c6e622a0ff6a2c83bb5b6f0f939367cf40083754b34e48f17cfcc73b0 129.04MB / 129.04MB 11.9s
=> => sha256:54406b2e8bb95003bcec911562d5606af1a17de7a2fcc7e8d7258fcb6e9a2fe 1.80kB / 1.80kB 0.0s
=> => sha256:7669e289697491b9ef28ca9dd0958a6f7ff9ddc0d50cefe1a58acc74b37ddd9b 155B / 155B 0.3s
=> => sha256:87cbbe43ece5024f0745be543c81ae6bf7b88291a8bc2b4429a43b7236254ec 2.36kB / 2.36kB 0.0s
=> => sha256:019c7b2e3cb8185c3c454f24679a7c83add6d31427e319d8bee35b12707f9a3 6.99kB / 6.99kB 0.0s
=> => extracting sha256:0c6e622a0ff6a2c83bb5b6f0f939367cf40083754b34e48f17cfcc73b05ad99c 3.6s
=> => extracting sha256:7669e289697491b9ef28ca9dd0958a6f7ff9ddc0d50cefe1a58acc74b37ddd9b 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 7.67MB 0.1s
=> [2/4] WORKDIR /app 0.1s
=> [3/4] COPY . ./ 0.1s
=> [4/4] RUN go build -o ./server-run ./server 1.1s
=> exporting to image 0.1s
=> => exporting layers 0.1s
=> => writing image sha256:d7aa4942052cd829b7556ea6dd31615b968b6c2ea946edb534b77207fbeaa175 0.0s
=> => naming to docker.io/library/go-image:base 0.0s
作成されたDocker imageを確認します。
$ docker image ls
※Docker v1.13 以降では、 旧docker images
⇒新docker image ls
コマンドが推奨されています。
REPOSITORY TAG IMAGE ID CREATED SIZE
go-image base 220026ab99c0 4 minutes ago 938MB
go-image
が表示されていることを確認します。
ここでは、Dockerイメージのビルドを確認できたDockerfileをcicd-handson-2021-code
リポジトリへPushします。
gitコマンド初回実行の場合は、任意のメールアドレス、ユーザ名を設定します。
最初にGitHubのユーザ名を確認します。 GitHubの右上のアイコンをクリックすることで確認できます。
"Your Name"
に確認したユーザ名を入力します。
$ git config user.email "[email protected]"
$ git config user.name "Your Name"
Dockerfile
をインデックス(コミット対象)に追加します。
$ git add Dockerfile
インデックスにあるDockerfile
をコミットします。
-m
:コメントメッセージを設定します。
$ git commit -m "Add Dockerfile"
[main da54a41] Add Dockerfile
1 file changed, 17 insertions(+)
create mode 100644 apps/Dockerfile
1 file changed
、apps/Dockerfile
と変更が表示されていることを確認します。
コミット内容を、リモートリポジトリorigin
上のmain
ブランチへ反映します。
$ git push origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 16 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 561 bytes | 561.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/<GITHUB_USER>/cicd-handson-2021-code.git
71c5d70..a80279a main -> main
※<GITHUB_USER>
は、GitHubユーザ名に置き換わっている状態。
cicd-handson-2021-code
リポジトリのmain
ブランチへPushされていることを確認します。
作成されたDocker imageからDockerコンテナを起動します。
--rm
:コンテナ終了時にコンテナ自動的に削除します。--name
:起動時のコンテナ名を指定します。-d
:コンテナをバックグラウンド実行します。
$ docker container run --rm --name go-container -d go-image:base
※Docker v1.13 以降では、 旧docker run
⇒新docker container run
コマンドが推奨されています。
8d3a4f0c85e671284ec4cab7c973cbbf91318f54583059b15db4419f6903af56
コンテナIDが表示されていることを確認します。
起動されたDockerコンテナを動作確認します。
$ docker container ls
※Docker v1.13 以降では、 旧docker ps
⇒新docker container ls
コマンドが推奨されています。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8d3a4f0c85e6 go-image:base "./server-run" 2 minutes ago Up 2 minutes 9090/tcp go-container
PORTS
に9090/tcp
と表示されていることを確認します。
GoアプリへGETリクエストを送信し、レスポンスを確認します。
$ curl http://localhost:9090/health
curl: (7) Failed to connect to localhost port 9090: Connection refused
Connection refused
と表示され、9090ポートへの接続に失敗することを確認します。
ここで、少し考えてみましょう。なぜ、接続に失敗するのでしょうか?
Goアプリにて公開設定したポート9090は、コンテナ内に限定されたコンテナポートであることを理解する必要があります。つまり、コンテナ内からコンテナポート9090へのアクセスは可能ですが、コンテナ外部(ローカルPC)からのコンテナポートへのアクセスは不可能であることを意味します。この場合には、Dockerのポートフォワーディング機能を利用し、ホストマシンのポートをコンテナポートに紐付け、コンテナ外との通信を可能にすることができます。以下で手順を確認します。
ポート設定が出来ていないコンテナを停止します。
$ docker container stop go-container
※Docker v1.13 以降では、 旧docker stop
⇒新docker container stop
コマンドが推奨されています。
また、このコマンドでは、docker container stop <"NAME" or "CONTAINER ID">
のように、コンテナ名以外に、コンテナIDを指定してコンテナを停止させることも出来ます。
go-container
Dockerコンテナを起動するで、--rm
オプションを指定して起動されたDockerコンテナが、コンテナ停止と共に削除されていることを確認します。
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
go-container
がコンテナ一覧に存在していないことを確認します。
作成されたDocker imageからDockerコンテナを起動します。
※ここでは、9090で公開したコンテナ内ポートを、9091でコンテナ外へ公開するための紐付け設定を行います。
-p
:{コンテナ外部側ポート}:{コンテナ内部側ポート}の書式で記述可能です。
$ docker container run --rm --name go-container -d -p 9091:9090 go-image:base
※Docker v1.13 以降では、 旧docker run
⇒新docker container run
コマンドが推奨されています。
d94c925240845c03b2f2dff0d43aea9d9b7c2f86184309e84b2cb4e93ff97c0a
コンテナIDが表示されていることを確認します。
起動されたDockerコンテナを動作確認します。
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d94c92524084 go-image:base "go run /work/main.go" 15 seconds ago Up 14 seconds 0.0.0.0:9091->9090/tcp, :::9091->9090/tcp go-container
PORTS
にポートフォワーディング設定がされていることを確認します。
9090ポート(コンテナ内部)⇒9091ポート(コンテナ外部)で公開されたGoアプリへGETリクエストを送信し、レスポンスを確認します。
$ curl http://localhost:9091/health
または、任意のブラウザで http://localhost:9091/health へアクセスしてください。
{"status":"Healthy"}
{"status":"Healthy"}
がレスポンスされることを確認します。
$ docker container stop go-container
go-container
ポートフォワーディング設定をしてDockerコンテナを起動するで、--rm
オプションを指定して起動されたDockerコンテナが、コンテナ停止と共に削除されていることを確認します。
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
go-container
がコンテナ一覧に存在していないことを確認します。
ここでは、ローカル環境で作成したDockerイメージをGitHub Packagesへpushします。
GitHubのPersonal Access Tokenの取得で作成し、ローカルディレクトリへ保存したPersonal Access Token(以下PAT)を使用して、docker login
コマンドで、GitHub Packagesの認証を受けることができます。また、ローカルファイルからトークンを読み取るDockerの--password-stdin
フラグを使うことをおすすめします。
$ cd "token.txtを保存した任意のローカルディレクトリ"
$ cat token.txt | docker login https://docker.pkg.github.com -u <GITHUB_USER> --password-stdin
Login Succeeded
ここでは、Docker imageをビルドするで作成したDockerイメージにタグ付けを行います。<GITHUB_USER>をリポジトリを所有するGitHubユーザ名で、REPOSITORYをプロジェクトを含むリポジトリの名前で、IMAGE_NAMEをパッケージもしくはイメージの名前で、VERSIONをビルドの時点のパッケージバージョンで置き換えてください。
$ docker image tag go-image:base docker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image:base
※Docker v1.13 以降では、 旧docker tag
⇒新docker image tag
コマンドが推奨されています。
<GITHUB_USER>
をGitHubユーザ名に置き換えてコマンドを実行します。
新しくタグ付けされたDocker imageを確認します。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
go-image base 220026ab99c0 4 hours ago 862MB
docker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image base 220026ab99c0 4 hours ago 862MB
※<GITHUB_USER>
は、GitHubユーザ名に置き換わっている状態。
docker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image
が表示されていることを確認します。
GitHubユーザ名を確認します。
$ cd cicd-handson-2021-code
$ git config user.name
<ご自身のGitHubユーザ名>
$ docker image push docker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image:base
※Docker v1.13 以降では、 旧docker push
⇒新docker image push
コマンドが推奨されています。
<GITHUB_USER>
をGitHubユーザ名に置き換えてコマンドを実行します。
The push refers to repository [docker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image]
3b29f7317fbb: Pushed
23255aaac099: Pushed
903b16bd3e46: Pushed
2f3906bb26c9: Pushed
d1c59e37fbfc: Pushed
ad83f0aa5c0a: Pushed
5a9a65095453: Pushed
4b0edb23340c: Pushed
afa3e488a0ee: Pushed
base: digest: sha256:11dd65371181d74b33c84b18f4f6ba87537cdbab7c884ef12ee6429865c0f640 size: 2209
※<GITHUB_USER>
は、GitHubユーザ名に置き換わっている状態。
端末によっては、すべてPushed
になるまでしばらくかかります。
実行結果が、全てPushed
になっていることを確認し、GitHub画面のPackagesにgo-image
が公開されていることを確認します。
GitHub Packagesの画面に出てくるまで、数分かかることがあります。
ここでは、Minikubeを使って、Kubernetesクラスタの起動からオブジェクトの作成までの操作を確認します。
Minikubeを参考に、minikube start
、kubectl get nodes
、kubectl get pods
コマンドを実行し、Minikubeを起動します。
Github PackagesにPushしたDockerイメージを使って、ポッドを作成するためのマニフェストを記述する前に、Docker imageをビルドするとDockerタグを付与するで作成した2つのローカル環境のDockerイメージを削除しておきます。
$ docker image rm go-image:base
$ docker image rm docker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image:base
※<GITHUB_USER>
をGitHubユーザ名に置き換えてコマンドを実行します。
Untagged: go-image:base
Untagged: docker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image:base
Untagged: docker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image@sha256:11dd65371181d74b33c84b18f4f6ba87537cdbab7c884ef12ee6429865c0f640
Deleted: sha256:f0e3dbfbe4c7cf3d65a39f33d9cb5bb049ca063b1b40dc7a55ef055d983c0b91
※<GITHUB_USER>
は、GitHubユーザ名に置き換わっている状態。
ローカルにgo-imageのDocker imageが存在しないことを確認します。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
go-image
とdocker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image
が一覧に存在しないことを確認します。
※<GITHUB_USER>
は、GitHubユーザ名に置き換わっている状態。
--save-config
:作成した現在の設定をannotationに保存します。--docker-server
:Dockerレジストリサーバを指定します。--docker-username
:GitHub登録時のユーザ名を指定します。--docker-password
:GitHubのPersonal Access Tokenの取得で作成したGitHubのPAT(Personal Access Token)を指定します。--docker-email
:GitHub登録時のメールアドレスを指定します。
$ kubectl create secret docker-registry --save-config dockerconfigjson-github-com --docker-server=docker.pkg.github.com --docker-username=<GITHUB_USER> --docker-password=<PERSONAL_ACCESS_TOKEN> --docker-email=<GITHUB_EMAIL>
※ghcr.io への読み書きについて、Working with the Container registryによると、--docker-password
には、GitHubのPATを指定する必要があります。間違えてGitHub登録時のパスワードを入力しないよう注意が必要です。
secret/dockerconfigjson-github-com created
リポジトリの作成で、GitHubからcloneしたローカル環境のリポジトリへカレントディレクトリを変更します。
$ cd cicd-handson-2021-config/manifests
Kubernetesでは、作成するポッドのリソース構成をマニフェストファイルにコードで記述することができます。
cicd-handson-2021-config/manifests
配下に、以下のマニフェストファイルを作成します。
- ファイル名:
goapp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: goapp-deployment
spec:
selector:
matchLabels:
app: goapp
template:
metadata:
labels:
app: goapp
spec:
containers:
- name: goapp
image: docker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image:base
ports:
- containerPort: 9090
imagePullSecrets:
- name: dockerconfigjson-github-com
※imagePullSecrets
にDockerコンテナレジストリ認証用のクレデンシャル(Secret)を作成するで作成したクレデンシャル(Secret)保存名dockerconfigjson-github-com
を指定し忘れないよう注意が必要です。
<GITHUB_USER>
は、GitHubユーザ名に置き換わっている状態。
マニフェストファイルからポッドを作成します。
-f
:ファイル名を指定します。
$ kubectl apply -f goapp.yaml
deployment.apps/goapp-deployment created
goapp-deployment
の作成結果が表示されていることを確認します。
-o wide
:より詳細なリストを表示します。
$ kubectl get deploy,pods -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/goapp-deployment 1/1 1 1 8m56s goapp docker.pkg.github.com/<GITHUB_USER>/cicd-handson-2021-code/go-image:base app=goapp
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/goapp-deployment-6c85ff5cc-6pc89 1/1 Running 0 8m56s 172.17.0.2 minikube <none> <none>
※<GITHUB_USER>
は、GitHubユーザ名に置き換わっている状態。
STATUS
がRunning
になっていることを確認します。
ここでは、ポッドの作成を確認できたマニフェストファイルをcicd-handson-2021-config
リポジトリへPushします。
goapp.yaml
をインデックス(コミット対象)に追加します。
$ git add goapp.yaml
インデックスにあるgoapp.yaml
をコミットします。
$ git commit -m "Add goapp.yaml"
[main 28d94de] Add goapp.yaml
1 file changed, 17 insertions(+)
create mode 100644 manifests/goapp.yaml
1 file changed
、manifests/goapp.yaml
と変更が表示されていることを確認します。
コミット内容を、リモートリポジトリorigin
上のmain
ブランチへ反映します。
$ git push origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 16 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 561 bytes | 561.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/<GITHUB_USER>/cicd-handson-2021-config.git
71c5d70..a80279a main -> main
※<GITHUB_USER>
は、GitHubユーザ名に置き換わっている状態。
cicd-handson-2021-config
リポジトリのmain
ブランチへPushされていることを確認します。
ローカルのポートを任意のPodのポートに転送するための設定を行います。ここではローカルの9092番ポートをdeploymentの9090番ポートに転送します。
$ kubectl port-forward deployment.apps/goapp-deployment 9092:9090
Forwarding from 127.0.0.1:9092 -> 9090
Forwarding from [::1]:9092 -> 9090
9092 -> 9090
の転送設定が表示されていることを確認します。
任意のブラウザにて、以下のURLを実行し、疎通できていることを確認します。
http://localhost:9092/health
{"status":"Healthy"}
{"status":"Healthy"}
が表示されていることを確認します。
マニフェストファイルから作成したポッドを削除します。
-f
:ファイル名を指定します。
$ kubectl delete -f goapp.yaml
deployment.apps "goapp-deployment" deleted
goapp-deployment
の削除結果が表示されていることを確認します。