20200401のdockerに関する記事は12件です。

Docker Executor内からDockerコンテナへのWebアクセス方法

本記事は以前書いた記事から最もハマった場所を抜粋したものです。
簡潔にトラブルシューティングのみ記載していきます。

全体の流れが知りたい方は以下の記事をご覧ください。
Docker in Dockerを利用してCIを構築してみた

やりたいこと

Docker Executor内に構築したDockerコンテナに対してcurlコマンドでアクセスを行い、応答が返却されるかをテストします。
用途はCI環境をDockerを利用して構築し、WebアプリもDockerコンテナとして作成したいケースが考えられます。

image.png

ハマったこと

IPアドレスを動的に取得してアクセスを試みましたができませんでした。
IPアドレスは取得できているにも関わらずTimeoutエラーが発生します。

 $ export CONTAINER_ADDRESS=$(docker inspect -f "{{.NetworkSettings.IPAddress}}" 
 ${CONTAINER_NAME})
 $ echo ${CONTAINER_ADDRESS}
 172.18.0.2
 $ curl http://${CONTAINER_ADDRESS}:80/${APP_NAME}/hello
   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                  Dload  Upload   Total   Spent    Left  Speed
   0     0    0     0    0     0      0      0 --:--:--  0:00:31 --:--:--     0
 curl: (28) Failed to connect to 172.18.0.2 port 80: Operation timed out

解決策

GitLabCIではservicesで定義したコンテナにアクセスする場合、定義した時の名前を使用する必要があります。
今回は.gitlab-ci.ymlファイル内で

services:
    - docker:dind

と定義していたため、dockerをホスト名として指定します。

 $ curl docker:80/${APP_NAME}/hello
   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                  Dload  Upload   Total   Spent    Left  Speed
 100    13  100    13    0     0     55      0 --:--:-- --:--:-- --:--:--    55
 Hello, World!

参考URL

Accessing the services
Docker Container Networking with Docker-in-Docker

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

Docker Executor内に構築したDockerコンテナへのWebアクセス方法

本記事は以前書いた記事から最もハマった場所を抜粋したものです。
簡潔にトラブルシューティングのみ記載していきます。

全体の流れが知りたい方は以下の記事をご覧ください。
Docker in Dockerを利用してCIを構築してみた

やりたいこと

Docker Executor内に構築したDockerコンテナに対してcurlコマンドでアクセスを行い、応答が返却されるかをテストします。
用途はCI環境をDockerを利用して構築し、WebアプリもDockerコンテナとして作成したいケースが考えられます。

image.png

ハマったこと

IPアドレスを動的に取得してアクセスを試みましたができませんでした。
IPアドレスは取得できているにも関わらずTimeoutエラーが発生します。

 $ export CONTAINER_ADDRESS=$(docker inspect -f "{{.NetworkSettings.IPAddress}}" 
 ${CONTAINER_NAME})
 $ echo ${CONTAINER_ADDRESS}
 172.18.0.2
 $ curl http://${CONTAINER_ADDRESS}:80/${APP_NAME}/hello
   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                  Dload  Upload   Total   Spent    Left  Speed
   0     0    0     0    0     0      0      0 --:--:--  0:00:31 --:--:--     0
 curl: (28) Failed to connect to 172.18.0.2 port 80: Operation timed out

解決策

GitLabCIではservicesで定義したコンテナにアクセスする場合、定義した時の名前を使用する必要があります。
今回は.gitlab-ci.ymlファイル内で

services:
    - docker:dind

と定義していたため、dockerをホスト名として指定します。

 $ curl docker:80/${APP_NAME}/hello
   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                  Dload  Upload   Total   Spent    Left  Speed
 100    13  100    13    0     0     55      0 --:--:-- --:--:-- --:--:--    55
 Hello, World!

参考URL

Accessing the services
Docker Container Networking with Docker-in-Docker

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

QNAPのContainer Station用private registryとimage作成

QNAP上でちょっとした個人的なDockerコンテナを動かしたいなと思ったので、それらの記録です。
あまりDockerに詳しくはないので、もっと良いやり方があるかもしれません。

目標

  • QNAP上で独自にbuildしたコンテナを動かす
  • イメージは公開しない状態で使えるようにする
    • QNAP上にprivate registryを立てて、そこにイメージを置く

前提

使用した機器はTS-231Pです。もうちょっと新しい良いものが欲しかったのですが、予算の都合的に。
また、ひとまず動作させるまでの記録なので、細かいセキュリティ的な設定等については触れません。

private registryの稼働

QNAPのContainer Station自体の設定については他にも書かれている方がいますので、特に触れません。
Container Stationを開いて、「作成」ページから "registry" で検索すればDocker Hub公式のイメージが見つかると思います。
今回は特にこだわりとかもないので、これを単純な形で使います。検索したところはこんな感じですね。
01.PNG

このイメージをインストールして起動すると、こんな感じで「概要」ページに表示されます。
02.PNG

上のスクリーンショットで黄色でマークしてあるコンテナ名をクリックすると、private registryのURLとポートが表示されます。
後ほど開発環境で作成したイメージをここにpushすることになります。
03.PNG

独自イメージの作成

さて、次に独自のイメージを開発環境で作成します。
これもまた、基本的にはコードを書いたりエントリポイントを用意して、Dockerfileからbuildするという基本的な所は他にも書かれてる方が沢山いるので割愛。

ARM版のイメージ作成

今回使用した機器のCPUは、cortex-a15です。要は32bitのARMアーキテクチャですね。
開発機にはx86_64を使っている人が大半でしょうから、先に作ったDockerfileでbuildしたイメージは普通に考えたらQNAP上に持っていっても動かないわけです。
ということで、ARMアーキテクチャベースのイメージを元に、イメージを作り直します。

この辺りについてはこちらの記事を参考にさせていただきました。"binfmt_misc のセットアップ" の所と "build" の箇所ですね。

