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

CetnOS8+SELinux+HAProxy+rootless dockerでWordPressを構築する

SELinuxの状態を確認します

$ getenforce
Enforcing

CentOS8でデフォルトで入っているpodmanは使いません

$ podman --version
podman version 1.6.4
# docker互換のpodman-dockerが入っていると以下のようになります。
$ podman --version
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
podman version 1.6.4

podmanを削除したい人はdnf remove podmanで削除してください。
※podman-docker+podman-composeの構成はうまくいきませんでした

root権限を持たないユーザwpuser1を作成します。

adduser wpuser1
passwd wpuser1
#wpuser1に切り替える
su - wpuser1

rootless dockerを導入

$ whoami
wpuser1
$ curl -fsSL https://get.docker.com/rootless | sh

実行すると以下のようなメッセージが表示されます

# Installing stable version 19.03.8
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 60.7M  100 60.7M    0     0  38.0M      0  0:00:01  0:00:01 --:--:-- 38.0M
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 17.8M  100 17.8M    0     0  7395k      0  0:00:02  0:00:02 --:--:-- 7392k
# starting systemd service
● docker.service - Docker Application Container Engine (Rootless)
   Loaded: loaded (/home/wpuser1/.config/systemd/user/docker.service; disabled; vendor preset: enabled)
   Active: active (running) since Mon 2020-03-30 09:29:28 UTC; 12ms ago
     Docs: https://docs.docker.com
 Main PID: 2143 (dockerd-rootles)
   CGroup: /user.slice/user-1000.slice/user@1000.service/docker.service
           tq2143 /bin/sh /home/wpuser1/bin/dockerd-rootless.sh --experimental --storage-driver=vfs
           tq2149 [slirp4netns]
           mq2150 grep -- --disable-host-loopback
Client: Docker Engine - Community
 Version:           19.03.8
 API version:       1.40
 Go version:        go1.12.17
 Git commit:        afacb8b7f0
 Built:             Wed Mar 11 01:22:56 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.8
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.17
  Git commit:       afacb8b7f0
  Built:            Wed Mar 11 01:30:32 2020
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683
# Docker binaries are installed in /home/wpuser1/bin
# Make sure the following environment variables are set (or add them to ~/.bashrc):\n
export DOCKER_HOST=unix:///run/user/1000/docker.sock

#
# To control docker service run:
# systemctl --user (start|stop|restart) docker
#

dockerが入っているか確認します

$ docker --version
Docker version 19.03.8, build afacb8b7f0

~/.bashrcに環境変数を追記します

$ vi ~/.bashrc
export DOCKER_HOST=unix:///run/user/1000/docker.sock

環境変数を再読み込みします

source ~/.bashrc

dockerを起動します

$ systemctl --user start docker

dockerが起動しているか確認します

$ systemctl --user status docker
● docker.service - Docker Application Container Engine (Rootless)
   Loaded: loaded (/home/wpuser1/.config/systemd/user/docker.service; disabled; vendor preset: enabled)
   ここ---> Active: active (running) since Mon 2020-03-30 09:29:28 UTC; 4min 10s ago
     Docs: https://docs.docker.com
 Main PID: 2143 (rootlesskit)
   CGroup: /user.slice/user-1000.slice/user@1000.service/docker.service
           tq2143 rootlesskit --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --po>
           tq2156 /proc/self/exe --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback ->
           tq2170 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 2156 tap0
           tq2188 dockerd --experimental --storage-driver=vfs
           mq2203 containerd --config /run/user/1000/docker/containerd/containerd.toml --log-level info

コンテナのコマンドが叩けるか確認します

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

docker-composeをインストールします

$ pip3 --version
pip 9.0.3 from /usr/lib/python3.6/site-packages (python 3.6)
$ pip3 install docker-compose --user
$ docker-compose --version
docker-compose version 1.25.4, build unknown
mkdir /home/wpuser1/testwp1
mkdir /home/wpuser1/testwp1/storage
cd /home/wpuser1/testwp1

ドメインを指定せず動かす

docker-compose.ymlに以下の内容を記載します

docker-compose.yml
version: "3.7"
services:
  db:
    ports:
     - "127.0.0.1:3306:3306"
    image: mariadb:10.4.12
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=wordpress
      - MYSQL_PASSWORD=wordpress
    volumes:
      - /home/wpuser1/testwp1/storage:/var/lib/mysql
  wordpress:
    image: wordpress:5.3.2-php7.4
    ports:
      - "0.0.0.0:8001:80"
    restart: always
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_PASSWORD=wordpress
      - WORDPRESS_DB_NAME=wordpress
    depends_on:
      - db
$ docker ps -a
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                      NAMES
5085cdce724d        wordpress:5.3.2-php7.4   "docker-entrypoint.s…"   12 seconds ago      Up 8 seconds        0.0.0.0:8001->80/tcp       testwp1_wordpress_1
94bcfba848ac        mariadb:10.4.12          "docker-entrypoint.s…"   17 seconds ago      Up 12 seconds       127.0.0.1:3306->3306/tcp   testwp1_db_1

root権限でポート8001を開きます

$ firewall-cmd --permanent --add-port=8001/tcp
$ firewall-cmd --reload

http://パブリックIPアドレス:8001
にアクセスすると、WordPressの初期設定画面が表示されます。

ドメインを指定してHAProxyで振り分ける

HAProxyを使い、80ポートからローカル8081に振り分けるようにします

# 先ほどdocker-compose upしたものを全削除
$ docker-compose down --rmi all --volumes

docker-compose.ymlにVIRTUAL_HOSTを追記します
yourdomain.example.comの部分を適宜置き換えてください。
あらかじめドメインにAレコードを設定します

docker-compose.yml
version: "3.7"
services:
  db:
    ports:
     - "127.0.0.1:3306:3306"
    image: mariadb:10.4.12
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=wordpress
      - MYSQL_PASSWORD=wordpress
    volumes:
      - /home/wpuser1/testwp1/storage:/var/lib/mysql
  wordpress:
    image: wordpress:5.3.2-php7.4
    ports:
      - "127.0.0.1:8001:80"
    restart: always
    environment:
      - VIRTUAL_HOST=yourdomain.example.com
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_PASSWORD=wordpress
      - WORDPRESS_DB_NAME=wordpress
    depends_on:
      - db
$ systemctl restart firewalld
$ systemctl status firewalld
Redirecting to /bin/systemctl status firewalld.service
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
   Active: active (running)

以下はroot権限で操作します

先ほどのポートを開けている場合は閉じます
$ firewall-cmd --permanent --remove-port=8001/tcp
$ firewall-cmd --permanent --add-port=80/tcp
$ firewall-cmd --reload

HAProxyのインストール

$ dnf install haproxy

rootでHAProxyのSELinuxポリシーを許可します

$ setsebool -P haproxy_connect_any 1

HAProxyの設定に追記します

/etc/haproxy/haproxy.cfg
frontend    multiple_domains
            bind    *:80
            mode    http
            timeout client  10s

            acl is_v1 hdr_dom(host) -i testwp1.example.com
            use_backend virtual_www1 if is_v1
            default_backend default_www

backend     default_www
            mode    http
            balance static-rr
            timeout connect 20s
            timeout server  20s
            timeout check   5s
            option  httplog
            option  httpchk GET /index.html HTTP/1.0
            server  default_www 127.0.0.1:80 check inter 5000 fall 2

backend     virtual_www1
            mode    http
            balance static-rr
            timeout connect 20s
            timeout server  20s
            timeout check   5s
            http-request set-header Client-Source-IP %[req.hdr_ip(X-Forwarded-For,1)]
            option forwardfor
            server www1 127.0.0.1:8001
$ systemctl start haproxy

http://ドメイン名/
でアクセスしてインストール画面が表示されることを確認します。

参考文献
HAProxyでマルチドメインを処理する
https://worklog.be/archives/2058

Run the Docker daemon as a non-root user (Rootless mode)
https://docs.docker.com/compose/compose-file/

https://hub.docker.com/_/wordpress/

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

大学がリモート授業をするなら画面にコメントを流すNicoNico SPEENYAはアリなんじゃないか

コロナ対策として、大学がリモートでの授業配信を進めていくらしいですね。
どういった形で配信されるのかはわかりませんが、大勢が聴講する授業では学生と講師間でのコミュニケーションが難しそうなので、コメントを打って意見や質問を共有できるといいんじゃないかと。
(最近はそういうのが当たり前にあるのかもしれないけど、特にどういうシステムが使われてるとかは知らない状態で書いてます)

そこで、Chrome Extensionでコメントを流せるNicoNico SPEENYAってあったよなと思い出して試してみたのでデプロイ方法とか書いておきます。
私は社畜なのでリモート会議ででもネタとして使わせていただこうと思います。

NicoNico SPEENYA
https://github.com/chimerast/niconico-speenya

前提

  • gitが利用可能
  • docker/docker-composeが利用可能

ローカルでデプロイ

git clone https://github.com/chimerast/niconico-speenya.git
cd niconico-speenya
vi docker-compose.yml
docker-compose.yml
version: "3"

services:
  nicosp:
    build: .
    restart: unless-stopped
    ports:
      - 2525:80
docker-compose up --build -d 

ブラウザで
http://localhost:2525

2020-03-30_225503.png

./make-package.sh
cd dist
[root@localhost dist]# ls -l
合計 308
-rw-r--r-- 1 root root 314662  3月 30 23:08 extension.zip

できあがったファイルzipファイルを
chrome://extensions/
にドラッグアンドドロップしてインストール。
コメントサーバ側からコメントを入力するとChromeにコメントが流れる。
2020-03-30_230205.png

コメントサーバをインターネットに公開しておいて、授業スライドをSharepointとかでWeb上で表示して画面共有しておけば、学生側がコメントを流せるというような使い方ができるんじゃないか。(認証がないとか、荒れるとかいう話は別にしておいて)

インターネット公開

一応簡単にインターネット公開用設定も。
例によってリバースプロキシにぶら下げてLet's Encrypt対応。

docker-compose.yml
version: "3"

