5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

DockerをインストールしてLinux系コンテナを構築したときの備忘録

Last updated at Posted at 2020-10-30

#目的

Dockerをインストールしていない状態から、Dockerをインストールしてコンテナ上のopenSUSEでzypperコマンドを使ってみる。
LPICとDocker学習を兼ねる。

#環境

macOS Catalina(バージョン10.15.7) MacBook Pro
Docker version 19.03.13

#Dockerインストール

Docker公式の指示に従い、Docker Hubからインストール。
インストール後にチュートリアルがあったので、DockerDesktopで指示どおりコマンドを入力(ボタンをクリックでもOK)。
内容としては、
alpine/gitというイメージからrepoという名前のコンテナを構築し、コンテナ上にGitHubのリポジトリからクローンを作成する。
②コンテナにあるファイルたちをローカルにコピーする。
③Dockerfileからイメージを構築し、docker101tutorialという名前を付ける。
④その作成したイメージにdocker/docker101tutorialという名前をつけ、DockerHubに上げて共有する。

$ docker run --name repo alpine/git clone https://github.com/docker/getting-started.git
$ docker cp repo:/git/getting-started/ .
$ cd getting-started/
$ docker build -t docker101tutorial .
$ docker tag docker101tutorial dockeridok/docker101tutorial 
$ docker push dockeridok/docker101tutorial

コマンド等 説明
docker run [オプション] イメージ[:タグor@ダイジェスト値] [コマンド] [引数...] 指定したイメージ上にコンテナ層を作成し、起動する。
docker create→docker startと同様の動作を行う。なお、指定したイメージがローカルにない場合はDocker Hubからダウンロードするのでdocker pullの動作を伴う場合もある。
今回は指定したイメージalpine/gitがローカルにないので、Docker Hubからダウンロードしている。
--name コンテナに名前を付ける。今回はrepoという名前を付けている。デフォルトはランダムな文字列から名前をつけている。
clone GitHubからクローンしている。ENTRYPOINTでgitを指定しているため、実質git cloneを実行している。
cp コンテナ:パス ローカルパス コンテナのファイルシステム上にある内容を、ローカルのパスにコピーする。
docker build [オプション] パス or URL or - パスにあるDockerfileから新しいイメージを構築。
-t 名前:タグ形式で名前とオプションのタグを指定。今回は名前だけを指定し、タグを省略している。
docker tag [オプション] イメージ[:タグ] [レジストリのホスト/][ユーザ名/]名前[:タグ] リポジトリ内のイメージにタグ付。今回はdocker101tutorialというイメージにdockeridok/docker101tutorialという名前をつけている。
docker push [オプション] 名前[:タグ] イメージをDocker Hubレジストリや、自分で作成したレジストリで共有できる。

#Dockerfile

イメージのベースとなるDockerfile。
Dockerは、Dockerfileから命令を読み込んで、自動的にイメージを構築する。
今回は公式サイトチュートリアルに載っていた簡単なDockerfileを見本にし、Dockerへの理解を深める。

Dockerfile

# ベースとなるイメージ
FROM node:current-slim

# Dockerfileで指定したRUN,COPYなどの命令実行時の作業ディレクトリを指定
WORKDIR /usr/src/app

# ファイルをホストからコンテナ内にコピーする。
COPY package.json .

# イメージファイルシステム内でコマンドを実行する。
RUN npm install

# コンテナのポートを解放する。
EXPOSE 8080

# コンテナで指定されたコマンドを実行。CMDはコンテナ実行時のデフォルトを提供する。
CMD [ "npm", "start" ]

# 全てのファイルなどをコンテナ内にコピーする。
COPY . .

#openSUSEのイメージをインストールし、コンテナ上でコマンドを打てるようにする

Dockerのことが何となく分かってきたので、本題のopenSUSEコンテナを作成する。

