Docker 備忘録
どんなものか
- https://www.docker.com/
- 解説:https://tech-lab.sios.jp/archives/18811
ミドルウェア以上のものをコンテナと呼ばれるもので仮想化する。
よく活用されている場面としては以下に記す。
1.開発アプリケーションのバージョンアップや開発のとき
⇒現在のアプリケーション郡をコンテナに収容し、それをコピーすることで同じ環境で自由に触れる環境が出来上がる
出来上がった環境をcommit?することで、本番環境へ切り替えも可能?
2.運用中のサーバプログラムの更新
⇒現在動作中のサーバプログラム類をコンテナ化して、それをコピーしてパッチ、バージョンアップを検証できる
- RHEL8(Red Hat Enterprise Linux 8)および CentOS8 からは Docker の代わりに Podman の使用が推奨されている.
CentOS 8 (2021 7/25)
# dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # dnf -y install docker-ce docker-ce-cli containerd.io --nobest --allowerasing
リポジトリがあるようなので,それから入れなおす.
- # rpm -e docker-ce-3:19.03.15
- # rpm -e containerd.io-1.2.6 --force
- 依存関係が複雑なので,dnf を使う
- # dnf erase containerd.io-1.2.6
# dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # dnf -y install docker-ce docker-ce-cli containerd.io
CentOS8 の場合の事前準備 (2020 8/15)
- CentOS8のcontainerd.io のバージンが古いので RPM で直接入れる
# dnf install container-selinux # wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm # rpm -ih containerd.io-1.2.6-3.3.el7.x86_64.rpm
- containerd.io が runc と競合する場合は
- runc は containerd.io と被る(同等?)の様
# rpm -e buildah # rpm -e cockpit-podman # rpm -e toolbox # rpm -e podman # rpm -e containers-common-1-2.module_el8.5.0+890+6b136101.noarch (必要なら) # rpm -e runc # rpm -ihv containerd.io-1.2.6-3.3.el7.x86_64.rpm
- Install & Getting Start へ
#br
もし podman が必要なら containerd.io をインストール後に,入れ直す.
# yum install podman -y # yum install toolbox -y # yum install cockpit-podman -y # yum install buildah -y
本体の Install & Getting Start
# wget -qO- https://get.docker.com/ | sh .............. # systemctl enable docker # systemctl start docker # docker run hello-world
or
# dnf install docker-ce # systemctl enable docker # systemctl start docker # docker run hello-world
CentOS6
- yum install https://get.docker.com/rpm/1.7.1/centos-6/RPMS/x86_64/docker-engine-1.7.1-1.el6.x86_64.rpm
- chkconfig --level 3 docker on
- 注)ipv6 が OFF だと bridge.ko の読み込みで,シンボル(ipv6_dev_get_saddr)未定義のエラーを起こす.
- Error starting daemon: Error initializing network controller: Error creating default \"bridge\" network: package not installed
- NSLでは /etc/modprobe.d/dist.conf の最終行をチェック <-- ここで ipv6 を止めている.
CentOSを使ってみる2
# docker pull centos:centos7 # docker run -ti -d --name centos7 centos:centos7 # docker exec -it centos7 /bin/bash [root@fbd5aeb4046a /]#
コンテナ
- コンテナ状況確認
- docker ps
- コンテナ状況確認(過去の終了したものも含む)
- docker ps -a
- コンテナから抜ける
- Ctrl+p, Ctrl+q
- コンテナへの接続を再開する
- docker attach コンテナID(またはコンテナ名)
- コンテナ内でシェルが動いていないとダメ.exit で抜けるとコンテナが停止する.
- docker exec -it コンテナID(またはコンテナ名) bash
- コンテナでPID=1のプロセスを実行する. exit で抜けてもコンテナは停止しない.
- docker attach コンテナID(またはコンテナ名)
- コンテナの削除
- docker rm コンテナID(またはコンテナ名)
- コンテナを止める
- docker stop コンテナID(またはコンテナ名)
- 止まっているコンテナを動かす
- docker start コンテナID(またはコンテナ名)
- コンテナのログを表示
- docker logs コンテナID(またはコンテナ名)
- docker logs コンテナID(またはコンテナ名)
イメージ
- イメージ一覧
- docker images
- ダウンロード または 更新
- docker pull イメージ名(:TAG)
- イメージ削除
- docker rmi イメージ名
- イメージ名の変更(A->B タグの付け替え)
- # docker tag A B
- # docker rmi A
- イメージを保存
- docker stop コンテナ名
- docker commit イメージ名
退避と復元
- ファイルシステムの書き出し
- docker export コンテナID(またはコンテナ名)
- tar 形式で標準出力に出力される.
- 例) docker export vyos_netp | ( cd rootfs; tar xfvp -)
- ファイルシステムの読み込み
- docker import ファイル名(tar形式) イメージ名
- 例)tar -C rootfs -c . | docker import - vyos_netp:200920
- イメージの保存
- docker save コンテナID(またはコンテナ名)
- tar 形式で標準出力に出力される.
- 例) docker save vyos_netp | ( cd rootfs; tar xfvp -)
- イメージの読み込み
- docker load
- tar 形式のイメージを標準入力から入力
- 例)tar -C rootfs -c . | docker load
使用していない(孤立した)リソースの削除
- システム: docker system prune
- イメージ: docker image prune
- コンテナ: docker container prune --filter "until=24h"
- ボリューム: docker volume prune --filter "label!=keep"
ファイル(Volume)共有
- volume : /var/lib/docker/volumes
- Podman : /var/lib/containers/storage/volumes
- DB: /var/lib/docker/volumes/metadata.db (PC毎に持つ必要がある)
- POdman(特殊ファイル): /var/lib/containers/storage/volumes/backingFsBlockDev 特に処理する必要はない(と思う)
- POdman(特殊ファイル): /var/lib/containers/storage/volumes/backingFsBlockDev 特に処理する必要はない(と思う)
none タグのイメージの名前(表示)を消す.
- 同じ名前のタグ付きイメージ名を作成し,それを消す.
docker tag 7fe93d9d7854 jupyterhub/singleuser:del (jupyterhub/singleuser:<none> の場合) docker rmi jupyterhub/singleuser:del
- 名前も none の場合は,docker tag で指定する名前は何でもよい.
cockpit-docker
- https://pkgs.org/download/cockpit-docker
- CentOS8 用は無いが,CentOS7用が使える(要 Python2)
最善策
- リモートとローカルの unix ソケットファイルを ssh でつなぐ.
- Docker の動いているマシンで,グループ docker に属するユーザを作成(例えば docker).
- パスワードを設定しておく.起動シェルは要らない.
- # adduser docker -u 105 -g docker -d /var/lib/docker -s /sbin/nologin
- # asswd docker
- パスワードを設定しておく.起動シェルは要らない.
- ローカルマシンで以下のコマンドを実行.
- ssh -fNL /var/run/mdlds.sock:/var/run/docker.sock docker@202.26.150.55
- chgrp apache /var/run/mdlds.sock
- chmod g+rw /var/run/mdlds.sock
- コマンド実行時は DOCKER_HOST=unix:///var/run/xxx.sock または docker -H unix:///var/run/mdlds.sock ps
- docker_rsock.sh
- Docker の動いているマシンで,グループ docker に属するユーザを作成(例えば docker).
ボツ SSH ポートフォワードを使用する.
- 202.26.150.55で動いている場合
# ssh -fNL localhost:9099:/var/run/docker.sock root@202.26.150.55 (rootログインがセキュリティ的に弱い) # export DOCKER_HOST=localhost:9099 # docker volume ls
Docker の実効ユーザを root 以外にしておく.ムリポ. Rootlessモードは何か違う.- ローカルマシンでは,Dockerデーモンは不要.クライアントのみで可.
- ログイン相手を docker グループのユーザにする.
- でもローカルポートにアクセス可能なら,結局やばい状況になる..ネ.
- でもローカルポートにアクセス可能なら,結局やばい状況になる..ネ.
ボツ docker の通信機能を使用する
- /usr/lib/systemd/system/docker.service
- ex.) ExecStart=/usr/bin/dockerd -H fd:// -H tcp://202.26.150.55:9099 --containerd=/run/containerd/containerd.sock
- systemctl daemon-reload
- systemctl restart docker
- ssh:// を指定するとエラー.man でも -H に ssh は載っていない.
- よく考えれば,リモートからは無条件でコマンドを受け入れる.やばいです.
Dcoker 内から DNSが引けない (その他のサービスも同様)
- ホストの firewall の影響
- ホストのfirewalld を止めてからイメージを実行
- ホストの firewall の条件を調べること
- Docker イメージが動いている最中に止めて駄目,=> Dockerを再起動
rattydave/jupyterhub
- C++, Java, Python, Tensorflow, Julia, SQL, NodeJS, Bash and more
- https://hub.docker.com/r/rattydave/jupyterhub
- 重い(10G).非力マシンではタイムアウト(30s)する.
jupyterhub/singleuser
/opt/conda/bin/conda update --prefix /opt/conda --all -y apt-get update -y apt-get upgrade -y apt-get install vim -y apt-get install subversion -y apt-get install make -y apt-get install automake -y apt-get install gcc -y apt-get install zlib1g-dev -y apt-get install mlocate -y
docker commit すると,起動時のオプション(arguments)まで保存する.
- 次回起動すると,オプションが 2重になる.なんてこったい! docker build では大丈夫(そもそも起動していない)
- 起動時のオプションは,イメージ(/var/lib/docker/image/overlay2/imagedb/....)に Cmd[ ] に値として保存されている.
- イメージファイルはテキスト(!?)なので,Cmd[ ] に何が書いてあるかわかる.
- "Cmd":["start-notebook.sh","--ip=0.0.0.0","--port=8888","--notebook-dir=/home/teacher/iseki/jupyter","--SingleUserNotebookApp.default_url=/lab"]
- しっかりコマンドが入っている.
- 流石に直接編集するのは躊躇われる.(一回やってみる?)
- エディタで直接編集したら,Docker から見えなくなった.まあ予想通り.
- "Cmd":["start-notebook.sh","--ip=0.0.0.0","--port=8888","--notebook-dir=/home/teacher/iseki/jupyter","--SingleUserNotebookApp.default_url=/lab"]
- ちゃんと動くやつの Cmd[ ] を確認して,docker commit 起動時に -C オプションで変更可!
- jupyter の場合: docker commit -c 'CMD ["start-notebook.sh"]' jupyter_old jupyter_new
- /etc/passwd と /etc/group も元に戻しておく
- jupyter の場合: docker commit -c 'CMD ["start-notebook.sh"]' jupyter_old jupyter_new
Jupyter で色々やっていたらコンテナが続々と自動生成->消滅 を繰り返している
- 何をどうやってもコマンドレベルでは停止しない
# systemctl stop docker # mv /var/lib/docker /var/lib/docker- # reboot
- Docker Swarm のせいかも.Swarm から強制離脱すればよかった模様
# docker swarm leave --force
docker run実行時のiptablesエラー
- ネットワーク設定を削除し,docker を再起動する
# \rm -r /var/lib/docker/network/files/* # systemctl restart docker
Dockerfile による RUNで,pipがNewConnectionError を出す.
- CentOS8 固有のエラーらしい.CentOS8 は Docker 未サポートだからな~
- Docker は iptables を操作するが,CentOS8では iptables ではなくて nftablesを利用しているのが原因のよう.
- Docker の iptables のコマンドが一部失敗している.
- https://qiita.com/DaichiSasak1/items/11687a3c613c8811350c
- 一つの解決法として Proxy サーバを立てると良いみたい
# yum install squid -y # systemctl enable squid # systemctl start squid # firewall-cmd --add-port 3128/tcp --permanent # filewall-cmd --reload # vi Dockerfile (pip にオプション --proxy=IPアドレス:3128 を追加)
- Dockerfile 内の名前解決については以下のRUNコマンドで確認可能
- python -c "import socket; print(socket.gethostbyname('security.ubuntu.com'))"
- python -c "import socket; print(socket.gethostbyname('security.ubuntu.com'))"
Counter: 2199,
today: 1,
yesterday: 0
最終更新: 2023-05-05 (金) 10:17:58 (JST) (491d) by iseki