1. ベースイメージの選択

上記の記事と基本的に同じ内容になってしまうのですが、見やすさの為に記述しておきます。

multiarchというリポジトリで、qemu-user-staticが組み込み済みのイメージを色々と公開されています。
今回自分はalpineを選択したので、そちらのディレクトリを開きます。

2. binfmt-supportの設定

Usageに書いてありますが、まずはbinfmt-supportの設定をdocker hostにするため、コマンドを実行。

$ docker run --rm --privileged multiarch/qemu-user-static:register --reset

3. build

続いて、同様にこちらで公開されいてるARM用のイメージを元にbuildします。このbuildについてはUsageには載っていませんが、先に触れた参考にさせてもらったblogでその様な事をしてますね。
DockerfileのFROMをこんな感じで書き換えてやります

- FROM python:3.8.2-alpine
+ FROM multiarch/alpine:armhf-edge

この例だと、とりあえず諸々Dockerfileを作り込む時は python:3.8.2-alpine で作っておいて、ARM版イメージを作るときは multiarch/alpine:mrmhf-edge に置き換えたということですね。
まあ、この例だと後者にpython周りをインストールするための設定が追加で必要になりますが。

ともあれ、buildします。

$ docker build . -f Dockerfile --tag 192.xxx.yyy.zzz:nnnn/my-private-image

tagには (private registryのホスト:port)/(イメージ名) の形で設定します。イメージ名はお好きなように。
これが無事に完了すればQNAP上で動くイメージの完成です。

4. insecure_registry

最初の方で見たとおり、private registryのURLはhttpとなってますので、pushする前にinsecure_registryの設定をします。
/etc/docker/daemon.json に下記のような設定を加えます。

{
  "insecure-registries": ["192.xxx.yyy.zzz:nnnn"]
}

既に他の設定のオブジェクトがある場合は、そのオブジェクト内に追加してやる形で大丈夫です。

5. push for private registry

諸々準備ができたので、作成したイメージをprivate registryにpushします。

$ docker push 192.xxx.yyy.zzz:nnnn/my-private-image

こんな感じですね。

作成したコンテナの起動

1. pull

QNAPのContainer Stationに戻りまして左のメニューから「画像」を開きます。これは「image」を訳した結果、そうなってしまったんでしょうね…。要はイメージの管理ページがここです。
右上にある「プル」を開きます。
04.PNG

pullしてくる対象のレジストリを選択出来るようになっているので、ここでprivate registryを追加します
05.PNG

名前とURLを記入します。ユーザー名とパスワードについては特に認証とかつけてないので、今回は不要です。
06.PNG

追加したら、レジストリをprivate registryに設定し、画像名(イメージ名)を入力します。先の例でいくと、 my-private-image ですね。
09.PNG

右上のバックグラウンドタスクが終われば、pullは完了です。
07.PNG

2. コンテナの作成

メニューの「作成」から検索しても出来ますが、よりお手軽な方法として、pullしたイメージのアクション列にある「+」ボタンからもコンテナを作成できます。
08.PNG

ホストとボリュームを共有したい場合などの設定は、詳細設定からできるようになっています。

概要ページに戻って、無事に起動されていれば完了です。

今後の課題

とりあえず最初の要件は満たせましたので、次はホストとコンテナとの共有フォルダをどうにかしてNASユーザーのディレクトリにすることですかね。
あと、もっとスマートな方法があればそちらに切り替えるとか。
ひとまずはこれで好き勝手出来そうなので、色々動かしてみようかと。

binfmt_misc辺りがちゃんとわかってないので、そこら辺を理解しておく。

後記

書き終わってから気づいたんですが、無理にx86_64の開発環境でbuildしなくても、QNAPにsshでログインして、そこでbuildすれば普通にARM環境でそのままbuild出来たんじゃないだろうか。dockerも既に入っている訳だし。
多分、これが今回の目的では一番楽な方法だった気がする。

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

Dockerコマンドの備忘録

docker1.png

(1)docker pull

DockerHubからdockerイメージをホストマシンに取得する

(2)docker create

イメージを基にして、コンテナを作成する
http://docs.docker.jp/engine/reference/commandline/create.html

※docker run -it IMAGE_ID の方が「コンテナの作成と起動、コンテナに入る」のやってくれている。

ホストマシンにあるDockerイメージ操作

ホスト上のイメージ一覧を表示する

docker images

Dockerイメージを検索する

docker search php
// おそらく検索元は、DockerHub だと思う

Dockerイメージからコンテナを作成して、コンテナを起動する

docker run IMAGE_ID

カスタマイズしたdockerイメージを作成する(1) docker commit

※Dockerfileを使ったやり方を推奨しているように思う。

docker pull debian 
docker run -it debian
apt update              // コンテナ作業
apt install python      // コンテナ作業
// docker container ls -a などで 作成したコンテナIDをメモをする

// カスタマイズしたdockerイメージを作成する
docker commit -m "update apt and add python" -a "yuzuma" dfe67b0d2e59 debian:v2

docker images // カスタマイズしたdockerイメージが作成できることが確認できる
docker run -t -i debian:v2 /bin/bash
python --version // コンテナ作業:作成したdebian:v2のコンテナでpythonが使えることが確認できる。

カスタマイズしたdockerイメージを作成する(2) docker build

Dockerfileを用いて、dockerイメージのカスタマイズをする

cat Dockerfile

FROM debian
MAINTAINER yuzuma

RUN apt -y update
RUN apt -y install python
docker build -t mydebian .
docker images  // mydebian のイメージが作成できることを確認できる

Dockerイメージの削除

http://docs.docker.jp/engine/reference/commandline/rmi.html

docker rmi  xxx // xxxは、IMAGE IDなど

ホストマシンにあるDockerコンテナ操作

Dockerコンテナの一覧を確認する

docker ps -a // aオプションは、停止しているコンテナも確認できる 

