- 投稿日:2020-05-21T23:57:15+09:00
Dockerコンテナ内のRで図をプロットする
はじめに
R の
tidyverse
パッケージ群を含む docker イメージとしてrocker/tidyverse
が有名です。ただし、これらのイメージは(恐らく)RStudio を使用する前提で作成されています。私は RStudio を使用しておらず、以下のような経緯もあってコンテナ内の R でプロットを表示させる方法を調べてみました。
- R のパッケージのバージョンを固定したい
tidyverse
パッケージ群のインストールは時間がかかるrockerjp/tidyverse
を使用すれば、自分で大量のパッケージをインストールしなくてすむため便利だろう- コンテナ内の R でプロットを表示させたい
参考URL
これらのリンク先の設定と比較すると項目が少ないですが、恐らく使用した R のコンテナ内で設定されているからと思います。
実例その1:
r-base
イメージの場合まず、R の公式イメージである
r-base
で試しました。試行錯誤した後の結果を示します。設定項目
-u docker
- これを指定しないとプロットが表示されませんでした
-e DISPLAY=$DISPLAY
および-v /tmp/.X11-unix:/tmp/.X11-unix
- 参考記事を参照
docker run --rm -it \ -u docker \ -e DISPLAY=$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix \ r-base Rboxplot(iris$Sepal.Length ~ iris$Species)プロットされました。
実例その2:
rockerjp/tidyverse
イメージの場合とりあえずチャレンジ
先程と異なり、ユーザー名は
rstudio
とします(元々のイメージ内で指定されています)。docker run --rm -it \ -u rstudio \ -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix \ rockerjp/tidyverse R> boxplot(iris$Sepal.Length ~ iris$Species) Error in (function (display = "", width, height, pointsize, gamma, bg, : X11 module cannot be loaded In addition: Warning message: In grSoftVersion() : unable to load shared object '/usr/local/lib/R/modules//R_X11.so': libXt.so.6: cannot open shared object file: No such file or directoryこのようにエラーが出てしまい、プロットされませんでした。
libXt.so.6
が不足しているようです。
libxt6
パッケージを追加したイメージの場合そこで、以下のような Docker ファイルを用意しました。
FROM rockerjp/tidyverse:latest RUN apt-get update \ && apt-get install -y libxt6ビルドします。イメージ名は仮に
mytidyverse
とします。docker build -t mytidyverse .docker run --rm -it \ -u rstudio \ -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix \ mytidyverse Rboxplot(iris$Sepal.Length ~ iris$Species)図は省略しますが今度はプロットされました。
tidyverse
がインストールされているのでggplot2
でも試してみます。library(ggplot2) ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot()これもプロットされました。
おわりに
rockerjp/tidyverse
のコンテナ内で R を起動して、プロットすることに成功しました。これで自分でtidyverse
パッケージ群をインストールせずに済みます。公式イメージで
libxt6
パッケージを追加してもらえれたら今回のような手間は減るのですが……(他力本願)
- 投稿日:2020-05-21T22:35:17+09:00
Goで書いたサーバーをCloud Runで動かす
Goで書いたサーバーをデプロイする先を探していて、Google App Engine(SE)やArukas、Herokuなどを試してきたが、今回は新たにCloud Runを試したのでその手順をここに記しておく。
前提
- Google Cloud Platformのアカウント(請求先の登録が必要)
- Google Cloud Platformのプロジェクト作成
- Google Cloud SDKのインストール
- Dockerがインストールされていること+起動していること
この辺りの説明は省略。
Cloud Runの有効化(初回のみ)
Cloud consoleでCloud Runのページを開き、Cloud Runを有効にしておく。フルマネージド環境で使う場合は「CLOUD RUNの使用を開始する」を選べばOK。
検証用サーバープログラムの準備
リクエストがくるとHello worldを返すだけのシンプルなHTTPサーバーを用意した。
Cloud Runで動かすコンテナは、環境変数PORT
で指定されたポートでListenできるようにしておかなければいけないので、Listenするポート番号を引数で指定できるようにしている。(環境変数を直接参照しても良いが)https://cloud.google.com/run/docs/reference/container-contract?hl=ja#port
main.gopackage main import ( "fmt" "net/http" "os" "strconv" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello world\n") } func main() { port, _ := strconv.Atoi(os.Args[1]) fmt.Printf("Starting server at Port %d", port) http.HandleFunc("/", handler) http.ListenAndServe(fmt.Sprintf(":%d", port), nil) }動作確認のため、ローカル3000版ポート指定で起動してみる。
go run main.go 3000別のShellからcurlでリクエストを送ってみて、Hello worldが返ってきたらOK。サーバーを停止する。
curl http://localhost:3000/Dockerイメージの作成
DockerfileFROM golang:latest as builder ENV CGO_ENABLED=0 ENV GOOS=linux ENV GOARCH=amd64 WORKDIR /go/src/github.com/yokoe/cloudrunexp COPY . . RUN go build main.go # runtime image FROM alpine COPY --from=builder /go/src/github.com/yokoe/cloudrunexp /app CMD /app/main $PORTalpineをベースに、最小限のサーバーのイメージを作る。サーバー起動時の引数に環境変数
$PORT
を渡すことで、$PORT
番号のポートでListenするようにする。docker build -t cloudrunexp .ビルドに失敗する場合はDockerが起動しているか確認する。
docker run -e "PORT=3000" -p 3000:3000 -t cloudrunexp動作確認用に
$PORT
=3000で、サーバーを起動してみる。ポートフォワーディングをして、http://localhost:3000/
でコンテナ内のサーバーにアクセスし、レスポンスが返ってくることを確認する。curl http://localhost:3000/Container RegistryへのPush
作成したイメージをGoogle Container Registry(GCR)にPushする。
Container Registry APIの有効化(初回のみ)
Container Registry APIを有効にしたことがない場合は、コンソールから有効にしておく。
Docker認証ヘルパーの有効化(初回のみ)
gcloud auth login gcloud auth configure-dockergcloudで認証し、Docker認証ヘルパーを有効にすることで、
docker push
コマンドでGCRにイメージをPushできるようになる。https://cloud.google.com/container-registry/docs/advanced-authentication?hl=ja
タグをつける
docker tag cloudrunexp gcr.io/go-server-exp/cloudrunexp:firstbuildアップデートしていく時に、どのイメージがどのビルドかわかるようにタグをつけておく。今回は最初なので
firstbuild
というタグをつけた。GCRにイメージをPushする
docker push gcr.io/go-server-exp/cloudrunexp:firstbuild
docker push
コマンドを使って、firstbuild
タグのついたイメージをGCRにPushする。Pushに成功すると、Cloud consoleのContainer Registry画面でPushされたイメージのリストを確認できる。
サービスの作成
Container Registryでイメージの確認
Container Registryのイメージのメニューから「Cloud Runへデプロイ」を選ぶと、Cloud Runのサービス作成画面が開く。
サービスの作成
自分で管理しているGKE上で動かしたいわけではないので、フルマネージドを選ぶ。また、パブリック(誰でもアクセスできる)なウェブサーバーとして動かしたいので「未認証の呼び出しを許可」を選択。
コンテナイメージが、先ほどContainer Registryで選んだイメージになっていることを確認して「作成」する。
作成完了すると、早速利用可能となり、自動生成されたURLが表示される。アクセスしてみて、Hello worldが表示されれば成功。カスタムドメインを割り当てたい場合は、URL横のinfoボタンから、「MANAGE CUSTOM DOMAINS」に進み、マッピングを追加すれば簡単に利用できた。
なお、今回はサービスの設定、デプロイはWeb UI経由で行ったがCI経由、Terraformなどを使っても操作できる。
感想
GKEでDeploymentやService、Ingressの設定をするのに比べると非常に楽だった。カスタムドメインの割当ても簡単だったし、ちょっとしたHTTPサーバーを立ち上げるのには結構良さそう。
HerokuのDocker Deployも同様に簡単で良かったが、GCSやCloudSQLなどGCP系のサービスと組み合わせる場合はCloud Runも良さそう。
参考
https://cloud.google.com/container-registry/docs/quickstart?hl=ja
- 投稿日:2020-05-21T20:51:06+09:00
Laravel勉強 その1 サーバのセットアップ、DockerでのLaravel環境構築
目的
- 勉強のため、Laravel 7.xの公式ドキュメントを読み解いていく。
- 今回はそのための準備として、Dockerを使用して環境を構築する。
EC2の構築~セットアップ
今回は勉強なので、AWSの無料枠を利用する。
インスタンスタイプはt2.micro、OSはAmazon Linux2で作成。参考
EC2(Amazon-Linux-2)にNginxを入れてブラウザで確認するまで2018冬 [画像で解説] Nginx編
rootでのPWログインをON
セキュリティ的には微妙なところもあるかもしれないが、いちいちsudo打たなければいけないのも面倒なので。。。
rootのPWを設定
# sudo su # passwdsshの設定ファイル変更
# vi /etc/ssh/sshd_configPermitRootLogin yes PasswordAuthentication yessshd再起動
# systemctl restart sshdec2-userの無効化
セキュリティ的に消した方がいいよ、という記事を見つけた。確かに。
# userdel ec2-userEC2を日本時間と日本語に対応させる
# yum update -y # timedatectl set-timezone Asia/Tokyo # localectl set-locale LANG=ja_JP.UTF-8 # localectl set-keymap jp106パッケージを自動更新させる
yum-cronのインストール
# yum install yum-cron -yyum-cronとは?
yum-cron パッケージは、アップデートを自動的に確認し、ダウンロードし、適用するための便利な方法を提供します。
パッケージをインストールするとすぐに yum-cron パッケージの cron ジョブが有効になり、特別な設定は必要ありません。通常の日次 cron ジョブの実行時に、このジョブが実行します。yum-cronを編集
# vi /etc/yum/yum-cron.conf/etc/yum/yum-cron.confapply_updates = yescronの自動起動をON
# systemctl status yum-cron # systemctl start yum-cron # systemctl enable yum-cronLaravel開発環境構築
参考
Docker × PHP7.3 × Laravel環境作ってみた
Docker・Docker Composeのインストール
Dockerインストール # amazon-linux-extras install docker Dockerサービス起動 # systemctl start docker.service サービスの起動確認 # systemctl status docker Dockerの自動起動設定 # systemctl enable docker 試しにDockerコマンド実行 # docker infoDocker Composeインストール # curl -L https://github.com/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose # chmod +x /usr/local/bin/docker-compose Docker Composeのインストールを確認 # docker-compose --version docker-compose version 1.25.4, build 8d51620aディレクトリ作成
以下の構成を想定しています。
project
├ docker-compose.yml
├ docker
│ ├ db
│ │ ├ data
│ │ ├ sql
│ │ └ my.cnf
│ ├ nginx
│ │ ├ default.conf
│ ├ php
│ │ ├ php.ini
│ │ └ Dockerfile
└ serverとのこと。(太字はディレクトリ)
# cd /var # mkdir project # mkdir project/docker project/server # mkdir project/docker/{php,nginx,db} # ll -d `find ./project` drwxr-xr-x 4 root root 34 May 21 19:08 ./project drwxr-xr-x 4 root root 30 May 21 19:08 ./project/docker drwxr-xr-x 2 root root 6 May 21 19:08 ./project/docker/db drwxr-xr-x 2 root root 6 May 21 19:08 ./project/docker/nginx drwxr-xr-x 2 root root 6 May 21 19:08 ./project/docker/php drwxr-xr-x 2 root root 6 May 21 19:08 ./project/server別にvarじゃなくてもいいけど、なんとなくvarで。
swap領域の有効化
過去の経験上、これをやらないとこける。
# /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB) copied, 13.537 s, 79.3 MB/s # /sbin/mkswap /var/swap.1 mkswap: /var/swap.1: insecure permissions 0644, 0600 suggested. Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes) no label, UUID=8be78b55-de6d-4ed4-9f9a-7a48f3dc30ae # /sbin/swapon /var/swap.1 swapon: /var/swap.1: insecure permissions 0644, 0600 suggested.docker-compose.yml作成
docker-composer.ymlversion: '3' services: php: container_name: php build: ./docker/php volumes: - ./server:/var/www nginx: image: nginx container_name: nginx ports: - 80:80 volumes: - ./server:/var/www - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - php db: image: mysql:5.7 container_name: db environment: MYSQL_ROOT_PASSWORD: ****(パスワードを記載しておく) MYSQL_DATABASE: test_db TZ: 'Asia/Tokyo' command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci volumes: - ./docker/db/data:/var/lib/mysql - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf - ./docker/db/sql:/docker-entrypoint-initdb.d ports: - 3306:3306Dockerfile作成
phpコンテナの構築時に、以下のDockerfileを使用する。
DockerfileFROM php:7.3-fpm COPY php.ini /usr/local/etc/php/ RUN apt-get update \ && apt-get install -y zlib1g-dev libzip-dev mariadb-client \ && docker-php-ext-install zip pdo_mysql #Composer install COPY --from=composer:latest /usr/bin/composer /usr/bin/composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin WORKDIR /var/www RUN composer global require "laravel/installer"各行の処理については、Dockerfileリファレンスを参照。
php.ini作成
phpの設定ファイル。
php.ini[Date] date.timezone = "Asia/Tokyo" [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"default.conf作成
nginxの設定ファイル。
default.confserver { listen 80; root /var/www/public; index index.php; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }php.ini作成
mysqlの設定ファイル。
my.cnf[mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci [client] default-character-set=utf8mb4Laravelプロジェクト作成
docker起動 # docker-compose up -d (略) Creating php ... done Creating db-host ... done Creating nginx ... done 起動の確認 # docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9fdcb0da6745 nginx "nginx -g 'daemon of…" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp nginx e1394b974a68 project_php "docker-php-entrypoi…" 3 minutes ago Up 2 minutes 9000/tcp php cbc7a83db192 mysql:5.7 "docker-entrypoint.s…" 3 minutes ago Up 2 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp db phpコンテナに入る # docker-compose exec php bash root@eec8f5f9ebe2:/var/www# Laravelプロジェクト作成 # laravel new (略) Application ready! Build something amazing.Laravelまわりのディレクトリのパーミッション変更
# sudo chmod 2775 /var/project/server # find /var/project/server -type d -exec sudo chmod 2775 {} + # find /var/project/server -type f -exec sudo chmod 0664 {} + # sudo chmod -R 777 /var/project/server/storage/ # sudo chmod -R 777 /var/project/server/bootstrap/cacheセキュリティグループの編集
今回環境を作成したEC2について、PORT:80からのインバウンド通信を許可するように編集する。
動作確認
動作確認をして、Laravelの白い画面が出てくればOK。
- 投稿日:2020-05-21T20:44:27+09:00
100日後に1人前になる新人エンジニア(1日目)
100日後に1人前になる新人エンジニア(1日目)
どうもこんばんは今日が1日目になります。
ちなみに昨日から始まっていますのでよかったらこちらからどうぞ
100日後に1人前になる新人エンジニア(0日目)今日やったこと
本日より本格的に業務に取り組みました。
さっそくissueに取りかかり頑張るぞ...
と思ってましたが、Dockerの使い方がわからん...
ということでまずそこで悪戦苦闘した前半。その後Railsでフォームの改修に取り組みましたが...
プロジェクトのフォルダ多すぎて何が何だかわからんぞという始まり方でした。
少しずつ理解を深めていきアーキテクチャとかクラスごとの繋がりも分かってきたら
面白いんだろうなあって思っています。Dockerあれこれ
今日はここからでした。いくつか使ったコマンドを
dockerコマンドdocker-compose build #サービス(web,DB)のビルドを実行 docker-compose up #コンテナを作成して、起動 docker-compose down #コンテナを停止し、そのコンテナとネットワークを削除 docker-compose ps #コンテナの一覧を表示 コンテナの状態がわかるよきっと他にもいっぱいあるので少しずつキャパを増やして行こう。
あれ..ファイルの変更時に情報が反映されないぞ...そんな時は
dockerコマンドdocker-compose build #サービス(web,DB)のビルドを実行 docker-compose up -d #デタッチド・モード:バックグラウンドでコンテナを実行し、新しいコンテナ名を表示なるほどねー。これで大丈夫みたい。
なんで情報の変更を反映時はバックグラウンドで起動するんだろ?
あと変更した時にこれを行わないで画面リロードで良い時もあったけど何が違うんだ?
本日の疑問点です。明日までに解決します。そしてコツコツとドキュメントを読んでいきます
--追記--
docker-compose.yml or ./docker/rails/Dockerfile に書かれている内容に変更があったら 再度buildする必要あり。疑問点は無事解決Rails あれこれ
プロジェクトがとても大きい...
どんなroutesになってるのかこんがらがっちまったよ・僕が知っていた方法...
config/routes見れば全部書いてあるだろ!!
って思ってたけど大変そうでした。よって以下の方法で確認$ rails routes他にも色々とあるようでして
Tipsを先輩社員の方からいただきました。・localhost:3000/rails/infoで
すげーroutes全部出てきたしちゃんと検索もできる!!・docker-compose upから
ログが出力されているのでどのコントローラを使って
画面が遷移しているのかが確認できるよありがたきアドバイスでした。
デバッグって
コードの途中にraiseを入れると...
アプリを立ち上げるとエラー画面になっているけど
その画面でコンソール?を打ち込むと各情報が得られました。すげー例えばform controllerのコードの途中にraiseを入れておいて
アプリを立ち上げ→エラー画面からコンソールを入力
params と入力してみるとどんな値が送られているのかちゃんと確認できました。
明日から使います。ありがたや...他にもやり方は色々とあるはずなのでそこは確認してみます。
formに関してはまだ完成していないので続きは明日に回します。
今日のさいごに
今日が連載初日でした。
何事も積み重ねだと思うので一日ひとつづつ。フィルヒースの言葉をいただきます。
Winning is habitualですね1人前のエンジニアになるまであと99日
- 投稿日:2020-05-21T20:20:02+09:00
Docker ToolboxでのWindows10共有フォルダマウント方法 備忘録
Dockerを使用する際、ホスト⇔コンテナ間でファイルを共有したい時の方法になります。
sshよりローカルでいじりたい!という人向け。使用ツール
Docker Toolbox v19.03.1
ホストOS:Windows 10 Home
コンテナOS:CentOS本記事で使用するフォルダ名
ホストOS:
folder_host
Dockerマシン:folder_machine
コンテナOS:folder_container
1.VirtualBoxの共有フォルダを設定する
VirtualBox->対象のDockerマシンの設定->共有フォルダー->追加
ホストOS側の共有させたいフォルダ絶対パスと、Dockerマシンに配置されることになる共有フォルダ名を設定する。ここでは例として、ホストOS側のフォルダ名を
folder_host
、Dockerマシンに配置される共有フォルダ名をfolder_machine
とする
(Dockerマシンに/folder_machine
が作られることになる)2.Dockerマシンを再起動する(大事)
投稿時は記載し忘たが、Dockerマシンに共有フォルダを認識させるために必要。
再起動docker-machine restart default3.マウントを指定してdocker runする
-v Dockerマシンに配置される共有フォルダパス:コンテナで使用したいフォルダパス
例として、コンテナで使用したいフォルダ名をfolder_container
とする。run例docker run -d -v /folder_machine:/folder_container centos /sbin/initあとはrunしたコンテナにexecでアタッチする。
例:docker exec -it <コンテナIDとか名前> /bin/bash
4.ホストOSとコンテナOSでファイルが共有できていることを確認する
ホストOS側のフォルダ
folder_host
と、コンテナOS側のフォルダ:folder_container
が共有される。
テストはecho "test" > /folder_container/test.txt
等雑記
本記事は備忘録になります。
検索すると色々なページが見つかりますが自分の環境でうまくいかず余計なことをしている気がして、
中でどういう動作をしているかわからないので少しでも動きを理解するために書きました。
Docker for Windowsに適したWindows 10がアップデートされるまでしょうがなくDocker Toolboxを使ってる人はどうぞ。
- 投稿日:2020-05-21T19:51:27+09:00
Dockerで構築したLaravel環境に、PHPStormでステップ実行デバッグを仕掛ける
元記事 Windows10 に PHP7+Laravel環境をDockerで構築
← 元元記事 最強のLaravel開発環境をDockerを使って構築する【新編集版】目的
Dockerで構築したLaravel環境で実行されているPHPコードに対して、
JetBrains社の「PHPStorm」からステップ実行デバッグができるようにしたい。ステップ実行デバッグとは
- 今実行されているコードの好きな行で処理を停止させて、その瞬間の変数リストや変数の中身を覗き見する。
- 1行ずつ実行させて、どこでエラー落ちするか追跡する。
といったことができる、例のアレ↓です。
概要
今回、PHP定番デバッグツール xdebug を使用して実現していきます。
(Laravel最新版には他にもイケてるデバッグツールがあると思いますが、諸事情で古いバージョンのLaravelを使用しなければならなかったので)PHPはサーバーサイドプログラミング言語なので、サーバー側に xdebug をインストールしてデバッグ情報を吐き出させるようにしないといけません。
加えて今回は、WindowsやMacの中に構築したDockerコンテナの中でサーバーを動かしているので、ちょっとだけ工夫が必要です。環境
基本的に、冒頭に書いた元記事および、そのさらに元記事に準じます。
今回わたしのほうでは、Windows / Mac 両方で動作確認できました。PHPStorm は最新版ならOKかと思います。
方法
サーバー側作業
PHPサーバーに xdebug インストール&有効化する設定を追記する。
PHPサーバーは今回 Docker で構築されるようになっているので、その設定ファイルをいじります。
2行ほど追記します。docker-laravel\infrastructure\docker\php\Dockerfile・ ・ ・ RUN apt-get update && \ apt-get -y install git libicu-dev libonig-dev libzip-dev unzip locales && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* && \ locale-gen en_US.UTF-8 && \ localedef -f UTF-8 -i en_US en_US.UTF-8 && \ mkdir /var/run/php-fpm && \ docker-php-ext-install intl pdo_mysql mbstring zip bcmath && \ composer config -g process-timeout 3600 && \ composer config -g repos.packagist composer https://packagist.org && \ # ↓↓↓ 追記 ↓↓↓ pecl install xdebug && \ docker-php-ext-enable xdebug && \ # ↑↑↑ 追記 ↑↑↑ composer global require hirak/prestissimo ・ ・ ・PHPサーバーの php.ini に xdebug 設定を追記する。
php.ini には「
host.docker.internal
というマシンからのデバッグ通信要求を受け付けてね」という設定を追加します。「
host.docker.internal
って、そんなアドレスのマシン持ってないぞ…?」
と思うかもですが、ご安心ください。
最近のバージョンの Docker Desktop をお使いであれば、自動でそういう設定をしてくれます。これは Dockerコンテナ から見た Dockerホスト、つまりお手元の Windows や Mac を指し示すようになっています。
(Dockerコンテナの中からlocalhost
とやるとDockerコンテナ自身を指してしまいDockerホストを辿れないので、こういう機能を用意してくれています。)docker-laravel\infrastructure\docker\php\php.ini・ ・ ・ [Assertion] zend.assertions = 1 [mbstring] mbstring.language = Japanese # ↓↓↓ 追記 ↓↓↓ [xdebug] xdebug.idekey="PHPStorm" xdebug.remote_host = "host.docker.internal" xdebug.default_enable = 1 xdebug.remote_autostart = 1 xdebug.remote_connect_back = 0 xdebug.remote_enable = 1 xdebug.remote_handler = "dbgp" xdebug.remote_port = 9000 # ↑↑↑ 追記 ↑↑↑サーバー環境を起動しておく。
これは元記事のまま、コマンド実行するだけです。
初めて実行する場合cd docker-laravel/infrastructure make create-project
すでにcreate-projectを実行したことがある場合cd docker-laravel/infrastructure make remake
コマンドが完了するまでお待ちください。
PHPStorm(クライアント)側作業
PHPStormを起動する。
ここで初めて起動してください。
もしすでに起動してdocker-laravelプロジェクトを開いてしまっていたら、再起動してください。
(Dockerビルド工程でインポートされたPHPライブラリ群がインクルードされていない場合があるので。)PHPStormで docker-laravel プロジェクトを開く。
メインメニューから設定画面を開く。
左メニューから
Languages & Frameworks
→PHP
を開く。画面右側の
+
を押す。ついでに
Include Path
欄に、PHPライブラリ群がずらーっとインクルードされているか念のため確認してください。docker-laravel を選択して
OK
を押す。今回のプロジェクトのルートディレクトリを丸ごとパスに追加します。
左メニューから
Languages & Frameworks
→PHP
→Debug
を開き、xdebug
→Debug port:
9000 にする。最初から 9000 だったらそのままでOKです。
次へ進みましょう。左メニューから
Languages & Frameworks
→PHP
→Servers
を開き+
を押す。以下の設定をして、最後に
Apply
ボタンを押す。
設定項目 値 Name docker-laravel Host localhost Port 9000 Debugger Xdebug User path mappings チェックON 終わったら閉じてOKです。
メインウィンドウ右上の
Add Configuration...
を押す。左ツリー上部の
+
を押してPHP Remote Debug
を選ぶ。以下の設定をして、最後に
Apply
ボタンを押す。
設定項目 値 Name docker-laravel Filter debug connection by IDE key チェックON Server docker-laravel IDE key PHPStorm 終わったら閉じてOKです。
メインウィンドウ右上の
緑色の昆虫
ボタンを押す。そうすると、
緑色の昆虫
ボタンの右のほうに赤い■
ボタンが点灯します。- メインウィンドウ下部にデバッグ情報小窓が展開されます。
これで、デバッグ中の状態になりました。
デバッグをやめるには赤い■
ボタンを押せばOKです。ブラウザでPHPサーバーにアクセスしてみる。
普通なら Laravel のサンプルページが開くはずですが、ずっとアクセス中のように見えます。
実は、デバッガーが割り込んで処理を途中で止めているのです!
デバッグ情報小窓→
Debugger
タブを開く。お、デバッグ情報が来てますね!
ただ、何やらエラーが表示されています。
「サーバーコードと手元のソースファイルが関連付けられていないから追跡できないよ!」と怒られています。
なので、設定してあげましょう。
すぐ下の行に表示されているClick to set up path mappings
を押して下さい。以下の設定をして
OK
を押す。
- この画面、出現当初はすごくウィンドウが小さいので、広げてあげてください。
Use path mappings
にチェックを入れます。- 下部にプロジェクトファイルリストが出てくるので、
File path on server:
に示されているコードに相当するソースファイルを指定してあげます。再度PHPサーバーにアクセスしてみる。
あれ、今度はすんなりWEBページが表示されて終わってしまいました。
でも大丈夫、正常です!ソースコードの該当行にブレークポイントを仕掛けてみる。
このページのソースコードは
index.php
ですね。
ではindex.php
を開いて、停止させてみたい行の冒頭をクリックしてみてください。
赤い●
が点灯します。再々度PHPサーバーにアクセスしてみる。
来ました!
54行目で処理が一時停止され、その瞬間の変数などが丸見えです!次のブレークポイントまで進めるなら
次の行、次の行、と一行ずつ進めていくならといったことも可能です。
長くなってしまいましたが、今回はここまで。
お疲れ様でした
- 投稿日:2020-05-21T19:13:56+09:00
Mac+Vagrant(CentOS7)+Docker+Jenkinsで優勝してみた
大蛇丸が料理をしたら、っていう発想ができるような人間になっていきたい今日この頃です。
目的
- 仮想化の新潮流であるコンテナ技術をDockerを用いて理解したい
- CI/CDツールの環境構築にも使用されているコンテナ技術でJenkinsを構築したい
- できたらPCのローカル環境は綺麗なままにしたい
ターゲット
- コンテナ技術を用いてCI/CDツールの導入を考えている方
- これからDockerを触ってみたい方 ※Dockerの説明は行いません。本記事は環境構築のみです。
参考書籍
Docker/Kubernetes 実践コンテナ開発入門(著者:山田明憲)
設計
当初は参考書籍に記述されているように、Macに直接Dockerをインストールしようとしました。
しかし、Macに直接Dockerを入れてしまうとDockerの複数バージョンを管理するのが難しいです。
また、ローカル環境にDocker資材などが混じり汚れてしまいます。
そこで仮想マシンを用意し、その中にDockerをインストールするようにしました。
これにより仮想マシン単位でDockerのバージョン管理ができます。
また、環境構築をソースコード(Vagrantfile)で管理できるため、2回目以降の構築時間短縮にも繋がります。
構築
仮想マシンの準備
VirtualBoxをインストール
作業環境:ホストOS
仮想化ソフトウェアのVirtualBoxをインストールします。(ホストOSに合わせてpkgをダウンロードしてください。)
※VagrantにはVirtualBoxは含まれていないので別途インストールする必要があります。Vagrantをインストール
作業環境:ホストOS
仮想化ソフトウェアのラッパーツールであるVagrantをインストールします。(ホストOSに合わせてdmgをダウンロードしてください。)
仮想マシンを作成
CentOS7のBoxを追加
作業環境:ホストOS
仮想マシンのBox(イメージファイル)を追加します。
今回は公式から提供されているCentOS7のBoxを追加します。# Vagrantインストール直後 $ vagrant box list There are no installed boxes! Use `vagrant box add` to add some. # CentOS7のBoxを追加 $ vagrant box add centos/7 ==> box: Loading metadata for box 'centos/7' box: URL: https://atlas.hashicorp.com/centos/7 This box can work with multiple providers! The providers that it can work with are listed below. Please review the list and choose the provider you will be working with. 1) hyperv 2) libvirt 3) virtualbox 4) vmware_desktop # 今回はVirtualBoxを使用しているので「3:virtualbox」を選択 Enter your choice: 3 ==> box: Adding box 'centos/7' (v1708.01) for provider: virtualbox box: Downloading: https://vagrantcloud.com/centos/boxes/7/versions/1708.01/providers/virtualbox.box ==> box: Successfully added box 'centos/7' (v1708.01) for 'virtualbox'! # Box追加後 $ vagrant box list centos/7 (virtualbox, 1708.01)初期設定
作業環境:ホストOS
仮想マシン構築に使用するVagrantfileを作成します。
# 今回はカレントディレクトリ直下に「centos7」というVagrantfileを格納するディレクトリを作成 $ mkdir centos7 # 作成したディレクトリの確認 $ ls -latr | grep centos7 drwxr-xr-x 5 ogino staff 160 5 19 16:21 centos7 # 作成したディレクトリに移動 $ cd centos7/ # 初期設定を実行 $ vagrant init centos/7 A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on `vagrantup.com` for more information on using Vagrant. # 初期設定によりVagrantfileが作成されたことを確認 ※他のファイルやディレクトリは後ほど説明します $ ls -latr total 8 drwxr-xr-x 4 ogino staff 128 5 10 15:28 .vagrant drwxr-xr-x 4 ogino staff 128 5 19 15:56 key -rw-r--r-- 1 ogino staff 3010 5 19 16:21 Vagrantfile ←VagrantfileができていればOK drwxr-xr-x 5 ogino staff 160 5 19 16:21 . drwxr-xr-x+ 47 ogino staff 1504 5 20 14:26 .. # 作成したVagrantfileを元に仮想マシンの状態を確認 $ vagrant status Current machine states: default not created (virtualbox) ←まだ仮想マシンは作成されていないのでOK The environment has not yet been created. Run `vagrant up` to create the environment. If a machine is not created, only the default provider will be shown. So if a provider is not listed, then the machine is not created for that environment.仮想マシンの操作
作業環境:ホストOS
Vagrantfileがあるディレクトリ上から仮想マシンを起動させます。
# Vagrantfileがあるディレクトリにいることを確認 $ pwd /Users/ogino/centos7 # Vagrantfileがあることを確認 $ ls -latr Vagrantfile -rw-r--r-- 1 ogino staff 3010 5 19 16:21 Vagrantfile # 仮想マシンを起動 $ vagrant up <中略> ==> default: Machine booted and ready! ←仮想マシンが起動したようなのでOK ==> default: Checking for guest additions in VM... default: No guest additions were detected on the base box for this VM! Guest default: additions are required for forwarded ports, shared folders, host only default: networking, and more. If SSH fails on this machine, please install default: the guest additions and repackage the box to continue. default: default: This is not an error message; everything may continue to work properly, default: in which case you may ignore this message. ==> default: Configuring and enabling network interfaces... ==> default: Rsyncing folder: /Users/ogino/centos7/ => /vagrant ==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision` ==> default: flag to force provisioning. Provisioners marked to run always will still run. # 仮想マシンの状態確認 vagrant status Current machine states: default running (virtualbox) ←起動中になっているのでOK The VM is running. To stop this VM, you can run `vagrant halt` to shut it down forcefully, or you can run `vagrant suspend` to simply suspend the virtual machine. In either case, to restart it again, simply run `vagrant up`.次は仮想マシンにSSH接続でログインしてみます。
# 仮想マシンにSSH接続でログイン $ vagrant ssh Last login: Tue May 19 06:04:50 2020 from 10.0.2.2 # 仮想マシンのホスト名 $hostname localhost.localdomain # ログインユーザは「vagrant」 $ who vagrant pts/0 2020-05-20 05:48 (10.0.2.2) # sudoコマンドも使用可能 $ sudo hostname localhost.localdomain # 仮想マシンからログアウト # exit ←Macなら「control + d」でもログアウトできます ログアウト Connection to 127.0.0.1 closed.最後に仮想マシンを停止させます。
# 仮想マシンを停止 vagrant halt ==> default: Attempting graceful shutdown of VM... # 仮想マシンが停止していることを確認 vagrant status Current machine states: default poweroff (virtualbox) ←電源が落ちているのでOK The VM is powered off. To restart the VM, simply run `vagrant up`VirtualBoxのアプリケーションからも作成した仮想マシンを確認することができます。
(今回はVagrantを使用するので、GUIではなくCUIベースで環境構築を進めていきます。)
仮想マシンのネットワーク設定
作業環境:ホストOS
Vagrantで作成した仮想マシンのネットワークは、
デフォルトだとホストオンリーアダプタといってホストとゲストの間でしか通信ができません。それだと何かと不便なので、内部ネットワークを利用してホストとゲスト、ゲスト間同士の通信ができる
プライベートネットワークを設定しておきます。# 仮想マシンにログイン $ vagrant ssh Last login: Tue May 19 06:04:50 2020 from 10.0.2.2 # net-tools系のコマンドは標準でインストールされないためyumを使ってインストール # 全て「y:Yes」で回答してOK $ sudo yum install net-tools # ホストオンリーアダプタ時のipアドレス(et0)を確認 $ ifconfig # 仮想マシンからログアウト $ exit logout Connection to 127.0.0.1 closed. # 仮想マシンを停止させる(Vagrantfileの修正内容を反映させるには再起動が必要なため) $ vagrant halt ==> default: Attempting graceful shutdown of VM... # Vagrantfileを修正 $ vi Vagrantfile ※修正内容は、以下の行のコメントマーク(#)を外します # config.vm.network "forwarded_port", guest: 80, host: 8080 # config.vm.network "private_network", ip: "192.168.33.10" # 仮想マシンを起動 $ vagrant up # 仮想マシンにSSH接続 $ vagrant ssh Last login: Wed May 20 06:27:38 2020 from 10.0.2.2 # プライベートネットワーク時のipアドレス(et1)を確認 $ ifconfig仮想マシンのユーザ設定
今回の環境構成だと、VagrantユーザのUID(1000)とJenkinsユーザのUID(1000)が衝突してしまう問題があります。
それを回避するためにVagrantユーザのUIDを別の値に変更します。
出典:公式 jenkins 配布コンテナは UID 1000 の jenkins ユーザーで動作する
参考:出来るだけ最短で Jenkins 環境を試したい(jenkins container + docker CE + CentOS7 + vagrant)新規ユーザの作成
作業環境:仮想マシン
# 仮想マシンのPrivate IPアドレスをメモする # ※新規ユーザで仮想マシンにアクセスする際はVagrantを経由しないためIPアドレスを指定する必要があります $ ip addr show eth1 # 「USERNAME1」変数に追加するユーザ名を設定 $ USERNAME1=ok2 # ユーザを追加 $ sudo useradd -m -u 1001 -g vagrant $USERNAME1 # 追加したユーザに切り替える $ sudo su - $USERNAME1 # カレントディレクトリが新規ユーザのホームディレクトリに切り替わっていることを確認 $ pwd /home/ok2 # 「.ssh」ディレクトリを作成 $ mkdir .ssh # 「.ssh」ディレクトリのアクセス権限を変更 $ chmod 700 .ssh/ # 新規ユーザからログアウト $ exit logout # 新規ユーザのパスワードを設定 $ sudo passwd $USERNAME1 Changing password for user ok2. New password: Retype new password: passwd: all authentication tokens updated successfully. # Vagrantユーザからログアウト $ exit logout Connection to 127.0.0.1 closed.鍵の作成
作業環境:ホストOS
# 公開鍵/秘密鍵を作成 $ ssh-keygen -t rsa -f ./id_rsa # 公開鍵の中身をメモする ※仮想マシン側にも鍵追加を行うため $ cat id_rsa.pub鍵の追加
作業環境:仮想マシン
# Vagrantユーザで仮想マシンにログイン vagrant ssh Last login: Wed May 20 09:03:38 2020 from 10.0.2.2 # 「USERNAME1」に追加ユーザ名を設定 $ USERNAME1=ok2 # 追加ユーザに切り替え $ sudo su - $USERNAME1 Last login: Wed May 20 09:05:30 UTC 2020 on pts/0 # 「.ssh」ディレクトリに移動 $ cd .ssh # 認証鍵リストにホストOSで作成した公開鍵を追加 $ vi authorized_keys # 認証鍵リストを確認 $ ls -latr total 4 drwx------. 3 ok2 vagrant 95 May 20 09:06 .. -rw-r--r--. 1 ok2 vagrant 403 May 20 09:13 authorized_keys drwx------. 2 ok2 vagrant 29 May 20 09:13 . # 認証鍵リストのアクセス権限を変更 $ chmod 600 authorized_keys # 認証鍵リストのアクセス権限が変更されていることを確認 $ ls -latr total 4 drwx------. 3 ok2 vagrant 95 May 20 09:06 .. -rw-------. 1 ok2 vagrant 403 May 20 09:13 authorized_keys drwx------. 2 ok2 vagrant 29 May 20 09:13 . # 追加ユーザからログアウト $ exit logout # Vagrantユーザからログアウト $ exit logout Connection to 127.0.0.1 closed.新規ユーザでのログイン
作業環境:ホストOS
# 「USERNAME1」変数に追加ユーザを設定 $ USERNAME1=ok2 # SSH接続で仮想マシン(Private IPアドレス)に接続 # ※以下は、known_hostsに過去のアクセスログが残っていたためエラー $ssh -i ./id_rsa $USERNAME1@192.168.33.10 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ <中略> Host key verification failed. # known_hosts内の情報を全て削除 $ vi /Users/ogino/.ssh/known_hosts # 再度SSH接続 $ ssh -i ./id_rsa $USERNAME1@192.168.33.10ユーザUIDの変更
作業環境:仮想マシン
# Vagrantが使用しているIDを確認(1000が指定されていること) $ sudo id vagrant uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant) # VagrantのUIDを1002に変更 $ sudo usermod -u 1002 vagrant # Vagrantが使用しているIDを確認(1002が指定されていること) $ sudo id vagrant uid=1002(vagrant) gid=1000(vagrant) groups=1000(vagrant) # ユーザ情報からも1000が使用されていないことを確認 $ grep 1000 /etc/passwd vagrant:x:1002:1000:vagrant:/home/vagrant:/bin/bash ok2:x:1001:1000::/home/ok2:/bin/bash # 追加ユーザからログアウト exit上記の対応をすることで、Jenkins導入後にUIDの衝突を回避することができます。
Dockerの準備
Dockerのインストール
作業環境:仮想マシン
コンテナ仮想化ソフトウェアのDockerを仮想マシンにインストールします。
# yumを最新にアップデート $ sudo yum update ←全て「y:Yes」で回答 # Dockerのインストール $ sudo yum -y install docker # Dockerデーモンの起動 $ sudo systemctl start docker # Dockerのブート時自動起動を設定 $ sudo systemctl enable docker Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service. # Dockerのバージョンを確認 $ docker --version Docker version 1.13.1, build 64e9980/1.13.1 ←無事にインストールできていることを確認Dockerはインストール時点ではroot権限(sudoをつけて実行)がないと権限エラーが発生します。
毎度sudo
をつけるのは手間なので、実行ユーザをDockerグループに所属させます。# Vagrantユーザで仮想マシンにログイン $ vagrant ssh Last login: Wed May 20 13:18:33 2020 from 10.0.2.2 # インストール時点ではsudoをつけて実行しないと権限エラーが発生 $ docker images Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.26/images/json: dial unix /var/run/docker.sock: connect: permission denied # Dockerグループを作成 $ sudo groupadd docker # 現行ユーザをdockerグループに所属 $ sudo gpasswd -a $USER docker ユーザ vagrant をグループ docker に追加 # dockerデーモンを再起動 $ sudo systemctl restart docker # ログアウト $ exit logout Connection to 192.168.33.10 closed. # 再ログイン $ vagrant ssh Last login: Wed May 20 13:18:33 2020 from 10.0.2.2 # Dockerコマンドがsudoなしで実行できることを確認 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZEDocker Composeのインストール
作業環境:仮想マシン
複数のコンテナを使う Docker アプリケーションを定義・実行するツールのDocker Composeをインストールします。
インストールするバージョンについては、公式ガイド を確認して、最新バージョン のものを入れるようにしてください。# 2020/05/20時点の安定版は1.25.5 sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 638 100 638 0 0 1641 0 --:--:-- --:--:-- --:--:-- 1640 100 16.7M 100 16.7M 0 0 785k 0 0:00:21 0:00:21 --:--:-- 1201k # ダウンロードしたバイナリに、実行可能権限を付与 $ sudo chmod +x /usr/local/bin/docker-compose # Docker Composeのインストールができたことを確認 $ docker-compose --version docker-compose version 1.25.5, build 8a1c60f6参考:Install Docker Compose on CentOS 7
Jenkinsの準備
Jenkins(マスタ)コンテナの作成
docker-compose.ymlの作成
作業環境:仮想マシン
docker-compose.ymlは、Dockerイメージをビルドするための情報やコンテナ起動するための情報、
使用するDockerネットワークなどを記載する設定ファイルです。
※書籍にあるjenkinsci
イメージを使用するとプラグインのインストールでエラーになるので、今回はjenkins
イメージを使用します。docker-compose.ymlversion: "3" services: master: container_name: master image: jenkins/jenkins ports: - 8080:8080 volumes: - ./jenkins_home:/var/jenkins_home:z今回はこれをDocker実行環境(仮想マシン内)に作成していきます。
# 上記のdocker-compose.ymlをコピーして貼り付け $ vi docker-compose.ymlJenkinsの起動
作業環境:仮想マシン
# コンテナ起動 $ docker-compose up <中略> master | touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied master | Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions? master exited with code 1 # マウントしようとしたディレクトリで権限エラーが発生したため、所有ユーザをJenkins(1000)に変更 $ sudo chown 1000 -R jenkins_home/ # 再度コンテナ起動 $ docker-compose up Starting master ... done Attaching to master <中略> master | master | ************************************************************* master | ************************************************************* master | ************************************************************* master | master | Jenkins initial setup is required. An admin user has been created and a password generated. master | Please use the following password to proceed to installation: master | master | <ここに初回ログイン時に求められるパスワードが表示> ←初期設定時に使用するのでメモに残しておきます master | master | This may also be found at: /var/jenkins_home/secrets/initialAdminPassword master | master | ************************************************************* master | ************************************************************* master | ************************************************************* master | <中略> master | 2020-05-20 13:51:53.388+0000 [id=19] INFO hudson.WebAppMain$3#run: Jenkins is fully up and running ←起動完了初期設定
作業環境:ホストOS
Jenkins(マスタ)コンテナを起動後に、http://<仮想マシンのPrivate IPアドレス>:8080/ にアクセスします。
コンテナ起動時にコンソールに表示されていたパスワードを入力します。
Install suggested plugins を選択しプラグインをインストールします。
ユーザ情報を登録します。
JenkinsのURLを決められますが、デフォルトのまま次に進みます。
セットアップ内容に不備がなければ Start using Jenkin を選択します。
JenkinsのTop画面が表示されれば成功です。
Jenkins(スレーブ)コンテナの作成
Jenkins(マスタ)コンテナのSSH鍵の作成
作業環境:コンテナ
Jenkinsのマスタ(コンテナ)からスレーブ(コンテナ)へ疎通が必要なため、
接続用に先ほど作成したマスタのSSH鍵を作成します。# マスタコンテナ起動 ※オプションに -d をつけることでバックグラウンドで実行されます $ docker-compose up -d Starting master ... done # コンテナ内でSSH鍵を作成 $ docker container exec -it master ssh-keygen -t rsa -C ""作業環境:仮想マシン
コンテナのディレクトリを仮想マシン上にマウントしているので、仮想マシンから作成した公開鍵を確認します。
# 公開鍵を確認 $ sudo cat jenkins_home/.ssh/id_rsa.pub <表示された公開鍵をメモ> # 秘密鍵を確認 $ sudo cat jenkins_home/.ssh/id_rsa <表示された秘密鍵をメモ>docker-compose.ymlの作成
作業環境:仮想マシン
docker-compose.ymlversion: "3" services: master: container_name: master image: jenkins/jenkins ports: - 8080:8080 volumes: - ./jenkins_home:/var/jenkins_home:z links: - slave01 slave01: container_name: slave01 image: jenkinsci/ssh-slave environment: - JENKINS_SLAVE_SSH_PUBKEY=<上記でメモした公開鍵>Jenkins(マスタ)コンテナ作成時に使用したymlファイルに追記します。
# 上記のdocker-compose.ymlをコピーして貼り付け $ vi docker-compose.ymlJenkinsの起動
作業環境:仮想マシン
# コンテナ起動 $ docker-compose up -d # 起動中のコンテナを確認 $ docker-compose ps Name Command State Ports ------------------------------------------------------------------------------------ master /sbin/tini -- /usr/local/b ... Up 50000/tcp, 0.0.0.0:8080->8080/tcp slave01 setup-sshd Up 22/tcp ←今回追加したスレーブコンテナがあればOK追加設定
作業環境:ホストOS
JenkinsのTopページから「Jenkinsの管理 - ノードの管理 - 新規ノード作成」を選択します。
ノード名には「Slave01」、Permanet Agentにはチェックをつけて、OKを選択します。
詳細設定の各欄に必要な情報を入力します。
ノード名:slave01
リモートFSルート:/home/jenkins
起動方法:SSH経由〜
ホスト:slave01
認証情報:後ほど作成した認証情報
Host Key Verification Strategy:Non verifying〜
高度な設定 - Javaのパス:/usr/local/openjdk-8/bin/java
認証情報の追加ボタンを押して、認証情報を追加します。
種類:SSH〜
ID:slave01
秘密鍵:Jenkins(マスタ)コンテナのSSH秘密鍵
パスフレーズ:SSH鍵作成時に設定したパスワード
ノード一覧画面にmasterとslave01が表示されていれば環境構築終了です。
最後に
今回はJenkinsの環境構築のみにフォーカスしています。
CI/CDやJenkinsをさらに理解したい場合は、
構築した環境を元に以下のJenkinsの入門チュートリアルなどを実践してみると良いかと思います。
参考:サルでもわかるJenkins入門〜自動テスト環境を構築しよう
- 投稿日:2020-05-21T18:53:09+09:00
alpineでbazelをビルドする
背景
- alpineでbazelを使いたい
- デフォルトのapkリポジトリに存在しない1
- Bazeliskはalpineのサポートをしていない
- コンパイルに時間がかかるのでビルド済みdockerイメージとして使えるようにしたい
コンパイルのためのdocker image
./compile.shでコンパイルしているgitリポジトリがあったので、参考に一部拝借・抜粋してdockerfileにしました。
bazel-buildFROM python:3.8-alpine3.11 ARG bazel_ver=3.1.0 ENV JAVA_HOME=/usr/lib/jvm/default-jvm \ PATH="$JAVA_HOME/bin:${PATH}" \ BAZEL_VERSION=3.1.0 RUN apk add --virtual .bazel_build --no-cache g++ gcc \ bash zip unzip cmake make linux-headers openjdk8 && \ wget -q "https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-dist.zip" \ -O bazel.zip && \ mkdir "bazel-${BAZEL_VERSION}" && \ unzip -qd "bazel-${BAZEL_VERSION}" bazel.zip && \ rm bazel.zip && \ cd "bazel-${BAZEL_VERSION}" && \ sed -i -e 's/-classpath/-J-Xmx6096m -J-Xms128m -classpath/g' \ scripts/bootstrap/compile.sh && \ EXTRA_BAZEL_ARGS=--host_javabase=@local_jdk//:jdk ./compile.sh && \ cp -p output/bazel /usr/bin/ && \ cd ../ && rm -rf "bazel-${BAZEL_VERSION}" && \ bazel version && \ apk del --purge .bazel_buildあとは
docker build
してpushするだけ注意点
ソースからコンパイルを行う場合は、openjdk11対応していないのでopenjdk8を入れる
sed
で置き換えている箇所はJavaのヒープ・メモリのサイズを指定している。指定しないとメモリを食い尽くして途中で落ちるケースがある。The system is out of resources. Consult the following stack trace for details. java.lang.OutOfMemoryError: Java heap space参考文献
apkのtestingリポジトリに存在するが、導入したいモジュールがこのバージョンに対応してないため使用しない ↩
- 投稿日:2020-05-21T17:28:27+09:00
GitLab Runner+docker でCIがうまく動かないときの対処法メモTips
環境
iMacでgitlab-runner+dockerを動かしてandroidアプリのCI環境を作っています。
gitlab-runnerは社内ランからしかアクセスできない設定で、CI環境の入っているiMacは社内にあります。うまく動かない事例とそれぞれの対処法
使っていないイメージが多すぎて悪さをしている。
apt-get updateやapt-get installしているところで
Error writing to output file - write (28: No space left on device) [IP: xxx.xxx.xxx.xxx xx]やら
W: Some index files failed to download. They have been ignored, or old ones used instead.やら
Reading package lists... Building dependency tree... Reading state information... Package file is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source E: Unable to locate package lib32stdc++6 E: Couldn't find any package by regex 'lib32stdc++6' E: Unable to locate package lib32z1 E: Unable to locate package aapt E: Package 'file' has no installation candidateやら出た時
→
dockerの動いているマシンのターミナルからdocker image pruneで使っていないイメージを消してやる。
WiFiなど、ネットワーク環境が悪い
サブモジュールなどを手動でgit cloneするところで
$ git clone http://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.xxxxx/hoge/hugahuga.git hugahuga Cloning into 'hugahuga'... error: RPC failed; curl 18 transfer closed with outstanding read data remaining fatal: the remote end hung up unexpectedly fatal: early EOF fatal: index-pack failedと出た時
→
dockerの動いているマシンのWiFiが弱いのが原因っぽい。WiFiをつなぎなおしてやったり、ネットワーク環境を整えてやる。gitlab-runnerやdockerがうまく動いていない。固まっている。
しょっぱなから
Running with gitlab-runner 12.2.0 (xxxxxxx) on iMac-docker xxxxxx ERROR: Preparation failed: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (executor_docker.go:983:120s) Will be retried in 3s ... ERROR: Preparation failed: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (executor_docker.go:983:120s) Will be retried in 3s ... ERROR: Preparation failed: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (executor_docker.go:983:120s) Will be retried in 3s ... ERROR: Job failed (system failure): Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (executor_docker.go:983:120s)とか出てなにもできずにエラーになるとき
→dockerかgitlab-runnerのどちらかがうまく動いていないので、dockerとgitlab-runnerをそれぞれ再起動してやる。(本格的に固まっていてうんともすんとも言わずマシンの再起動になることも多々あり。)
- 投稿日:2020-05-21T15:14:05+09:00
Oracleいろいろ
Docker で Oracle を軽く確認したい場合。
11g であれば、以下ので成功した。
https://registry.hub.docker.com/r/wnameless/oracle-xe-11g-r2docker run -d -p 49161:1521 -e ORACLE_ALLOW_REMOTE=true -e ORACLE_DISABLE_ASYNCH_IO=true wnameless/oracle-xe-11g-r212 は成功したことがない。
docker をクリアする場合、https://docs.docker.com/config/pruning/を参照
まず
docker image pruneTo remove all images which are not used by existing containers, use the -a flag:
docker image prune -a
Oracle 良いクライアントソフト(Windowsのみ)
OSqlEdit Oracle SQLエディタ(有料)
http://www.hi-ho.ne.jp/a_ogawa/osqledit/
良い点:操作がいい。data-grid も実用性的。
悪い店:oracle cient をインストールする必要がある。A5:SQL Mk-2(無料)
https://a5m2.mmatsubara.com/
良い点:oracle cient をインストールする必要なし。直接接続できる。
悪い店:操作感がイマイチ。
- 投稿日:2020-05-21T14:40:49+09:00
NestJs + Docker
プロジェクトをインストールして作成
一時的なDockerコンテナーを作成する
Make temporary docker container
sudo docker container run -it -v $(pwd):/app -w /app node:12.13.1-alpine /bin/shそのDockerコンテナ内に「nest-cli」をインストールして新しいプロジェクトを作成します
Inside that docker container, install the
nest-cli
and make a new project$ npm i -g @nestjs/cli $ nest new project-nameプロジェクトが作成されたら、プロジェクトの内部に入り、依存関係をインストールします
Once your project is created, get inside the project, and install dependencies
$ cd project $ npm install $ npm run start完了したら、コンテナを終了できます。
Once done, you can exit the container.
プロジェクトファイルの所有者を変更します。
Change the owner od the project files.
sudo chown -R myuser:myuser <project-name>開発モードを実行するようにDockerを構成する
プロジェクトディレクトリ内に「Dockerfile」を作成します
Inside the project directory, create a
Dockerfile
FROM node:12.13.1-alpine WORKDIR /app RUN apk update && \ apk add git && \ npm install -g npm && \ npm install -g @nestjs/cli ENV HOST 0.0.0.0 EXPOSE 3000また、
docker-compose.yaml
も作成しますand also create a
docker-compose.yaml
version: '3' services: nest: build: . tty: true command: npm run start:dev volumes: - .:/app ports: - "3000:3000"作成後、
localhost:3000
にアクセスすると、Hello World
ページが表示されます。Upon creation, you can visit
localhost:3000
, you should see theHello World
page.ウォッチをテストするには、
app.services.ts
のgetHello()を編集します。編集したら、ページを更新して変更を確認できます。To test the watch, you can edit the
app.services.ts
getHello(), once edited, you can refresh the page, to see the change.新しいコントローラーを作成する
sudo docker-compose exec nest nest generate controller catsこれはプロジェクトの
src
ディレクトリの中にcats
ディレクトリを作成しますThis will create a
cats
directory inside thesrc
directory of the project私の例をコピーして貼り付けることができます
You can copy-paste my example
import { Controller, Get, Req, Param } from '@nestjs/common'; @Controller('cats') export class CatsController { @Get() findAll():Object{ var test = {id:1,name:"my cat"} return test; } @Get("filter") getFilter(@Req() req):Object{ return {id:req.query.id,name:"my cat id"}; } @Get(':id') findOne(@Param() params): string { return `This action returns a #${params.id} cat`; } }
localhost:3000/
localhost:3000/filter?id=55
localhost:3000/20
- 投稿日:2020-05-21T10:18:34+09:00
Docker で Spring Boot
はじめまして。ドカっとドカ土香 ドカちゃんです♡
今回は、
Springドキュメントのガイド『Docker で Spring Boot』を見ながら進めてたんだけど、所々詰まったから手順を残しておくよ
気になったところはガイドを見てね。環境
・Windows 10 pro
前提条件
Windows 10でDockerを利用するには「Hyper-V」 が必要だよ。
Windows 10 の Professional 以上のエディションが必要で、Windows 10 Home には対応していないよ。Hyper-Vを有効化
コントロール パネルを開いて、
プログラムと機能→左の[Windows の機能の有効化または無効化] →[Hyper-V] 選択→[OK]
Windowsの再起動をするよ。Dockerのインストール
利用するには Docker IDを登録する必要があるよ。
・https://hub.docker.com/ここからインストールしていくよ。
インストールは簡単だったよ。
・https://hub.docker.com/?overlay=onboarding
手順の中でPowerShellが必要になるよ。
インストールできたら、PowerShellを起動してコピペで入力していくだけだよ。
・windows PowerShellのインストールチュートリアルを完了してレジストリができていたらおkだよ。
Spring Boot
準備するもの
- ファイル編集用にテキストエディターまたは IDE →メモ帳でおk
- JDK 1.8 以降 →コマンドプロンプトで「jar」と打って使用方法が表示されたらおk インストール方法
- Gradle 4+ →インストールサイト
PowerShellに次のコードを入力するよ。
①git clone https://github.com/spring-guides/gs-spring-boot-docker.git
②cd gs-spring-boot-docker/initial
(参考パス、C:ユーザー/ユーザー名/gs-spring-boot-docker/initial/)
src/main/java/hello/Application.javaを開くよ。
「Hello Docker World」を表示させたいなら以下に書き換えるよ。package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class Application { @RequestMapping("/") public String home() { return "Hello Docker World"; } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
gradlew buildをしていくよ。
Springのガイドでは以下を入力するよう記載されてるけどPowerShelldだとエラーがでるよ。
./gradlew build && java -jar build/libs/gs-spring-boot-docker-0.1.0.jar
エラー.発生場所 行:1 文字:17 + ./gradlew build && java -jar build/libs/gs-spring-boot-docker-0.1.0.j ... + ~~ トークン '&&' は、このバージョンでは有効なステートメント区切りではありません。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : InvalidEndOfLine「&&」を「;」に書き換えると成功するよ。
./gradlew build ; java -jar build/libs/gs-spring-boot-docker-0.1.0.jar
8080に繋げて「Hello Docker World」が表示されたらOKだよ。
クリック→ http://localhost:8080/コンテナー化
パス:~/gs-spring-boot-docker/initial/ 配下にDockerfileを作成するよ。
このあとのDockerイメージを作成するのに必要だよ。
拡張子はつけないよ。
①~③パターンあるよ。
初めて作る人は①から試して理解を深めていくといいよ。
面倒なら①だけでもいいし、最適化された③から実施してもいいよ。①基本
Dockerfile.FROM openjdk:8-jdk-alpine ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"]JDK8をベースとしているよ。
JAR ファイルを「app.jar」としてコンテナーに入れ、
ENTRYPOINT で実行しているよ。
PowerShellで以下を実行してイメージを作成するよ。
docker build --build-arg JAR_FILE=build/libs/*.jar -t springio/gs-spring-boot-docker .
「docker build [OPTION]には一つ以上の引数が必要です~」とメッセージが出てビルドできなかったけど、
端末再起動後に入力したら上手くいったよ。
成功すると以下のようなイメージで表示されるよ。成功イメージ.Sending build context to Docker daemon 21.11MB Step : FROM openjdk:8-jdk-alpine ---> Step : ARG JAR_FILE=target/*.jar ---> Using cache ---> Step 5/6 : COPY ${JAR_FILE} app.jar COPY failed: no source files were specified②セキュリティ向上ver.
このままではセキュリティ上問題があるらしく、
非 root ユーザーとしてアプリを実行するように書き換えるよ。Dockerfile.FROM openjdk:8-jdk-alpine RUN addgroup -S spring && adduser -S spring -G spring USER spring:spring ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"]イメージ作成
docker build -t springio/gs-spring-boot-docker .
以下で実行すると
docker run -p 8080:8080 springio/gs-spring-boot-docker
ユーザー名を確認できるよ。ログ.. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.2.1.RELEASE) 2020-04-23 07:29:41.729 INFO 1 --- [ main] hello.Application ...③パフォーマンス向上ver.
次にSpring Boot fat の特性を活かしてパフォーマンスを上げるよ。また書き換えていくよ。
Spring Boot fat jar ファイルでは依存関係とアプリケーションリソースが明確に分離されており、その事実を使用してパフォーマンスを向上させることができます。
Dockerfile.FROM openjdk:8-jdk-alpine RUN addgroup -S spring && adduser -S spring -G spring USER spring:spring ARG DEPENDENCY=target/dependency COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib COPY ${DEPENDENCY}/META-INF /app/META-INF COPY ${DEPENDENCY}/BOOT-INF/classes /app ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]次にSpringのガイドでは下のコードで実行するように記載してあるけどPowerShellだとエラーが起こるよ。
mkdir -p build/dependency && (cd build/dependency; jar -xf ../libs/*.jar)
エラー.式の終わりの ')' が存在しません。 発生場所 行:1 文字:30 + mkdir -p build/dependency && (cd build/dependency; jar -xf ../libs/*. ... + ~~~~~~~~~~~~~~~~~~~~ 式は、パイプラインの最初の要素としてのみ許可されます。 発生場所 行:1 文字:73 + ... r -p build/dependency && (cd build/dependency; jar -xf ../libs/*.jar) + ~ 式またはステートメントのトークン ')' を使用できません。「()」括弧を使えないみたいだよ。
macだと問題ないのかな?
かなり探したけど括弧を置き換えたり、有効化する方法は見つからなかったよ。。
よく見たら括弧外して処理を分けれるよ。
①mkdir -p build/dependency
②cd .\build\dependency\
③jar -xf ../libs/*.jar
dependency配下に、BOOT-INF/lib とアプリケーションクラスを含む BOOT-INF/classes ディレクトリが作成されたよ。Gradle を使用して Docker イメージを作成する
Gradle で Docker イメージを作成するよ。
ネームスペースにはdockaerのユーザー名を入力するよ。
(ちなみに、個人のイメージはネームスペースが必要で、公式イメージなら必要ないよ。)
リポジトリ名は自由に決めてね。
今回はリポジトリ名を「spring-boot-docker」にしておくよ。
./gradlew bootBuildImage --imageName=ネームスペース/spring-boot-docker
イメージを作成したときのログだよ。
images()の中身はイメージIDだよ。
「./gradlew」が使えないとエラーが出たら階層を間違えているからGradleのある場所に戻ればいいよ。
例:cd C:\Users\ユーザー名\gs-spring-boot-docker\initial
ローカルで作成したイメージを動かしてみるよ。
docker run -p 8080:8080 -t springio/gs-spring-boot-docker
DockerHubへプッシュ
docker images
で作成したイメージ一覧を確認できるよ。
docker push ユーザー名/spring-boot-docker
でプッシュするよ。(ちなみに docker rmi コマンドでイメージを削除できるよ。
削除するにはイメージ ID かイメージ名を使うよ。
・docker rmi -f 7d9495d03763
・docker rmi -f spring-boot-docker)dockaerにログインしてリポジトリ一覧を見るとプッシュしたリポジトリが追加されているよ。
おわりだYO!!
間違っていたら指摘お願いするよ。
- 投稿日:2020-05-21T10:18:34+09:00
DockerのインストールからSpring BootでDockerHubへプッシュまで
はじめまして。ドカっとドカ土香 ドカちゃんです♡
Dockerの使い方あまりわかってないけど、
とりあえず使いながら理解していこうってことで、
Springドキュメントのガイド『Docker で Spring Boot』を見ながら進めてたんだけど、所々詰まったから手順を残しておくよ><
気になったところはガイドを見てね。環境
・Windows 10 pro
前提条件
Windows 10でDockerを利用するには「Hyper-V」 が必要だよ。
Windows 10 の Professional 以上のエディションが必要で、Windows 10 Home には対応していないよ。Hyper-Vを有効化
コントロール パネルを開いて、
プログラムと機能→左の[Windows の機能の有効化または無効化] →[Hyper-V] 選択→[OK]
Windowsの再起動をするよ。Dockerのインストール
利用するには Docker IDを登録する必要があるよ。
・https://hub.docker.com/ここからインストールしていくよ。
インストールは簡単だったよ。
・https://hub.docker.com/?overlay=onboarding
手順の中でPowerShellが必要になるよ。
インストールできたら、PowerShellを起動してコピペで入力していくだけだよ。
・windows PowerShellのインストールチュートリアルを完了してレジストリができていたらおkだよ。
Spring Boot
準備するもの
- ファイル編集用にテキストエディターまたは IDE →メモ帳でおk
- JDK 1.8 以降 →コマンドプロンプトで「jar」と打って使用方法が表示されたらおk インストール方法
- Gradle 4+ →インストールサイト
PowerShellに次のコードを入力するよ。
①git clone https://github.com/spring-guides/gs-spring-boot-docker.git
②cd gs-spring-boot-docker/initial
(参考パス、C:ユーザー/ユーザー名/gs-spring-boot-docker/initial/)
src/main/java/hello/Application.javaを開くよ。
「Hello Docker World」を表示させたいなら以下に書き換えるよ。package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class Application { @RequestMapping("/") public String home() { return "Hello Docker World"; } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
gradlew buildをしていくよ。
Springのガイドでは以下を入力するよう記載されてるけどPowerShelldだとエラーがでるよ。
./gradlew build && java -jar build/libs/gs-spring-boot-docker-0.1.0.jar
エラー.html発生場所 行:1 文字:17 + ./gradlew build && java -jar build/libs/gs-spring-boot-docker-0.1.0.j ... + ~~ トークン '&&' は、このバージョンでは有効なステートメント区切りではありません。 + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : InvalidEndOfLine「&&」を「;」に書き換えると成功するよ。
./gradlew build ; java -jar build/libs/gs-spring-boot-docker-0.1.0.jar
8080に繋げて「Hello Docker World」が表示されたらOKだよ。
クリック→ http://localhost:8080/コンテナー化
パス:~/gs-spring-boot-docker/initial/ 配下にDockerfileを作成するよ。
このあとのDockerイメージを作成するのに必要だよ。
拡張子はつけないよ。
①~③パターンあるよ。
初めて作る人は①から試して理解を深めていくといいよ。
面倒なら①だけでもいいし、最適化された③から実施してもいいよ。①基本
Dockerfile.FROM openjdk:8-jdk-alpine ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"]JDK8をベースとしているよ。
JAR ファイルを「app.jar」としてコンテナーに入れ、
ENTRYPOINT で実行しているよ。
PowerShellで以下を実行してイメージを作成するよ。
docker build --build-arg JAR_FILE=build/libs/*.jar -t springio/gs-spring-boot-docker .
「docker build [OPTION]には一つ以上の引数が必要です~」とメッセージが出てビルドできなかったけど、
端末再起動後に入力したら上手くいったよ。
成功すると以下のようなイメージで表示されるよ。成功イメージ.htmlSending build context to Docker daemon 21.11MB Step : FROM openjdk:8-jdk-alpine ---> Step : ARG JAR_FILE=target/*.jar ---> Using cache ---> Step 5/6 : COPY ${JAR_FILE} app.jar COPY failed: no source files were specified②セキュリティ向上ver.
このままではセキュリティ上問題があるらしく、
非 root ユーザーとしてアプリを実行するように書き換えるよ。Dockerfile.htmlFROM openjdk:8-jdk-alpine RUN addgroup -S spring && adduser -S spring -G spring USER spring:spring ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"]
イメージ作成
docker build -t springio/gs-spring-boot-docker .
以下で実行すると
docker run -p 8080:8080 springio/gs-spring-boot-docker
ユーザー名を確認できるよ。ログ.html. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.2.1.RELEASE) 2020-04-23 07:29:41.729 INFO 1 --- [ main] hello.Application ...③パフォーマンス向上ver.
次にSpring Boot fat の特性を活かしてパフォーマンスを上げるよ。また書き換えていくよ。
Spring Boot fat jar ファイルでは依存関係とアプリケーションリソースが明確に分離されており、その事実を使用してパフォーマンスを向上させることができます。
Dockerfile.FROM openjdk:8-jdk-alpine RUN addgroup -S spring && adduser -S spring -G spring USER spring:spring ARG DEPENDENCY=target/dependency COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib COPY ${DEPENDENCY}/META-INF /app/META-INF COPY ${DEPENDENCY}/BOOT-INF/classes /app ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]次にSpringのガイドでは下のコードで実行するように記載してあるけどPowerShellだとエラーが起こるよ。
mkdir -p build/dependency && (cd build/dependency; jar -xf ../libs/*.jar)
エラー.html式の終わりの ')' が存在しません。 発生場所 行:1 文字:30 + mkdir -p build/dependency && (cd build/dependency; jar -xf ../libs/*. ... + ~~~~~~~~~~~~~~~~~~~~ 式は、パイプラインの最初の要素としてのみ許可されます。 発生場所 行:1 文字:73 + ... r -p build/dependency && (cd build/dependency; jar -xf ../libs/*.jar) + ~ 式またはステートメントのトークン ')' を使用できません。「()」括弧を使えないみたいだよ。
macだと問題ないのかな?
かなり探したけど括弧を置き換えたり、有効化する方法は見つからなかったよ。。
よく見たら括弧外して処理を分けれるよ。
①mkdir -p build/dependency
②cd .\build\dependency\
③jar -xf ../libs/*.jar
dependency配下に、BOOT-INF/lib とアプリケーションクラスを含む BOOT-INF/classes ディレクトリが作成されたよ。Gradle を使用して Docker イメージを作成する
Gradle で Docker イメージを作成するよ。
ネームスペースにはdockaerのユーザー名を入力するよ。
(ちなみに、個人のイメージはネームスペースが必要で、公式イメージなら必要ないよ。)
リポジトリ名は自由に決めてね。
今回はリポジトリ名を「spring-boot-docker」にしておくよ。
./gradlew bootBuildImage --imageName=ネームスペース/spring-boot-docker
イメージを作成したときのログだよ。
images()の中身はイメージIDだよ。
「./gradlew」が使えないとエラーが出たら階層を間違えているからGradleのある場所に戻ればいいよ。
例:cd C:\Users\ユーザー名\gs-spring-boot-docker\initial
ローカルで作成したイメージを動かしてみるよ。
docker run -p 8080:8080 -t springio/gs-spring-boot-docker
DockerHubへプッシュ
docker images
で作成したイメージ一覧を確認できるよ。
docker push ユーザー名/spring-boot-docker
でプッシュするよ。(ちなみに docker rmi コマンドでイメージを削除できるよ。
削除するにはイメージ ID かイメージ名を使うよ。
・docker rmi -f 7d9495d03763
・docker rmi -f spring-boot-docker)dockaerにログインしてリポジトリ一覧を見るとプッシュしたリポジトリが追加されているよ。
おわりだYO!!
間違っていたら指摘お願いするよ。
- 投稿日:2020-05-21T06:14:39+09:00
Rundeck ~ Dockerで環境構築からSlack通知まで ~
やること
- コンテナ起動
- プロジェクト / ジョブの作成
- Slack通知設定
環境
MacOS Catalina 10.15.4 Docker Desktop 2.3.0.2Dockerコンテナ起動
こちらのDockerイメージで。
現在最新のVersion 3.2.6 をつかいます。
https://hub.docker.com/r/jordan/rundeck/docker run --rm -p 4440:4440 jordan/rundeck:3.2.6docker run
docker pull
とdocker create
とdocker start
を1発で行うやつ。
イメージがホストマシン上になければDocker Hubからpullしてきて、コンテナつくって、コンテナを起動します。
-it
-i と -tをまとめて書いてるものです。-i or --interactive
=> ホスト側のシェルからコンテナ内を操作できるようにする。-t or --tty
=> 仮想ttyの割当て。キーバインドを使用したり、色を出力したりシェル操作を便利に行うために指定。こちらが非常にわかりやすいです。
https://teratail.com/questions/121780
https://teratail.com/questions/19477
https://teratail.com/questions/100044
-p 4440:4440
ホスト側のポート番号
:コンテナ側のポート番号
をひも付けます。
ローカルのブラウザからlocalhost:4440
でRundeckの設定画面を開けるようにします。
--rm
コンテナを停止したときに自動で削除もしてくれます。
ログイン
ブラウザかlocalhost:4440にアクセス
※docker run してからアクセスできるようになるまで少しだけ時間がかかります(30秒くらい??)Username: admin
Password: adminでログイン
※ 初期設定がadminプロジェクト作成
今回は名前だけ設定し作成
SlackにAppをインストール
通知を可能にするために、Incomming WebhooksというアプリケーションをSlackへインストールします。
■Slack■
サイドメニューのApp >
incomming webhooks
で検索 > 追加or
https://あなたのワークスペース.slack.com/apps/A0F7XDUAZ--incoming-webhook-?next_id=0
■ブラウザ■
ブラウザがひらくので、右上のワークスペースを選択 > Slackに追加
通知先チャンネルを指定 > 追加
Webhook URLをコピー
■Rundeck■
Rundeckにもどり、Slack通知設定をします。
設定ファイルが開くので、末尾に以下の1行を追記
project.plugin.Notification.SlackNotification.webhook_url=https://hooks.slack.com/services/FOO/BAR/hogefuga
※
https://hooks.slack.com/services/FOO/BAR/hogefuga
の部分がさっきコピーしたご自身のWebhook URLになります。ジョブの作成
適当な名前をつけて
Workflowタブで
いろいろなステップを追加できますが、今回はお手軽にコマンドで
pwd
でカレントディレクトリを表示させましょう。Scheduleタブから、時間やら定期実行やらをご自由に
※Cronの記法でも登録できます。日本の方はタイムゾーンを
Asia/Tokyo
にNotificationsタブで通知設定をします。
成功時のSlackにチェックをいれます。※今回はDockerイメージを利用しているので不要ですが、本来Slack通知を行うためにはプラグインファイルの設置などが必要になります。
参照: https://namionobkup.hatenablog.com/entry/2018/05/06/112439※さきほどのWeb Hooks URLを設定しておかないと、以下の
~ Override
の欄に記入しても無効でした。
こちらの記事に助けて頂きました
参照: https://obel.hatenablog.jp/entry/20190326/1553563656ちなみに
ここからすぐにジョブを実行することも可能です。で、こんな感じでSlackに通知がきます
さいごに
Dockerイメージが公開されているので、簡単に環境構築ができてありがたいです。
おしまい。
- 投稿日:2020-05-21T03:16:19+09:00
Raspberry Pi 4でKubernetesクラスターを構築する【ソフトウェア編】
この記事はRaspberry Pi 4でKubernetesクラスターを構築する【ハードウェア編】の続きです。
この記事でできるようになること
【ソフトウェア編】を読むと、Kubernetes(以下k8s)のクラスターを、Raspberry Pi上に構築できるようになります。
(ルーター等の解説は割愛)クラスターは下記の構成で構築していきます。
- Master Node * 1
- Kubernetes v1.18
- Pod Network: Flannel
- Worker Node * 2
OSのインストール
Macを用いてセットアップしていきます。
下記の作業を3台分行います。OSイメージのダウンロード
Downloads Raspbianから
Raspbian Buster Lite
をダウンロードします。
(Desktop版でもOKです)$ cd ~/Downloads # zipファイルを解凍 $ unzip 2020-02-13-raspbian-buster-lite.zip Archive: 2020-02-13-raspbian-buster-lite.zip inflating: 2020-02-13-raspbian-buster-lite.imgmicroSDにOSを焼く
SDカードリーダーが必要です。
私はたまたま持っていた、Anker PowerExpand Direct 7-in-2を使用しました。詳しい手順は、Copying an operating system image to an SD card using Mac OSに記載されています。
# マウント先の特定 $ diskutil list /dev/disk0 (internal, physical): #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *500.3 GB disk0 1: EFI EFI 314.6 MB disk0s1 2: Apple_APFS Container disk1 500.0 GB disk0s2 /dev/disk1 (synthesized): #: TYPE NAME SIZE IDENTIFIER 0: APFS Container Scheme - +500.0 GB disk1 Physical Store disk0s2 1: APFS Volume Macintosh HD - Data 157.8 GB disk1s1 2: APFS Volume Preboot 79.4 MB disk1s2 3: APFS Volume Recovery 528.1 MB disk1s3 4: APFS Volume VM 5.4 GB disk1s4 5: APFS Volume Macintosh HD 11.1 GB disk1s5 /dev/disk2 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *31.9 GB disk2 1: Windows_FAT_32 boot 268.4 MB disk2s1 2: Linux 31.6 GB disk2s2上記のコマンドで
/dev/disk2
がmicroSDだと分かりました。# microSDをアンマウントする $ diskutil unmountDisk /dev/disk2 Unmount of all volumes on disk2 was successful次にイメージをmicroSDに焼きます。
注意してほしいのは、対象を間違えるとMac本体のデータが消えてしまうので、必ずmicroSDの番号に対して実行してください。# OSイメージを焼く $ sudo dd bs=1m if=2020-02-13-raspbian-buster-lite.img of=/dev/rdisk2; sync 1780+0 records in 1780+0 records out 1866465280 bytes transferred in 93.421984 secs (19978866 bytes/sec)SSHを有効にする
Raspberry Piは、デフォルトではSSHができないようになっているので、有効にします。
microSDを挿し直してから実行してください。$ cd /Volumes/boot # 空のファイルを作成する $ touch sshcgroupsの設定
enabling cgroup memory doesn't take effect
$ cd /Volumes/boot/ $ vim cmdline.txt
cgroup_enable=cpuset
cgroup_enable=memory
cgroup_memory=1
を下記のように追加します。cmdline.txtdwc_otg.lpm_enable=2 console=serial0,115200 console=tty1 root=PARTUUID=7ee80803-02 rootfstype=ext4 cgroup_enable=cpuset cgroup_memory=memory cgroup_memory=1 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.shRaspberry Piの起動
基盤の裏側にmicroSDスロットがあります。
挿入したら、USB Type-Cケーブルを挿し、給電します。ここまでの作業を計3回行ってください。
各ソフトウェアのインストール
Macのターミナル等から、下記のコマンドを実行して、各Raspberry Piに割り当てられたIPアドレスを取得します。
下記の作業を3台分行います。$ arp -a ? (192.168.13.1) at 58:27:8c:25:11:ea on en0 ifscope [ethernet] ? (192.168.13.2) at dc:a6:32:72:b9:50 on en0 ifscope [ethernet] ? (192.168.13.3) at dc:a6:32:72:73:9f on en0 ifscope [ethernet] ? (192.168.13.5) at dc:a6:32:72:ba:4 on en0 ifscope [ethernet]下3つがRaspbery PiのIPアドレスです。(一番上はトラベルルーターのIPアドレス)
sshログイン
Raspbian OSはデフォルトで
ユーザー: pi
パスワード: raspberry
のユーザーが作成されています。$ ssh pi@192.168.13.2ユーザーを作成し、piユーザーを削除
piユーザーはパスワードが公開されているので、同じ権限の別のユーザーを作成し、piユーザーを削除します。
# ユーザー作成 $ sudo adduser butter # piユーザーの権限を確認 $ groups pi pi : pi adm dialout cdrom sudo audio video plugdev games users input netdev pi spi i2c gpio # 作成したユーザーに同じ権限を付与 $ sudo usermod -G pi,adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,spi,i2c,gpio butter # 作成したユーザーに切り替える $ su - butter # piユーザーの削除 $ sudo userdel -r piDockerのインストール
インストール方法の詳細はDocker公式ドキュメントをご覧下さい。
# 必要なパッケージのインストール $ sudo apt-get update $ apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common # GPGキーの追加 $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - # リポジトリの追加 $ echo "deb [arch=armhf] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \ $(lsb_release -cs) stable" | \ sudo tee /etc/apt/sources.list.d/docker.list # Dockerエンジンのインストール $ sudo apt-get update $ sudo apt-get install docker-ceKubernetesのインストール
kubeadm, kubelet, kubectlをインストールします。
インストール方法の詳細はKubernetes公式ドキュメントをご覧下さい。$ sudo apt-get update && sudo apt-get install -y apt-transport-https curl $ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - $ cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list deb https://apt.kubernetes.io/ kubernetes-xenial main EOF $ sudo apt-get update $ sudo apt-get install -y kubelet kubeadm kubectl $ sudo apt-mark hold kubelet kubeadm kubectlSwapの無効化
Swapが有効になっているとKubeletが起動しないため、Swapを無効化しておきます。
$ sudo swapoff -aここまでの作業を3台分繰り返してください。
これでクラスター構築の準備は完了と言っていいでしょう。Kubernetesクラスターの構築
ここからはMasterNodeとWorkerNodeで別の作業をしていきます。
Master Nodeの構築
CNIプラグインはFlannelを使用します。
Flannelを使用する場合、--pod-network-cidr=10.244.0.0/16
を指定する必要があります。$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16 W1228 06:06:27.607623 2273 validation.go:28] Cannot validate kube-proxy config - no validator is available W1228 06:06:27.607962 2273 validation.go:28] Cannot validate kubelet config - no validator is available [init] Using Kubernetes version: v1.17.0 [preflight] Running pre-flight checks [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/ [preflight] Pulling images required for setting up a Kubernetes cluster [preflight] This might take a minute or two, depending on the speed of your internet connection [preflight] You can also perform this action in beforehand using 'kubeadm config images pull' [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Starting the kubelet [certs] Using certificateDir folder "/etc/kubernetes/pki" [certs] Generating "ca" certificate and key [certs] Generating "apiserver" certificate and key [certs] apiserver serving cert is signed for DNS names [k8s-master kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.13.101] [certs] Generating "apiserver-kubelet-client" certificate and key [certs] Generating "front-proxy-ca" certificate and key [certs] Generating "front-proxy-client" certificate and key [certs] Generating "etcd/ca" certificate and key [certs] Generating "etcd/server" certificate and key [certs] etcd/server serving cert is signed for DNS names [k8s-master localhost] and IPs [192.168.13.101 127.0.0.1 ::1] [certs] Generating "etcd/peer" certificate and key [certs] etcd/peer serving cert is signed for DNS names [k8s-master localhost] and IPs [192.168.13.101 127.0.0.1 ::1] [certs] Generating "etcd/healthcheck-client" certificate and key [certs] Generating "apiserver-etcd-client" certificate and key [certs] Generating "sa" key and public key [kubeconfig] Using kubeconfig folder "/etc/kubernetes" [kubeconfig] Writing "admin.conf" kubeconfig file [kubeconfig] Writing "kubelet.conf" kubeconfig file [kubeconfig] Writing "controller-manager.conf" kubeconfig file [kubeconfig] Writing "scheduler.conf" kubeconfig file [control-plane] Using manifest folder "/etc/kubernetes/manifests" [control-plane] Creating static Pod manifest for "kube-apiserver" [control-plane] Creating static Pod manifest for "kube-controller-manager" W1228 06:08:56.859476 2273 manifests.go:214] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC" [control-plane] Creating static Pod manifest for "kube-scheduler" W1228 06:08:56.868671 2273 manifests.go:214] the default kube-apiserver authorization-mode is "Node,RBAC"; using "Node,RBAC" [etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests" [wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s [kubelet-check] Initial timeout of 40s passed. [apiclient] All control plane components are healthy after 48.007975 seconds [upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace [kubelet] Creating a ConfigMap "kubelet-config-1.17" in namespace kube-system with the configuration for the kubelets in the cluster [upload-certs] Skipping phase. Please see --upload-certs [mark-control-plane] Marking the node k8s-master as control-plane by adding the label "node-role.kubernetes.io/master=''" [mark-control-plane] Marking the node k8s-master as control-plane by adding the taints [node-role.kubernetes.io/master:NoSchedule] [bootstrap-token] Using token: ul0n5s.x4ukjc7en79vt4o7 [bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles [bootstrap-token] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials [bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token [bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster [bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace [kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key [addons] Applied essential addon: CoreDNS [addons] Applied essential addon: kube-proxy Your Kubernetes master has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config You should now deploy a pod network to the cluster. Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ You can now join any number of machines by running the following on each node as root: kubeadm join 192.168.13.2:6443 --token vpmuze.ina6swjhlxh57lds --discovery-token-ca-cert-hash sha256:fcda1034ebb1374f0a0b487cd349b29ac1c253e83e6344b4d567cf61123a509ckubectlの設定
$ mkdir -p $HOME/.kube $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config $ sudo chown $(id -u):$(id -g) $HOME/.kube/configPod Network Addonのインストール
$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml podsecuritypolicy.policy/psp.flannel.unprivileged created clusterrole.rbac.authorization.k8s.io/flannel created clusterrolebinding.rbac.authorization.k8s.io/flannel created serviceaccount/flannel created configmap/kube-flannel-cfg created daemonset.apps/kube-flannel-ds-amd64 created daemonset.apps/kube-flannel-ds-arm64 created daemonset.apps/kube-flannel-ds-arm created daemonset.apps/kube-flannel-ds-ppc64le created daemonset.apps/kube-flannel-ds-s390x createdWorker Nodeの構築
Master Nodeを構築したときに出力されたコマンドをそのまま使用します。
$ sudo kubeadm join 192.168.13.2:6443 --token vpmuze.ina6swjhlxh57lds --discovery-token-ca-cert-hash sha256:fcda1034ebb1374f0a0b487cd349b29ac1c253e83e6344b4d567cf61123a509c W1228 06:21:59.043224 3046 join.go:346] [preflight] WARNING: JoinControlPane.controlPlane settings will be ignored when control-plane flag is not set. [preflight] Running pre-flight checks [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/ [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml' [kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.17" ConfigMap in the kube-system namespace [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.この作業をWorkerNode数分繰り返してください。
構築確認
Master Nodeで下記のコマンドを実行。
$ kubectl get nodes NAME STATUS ROLES AGE VERSION rp-kube-master Ready master 12m v1.18.2 rp-kube-worker1 Ready <none> 2m13s v1.18.2 rp-kube-worker2 Ready <none> 43s v1.18.2Worker NodeのROLESが
<none>
になっているので、ラベルを追加します。$ kubectl label node rp-kube-worker1 node-role.kubernetes.io/worker=worker node/rp-kube-worker1 labeled $ kubectl label node rp-kube-worker2 node-role.kubernetes.io/worker=worker node/rp-kube-worker2 labeled $ kubectl get nodes NAME STATUS ROLES AGE VERSION rp-kube-master Ready master 12m v1.18.2 rp-kube-worker1 Ready worker 2m13s v1.18.2 rp-kube-worker2 Ready worker 43s v1.18.2これでクラスターの構築は完了です。
最終的な状態
また、それぞれに静的IPアドレスを割り当てて、再起動等を繰り返してもIPが変わらないようにしたり、host名を変更したりしました。
まとめ
k8sのクラスター構築は初めてやったので、手順通りにやっただけではあるものの、かなり勉強になることが多かったです。
これから本格的に触れていこうと思うので、今後もk8sに関する記事を書いていければと思います。参考記事
Raspberry PiでおうちKubernetes構築【論理編】
Raspberry Pi 4 でおうちKubernetesを作ろう(Raspbian Buster Lite対応版)
ラズパイ4で作るディスプレイ付きKubernetesクラスター
ラズパイでKubernetesクラスタを構築する
- 投稿日:2020-05-21T03:15:40+09:00
Raspberry Pi 4でKubernetesクラスターを構築する【ハードウェア編】
目的
業務でKubernetes(以下k8s)を扱うようになり、勉強のために1から構築します。
GKEやAKSを使うのではなく1から環境構築したくなり、過去にRaspberryPiでk8sのクラスターを構築している方の記事をみたことを思い出し、自分でもやってみることにしました。この記事でできるようになること
【ハードウェア編】では、k8sのクラスター構築の準備として、以下の画像のようなデバイスを組み立てます。
必要な部品とそれらのリンクも記載するので、購入した上で手順通りに組み立てれば、k8s等をインストールするための準備は完了します。最終的なゴール
【ハードウェア編】【ソフトウェア編】の両方を読み終えると、以下の環境を構築できるようになります。
- Master Node * 1
- Kubernetes v1.18
- Pod Network: Flannel
- Worker Node * 2
購入した部品
部品 個数 備考 Raspberry Pi 4 Model B/4GB 3個 Raspberry Pi 4 ヒートシンク 3個 アクリルケースに付属されているヒートシンクを使う場合は不要 microSDHC 32GB 3個 アクリルケース 1個 ヒートシンク、ピンセット、ドライバー付属 無線LAN トラベルルーター 1個 5ポート USB充電器 1個 スイッチングハブ 1個 USB Type-C ケーブル 3本 このリンクは3本組の商品です Micro USBケーブル 2本 このリンクは2本組の商品です 0.5m LANケーブル 4本 その他に使用したもの
- microSDカードリーダー
- 両面テープ
組み立てる
Raspberry Pi 4開封
Raspbery Pi 3では基盤は袋で密閉されているようでしたが、4は剥き出しの状態で入っています。
箱を開けた時にびっくりして一瞬不安になりましたwRaspberry Piをアクリルプレートに固定
アクリルプレートのフィルムを剥がすのが一番大変でしたw
Raspberry Piの裏面にmicroSDを挿入するスロットがあり、プレートはこのスロットに当たらないように作られています。
なので、それぞれの向きを間違えないように注意してください。Raspberry Piにヒートシンクをつける
それぞれ大きさが異なり、貼り付ける位置が違うので注意してください。
USB充電器を設置
大きめの両面テープで固定しています。
スイッチングハブ、トラベルルーターを設置
トラベルルーターは少しずらして設置しています。
理由は、スイッチングハブのLANケーブルの爪が当たってしまい、設置する時に少し浮いてしまうからです。
トラベルルーターとスイッチングハブは、それぞれ両面テープで固定しています。アクリルプレートを固定用のネジでつなげる
このときに、どうケーブリングするかイメージしながらプレートを固定していくといいと思います。
私は、正面にケーブルが出ているのがいやだったので、以下のような向きで固定しました。
(すべて正面から見た場合)
段数 設置物 固定方法 1~3段目 Raspberry Pi USBポートやLANポートが左側に来るように固定 4段目 USB充電器 USBポートが左側に来るように固定 5段目 スイッチングハブ、トラベルルーター LANポートが裏面に来るように固定 ケーブリング
正面
裏面
まとめ
基盤を触ったり、配線を考えたりするのが久しぶりだったので、結構ワクワクしました。
ルーターの設定やk8sのインストール、クラスターの構築は、【ソフトウェア編】で解説しているので、ぜひそちらもご覧ください。参考記事
Raspberry PiでおうちKubernetes構築【物理編】
Raspberry Pi 4 でおうちKubernetesを作ろう(Raspbian Buster Lite対応版)
3日間クッキング【Kubernetes のラズペリーパイ包み “サイバーエージェント風”】
- 投稿日:2020-05-21T01:23:12+09:00
自分用: ネットワークのメモ
はじめに
ネットワークは前にやったきりで時間も経ってるため、だいぶ忘れてしまいました.
久しぶりにネットワークの復習と追加学習をしました.
その内容をここにメモします.
間違ってたりアドバイスあったら優しく教えてくれると助かります〜TCP
L3までのおかげでパケットを相手に送信する事ができるようになったが、実際に届いたかどうかはわからない.
なので、相手はパケットが届いたら届いたよ!と、教えたりするルールを設けたのがTCP.(詳しくは省くパケットを送る時はPORT番号を指定する必要がある.
TCPの場合、相手からのパケットも受け取る必要があるので、依頼元も今回の通信で使うPORT番号を指定する.
送信元PORT番号は[動的・プライベート ポート番号 (49152–65535)]から選ばれる.
つまり、このout用のport番号を超えた65535-49152=16383を超える同時な外部へのTCPでの接続は工夫しないと、基本的にできない.
UDPの場合は、送信元PORTが必要ないので、この動的ポート番号枯渇による起きる制限はない.ARP
http://www5e.biglobe.ne.jp/aji/3min/26.html
ARPはL3のプロトコルで、ARP Requestをブロードキャストすることにより、ARP Requestに含まれている ARP Replyを頂ける.
ARP ReplyにリクエストされたMACアドレスが含まれた状態で届く.
これを利用することにより、ARP tableに宛先mac addressがない場合でもパケットを届けられるようになる.ARPのusecaseその4ぐらい
手動でnic設定したstatic ip addressで一度も外部通信していない場合、bridgeやRouterのARP tableにmac addressが記録されていない.
その様な状態の時に、Routerは受け取った宛先 IPのMac AddressをARPを使って調べる.firewall
firewallでよく80番ポートだけ開放するとかやります.
その場合、80番ポート以外のポートが記載されたパケットを全てロスする設定になっていると、動的ポート番号のパケットまで捨てられてしまいます.
そうした場合、TCPを利用したやりとりができなくなってしまいます.
なので、当たり前ですが、基本的にinとout用でセキュリティで考慮することや設定は変わります.
ちなみにUDPの場合は、response用のポートを動的ポート番号で確保する必要ないので、UDPリクエストしかしないと保証されているようなクライアントがいた場合、全てのportを閉じてもデータを外部に送れます.NIC
eh0はnic0枚目、eth1はnic1枚目って事
ethN == nicって認識で基本大丈夫
物理レイヤーにパケットを送る場合はethに送信パケットを投げて、ethがそれをethのpeerに対して送る. (nicは基本イーサネットケーブル等を通じて、bridgeやrouter等、対となるnicと繋がっている.その対のことをpeerと呼ぶ.Router作成の概念
http://redhatlinux.kt.fc2.com/cont/router.htm
このサイトが詳しい.
route -n
の見方がわからない場合、このサイトを見るといい.
https://xtech.nikkei.com/it/article/COLUMN/20080520/303086/
http://linux.kororo.jp/cont/intro/dgate.phpコンバージェンスとか一旦置いといた、一番シンプルなRouterはNICから受け取ったパケットを別のNICに飛ばす技術であるip forwardだけで実現が可能.
linuxでip forwardを有効化するには、/etc/sysctl.conf
にnet.ipv4.ip_forward=1
を追記し、ネットワークを再起動すると、ip forwardの機能が有効化される.ifconfig vs ip command
ifconfigはnet-toolsパッケージに含まれているコマンド.
その他にもよく使うroute, netstat, arpなどもnet-toolsパッケージに入っているコマンド.
net-toolsパッケージは現在非推奨になっている.仮想bridgeの作り方
bridgeは以下のいずれからでも作成できる
- bridge-utils
- iproute2
- netctl
- systemd-networkd
- NetworkManager
bridgeにはeth0等の実デバイスとveth等の仮想デバイスを接続することができます
仮想networkの作り方
仮想nicを作りまくって、仮想bridgeに繋げば、仮想プライベートネットワークは作れる.
しかし、このままだとプライベートネットワークがインターネットとやりとりできない.
直接eth0と繋ぐと、今度はeth0が専有されて、プライベートネットワークに所属していない奴らがインターネットに接続できなくなる.
なので、iptablesを使い、ipマスカレードする事によって、できる.
なので、docker等のbridgeのipマスカレードの設定を消すと、完全にネットワークから切り離せる.ipマスカレード(NAPT
iptablesを使う事により、ipマスカレードを使える.
ipマスカレードを使うと、NAPTの機能はもちろん、port forwardや、securityとかも行える.port forward
https://qiita.com/Ayaka14/items/449e2236af4b8c2beb81
こんな感じ
iptablesでもできる
特定のportに届いたパケットを特定のip addressのportに転送できる.
L2のproxyとして使える.
また、ネットワークセグメント同士を繋ぐのにも使える.
ネットワークセグメント同士を繋げば、VXLANが構築できる.VXLAN
https://tech.uzabase.com/entry/2017/08/23/175813
このサイトが詳しい.冗長化
基本的に対障害の為、単一のマイクロサービスを複数ホストに配置したいので、1マイクロサービスは複数ネットワークセグメント上に展開する.
VXLANの感想
結局はroutingの設定って感じがした.
routingの特定項目の設定とかにport forwardとか色んな特別な名前をつけてる感じ.参考文献
- 3分間ネットワーキング
- IPフォワード
- IPルーティング
- 【図解】初心者にも分かる PPP の仕組み, フォーマット
- Linuxルーターから、PPPoEによるインターネット接続を行う
- チュートリアル:WAN設定:PPPoEを使用したWAN-IPアドレス取得の設定
- スーパーネット化
- ネットワーク ゲームにおけるTCPとUDPの使い分け
- DHCPとは
- VXLANとは
- Docker/Kubernetesを扱う上で必要なネットワークの基礎知識(その1)
- Docker/Kubernetesを扱う上で必要なネットワークの基礎知識(その2)
- Dockerのネットワークの仕組み
- TCPやUDPにおけるポート番号の一覧
- TCP ソケットバッファーを調整する
- https://qiita.com/zembutsu/items/9e9d80e05e36e882caaa
- Linuxマシンをルータにする方法
- 第13回 IPとルーティング
- デフォルトゲートウェイの設定 - コロのLinuxサーバー構築
- マルチホストでのDocker Container間通信 第1回: Dockerネットワークの基礎
- マルチホストでのDocker Container間通信 第2回 Port Forwarding と Overlay Network
- マルチホストでのDocker Container間通信 第3回: Kubernetesのネットワーク(CNI, kube-proxy, kube-dns)
- iproute2
- iproute2 wiki
- [netns] 秒速でネットワーク作成 [veth peer]
- LinuxのNetns/veth/Bridge/NATで仮想ネットワーク構築
- ネットワークブリッジ
- カテゴリ:ネットワーク