services:
  nicosp:
    build: .
    restart: unless-stopped
    environment:
      TZ: Asia/Tokyo
      VIRTUAL_HOST: #あなたのドメイン名
      LETSENCRYPT_HOST: #あなたのドメイン名
      LETSENCRYPT_EMAIL: #メアド

  nginx-proxy:
    image: jwilder/nginx-proxy
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - /dockerdata/nginx-proxy/certs:/etc/nginx/certs:ro
      - /dockerdata/nginx-proxy/htpasswd:/etc/nginx/htpasswd
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro

  letsencrypt-nginx-proxy-companion:
    image: jrcs/letsencrypt-nginx-proxy-companion
    restart: always
    volumes:
      - /home/web/wordpress/certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro
    volumes_from:
      - nginx-proxy

networks:
  default:
    external:
      name: shared

Chrome extensionを公開したサーバに対応させる。

vi ./extension/scripts/content-script.js
--------------------
  const SERVER_URL = 'http://localhost:2525' #ここを公開したURLに書き換える。
--------------------
./make-package.sh

これで公開したコメントサーバから読み込むことができるはず。

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

Docker環境でRailsアプリにvue.jsを導入する

目的

railsアプリにvue.jsを導入するために、練習もかねてサンプルのアプリにvueを導入してみたいと思う。

サンプルアプリのディレクトリ作成

任意のワークスペースでディレクトリを作成します。

ターミナル
mkdir sample_app
cd sample_app

Dockerの設定ファイルを作成

Dockerfile
FROM ruby:2.5.3

RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - && apt-get update && \
    apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*

RUN apt-get update -qq && apt-get install -y build-essential libpq-dev

RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && apt-get install -y yarn

RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && \
    apt-get install nodejs

RUN yarn add node-sass

RUN mkdir /app
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
COPY . /app
docker-compose.yml
version: '3'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
volumes:
  db-volume:
Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.3'

あとは、Gemfile.lockの空ファイルを作成。

Railsプロジェクトを作成する

ターミナル
$ docker-compose run web rails new . --force --database=mysql

※rails newの . は現在いるディレクトリにそのままプロジェクトを作成するというもの)だそうです。

database.ymlを編集

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db

hostの部分をdbに変更する。

vue.jsの導入

Gemfile
gem 'webpacker', github: 'rails/webpacker'

その後、

$ docker-compose exec web bash

でwebコンテナに入る。

コンテナ内でコマンドを以下のコマンドを実行

$ rails webpacker:install
$ rails webpacker:install:vue
$ bin/webpack

Railsのviewファイルに以下を記述する

<%=javascript_pack_tag 'hello_vue'%>

こんな画面が出てきたら成功です。

55425ab4b1d58a46d5041eeb75e2128e.png

以上

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

Docker in Dockerを利用してCIを構築してみた

はじめに

会社でCI環境を構築するためにGitLab CI/CDを勉強中です。
社内用途ではShared Executorを選択すれば十分なのですが、Dockerを触ってみたかったのでチュートリアルではDocker Executorを選択してみました。
本記事ではDocker Executor上でDockerコンテナを使用した環境構築を行います。
そのため、「Docker Executor上でDockerを使用する = "Docker in Docker(dind)"」を活用していきます。

チュートリアルにはGitLab実践ガイド(著:北山 晋吾さん)を使用しています。
第5章と第6章の内容です。
kindle unlimitedで読めるので、是非読んでみてください。
GitLab実践ガイド

なお、本記事では上記書籍のコードを引用している箇所が有ります。著作権侵害の意思は全くなく、あくまで試してみたい方や同じようなエラーに遭遇した方向けに状況や手順を詳細に説明する目的で引用しています。著作権に触れる場合はご指摘頂ければ即刻削除致しますのでご連絡ください。

こんな人におすすめ

対象読者は以下の通りです。

  • Docker in Dockerを使用してGitLab CI立ち上げたい人
  • GitLab実践ガイドの読者
  • Docker Executor内のDockerコンテナにアクセスできなくて困っている人
  • CI環境で本番用のDockerイメージをDockerリポジトリにPushしたい人

やったこと

Javaで作成したWebアプリケーションを使用してGitLab CI/CDを試していきます。
ゴールはDocker Executor内部でDockerコンテナ上にwebアプリケーションを配置し、Docker ExecutorからWebアプリーケーションにWebアクセスを行うことです。

image.png

本記事ではGitLab CI/CDのジョブを定義するために利用するgitlab-ci.ymlの構成をメインに記載します。
環境構築やWebアプリケーションの詳細等はGitLab実践ガイドをご覧ください。

前提知識

簡単に前提知識をまとめます。

GitLab CI/CDとは

作成したジョブに従ってGitLabからビルドツールやテストツールと連携したCIを行う機能です。
Pushやマージと連携してCIを回すことができます。

GitLabにはDockerレジストリ機能もありますし、課題としてチケット管理することもできます。
GitLabを使用するメリットはリポジトリ管理、チケット管理、CI/CD、Dockerレジストリ管理まで用途に合わせて一つのシステムで構築できることだと思っています。

以下はGitLab関連の用語解説です。

GitLab Runner

GitLab CI/CD上からの要求を受けて、実際にビルドしたりテストしたりするプロセスです。
Gitlab RunnerにはShared RunnerとSpecific Runnerの2種類があります。

Shared Runner

複数のプロジェクトのジョブ実行を、全てのプロジェクト共通で使用できるRunnerで処理する方式です。
GitLab.comには予め使用できるRunnerが登録されています。
本記事ではRunnerの構成を一般化するためにShared Runnerを使用します。
image.png

Specific Runner

特定のプロジェクトのジョブのみを実行する方式です。
例えば、Specific Runnerであれば「GitLab.comにプロジェクトを展開しながら自身の仮想環境サーバーに構築したRunnerを登録する」といったことができます。
プロジェクト独自のRunnerを用意できるため色々設定をカスタマイズできることが利点です。
image.png

Executor

Runner上でジョブを実行するための実行方式です。
GitLab.com上のShared Runnerであれば、tag情報としてExecutorの種類が記載されています。
Runnerを登録するときに決定する必要があります。

Executorにはいくつか種類がありますが、ここでは2つだけ紹介します。

Shell Executor

Shell ExecutorはRunnerが走っているサーバー上で動作するExecutorです。
例えばLinux系にRunnerをインストールすればデフォルトでBashが動作し、ジョブを実行します。

Docker Executor

Docker Executorは、事前に用意したDocker環境のDocker Engineに対してDocker APIを通して接続することで動作するExecutorです。
環境を汚さずに、どのプラットフォーム上でも再現性のあるビルドやテストが実行できることがメリットです。

Docker in Docker(dind)

Dockerコンテナ内部からDockerコンテナを使用する技術です。
当初「Dockerコンテナ内でDockerコマンド叩けば良いんでしょ」と思ってましたが、意外と難有りでややこしいです。
詳しい説明は以下記事に非常にわかりやすく記載されているため本記事では省略します。
Dockerコンテナ内からDockerを使うことについて

環境

  • GitLab動作環境 : GitLab.com
  • Runner動作環境 : Shared Runner (shared-runners-manager-3.gitlab.com)

手順

事前準備

GitLab CI/CDのジョブは「.gitlab-ci.yml」というファイルで定義します。
このファイルに実行したいジョブを書いておき、プロジェクトのトップ階層に置いてコミットします。

今回は動的にジョブ内でDockerイメージをビルドするため、Dickerfileもプロジェクトのアプリケーション内に配置しておきます。

全体的な構成は以下のようになります。

.
├── README.md
├── scripts
│   └── gitlab-ci.txt
└── web_demo
    ├── Dockerfile
    ├── bin
    │   └── (省略) 
    ├── build.gradle
    └── src
        ├── main
        │   └── (省略)
        └── test
            └── (省略)

共通設定

最初に全フェーズで共通の設定を記載していきます。

設定パラメータは以下のようになります。

.gitlab-ci.yml
stages:
  - build
  - packaged
  - test

image: docker:latest

variables:
  APP_NAME: 'web_demo'
  CONTAINER_NAME: ${CI_PROJECT_NAME}_${APP_NAME}
  CONTAINER_IMAGE: ${CI_REGISTRY}/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}/${APP_NAME}
  DOCKER_DRIVER: overlay2

services:
  - docker:dind

  • stages : 本スクリプトで実行するステージを指定します。
  • image : ジョブを実行するExecutorのDockerイメージを指定します。
  • services : docker内で使用するDockerサービスを指定します。
  • variables : 定数を定義します。
    • APP_NAME : 今回使用するアプリ名
    • CONTAINER_NAME : アプリを配置するコンテナ名
    • CONTIANER_IMAGE : Dockerリポジトリに登録するイメージ名
    • DOCKER_DRIVER : ストレージドライバの選択

ストレージドライバの選択に関する公式ドキュメントはこちら。
今回はチュートリアル目的のため、参考書に従ってoverlay2を選択しました。
ストレージ・ドライバの選択

ビルド

以下はビルドステージのジョブ定義です。

