Docker

docker ファイルの作成からコンテナの起動までの流れ

docker fileの基本

goで書いたプログラムをDockerコンテナ内で動かすためのDocker fileの例です。 動作としては、

  1. echo ディレクトリを作成します。
  2. 予め準備していた、main.go ファイルを echo ディレクトリにコピーします。
  3. go run /echo/main.go コマンドを実行して、コンテナの動作を開始します。
FROM  golang:1.15.1

RUN mkdir /echo
COPY main.go /echo 

CMD ["go", "run", "/echo/main.go"]
  • RUNは、Dockerイメージビルド時に、Dockerコンテナ内で、実行するコマンドを定義します。
  • CMDは、Dockerコンテナとして実行する際に、コンテナないで、実行するプロセスを指定します。 イメージをBuildするためのRUNに対して、、CMDはコンテナ起動時に、1度実行されます。 CMDはコンテナ内で、アプリケーションそのものを実行するイメージとなります
docker imageの起動時にパラメータを引き渡す方法。

パラメータを引き渡すためには、Docker fileにどのCommand実行時にパラメータを引渡するかをしているする必要があります。
以下のようにENTRYPOINTで指定したコマンドは、docker run コマンド実行字に引数を渡すことができます。

FROM  centos:7

#Entry point : Provide parameter to executable cmd in docker container.
ENTRYPOINT ["sh", "/sayhello/sayhello.sh"]

RUN mkdir /sayhello
COPY sayhello.sh /sayhello

#Default prameter to provide executable cmd in docker container.
#If no parameter are setting when executing cmd, this parameter is provided .
CMD ["5"]

Reference: EntryPointの例 https://gitlab.com/stm05/k8s/dockerexample/-/tree/master

docker imageのビルド

Dockerファイルの準備ができたら、Dockerfileと必要なファイルを同じディレクトリに集めて、以下のコマンドで、buildを行います。

# docker image build -t イメージ:[タグ名] Docerfile 配置ディレクトリのパス
$ sudo docker image build -t example/echo:latest .

Sending build context to Docker daemon  6.441MB
Step 1/4 : FROM golang:1.15.1
 ---> 9f495162f677
Step 2/4 : RUN mkdir /echo
 ---> Using cache
 ---> 876f76330b0c
Step 3/4 : COPY main.go /echo
 ---> Using cache
 ---> f6f3a9a2dc3a
Step 4/4 : CMD ["go", "run", "/echo/main.go"]
 ---> Using cache
 ---> 9e8663cc9057
Successfully built 9e8663cc9057
Successfully tagged example/echo:latest
docker イメージの確認

Docker ファイルのBuildに成功すると、以下のようにimageが登録されます。

# docker images
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
example/echo                             latest              9e8663cc9057        22 minutes ago      839MB
docker コンテナの実行/停止

上記のDocker imagesを指定して、Dockerのプロセスを実行します。

# docker run example/echo:latest 

コンテナの停止は以下のコマンドを利用します。

# docker stop [docker Names]
docker コンテナのポートフォワーディング

Dockerコンテナは、外部からは独立しており、Docker内のアプリケーションのポートが開放されていても、外部からはそのままでは、アクセスできないです。 アクセスするためには、Dockerホストのポートと、Docker内部のアプリケーションのポートを紐付ける必要があります。

以下のように'-p' オプションを利用することで、ポートフォワーディングの設定ができます。

-p ホストのポート:コンテナアプリケーションのポート  で指定します。

# docker run -p 9000:8080   9e8663cc9057  

上記で、起動したコンテナには、外部から9000番ポートでアクセス可能です。

なお、起動しているコンテナのどのポートが空いているかは、docker psコマンドで確認可能です。

# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
6e940bc44898        9e8663cc9057        "go run /echo/main.go"   7 minutes ago       Up 7 minutes        0.0.0.0:9000->8080/tcp   dreamy_murdock

0.0.0.0:9000->8080/tcp  となっており、ホストの9000番ポートから、コンテナの8080ポートにアクセスすることができます。

Docker コンテナ内へのアクセス

Docker コンテナ内へアクセスするためのコマンドは以下の通り。

# docker exec -it 6e940bc44898 /bin/bash
Dockerのイメージを一括で削除したい場合

Dockerの不要イメージを削除する場合は、docker image prune コマンドを利用します。 これは、dokcer自身が不要だと判断したimageが削除されます。

docker image prune
 Dockerの利用状況の取得

以下のコマンド(docker stats)を利用して、コンテナ単位で、システムリソースの利用状況を把握できます。

docker stats [Docker name]

