20200627のdockerに関する記事は17件です。

Docker hub からイメージを pull する時、CPUのアーキテクチャを指定する。

Docker hub にて、イメージを選択した時に出てくる、この項目。
docker-hub-02.png

気になって調べてみたら、pull する時、イメージのCPUアーキテクチャを指定する事ができるみたいです。

参考までに、Docker のマニュアル(docker pull)が、こんな感じになってます。
https://docs.docker.com/engine/reference/commandline/pull/

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

TAG を指定する方法の他に、DIGEST を指定する方法もあるみたいです。

今回のケースの場合、DIGEST は、この部分。
docker-hub-03.png

DIGESTを指定して pull する時、こんな感じなります。

docker pull php@sha256:84311597ecddef820dfab8893acbcdc1f1b3b545decfedf791aa7b99429206df

「:」ではなく「@」を使い、「sha256~」のあたりから書き始めます。

試しに、php:7.4.7-fpm-buster の各種アーキテクチャで実験してみました。

docker-compose.yml
version: '3'
services:
  # linux/amd64
  app01:
    image: php@sha256:cf3f0f13f1726595bdee10ece07c788b54e3f491817ae1b274931d5520af2d47
  # linux/ppc64le
  app02:
    image: php@sha256:89a021692e04f3e88a574e918ecf2b620465d70f936ab9d2cd17cdf99bf8cd87
  # linux/386
  app03:
    image: php@sha256:5846a11aa9541b93c07160af0359a2650842e914f2e23a0f77c123945b0670bf
  # linux/s390x
  app04:
    image: php@sha256:250e769a4d0eb7502e7aa73d7c5151129f6a07931467ba16b4c930f2ba942d2c
  # linux/arm/v7
  app05:
    image: php@sha256:84311597ecddef820dfab8893acbcdc1f1b3b545decfedf791aa7b99429206df
  # linux/arm64/v8
  app06:
    image: php@sha256:a8a5be3677f3e25dde3cb9b528535b8493d9c4a4e99b7a56d622e5638c7c307b
  # linux/arm/v5
  app07:
    image: php@sha256:8e95f90bba6652bb5a42291a46a17923dcadd6cabf69fda594aba1be2a9b6555

以下、コンテナの中に入って、arch コマンドでアーキテクチャを出力した時の内容です。

#linux/amd64
x86_64

# linux/ppc64le
ppc64le

# linux/386
x86_64

# linux/s390x
s390x

# linux/arm/v7
armv7l

# linux/arm64/v8
aarch64

# linux/arm/v5
armv7l

マニュアルを読んでも、DIGEST は、「イメージの一意の値を表すもの」という表現しかなく、CPU については触れていないので、ちょっと分かりづらい気がする。

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

Docker で Ruby on Jets + React のアプリを作成する開発環境構築

概要

Ruby on Jets(API)と React のアプリを作成するための開発環境構築手順です。
Ruby on Jets は API 専用として作成します。DB は MySQL を利用。
React は Typescript を使います。
Docker は Docker for Mac を利用。

ローカルでページを開くと API から DB に保存されているユーザー情報を取得して表示するところまでやっています。
AWS へのデプロイまではしていません。

ファイル構成

reactjets/
  ├ api/
  │  ├ ...
  ├ front/
  │  ├ ...
  ├ docker/
  │  ├ api/
  │  │  ├ Dockerfile
  │  ├ front/
  │  │  ├ Dockerfile
  │  ├ mysql/
  │  │  ├ conf.d
  │  │  │  ├ my.cnf
  │  ├ docker-compose.yml

Docker 環境構築

Dockerfile(2種),Gemfile, Gemfile.lock, my.cnf, docker-compose.yml を作成

docker/front/Dockerfile
FROM node:12.18
docker/api/Dockerfile
FROM ruby:2.7.1

WORKDIR /api
COPY api /api
RUN bundle install
api/Gemfile
source 'https://rubygems.org'
gem 'jets'

Gemfile.lock は空のファイルを作成

api/Gemfile.lock
touch Gemfile.lock
docker/mysql/conf.d/my.cnf
[mysqld]
character-set-server=utf8mb4
explicit-defaults-for-timestamp=1

[client]
default-character-set=utf8mb4
docker/docker-compose.yml
version: '3'

services:
  front:
    build:
      context: ../
      dockerfile: docker/front/Dockerfile
    volumes:
      # :より左の部分は自分の環境に合わせる
      - ~/Dev/reactjets/front:/front
    ports:
      - "8000:3000"
    stdin_open: true

  api:
    build:
      context: ../
      dockerfile: docker/api/Dockerfile
    command: bash -c "bundle exec jets server --port 3000 --host 0.0.0.0"
    volumes:
      # :より左の部分は自分の環境に合わせる
      - ~/Dev/reactjets/api:/api
    ports:
      - "3000:3000"
    depends_on:
      - db

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: app
      MYSQL_USER: docker
      MYSQL_PASSWORD: docker
      TZ: 'Asia/Tokyo'
    ports:
      - 3306:3306
    volumes:
      - ./mysql/conf.d:/etc/mysql/conf.d

docker-compose ビルド

$ docker-compose build

Jets アプリ作成

$ docker-compose run api jets new . --mode api --database=mysql

※ Overwrite /api/Gemfile? (enter "h" for help) [Ynaqdhm] がでてきたら Y

api 配下に jets アプリケーションが作成されていることを確認
DB 接続のために .env.development に環境変数を追加

.env.development
DB_HOST=db
DB_NAME=app
DB_USER=docker
DB_PASS=docker

React アプリ作成

$ docker-compose run --rm front sh -c 'yarn create react-app front --template typescript'

front 配下に react アプリケーションが作成されていることを確認

起動

$ docker-compose up --build

react 起動

$ docker exec -it docker_front_1 bash

# cd front
# yarn start

画面が表示されることを確認
Ruby on Jets : http://localhost:3000
React : http://localhost:8000
スクリーンショット 2020-06-27 10.42.37.pngスクリーンショット 2020-06-27 17.56.45.png

api 作成

user を scaffold で作成

$ docker exec -it docker_api_1 bash

# jets generate scaffold user name:string age:integer
# jets db:create db:migrate

※ jets db:create db:migrate で access denied など出ていたら mysql 側のユーザーの権限設定を確認する

GRANT ALL ON *.* to docker@'%';

users テーブルが作成されているので、直接2件適当に INSERT し
http://localhost:3000/users にアクセスすると、以下のようなデータが返ってきていることが確認できる

[{"id":1,"name":"mikami","age":26,"created_at":"2020-06-27T18:57:44.000Z","updated_at":"2020-06-27T18:57:44.000Z"},{"id":2,"name":"tomoyuki","age":32,"created_at":"2020-06-27T18:57:44.000Z","updated_at":"2020-06-27T18:57:44.000Z"}]

front と api の疎通

front 側

axios インストール

$ docker exec -it docker_front_1 bash

# cd front
# yarn add axios

App.tsx を編集

App.tsx
import React from 'react';
import axios from 'axios';
import './App.css';

class App extends React.Component<any, any> {
  constructor(props: any) {
    super(props);
    this.state = {
      users: []
    }
  }

  componentDidMount() {
    axios.get('http://localhost:3000/users')
      .then((result) => {
        this.setState({ users: result.data });
      })
  }

  render() {
    return (
      <div className="App">
        <h1>Users</h1>
        <div>
          { this.state.users.map((v: any) => {
            return (
              <div key={v.id}>
                <p>id: {v.id}</p>
                <p>name: {v.name}</p>
                <p>age: {v.age}</p>
              </div>
            )
          })}
        </div>
      </div>
    )
  }
}

export default App;

このままでは CORS で通信できないので、api 側で CORS の設定をする

api 側

以下のコメントアウトを外す

application.rb
config.cors = true # for '*'' # defaults to false

確認

再起動

$ docker-compose stop
$ docker-compose start
$ docker exec -it docker_front_1 bash

# cd front
# yarn start

http://localhost:8000/ にアクセスすると以下のように表示されていれば疎通ok
スクリーンショット 2020-06-27 19.25.09.png