openSUSEイメージの名称がDockerHubのopensuse/leapによりわかったので、あとは走らせるだけ。
コマンドを確認するだけなら仮想マシン構築より爆速。

% docker run -it opensuse/leap:latest
Unable to find image 'opensuse/leap:latest' locally
latest: Pulling from opensuse/leap
658f48177d00: Already exists 
Digest: sha256:
Status: Downloaded newer image for opensuse/leap:latest

0a5ec012802e:/ # cat /etc/*release
NAME="openSUSE Leap"
VERSION="15.2"
ID="opensuse-leap"
ID_LIKE="suse opensuse"
VERSION_ID="15.2"
PRETTY_NAME="openSUSE Leap 15.2"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:leap:15.2"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"

0a5ec012802e:/ # zypper --version
zypper 1.14.38
コマンド等 説明
-i コンテナの標準入力(STDIN)を取得。コンテナ内で標準入力ができるようになる。
-t コンテナ内に擬似ターミナルを割り当てる。-tと合わせることで通常のターミナルのようにコマンド入力ができる(どこまで通常どおりに行えるか分からないが。)。

#CentOSでsystemctl,localectlが使用できなかったので対処する

CentOSのコンテナも構築して使っていたが、can't set the locale; make sure $LC_* and $LANG are correctと表示されるのが煩わしかったのでlocaleを変更しようとしたら、

System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to create bus connection: Host is down

と表示。
PID1をシェルが使用しているからsystemdが動けない?

[root@15900d9cd863 /]bash# ps
  PID TTY          TIME CMD
    1 pts/0    00:00:00 bash
  162 pts/0    00:00:00 ps

こちらの記事どおりにしたら解決しました。
百蔵の部屋「CentOS7コンテナでsystemctlが使えない時」

docker run -itd --privileged イメージ /sbin/init

docker exec -it コンテナ /bin/bash

[root@d7a7f918cfde /]bash# ps
PID    TTY       TIME CMD
119    pts/1     00:00:00 bash
15560  pts/1     00:00:00 ps

コマンド等 説明
--privileged コンテナに対して拡張権限(全ての権限)を与える。他のコンテナにも接続でき、ホスト上の全てのデバイスに対して接続可能になる。
/sbin/init systemdへのシンボリックリンクで、--privilegedと併用することで/sbin/initが動作してsystemctlなどが実行できるようになる
docker exec [オプション] コンテナ コマンド [引数...] 実行中のコンテナでコマンドを実行する。今回は、コンテナ内でコマンドを実行すると、「/bin/bash コマンド」という意味になる?

ついでにlocale設定。設定後はsource /etc/locale.confで反映されるはず(rebootしてコンテナから出てしまったので上記コマンドは行っていない。)。

[root@d7a7f918cfde /]bash# localectl
   System Locale: LANG=en_US.UTF-8
       VC Keymap: us
      X11 Layout: n/a
[root@d7a7f918cfde /]bash# localectl list-locales
C.utf8
[root@d7a7f918cfde /]bash# dnf -y install langpacks-ja
[root@d7a7f918cfde /]bash# localectl list-locales
C.utf8
ja_JP.eucjp
ja_JP.utf8
[root@d7a7f918cfde /]bash# localectl set-locale LANG=ja_JP.utf8
[root@d7a7f918cfde /]bash# localectl
   System Locale: LANG=ja_JP.utf8
       VC Keymap: us
      X11 Layout: n/a

#プロンプトの色付け

プロンプト部分を分かりやすくしたいので、色つけする。
参考サイト:とほほのWWW「シェル入門」

# シェル確認
$ echo $SHELL
# 設定ファイル編集。緑に色付けして時間も表示する。
$ vi /etc/bashrc
export PS1="\[\e[1;32m\][\u@\h \w][\t]\[\e[0m\]\s\ $"
#反映
$ source /etc/bashrc

#時間設定

プロンプトに時間を表示したら日本ではなかったので、日本に変更する。

