20190524のdockerに関する記事は10件です。

Ubuntu 18.04のインストールログ(自分用)

インストール - Windowsとデュアルブートする

参考にした記事:2つの別ディスク (HDD) にそれぞれ Windows と Ubuntu をインストールする

WindowsとUbuntuはそれぞれ別のSSDにインストールする。Windowsは既にインストール済。

DVDからインストーラを立ち上げる。インストールの種類では「それ以外」を選ぶ。
パーティションの設定は次の通り。

  • swap
    • サイズ:メモリの2倍(昔どこかで根拠を読んだけど詳細は忘れてしまった)
    • 論理パーティション
    • 利用方法:スワップ領域
  • メイン
    • サイズ:残りを全部
    • 基本パーティション
    • マウントポイント:/

ブートローダをインストールするデバイス には、Ubuntuをインストールするディスクを選ぶ。Windowsがインストールされているディスクを選んでしまうと、Windowsのブートローダを上書きしてしまって面倒なことになる。

ディレクトリ名を英語にする

参考にした記事:Ubuntuでホームディレクトリの中身を英語にする

ターミナルを開き、以下のコマンドを実行する:

$ LANG=C xdg-user-dirs-gtk-update

アップデート

$ sudo apt update
$ sudo apt upgrade

時計がずれる問題

参考にしたサイト:

WindowsとUbuntuとで時計に9時間のずれが生じてします。これは、システム時刻について、WindowsではLocal time(ローカル時)、LinuxではUTC(協定世界時)を使っていることに起因するらしい。したがって、どちらかに統一すればいい。ここではUTCに統一する。

コマンドプロンプトを管理者権限で開き、次のコマンドを実行する:

reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_DWORD /f

docker

インストール

参考にしたサイト:Get Docker CE for Ubuntu

書いてあるとおりにコマンドを実行すればよい。ありがたい。

# 依存関係を入れる
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

# GPG鍵を入れてからstable版をインストール
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
$ sudo apt update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

# 動作確認
$ sudo docker run hello-world

dockerグループの作成

参考にした記事:nvidia-docker でポータブルな機械学習の作業環境を作る

sudoなしでdockerを実行するため。

# もしグループdockerが無ければ、sudo groupadd dockerで作成する
$ sudo usermod -aG docker $USER

再ログインすると設定が反映される。

権限の設定

参考にした記事:Dockerのバージョン1.10で正式に導入されたUser Namespacesを試してみる

そのままだと、root権限のディレクトリをマウントして操作できてしまうらしい。

$ sudo systemctl stop docker.service
# もしユーザdockremapがいなかったら、sudo adduser dockremapで作成する
$ sudo sh -c 'echo dockremap:500000:65536 > /etc/subuid'
$ sudo sh -c 'echo dockremap:500000:65536 > /etc/subgid'
$ sudo vi /etc/docker/daemon.json
{
    "userns-remap": "default"
}
$ sudo systemctl start docker.service

nvidia-docker

グラフィックスドライバのインストール

sudo ubuntu-drivers autoinstallでサクッと入るけど、最新のが好きなので。NVIDIA公式からNVIDIA-Linux-x86_64-430.14.runをダウンロード。デフォルトのドライバnouveauを止めて、ランレベル3でインストールする。これ、もう少し楽にならないものかな。

# nouveauを使わないようにする
$ sudo sh -c "echo blacklist nouveau > /etc/modprobe.d/blacklist-nvidia-nouveau.conf"
$ sudo sh -c "echo options nouveau modeset=0 >> /etc/modprobe.d/blacklist-nvidia-nouveau.conf"
$ sudo update-initramfs -u
$ sudo reboot

# 最小構成でインストールしたせいで、ここでMakeがないことに気がつく
$ sudo apt install build-essentials

$ sudo telinit 3
$ sudo sh ./NVIDIA-Linux-x86_64-430.14.run
$ sudo telinit 5

# ちゃんとインストールされたことを確認
$ nvidia-smi

nvidia-dockerのインストール

公式GitHubに書いてあるとおりやればいい。さっき書いたdaemon.jsonを上書きされてしまうので注意(diffを見せてくれるのにmergeはしてくれないのか…)。

$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
$ sudo apt-key add -
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
$ sudo tee /etc/apt/sources.list.d/nvidia-docker.list
$ sudo apt update
$ sudo apt install -y nvidia-docker2

# 動作確認
$ sudo systemctl restart docker.service
$ docker run --runtime=nvidia --rm nvidia/cuda:9.0-base nvidia-smi

linuxbrew

Homebew on Linuxを参考に。

$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"

.bashrcにパスの設定をしておく:

export PATH=/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH

Emacs

参考にした記事:Ubuntuにemacs26をインストールする

設定ファイルの都合上、26でないと色々と動かない。

sudo add-apt-repository ppa:kelleyk/emacs
sudo apt update
sudo apt install emacs26

Python

pyenv

$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv

.bashrcに追記:

export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
if command -v pyenv 1>/dev/null 2>&1; then
    eval "$(pyenv init -)"
fi

この辺が無いよと言われるので入れておくといいかもしれない。

$ sudo apt install -y zlib1g-dev libssl-dev libbz2-dev libreadline-dev libsqlite3-dev

適当にどれか入れてみる。

# インストールできるバージョンを一覧
$ pyenv install --list
# 機械学習界隈では3.6の方が無難かな?
$ pyenv install 3.6.8
# 3.6.8を使う
$ pyenv global 3.6.8
# 確認
$ pyenv versions

pipenv

$ brew install pipenv

各プロジェクトのディレクトリ内に仮想環境を作って欲しいので、.bashrcに追記する:

export PIPENV_VENV_IN_PROJECT=1

PyCharm

公式のダウンロードページからCommunity editionをダウンロードしてくる。

$ tar -zxvf pycharm-community-2019.1.2.tar.gz
$ mv pycharm-community-2019.1.2 ~/bin
$ cd ~/bin/pycharm-community-2019.1.2/bin
$ ./pycharm.sh
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker で Laravel開発環境

Nginxのconfを作成する