WIP

AWS へのデプロイ手順

Ruby on Jets デプロイ

https://qiita.com/kskinaba/items/9c570093ed912f8f1681 この通りにやる

Ruby 2.5系じゃないとだめらしい…

Deploying to Lambda api-dev environment...
/usr/local/bundle/gems/memoist-0.16.2/lib/memoist.rb:213: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/usr/local/bundle/gems/jets-2.3.16/lib/jets/lambda/dsl.rb:319: warning: The called method `_unmemoized_find_all_tasks' is defined here
Building CloudFormation templates.
Generated CloudFormation templates at /tmp/jets/api/templates
Deploying CloudFormation stack with jets app!
Waiting for stack to complete
02:25:31AM CREATE_IN_PROGRESS AWS::CloudFormation::Stack api-dev User Initiated
02:25:34AM CREATE_IN_PROGRESS AWS::S3::Bucket S3Bucket
02:25:35AM CREATE_IN_PROGRESS AWS::S3::Bucket S3Bucket Resource creation Initiated
02:25:56AM CREATE_COMPLETE AWS::S3::Bucket S3Bucket
02:25:58AM CREATE_COMPLETE AWS::CloudFormation::Stack api-dev
Stack success status: CREATE_COMPLETE
Time took for stack deployment: 28s.
You are using Ruby version 2.7.1 which is not supported by Jets.
Jets uses Ruby 2.5.3.  You should use a variant of Ruby 2.5.x
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker MAMP ポート nginxエラーが出た話

dockerをいれたら、localhostでMAMPに入れなくなった。
nginxの404エラーだったので、おそらくポートが競合していると考えた。

MAMPの上のバーのファイルからpreferencesで、
ポートを80から50にして、
nginxから apacheに変更して解決。
次回以降ログインの際には、localhot:50/で始める必要ありますが。。。

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

100日後にエンジニアになるキミ - 99日目 - 開発環境 - Kubernetesについて

昨日までのはこちら

100日後にエンジニアになるキミ - 95日目 - 開発環境 - Docker について

100日後にエンジニアになるキミ - 94日目 - 開発環境 - 仮想化について

100日後にエンジニアになるキミ - 91日目 - 運用 - 監視について

100日後にエンジニアになるキミ - 90日目 - 開発 - CIについて

100日後にエンジニアになるキミ - 88日目 - データ - データ転送について

100日後にエンジニアになるキミ - 86日目 - データベース - Hadoopについて

100日後にエンジニアになるキミ - 76日目 - プログラミング - 機械学習について

100日後にエンジニアになるキミ - 70日目 - プログラミング - スクレイピングについて

100日後にエンジニアになるキミ - 66日目 - プログラミング - 自然言語処理について

100日後にエンジニアになるキミ - 63日目 - プログラミング - 確率について1

100日後にエンジニアになるキミ - 59日目 - プログラミング - アルゴリズムについて

100日後にエンジニアになるキミ - 53日目 - Git - Gitについて

100日後にエンジニアになるキミ - 42日目 - クラウド - クラウドサービスについて

100日後にエンジニアになるキミ - 36日目 - データベース - データベースについて

100日後にエンジニアになるキミ - 24日目 - Python - Python言語の基礎1

100日後にエンジニアになるキミ - 18日目 - Javascript - JavaScriptの基礎1

100日後にエンジニアになるキミ - 14日目 - CSS - CSSの基礎1

100日後にエンジニアになるキミ - 6日目 - HTML - HTMLの基礎1

本日はKubernetesについてです。

Kubernetesについて

image.png

公式などの説明だと、コンテナ化したアプリケーションのデプロイ、スケーリング
および管理を行うための、オープンソースのコンテナオーケストレーションシステム
と言うことだそうです。

簡単に言うとコンテナの運用管理と自動化を行うためのツール
と言ったところでしょうか。

K8sと略記され、ギリシャ語で「操舵手」や「パイロット」という意味があり
知事やサイバネティックスの語源にもなっています。
ロゴも舵な感じですね。

K8sは8文字のubernete8に置き換えた略語だそうです。

コンテナを使う意義

とその前にコンテナを使うことの意味ですが
昔の開発環境では1つのサーバーにライブラリをたくさんインストールして
その上で動くアプリケーションを配置していました。

1つ1つの環境は重めになります。

スクリーンショット 2020-06-27 16.50.39.png

それに対して現在の開発の主流はアプリケーションごとに
使用するライブラリ群を切り離すことで実行環境を軽くし
ビルドやデプロイなどの時間がかからないようにすることを目指しています。

アプリケーションの開発では開発環境の構築から始まりので
それを1からまとめてコンテナに集約し
開発現場と本番環境に差異がないようにしたり
環境整備にかかる時間の圧縮をしています。

そのような開発のメリットからコンテナを用いた開発が増えています。

コンテナオーケストレーション

当然開発するアプリケーション群が増えていくと
コンテナも増えていくことになります。

複数のコンテナを管理して自動化を行なって、複数制御してと言うことが
必要になって来ました。

Kubernetesの登場により、複数のコンテナの管理や自動化が進んだため
この仕組みはコンテナオーケストレーションと呼ばれるようになりました。

コンテナにも種類がありDockerはその一つです。
Kubernetesが対象としているコンテナはDockerが標準になっています。

image.png

参考:https://www.kagoya.jp/howto/rentalserver/kubernetes/

Kubernetesを使うと何が出来るのか

プロダクションで利用しようとすると下記のようなことを考えなければなりません。

複数のDockerホストの管理
コンテナの死活監視
コンテナのスケジューリング、アップデート
スケーリング / オートスケーリング
ロードバランシング
障害時のセルフヒーリング
データやワークロード、ログの管理
その他システムとの連携、拡張、同期

Kubernetesを利用することでこれらの課題を解決することができます。

Kubernetesを利用しない場合には
これらの自動化の仕組みを1から作り上げる必要があります。

フルマネージドのサービス

クラウドサービスではKubernetesを取り扱うことのできる
フルマネージドのサービスが存在したりします。

Google Kubernetes Engine(GKE)
Amazon Elastic Kubernetes Service(EKS)

これらを用いることで、自前で組むよりも簡単に
Kubernetesを用いた環境を構築することができます。

まとめ

データ分析くらいであれば、コンテナ1つ使ってくらいで事足りますが
大規模開発になると数百とかのコンテナ数になり
管理もしきれなくなって来ます。

1からコンテナ管理の仕組みを作るのも大変ですし
既にコンテナ管理の仕組みは存在しているので
それを利用する方が得策です。

モダンな開発現場で仕事をしたい場合は
こう言ったコンテナ環境の制御の仕組みがあることを
押さえておく必要があると思います。

君がエンジニアになるまであと01日

作者の情報

乙pyのHP:
http://www.otupy.net/

Youtube:
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMw

Twitter:
https://twitter.com/otupython

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

macOS の上の VirtualBox の上の Ubuntu の上の Docker の上の jupyter notebook を、SSH で扱うためのリンク集

MacOS の VirtualBox に Ubuntu をインストールする

やっとできた!MacのVirtualBox上にUbuntuをインストールする方法
https://tomslifestylelab.com/mac-virtualbox-ubuntu/

とりあえず

sudo apt-get update
sudo apt-get upgrade

MacでUbuntuを快適に使う
https://qiita.com/ryoheimorimoto/items/a82369a83c100a646cce

Ubuntu に SSH でアクセスできるようにする

Mac 上のVirtual Box のUbuntu にSSH でアクセスしX転送する
https://withfpga.com/?p=78

Virtualboxでアダプタ2,アダプタ3,アダプタ4が選択できない
https://teratail.com/questions/164319

SSH で Docker をインストールする

Ubuntu に Docker をインストールする
https://docs.docker.com/engine/install/ubuntu/

Dockerコマンドをsudoなしで実行する方法
https://qiita.com/DQNEO/items/da5df074c48b012152ee

Docker 上で Jupyter notebook を作成してアクセスする

Dockerで基本的なData Science環境(Jupyter, Python, R, Julia, 定番ライブラリ)を構築する。
https://qiita.com/y4m3/items/c2703d4e131e05084b7b

サーバーのDockerで起動したJupyter Notebookを他のパソコンからアクセスできるようにした話
https://qiita.com/yamasakih/items/d23ac0bf773e9b1b4d9d

Julia+Jupyter Notebook環境をDockerで構築
https://qiita.com/yoshikiri/items/683722701b57fa77aec1

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

macOS の上の VirtualBox の上の Ubuntu の上の Docker の上の Python を、SSH でアクセスして実装するためのリンク集

MacOS の VirtualBox に Ubuntu をインストールする

やっとできた!MacのVirtualBox上にUbuntuをインストールする方法
https://tomslifestylelab.com/mac-virtualbox-ubuntu/

とりあえず

sudo apt-get update
sudo apt-get upgrade

MacでUbuntuを快適に使う
https://qiita.com/ryoheimorimoto/items/a82369a83c100a646cce

Ubuntu に SSH でアクセスできるようにする

Mac 上のVirtual Box のUbuntu にSSH でアクセスしX転送する
https://withfpga.com/?p=78

Virtualboxでアダプタ2,アダプタ3,アダプタ4が選択できない
https://teratail.com/questions/164319

SSH で Docker をインストールする

Ubuntu に Docker をインストールする
https://docs.docker.com/engine/install/ubuntu/

Dockerコマンドをsudoなしで実行する方法
https://qiita.com/DQNEO/items/da5df074c48b012152ee

Docker 上で Jupyter notebook を作成してアクセスする

Dockerで基本的なData Science環境(Jupyter, Python, R, Julia, 定番ライブラリ)を構築する。
https://qiita.com/y4m3/items/c2703d4e131e05084b7b

サーバーのDockerで起動したJupyter Notebookを他のパソコンからアクセスできるようにした話
https://qiita.com/yamasakih/items/d23ac0bf773e9b1b4d9d

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

Dockerで ROS Kinetic 環境を扱う

目的

Dockerで ROS Kinetic 環境を扱う際の備忘録です

Docker ROS Kinetic 環境のイメージファイルを取得する

$ docker run -it --rm -p 6080:80 ct2034/vnc-ros-kinetic-full

ブラウザから、http://127.0.0.1:6080 へアクセスできればOK

スクリーンショット 2020-05-17 12.27.25.png

turtlesimも動きました

roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key

スクリーンショット 2020-05-17 12.29.09.png

Dockerfileから起動

$ mkdir -p test
$ cd test
$ git clone git https://github.com/ct2034/docker-ubuntu-vnc-desktop
$ cd docker-ubuntu-vnc-desktop

Dockerfileはこのようになっている

FROM ubuntu:16.04

ENV DEBIAN_FRONTEND noninteractive

# built-in packages
RUN apt-get update \
    && apt-get install -y --no-install-recommends software-properties-common curl \
    && sh -c "echo 'deb http://download.opensuse.org/repositories/home:/Horst3180/xUbuntu_16.04/ /' >> /etc/apt/sources.list.d/arc-theme.list" \
    && curl -SL http://download.opensuse.org/repositories/home:Horst3180/xUbuntu_16.04/Release.key | apt-key add - \
    && add-apt-repository ppa:fcwu-tw/ppa \
    && apt-get update \
    && apt-get install -y --no-install-recommends --allow-unauthenticated \
        supervisor \
        openssh-server pwgen sudo vim-tiny \
        net-tools \
        lxde x11vnc xvfb \
        gtk2-engines-murrine ttf-ubuntu-font-family \
        firefox \
        nginx \
        python-pip python-dev build-essential \
        mesa-utils libgl1-mesa-dri \
        gnome-themes-standard gtk2-engines-pixbuf gtk2-engines-murrine pinta arc-theme \
        dbus-x11 x11-utils \
        terminator \
    && apt-get autoclean \
    && apt-get autoremove \
    && rm -rf /var/lib/apt/lists/*

# =================================
# install ros (source: https://github.com/osrf/docker_images/blob/5399f380af0a7735405a4b6a07c6c40b867563bd/ros/kinetic/ubuntu/xenial/ros-core/Dockerfile)
# install packages
RUN apt-get update && apt-get install -y --no-install-recommends \
    dirmngr \
    gnupg2 \
    && rm -rf /var/lib/apt/lists/*

# setup keys
RUN apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654

# setup sources.list
RUN echo "deb http://packages.ros.org/ros/ubuntu xenial main" > /etc/apt/sources.list.d/ros-latest.list

# install bootstrap tools
RUN apt-get update && apt-get install --no-install-recommends -y \
    python-rosdep \
    python-rosinstall \
    python-vcstools \
    && rm -rf /var/lib/apt/lists/*

# setup environment
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8

# bootstrap rosdep
RUN rosdep init \
    && rosdep update

# install ros packages
ENV ROS_DISTRO kinetic
RUN apt-get update && apt-get install -y \
#    ros-kinetic-ros-core=1.3.1-0* \
    ros-kinetic-desktop-full \
    #              A
    #              +--- full desktop \
    && rm -rf /var/lib/apt/lists/*

# setup entrypoint
# COPY ./ros_entrypoint.sh /


# =================================

# user tools
RUN apt-get update && apt-get install -y \
    terminator \
    gedit \
    okular \
    vim \
    && rm -rf /var/lib/apt/lists/*

# tini for subreap
ENV TINI_VERSION v0.9.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /bin/tini
RUN chmod +x /bin/tini

ADD image /
RUN pip install setuptools wheel && pip install -r /usr/lib/web/requirements.txt

RUN cp /usr/share/applications/terminator.desktop /root/Desktop
RUN echo "source /opt/ros/kinetic/setup.bash" >> /root/.bashrc


EXPOSE 80
WORKDIR /root
ENV HOME=/home/ubuntu \
    SHELL=/bin/bash
ENTRYPOINT ["/startup.sh"]

gnome-terminal をインストールする場合

apt-get update
apt-get install -y gnome-terminal

less をインストールする場合

apt-get install -y less

ros-kinetic-turtlebot3 関係のパッケージを入れる

一通り必要そうなものをインストール

apt-get install -y python-pip; \
pip install requests flask; \
apt-get install -y ros-kinetic-turtlebot3 ros-kinetic-turtlebot3-msgs ros-kinetic-turtlebot3-simulations; \
apt-get install -y ros-kinetic-aruco-ros; \
echo "export TURTLEBOT3_MODEL=burger" >> ~/.bashrc
source ~/.bashrc

必要に応じて、GAZEBOモデルのパスを追加する

echo "export GAZEBO_MODEL_PATH="GAZEBOモデルのパス" >> ~/.bashrc
source ~/.bashrc

catkin_wsの設定

http://wiki.ros.org/ja/catkin/Tutorials/create_a_workspace

mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace
cd ~/catkin_ws/
catkin_make
echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
source ~/.bashrc

その他

何か不足点あれば教えて頂けますと幸いです。
(新しいエラーに直面した時に、あまり先人の資料がなく解決が難しいです。。)

参考

ROS Kinetic の Ubuntu へのインストール
ROSトピックの理解
Problem with “gnome-terminal” on Gnome 3.12.2
ct2034/vnc-ros-kinetic-full
ct2034/docker-ubuntu-vnc-desktop
fcwu/docker-ubuntu-vnc-desktop
gnome-terminal-3.36.2
最小インストールしたDebianの初期設定メモ

http://wiki.ros.org/ja/catkin/Tutorials/create_a_workspace
ROS kineticでmove base使用時にDWAPlannerROS planner周りのエラーが出た時の対策メモ

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

Laravel開発用のDockerイメージできたのでシェアします。

これからLaravelを使って開発とかしていく予定だったので、すぐにスタートできるようにDockerでイメージ作りました。
同じ環境で開発してる方など、よかったら持ってってください。

https://hub.docker.com/r/ryuki0529/webserver

大まかなイメージ環境

  • OS:CentOS 7.8
  • サーバー:Apache 2.4.6
  • PHP 7.4.7
  • PHPMyAdmin 5.0.2
  • Composer 1.10.7
  • Laravel Installer 3.1.0
  • Git 2.9.5
  • データベース:mysql Ver 15.1 Distrib 10.4.13-MariaDB

注意点

docker runでコンテナ作るときに、--privilegedと起動時のコマンドで/sbin/initを指定しないとsystemctlコマンド周りが使えないので注意です。これで3時間ほどハマってしまいました。

詳しくは下記の記事で説明されてます。
CentOS7のコンテナでsystemctlを使うための方法

ということで、最終的にコマンドは以下になります。

docker run -itd -p 80:80 --privileged webserver:1.0.2 /sbin/init
docker exec -it webserver /bin/bash
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsのdevise導入でdefault_url_optionsの設定でハマった

deviseのユーザー認証設定

デフォルトの場合以下のようにconfig.action_mailer.default_url_options{ host: 'localhost', port: 3000 }と設定されると多います。

development.rb
  # default url
  config.action_mailer.default_url_options = {  host: 'localhost', port: 3000 }
  # mail setting
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :address => "smtp.gmail.com",
    :port => 587,
    :user_name => Rails.application.credentials.gmail[:user_name],
    :password => Rails.application.credentials.gmail[:password],
    :authentication => :plain,
    :enable_starttls_auto => true
  }

その場合認証メールで送られてくるURLはhttp://localhost:3000/users/confirmation?confirmation_token=-XiHyA_1xCxhk846ae9G
みたいな形になる思います。

Dockerでrootディレクトリが3000ポートを付けない形で構築したのでポート番号がない形でURLを作成しなければいけないので以下のように設定を変更しました。

development.rb
config.action_mailer.default_url_options = {  host: 'localhost' }

URLが変更されない

本来であればhttp://localhost/users/confirmation?confirmation_token=-XiHyA_1xCxhk846ae9Gのような形でURLが生成されるはずがされず数時間ハマりました。

結論

Dockerの再起動で反映された。

Web開発をしていると常にハマるポイントがありますが、再起動で動くことが多々あるので「ハマったら再起動してみる」ということをもっと心がけて行きたいです。

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

NVIDIA container toolkitを使って、dockerのコンテナ上でcudaを動かす

概要

docker上でcudaを動かしたいと思うときがあったので、その方法を調べたところnvidia container toolkitを使えばいいとわかったので、その手順をまとめました。nvidia-dockerやnvidia-docker2の進化系がnvidia container toolkitです。詳しくはこちらのリンクにまとめられています。
Screenshot from 2020-06-27 13-42-19.png
https://github.com/NVIDIA/nvidia-docker

目的

nvidia docker container tookitを使って、dockerのコンテナ上でcuda(10.1)を動かします。また、opencvとpytorchもコンテナ上に入れます。

環境

  • Ubuntu 18.04
  • docker 19.03
  • nvidia driver 450.36

手順

1. nvidia container toolkitをインストールする

公式通りに進めます。まずは、nvidia container toolkitのインストールです。

# Add the package repositories
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
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-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker

2. cudaの動作確認

下のコマンドを打てば、自分の入れたいcudaが入っている仮想環境を動かすことができます。今回は、cuda10.1&ubutu18.04のイメージをもとに作成しました。こちらにcudaのイメージの一覧があるので、自分の作りたい環境に合わせて、コマンドのnvidia/cuda:10.1-base-ubuntu18.04の箇所を入れ替えてください。また、gpusのところで使いたいgpusの個数を選べます。今回はgpuを全て使うallとしていますが、例えばgpuを4個中2個使いたいときは--gpus 2とすれば大丈夫です。

docker run --gpus all nvidia/cuda:10.1-base-ubuntu18.04 nvidia-smi

3. pytorchのイメージを入手する

docker pull pytorch/pytorch

4. コンテナを作成、起動する

ローカルのディレクトリをdockerのディレクトリにマウントします。

docker run -it --gpus all -v ホストpcのディレクトリ:docker上のディレクトリ --shm-size 16G --name ml pytorch/pytorch

-itでそのままbashを起動します。--gpusで使うgpuの数を決められます。-vでホストpcのディレクトリをdockerのディレクトリにマウントできます。--shm-sizeはコンテナに割り当てるメモリのサイズです。--nameはコンテナ名です。自由に決められます。pytorch/pytorchはpullしてきたimageの名前です。bashが起動してlsコマンドを打つと、ローカルのディレクトリがマウントされていることが確認できると思います。

5. opencvをインストール

pip install opencv-python

ImportError: libgthread-2.0.so.0: cannot open shared object file: No such file or directory

import cv2したときに上のようなエラーが出る場合は、下のコマンドを打てば大丈夫だと思います。

apt update
apt-get install -y libglib2.0-0 libsm6 libxrender1 libxext6

まとめ

nvidia container toolkitを使えばローカルを汚さずに環境構築できるし、楽ちん。

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

MacでDockerをインストールして起動しようとしたらThe operation couldn’t be completed. (Docker.VmnetdError error 1.)と出た

Dockerを起動できなくなったので、再インストールしてしている時に起こった

The operation couldn’t be completed. (Docker.VmnetdError error 1.)

単純にオペレーション終わってないですよ!ということなのだが、これがDockerを起動しようとしたら起こり、そしてインストール後にも同様のエラー。

何事かと思い、ひとまずググる。
すると同じエラーを抱えた人がたくさんいたらしく、Issuesに投稿されていた。

解決法

https://github.com/docker/for-mac/issues/3886

スクリーンショット 2020-06-27 12.54.03.png

インストールした後にそのままこの画面から起動するのではなく、Applicationから起動すると起動できた。

ただ、これだけでは起動できないパターンもあるらしく、その場合はbrewをインストールし直すと解決した例があるらしい。

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

プライベートなDockerレジストリからイメージ情報を取得する

curl <registory.domain:port>/v2/_catalogで取得できる。

~$ curl http://0.0.0.0:5000/v2/_catalog
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RailsとDockerでよく使うコマンドまとめ

docker-compose build #コンテナの作成
docker-compose up #コンテナ立ち上げ
docker-compose down #コンテナをダウン ctrl+cでも止められるがserver.pidでエラーになる
docker-compose stop #コンテナをストップ
docker-compose up --build #docker関連のファイルの変更を反映した上に、サーバーを再起動
docker images #イメージ一覧
docker ps #動いているコンテナ一覧
docker ps -a #動いていないコンテナも含めた一覧
docker rm `docker ps -a -q` #コンテナの一括削除
docker rmi `docker images -a -q` #イメージの一括削除
mysql -u root -p -h localhost -P 3306 --protocol=tcp #DockerからMYSQLへ

docker-compose run web bundle install #bundle install
docker-compose run web rails db:create #db作成
docker-compose run web rails db:migrate #マイグレート

以上、RailsとDockerでよく使うコマンドたちでした!
参考になれば幸いです。
間違えなどありましたらご指摘お願いします。

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

Ubuntu18.04にDoker19.03環境構築(+NVIDIA Container Toolkit)

参考文献

本ページは以下を参考にしています。

概要

Dockerを使えば

  • 環境を汚すことなくCUDA ToolkitやcuDNNのバージョンが変えられる
  • 環境構築に要する時間が短くなる

と聞いたので上記ページを参考に自身の環境にDocker環境を構築しました。
自身の備忘録ですので、参考程度にご覧ください。

手順1 Dockerのインストール

Install Docker Engine on Ubuntuに従って進めます。

  1. 古いDockerの削除

    $ sudo apt-get remove docker docker-engine docker.io containerd runc
    
  2. リポジトリの設定

    $ sudo apt-get update
    $ sudo apt-get install \
           apt-transport-https \
           ca-certificates \
           curl \
           gnupg-agent \
           software-properties-common
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    $ sudo apt-key fingerprint 0EBFCD88
    # x86_64 / amd64 の場合
    $ sudo add-apt-repository \
           "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
           $(lsb_release -cs) \
           stable"
    
  3. Docker Engineのインストール

    $ sudo apt-get update
    # 最新版をインストール(特定のバージョンをインストールする方法は公式ページを参照)
    $ sudo apt-get install docker-ce docker-ce-cli containerd.io
    # 再起動
    $ sudo reboot
    
  4. 確認

    $ sudo docker run hello-world
    # --- 以下のような情報が出力される ---
    # Unable to find image 'hello-world:latest' locally
    # latest: Pulling from library/hello-world
    # 0e03bdcc26d7: Pull complete 
    # Digest: sha256:d58e752213a51785838f9eed2b7a498ffa1cb3aa7f946dda11af39286c3db9a9
    # Status: Downloaded newer image for hello-world:latest
    # 
    # Hello from Docker!
    # This message shows that your installation appears to be working correctly.
    # 
    # To generate this message, Docker took the following steps:
    #  1. The Docker client contacted the Docker daemon.
    #  2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    #     (amd64)
    #  3. The Docker daemon created a new container from that image which runs the
    #     executable that produces the output you are currently reading.
    #  4. The Docker daemon streamed that output to the Docker client, which sent it
    #     to your terminal.
    # 
    # To try something more ambitious, you can run an Ubuntu container with:
    #  $ docker run -it ubuntu bash
    #
    # Share images, automate workflows, and more with a free Docker ID:
    #  https://hub.docker.com/
    # 
    # For more examples and ideas, visit:
    #  https://docs.docker.com/get-started/
    

手順2 NVIDIA Container Toolkitのインストール

NVIDIA/nvidia-dockerのQuickstartに従って進めます。

  1. リポジトリ追加

    $ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
    $ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
    $ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
    
  2. インストール

    $ sudo apt-get update
    $ sudo apt-get install -y nvidia-container-toolkit
    # Dockerリスタート
    $ sudo systemctl restart docker
    
  3. 確認

    # CUDA10.0,すべてのGPUを使用
    docker run --gpus all nvidia/cuda:10.0-base nvidia-smi
    

おまけ 非toot権限でDockerコマンド使用

Post-installation steps for Linuxに従って進めます。

  1. dockerグループの作成

    $ sudo groupadd docker
    
  2. ユーザーの追加

    $ sudo usermod -aG docker $USER
    
  3. 設定の反映(ログアウト&ログイン or 以下コマンド実行)

    $ newgrp docker
    
  4. 確認

    $ docker run hello-world
    

感想

インストールは手順がしっかり記載されていたため、特に問題なくできました。
ただ、Dockerの使い方が全然わかりません(笑)

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

WSL2+Docker+Laravel既存コードでの開発環境作成(XAMPPからの移行)

PC移行に伴い新たな開発環境を構築する必要が出てきたが、XAMPP入れるのも古いかな(nginx使いたいし)、WSL上にごちゃごちゃ入れると何入れたかわからなくなる、と思ったのでDockerでなんとかならないかと試してみることに。
Dockerが動く状況なら移行先でも同様の開発環境がすぐに構築できるようになったはず。

WSLを入れるところから長々書いているので、答えだけdockerのファイルの答えだけ見たい方は、下の方を見るか
https://github.com/miyawa-tarou/docker-test/commit/5d5c78633a6c0e94b0c25849cf683c9a459b891e
あたりを見てください。

WSL2を入れる

Windowsのアップデート

  • Windows 10、バージョン 2004、ビルド 19041 以上である必要があるので、アップデートします。
  • WindowsUpdateのところからできる場合もあるようですが、ゆっくりと順次配布のためない場合は下記からダウンロードできます

仮想化を有効にする

BIOS

  • ここはメーカーによるから細かい方法は置いておくが、BIOSに入って
  • Intel Virtualizationとかがdisalbeになっていたらenableにする

Windows

Windowsの仮想化を有効に(GUIからやる方法もあるはず)
PowerShellを管理者モードで開き下記を実行

> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
> Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform

再起動

WSL2の設定

https://docs.microsoft.com/ja-jp/windows/wsl/install-win10
再びPowerShellを管理者モードで開き下記を実行

> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

WSLのデフォルトをバージョン2にしておく
powershell
wsl --set-default-version 2

「最新の WSL2 Linux カーネル更新プログラム パッケージ」が必要なこともあるかもしれない。
その場合は下記からダウンロード。

https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel

ディストリビューションを入れる

https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#install-your-linux-distribution-of-choice

WindowsStoreから好みを入れる(自分はUbuntuを入れた)
入ったら一回起動しておく(ここは起動しなくて動くか確かめてない)

ディストリビューションをあとからWSL2にする

WSL1で入れてしまった場合は、下記コマンドで変換する

> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-18.04    Stopped         1
  Ubuntu          Running         1
> wsl --set-version Ubuntu 2

変換なのでちょい時間がかかる

Docker Desktopを入れる

https://www.docker.com/products/docker-desktop

Enable WSL2 Windows Featuresのチェックは付けたまま
これでDocker環境の準備は整ったはず

既存ファイル郡にDockerのファイルを追加する

ここからはDockerの話
既存コードににDocker設定を入れる

  • ドキュメントルートに docker-composer.yml
  • それ以外のDocker関連ファイルを ./docker/ 以下に置く

docker-composer.yml

XAMPPからの移行だが、本番はに近づけるため、
nodeサーバー、php-fpm、MariaDBと、XAMPPを意識するという点で今回はphpmyadminを入れる

それぞれ別のコンテナで動かす

docker-composer.yml
version: '3'
services:
  test_db:
    image: mariadb:latest
    volumes:
      # データ永続化用
      - ./docker/dbdata:/var/lib/mysql
      # 初期データ用(ここに置いたsqlファイル等は実行される)
      - ./docker/initdb:/docker-entrypoint-initdb.d
    environment:
      - MYSQL_ROOT_PASSWORD=mariadb
    ports:
      # Docker外(ローカル)からも3306で繋がるようにしておく
      - 3306:3306
  test_myadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      # 上のDBコンテナ名
      - PMA_HOST=test_db
      # root固定
      - PMA_USER=root
      # 上のMYSQL_ROOT_PASSWORDの値
      - PMA_PASSWORD=mariadb
    links:
      # DBコンテナにつながるようにする
      - test_db
    ports:
      # ローカルのブラウザからはlocalhost:8080で見られるようにする
      - 8080:80
  test_nginx:
    image: nginx:alpine
    depends_on:
      - test_php
    volumes:
      # nginxの設定
      - ./docker/nginx/docker.conf:/etc/nginx/conf.d/default.conf
      # nginxのrootに合わせる(rootにはpublicを付ける必要がある)
      - .:/var/www/test
    ports:
      - 80:80
    environment:
      - NGINX_PORT=80
  test_php:
    # これだけ素のイメージでは足りないのでDockerfileを利用する(Dockfileのパスを指定)
    build: ./docker/php
    links:
      - test_db
    volumes:
      # php.iniの設定を送る(今回は特にめだった何かはしていない)
      - ./docker/php/php.ini:/usr/local/etc/php/php.ini
      - .:/var/www/test
    ports:
      - 9000:9000

Dockerを理解してないがゆえに割と悩んだのが、多くの環境構築系資料で、ここにおいたコードが実行されるでしょみたいの書かれるけど、「え?どうやって編集するの?」ということ

結論としては、volumes以下はコピーされるのではなくマウントされるので、更新すれば自動で反映される。なので

volumes
  - .:/var/www/hoge

とかやれば、ファイル全体が自動的にマウントされる、Dockerコンテナ側に反映される

Dockerfile(PHPサーバー)

docker/php/Dockerfile
FROM php:7.3-fpm

RUN apt-get update \
    # Laravel実行には必要
    && apt-get install -y zlib1g-dev libzip-dev mariadb-client \
    && docker-php-ext-install zip pdo_mysql \
    # XDebug用(今回は不要)
    && pecl install xdebug \
    && docker-php-ext-enable xdebug
COPY --from=composer /usr/bin/composer /usr/bin/composer

composerは必須ではないが、後述のLaravelクソ重い問題で利用する

Docker に Composer をインストールするベストプラクティス(と解説)

Nginxのconf

docker/nginx/docker.conf
server {
    # nginxコンテナのポートの右側の数値
    listen       80;
    server_name  localhost;
    charset      utf-8;

    # volumesでマウントしているところと一致させる(Laravelなのでこちらはpublicをつける)
    root /var/www/test/public;

    index index.php;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        # test_phpはdockerのPHPコンテナ名、9000はそのポート(右側の数字)
        fastcgi_pass  test_php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }
}

初期SQLを置く

docker-compose.yml のファイル内のコメントに書いたが、データベース系のコンテナだあと
/docker-entrypoint-initdb.d に置かれたファイルは自動でよしなにしてくれるらしい。
ここに .sql , .sql.gz をおけばSQLが実行、.shを置けばシェルが走るらしい。
artisanでmigrationで行う場合は .sh で書けば良い

上のdocker-composerで/docker/initdb においたものが/docker-entrypoint-initdb.d にコピーされるのでそこにおいておく

なお、いきなりテーブル作成をしてしまうとエラーになる。ちゃんとdatabaseの作成・指定から行う。

Docker で MySQL 起動時にデータの初期化を行う

Laravelの.env設定

関係あるのはDB周りだけなので、そこの部分だけ修正する。

DB_CONNECTION=mysql
# DBコンテナ名
DB_HOST=test_db
# DBコンテナで指定したポート(右側)
DB_PORT=3306
# 実際に使っているもの次第(今回は初期データがここに入ってる)
DB_DATABASE=docker_test
DB_USERNAME=root
# 指定したパスワード
DB_PASSWORD=mariadb

起動してみる

composer-docker.ymlのある場所まで移動して

$ docker-compose up -d

Windows側でもWSL側でも動くはずである。
ミスがなければ起動するはず。
DockerDesktop側のDashboardからも起動が確認できる

動作確認

問題点1:Laravelがクソ重い

上のを実行すると気づくとも思うが、何もしてない処理でもクソ重い。
大して何もしてないページなのに表示に数秒かかる・・・。これではさすがに厳しい。
どうやら調べてみると、「マウントするファイルが多いと重くなる」模様
下記が解決策として実行したもの・浮かんだもの

不要なファイルはマウントしない(今回やった解決策)

自分で触ることのないファイルはわざわざ、マウントする必要がない

  • vendor以下は依存を変えない限りは不要である
  • storage以下は自動で作られるファイルだからこちらかアップすることはない

しかし単にマウントしないだけだと以下の問題が起きる

  • vendor以下がないため、composer installをする必要がある
  • storage以下のファイルが存在しないからエラーになる

一旦ファイルを送ってからマウントを切るという手もあるが、一発で構築できないという点でイケてない。
構築後に中に入って準備をするのもイケてない。

なので、必要なファイルはDockerfileで取得するようにする

docker-compose.yml
volumes:
  # php.iniの設定を送る
  - ./docker/php/php.ini:/usr/local/etc/php/php.ini
  - .:/var/www/test
  # 除外
  - /var/www/test/storage
  - /var/www/test/vendor

Dockerfileに下記を追加

docker/php/Dockerfile
# storageファイルはマウントしないのでもともと必要なディレクトリは作成する
RUN mkdir -p /var/www/test/storage/app/public
RUN mkdir -p /var/www/test/storage/framework/cache/data
RUN mkdir -p /var/www/test/storage/framework/sessions
RUN mkdir -p /var/www/test/storage/framework/testing
RUN mkdir -p /var/www/test/storage/framework/views
RUN chmod -R 777 /var/www/test/storage

# vendorはマウントしないのでcomposerで入れる
COPY composer.lock /var/www/test/composer.lock
# いらないかも
COPY composer.json /var/www/test/composer.json

# composer.jsonで必須になっているもの(autoloadまわり)
RUN mkdir -p /var/www/test/database/seeds
RUN mkdir -p /var/www/test/database/factories

# cd /var/www/test && composer install でも動きそう
WORKDIR /var/www/test
# scriptsでファイルチェックをしているが、マウント前のこの時点では存在しないのでそれは避ける
RUN composer install --no-scripts

これで再作成

$ docker-compose build --no-cache

表示に1秒かからなくなった!

その他解決策1:docker-syncを使う

WindowsもLinuxもベータ版らしい

Docker for MacのLaravel アプリケーションのが遅い?それ、ファイルをいっぱいマウントしてるからかもです。

Macだとこれが普通に行われている記事をよく見る

その他解決策2:ファイルwatch+rsyncする

上のdocker-syncはrsyncしているだけなので、自分で動かすこともできる気がする。
実際うまく動くかは不明

https://medium.com/@imranhsayed/rsync-using-phpstorm-on-save-b1e73c079db0

問題点2:同じ.envファイルでWSLとDocker上両方動かせない

.envDB_HOST=test_db としているがDocker内での名称であり、WSL側では認識せず動かせない
そのため、開発を行うWSL側から php artisan などを実行してもDB周りが上手く動かない

  • 127.0.0.1だとDockerコンテナからは127.0.0.1ではないため動かない
    • Connection refused.
  • localhostだとsocketのエラーが出る
    • SQLSTATE[HY000] [2002] No such file or directory

Socketファイルを云々している記事もあったがこれじゃない感。

Docker側から見てlocalhostとはなにかというと、 host.docker.internal であり、これを入れて見るとartisanも動いたし、Dockerホスト側からも動いた

.env
DB_HOST=host.docker.internal

最終形

こちらにLarvelのテストファイルと共に置いてます:https://github.com/miyawa-tarou/docker-test/commit/5d5c78633a6c0e94b0c25849cf683c9a459b891e

docker-compose.yml

docker-compose.yml
version: '3'
services:
  test_db:
    image: mariadb:latest
    volumes:
      # データ永続化用
      - ./docker/dbdata:/var/lib/mysql
      # 初期データ用(DB系イメージだとここに置いたsqlファイル等が実行される)
      - ./docker/initdb:/docker-entrypoint-initdb.d
    environment:
      - MYSQL_ROOT_PASSWORD=mariadb
    ports:
      # Docker外からも3306で繋がるようにしておく
      - 3306:3306
  test_myadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      - PMA_ARBITRARY=1
      # 上のDBコンテナのホスト
      - PMA_HOST=test_db
      # root固定
      - PMA_USER=root
      # 上のMYSQL_ROOT_PASSWORDの値
      - PMA_PASSWORD=mariadb
    links:
      # DBコンテナにつながるようにする
      - test_db
    ports:
      # ブラウザからはlocalhost:8080で見られるようにする
      - 8080:80
  test_nginx:
    image: nginx:alpine
    depends_on:
      - test_php
    volumes:
      - ./docker/nginx/docker.conf:/etc/nginx/conf.d/default.conf
    ports:
      - 80:80
    environment:
      - NGINX_PORT=80
  test_php:
    # これだけ素のイメージでは足りないのでDockerfileを利用する(Dockrfileのパスを指定)
    build:
      # composer.lockをDockerfile内で使うために実行場所は変えない(通常だとDockerfileの位置からの参照、親ファイルは読めない)
      context: .
      dockerfile: ./docker/php/Dockerfile
    links:
      - test_db
    volumes:
      # php.iniの設定を送る
      - ./docker/php/php.ini:/usr/local/etc/php/php.ini
      - .:/var/www/test
      # 除外
      - /var/www/test/storage
      - /var/www/test/vendor
    ports:
      - 9000:9000

docker/php/Dockerfile

docker/php/Dockerfile
FROM php:7.3-fpm

# composer.jsonで必須になっているもの
RUN mkdir -p /var/www/test/database/seeds
RUN mkdir -p /var/www/test/database/factories

RUN apt-get update \
    # Laravel実行には必要(多分)
    && apt-get install -y zlib1g-dev libzip-dev mariadb-client \
    && docker-php-ext-install zip pdo_mysql \
    # XDebug用
    && pecl install xdebug \
    && docker-php-ext-enable xdebug
COPY --from=composer /usr/bin/composer /usr/bin/composer

# storageファイルはマウントしないのでもともと必要なディレクトリは作成する
RUN mkdir -p /var/www/test/storage/app/public
RUN mkdir -p /var/www/test/storage/framework/cache/data
RUN mkdir -p /var/www/test/storage/framework/sessions
RUN mkdir -p /var/www/test/storage/framework/testing
RUN mkdir -p /var/www/test/storage/framework/views
RUN chmod -R 777 /var/www/test/storage

# vendorはマウントしないのでcomposerで入れる
COPY composer.json /var/www/test/composer.json
COPY composer.lock /var/www/test/composer.lock

# composer.jsonで必須になっているもの(autoloadまわり)
RUN mkdir -p /var/www/test/database/seeds
RUN mkdir -p /var/www/test/database/factories

# cd /var/www/test && composer installでも動きそう
WORKDIR /var/www/test
# scriptsでファイルチェックをしているが、この時点ではないのでそれは避ける(後でマウントされるため)
RUN composer install --no-scripts

docker/nginx/docker.conf

docker/nginx/docker.conf
server {
    # nginxコンテナのポートの右側の数値
    listen       80;
    server_name  localhost;
    charset      utf-8;

    # volumesでマウントしているところと一致させる
    root /var/www/test/public;

    index index.php;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        # test_phpはdockerのPHPコンテナ、9000はそのポート(右側の数字)
        fastcgi_pass  test_php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }
}

.env(差分では.env.exampleに置いてます)

.env
DB_CONNECTION=mysql
DB_HOST=host.docker.internal
DB_PORT=3306
# 実際に使っているもの次第
DB_DATABASE=docker_test
DB_USERNAME=root
DB_PASSWORD=mariadb

Xdebug入れてますが、まだ設定はしていない・・・。

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

検証用にDockerでbindを動かす

Docker上でbindを動かしたかったのでやってみる。

実行環境

自分の実行を確認、、、とりあえず動くので今回はこれで(古すぎる)
今回はDockerに関する初期設定は割愛。いい記事たくさんあるので。

$ cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
$ sudo docker version
Client:
 Version:         1.12.6
 API version:     1.24
 Package version: docker-common-1.12.6-16.el7.centos.x86_64
 Go version:      go1.7.4
 Git commit:      3a094bd/1.12.6
 Built:           Fri Apr 14 13:46:13 2017
 OS/Arch:         linux/amd64

Server:
 Version:         1.12.6
 API version:     1.24
 Package version: docker-common-1.12.6-16.el7.centos.x86_64
 Go version:      go1.7.4
 Git commit:      3a094bd/1.12.6
 Built:           Fri Apr 14 13:46:13 2017
 OS/Arch:         linux/amd64

Dockerfileの用意

Dockerfile
FROM centos:7

RUN yum -y update
RUN yum install -y bind bind-chroot bind-utils
RUN groupadd bind
RUN useradd -m bind -g bind -s /sbin/nologin

RUN /usr/sbin/rndc-confgen -a  -t /var/named/chroot -u bind -r /dev/urandom

EXPOSE 53/UDP
EXPOSE 53/TCP

COPY named.conf /var/named/chroot/etc/
COPY sample.com.zone /var/named/chroot/var/named/
COPY localhost.rev /var/named/chroot/var/named/
COPY named.root /var/named/chroot/var/named/
RUN chown -R bind:bind /var/named/chroot/

CMD ["/usr/sbin/named", "-u", "bind", "-t", "/var/named/chroot", "-c", "/etc/named.conf", "-g"]

解説

・パッケージ
bindはyumに上がっているものを使用。最新バージョンを利用したい場合は自分でビルドすること(bindは脆弱性報告が多いので)
bind-chrootはchroot化するためのパッケージ。入れなくても全然動く。
bind-utilsはdigなどのコマンドのために入れているが、bindを動かすためには不要。

・rndcの鍵生成
bind操作用にrndcを使用するため、rndc-confgenコマンドで鍵を生成する。
デフォルトでは/etc/rndc.keyに生成されるが、-t オプションでchroot化している。

・EXPOSE
DNSはudpとtcpの53を利用するため、EXPOSEで設定する。

・設定ファイルのCOPY
bindの設定に必要な設定ファルを指定。
COPY元のファイルはDockerファイルと同じディレクトリにある状態。
chroot化するため、/var/named/chroot/配下を指定する。

・bindの起動
Dockerではsystemctlは使用できない(回避方法はある)ので、/usr/sbin/namedを直接指定して起動する。
-t はchroot用のパスを指定。

配置ファイル

named.conf

bindの設定ファイル。
今回は権威とキャッシュの両方の機能を動かしている。
なお、globalIPを持っている環境では外部から参照されるリスクがあるため、必ずaclを設定すること。
今回はlocalhostとDockerで割り当てられるprivateIPに絞っている。

named.conf
logging {
    channel "query-log" {
        file "/var/log/query.log" versions 6 size 1024M;
        severity dynamic;
        print-time yes;
        print-category yes;
    };
    category queries { "query-log"; };
    category lame-servers { null; };
    category resolver { null; };
};

include "/etc/rndc.key";
controls {
    inet 127.0.0.1 allow { 127.0.0.1; } keys { "rndc-key"; };
};

acl "access-list" {
    127.0.0.1;
    172.17.0.0/16;
};

options {
    directory "/var/named/";
    pid-file "/run/named/";
    dump-file "/var/named/named_dump.db";
    statistics-file "/var/named/named.stats.log";

    zone-statistics yes;
    version "";
    masterfile-format text;
    recursive-clients 10000;
    tcp-clients 10000;

    allow-recursion { access-list; };
    allow-query { access-list; };
    allow-query-cache { access-list; };
};

view "internal" {
    recursion yes;

    zone "." {
        type hint;
        file "named.root";
    };

    zone "0.0.127.in-addr.arpa" {
        type master;
        file "localhost.rev";
    };

    zone "sample.com" {
        type master;
        file "sample.com.zone";
    };
};

named.root

rootゾーン情報が書いてあるファイル
named.rootはInterNICで公開されているものを使用
https://www.internic.net/domain/named.root

$ wget https://www.internic.net/domain/named.root

localhost.rev

自ホストの逆引きゾーンファイル

$TTL    86400
@   IN  SOA localhost.  root.localhost. (
        2020062101  ; Serial
        28800       ; Refresh
        14400       ; Retry
        3600000     ; Expiry
        86400 )     ; Minimum

@   IN  NS  localhost.
1   IN  PTR localhost.

sample.com.zone

テスト用のゾーンファイル。
sample.comについて権威を定義。

$TTL 900
@   IN  SOA sample.com. postmaster.sample.com. (
        2020062101      ; Serial Number
        1800            ; Refresh
        900             ; Retry
        1209600         ; expire
        900             ; minimum
        )
@
    IN  NS  sample.com.
    IN  A  127.0.0.1
www IN  A   127.0.0.1
text    IN  TXT "sample.com.zone text"
cname   IN  CNAME   www.sample.com.

Dockerfileのbuild

bindのimageをbuildする。
cacheが残っていて困ったことがあるので、あえて--no-cacheオプションを付けてる。

$ sudo docker build . -t bind --no-cache

成功するとコマンドでimageが確認できる。

$ sudo docker images bind
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
bind                latest              00b75189b7d1        2 hours ago         492.3 MB

Dockerの起動

-p オプションでサーバの53ポートとdocker上の53をバインドする。
udpをバインドする場合は、53:53/udpでudpを指定する。

$ sudo docker run -it -d -p 53:53 -p 53:53/udp --name bind bind:latest
f269bd4ee38ecd22ae209420a7b1df26099de7da60f2bf675dce69c1e451a61a

起動の確認

$ sudo docker ps | grep bind
f269bd4ee38e bind:latest "/usr/sbin/named -u b" 43 seconds ago Up 42 seconds 0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udp bind

動作確認

digはdockerを起動しているサーバから実行。

・定義したsample.comドメイン

-bash-4.2$ dig @localhost www.sample.com +nostats

; <<>> DiG 9.9.4-RedHat-9.9.4-38.el7_3.3 <<>> @localhost www.sample.com +nostats
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29686
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.sample.com.            IN  A

;; ANSWER SECTION:
www.sample.com.     900 IN  A   127.0.0.1

;; AUTHORITY SECTION:
sample.com.     900 IN  NS  sample.com.

;; ADDITIONAL SECTION:
sample.com.     900 IN  A   127.0.0.1

・未定義のドメイン

$ dig @localhost www.yahoo.co.jp +nostats

; <<>> DiG 9.9.4-RedHat-9.9.4-38.el7_3.3 <<>> @localhost www.yahoo.co.jp +nostats
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13134
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 3

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.yahoo.co.jp.       IN  A

;; ANSWER SECTION:
www.yahoo.co.jp.    900 IN  CNAME   edge12.g.yimg.jp.
edge12.g.yimg.jp.   60  IN  A   182.22.25.252

;; AUTHORITY SECTION:
g.yimg.jp.      900 IN  NS  gns02.yahoo.co.jp.
g.yimg.jp.      900 IN  NS  gns12.yahoo.co.jp.

;; ADDITIONAL SECTION:
gns12.yahoo.co.jp.  900 IN  A   124.83.255.100
gns02.yahoo.co.jp.  900 IN  A   118.151.254.148

うまく権威とキャッシュの機能がそれぞれ動作している。

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

【2020/06版】今使えるKubernetes on CentOS7設定手順

宗教上の理由などにより既存のサービスが使えないのでLinux環境に一からKubernetesを作りたいよって人、書いてある通りにやってるのになぜか動かないよって人向け
検証環境はVirtualBox上のCentOS7.8
k8s-master IP:192.168.100.200 CPU:2 MEM:2GB HDD:16GB
k8s-node01 IP:192.168.100.201 CPU:2 MEM:2GB HDD:16GB
k8s-node02 IP:192.168.100.202 CPU:2 MEM:2GB HDD:16GB
(マスターには2Core以上が必須らしい)

※初回投稿後自分の書いた記事で再現テストを何度かやって何か所か修正しました

お世話になった記事

kubeadmでkubernetes v1.14.1のインストール
CentOS 上 に Kubernetes クラスター を構築する方法
kubeadm で kubernetes v1.8 + Flannel をインストール

手順

以下の手順はrootユーザーとして行うものとする

マスター、ワーカー共通手順

準備

・システムアップデート
・SELinux無効化
・SWAP無効化

# yum update
# systemctl reboot -i
# setenforce 0
# swapoff -a
/etc/selinux/config
-SELINUX=enforcing
+#SELINUX=enforcing
+SELINUX=disabled
/etc/fstab
-/dev/mapper/centos-swap swap                    swap    defaults        0 0
+# /dev/mapper/centos-swap swap                    swap    defaults        0 0

・hostsの設定

/etc/hosts
+192.168.100.200    k8s-master
+192.168.100.201    k8s-node01
+192.168.100.202    k8s-node02

Dockerのインストール

# yum install yum-utils device-mapper-persistent-data lvm2
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum install docker-ce
# mkdir -m 644 /etc/docker
/etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
# systemctl enable docker && systemctl start docker

kubernetesのインストール

/etc/yum.repos.d/kube-rnetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
# yum install kubelet kubeadm --disableexcludes=kubernetes
# systemctl enable kubelet && systemctl start kubelet

※VM環境の場合ここで一旦シャットダウンし、クローンを作る
クローン生成後一端起動してIPを再設定する

/etc/sysconfig/network-scripts/ifcfg-enp0s3
DEVICE=enp0s3
ONBOOT=yes
IPADDR=192.168.100.200OSインストール時に固定IPにした場合ここだけを変更して「systemctl restart networkPREFIX=24
GATEWAY=192.168.100.1
DNS1=8.8.8.8

環境によってenp0s3の部分が違う場合もあるのでip addrなどで確認すること

Firewallの設定

Master側

firewall-cmd --permanent --new-zone=k8s
firewall-cmd --permanent --zone=k8s --add-source=192.168.100.201
firewall-cmd --permanent --zone=k8s --add-source=192.168.100.202
firewall-cmd --permanent --zone=k8s --add-port 6443/tcp
firewall-cmd --permanent --zone=k8s --add-port 2379-2380/tcp
firewall-cmd --permanent --zone=k8s --add-port 10250/tcp
firewall-cmd --permanent --zone=k8s --add-port 10251/tcp
firewall-cmd --permanent --zone=k8s --add-port 10252/tcp
firewall-cmd --reload

Worker側

firewall-cmd --permanent --new-zone=k8s
firewall-cmd --permanent --zone=k8s --add-source=192.168.100.200
firewall-cmd --permanent --zone=k8s --add-port 10250/tcp
firewall-cmd --permanent --zone=k8s --add-port 30000-32767/tcp
firewall-cmd --reload

Master設定

# echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
# kubeadm init --pod-network-cidr=10.244.0.0/16 --kubernetes-version v1.18.4

(v1.18.4の部分はインストールしたバージョン)
kubeadm initだけでもいい気もするけどVMのBuild&Scrapしてると
オプション付けてた方がうまくいくような気がするのでとりあえず付ける事にした

実行後以下の様な文字列が実行結果の最終行に表示されるので控えておく
kubeadm join 192.168.100.200:6443 --token ***.************* --discovery-token-ca-cert-hash sha256:****************************************************************

(*の部分はkubeadm initコマンドを実行する度に生成される)

kubectl get nodesなどのコマンドで正しい応答を得る為に以下を実行

# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo chown $(id -u):$(id -g) $HOME/.kube/config

flannelのインストール

これがないとYAMLを実行してもPod生成がペンディングで止まる

# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

※古い記事の場合https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml
を参照しようとしてエラーが多発する

Worker設定

上で得られたkubeadm joinを実行

# echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
# kubeadm join 192.168.100.200:6443 --token ******.**************** --discovery-token-ca-cert-hash sha256:****************************************************************

Master側で確認

Workerノードを2つ繋げると以下のようになる

# kubectl get nodes
NAME         STATUS   ROLES    AGE     VERSION
k8s-master   Ready    master   3h20m   v1.18.4
k8s-node01   Ready    <none>   3h20m   v1.18.4
k8s-node02   Ready    <none>   3h20m   v1.18.4

検証用YAMLを実行

test.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-test
spec:
  replicas: 10
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.18

YAMLの適用

# kubectl apply -f test.yml

実行してしばらく経つと以下のようになる

nginx-test-74b9fcbbc7-2t2j9   1/1     Running   0          35s
nginx-test-74b9fcbbc7-4776q   1/1     Running   0          35s
nginx-test-74b9fcbbc7-bp92t   1/1     Running   0          35s
nginx-test-74b9fcbbc7-fhv4k   1/1     Running   0          35s
nginx-test-74b9fcbbc7-hfdm4   1/1     Running   0          35s
nginx-test-74b9fcbbc7-hp98l   1/1     Running   0          35s
nginx-test-74b9fcbbc7-ln484   1/1     Running   0          35s
nginx-test-74b9fcbbc7-mqjwl   1/1     Running   0          35s
nginx-test-74b9fcbbc7-nx7vn   1/1     Running   0          35s
nginx-test-74b9fcbbc7-v96rt   1/1     Running   0          35s

上手くいかないとき

再起動後などkubeadm initやkubeadm joinなどでうまくいかない場合

# echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables

を再度実行すると多分うまくいく
もしくはWorkerの場合

# kubeadm reset

でリセットするなどする必要がある場合も

ゾンビポッドなどが残ってどうしようもないような場合などは
Master、Workerそれぞれで

# kubeadm reset
# echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
# kubeadm init --pod-network-cidr=10.244.0.0/16 --kubernetes-version v1.18.4
# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo chown $(id -u):$(id -g) $HOME/.kube/config
# kubeadm reset
# echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
# kubeadm join 192.168.100.200:6443 --token ******.**************** --discovery-token-ca-cert-hash sha256:****************************************************************

とやるとまっさらな環境で再度試行できる

課題

Dashboradの実行がまだ再現できていない

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