[root@f95fa15cf5fb /][13:26:29]bash#timedatectl 
               Local time: 日 2020-11-01 13:26:37 UTC
           Universal time: 日 2020-11-01 13:26:37 UTC
                 RTC time: 日 2020-11-01 13:26:37
                Time zone: UTC (UTC, +0000)
System clock synchronized: no
              NTP service: n/a
          RTC in local TZ: no

[root@f95fa15cf5fb /][13:26:37]bash#timedatectl set-timezone Asia/Tokyo
       
[root@f95fa15cf5fb /][22:27:03]bash#timedatectl 
               Local time: 日 2020-11-01 22:27:07 JST
           Universal time: 日 2020-11-01 13:27:07 UTC
                 RTC time: 日 2020-11-01 13:27:07
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: no
              NTP service: n/a
          RTC in local TZ: no

 補完機能が有効にならないことが度々あって面倒だったので、有効にする。
 綺麗ではないが、以下のコマンド実行後にコンテナから抜け出し、コンテナをコミットしてイメージを作成し、そのイメージをコンテナにすることで補完機能を有効にした。

[root@f95fa15cf5fb /][22:32:18]bash#yum info bash-completion
Last metadata expiration check: 1:18:08 ago on 2020年11月01日 21時24分15秒.
Available Packages
Name         : bash-completion
Epoch        : 1
Version      : 2.7
Release      : 5.el8
Architecture : noarch
Size         : 274 k
Source       : bash-completion-2.7-5.el8.src.rpm
Repository   : BaseOS
Summary      : Programmable completion for Bash
URL          : https://github.com/scop/bash-completion
License      : GPLv2+
Description  : bash-completion is a collection of shell functions that take advantage
             : of the programmable completion feature of bash.

[root@f95fa15cf5fb /][22:42:23]bash#yum install bash-completion

#コンテナから脱出して同じ環境のコンテナに戻る

Ctrl+p,Ctrl+qでデタッチする(コンテナから出る。)。
コンテナは実行中。
コンテナに入るときは、前述のexecコマンドを入力して実行。

[root@fabcffc6d45e /][13:32:44]bash# read escape sequence

docker exec -it コンテナ /bin/bash

使用したDockerコマンドまとめ

# コンテナ削除
docker rm コンテナ名

# 実行中のコンテナを削除。--forceでコンテナを停止してから削除している。
docker rm --force コンテナ名

# 実行中だけでなく停止中のコンテナも確認
docker ps -a

# イメージ削除
docker rmi イメージ名

# イメージ全削除。-qオプションはIDのみ表示するので、引数として全イメージIDを渡している。
docker rmi `docker images -q`

# 全てのイメージ確認
docker images

# コンテナ起動。公式サイトのチュートリアルより。コマンドの詳細は後述。
docker run --publish 8000:8080 --detach --name bb bulletinboard:1.0

# 停止したコンテナを起動
docker start コンテナID or 名前

# systemdなどを動かす時のコンテナ起動
docker run -itd --privileged イメージID /sbin/init
docker exec -it コンテナID or 名前 /bin/bash

# 何らかの原因で上記コンテナが停止した時の起動法
docker start コンテナID or 名前
docker exec -it コンテナID or 名前 /bin/bash

# コンテナを起動したままコンテナから抜け出す
Ctrl+P,Ctrl+Qでデタッチしてコンテナから抜け出す

# コンテナからイメージを作成
docker commit -m "message" -a ”担当者" \
コンテナID  hogeuser/opensuse:v2
コマンド等 説明
--publish 8000:8080 コンテナのポートをホスト側に公開。ホストポート8000をコンテナポート8080に転送する。
--detach コンテナをバックグラウンドで実行。
docker commit [オプション] コンテナ [リポジトリ[:タグ]] コンテナのファイル変更や設定を反映した新しいイメージを作成する。
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?