# docker stats jolly_perlman 

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT    MEM %               NET I/O             BLOCK I/O           PIDS
7295a86a463f        jolly_perlman       0.20%               2.52MiB / 15.56GiB   0.02%               6.91kB / 0B         0B / 0B             2

Docker registryをLocalで建てて、ImageをPush する方法

  1. Docker registry をPullします。
# sudo docker pull registry
  1. Docker registry をRunさせてます。 5000ポートでアクセスできるように、設定。
#docker run -d -p 5000:5000 --name registry -e REGISTRY_STORAGE_DELETE_ENABLED=true registry:2

3. イメージをbuildします。

# docker image build -t イメージ:[タグ名] Docerfile 配置ディレクトリのパス

4. イメージをTagをつけて、resittryにPush します。 ここでは、registryがLocalにあり、5000ポートでListen しているとしています。   

# docker tag <image Tag> localhost:5000/imagename:latest
# docker push localhost:5000/imagename:latest
  1. なお、registryに登録されているイメージは、以下のように取得可能です。
$ curl http://localhost:5000/v2/_catalog
{"repositories":["video2"]}

Docker のプライベートregistryにhttpでアクセスする方法

問題

デフォルト設定では、Dockerのregistryに外のノードからhttpでアクセスしようとすると、怒られる。

$ sudo docker  push 192.168.10.100:5000/sample-application:latest 

The push refers to repository [192.168.10.100:5000/sample-application]
Get https://192.168.10.100:5000/v2/: http: server gave HTTP response to HTTPS client
解決方法

Client側の/etc/docker/にdaemon.jsonファイルを作成して、httpでアクセスしたい、registry除法を記載する。

I.E. registryが192.168.10.100 の5000ポートの場合

{
 "insecure-registries": ["192.168.10.100:5000"]
}

その後、以下のコマンドでdocker daemonをリスターとする。

#system daemon-reload 
#system restart docker.service

Docker のプライベートregistryに登録されているImageを削除する方法

  1. プライベートregistry内に登録されているImageを確認します。
$ curl localhost:5000/v2/_catalog |jq .

{
  "repositories": [
    "sample-applicatoin"
  ]
}
  1. 上記のsample-applicationのImageのタグ一覧を確認します。

APIのフォーマットは以下の通りです。 /v2/<イメージ>/tags/list

$ curl   http://localhost:5000/v2/sample-application/tags/list |jq .
{
  "name": "sample-application",
  "tags": [
    "latest"
  ]
}
  1. 削除したいイメージのDigistを確認します。

APIのフォーマットは以下の通りです。 /v2/<イメージ>/manifests/ なお、Dockerのdigistは、上記APIのレスポンスヘッダに記述されます。curlコマンドを利用する問いは、-iオプションを忘れずにつけましょう。

$ curl  -i http://localhost:5000/v2/sample-application/manifests/latest 
HTTP/1.1 200 OK
Content-Length: 7297
Content-Type: application/vnd.docker.distribution.manifest.v1+prettyjws
Docker-Content-Digest: sha256:caf02fe9a6a2ef22272d592b613ae4328865047c9c5c8c1b1f4ebf376ccb54b3
Docker-Distribution-Api-Version: registry/2.0
Etag: "sha256:caf02fe9a6a2ef22272d592b613ae4328865047c9c5c8c1b1f4ebf376ccb54b3"
X-Content-Type-Options: nosniff
Date: Fri, 06 Aug 2021 05:36:26 GMT

{
   "schemaVersion": 1,
   "name": "sample-application",
   "tag": "latest",
   "architecture": "amd64",
   "fsLayers": [
      {
         "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4"
      },
      {
         "blobSum": "sha256:c2ffe8edbb6aa773ae9760834096556bb56aa0d0f441094d2470c86afbc567d1"

Docker-Content-Digest: sha256:caf02fe9a6a2ef22272d592b613ae4328865047c9c5c8c1b1f4ebf376ccb54b3 が必要なdigist です。

4.イメージの削除

 トラブルシュート

DNSで名前解決ができない。

DockerBuild時に、以下のようなエラーが出る場合、dockerが名前を解決できていない可能性がある。

npm ERR! code EAI_AGAIN
npm ERR! errno EAI_AGAIN
npm ERR! request to https://registry.npmjs.org/semver/-/semver-6.3.0.tgz failed, reason: getaddrinfo EAI_AGAIN proxyg.co.jp

解決方法 /etc/docker/daemon.jsonDNSサーバのアドレスを入力。 /etc/docker/daemon.json

{
    "dns": ["DNSアドレス1","DNSアドレス2"]
}

dockerサービスを再起動する。

# systemctl resetart docker.service