.gitlab-ci.yml
build_web_demo:
  stage: build
  image: gradle:4.4.1-jdk8
  script:
    - cd ./${APP_NAME}
    - gradle war
    - gradle test
  artifacts:
    paths:
      - ${APP_NAME}/build/libs/*.war
    expire_in: 60 min
  tags:
    - docker
    - linux

ビルドステージではdindは使用しません。
artifactsとしてビルド成果物を保持しています。
expire_inで指定した時間だけ一時的に保存され、この後のステージで使用することができます。

パッケージ化

以下はパッケージ化ステージのジョブ定義です。

.gitlab-ci.yml
packaged_web_app:
  stage: packaged
  before_script:
    - docker login -u "gitlab-ci-token" -p "$CI_BUILD_TOKEN" ${CI_REGISTRY}
  script:
    - cd ./${APP_NAME}
    - docker build . -t ${CONTAINER_IMAGE}
    - docker push ${CONTAINER_IMAGE}
  tags:
    - docker
    - linux

Dockerイメージをビルドして、成果物をGitLab上のDockerリポジトリにPushしています。
dind使用時はジョブが変わるとDocker環境が初期化されるため、パッケージ化したイメージをテストステージで再利用するためにDockerリポジトリ使用しています。
Dockerリポジトリを使用しない場合はテストステージでDockerイメージが見つからない旨のエラーが発生します。

 $ docker run --name ${CONTAINER_NAME} -p 80:8080 -d ${APP_NAME}
 Unable to find image 'web_demo:latest' locally
 docker: Error response from daemon: pull access denied for web_demo, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.

また、Dockerリポジトリは最初にログインしておかなければ'access forbidden'が発生します。

テスト

以下はテストプロセスのジョブ定義です。

.gitlab-ci.yml
test_web_demo:
  stage: test
  before_script:
    - docker login  -u "gitlab-ci-token" -p "$CI_BUILD_TOKEN" $CI_REGISTRY
    - apk update
    - apk add curl
  script:
    - docker run --name ${CONTAINER_NAME} -p 80:8080 -d ${CONTAINER_IMAGE}
    - sleep 10
    - curl docker:80/${APP_NAME}/hello
  tags:
    - docker
    - linux

注意するポイントはcurlコマンドのホスト名設定です。
Docker内で動作しているDockerコンテナのIPアドレスを動的に取得し、IPアドレスを指定してアクセスするとTimeoutエラーが発生します。
IPアドレスの取得は成功しているものの、アクセスできていないことがログからわかります。

 $ 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

この問題の解決方法として、ホスト名をdockerに変更します。
GitLabCIではservicesで定義したコンテナにアクセスする場合、定義した時の名前を使用する必要があります。
今回は'docker:dind'と定義していたため、dockerをホスト名として指定します。

以下はトラブルシューティングに活用したURLです。
Accessing the services
Docker Container Networking with Docker-in-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!

以上で無事ビルドステージ、パッケージ化ステージ、テストステージを経てCIが成功しました。

まとめ

今回はdindを使用してDockerイメージをビルドし、テストまでしてみました。
特にテストステージは調査に苦労したため、参考になったら嬉しいです。

調査した内容や書籍の内容をベースに載せていますが、専門外のため間違っている箇所があったら指摘して頂けたら幸いです。

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

Dockerのコマンドについて詳しくなろう

build

buildコマンドはimageを構築するのみ。コンテナ作成はしない。

$ docker-compose build

up

upコマンドでは、キャッシュがある場合はそれを使って一発でイメージの構築から、コンテナの構築・起動までします。

$ docker-compose up

start

startコマンドは既存のコンテナを起動します。

$ cocker-compose start

run

runコマンドはimageの構築から、コンテナの構築・起動までする。引数でサービスを指定する必要あり。

$ docker-compose run web

exec

コンテナの中に移動できる

$ docker-compose exec web bash

bash ashの違いは、ashの方が軽量なコマンドらしい。

新たなrailsプロジェクトを立ち上げるコマンド

ターミナル
docker-compose run web rails new . --force --database=mysql

rails newの . は現在いるディレクトリにそのままプロジェクトを作成するというもの)だそうです。

以上

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

emacs と vim の lsp をdocker で試す

はじめに

language server(以下 lsp)の登場でどのエディタでも、統合環境のような高機能エディタとなることが可能になりました。
みんな大好き emacs や vim でも lsp をサポートし、言語ごとの設定が大分楽になり敷居が下がってきたんじゃないかなって思います。しかし、如何せん試してみるのも面倒だなーって思う人は結構いるはずです。試してみる気力があったらとっくに入門してますしね...。
そこで、今回は emacs と vim の lsp 設定が内包した docker を使ってみて最新エディタ気分を味わっていきたいと思います。

emacs + lsp on docker

まず、emacs + lsp です。最近は spacemacs が流行っていますが今回は普通の emacs でやっていきます。最初に、以下のコードで emacs + lsp on docker のコードをローカルに落としてきます。

git clone https://github.com/emacs-lsp/lsp-docker.git

権限を与えて実行します。

cd lsp-docker
chmod u+x start-emacs.sh
./start-emacs.sh

立ち上がったら、パッケージのインストールを聞かれるのでyで進んで行きます。

スクリーンショット 2020-03-29 13.44.10.png

インストールが終わったら、C-x C-fProject の適当な言語のファイルを開いて見ます(C-x は windows だと Ctr+x、mac だと ⌃+x です)。
スクリーンショット 2020-03-29 13.54.01.png

ファイルが開けたら、適当に色々試して見ながらコーディングすると楽しいと思います。
補完が効いているのとかがよく分かると思います。
スクリーンショット 2020-03-29 13.57.46.png

ただ、定義ホバーがオンになっているせいかdockerとの相性なのか、少し重いですね...。
詳しい挙動やできることなどは以下を見ていただけると助かります。
https://github.com/emacs-lsp/lsp-mode

vim + lsp on docker

次に vim + lsp です。こちらも流行りの neovim でなく普通の vim でやっていきます。今回も同じようにコードを落としてきます。今回は公式で用意されていなかったため自前で用意しました。

git clone https://github.com/komem3/vim-lsp-docker.git

Docker イメージをビルドします。

./build.sh

emacs + lsp のようなサンプルプロジェクトを用意するのが面倒だったため、引数にサンプルプロジェクトへのパスを指定して実行します。

vim-lsp-docker % PROJECT_DIR=~/Downloads/lsp-docker/demo-projects ./start.sh # PROJECT_DIR に lsp-docker/demo-projects へのパスを指定する

コンソールが開けたら、Project下の適当なファイルを vim コマンドで開いてみます。
(TypeScriptとC++はうまく動かせなかったので他の言語でおねがいします...)

vim Project/Javascript/hello-world.js 

こちらもファイルが開けたら適当にコーディングしてみると楽しいと思います。
vim の軽さをすごい感じます。
スクリーンショット 2020-03-30 19.29.40.png

詳しい挙動やできることなどは以下を見ていただけると助かります。
https://github.com/prabirshrestha/vim-lsp

終わりに

お手軽に emacs や vim の lsp を試せるので、興味がある人は試してみてほしいなって思います。
また、今回使った emacs や vim の設定ファイルはどちらもとても短い記述内容になっているので、軽く見てみると簡単に設定できるもんだなぁって思うと思います。

今回の設定はどちらも最低限のものになっていますが、emacs や vim の魅力は高い拡張性や自分好みの設定にし放題なことのため、まだまだ力を温存しています。しかも最近は spacemacs とか neovim とか出てて楽しい界隈だなぁ。

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

kubernetesのWorkerノードをWindows Serverで構築

何となく、構築してみたかっただけです。
適当です。

0 構築環境

・ノード構成

ノード種類 OS IPアドレス サブネットマスク 備考
MASTER CentOS 7.7 192.168.1.221 24
WORKER Windows Server 2019 Standard 192.168.1.222 24 ServerCore、英語版、評価版

・kubernetesネットワーク

ネットワーク種類 ネットワーク サブネットマスク
POD CIDER 10.244.0.0 16
SERVICE SIDER 10.0.0.0 16

・hosts
/etc/hosts,C:\Windows\System32\drivers\etc\hostsに以下を登録

192.168.1.221 VM200001
192.168.1.222 VM200002

1 マスターノードの構築

1.1 SELinux無効化

# sed -i -e 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# setenforce 0

1.2 SWAP無効化

# sed -i -e '/swap/d' /etc/fstab
# swapoff -a

1.3 カーネルパラメタ設定

# cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

# sysctl --system

1.4 FireWall無効化

# systemctl disable firewalld
# systemctl stop firewalld

1.5 yumリポジトリ登録

$ cat > /etc/yum.repos.d/add.repo << EOF
[docker-ce-stable]
name=Docker CE Stable
baseurl=https://download.docker.com/linux/centos/7/x86_64/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[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
EOF

1.6 Docker、kubernetesのインストール

# yum install yum-utils device-mapper-persistent-data lvm2 nfs-utils rpcbind wget -y
# yum install docker-ce -y kubelet kubeadm kubectl -y

1.7 DockerのCgroup設定

# mkdir /etc/docker/
# echo {\"exec-opts\":[\"native.cgroupdriver=systemd\"]} > /etc/docker/daemon.json

1.8 各種サービス起動設定

# systemctl enable docker
# systemctl restart docker

# systemctl enable kubelet
# systemctl restart kubelet

1.9 初期化

# kubeadm init --pod-network-cidr=10.244.0.0/16 --service-cidr=10.0.0.0/16 

1.10 マスターノードでもPODが動くようにする。

※今回はLinuxのワーカーノードは作らない

# kubectl taint nodes --all node-role.kubernetes.io/master-

1.11 CNI(flannel)のマニュフェストの修正

# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# vi kube-flannel.yml

・修正箇所1

  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }

        ↓

  cni-conf.json: |
    {
      "name": "vxlan0", #★変更箇所
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }

・修正箇所2

  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }

        ↓

  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan", #★変更箇所
        "VNI" : 4096,    #★変更箇所
        "Port": 4789     #★変更箇所
      }
    }

・修正箇所3

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-amd64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:


        ↓

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-amd64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      nodeSelector:                 #★追加箇所
        kubernetes.io/os: linux     #★追加箇所
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:

1.12 CNI(flannel)のインストール

kubectl apply -f kube-flannel.yml

2 Windows ワーカーノードの構築

※PowerShellで実施する。

2.1 インストールディレクトリ作成

mkdir c:\k

2.2 バイナリプログラムおよびインストールスクリプトを設置

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
wget https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/windows/amd64/kubectl.exe -o c:\k\kubectl.exe
wget https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/windows/amd64/kubelet.exe -o c:\k\kubelet.exe
wget https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/windows/amd64/kube-proxy.exe -o c:\k\kube-proxy.exe
wget https://github.com/coreos/flannel/releases/download/v0.12.0/flanneld.exe -o c:\k\flanneld.exe
wget https://github.com/Microsoft/SDN/raw/master/Kubernetes/flannel/start.ps1 -o c:\k\start.ps1
wget https://raw.githubusercontent.com/microsoft/SDN/master/Kubernetes/flannel/register-svc.ps1 -o c:\k\register-svc.ps1
wget  https://nssm.cc/release/nssm-2.24.zip -o c:\k\nssm-2.24.zip
Expand-Archive -Path c:\knssm-2.24.zip -DestinationPath c:\k
copy c:\k\nssm-2.24\win64\nssm.exe c:\k

2.3 configの設置

マスターノードの/etc/kubernetes/admin.confをc:\k\の下にconfigという名前でコピーする。

2.4 環境変数(PATHとKUBECONFIG)の設定

[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\k", [EnvironmentVariableTarget]::Machine)
[Environment]::SetEnvironmentVariable("KUBECONFIG","C:\k\config", [EnvironmentVariableTarget]::User)

2.5 Dockerのインストール

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name Docker -ProviderName DockerMsftProvider

2.6 再起動

Restart-Computer -Force

2.7 JOIN

cd c:\k
.\start.ps1 -ManagementIP <WindowsノードIP>  -NetworkMode overlay -ClusterCIDR <POD CIDR> -ServiceCIDR <Service Cider> -KubeDnsServiceIP <kube-DNSのサービスIP> -LogDir c:\k

・例

cd c:\k
.\start.ps1 -ManagementIP 192.168.1.222  -NetworkMode overlay -ClusterCIDR 10.244.0.0/16 -ServiceCIDR 10.0.0.0/16 -KubeDnsServiceIP 10.0.0.10 -LogDir c:\k

2.8 サービス自動起動有効化

C:\k\register-svc.ps1 -NetworkMode overlay -ManagementIP 192.168.250.161 -ClusterCIDR <POD CIDR> -KubeDnsServiceIP <kube-DNSのサービスIP> -LogDir c:\k

・例

C:\k\register-svc.ps1 -NetworkMode overlay -ManagementIP 192.168.250.161 -ClusterCIDR 10.244.0.0/16 -KubeDnsServiceIP 10.0.0.10 -LogDir c:\k

おまけ

[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# kubectl  get node -o wide
NAME       STATUS   ROLES    AGE     VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                                  KERNEL-VERSION                CONTAINER-RUNTIME
vm200001   Ready    master   19m     v1.18.0   192.168.1.221   <none>        CentOS Linux 7 (Core)                     3.10.0-1062.18.1.el7.x86_64   docker://19.3.8
vm200002   Ready    <none>   2m49s   v1.18.0   192.168.1.222   <none>        Windows Server 2019 Standard Evaluation   10.0.17763.1098               docker://19.3.5
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# kubectl  get node --show-labels
NAME       STATUS   ROLES    AGE     VERSION   LABELS
vm200001   Ready    master   20m     v1.18.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=vm200001,kubernetes.io/os=linux,node-role.kubernetes.io/master=
vm200002   Ready    <none>   2m56s   v1.18.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=windows,kubernetes.io/arch=amd64,kubernetes.io/hostname=vm200002,kubernetes.io/os=windows,node.kubernetes.io/windows-build=10.0.17763
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# kubectl  get all -o wide -A
NAMESPACE     NAME                                   READY   STATUS    RESTARTS   AGE   IP              NODE       NOMINATED NODE   READINESS GATES
kube-system   pod/coredns-66bff467f8-svj5g           1/1     Running   0          19m   10.244.0.3      vm200001   <none>           <none>
kube-system   pod/coredns-66bff467f8-vznrl           1/1     Running   0          19m   10.244.0.2      vm200001   <none>           <none>
kube-system   pod/etcd-vm200001                      1/1     Running   0          20m   192.168.1.221   vm200001   <none>           <none>
kube-system   pod/kube-apiserver-vm200001            1/1     Running   0          20m   192.168.1.221   vm200001   <none>           <none>
kube-system   pod/kube-controller-manager-vm200001   1/1     Running   0          20m   192.168.1.221   vm200001   <none>           <none>
kube-system   pod/kube-flannel-ds-amd64-cd7rq        1/1     Running   0          17m   192.168.1.221   vm200001   <none>           <none>
kube-system   pod/kube-proxy-m9qn2                   1/1     Running   0          19m   192.168.1.221   vm200001   <none>           <none>
kube-system   pod/kube-scheduler-vm200001            1/1     Running   0          20m   192.168.1.221   vm200001   <none>           <none>

NAMESPACE     NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE   SELECTOR
default       service/kubernetes   ClusterIP   10.0.0.1     <none>        443/TCP                  20m   <none>
kube-system   service/kube-dns     ClusterIP   10.0.0.10    <none>        53/UDP,53/TCP,9153/TCP   20m   k8s-app=kube-dns

NAMESPACE     NAME                                   DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE   CONTAINERS     IMAGES                                 SELECTOR
kube-system   daemonset.apps/kube-flannel-ds-amd64   1         1         1       1            1           kubernetes.io/os=linux   17m   kube-flannel   quay.io/coreos/flannel:v0.12.0-amd64   app=flannel
kube-system   daemonset.apps/kube-proxy              1         1         1       1            1           kubernetes.io/os=linux   20m   kube-proxy     k8s.gcr.io/kube-proxy:v1.18.0          k8s-app=kube-proxy

NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                     SELECTOR
kube-system   deployment.apps/coredns   2/2     2            2           20m   coredns      k8s.gcr.io/coredns:1.6.7   k8s-app=kube-dns

NAMESPACE     NAME                                 DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                     SELECTOR
kube-system   replicaset.apps/coredns-66bff467f8   2         2         2       19m   coredns      k8s.gcr.io/coredns:1.6.7   k8s-app=kube-dns,pod-template-hash=66bff467f8
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# cat iis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: iis
  labels:
    app: iis
spec:
  replicas: 2
  selector:
    matchLabels:
      app: iis
  template:
    metadata:
      labels:
        app: iis
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      containers:
      - name: iis
        image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: iis
  labels:
    app: iis
spec:
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
  selector:
    app: iis
  type: NodePort
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# kubectl apply -f iis.yaml
deployment.apps/iis created
service/iis created
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# kubectl  get deploy,pod,svc -o wide
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                                                                SELECTOR
deployment.apps/iis   2/2     2            2           56s   iis          mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019   app=iis

NAME                       READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
pod/iis-6975cd4f89-28v94   1/1     Running   0          56s   10.244.1.3   vm200002   <none>           <none>
pod/iis-6975cd4f89-dq6jc   1/1     Running   0          56s   10.244.1.4   vm200002   <none>           <none>

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE   SELECTOR
service/iis          NodePort    10.0.119.23   <none>        80:30080/TCP   56s   app=iis
service/kubernetes   ClusterIP   10.0.0.1      <none>        443/TCP        37m   <none>
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#

image.png

image.png


参考

Windows 上のコンテナーに関するドキュメント
https://docs.microsoft.com/ja-jp/virtualization/windowscontainers/

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

kubernetesのWORKERノードをWindows Serverで構築

何となく、構築してみたかっただけです。
適当です。

2020/03/30 00:50現在
なんかnssmのサイト落ちてる?


0 構築環境

・ノード構成

ノード種類 ホスト名 OS IPアドレス サブネットマスク 備考
MASTER VM200001 CentOS 7.7 192.168.1.221 24
WORKER VM200002 Windows Server 2019 Standard 192.168.1.222 24 ServerCore、英語版、評価版

・kubernetesネットワーク

ネットワーク種類 ネットワーク サブネットマスク
POD CIDER 10.244.0.0 16
SERVICE CIDER 10.0.0.0 16

・hosts
/etc/hosts,C:\Windows\System32\drivers\etc\hostsに以下を登録

192.168.1.221 VM200001
192.168.1.222 VM200002

1 MASTERノードの構築

1.1 SELinux無効化

# sed -i -e 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
# setenforce 0

1.2 SWAP無効化

# sed -i -e '/swap/d' /etc/fstab
# swapoff -a

1.3 カーネルパラメタ設定

# cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

# sysctl --system

1.4 FireWall無効化

# systemctl disable firewalld
# systemctl stop firewalld

1.5 yumリポジトリ登録

$ cat > /etc/yum.repos.d/add.repo << EOF
[docker-ce-stable]
name=Docker CE Stable
baseurl=https://download.docker.com/linux/centos/7/x86_64/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg

[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
EOF

1.6 Docker、kubernetesのインストール

# yum install yum-utils device-mapper-persistent-data lvm2 nfs-utils rpcbind wget -y
# yum install docker-ce kubelet kubeadm kubectl -y

1.7 DockerのCgroup設定

# mkdir /etc/docker/
# echo {\"exec-opts\":[\"native.cgroupdriver=systemd\"]} > /etc/docker/daemon.json

1.8 各種サービス起動設定

# systemctl enable docker
# systemctl restart docker

# systemctl enable kubelet
# systemctl restart kubelet

1.9 初期化

# kubeadm init --pod-network-cidr=10.244.0.0/16 --service-cidr=10.0.0.0/16 

1.10 MASTERノードでもPODが動くようにする。

※今回はLinuxのWORKERノードは作らない

# kubectl taint nodes --all node-role.kubernetes.io/master-

1.11 CNI(flannel)のマニュフェストの修正

# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# vi kube-flannel.yml

・修正箇所1

  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }

        ↓

  cni-conf.json: |
    {
      "name": "vxlan0", ★変更箇所
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }

・修正箇所2

  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }

        ↓

  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan", ★変更箇所
        "VNI" : 4096,    ★変更箇所
        "Port": 4789     ★変更箇所
      }
    }

・修正箇所3

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-amd64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:


        ↓

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds-amd64
  namespace: kube-system
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      nodeSelector:                 ★追加箇所
        kubernetes.io/os: linux     ★追加箇所
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:

1.12 CNI(flannel)のインストール

# kubectl apply -f kube-flannel.yml

1.13 CNI(flannel)の不要なDaemonSetを削除

# kubectl -n kube-system delete ds \
kube-flannel-ds-arm \
kube-flannel-ds-arm64 \
kube-flannel-ds-ppc64le \
kube-flannel-ds-s390x

2 Windows WORKERノードの構築

※PowerShellで実施する。

2.1 インストールディレクトリ作成

mkdir c:\k

2.2 バイナリプログラムおよびインストールスクリプトを設置

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
wget https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/windows/amd64/kubectl.exe -o c:\k\kubectl.exe
wget https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/windows/amd64/kubelet.exe -o c:\k\kubelet.exe
wget https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/windows/amd64/kube-proxy.exe -o c:\k\kube-proxy.exe
wget https://github.com/coreos/flannel/releases/download/v0.12.0/flanneld.exe -o c:\k\flanneld.exe
wget https://github.com/Microsoft/SDN/raw/master/Kubernetes/flannel/start.ps1 -o c:\k\start.ps1
wget https://raw.githubusercontent.com/microsoft/SDN/master/Kubernetes/flannel/register-svc.ps1 -o c:\k\register-svc.ps1
wget https://nssm.cc/release/nssm-2.24.zip -o c:\k\nssm-2.24.zip
Expand-Archive -Path c:\k\nssm-2.24.zip -DestinationPath c:\k
copy c:\k\nssm-2.24\win64\nssm.exe c:\k

2.3 configの設置

MASTERノードの/etc/kubernetes/admin.confをc:\k\の下にconfigという名前でコピーする。

2.4 環境変数(PATHとKUBECONFIG)の設定

[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\k", [EnvironmentVariableTarget]::Machine)
[Environment]::SetEnvironmentVariable("KUBECONFIG","C:\k\config", [EnvironmentVariableTarget]::User)

2.5 Dockerのインストール

Install-Module -Name DockerMsftProvider -Repository PSGallery -Force
Install-Package -Name Docker -ProviderName DockerMsftProvider

2.6 再起動

Restart-Computer -Force

2.7 WORKERとして参加

cd c:\k
.\start.ps1 -ManagementIP <WindowsノードIP>  -NetworkMode overlay -ClusterCIDR <POD CIDR> -ServiceCIDR <Service Cider> -KubeDnsServiceIP <kube-DNSのサービスIP> -LogDir c:\k

・例

cd c:\k
.\start.ps1 -ManagementIP 192.168.1.222  -NetworkMode overlay -ClusterCIDR 10.244.0.0/16 -ServiceCIDR 10.0.0.0/16 -KubeDnsServiceIP 10.0.0.10 -LogDir c:\k

2.8 サービス自動起動設定

C:\k\register-svc.ps1 -NetworkMode overlay -ManagementIP <WindowsノードIP> -ClusterCIDR <POD CIDR> -KubeDnsServiceIP <kube-DNSのサービスIP> -LogDir c:\k

・例

C:\k\register-svc.ps1 -NetworkMode overlay -ManagementIP 192.168.1.222 -ClusterCIDR 10.244.0.0/16 -KubeDnsServiceIP 10.0.0.10 -LogDir c:\k

おまけ

[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# kubectl  get node -o wide
NAME       STATUS   ROLES    AGE     VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                                  KERNEL-VERSION                CONTAINER-RUNTIME
vm200001   Ready    master   19m     v1.18.0   192.168.1.221   <none>        CentOS Linux 7 (Core)                     3.10.0-1062.18.1.el7.x86_64   docker://19.3.8
vm200002   Ready    <none>   2m49s   v1.18.0   192.168.1.222   <none>        Windows Server 2019 Standard Evaluation   10.0.17763.1098               docker://19.3.5
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# kubectl  get node --show-labels
NAME       STATUS   ROLES    AGE     VERSION   LABELS
vm200001   Ready    master   20m     v1.18.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=vm200001,kubernetes.io/os=linux,node-role.kubernetes.io/master=
vm200002   Ready    <none>   2m56s   v1.18.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=windows,kubernetes.io/arch=amd64,kubernetes.io/hostname=vm200002,kubernetes.io/os=windows,node.kubernetes.io/windows-build=10.0.17763
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# kubectl  get all -o wide -A
NAMESPACE     NAME                                   READY   STATUS    RESTARTS   AGE   IP              NODE       NOMINATED NODE   READINESS GATES
kube-system   pod/coredns-66bff467f8-svj5g           1/1     Running   0          19m   10.244.0.3      vm200001   <none>           <none>
kube-system   pod/coredns-66bff467f8-vznrl           1/1     Running   0          19m   10.244.0.2      vm200001   <none>           <none>
kube-system   pod/etcd-vm200001                      1/1     Running   0          20m   192.168.1.221   vm200001   <none>           <none>
kube-system   pod/kube-apiserver-vm200001            1/1     Running   0          20m   192.168.1.221   vm200001   <none>           <none>
kube-system   pod/kube-controller-manager-vm200001   1/1     Running   0          20m   192.168.1.221   vm200001   <none>           <none>
kube-system   pod/kube-flannel-ds-amd64-cd7rq        1/1     Running   0          17m   192.168.1.221   vm200001   <none>           <none>
kube-system   pod/kube-proxy-m9qn2                   1/1     Running   0          19m   192.168.1.221   vm200001   <none>           <none>
kube-system   pod/kube-scheduler-vm200001            1/1     Running   0          20m   192.168.1.221   vm200001   <none>           <none>

NAMESPACE     NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE   SELECTOR
default       service/kubernetes   ClusterIP   10.0.0.1     <none>        443/TCP                  20m   <none>
kube-system   service/kube-dns     ClusterIP   10.0.0.10    <none>        53/UDP,53/TCP,9153/TCP   20m   k8s-app=kube-dns

NAMESPACE     NAME                                   DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE   CONTAINERS     IMAGES                                 SELECTOR
kube-system   daemonset.apps/kube-flannel-ds-amd64   1         1         1       1            1           kubernetes.io/os=linux   17m   kube-flannel   quay.io/coreos/flannel:v0.12.0-amd64   app=flannel
kube-system   daemonset.apps/kube-proxy              1         1         1       1            1           kubernetes.io/os=linux   20m   kube-proxy     k8s.gcr.io/kube-proxy:v1.18.0          k8s-app=kube-proxy

NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                     SELECTOR
kube-system   deployment.apps/coredns   2/2     2            2           20m   coredns      k8s.gcr.io/coredns:1.6.7   k8s-app=kube-dns

NAMESPACE     NAME                                 DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                     SELECTOR
kube-system   replicaset.apps/coredns-66bff467f8   2         2         2       19m   coredns      k8s.gcr.io/coredns:1.6.7   k8s-app=kube-dns,pod-template-hash=66bff467f8
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# cat iis.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: iis
  labels:
    app: iis
spec:
  replicas: 2
  selector:
    matchLabels:
      app: iis
  template:
    metadata:
      labels:
        app: iis
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      containers:
      - name: iis
        image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: iis
  labels:
    app: iis
spec:
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
  selector:
    app: iis
  type: NodePort
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# kubectl apply -f iis.yaml
deployment.apps/iis created
service/iis created
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]# kubectl  get deploy,pod,svc -o wide
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                                                                SELECTOR
deployment.apps/iis   2/2     2            2           56s   iis          mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019   app=iis

NAME                       READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
pod/iis-6975cd4f89-28v94   1/1     Running   0          56s   10.244.1.3   vm200002   <none>           <none>
pod/iis-6975cd4f89-dq6jc   1/1     Running   0          56s   10.244.1.4   vm200002   <none>           <none>

NAME                 TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE   SELECTOR
service/iis          NodePort    10.0.119.23   <none>        80:30080/TCP   56s   app=iis
service/kubernetes   ClusterIP   10.0.0.1      <none>        443/TCP        37m   <none>
[root@VM200001 ~]#
[root@VM200001 ~]#
[root@VM200001 ~]#

image.png

image.png


参考

Windows 上のコンテナーに関するドキュメント
https://docs.microsoft.com/ja-jp/virtualization/windowscontainers/

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

Dockerイメージが対応しているプラットフォーム(OS、CPUアーキテクチャ)を調べる

2行まとめ

  • Docker、Docker Hubはマルチプラットフォーム(OS、CPUアーキテクチャ)に対応しています。
  • DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect <イメージ名>でDockerイメージが対応しているプラットフォームを確認できます。

1. 概要

 Docker、Docker Hubがマルチプラットフォーム(OS、CPUアーキテクチャ)に対応して久しいです。Dockerをインストールし、Dockerイメージさえ対応していれば、どのOS、どのCPUアーキテクチャでもdocker run hello-worldのようにDockerコンテナを起動できます。

 場合によっては、Dockerイメージが対応しているプラットフォームを確認したいこともあるでしょう。結論から言えば、以下のコマンドで確認できます。

DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect <イメージ名>

2. 環境

 動作を確認した環境は以下の通りです。

mac$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.6
BuildVersion:   18G103

mac$ docker version
Client: Docker Engine - Community
 Version:           19.03.8
 API version:       1.40
 Go version:        go1.12.17
 Git commit:        afacb8b
 Built:             Wed Mar 11 01:21:11 2020
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.8
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.17
  Git commit:       afacb8b
  Built:            Wed Mar 11 01:29:16 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

3. DOCKER_CLI_EXPERIMENTAL環境変数について

 docker manifestコマンドは、Docker CLI v19.03.8の時点では実験的な機能です。そのため、このコマンドを有効化するためには~/.docker/config.json{"experimental": "enabled"}を指定するか、環境変数DOCKER_CLI_EXPERIMENTALenabledを設定する必要があります。

 実験的機能が有効化されていない場合、以下の通りエラーになります。

mac$ docker manifest inspect hello-world:latest
docker manifest inspect is only supported on a Docker cli with experimental cli features enabled

4. 実行例

docker manifest inspectの実行例をいくつか示します。対応しているプラットフォームが出力されていることが確認できます。

4.1. hello-world:latest

mac$ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect hello-world:latest
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 524,
         "digest": "sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 525,
         "digest": "sha256:e5785cb0c62cebbed4965129bae371f0589cadd6d84798fb58c2c5f9e237efd9",
         "platform": {
            "architecture": "arm",
            "os": "linux",
            "variant": "v5"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 525,
         "digest": "sha256:50b8560ad574c779908da71f7ce370c0a2471c098d44d1c8f6b513c5a55eeeb1",
         "platform": {
            "architecture": "arm",
            "os": "linux",
            "variant": "v7"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 525,
         "digest": "sha256:963612c5503f3f1674f315c67089dee577d8cc6afc18565e0b4183ae355fb343",
         "platform": {
            "architecture": "arm64",
            "os": "linux",
            "variant": "v8"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 527,
         "digest": "sha256:85dc5fbe16214366748ebe9d7cc73bc42d61d19d61fe05f01e317d278c2287ed",
         "platform": {
            "architecture": "386",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 525,
         "digest": "sha256:8aaea2a718a29334caeaf225716284ce29dc17418edba98dbe6dafea5afcda16",
         "platform": {
            "architecture": "ppc64le",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 525,
         "digest": "sha256:577ad4331d4fac91807308da99ecc107dcc6b2254bc4c7166325fd01113bea2a",
         "platform": {
            "architecture": "s390x",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1124,
         "digest": "sha256:468a2702c410d84e275ed28dd0f46353d57d5a17f177aa7c27c2921e9ef9cd0e",
         "platform": {
            "architecture": "amd64",
            "os": "windows",
            "os.version": "10.0.17763.1098"
         }
      }
   ]
}

4.2. ubuntu:18.04

mac$ DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect ubuntu:18.04
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1152,
         "digest": "sha256:e5dd9dbb37df5b731a6688fa49f4003359f6f126958c9c928f937bec69836320",
         "platform": {
            "architecture": "amd64",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1152,
         "digest": "sha256:3b029ac9aa8eb5dffd43bb7326891cf64f9c228b3960cec55a56605d2ae2ad42",
         "platform": {
            "architecture": "arm",
            "os": "linux",
            "variant": "v7"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1152,
         "digest": "sha256:12b9106d200061c8eb2179c984e63cc17d5a4e7a34f6e9ad03360b8efe492e96",
         "platform": {
            "architecture": "arm64",
            "os": "linux",
            "variant": "v8"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1152,
         "digest": "sha256:3e6b4be46d13e13127671a6f2bb848aec9125d6a389d012b2469721b89073b94",
         "platform": {
            "architecture": "386",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1152,
         "digest": "sha256:705518497e5e3dd432fbfecec0ed1658947ff1e5068c266d42868bd3eb4a5a59",
         "platform": {
            "architecture": "ppc64le",
            "os": "linux"
         }
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 1152,
         "digest": "sha256:fbbc16efb3db29132a98651f0499467fbb4cea315d57aaf13397a2c2e68a09d0",
         "platform": {
            "architecture": "s390x",
            "os": "linux"
         }
      }
   ]
}

5. 最後に

 ARM64(AArch64)が勢いを増す今日この頃、マルチアーキテクチャ対応のDockerイメージが充実してくることを願っています!

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

Docker-machineに関して(インストール)

Docker-machineに関して

備忘録として書きます。
今回は簡易的です。

本日、docker-machine --versionとターミナルに入力して
versionを確認しようとしたら

$ docker-machine version

failed MSpanList_Insert 0x2707000 0x2e039a1c174 0x0 0x0
fatal error: MSpanList_Insert

runtime stack:
runtime.throw(0x16e41e0, 0x10)
    /usr/local/go/src/runtime/panic.go:530 +0x90 fp=0x7ffeefbff3e0 sp=0x7ffeefbff3c8
runtime.(*mSpanList).insert(0x22a0ca8, 0x2707000)
....
(この下にもっとありましたが、省略)

上記エラーが出て、数時間謎のまま。。。

ですが、https://blog.fkoji.com/2020/01231607.html
を参考にして解決しました。

どうやら、バージョン 2.2.0.0 から Docker Machine は Docker Desktop に含まれなくなった
との記載があったので、書いてある通りに

$ rm /usr/local/bin/docker-machine
$ curl -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-`uname -s`-`uname -m` >/usr/local/bin/docker-machine && \
  chmod +x /usr/local/bin/docker-machine

を実行したところ、docker-machineのversionが確認できました。

$ docker-machine version
docker-machine version 0.16.2, build bd45ab13

参考文献(参考記事)

https://blog.fkoji.com/2020/01231607.html

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

Node.js(express+ejs)のWebアプリサンプルをDocker上で動かす

はじめに

  • Node.jsをDockerで起動し、適当なWeb画面を表示させるところまでをやります
  • Node.jsでのサンプルはAkinari Tsugoさんの記事を参考に実装しました

やったこと

  • Node.js(express + ejs)の環境をdockerで構築する
  • express + ejsを使用したWebアプリサンプルを作成し、docker上で起動させる

使用するフレームワークについて

expressとは

  • Node.jsでWebアプリを開発する際に使用するフレームワーク
  • 画面遷移とかWebアプリ開発に必要な諸々をサポートする機能あり
  • expressの公式はこちら

ejsとは

  • JavaScriptでHTMLを作成できるテンプレート言語
  • JavaでいうところのJSPに相当する
  • ejsの公式はこちら

node.jsをdockerで構築する

Dockerfileの作成

  • 鉄板のalpineを選択
  • express、ejsのみをnpmで投入
FROM node:alpine

RUN npm install express
RUN npm install ejs

# 作業ディレクトリへ移動
WORKDIR /app

# 3000番ポートを公開
EXPOSE 3000

docker-compose.ymlの作成

  • volumesの設定など、何かとdocker-composeにしておいた方がいいのでdocker-compose.ymlを作成
  • tty: trueとしておくことで、コンテナをずっと起動状態にできる
  • build: .でDockerfileの位置を指定
  • volumes:の指定で、コンテナ内の/appをホスト側にもマウント
version: '3'
services:
  app:
    build: .
    tty: true
    container_name: node-sample01
    volumes:
      - ./app:/app
    ports:
      - "8080:3000"

Webアプリサンプル

ディレクトリ構成

  • ディレクトリ全体構成は以下の通り
app/
 ├ public/
 │ └ 静的なファイル群
 ├ routes
 │ └ index.js
 ├ views
 │ └ index.ejs
 └ app.js
Dockerfile
docker-compose.yml

app.js

var express = require('express');
var app = express();

// テンプレートエンジンをEJSに設定
app.set('views', './views');
app.set('view engine', 'ejs');

// public配下の静的ファイルは無条件に公開
app.use('/public', express.static('public'));

// URLと処理をマッピング
app.use('/', require('./routes/index.js'));

// ポート3000で起動
app.listen(3000);

// アプリケーション開始時のログ
console.log('Server running at http://localhost:3000');

index.js

var express = require('express');
var router = express.Router();

// デフォルトルーティング
router.get('/', function (request, response) {
    // パラメータに値を設定、設定したパラメータはejs内で参照可能となる
    response.render('index', { title: 'NodeSample01', message: 'Hello Node.js' });
});

module.exports = router;

index.ejs

  • index.jsで設定したtitlemessageをejs内で参照
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><%= title %></title>
    <link rel="stylesheet" href="/public/bootstrap/bootstrap.css" />
    <link rel="stylesheet" href="/public/css/index.css" />
    <script type="text/javascript" src="/public/jquery/jquery.js"></script>
    <script type="text/javascript" src="/public/bootstrap/bootstrap.js"></script>
    <script type="text/javascript" src="/public/js/index.js"></script>
  </head>
  <body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">Hello Project</a>
        </div>
      </div>
    </nav>

    <div class="container">
      <div class="starter-template">
        <p><%= message %></p>
        <p><img id="img" src="/public/images/drum.jpg" class="img-thumbnail"></p>
      </div>
    </div> 
  </body>
</html>

起動方法

  • docker-compose upにてコンテナを起動したら、以下でコンテナにログイン
docker exec -it node-sample01 /bin/ash
  • コンテナ内でNode.jsを起動
node app.js

サンプル画面の表示

  • http://localhost:8080で以下画面が表示される NodeSample01.png
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Dockerやりたい!と思ったらプロキシにボコボコにされた。

0.なぜDocker?

興味はあったのですが、なかなか手が出せていませんでした。
そんななか社内で検証をやってみる機会があったので今回学んだ内容を備忘録にしておこうと思います。
まあ、ほとんどの失敗が社内Proxyの壁なんですけどね… 

1.まずはサクっとDockerインストールのつもりが…

こちら2つを参考にさせていただきました。
Docker入門(第二回)~Dockerセットアップ、コンテナ起動~
Docker超入門①〜Dockerってなに?〜【初心者向け】

社内プロキシがあることは知っていたのでdockerのインストールは
yum.confに情報を記載してインストールに成功していました。

ですが、docker pullにはdockerのプロキシ認証設定が必要らしく、
こちら を参考に/etc/systemd/system/docker.service.dに認証情報を記入
おかげさまで無事docker pullできました。

2.Dockerfileにも必要!proxy設定

dockerfileを作成していて、さあ、buildしようと思ったら盛大にエラーが発生。
そんな時にはdockerfile自体にproxy設定をしておかなければいけないみたいです。
参考は(https://maku77.github.io/docker/proxy.html)

qiita.rb
ENV http_proxy http://proxy.example.com:8888/

(ずっと RUN export http_proxy http://proxy.example.com:8888/ とかふざけたことしていたから繋がらなかった…)
ちゃんとRUNやENVといったDockerfileの書き方も学んでおくべきでした。

3.さあ、立ち上がったサーバをブラウザから確認しよう!と思ったら

データサイエンスのためのPython入門①〜DockerでJupyter Labを使う〜
dockerfileの練習にこちらを参考にさせて頂いていたのですが、localhost:8888につながらない。
dockerfileの社内proxyは通ったし、docker statusで調べてみてもサーバは動いている。
はい?ってなりましたが、よくよく考えると私、VMware ESXiで仮想マシンを立てて動かしていたのです。
なのでlocalhostを自分の仮想マシンのIPアドレスにしなければいけませんでした。
参考は[https://ichizaki.com/en/81/]

4.やってみて

社内proxyがあったり、仮想マシンだったり、環境が違えば参考通りにいかないものです。
それでこそ成長できると信じて社内検証がんばります!
:

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

AWS Lambda で実行できるコマンドを作成する環境を作ってみた

いったい何の役に立つねんシリーズ。技術の無駄遣い担当の平野です。いや、今回の役に立つはず。

AWS Lambda で Python や Node のスクリプトを書いていると、「あー、この Linux コマンド使えたら便利なのに」と思うときが時々あります。

ということで、Lambda 用に簡単にコマンドを作成、取り出しできる Docker コンテナを作ってみました。

github:
https://github.com/qualitiaco/build-pack

dockerhub:
https://hub.docker.com/r/qualitiaco/lambda-build-pack

今回は、これの解説と使い方を説明したいと思います。

AWS Lambda の実行環境

AWS Lambda で動作しているのと同様の Docker Image が AWS から公開されています。

github:
https://github.com/lambci/docker-lambda

dockerhub:
https://hub.docker.com/u/lambci

今回は、この dockerhub にある、lambci/lambda-base-2 を使ってビルドしてみました。

Build 環境と実行環境

lambci/lambda-base-2 のコンテナイメージには、latest タグと、build タグが存在します。
latest の方が、実際の runtime 環境のベースになるもののようで、lambda-base-2:latest に対して Python や NodeJS の環境が追加された物が lambda の実行環境になる、というようなイメージです。
実際、こちらには yum も gcc も実行時に必要なさそうなものは入っていません。
本物の AWS Lambda では Python や Node が必要とするライブラリも入っていますので、完全に同じというわけではありません。

一方、biuld タグの方は、yum や git など開発に必要なものがいくつかインストールされています。

AWS Lambda で動作するバイナリファイルとライブラリの取り出し方法

基本的には lambda-base-2:build の環境上でコンパイルしてできたバイナリファイルを AWS Lambda に持って行って動かせばいいのですが、実行ファイルだけを持って行っても、必要なライブラリが Lambda 環境にない場合があります。
リンクされているものを全部持って行くと、これも大げさで、あまり現実的ではありません。

そこで、lambda-base-2:build で作成した実行ファイルを lambda-base-2:latest の環境で検証し、足りないライブラリのみを抽出することで、AWS Lambda 上で必要十分なライブラリを用意することにしました。
Python が必要とするライプラリ等、多少重複する物もありますが、今回はどの Lambda でも動作する物を目指します。
どうしても小さくしたければ、lambci には Python 用のイメージ等もありますので、Dockerfile を変更することで簡単に実現できると思います。

環境の作成

Docker の stage build を使って、lambda-base-2:latest の/usr/lib64 以下を lambda-base-2:build の/lib64.runtime に保存し、比較できるようにしました。

詳細な動作は、ソースをご覧ください。
https://github.com/qualitiaco/build-pack

AWS Lambda で動作するバイナリファイルとライブラリの取り出し

作成した Docker イメージを使用してみます。

今回は、シンプルだけどシンプルじゃなさそうな、dig コマンドを AWS Lambda で実行してみたいと思います。

必要なコマンドの取り出すスクリプト作成

まず、以下のような Shell Script を src/build.sh として作成します。

  • AWS Lambda で実行したいコマンドを yum で作成するか、または、コンパイルします
  • コマンドを\${OUTPUT_PATH}にコピーします
src/build.sh
#!/bin/sh

OUTPUT_PATH=${OUTPUT_PATH:-output}

yum install -y bind-utils
cp -a /usr/bin/dig ${OUTPUT_PATH}

コマンドとライブラリの取り出し

docker を実行して、コマンドとライブラリを取り出します。

docker run -v $(pwd)/output:/output -v $(pwd)/src:/src -it --rm qualitiaco/lambda-build-pack

取り出したライブラリの確認

dig コマンドと、必要そうなライブラリが抽出されました。

.
|-- output
|   |-- dig
|   `-- lib
|       |-- libGeoIP.so.1 -> libGeoIP.so.1.5.0
|       |-- libGeoIP.so.1.5.0
|       |-- libbind9.so.160 -> libbind9.so.160.0.8
|       |-- libbind9.so.160.0.8
|       |-- libdns.so.1102 -> libdns.so.1102.1.2
|       |-- libdns.so.1102.1.2
|       |-- libidn.so.11 -> libidn.so.11.6.11
|       |-- libidn.so.11.6.11
|       |-- libisc.so.169 -> libisc.so.169.0.3
|       |-- libisc.so.169.0.3
|       |-- libisccfg.so.160 -> libisccfg.so.160.2.1
|       |-- libisccfg.so.160.2.1
|       |-- liblwres.so.160 -> liblwres.so.160.0.2
|       |-- liblwres.so.160.0.2
|       |-- liblzma.so.5 -> liblzma.so.5.2.2
|       |-- liblzma.so.5.2.2
|       |-- libxml2.so.2 -> libxml2.so.2.9.1
|       `-- libxml2.so.2.9.1
`-- src
    `-- build.sh

AWS Lambda で動かすコマンドの作成

今回は output/lambda_function.py として output の中に直接作成します。

output/lambda_function.py
import subprocess


def lambda_handler(event, context):
    subprocess.call(["./dig", "qiita.com"])

qiita.com の DNS を引くだけのシンプルなプログラムです。
直下の lib/の下は気にしなくても参照されるようで、LD_LIBRARY_PATH 等の設定も必要ありませんでした。
もし、動作しなければ、そこを疑ってください。

zip で固める

lambda にアップロードするために、zip で固めます。
シンボリックリンクを含みますので、「-y」オプションを付けるのを忘れないでください。

cd output
zip -9yr ../output.zip *

lambda にアップロードして確認

あらかじめ Python 用の Lambda 関数を作成してからアップロードします。

いい感じです。

lambda1.png

実行してみます。

lambda2.png

ちゃんと、動作しているようです。

おわりに

今回わけあって作成して公開した Docker イメージ、qualitiaco/lambda-build-pack の紹介をしました。
応用した楽しいアイデアがあれば、ぜひお知らせください。
PullReq や間違いの指摘などもお待ちしております。

github:https://github.com/qualitiaco/build-pack
dockerhub: https://hub.docker.com/r/qualitiaco/lambda-build-pack

*本記事は @qualitia_cdevの中の一人、@hirachanさんに作成して頂きました。

*いったい何の役に立つねんシリーズ

  1. CentOS で/lib64 のシンボリックリンク先を/usr/lib64 から/my-lib64 に変更したい
  2. AWS Lambda で実行できるコマンドを作成する環境を作ってみた
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dockerでカラムの変更ができないエラー

docker-composeで自作アプリのテーブルをいじっていたらこんなエラーに遭遇しました。

$ docker-compose run --rm app rails g migration rename_star_column_to_topics
Starting sakelog_db_1 ... done
Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"rails\": executable file not found in $PATH": unknown

再起動してみたり、appをdbに書き換えてみたり、色々試しましたが解決できず。

でも解決法は意外と単純でした。

$ docker-compose run --rm app bundle exec rails g migration rename_star_column_to_topics
Starting sakelog_db_1 ... done
      invoke  active_record
      create    db/migrate/20200330013557_rename_star_column_to_topics.rb

railsの前に bundle execを付け足したらよかったんですね。

今までよくわからずに放置して使ってたbundle exec。
今回のエラーを経て改めて検索し直したら、
bundle execをつけずに実行すると、グローバルにインストールされているgemが動くのに対し、
bundle execをつけて実行するとプロジェクト内にあるgemが動くんだそうで。

なるほど、dockerのことはまだよくわかって無いですが、なんとな〜く理解できてきた気がするぞ。

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

CloudMapperをDockerで動かして、AWSのネットワーク構成を可視化しよう。

こんにちは。

AWSいいですよね。
でも、AWSって一つ一つのサービスがしっかり役割分担されているので、いざ一つのシステムとしてネットワーク構成図がどうなっているのかをみようとすると頭がこんがらがっちゃうんです、私。

そんなときCloudMapperにお世話になりたくなります。READMEを読んでいただければですが、現在のAWSのネットワーク構成図を自動生成してくれるやつです。
ただ、何度かチャレンジしているのですが、いつも何かが足りなくてうまく動かないんです、私。最近は何をやるにもDockerでやっちゃっているのでローカル環境もあんまり汚したくなくて...

CloudMapper公式や他の方々もDockerで動くようにソースコードを公開していたりするんですが、なんでかうまく行かなかったりしたので、今回は自分でDockerfileから作ってみようという記事です。

前提

  • AWSアカウントがあること
  • SecurityAuditViewOnlyAccessの権限をもったIAM(以下、IAM_A)があること(よくわからなければ最悪AdministratorAccessの権限でもひとまずOK)
  • IAM_AのアクセスキーIDとシークレットアクセスキーを払い出していること
  • DockerおよびDocker Composeが利用可能であること

CloudMapperが動くDockerイメージを作る

CloudMapperはPythonで動いているのでPythonのDockerイメージをベースに必要なパッケージをインストールしたDockerイメージを作るためのDockerfileを作成します。

Dockerfile
FROM python:latest

RUN git clone https://github.com/duo-labs/cloudmapper.git && \
    pip install \
      jinja2 \
      netaddr \
      parliament \
      policyuniverse \
      pyjq \ 
      pyyaml && \
    apt update -qq && \
    apt install -q -y vim

最初にgitCloudMapperのソースコードをダウンロードしています。

PythonのDockerイメージを使うと、READMEで必要と言われているパッケージはほとんど入っているようで、実際にCloudMapperを実行しようとしたときに追加で必要になったパッケージをpipコマンドで追加してあげています。

vimはコンテナ内でファイルを編集したい時などに使いたいのでインストール。

次にDocker Compose用のファイルを作ります。

docker-compose.yml
version: "3"

services:
  cm:
    build: .
    working_dir: /cloudmapper
    ports:
      - 8000:8000
    environment:
      - AWS_ACCESS_KEY_ID=[IAM_AのアクセスキーID]
      - AWS_SECRET_ACCESS_KEY=[IAM_Aのシークレットアクセスキー]
    volumes:
      - ./config.json:/cloudmapper/config.json

working_dir

cloudmappergit cloneしているのでDockerイメージの中には/cloudmapperというディレクトリができています。そこをワーキングディレクトリにします。

ports

CloudMapperのViewを表示するポートです。8000がデフォルトなのでそれに合わせて。

environment

ここでIAM_AのアクセスキーIDとシークレットアクセスキーを環境変数に定義します。

volumes

この後書きますが、CloudMapperが情報を取得しにいくAWS AccountのAccount IDを設定するconfig.jsonが必要になるのでローカルのファイルをマウントするようにしています。コンテナの中で書き換えてもいいのですが、毎回書くのは面倒なのでローカルのファイルと同期しておきます。

config.jsonも作っておきましょう。CloudMapperのソースコードにあるconfig.json.demoを参考に以下のように書きます。

config.json
{ 
  "accounts": [
    {
      "id": "[AWSのAccount ID]",
      "name": "[識別名]",
      "default": true
    }
  ],
  "cidrs": {}
}

AWSのAccount IDはコンソールの「マイアカウント」から確認できます。(12桁の数字。もしどこ見ればいいの?って方はこの記事の最後のAppendix2のやり方とかみてみてください。)

ここまで準備ができたらDockerイメージをビルドします。

$ docker-compose build

CloudMapperをDockerコンテナで動かす

ビルドが完了したらコンテナの中でCloudMapperを動かしてみましょう!

まずコンテナを起動させて中に入ります。

$ docker-compose run --service-ports cm bash

--service-portsオプションはdocker-compose runコマンドを実行するときにdocker-compose.ymlの中のportsを適用させるためのオプションです。これがないとローカル環境からhttp://localhost経由でCloudMapperのWebページにアクセスできないので注意です。

コンテナの中に入ったらAWSからデータを収集します。先ほどのconfig.jsonaccounts.namesampleという名前をつけたことにします。

# python cloudmappler.py collect

このコマンドでAWSアカウントのネットワーク構成情報をめっちゃ取得してくれます。
全てのリージョンの全ての情報を取ってきているみたいで結構時間がかかります。
毎回これをやるのはきついんで何回もコンテナを消して立ち上げ直してとやる場合は、/cloudmapper/account-data/をマウントしておけばこの工程を省けます。(このディレクトリにデータを生成している工程なので)

情報を取得できたらレポートを作成します。

# python cloudmapper.py prepare
# python cloudmapper.py report --accounts sample

最後に収集してレポートを作ったサイトを公開します。

# python cloudmapper.py webserver --public

さぁ!これでhttp://localhost:8000にアクセスしてみましょう!

image.png
こちらは公式のイメージですが、こんな感じのページが表示されるはずです!

まとめ

CloudMapperをDockerで動かすことができました!
READMEを見ると色々とパッケージのインストールなどが大変そうだな(実際つまづいた)という感じだったのですが、Dockerですっきりと動かせました〜。

Appendix1: CloudMapperのヘルプ

READMEだけだとあんまりわからなかったのですが、cloudmapper.pyはhelp機能がついてました。

# python cloudmapper.py -h

CloudMapper 2.8.2
usage: cloudmapper.py [access_check|amis|api_endpoints|audit|collect|configure|find_admins|find_unused|iam_report|prepare|public|report|sg_ips|stats|weboftrust|webserver] [...]
  access_check: [proof-of-concept] Check who has access to a resource
  amis: Cross-reference EC2 instances with AMI information
  api_endpoints: [Deprecated] Map API Gateway end-points
  audit: Identify potential issues such as public S3 buckets
  collect: Run AWS API calls to collect data from the account
  configure: Add and remove items from the config file
  find_admins: Find privileged users and roles in accounts
  find_unused: Find unused resources in accounts
  iam_report: Create IAM report
  prepare: Generate network connection information file
  public: Find publicly exposed services and their ports
  report: Create report
  sg_ips: Find all IPs are that are given trusted access via Security Groups
  stats: Print counts of resources for accounts
  weboftrust: Create Web Of Trust diagram for accounts
  webserver: Run a webserver to display network or web of trust map
# python cloudmapper.py collect -h

usage: cloudmapper.py [-h] [--config CONFIG] [--account ACCOUNT_NAME]
                      [--profile PROFILE_NAME] [--clean]
                      [--max-attempts MAX_ATTEMPTS]

optional arguments:
  -h, --help            show this help message and exit
  --config CONFIG       Config file name
  --account ACCOUNT_NAME
                        Account to collect from
  --profile PROFILE_NAME
                        AWS profile name
  --clean               Remove any existing data for the account before
                        gathering
  --max-attempts MAX_ATTEMPTS
                        Override Botocore config max_attempts (default 4)

チェックしてみると使い方が良くわかるかもしれないです!(webserver--publicオプションはこれで見つけられた...)

Appendix2: AWS Account IDを調べる

AWS Account IDはAWS CLIで取得することもできます。
この記事で作成したコンテナではAWS CLIを使えないのでDockerfileを少し更新します。

Dockerfile
  FROM python:latest

  RUN git clone https://github.com/duo-labs/cloudmapper.git && \
      pip install \
+       awscli \
        jinja2 \
        netaddr \
        parliament \
        policyuniverse \
        pyjq \ 
        pyyaml && \
      apt update -qq && \
      apt install -q -y vim

ビルドしてDockerコンテナの中で以下のコマンドを実行します。

# aws sts get-caller-identity
{
  "UserId": "XXXXXXXXXXXXXXXXXXXX",
  "Account": "123456789012",
  "Arn": "arn:aws:iam::123456789012:user/xxxxxxxxxx"
}

ここのAccountに表示されている数字列がAccount IDです。
参考:【小ネタ】AWS CLIでAWS Account IDが取れるようになりました! | Developers.IO

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

Windows10 HomeでDocker Desktop for Windows Edgeをゲットしてみる(WSL2も導入してみよ)

Dockerとやらを使いたくなった自分。
そして!2020年3月2日windows10 homeユーザー(つまり私)でも非正式運用版ですがDocker Desktopが使えるようになったらしい。(今まではDocker Toolbox、Docker公式ページにはレガシーと記載。挫けない)
そのための条件は、

  • WSL2をパソコンに導入していること

なんやそれはってところから、
Docker Desktop for Windows Edgeダウンロードまでしてみたざっと備忘録

WSLの設定

WSL2の前にまずWSL自体の設定をしておこう。
※ちなみにWSL(Windows Subsystem for Linux)を設定することでWindowsでLinuxを使えるようになるらしい
PowerShellを管理者として開いて

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

で再起動
※ちなみにコントロールパネルからも設定できるらしい
こちらの記事の[WSLと仮想化機能の有効化]を参考

再起動後WSLが有効になったか確認してみよ

PowerShell
Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

wsl.png
StateがEnabledになっていたら?

ディストリビューション選び

Microsofe Storeでwslで検索
私は意味もなくUbuntu18.04LTSにしました(違いはわからん)
コメント 2020-03-30 012337.png

インストール完了したらUbuntuのターミナルから、ユーザ名とパスワード設定(忘れちゃだめよ)

WSL2へアップデート

MicrosoftのWSL2のインストラクションページ
にもあるように

WSL 2 is only available in Windows 10 builds 18917 or higher

WSL2をゲットするには、OSビルドなるものをが18917以上でなくてはだめであります。
今の自分のOSビルドの確認

PowerShell
winver

winver.jpg
足りない?
そこでWindows Insider Program(多分Microsoftの発展に協力する系?特に支障なし)となるものに登録すればこれを18917以上にできます。

PCの設定→更新とセキリュティ→左の一番下Windows Insider Programでスローかファストを登録(自分はスローですがDocker使えてます)
insider.png

その後ひたすらWindows Updateをしましょう(長かった…)
その後また

PowerShell
winver

すると、
upload_ver.jpg
なったー!!よしこれでWSL2にできる

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
ここでWSL→WSL2へをアップデート

Ubuntu18.04LTSのVERSIONを2にする

PowerShell
>wsl -l -v

でubutuのバージョンを見てみると1のままです。
これ2にします。

PowerShell
wsl --set-version Ubuntu-18.04 2

確認~

PowerShell
>wsl -l -v
NAME                   STATE           VERSION
Ubuntu-18.04           Stopped         2

よしこれでWSL2導入まで完了ー次はDockerインストールじゃー
その前にUbuntuを最新版にしておこう

Ubuntu
sudo apt update -y && sudo apt dist-upgrade -y

Dockerをゲット

Docker Desktop for Windows Edge Release notes

Windows 10 Home users can now use Docker Desktop through the experimental WSL 2 support.

ここにも記載があります、知ってるよDockerくん
↑のサイトのDocker Desktop Community 2.2.2.0のDownloadボタンからダウンロードしよう

終わったらなぜかデスクトップにあるDockerアイコンをクリックしても何の反応もないので、
docker.png
この下のナンチャラバーからクジラマークをクリック
settings→ResoucesからUbuntu18.04のスライドバーを有効にする
Docker2.png

docker ps

と試しに打ってみよう
docker3.png

こんな画面が出たらdocker コマンド効いてる=Welcome Docker Worldってことかしら:heart_eyes:

以上です!おつかれちゃんでした

余談

今のところDockerの起動具合は半々ぐらいで、たまに起動せずー再起動してみたら起動したって感じ。学習用だから無問題
あーDocker詳しくなりターいターイ

Ubuntuの日本語設定
sudo apt install locales
sudo apt install -y language-pack-ja
sudo update-locale LANG=ja_JP.UTF-8
man(マニュアル)日本語版導入
sudo apt install -y man manpages-ja manpages-ja-dev
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerでWordpressコンテナを立ち上げる

概要

本書ではUbuntuにDockerをインストールし、Wordpressコンテナを起動します。

0.動作環境

  • OS : Ubuntu 16.04
  • 仮想環境 : Hyper-V (Windows10 Pro)

1. Dockerのインストール

  1. リポジトリ一覧を更新する

    > sudo apt-get update
    
  2. docker-ceに必要なパッケージをインストールする

    > sudo apt-get install \
      apt-transport-https \
      ca-certificates \
      curl \
      gnupg-agent \
      software-properties-common
    
  3. docker-ceの暗号鍵を取得する

    > curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    
  4. docker-ceのリポジトリを取得する

    > sudo add-apt-repository \
     "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
     $(lsb_release -cs) \
    
  5. リポジトリ一覧を更新する

    > sudo apt-get update
    
  6. docker-ceをインストールする

    > sudo apt-get install docker-ce docker-ce-cli containerd.io
    
  7. Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sockのエラーが表示された場合、dockerグループにユーザを追加する

    > sudo gpasswd -a [ユーザー名] docker
    > id [ユーザー名]
      dockerグループに所属していることを確認
    > exit
      再ログイン
    
  8. dockerを起動する

    > sudo systemctl start docker
    
  9. dockerを自動起動するように設定する

    >  sudo systemctl enable docker
    
  10. dockerの起動状態を確認する

    > sudo systemctl status docker
    

2. Wordpressの起動

  1. mysqlのdockerイメージを取得する

    > docker pull mysql:5
    
  2. wordpressのdockerイメージを取得する

    > docker pull wordpress
    
  3. dockerのネットワークを作成する

    > docker network create [ネットワーク名]
    
  4. mysqlのdockerコンテナを作成する

    > docker run --name [mysqlのdockerコンテナ名] --net [ネットワーク名] -e MYSQL_ROOT_PASSWORD=[mysqlのパスワード] -d mysql:5
    
  5. mysqlのdockerコンテナが作成されたことを確認する

    > docker ps
    
  6. wordpressのdockerコンテナを作成する

    > docker run --name [wordpressのdockerコンテナ名] --net [ネットワーク名] -e WORDPRESS_DB_HOST=[mysqlのdockerコンテナ名] -e WORDPRESS_DB_PASSWORD=[mysqlのパスワード] -p 8080:80 -d wordpress
    
  7. wordpressのdockerコンテナが作成されたことを確認する

    > docker ps
    
  8. WEBブラウザを開き、http://[IPアドレス]:8080に接続する

  9. wordpressの初期設定画面が表示されたことを確認する
    docker_037.JPG

  10. wordpressの初期設定後、管理画面やwordpressで作成したサイトが表示されたことを確認する
    docker_051.JPG
    docker_058.JPG

最後に

Dockerを利用することでWordpressをすぐに立ち上げることができます。これによりWordpressの検証環境をすぐに用意することができます。

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