Dockerコンテナを起動する

docker start xxx  // xxxはcontainer id, container_nameなど

Dockerコンテナの停止

docker stop  xxx // xxxはcontainer id, container_nameなど

Dockerコンテナの削除

docker rm  xxx // xxxはcontainer id, container_nameなど

docker-composeもメモをする

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

MERNスタックをDockerでやっていく

はじめに

30代正社員経験のないクズ人間だけどSHUSHOKUできました!やったー!
うれC!!!!!!!!うれC!!!
MERNスタック使って、ポートフォリオ用にWebアプリ作ってみたけど、大変だった気がします。正直全部大変だし難しいし自分が何やってるかよくわからない感じになります。頭が悪いので整理ができない……(´・ω・`)
DockerでMERNスタック環境構築したらDocker使っちゃう気持ちもアゲアゲでいけるのでは?などと考え、あとからECRやら楽なんじゃね?とか思っていた時期が自分にもありました。

MERNスタックでなんかDockerもつかって気軽に色々できればいいなあというわけで、今後忘れないように書いておこうと思います。

Dockerについては、「何故Dockerなのか」とか、なんか公式読めば良いとかいう風潮がある気がします。
公式は字が多すぎて読む気がおきないみたいなやつはあります。でも、読め!とインターネッツの中の人たちが言ってくるので読みました。読んでもよくわからないので、脳がやばい。
脳みそやわやわな状態でやっているので、やっていける気がしない。

チラシの裏にでも書いてろ!という記事です。でもQiitaに書いたろと思いました。承認欲求モンスターなので。謝罪しておきます。申し訳ございません。

フォルダ構成

とりあえず、こんなん

.
├── README.md
├── backend
│   ├── Dockerfile-dev
│   ├── app.js
│   ├── config.env
│   ├── controllers
│   ├── middleware
│   ├── models
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   ├── routes
│   ├── uploads
│   └── utils
├── frontend
│   ├── Dockerfile-dev
│   ├── build
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   └── src
├── dev-docker-compose.yml
├── node_modules
├── package-lock.json
└── package.json

メインにフロントエンドとバックエンドそれぞれフォルダを作りその中にdev環境Dockerfileをそれぞれ置いておく。
メインフォルダにはdev環境Docker-compose.ymlをつくる。
とりあえずsudo apt install docker-composeやら色々はやってる状態。
他のフォルダなんかは、皆自由にやっていっていると思います。

基本的に↓

nanka_app_nandemo_yoi_example/
├── node-backend/
│   └── Dockerfile
├── react-frontend/
│   └── Dockerfile
└── docker-compose.yml

こういう構成で作っていきたい気持ち。

バックエンド(MERNのN担当Node.js)

とりあえず動かしたいので、こんな感じに。

Dockerfile-dev
FROM node:10.18.0-alpine3.9

EXPOSE 3000

RUN apk add --update curl
WORKDIR /usr/src/app

COPY package.json package-lock.json* ./

RUN npm cache clean --force && npm install && npm install -g nodemon
COPY . .

CMD ["npm", "run", "dev"]

自分にはdev環境とproduction環境をしっかり構成したいという夢がありました
というわけで、devになっていますが、別にDockerfileとしていれば良い。

フロントエンド(MERNのR担当React.js)

担当とか書くと、なんかMERNの中で誰推し?みたいな雰囲気になっていいですね。
皆JS界からきてるわけですし、でかいアイドルグループみたいなもんやろ。しらんけど。
自分は誰推しでもないです、皆むずかしい。もう誰も信じない。

とりあえずこんな感じ

Dockerfile-dev
FROM node:10.18.0-alpine3.9

EXPOSE 3000

RUN apk add --update curl
WORKDIR /usr/src/app

COPY package.json package-lock.json* ./

COPY . .

CMD [ "npm", "start" ]

ほぼバックエンド側と変わらない感じのやつ。少しでも、行数を減らしたい。行が増えると絶望感が増す。

COMPOSEファイル(MERNのM担当Mongoあたりも登場)

コンポーズファイル作ります。
こいつがないと私にはなにもできない。

dev-docker-compose.yml
version: "2.2"

services:
  mongodb:
    image: "mongo"
    ports:
      - "27017:27017"
  backend:
    build:
      context: ./backend/
      dockerfile: Dockerfile-dev
    ports:
      - "6200:6200"
    volumes:
      - ./backend:/usr/src/app
    depends_on:
      - mongodb
  frontend:
    build:
      context: ./frontend/
      dockerfile: Dockerfile-dev
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/usr/src/app
    depends_on:
      - backend

ビルドしたい

docker-compose -f dev-docker-compose.yml buildこれでビルドできる。
あとは毎回docker-compose -f dev-docker-compose.yml upとかすれば良い。

これで、なんか構築はされる感じになっている。
あとはCircleCIがどうとか、Node.js側でAPIがどうのとかReact側でSPAがどうとか、MongoDBでAtlasで某とか、そういうあれでなんかやっていきます。

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

Qita&Dockerを入門してみた

Dockerとは

コンテナ型のアプリケーション実行環境
アプリケーションにデプロイに特化しており、コンテナを中心とした開発・運用を可能とします。

Dockerのメリット

  • 軽量な仮想環境

    例えば、WEBアプリケーションを開発する上で、ApacheやNginxのようなwebサーバーをローカル環境に構築する作業
    ローカル環境でdockerのセットアップが済んでいれば、コマンド一つ叩くだけで環境構築ができる。

  • 優れたポータビリティを持つ

    ローカルのDocker環境で実行しているコンテナを、別のサーバーにあるDocker環境にデプロイする、あるいはその逆にサーバーのDockerの環境で動作するコンテナをローカルに持ってくることが可能です。

  • 軽い!

    従来の仮想環境と比べて軽いのが特徴

Dockerの基本動作

dockerイメージとコンテナの関係性

イメージ

 Dockerコンテナを構成するファイルシステムや、実行するアプリケーションや設定をまとめたもので、コンテナを作成するための利用されるテンプレートとなるもの

コンテナ

 Dockerイメージをもとに作成され具現化されたファイルシステムとアプリケーションが実行されている状態

Dockerfile

基本的なインストラクション

FORM

FROMは作成するDockerイメージのベースとなるイメージを指定します。
Dockerfileで、イメージをビルドする際、まず最初にFROMdで指定されたイメージをダウンロードしてから実行される。
FROMはDocker Hubのレジストリを参照する。

RUN

RUNはDockerイメージビルド時に、Dockerコンテナ内で実行するコマンドを定義します。
RUNの引数にはDockerコンテナ内で実行するコマンドをそのまま指定します。

COPY

Dockerを動作させいているホストマシン上のファイルやディレクトリをDockerコンテナ内にコピーするためのインストラクションです。

CMD

CMDはDockerコンテナとして実行する際に、コンテナ内で実行するプロセスを指定します。
イメージをビルドするためのRUNに対して、CMDはコンテナ起動時に1度実行されます。
RUNでアプリケーションの更新や配置、CMDでアプリケーションそのものを動作させると考えてください。

Docker-composeによるコンテナ実行

Docker compose とは、複数のコンテナから成るサービスを構築・実行する手順を自動的にし、管理を容易にする機能です。
Docker compose では、compose ファイルを用意してコマンドを1 回実行することで、そのファイルから設定を読み込んですべてのコンテナサービスを起動することができます。

docker-compose.ymlが置かれているディクトリ内で以下のコマンドを実行する

コンテナの実行
 docker-compose up -d
コンテナの停止
 docker-compose down

詳細は他の方の記事へ!!!

投稿者は Docker初心者なので今回はざっくりの記事ですみません!
その他学びがあればこれから投稿していくのでよろしくお願いします!

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

https-portalを使ってみて、個人的にぶつかりそうな壁の解決方法

とても参考になったもの

https://qiita.com/kuboon/items/f424b84c718619460c6f

実際にやっていくと、「?、これ..どうすんだっけ」が何個かあったので

STAGEがlocal、staging(default)、productionとある...

  1. localはドメインも持っていないが、とりあえず一連の流れをやってみたい
  2. stagingはドメインを持っていて、本番サーバーではないが、とりあえず一連の流れをやってみたい
  3. productionはドメインを持っていて、本番サーバーで動かす場合

実際にlocalでやるには

hostsを書き換えて適当なドメイン名がローカルサーバーに行くように設定

hosts
192.168.1.100 domain.local # 実在しないのでも
192.168.1.100 qiita.com    # 実在するのでも

stagingでやるには

ドメインはあってもなくても良いけど、stagingなんで、実際のドメインでやるけどサーバーが本番サーバーじゃない的な
*お名前とかのレジストラで、ドメインのAレコードをテスト用のサーバーに向けるとか
*自分1人でテストするならlocalのようにhostsで強制しても構わない

local、stagingは警告が出るがhttps通信のオレオレ

productionでやってみた

let's encryptに証明書を取得して、実際にアクセス出来るまでに結構ラグがあった。
コーヒー一杯作る時間は待つと思う。

FORCE_RENEW=true

基本的にはlocalやstagingで実行するので通常は必要ない。どうしても証明書にキャッシュが効いてて挙動がおかしいとかそういうときだけに使う。
productionでは基本使わない。どうしてもおかしい場合は、一回だけtrueにしてdocker再起動させて、すぐにコメントアウトでもしておく。
そうじゃないとLet's Encryptにはrate limitがあるから最悪証明書が取れなくなる。

About Rate Limits of Let's Encrypt

For most people the most important rate limits are:

5 failed validation attempts per hour
50 certificates per registered domain per week
5 duplicated certificate per week (for renewal)

普通使いそうなオプション

色々サイトを回ってみたけど、余り触れられてない。
けど、有用なオプションが結構ある。

CLIENT_MAX_BODY_SIZE
nginxはアップロード量の制限がデフォルトで1MBなんで、まずい。

docker-compose.ymlの環境変数
environment:
#  CLIENT_MAX_BODY_SIZE: 0  # これだと無制限
  CLIENT_MAX_BODY_SIZE: 10M # とか

WEBSOCKET
websocketを使う時はこれを入れてないと動かない

docker-compose.ymlの環境変数
environment:
  WEBSOCKET: "true"

HSTS_MAX_AGE
HTTPで来ても、強制HTTPS

docker-compose.ymlの環境変数
environment:
  HSTS_MAX_AGE: 60 # 秒

いきなり1日分とかデカイ秒数設定すると、その時間HTTPには戻れないから注意してとある。

SSL Certificatesをdockerホスト上に保存

https-portal:
  # ...
  volumes:
    - /data/ssl_certs:/var/lib/https-portal

他のプログラムで同じ物を使う場合とからしいけど、こうしておけば多分コンテナを消しても再生成しなくてすむから、テスト中は時間短縮によさそう。

参考

ここの3ファイルは眺めておくと、挙動が分かりやすいと思う。

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

Ansible Moleculeを使ってテストを自動化してみよう

目次

1. Moleculeとは

MoleculeはAnsible roleを開発したりテストしたりするツールです。
コマンドを実行することにより、作成したroleの構文チェック、実行環境構築、実行テスト、実行環境削除まで行ってくれます。
実行環境構築するには、『ドライバー』というものが必要になります。

実際にMoleculeを使用しroleの作成、実行環境の作成、role実行テスト、実行環境の削除の検証した結果を記録します。
ドライバーは『docker』を使用します。

2. 検証環境

  • CentOS 7.7
  • Ansible 2.9.6
  • Molecule 3.0.2
  • Python 3.6.8
  • Docker 1.13.1

3. 参照資料

Molecule公式ページです。
https://molecule.readthedocs.io/en/latest/
Molecule2系3系の違いについて参考にさせていただきました。
https://qiita.com/answer_d/items/78b047eb5708dda1375d
書籍では『Ansible 構築・運用ガイドブック』に記載されていました。

4. Moleculeの構築

epel-releaseのインストール

[root@Kensyo ~]# yum install -y epel-release

パッケージのインストール

[root@Kensyo ~]# yum install -y gcc python3-pip python3-devel openssl-devel libselinux-python

dockerのインストール

[root@Kensyo ~]# yum install -y docker

dockerの起動・自動起動を有効

[root@Kensyo ping]# systemctl start docker
[root@Kensyo ping]# systemctl enable docker
[root@Kensyo ping]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)

setuptoolsの更新

[root@Kensyo ~]# python3 -m pip install --upgrade setuptools

moleculeをインストール

[root@Kensyo ~]# python3 -m pip install molecule
[root@Kensyo ~]# molecule --version
molecule 3.0.2
   ansible==2.9.6 python==3.6

dockerドライバーをインストール

[root@Kensyo ~]# python3 -m pip install molecule[docker]

構文チェックツールをインストール

[root@Kensyo ~]# python3 -m pip install "molecule[lint]"

5. Moleculeの操作手順

5.1. roleの作成

『molecule init』を実行しロールを作成します。
ロールの作成は[molecule init role “role名”]で作成されます。
※コメント※
既存のロールを使用する場合は[molecule init scenario -r “role名”]を実行してください。
実行場所は対象ロールに移動して実行してください。

[root@Kensyo ~]# mkdir roles
[root@Kensyo ~]# cd roles
[root@Kensyo roles]# molecule init role my-role-name
--> Initializing new role my-role-name...
Initialized role in /root/roles/my-role-name successfully.
[root@Kensyo roles]# cd my-role-name
[root@Kensyo my-role-name]# ls
README.md  defaults  files  handlers  meta  molecule  tasks  templates  tests  vars

不要ディレクトリを削除します。
「meta」ディレクトリ配下のmain.ymlが構文チェックでエラーとなるため削除してください。
※コメント※
本手順では「meta」ディレクトリは不要な要素のため削除しております。必要に応じて修正してください。

[root@Kensyo my-role-name]# rm -rf meta/

tasks/main.ymlにコメントが記載されていますので修正してください。
今回の検証はhttpdのインストールを行うタスクを作成します。
記載内容はcatコマンドの出力内容を確認してください。

[root@Kensyo my-role-name]# cd tasks
[root@Kensyo tasks]# vi main.yml
[root@Kensyo tasks]# cat main.yml
---
- name: install httpd
  yum:
    name: httpd
    state: present
[root@Kensyo tasks]# cd /root/roles/my-role-name/
[root@Kensyo my-role-name]# pwd
/root/roles/my-role-name

molecule.ymlに記載を修正します。
内容はcatコマンド出力内容を確認してください。
molecule バージョン3系でlintはデフォルトで無効となっており、記載されていない為追記しています。moleculeバージョン2系に比べ記載方法も変わっています。

[root@Kensyo my-role-name]# cd molecule/default/
[root@Kensyo my-role-name]# cp -p molecule.yml molecule.yml.org
[root@Kensyo default]# vi molecule.yml
[root@Kensyo default]# cat molecule.yml
---
dependency:
  name: galaxy
driver:
  name: docker
platforms:
  - name: instance
    image: docker.io/pycontribs/centos:7
    pre_build_image: true
provisioner:
  name: ansible
verifier:
  name: ansible
lint: |
   yamllint .
   ansible-lint .
   flake8

5.2. Molecule lint

『molecule lint』を実行し構文をチェックします。
エラーが表示されなければ問題ありません。

[root@Kensyo default]# cd /root/roles/my-role-name/
[root@Kensyo my-role-name]# molecule lint
--> Test matrix

└─default
   ├─ dependency
   └─ lint

--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'lint'
--> Executing: yamllint .
ansible-lint .
flake8

構文に不備がある場合は以下のように表示されます。

[root@Kensyo my-role-name]# cat tasks/main.yml
---
- name: install httpd
   yum:
   name: httpd
   state: present
[root@Kensyo my-role-name]# molecule lint
--> Test matrix

└─default
   ├─ dependency
   └─ lint

--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'lint'
--> Executing: yamllint .
ansible-lint .
flake8
./tasks/main.yml
  3:7       error    syntax error: mapping values are not allowed here (syntax)

Syntax Error while loading YAML.
  mapping values are not allowed here

The error appears to be in '/root/roles/my-role-name/tasks/main.yml': line 3, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- name: install httpd
   yum:
      ^ here

5.3. インスタンスの確認

インスタンスの状態を確認します。『Created』『Converged』が『false』な状態です。

Instance Name    Driver Name    Provisioner Name    Scenario Name    Created    Converged
---------------  -------------  ------------------  ---------------  ---------  -----------
instance         docker         ansible             default          false       false

5.4. molecule create

『molecule create』を実行しコンテナの作成を行います。
[failed=1]エラー終了していないことを確認してください。

[root@Kensyo my-role-name]# molecule create
--> Test matrix

└─default
   ├─ dependency
   ├─ create
   └─ prepare

--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'create'
--> Sanity checks: 'docker'

    PLAY [Create] ******************************************************************

    TASK [Log into a Docker registry] **********************************************
    skipping: [localhost] => (item=None)

    TASK [Check presence of custom Dockerfiles] ************************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Create Dockerfiles from image names] *************************************
    skipping: [localhost] => (item=None)

    TASK [Discover local Docker images] ********************************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Build an Ansible compatible image (new)] *********************************
    skipping: [localhost] => (item=molecule_local/docker.io/pycontribs/centos:7)

    TASK [Create docker network(s)] ************************************************

    TASK [Determine the CMD directives] ********************************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Create molecule instance(s)] *********************************************
    changed: [localhost] => (item=instance)

    TASK [Wait for instance(s) creation to complete] *******************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    PLAY RECAP *********************************************************************
    localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0

--> Scenario: 'default'
--> Action: 'prepare'
Skipping, prepare playbook not configured.

インスタンスの状態を確認します。Createdが『true』になっています。コンテナが作成されている状態です。

Instance Name    Driver Name    Provisioner Name    Scenario Name    Created    Converged
---------------  -------------  ------------------  ---------------  ---------  -----------
instance         docker         ansible             default          true       false

5.5. molecule login

『molecule login』を実行しコンテナにログインします。ロール実行前の環境を確認するため、
実行予定のhttpdパッケージがインストールされているか確認してください。

[root@Kensyo my-role-name]# molecule login
[root@instance /]#
[root@instance /]# rpm -qa | grep httpd
[root@instance /]#

5.6. molecule converge

molecule convergeを実行し、ロールの実行を行います。
「failed=1」エラー終了していないことを確認してください。

[root@Kensyo ping]# molecule converge
--> Test matrix

└─default
   ├─ dependency
   ├─ create
   ├─ prepare
   └─ converge

--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'create'
--> Sanity checks: 'docker'


    PLAY [Create] ******************************************************************

    TASK [Log into a Docker registry] **********************************************
    skipping: [localhost] => (item=None)

    TASK [Check presence of custom Dockerfiles] ************************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Create Dockerfiles from image names] *************************************
    skipping: [localhost] => (item=None)

    TASK [Discover local Docker images] ********************************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Build an Ansible compatible image (new)] *********************************
    skipping: [localhost] => (item=molecule_local/docker.io/pycontribs/centos:7)

    TASK [Create docker network(s)] ************************************************

    TASK [Determine the CMD directives] ********************************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Create molecule instance(s)] *********************************************
    changed: [localhost] => (item=instance)

    TASK [Wait for instance(s) creation to complete] *******************************
    FAILED - RETRYING: Wait for instance(s) creation to complete (300 retries left).
    changed: [localhost] => (item=None)
    changed: [localhost]

    PLAY RECAP *********************************************************************
    localhost                  : ok=5    changed=2    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0

--> Scenario: 'default'
--> Action: 'prepare'
Skipping, prepare playbook not configured.
--> Scenario: 'default'
--> Action: 'converge'

    PLAY [Converge] ****************************************************************

    TASK [Gathering Facts] *********************************************************
    ok: [instance]

    TASK [Include my-role-name] ****************************************************

    TASK [my-role-name : install httpd] ********************************************
    changed: [instance]

    PLAY RECAP *********************************************************************
    instance                   : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

インスタンスの状態を確認します。Convergedが「true」になっているため、ロールが実行された状態です。

Instance Name    Driver Name    Provisioner Name    Scenario Name    Created    Converged
---------------  -------------  ------------------  ---------------  ---------  -----------
instance         docker         ansible             default          true       true

molecule loginを実行しコンテナ内でパッケージがインストールされているか確認します。

[root@Kensyo my-role-name]# molecule login
[root@instance /]#
[root@instance /]# rpm -qa | grep httpd
httpd-2.4.6-90.el7.centos.x86_64
httpd-tools-2.4.6-90.el7.centos.x86_64
[root@instance /]# exit
[root@Kensyo my-role-name]#

5.7. molecule destroy

molecule destroyを実行し、作成したコンテナを削除します。

[root@Kensyo my-role-name]# molecule destroy
--> Test matrix

└─default
   ├─ dependency
   ├─ cleanup
   └─ destroy

--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'cleanup'
Skipping, cleanup playbook not configured.
--> Scenario: 'default'
--> Action: 'destroy'
--> Sanity checks: 'docker'

    PLAY [Destroy] *****************************************************************

    TASK [Destroy molecule instance(s)] ********************************************
    changed: [localhost] => (item=instance)

    TASK [Wait for instance(s) deletion to complete] *******************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Delete docker network(s)] ************************************************

    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=2    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

--> Pruning extra files from scenario ephemeral directory

6. Molecule コマンドまとめ

molecule コマンドはたくさんありますので検証で使用したコマンドをまとめます。


『molecule create』コマンドはインスタンスを作成します。
『molecule converge』コマンドはインスタンスの作成とロールの実行を行います。
『molecule login』コマンドは作成したインスタンスにログインします。
『molecule destroy』コマンドは作成したインスタンスを削除します。
『molecule converge』や『molecule test』を複数回行うことで冪等性のチェックが可能です。
『molecule test』コマンドはインスタンスの作成から削除までの一連の工程を実行します。
Molecule コマンドを実行する際にデバッグを出力することが可能です。
例: [molecule --debug create]
その他コマンドにつきましては、公式サイト『Command Line Reference』をご参照ください。


7. 実行が失敗したタスク

/etc/hosts の修正を行うタスクを記載し実行したところ、タスクが失敗しエラーとなりました。

(中略)
    PLAY RECAP *********************************************************************
    instance                   : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

            "seuser": null,
            "src": "/root/.ansible/tmp/ansible-tmp-1585125530.483603-191325592318519/source",
            "unsafe_writes": null,
            "validate": null
        }
    },
    "msg": "Unable to make /root/.ansible/tmp/ansible-tmp-1585125530.483603-191325592318519/source into to /etc/hosts, failed final rename from /etc/.ansible_tmp9N6Mzahosts: [Errno 16] Device or resource busy"
}

ERROR:

Dockerを使用していることによるエラー内容です。
ドライバー以外(例えばvmwareなど)を対象に作成したrolesは場合によりエラーとなるかもしれません。
Moleculeを実践的に使用する方法としては、
dockerを対象に構築したrolesをテストするために、dockerドライバーを使い『Molecule』を使用するのがよさそうです。
Molecule2系では複数ドライバーが存在したので、3系でも今後使用できる環境が増えるといいですね。

8. 技術ブログ

会社Webサイトにて技術ブログを掲載しております。ご覧いただければ幸いです。

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

kibanaの日本語化まで(Dockerベース)

背景

  • 久しぶりにElastic系が使いたくなり、立ち上げてみた(Elastic cloudではなく)
  • 日本語化をしてなかったのでしたくなった
  • 日本語化がほんの少し面倒だったので、備忘のため

ベース

  • ubuntu19.04
  • Dockerは導入済み
  • kibanaは7.6.1で立てる

コンテナの起動

このあたりを参考にさせてもらった。そのまま掲載
https://qiita.com/ajitama/items/c2deb9c3bdde61660f92

  • ネットワークブリッジの用意
docker network create elasticsearch --driver bridge
  • Elastic Search (7.6.1) のコンテナ起動
docker run -d -e "http.host=0.0.0.0" -e "transport.host=127.0.0.1" -e "xpack.security.enabled=false" -e "xpack.monitoring.enabled=false"     -e "xpack.watcher.enabled=false" -e "xpack.graph.enabled=false" -e "xpack.ml.enabled=false" -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" -p 9200:9200 -p 9300:9300 --name elasticsearch --network="elasticsearch" docker.elastic.co/elasticsearch/elasticsearch:7.6.1
  • Kibana (7.6.1) のコンテナ起動
    • XXXXXはElastic Searchは適当に合わせて変更する
    • --privilegedは消してもOK(この後の手順でKibanaの再起動時にsystemctlを使おうと思ったけどダメだったこともあり)
docker run -d --privileged --name kibana -p 5601:5601 -e "ELASTICSEARCH_URL=http://XXXXXX:9200" -e "xpack.graph.enabled=false" -e "xpack.security.enabled=false" -e "xpack.ml.enabled=false" --network="elasticsearch" docker.elastic.co/kibana/kibana:7.6.1
  • ここまでで一旦サービスは起動済みのはず
root@xxx:~# docker ps -a
CONTAINER ID        IMAGE                                                 COMMAND                  CREATED             STATUS                    PORTS                                            NAMES
9ded6340d965        docker.elastic.co/kibana/kibana:7.6.1                 "/usr/local/bin/dumb…"   29 minutes ago      Up 22 minutes             0.0.0.0:5601->5601/tcp                           kibana
a0161d387e5b        docker.elastic.co/elasticsearch/elasticsearch:7.6.1   "/usr/local/bin/dock…"   2 hours ago         Up 2 hours                0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   elasticsearch

日本語化まで

  • root権限が必要なので、-u 0オプション等をつけて起動すること
docker exec -u 0 -it kibana bash
  • お目当ての日本語化ファイルの配置場所にcdすると既にファイルが存在する
    • translataionファイルの居場所は/usr/share/kibana/x-pack/plugins/translations/translations/
    • 念のためwgetする場合はhttps://github.com/elastic/kibana/raw/master/x-pack/plugins/translations/translations/ja-JP.jsonから取得し置き換える
    • 自分は面倒だったので変えなかった。話題のDeepLとかで翻訳したほうが実はいいかも
[root@9ded6340d965 kibana]# cd /usr/share/kibana/x-pack/plugins/translations/translations/
[root@9ded6340d965 translations]# ll
total 3152
-rw-rw-r-- 1 kibana root 1746780 Feb 29 00:51 ja-JP.json
-rw-rw-r-- 1 kibana root 1478465 Feb 29 00:51 zh-CN.json
  • ymlの書き換えを実施
    • Editorが入ってないと思うので、yum install -y vimとかでinstallすること
    • ymlの居場所は/usr/share/kibana/config/kibana.yml
[root@9ded6340d965 translations]#vim /usr/share/kibana/config/kibana.yml
#
# ** THIS IS AN AUTO-GENERATED FILE **
#

# Default Kibana configuration for docker target
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true

↓↓ここから追加した↓↓
# Specifies locale to be used for all localizable strings, dates and number formats.
# #i18n.locale: "en"
i18n.locale: "ja-JP"
  • あとはサービスの再起動
    • ここでsystemctlを使おうとしたら、Failed to get D-Bus connection: Operation not permittedcのエラーが出てしまったので、早々に諦め
    • コンテナ自体を再起動でDone
docker restart kibana

でアクセスすると、日本語で起動してるね!OK!

image.png

備考

  • こういう時だからこそ、たまには記事書くのもいいかも
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS公式さんがDocker Hubで aws-cli のイメージを公開してくれた!

AWS公式さんがDocker Hubでイメージを公開してくれました。 (2020/03/31)
待ってました :tada: :tada: :tada:

AWS CLI v2 Docker image | AWS Developer Blog
https://aws.amazon.com/jp/blogs/developer/aws-cli-v2-docker-image/

(Google翻訳) AWS CLI v2の2.0.6のリリースにより、AWS CLI v2がDockerイメージとして利用できるようになったことをお知らせします。

これにより、ユーザーはAWS CLI v2のインストールを自分で管理する必要なく、コンテナベースの環境でAWS CLI v2を使用できます。このDockerイメージを利用するにはさまざまな方法がありますが、特にCI / CD設定では、ローカルマシンのDockerコンテナでAWS CLI v2を実行する方法について説明します。

amazon/aws-cli - Docker Hub
https://hub.docker.com/r/amazon/aws-cli

使い方も、かなーり詳しくしてくれているので詳細はDocker Hubをご確認ください。

前にaws-cli を実行するためにDockerイメージを作成して利用していた ( DockerコンテナからAWSコマンドを簡単に実行できるコマンドをつくってみた - Qiita ) のですが、その手間が省けます。はかどります。
バージョンは2.0.6 となっており (2020/04/01 時点)、今後のバージョンアップにも対応してくれることでしょう (期待)

つかってみる

使い方は簡単です。

エイリアス設定して利用する設定があったので、それを利用してみます。

認証や設定情報を含むディレクトリを-v ~/.aws:/root/.aws でマウント、コマンド実行するカレントディレクトリを-v $(pwd):/aws でDockerコンテナ内の/aws にマウントすることでファイルの読み書きもホストでaws コマンドを実行するときと同じ挙動になります。

# 確認用としてエイリアスを aws ではなく、 aws-test としています
> alias aws-test='docker run --rm -ti -v ~/.aws:/root/.aws -v $(pwd):/aws amazon/aws-cli'

# Fishの場合
> alias aws-test='docker run --rm -ti -v ~/.aws:/root/.aws -v $PWD:/aws amazon/aws-cli'

> aws-test --version
aws-cli/2.0.6 Python/3.7.3 Linux/4.19.76-linuxkit botocore/2.0.0dev10

# カレントディレクトリで読み書きできる
> aws-test s3 cp ./hoge.txt s3://<任意のバケット>/

# カレントディレクトリ外はだめ
> aws-test s3 cp ../hoge.txt s3://<任意のバケット>/

これでもうイメージをビルドしなくてもいいんやなって。

参考

amazon/aws-cli - Docker Hub
https://hub.docker.com/r/amazon/aws-cli

DockerコンテナからAWSコマンドを簡単に実行できるコマンドをつくってみた - Qiita
https://qiita.com/kai_kou/items/99d9f9372eed970eab3b

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

コンテナにリモートデスクトップ接続しようとしてlogin failed for display 0となった時の対応方法

  • 環境
    • 接続元 : Windows10 64bit バージョン1909
    • 接続先 : Dockerで作ったコンテナ
      • ホスト : CentOS Linux release 7.6.1810 (Core)
      • コンテナ : CentOS Linux release 7.6.1810 (Core)

事象 : リモートデスクトップ接続しようとしたらダイアログが表示されてログインできない

ダイアログのメッセージ
connectiong to sesman ip 127.0.0.1 port 3350
sesman connect ok
sending login info to session manager, please wait...
login failed for display 0

原因1 : 指定するポートが誤っていたから

コンテナには2つポートを開けていて8082->8080がリモートデスクトップ接続用だった。

$ docker ps
CONTAINER ID  IMAGE        COMMAND          CREATED       STATUS        PORTS                                             NAMES
123456789012  host-ponsuke "/usr/sbin/init" 9 months ago  Up 14 minutes 0.0.0.0:8082->8080/tcp, 0.0.0.0:8083->8081/tcp    ponsuke

そこで、リモートデスクトップ接続時にホストのIPアドレス:8080を指定していた・・・コンテナ設定時に描いた絵を見て気が付いた・・・ポートがホストとコンテナで逆だ・・・

image.png
Dockerコンテナ上のTomcatに外部のブラウザからアクセスする方法 - Qiita

対応方法 : 正しいポートを指定してリモートデスクトップ接続する

  1. ホストのIPアドレス:ホストのリモートデスクトップ用ポート(今回の場合ホストのIPアドレス:8082)でリモートデスクトップ接続する
  2. 接続できる

原因2 : その他

  • パスワードが誤っているときにもこのメッセージが出る
    • 正しいパスワードを忘れてしまった場合は、コマンドを使ってrootでコンテナにログインしてパスワードを変更してあげる
  • /var/log/xrdp.log/var/log/xrdp-sesman.log などのログを見てみる
  • よくわからないときはとりあえずコンテナを再起動してみる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

docker上でRailsアプリを動かす際に、localhostでアクセスするためのオプション

はじめに

学習環境を用意するにおいて、コンテナ上に開発環境が用意できることで、

・ホストPCを汚すことなく環境を構築できる
・異なるPC間で同じ環境を使いまわせる
・格好いいと感じる

といった理由からRailsアプリをコンテナ上で作って動かしてみましたが、ホストからの動作確認で引っかかったのでメモします。
※動かしたのはscaffoldレベルのアプリです

先にまとめ

先に問題と解決をまとめて書いておきます

  • 問題
    • コンテナ内で起動したRailsアプリにホストからアクセスできない
  • 解決方法
    • Railsアプリを立ち上げる際に、-b 0.0.0.0をオプションとしてつける

以下、やったこと

まとめにたどり着くまでの状況をつらつらと

準備

ポートフォワードの設定をしてコンテナを立ち上げる

(ホスト)$ docker container run -it -p 30000:3000 /bin/bash

コンテナ内でアプリを作る

(コンテナ)# rails new scaffold_sample
(コンテナ)# bin/rails db:create

データベースを作成無事できたことを確認した後にアプリケーションを起動

(コンテナ)# bin/rails server

上記手順で起動したアプリにアクセスできない

ホストからlocalhost:30000(30000はポートフォワードの設定)にアクセスしてもアプリケーションからの応答はなし
ホストのターミナルからcurlを実行してもエラー
コンテナからlocalhost宛にcurlを実行すると正常な(期待する)htmlが返却される

解決手段

アプリケーションの起動時に-b 0.0.0.0をオプションとしてつける

(コンテナ)# bin/rails server -b 0.0.0.0

するとホスト側のブラウザからアプリケーションにアクセスできるようになった
「localhost:30000」「127.0.0.1:30000」「0.0.0.0:30000」のどれでもlocalhostにアクセスできていた

オプションの値について

上記の通り、-b 0.0.0.0を指定することでによってホストからのアクセスは可能になったが
-b 127.0.0.1-b localhostではホストからアクセスできるようにはならなかった

個人的なメモとして

0.0.0.0や127.0.0.1の持つ意味や、コンテナからみた自分のIP、コンテナからみたホストのIP、ホストから見たコンテナのIPなどが、
ネットワークのオプションとともにどのように振る舞うのかを学ばなければならないと感じた

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