server {
    listen  80;
    root /usr/share/nginx/laravel/public;
    index index.php index.html index.htm;
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ ^/.+\.php(/|$) {
        fastcgi_pass laravel-container:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

DockerでPHP-FPMを作成する

FROM php:7.3-fpm-alpine
RUN apk add libzip-dev
RUN docker-php-ext-configure zip --with-libzip
RUN docker-php-ext-install pdo_mysql zip

docker-composeを作成する

version: "3.7"

services:

  laravel:
    build: .
    container_name: laravel-container
    working_dir: /usr/share/nginx/laravel
    networks:
      - laravel-docker
    volumes:
        - ./laravel:/usr/share/nginx/laravel

  nginx:
    image: nginx:1.16-alpine
    container_name: reverse-proxy
    working_dir: /usr/share/nginx/laravel
    networks:
      - laravel-docker
    ports:
        - "8080:80"
    volumes:
        - ./default.conf:/etc/nginx/conf.d/default.conf
        - ./laravel:/usr/share/nginx/laravel

  mysql:
    image: mysql:8.0
    container_name: mysql-server
    networks:
      - laravel-docker
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=homestead
      - MYSQL_USER=homestead
      - MYSQL_PASSWORD=secret
    ports:
      - 3306:3306

  redis:
    image: redis:5.0-alpine
    container_name: redis-server
    networks:
      - laravel-docker
    ports:
      - 6379:6379

networks:
  laravel-docker:
    driver: bridge

詳細は下記(ハンズオン)

https://github.com/hexaforce/laravel-docker

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

白黒写真の彩色プログラムを使用してみた(2019年対応版)

この度NPO法人 まちづくりエージェント SIDE BEACH CITY.で、パソコン・スマートフォンの活用方法を紹介するパフォーマンスをすることになりました。

6/15開催のいそご地域活動フォーラムにて、PC活用パフォーマンスを開催 | まちづくりエージェント SIDE BEACH CITY.

まあそれはそれとして、この場で以前紹介されていた、白黒写真を彩色するプログラムを見せることになり、オープンソースなので実際にビルドし、実行してみることに。

大まかには以下の記事にあがっていますので、環境が揃っている人は特に問題はないかと。

ただし、わたしはWindowsのPCしか持っていないため、とりあえずDockerを使って実行環境を構築しました。また、2019年現在は上記プログラムのままでは動作しない部分があるため、それも含めてメモ。

手順

だいたい上記の通りですが、ひとつだけ。

ubuntu 14.04 でのapt-add-repositoryのインストール - Qiitaに書いてあるとおり、「python-software-properties」というパッケージは2019年5月24日現在のUbuntuの環境には存在しないため、「software-properties-common」に変更する必要があります。

また、DockerhubでインストールできるUbuntu環境にはwgetなどの基本的なコマンドが入っていないため、apt-getでちゃんとインストールしておきます。

で。

で、つくってみたDockerfileがこちら。

d_build.shでコンテナイメージをビルドし、d_run.shでコンテナを実行、bashに入れます。

README.mdにも書いているとおり、事前に

  • 仮想マシンに8GBくらいの容量を割り当てておくこと
  • /dockerというディレクトリを共有フォルダとして作成しておくこと

ということが必要になります。

では結果はどうなるかというと、とりあえずWebサービス版と同じなようです。ImageNet Modelというものもあるようなので、そちらを使うとまた違うのかもしれません。

色鮮やかになるかどうかは、「とりあえず写真による」という感じです。すごく鮮明に彩色される写真もあれば、全体的に茶色っぽくなるだけという写真もあるという感じ。また、最近になってモノクロレンズで撮影したり、別のアプリで白黒化した写真は、おおよそ元の画像に近くなるという印象がありました。

そのほか

そのほかDockerfile作成に当たって気をつけた点

RUNコマンドの扱いについて

Dockerfileでは、ファイルを修正したあと再イメージのビルドを行うと、「修正したより下の行だけ」再構築されます。

torchのビルドなどはなるべくRUNコマンドを1行ごとに分けておくと、ビルドイメージの作成に失敗したときの手戻りが少なく安心です(よくあるサンプルのように別のshファイルで処理したり、複数コマンドを&&で繋いだりすると、コマンドが失敗したときに一からやり直しになる)。

Dockerfileのビルドと実行について

Dockerfileのビルド(docker build)と実行(docker run)については、何度も実行することになるためシェルスクリプトに分けておくと日々の修正が苦痛になりません。

また、うっかりコマンドラインで設定するべきパラメータを忘れたり、結びつけるべきディレクトリを指定し忘れたりすることも防げるので、忘れずシェルスクリプトにしておくとよいでしょう(今回はあまりやり直しをせずにすみましたが)。

参考

siggraph2016_colorizationのREADME.mdを読む限り、メモリは4GB以上あればよいみたいですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

multipassでつくるmacOS向けのDockerd & K8s環境

きっかけ

minikubeが最近重い。Minikube自身が原因かどうか深追いはしてないものの、気軽に乗り換えられそうならやってみるか、程度の軽い気持ちで試してみました。

// minikubeの重さについて定量的な検証はとくにしていないので、必要な形はこの手順で構築したVMとminikubeVMのCPU・メモリ利用量などを実際に比較してみることをおすすめします

TL;DR;

multipass というシングルバイナリのツールで、Ubuntuの入ったhyperkit VMを簡単に操作できる。

  • UbuntuでDocker/ローカルK8sを利用する標準的な構成(docker & microk8s)をセットアップするだけの構成。

minikube同様な点

  • ホストOS側のディレクトリマウントにも対応している。

minikubeよりよいと思われる点

  • microk8sのアドオンにローカルdocker registryがあり、高速にdocker build -> push -> K8sへデプロイするサイクルがまわせる
  • microk8sとk3dによるK8sクラスタを共存させることもできる。Namespacedでないリソース(CRDなど)を複数バージョン作って平行でE2Eテストを走らせるような使い方をする場合、microk8sだとバッティングしてしまうので、k3dで高速に使い捨てのクラスタをつくれるのは便利。

そのほかにやってみたこと

  • k3dでmultipass VM上に軽量K8sを構築。microk8sのk8sクラスタと共存
  • kanikoでmacOS上のファイルをクラスタに転送してコンテナイメージをビルド(dockerd依存なしで)してローカルレジストリに高速にpush

手順

multipassのインストール

0.7.0のRC版を使います(後述の primary マシンが使えるようになり便利になったので

https://github.com/CanonicalLtd/multipass/releases/tag/v0.7.0-rc

VM の作成

multipass launch の引数にVMに割り当てる最大メモリ、ストレージサイズ、CPUコア数とVM名(名前を変えればVMを複数つくることができます)を指定する。

名前を primary にすると、multipass の各コマンドでVM名を省略したときのデフォルトとして扱ってくれるため、よく使うVMまたは最初の一台とりあえず primary にしておくことをおすすめします。

mac$ multipass launch --mem 8G --disk 40G --cpus 2 --name primary

multipass ls コマンドでVM一覧を確認できます。StateがRunningとなっていればひとまず問題ありません。また、IPv4 欄に表示されるIPアドレスは macOS 側からVMで起動しているサービスにアクセスする場合によく使うことになるので、覚えておきましょう。

mac$ multipass ls
Name                    State             IPv4             Release
primary                 Running           192.168.64.8     Ubuntu 18.04 LTS

K8sクラスタの構築

最小構成としてK8s自身とクラスタDNS、そしてローカル開発に便利なクラスタ内コンテナイメージレジストリを構築する。

K8s自身は、Ubuntuのパッケージマネージャである snapmicrok8s というsnapをインストールして、IPフォワードの許可をするだけでOK。

multipass@primary:~$ sudo snap install microk8s --classic
multipass@primary:~$ sudo iptables -P FORWARD ACCEPT

次に、クラスタDNSとコンテナイメージレジストリをmicrok8s.enableコマンドでインストールする。

multipass@primary:~$ microk8s.enable registry
Enabling the private registry
Enabling default storage class
deployment.extensions/hostpath-provisioner created
storageclass.storage.k8s.io/microk8s-hostpath created
Storage will be available soon
Applying registry manifest
namespace/container-registry created
persistentvolumeclaim/registry-claim created
deployment.extensions/registry created
service/registry created
The registry is enabled
multipass@primary:~$ microk8s.enable dns
Enabling DNS
Applying manifest
service/kube-dns created
serviceaccount/kube-dns created
configmap/kube-dns created
deployment.extensions/kube-dns created
Restarting kubelet
DNS is enabled

microk8s をインストールすると、同梱された containerd が起動した状態になる。

multipass@primary:~$ ls /var/snap/microk8s/current/args/
cni-network/              containerd-env            containerd.toml           etcd                      kube-controller-manager   kube-scheduler            kubelet
containerd                containerd-template.toml  ctr                       kube-apiserver            kube-proxy                kubectl
multipass@primary:~$ cat /var/snap/microk8s/current/args/containerd
--config ${SNAP_DATA}/args/containerd.toml
--root ${SNAP_COMMON}/var/lib/containerd
--state ${SNAP_COMMON}/run/containerd
--address ${SNAP_COMMON}/run/containerd.sock

これだけだと docker コマンドの接続先となる、containerd のフロントエンドとなる dockerd が存在しないため、別途 docker のみインストールする。

multipass@primary:~$ sudo apt-get install docker.io
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following package was automatically installed and is no longer required:
  grub-pc-bin
Use 'sudo apt autoremove' to remove it.
Suggested packages:
  aufs-tools debootstrap docker-doc rinse zfs-fuse | zfsutils
The following NEW packages will be installed:
  docker.io
0 upgraded, 1 newly installed, 0 to remove and 48 not upgraded.
Need to get 0 B/46.4 MB of archives.
After this operation, 234 MB of additional disk space will be used.
Preconfiguring packages ...
Selecting previously unselected package docker.io.
(Reading database ... 60225 files and directories currently installed.)
Preparing to unpack .../docker.io_18.09.2-0ubuntu1~18.04.1_amd64.deb ...
Unpacking docker.io (18.09.2-0ubuntu1~18.04.1) ...
Setting up docker.io (18.09.2-0ubuntu1~18.04.1) ...
Processing triggers for ureadahead (0.100.0-21) ...
Processing triggers for systemd (237-3ubuntu10.21) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...

systemctl statusdockerd が起動していることを確認しておく。 Active: active (running) になっていれば一旦は問題なし。

multipass@primary:~$ systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled)
   Active: active (running) since Wed 2019-05-22 17:47:16 JST; 25min ago
     Docs: https://docs.docker.com
 Main PID: 7660 (dockerd)
    Tasks: 25
   CGroup: /system.slice/docker.service
           ├─7660 /usr/bin/dockerd -H fd://
           └─7687 docker-containerd --config /var/run/docker/containerd/containerd.toml --log-level info

May 22 17:47:15 primary dockerd[7660]: time="2019-05-22T17:47:15.888067580+09:00" level=info msg="Loading containers: done."
May 22 17:47:16 primary dockerd[7660]: time="2019-05-22T17:47:16.055035350+09:00" level=info msg="Docker daemon" commit=6247962 graphdriver(s)=overlay2 version=18.09.2
May 22 17:47:16 primary dockerd[7660]: time="2019-05-22T17:47:16.055151889+09:00" level=info msg="Daemon has completed initialization"
May 22 17:47:16 primary dockerd[7660]: time="2019-05-22T17:47:16.065357823+09:00" level=info msg="API listen on /var/run/docker.sock"
May 22 17:47:16 primary systemd[1]: Started Docker Application Container Engine.
May 22 17:49:11 primary dockerd[7660]: time="2019-05-22T17:49:11.615281919+09:00" level=info msg="Attempting next endpoint for push after error: Get https://localhost:32000/v2/: http: server gave HTTP response to HTTPS client"
May 22 17:49:54 primary dockerd[7660]: time="2019-05-22T17:49:54.981556940+09:00" level=info msg="Pull session cancelled"
May 22 17:49:55 primary dockerd[7660]: time="2019-05-22T17:49:55.748494759+09:00" level=info msg="shim docker-containerd-shim started" address="/containerd-shim/moby/c7265d99a9070c43c41bc7f6a298b669a4c87354a22599174dd0d37a82acd483/shim.
May 22 17:50:20 primary dockerd[7660]: time="2019-05-22T17:50:20.647918693+09:00" level=info msg="shim reaped" id=c7265d99a9070c43c41bc7f6a298b669a4c87354a22599174dd0d37a82acd483
May 22 17:50:20 primary dockerd[7660]: time="2019-05-22T17:50:20.657969019+09:00" level=info msg="ignoring event" module=libcontainerd namespace=moby topic=/tasks/delete type="*events.TaskDelete"

このままだと /var/run/docker.sock への権限が原因で sudo をつけないと docker コマンド経由の通信が失敗するため、docker.help コマンドの出力に従ってLinuxユーザ・グループをセットアップする。

multipass@primary:~$ docker.help
Docker snap: Docker Linux container runtime.

Due to the confinement issues on snappy, it requires some manual setup to make docker-snap works on your machine.
We'll take you through the steps needed to set up docker snap work for you on ubuntu core and ubuntu classic.

On Ubuntu classic, before installing the docker snap,
please run the following command to add the login user into docker group.
    sudo addgroup --system docker
    sudo adduser $USER docker
    newgrp docker

On Ubuntu Core 16, after installing the docker snap from store,
you need to connect the home interface as it's not auto-connected by default.
    sudo snap connect docker:home :home

Then have fun with docker in snappy.
$ sudo addgroup --system docker
$ sudo adduser $USER docker
$ newgrp docker

実際に docker コマンドをいくつか実行してみて、動作確認しておく。

multipass@primary:~$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
multipass@primary:~$ docker version
Client:
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.4
 Git commit:        6247962
 Built:             Tue Feb 26 23:52:23 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.09.2
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       6247962
  Built:            Wed Feb 13 00:24:14 2019
  OS/Arch:          linux/amd64
  Experimental:     false

docker build もできる。

multipass@primary:~/work$ cat >Dockerfile
FROM nginx:alpine
^C
multipass@primary:~/work$ docker build . -t mynginx:local
Sending build context to Docker daemon  2.048kB
Step 1/1 : FROM nginx:alpine
alpine: Pulling from library/nginx
e7c96db7181b: Pull complete
264026bbe255: Pull complete

最高のクラスタ内コンテナイメージレジストリを用意する

少し手間をかけると、docker pushだけでなくkanikoにも対応できます。

microk8s デフォルトの状態

microk8s.enable registry でインストールした docker registry は VM の 32000番でアクセスできるようになっている。また、apt-get でインストールした dockerd はデフォルトでローカルレジストリを信頼するようになっている。したがって、以下のように localhost:32000 をDockerレジストリとして docker push などが可能。

docker build . -t localhost:32000/mynginx:registry
docker push localhost:32000/mynginx

dockerd, K8sの両方からローカルレジストリにアクセス可能にする

レジストリ名にはlocalhostではなくIPアドレスを使うことがポイント。

イメージ名に含まれるレジストリのアドレスに「localhost:32000」を使うより、IPアドレス:ポートを使うようにする、ということ。

localhostの場合multipass VM上のUbuntuから起動しているdockerdがアクセスすることはもちろん可能だが、例えばkanikoでin-cluster buildをしてkanikoからpushをするような場合にアクセスできないから(kanikoにとってのlocalhostはkaniko自身のPodになるため)。

したがって、multipass ls で確認できるVMのIPアドレスが 192.168.64.8 だとしたら、192.168.64.8:32000 をイメージレジストリのアドレスとして利用する。そうすれば、macOSやUbuntuからdocker push する場合、kanikoからin-cluster build/pushする場合で同じレジストリのアドレスを利用することができ、混乱が少ない。

dockerdのinsecure registry設定

基本的には docker コマンドを使う場合は docker tag 192.168.64.8:32000/MYIMAGE のようにタグを打てばよいが、dockerd側の設定をしないと以下のエラーになる。

multipass@primary:~$ docker push 192.168.64.8:32000/alpine
The push refers to repository [192.168.64.8:32000/alpine]
Get https://192.168.64.8:32000/v2/: http: server gave HTTP response to HTTPS client

これは、microk8sで導入したレジストリがHTTPモードになっているため。dockerdはlocalhost:32000のようなレジストリが指定された場合はHTTPモードのレジストリとして通信をするが、IPアドレス:32000 のようにIPアドレスを明示した場合はHTTPSをデフォルトとして利用するようで、このようなエラーになってしまう。

そこで、dockerd に該当アドレスにいるレジストリはHTTPを話すということを伝える必要がある。具体的には、/etc/docker/daemon.json を以下の通り作成する。

multipass$ sudo sh -c 'cat > /etc/docker/daemon.json'
{
  "insecure-registries" : ["192.168.64.8:32000"]
}

参考: https://docs.docker.com/registry/insecure/

この設定をdockerdに読み込ませるために、dockerdを再起動する。

multipass@primary:~$ sudo systemctl restart docker

先程エラーになったdocker pushコマンドを再度実行してみると、今度はうまくいく。

multipass@primary:~$ docker push 192.168.64.8:32000/alpine
The push refers to repository [192.168.64.8:32000/alpine]
f1b5933fe4b5: Pushed
3.9: digest: sha256:bf1684a6e3676389ec861c602e97f27b03f14178e5bc3f70dce198f9f160cce9 size: 528

kanikoのinsecureレジストリ設定

kaniko の場合は、--insecure というフラグをつけるとpush先のレジストリをHTTPサーバとみなす。

https://github.com/GoogleContainerTools/kaniko#--insecure

kaniko のREADMEによれば、kaniko を試すときは docker runやkubectlから実行するのが常のようだが、手元から試しにビルドする場合には手順が煩雑なので、ここではskaffoldを使うことにする。skaffoldにはkanikoビルダがあり、kanikoを直接使うよりは簡単にビルドができる。

skaffoldはkaniko--insecureフラグを自動で付与したりはしてくれない(しようもない)ので、それは自分で skaffold の設定ファイルに記述する。

skaffoldの設定ファイルであるskaffold.yamlのリファレンスのとおり、build.artifacts[].kanikoにkaniko関連の設定を記述する。

https://skaffold.dev/docs/references/yaml/

flags に前述の--insecureフラグを追加すればよい。

apiVersion: skaffold/v1beta11
kind: Config
build:
  artifacts:
  - image: 192.168.64.8:32000/mumoshu/skaffoldtest
    context: .
    kaniko:
      flags:
      # Required in order to avoid the following error when pusing to a local, insecure registry:
      #   error pushing image: failed to push to destination 192.168.64.8:32000/mumoshu/skaffoldtest:6383d2f-dirty: Get https://192.168.64.8:32000/v2/: http: server gave HTTP response to HTTPS client
      - --insecure
      buildContext:
        localDir: {}
  # If omitted, `local` builder is selected by default even though the `kaniko` settings is provided
  cluster:
    pullSecret: /Users/YOU/.docker/config.json

この内容で skaffold build を実行すると、skaffoldがkanikoを使ってクラスタ内(のPodを使って)イメージビルドしてくれる。

$ skaffold build
Generating tags...
 - 192.168.64.8:32000/mumoshu/skaffoldtest -> 192.168.64.8:32000/mumoshu/skaffoldtest:6383d2f-dirty
Tags generated in 49.780056ms
Starting build...
Creating kaniko secret [kaniko-secret]...
Building [192.168.64.8:32000/mumoshu/skaffoldtest]...
Storing build context at /var/folders/_w/3lwtgvv51tl_fgxkdvcmtm340000gp/T/context-c2cb37afc85a7037bdbf94e9502fcbd7.tar.gz
WARN[0000] The additionalFlags field in kaniko is deprecated, please consult the current schema at skaffold.dev to update your skaffold.yaml.
INFO[0000] Downloading base image nginx:alpine
2019/05/24 06:22:47 No matching credentials were found, falling back on anonymous
INFO[0002] Taking snapshot of full filesystem...
INFO[0002] Skipping paths under /kaniko, as it is a whitelisted directory
INFO[0002] Skipping paths under /secret, as it is a whitelisted directory
INFO[0002] Skipping paths under /dev, as it is a whitelisted directory
INFO[0002] Skipping paths under /sys, as it is a whitelisted directory
INFO[0002] Skipping paths under /proc, as it is a whitelisted directory
INFO[0002] Skipping paths under /var/run, as it is a whitelisted directory
2019/05/24 06:22:50 existing blob: sha256:5595887beb811004cfb48cd5bb3eb9a9602fb1fd47d93117b92ef97e22859c00
2019/05/24 06:22:50 existing blob: sha256:264026bbe25598d28ce74f288ce0b4ef93dc4123bb793bf655780e0455453f4c
2019/05/24 06:22:50 existing blob: sha256:a71634c55d292856f6a48a5984ff4aa7e244f2e82083e1279aa5af8a7da5819f
2019/05/24 06:22:50 existing blob: sha256:e7c96db7181be991f19a9fb6975cdbbd73c65f4a2681348e63a141a2192a5f10
2019/05/24 06:22:50 pushed blob sha256:a0c491e91aadbd72d0375bc0d186ebede44c5e9e2f2377a035de37baf5b1d878
2019/05/24 06:22:50 192.168.64.8:32000/mumoshu/skaffoldtest:6383d2f-dirty: digest: sha256:ac66fceb3d272c21e54450bfa7c18e7235baea1b5924c2ac2d2e029eae8b78fb size: 912
Build complete in 14.884723143s
Starting test...
Test complete in 7.838µs
Complete in 14.9516144s

kanikoがローカルレジストリにpushしたことを確認するため、dockerコマンドを使ってdockerdにpullしてみる。

まず、pullする前はイメージがdockerdには見えない状態。これは、kanikoがdocker/dockerdを経由しないで自前でイメージをビルドしてローカルレジストリにpushしたため。

$ docker images

以下のようにpullすれば、イメージが見えるようになるはず。

$ docker pull 192.168.64.8:32000/mumoshu/skaffoldtest:6383d2f-dirty
6383d2f-dirty: Pulling from mumoshu/skaffoldtest
e7c96db7181b: Already exists
264026bbe255: Already exists
a71634c55d29: Already exists
5595887beb81: Already exists
Digest: sha256:3132ea39b2e91e2d76f45adbdf0921f394a5793fd9ab4a4b7c895da46ecdd033
Status: Downloaded newer image for 192.168.64.8:32000/mumoshu/skaffoldtest:6383d2f-dirty

docker images コマンドで dockerd から見えているイメージを見てみると、無事にkanikoがpushしたイメージがある。

macos$ docker images | grep mumoshu
192.168.64.8:32000/mumoshu/skaffoldtest   6383d2f-dirty       f39da67d6567        39 seconds ago      16.1MB

macOS側からdockerdにアクセスできるようにする

このままだと /var/run/docker.sock 経由によるdockerdとの通信しかできない。macOS側の docker コマンドからは tcp 経由の通信をしたいので、 dockerd の設定を変更する。

multipass@primary:~$ sudo mkdir /etc/systemd/system/docker.service.d/
multipass@primary:~$ sudo sh -c 'cat > /etc/systemd/system/docker.service.d/startup_options.conf'
# /etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376
^C
multipass@primary:~$ sudo systemctl daemon-reload
multipass@primary:~$ sudo systemctl restart docker.service

以下のように dockerd のコマンドライン引数に -H tcp://0.0.0.0:2376 が追加されていればOK

multipass@primary:~$ systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled)
  Drop-In: /etc/systemd/system/docker.service.d
           └─startup_options.conf
   Active: active (running) since Wed 2019-05-22 18:14:13 JST; 1s ago
     Docs: https://docs.docker.com
 Main PID: 17395 (dockerd)
    Tasks: 22
   CGroup: /system.slice/docker.service
           ├─17395 /usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376
           └─17432 docker-containerd --config /var/run/docker/containerd/containerd.toml --log-level info

May 22 18:14:13 primary dockerd[17395]: time="2019-05-22T18:14:13.122806400+09:00" level=warning msg="Your kernel does not support cgroup rt period"
May 22 18:14:13 primary dockerd[17395]: time="2019-05-22T18:14:13.122820048+09:00" level=warning msg="Your kernel does not support cgroup rt runtime"
May 22 18:14:13 primary dockerd[17395]: time="2019-05-22T18:14:13.123708656+09:00" level=info msg="Loading containers: start."
May 22 18:14:13 primary dockerd[17395]: time="2019-05-22T18:14:13.217868247+09:00" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used to set a preferred IP address"
May 22 18:14:13 primary dockerd[17395]: time="2019-05-22T18:14:13.254483709+09:00" level=info msg="Loading containers: done."
May 22 18:14:13 primary dockerd[17395]: time="2019-05-22T18:14:13.305465422+09:00" level=info msg="Docker daemon" commit=6247962 graphdriver(s)=overlay2 version=18.09.2
May 22 18:14:13 primary dockerd[17395]: time="2019-05-22T18:14:13.305581627+09:00" level=info msg="Daemon has completed initialization"
May 22 18:14:13 primary dockerd[17395]: time="2019-05-22T18:14:13.311982639+09:00" level=info msg="API listen on [::]:2376"
May 22 18:14:13 primary dockerd[17395]: time="2019-05-22T18:14:13.312016834+09:00" level=info msg="API listen on /var/run/docker.sock"
May 22 18:14:13 primary systemd[1]: Started Docker Application Container Engine.

macOS側

Dockerの接続先設定

まだ入ってなければ docker コマンドをインストールする。

mac$ brew install docker

multipass ls コマンドで VMのIPアドレスを調べて、

$ multipass ls
Name                    State             IPv4             Release
primary                 Running           192.168.64.8     Ubuntu 18.04 LTS

docker コマンドであれば -H フラグでそのIPアドレスの2376(前述の設定のとおり)をDocker APIのエンドポイントとして使うようにします。

mac$ docker -H 192.168.64.8:2376 ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

いちいち -H を設定するのが面倒な場合や、docker コマンド以外の方法(例えば各プログラミング言語向けの Docker APIクライアントやそれを内部的に使っているようなツール)で dockerd と通信したいような場合は、DOCKER_HOST 環境変数を設定してください。

mac$ export DOCKER_HOST=tcp://192.168.64.8:2376
mac$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

VM上のK8s APIにアクセスする

microk8s をインストールすると作られる microk8s.config コマンドで、kubeconfig の内容を標準出力に出すことができます。

multipass@primary:~$ microk8s.config

設定内容に含まれるK8s APIエンドポイントURLのホスト名部分には VMのプライベートIPアドレスが書かれており、VMのIPアドレスはmacOS側から特に何もせずともアクセスすることができるため、これを単にmacOS側に保存してkubectl などに読ませればOKです。

$ multipass exec primary -- /snap/bin/microk8s.config > microk8s.kubeconfig
$ export KUBECONFIG=$(pwd)/microk8s.kubeconfig

実際に kubectl を実行してアクセスできるか確認してみます。

$ kubectl version
$ kubectl get no
NAME      STATUS   ROLES    AGE   VERSION
primary   Ready    <none>   9h    v1.14.1

ホームディレクトリのマウント

TL;DR;
mac$ multipass mount $HOME primary:$HOME
説明

macOSの場合 $HOME = /Users/$USER がホームディレクトリになっていると思います。minikubedocker-machine はデフォルトで macOS 側のホームディレクトリを VM 上の同じパスにマウントしてくれるため、ホームディレクトリ以下のディレクトリであれば docker run -v $SRC:$DST でマウントするソースディレクトリのパスに macOS 側のパスをそのまま利用できて便利です。

たとえば docker run --rm -it -v $(pwd):$(pwd) myimage /bin/bash のようにカレントディレクトリをマウントしたコンテナを起動するというようなことができるのは、macOS側の$(PWD)が示すパスがVM上にもあるから、ですよね。

multipass mount で明示的にホームディレクトリをマウントすれば、同じ状態を再現することができます。

mac$ multipass mount $HOME primary:$HOME

これまで通り、macOS側のパスとVM上のパスの読み替えをすることなく、macOSにあるファイルをコンテナ内から参照することができます。

mac$ docker run --rm -it -v $HOME:$HOME alpine:3.9 sh

上級編

k3d on multipass VM

multipass VM上にmicrok8sとは別の、k3dによるK8sクラスタを相乗りさせることもできる。

ただし、k3dの実装上の都合により、k3dが作成したK8sクラスタへのアクセスはVM側から行ったほうが良い。例えばkubectlを使うなら、macOS側からではなくUbuntu側からkubectlを実行したほうがよい。これは、macOS側からk3dのK8sにアクセスしようとすると、CA証明書の検証エラーとなってしまうため。

$ KUBECONFIG=~/.config/k3d/k3s-default/kubeconfig.yaml  k get no
Unable to connect to the server: x509: certificate signed by unknown authority

エラー内容から察するに、k3dはUbuntu側のローカルルートCAで署名されたCA証明書をK8s APIとの通信に利用するようになっており、Ubuntu側のローカルルートCAはmacOS側で信頼されていないから、ということではないかと思う。(macOS側でそのルートCAを信頼するようにすればよいが、面倒なのでやっていない。)

そのときに利用するKUBECONFIGはk3dコマンドが生成したものを使うことになるため、最初からmacOS側ではなくUbuntu側でk3dコマンドを実行してkubeconfigがmacOS側ではなくUbuntu側に用意された状態にすると混乱がない。

以上を踏まえて、Ubuntu側に kubectlk3d をインストールし、Ubuntu上で k3d によるK8sクラスタの作成と、kubectl による接続確認を行う。

multipass@primary:~$ sudo snap install kubectl --classic
multipass@primary:~$ k3d create
2019/05/24 11:06:10 Created cluster network with ID baee312bc080400e2625b2097f886fef96b7c41a8afb1f9fb40c0826380495b2
2019/05/24 11:06:10 Creating cluster [k3s-default]
2019/05/24 11:06:10 Creating server using docker.io/rancher/k3s:v0.5.0...
2019/05/24 11:06:12 SUCCESS: created cluster [k3s-default]
2019/05/24 11:06:12 You can now use the cluster with:

export KUBECONFIG="$(k3d get-kubeconfig --name='k3s-default')"
kubectl cluster-info

KUBECONFIGを指定しない場合は microk8s で作られたほうの K8s に向いている。

multipass@primary:~$ kubectl cluster-info
Kubernetes master is running at http://localhost:8080
KubeDNS is running at http://localhost:8080/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

k3d create コマンドの出力で指示されたとおりKUBECONFIGを設定すると、k3d で作られたほうのK8sに向く。

multipass@primary:~$ export KUBECONFIG="$(k3d get-kubeconfig --name='k3s-default')"
multipass@primary:~$ kubectl cluster-info
Kubernetes master is running at https://localhost:6443
CoreDNS is running at https://localhost:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

注意点

再起動するたびに下記コマンドを実行すること。

multipass@primary:~$ sudo iptables -P FORWARD ACCEPT

実行しないと、クラスタ外のIPアドレス(例えばインターネット上のAlpine Package Registryやコンテナイメージレジストリ含めて)にあらゆるPod内からアクセスできない。kube-dnsもUpstreamである 8.8.8.8 などにアクセスできないので、kube-dnsが起動しているにもかかわらず、あらゆるPodからクラスタ外の名前解決ができない、という状態になってしまう。

動かないときは

とりあえず microk8s.inspect を実行して、なにかエラーや注意が出ていないか確認する。例えば前述のiptablesの件は、microk8s.inspectにも出てくる。(WARNING の部分)

multipass@primary:~$ microk8s.inspec
microk8s.inspec: command not found
multipass@primary:~$ microk8s.inspect
Inspecting services
  Service snap.microk8s.daemon-containerd is running
  Service snap.microk8s.daemon-apiserver is running
  Service snap.microk8s.daemon-proxy is running
  Service snap.microk8s.daemon-kubelet is running
  Service snap.microk8s.daemon-scheduler is running
  Service snap.microk8s.daemon-controller-manager is running
  Service snap.microk8s.daemon-etcd is running
  Copy service arguments to the final report tarball
Inspecting AppArmor configuration
Gathering system info
  Copy network configuration to the final report tarball
  Copy processes list to the final report tarball
  Copy snap list to the final report tarball
  Inspect kubernetes cluster




 WARNING:  IPtables FORWARD policy is DROP. Consider enabling traffic forwarding with: sudo iptables -P FORWARD ACCEPT
Building the report tarball
  Report tarball is at /var/snap/microk8s/522/inspection-report-20190524_145809.tar.gz

所感

  • (個人的には)ブラックボックス感が少なくて、問題が起きたときに対処しやすそう
  • minikubeでよく行っていた docker build && kubectl apply のようなワークフローも問題なく流せそうなので、移行したい
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerのコンテナのロケール設定(解決編)

はじめに

なにがあったかはこちら

解決策

RUN apt-get install -y tzdata
RUN ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python 事始め 2019 for mac

令和になって人生で初めての負荷試験担当になりました(予定)。
今から死ぬことになるんだろうな、と戦々恐々としながら AWS の負荷試験入門の本(アフェリンクじゃないよ) 読んでます。

どうせなら保守 & 保守が辛い jMeter よりも、保守しやすく柔軟性の高いと言われてる Locust を使うことを目標に python 始めました。

python (もとい自分の知らない言語)を始めるにあたり必要になるのは開発環境。
開発環境といえば docker ですよね。
大体下になりました。

  • vscode -> ダウンロードする. python 拡張入れるで大体使える。
  • docker -> 環境汚さない。バージョン切り替え用意。構築まで早い。好き。

docker は公式にあるものを使います。それが一番早い。
https://hub.docker.com/_/python

$ docker pull python:3
$ docker run --rm python:3 python --version
Python 3.7.3

これで準備おわりです。便利な世の中。

次、作業環境を構築していきます。
Dockerfile の用意、これも公式をパクれば良いです。
若干書き換えてますが、今は気にしないのが大人です。

FROM python:3

WORKDIR /usr/src/app

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

CMD [ "pytest", "test.py" ]

Dockerfile で requirements.txt なるものをコピーしてるので用意してあげます。
簡単に調べてみると、これはパッケージ管理用のファイルみたいでした。

requirements.txt
pytest

ここまでを build してコンテナ作成します。

$ docker build -t test .

よくあるこんにちは世界をやります。

hello/api.py
def hello():
  return 'hello world !!'

if __name__ == '__main__':
  print(hello())

こんにちはできました!

$ docker run --rm test python hello/api.py
hello world !!

次、開発にとって大事なテスト導入します。
デフォルトのやつもあるみたいですが、さっきスルーしてもらった pytest がわりかしスマートで良さそうでした。

テストするにあたってまず自作関数をモジュールとして読み込めるようにします。
__init__.py ってのを作って定義すればよしなに。

hello/__init__.py
from .api import (
  hello
)

次にテストファイル

test.py
import pytest
from hello import hello

def test_hello():
  assert 'hello orld' == hello()

そしてテスト実行!

$ docker run --rm test
============================= test session starts ==============================
platform linux -- Python 3.7.3, pytest-4.5.0, py-1.8.0, pluggy-0.11.0
rootdir: /usr/src/app
collected 1 item

test.py F                                                                [100%]

=================================== FAILURES ===================================
__________________________________ test_hello __________________________________

    def test_hello():
>     assert 'hello orld' == hello()
E     AssertionError: assert 'hello orld' == 'hello world !!'
E       - hello orld
E       + hello world !!
E       ?       +    +++

test.py:5: AssertionError
=========================== 1 failed in 0.07 seconds ===========================

Dockerfile はコマンドが省略されたとき CMD をデフォルトとして実行します。
今回は pytest test.py ですね。
そしてはい、こけます。
修正しましょう。

import pytest
from hello import hello

def test_hello():
-  assert 'hello orld' == hello()
+  assert 'hello world' == hello()

あと毎回 build -> run って叩くのめんどいので Makefile 作りましょう。
python のランナーは探せば良いのあるかもしれないけど、今回のやつ程度なら Makefile でサクで良いです。(先頭タブじゃないとダメなのが面倒)

# vim:set noexpandtab :
build:
  @docker build -t csvql .

test: build
  @docker run --rm csvql
$ make test
...
============================= test session starts ==============================
platform linux -- Python 3.7.3, pytest-4.5.0, py-1.8.0, pluggy-0.11.0
rootdir: /usr/src/app
collected 1 item

test.py .                                                                [100%]

=========================== 1 passed in 0.04 seconds ===========================

無事通りました :raised_hands:
ここまで出来ればあとは開発へ :thumbsup:

まとめ

  • バージョン切り替えができる環境
  • 環境に左右されない。汚さない。
  • ユニットテストができるように
  • モジュール化を覚えた
  • vscode 使った?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerHubにコンテナイメージをPushしてみよう

はじめに

本ページでは、
Docker上で起動中のコンテナを、コンテナイメージ化し、
DockerHubにPushするところまでをハンズオンを通して学んでいただきます。

前提条件

  • ホストOS:CentOS 7
  • Dockerインストール済み
  • DockerHubアカウント取得済み
    ※DockerHubアカウントを持っていない方は、こちら から必要事項を入力して登録してください。

まずは、DockerHubにPushする元となる Dockerコンテナを起動しましょう。

1. イメージファイルの準備

DockerHubから docker pull コマンドでイメージファイルを取得します。
今回は nginx のコンテナイメージを使用します。

$ docker pull nginx:latest

latest: Pulling from library/nginx
743f2d6c1f65: Pull complete 
6bfc4ec4420a: Pull complete 
688a776db95f: Pull complete 
Digest: sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
Status: Downloaded newer image for nginx:latest

取得したDockerコンテナイメージを docker images コマンドで確認してみましょう。

$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              53f3fd8007f7        2 weeks ago         109MB

2. Dockerコンテナの起動

コンテナイメージから、コンテナを起動します。

$ docker run -d -it --name test-nginx -p 8080:80 nginx:latest

起動したコンテナを docker ps コマンドで確認してみましょう。

$ docker ps -a

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
9e5fa5d4fdfc        nginx:latest        "nginx -g 'daemon of…"   42 seconds ago      Up 42 seconds       0.0.0.0:8080->80/tcp   test-nginx

3. nginxコンテナに接続

ブラウザを起動して、http://<ホストのIPアドレス>:8080 にアクセスしてみましょう。

image.png
nginx が起動していることが確認できました。

4. nginxコンテナを操作

nginxコンテナにログインして index.html ファイルを書き換えてみましょう。

$ docker exec -it test-nginx /bin/bash

root@9e5fa5d4fdfc:/# cat /usr/share/nginx/html/index.html

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

この index.html<h1>Welcome to nginx!</h1> を、自分の名前などに書き換えましょう。

root@9e5fa5d4fdfc:/# sed -i -e "s/Welcome to/KKFD/g" /usr/share/nginx/html/index.html

再度、ブラウザを起動して、http://<ホストのIPアドレス>:8080 にアクセスすると、
表示が変わっていることが確認できます。

image.png
確認できたら、 exit コマンドでコンテナからログアウトしましょう。

root@9e5fa5d4fdfc:/# exit

さぁ、これでDockerHubにPushするコンテナができました!
続いて、このコンテナをコンテナイメージに変換しましょう。


DockerコンテナをDockerコンテナイメージに変換しましょう。

5. コンテナイメージへの変換

コンテナをコンテナイメージに変換するには、 docker commit コマンドを使います。

docker commit コマンドの使い方は下記の通りです。

$ docker commit 変換元のDockerコンテナ名 DockerHubのアカウント名/変換先のDockerコンテナイメージ名[:tag] 

それでは、実際に先ほど作成した nginxコンテナをコンテナイメージに変換してみましょう。

$ docker commit test-nginx DockerHubのアカウント名/test-nginx:kkfd

docker images コマンドを入力すると、実際にコンテナイメージができていることが確認できます。

$ docker images

REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
***********/test-nginx   kkfd                1c7d5fc36af2        4 seconds ago       109MB
nginx                    latest              53f3fd8007f7        2 weeks ago         109MB

ここまでで、DockerHubにPushするDockerコンテナイメージができました!
次はいよいよDockerHubへのPushです!


Dockerコンテナイメージを、DockerHubにPushしましょう。

6. DockerHubへログイン

DockerHubにコンテナイメージをPushするためには、まずDockerHubにログインする必要があります。
事前準備にて作成したDockerHubアカウントを用いてDockerHubにログインしてみましょう。

コマンドは docker login を使用します。
Username と Password を聞かれますので、作成したアカウントでログインしてください。

$ docker login

Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: ***********
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

7. DockerHubへコンテナイメージをPush

いよいよDockerHubへ作成したコンテナイメージをPushします。

コンテナイメージをPushするには、 docker push コマンドを使います。

docker push コマンドの使い方は下記の通りです。

$ docker push DockerHubのアカウント名/Dockerコンテナイメージ名[:tag]

それでは、実際に先ほど作成した コンテナイメージをPushしてみましょう。

$ docker push ***********/test-nginx:kkfd

5e070a02339c: Pushed 
332fa54c5886: Pushed  
6ba094226eea: Pushed
6270adb5794c: Pushed
kkfd: digest: sha256:2270a676f41a51d49586ffdf92d9debe77b02f152de5915f0e2ccfb12a34ca3a size: 1155

これで、DockerコンテナイメージをDockerHubにPushできました!
ブラウザから、DockerHubにログインしてPushされたコンテナイメージを確認してみましょう。

image.png
Pushに成功すると、このようにDockerHubにコンテナイメージが反映されます。

最後に、Pushしたコンテナイメージを再度Pullしてコンテナを起動してみましょう。


PushしたDockerコンテナイメージを起動してみましょう。

8. 既存コンテナ、既存コンテナイメージの掃除

PushしたDockerコンテナイメージをPullする前に、いったん環境をクリアしましょう。

docker rm :コンテナの削除
docker rmi:コンテナイメージの削除

$ docker stop test-nginx
$ docker rm test-nginx

$ docker ps -a

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
$ docker rmi nginx ***********/test-nginx:kkfd

$ docker images

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE

これで、docker環境はクリアされました。

9. PushしたDockerコンテナイメージをPull

先ほどPushしたコンテナイメージを docker pull で pullします。

$ docker pull ***********/test-nginx:kkfd

kkfd: Pulling from ***********/test-nginx
743f2d6c1f65: Pull complete 
6bfc4ec4420a: Pull complete 
688a776db95f: Pull complete 
c9babe9c6f7c: Pull complete 
Digest: sha256:2270a676f41a51d49586ffdf92d9debe77b02f152de5915f0e2ccfb12a34ca3a
Status: Downloaded newer image for *******/test-nginx:kkfd

docker images でpullしたイメージを確認してみましょう。

$ docker images

REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
***********/test-nginx   kkfd                1c7d5fc36af2        28 minutes ago      109MB

無事に、Dockerコンテナイメージがpullできました。

10. コンテナを起動

pullしてきたDockerコンテナイメージから、コンテナを起動します。

$ docker run -d -it --name test-nginx -p 8080:80 ***********/test-nginx:kkfd

起動したコンテナを docker ps コマンドで確認してみましょう。

$ docker ps -a

CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                  NAMES
7aba72530772        ***********/test-nginx:kkfd   "nginx -g 'daemon of…"   6 seconds ago       Up 4 seconds        0.0.0.0:8080->80/tcp   test-nginx

11. nginxコンテナに接続

ブラウザを起動して、http://<ホストのIPアドレス>:8080 にアクセスしてみましょう。

image.png

DockerHubにPushしたコンテナイメージが、正しく起動することを確認できました!

ハンズオンは以上です。 お疲れ様でした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ubuntu Desktop 18.04.2 LTSにDockerをいれる

以下

$ sudo apt install -y docker.io
$ sudo snap install docker
$ sudo apt install docker-compose
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ubuntu上でのDocker環境構築

Ubuntu16.04LTS上でのDocker環境構築(CPU/GPU)

社内の開発環境としてDocker環境を構築しhた。備忘録としてメモする。

背景

サーバ向けアプリの機能開発のため、以前から聞いたことのあったDockerを使用した開発を試みた。
備忘録としてメモに残しておく。

GPUなしの環境での環境構築

環境

 Ubuntu16.04 LTS

セットアップ手順

  • Dockerをインストールする。
# sudo apt update
# sudo apt install docker
  • Dockerの起動、自動起動設定
# sudo systemctrl start docker
# sudo systemctrl enable docker
  • Dockerのプロキシ設定をする ※Proxy環境のみ設定
# mkdir /etc/systemd/system/docker.service.d/
# vim /etc/systemd/system/docker.service.d/http-proxy.conf
http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://(proxy_ip):(proxy_port)/"

proxy_ipproxy_portは使用環境のものを設定

  • DNSサーバの設定をする
# sudo vim /etc/docker/daemon.json
daemon.json
{
    "dns" : ["dns_ip"],
    "dns-opts" : ["timeout:1"]
}

dns_ipには使用環境のDNSサーバIPを入れる

  • Dockerの再起動
# sudo systemctrl daemon-reload
# sudo systemctrl restart docker
  • 一般ユーザでもDockerが起動できるようにする
# sudo usermod -G docker user_name

user_nameには使用するユーザ名を入れる

  • Dockerの起動テスト確認 ※上記一般ユーザで実施
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
d1725b59e92d: Pull complete
Digest:sha256:0add3ace90ecb4adbf777・・・・
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
(省略)

おわり

GPUありの環境での環境構築(nvidia-docker)

環境

 Ubuntu16.04 LTS
 Nvidia Geforce 1080ti

セットアップ手順

  • nvidia driverのインストール
# sudo add-apt-repository ppa:graphics-drivers/ppa
# sudo apt update && sudo apt install -y nvidia-384
# sudo reboot
  • cuda9.0のインストール
# wget https://developer.nvidia.com/compute/cuda/9.0/Prod/local_installers/cuda-repo-ubuntu1604-9-0-local_9.0.176-1_amd64-deb
# sudo dpkg -i cuda-repo-ubuntu1604-9-0-local_9.0.176-1_amd64-deb
# sudo apt-key add /var/cuda-repo-9-0-local/7fa2af80.pub
# sudo apt upgrade
# sudo apt update && sudo apt install -y cuda-9-0
# sudo reboot

nvccコマンドが聞かない場合には、~/.bashrcに以下を追記する

.barhrc
## CUDA paths
export PATH=/usr/local/cuda-9.0/bin:${PATH}
export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64:${LD_LIBRARY_PATH}
  • Dockerをインストールする。
# sudo apt update
# sudo apt install docker
  • Dockerの起動、自動起動設定
# sudo systemctrl start docker
# sudo systemctrl enable docker
  • Dockerのプロキシ設定をする ※Proxy環境のみ設定
# mkdir /etc/systemd/system/docker.service.d/
# vim /etc/systemd/system/docker.service.d/http-proxy.conf
http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://(proxy_ip):(proxy_port)/"

proxy_ipproxy_portは使用環境のものを設定

  • DNSサーバの設定をする
# sudo vim /etc/docker/daemon.json
daemon.json
{
    "dns" : ["dns_ip"],
    "dns-opts" : ["timeout:1"]
}

dns_ipには使用環境のDNSサーバIPを入れる

  • Dockerの再起動
# sudo systemctrl daemon-reload
# sudo systemctrl restart docker
  • 一般ユーザでもDockerが起動できるようにする
# sudo usermod -G docker user_name

user_nameには使用するユーザ名を入れる

  • nvidia-dockerに必要なライブラリをインストール
# sudo apt update && sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
  • nvidia-packageのダウンロード&インストール
# wget https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
# sudo dpkg -i nvidia-docker_1.0.1-1_amd64.deb
  • nvidia-dockerの起動テスト確認 ※上記一般ユーザで実施
$ nvidia-docker run -it --rm nvidia/cuda:9.0-cudnn7-devel-ubuntu16.04

(docker containerログイン後)

# nvidia-smi

おわり

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker 初学 ~imageとcontainer~

Docker 初学 ~ imageとcontainer~

Dockerについて学習したのでDocker imageとcontainerについての知見を深めるために、
自分が学んだことをアウトプットしていきます。

Dockerとは

Dockerとはコンテナ型仮想化技術を実現したプロダクトです。
簡単にいうと、自分のローカル端末の環境を他の人に簡単に渡せるようになるという感じです。
コンテナ型仮想化技術についての詳細はここでは割愛します。
Dockerの基礎的な動作は「Docker image」と「Docker container」に分けられます。

「Docker image」と「Docker container」の関係性

imageとcontainerがどんな関連性を持つか簡単なイメージを作成しました。

スクリーンショット 2019-05-23 21.29.03.png

Docker image
実行するアプリケーションやOSなどの設定をまとめたもので、コンテナを作成するもとになるものです。
Docker container
imageをもとにcontainerを作成して、アプリケーションやOSを実行状態にしたものです。

まとめ
すごく簡単にいうとimageはあくまで設定をまとめたもので、containerはimageを実行している状態のものです。
補足情報
一つのimageから複数のcontainerを作成することができます。

Docker imageについて

「Docker image」の作成は、とてもシンプルです。「Docker File」と言われる定義ファイルにOSなどを設定していけば「Docker image」を作成できます。

ここで簡単なDockerfileを作成してみます。ファイル名は「Dockerfile」です。拡張子もいりません。

Dockerfile
# From句 必須項目 DockerHubから元となるイメージを取得する。
# Dockerfileは必ずFrom句から始まります。そして、DockerHubからイメージをダウンロードしてきます。
From debian:stable-slim
# CMD句 任意項目 Docker image 作成時に実行するコマンドを定義する。
CMD ["echo","Hello World!"]

何をしているかというと、DockerHubにあるdebianのimageをもとにDockeriamgeを作成しているだけです。
(OSを設定しているだけでアプリケーションは乗せてないです。)

そして、以下のコマンドを実行すると、Dockerimageができると思います。

docker image build -t example/echo:latest .

Docker imageが作成できた確認として以下のコマンドを実行してください。

docker images
# example/echoとdebianのimageが表示されるはずです。

今回作成した「Docker image」のイメージ図は以下の感じです。
debianを内包しているような感じです。
スクリーンショット 2019-05-23 22.08.14.png

ここにjavaだとかgoとか様々なアプリをカスタマイズしていきます。
(プログラミング言語を内包したDockerimageは公式として提供されているケースが多いです。)
まとめ
Dockerfileを作成して「Docker image」を作成する。
自作の「Docker image」は別の「Docker image」に依存するケースがある。
(From 句でscrachと指定されているのは違いますが、話が難しくなるので割愛します。)

Docker containerについて

それでは、イメージからコンテナを作成してみましょう。

docker container run example/echo

Hello Worldと出力されたと思います。

今回作成したコンテナはコマンド実行だけですが、httpリクエスト受付やできることが
もっとありますので、今度試してみたいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む