- 投稿日:2019-11-29T22:55:06+09:00
Docker ComposeでLaravel6.5の環境を作成
少しDockerComposeについて勉強してみたので
試しにLaradockを使わずにDocker ComposeでLaravelの環境構築をしてみます作成する環境
Laravel 6.5.2
php7.3
mysql 8.0.18
nginx 1.17ディレクトリ構成
project ├ docker-compose.yml ├ docker | ├ php │ │ ├ php.ini │ │ └ Dockerfile │ ├ nginx │ │ └ default.conf │ └ mysql │ ├ conf.d │ │ └ default_authentication.cnf │ └ data └ srcPHP用のDockerfileを作成
docker/php/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 RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" RUN php -r "if (hash_file('sha384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" RUN php composer-setup.php RUN php -r "unlink('composer-setup.php');" RUN mv composer.phar /usr/local/bin/composer # rootでのcomposerコマンド実行を許可 ENV COMPOSER_ALLOW_SUPERUSER 1 # composerのグローバルパッケージがインストールされるディレクトリの指定 ENV COMPOSER_HOME /composer # composerのパスを通す ENV PATH $PATH:/composer/vendor/bin # laravelインストール RUN composer global require "laravel/installer" RUN curl -SL https://deb.nodesource.com/setup_13.x | bash RUN apt-get install -y nodejs && \ npm install -g npm@latest && \ npm install -g @vue/cli WORKDIR /var/wwwphp.iniの設定
docker/php/php.ini; timezone date.timezone = Asia/Tokyo ; error reporing log_errors = On error_log = /dev/stderr display_errors = Off ; mbstring mbstring.language = "Japanese"timezoneを東京に
errorログを標準出力エラーに設定
デフォルトで使用する言語を日本語に設定nginxの設定ファイルを記述
docker/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-fpm:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }fastcgi_pass php-fpm:9000;のphp-fpmにはdocker-compose.ymlで定義したサービス名を指定します。
mysql
MySQL8系のデフォルト認証形式を変更するための設定ファイルを作成します
docker/mysql/conf.d/default_authentication.cnf[mysqld] default_authentication_plugin= mysql_native_password続いて、mysqlのデータを永続化するためのディレクトリを作成します
$ mkdir /docker/mysql/datadocker-compose.ymlの作成
docker-compose.ymlversion: '3' services: nginx: image: nginx:1.17-alpine # nginxのimageにnginx:1.17-alpineを指定 container_name: "nginx" ports: - "8080:80" # ホストの8080ポートでnginxコンテナの80にアクセス volumes: - ./src:/var/www # ホストのsrcをnginxコンテナの/var/wwwにマウント - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf # 作成したdefault.confを/etc/nginx/conf.d/default.confにマウント depends_on: # コンテナの依存関係を定義する - php-fpm # php-fpmの起動後にnginxを起動 php-fpm: build: ./docker/php # ./docker/php/Dockerfileをbuildしてイメージ作成 container_name: "php-fpm" volumes: - ./src:/var/www # ホストのsrcをphp-fpmコンテナの/var/wwwにマウント links: # コンテナと他のサービスを繋げる - db depends_on: - db # dbの起動後にphp-fpmを起動 db: image: mysql:8.0.18 # mysqlのimageにmysql:8.0.18を指定 container_name: "db" volumes: - ./docker/mysql/conf.d:/etc/mysql/conf.d # mysqlのせってファイルをマウント - ./docker/mysql/data:/var/lib/mysql # mysqlのデータ永続化 ports: - 3306:3306 environment: MYSQL_DATABASE: hogehoge MYSQL_USER: hoge MYSQL_PASSWORD: hoge MYSQL_ROOT_PASSWORD: root TZ: "Asia/Tokyo" command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ciコンテナ起動
$ docker-compose build $ docker-compose up -dlaravelのプロジェクトファイル作成
$ docker-compose exec php-fpm composer create-project --prefer-dist "laravel/laravel=6.5.2" .確認
これでhttp://localhost:8080にアクセスするとlaravelのページが表示されます
laravelの認証画面まで作ってみる
$ docker-compose exec php-fpm composer require laravel/ui $ docker-compose exec php-fpm php artisan ui vue --auth $ docker-compose exec php-fpm npm run devphp artisan make:auth をしたら怒られました、、、laravel6で変更されたんですね
このためにDockerfileで下記を書いています
RUN curl -SL https://deb.nodesource.com/setup_13.x | bash RUN apt-get install -y nodejs && \ npm install -g npm@latest && \ npm install -g @vue/cli再度確認
http://localhost:8080/register
無事ユーザー登録ページが表示されました
登録してみる
laravelの.envでDBの設定を忘れていたので設定
src/.envDB_CONNECTION=mysql DB_HOST=db DB_PORT=3306 DB_DATABASE=hogehoge DB_USERNAME=hoge DB_PASSWORD=hogeDB_HOST
DB_DATABASE
DB_USERNAME
DB_PASSWORD
をdocker-compose.ymlで定義したものに変更してください
DB_HOSTはDBコンテナのサービス名です認証用のテーブルも作り忘れていたので作成
$ docker-compose exec php-fpm php artisan migrate再度作成!
まだまだDocker勉強中で間違っている所があるかと思いますので
ご指摘ありましたらよろしくお願いいたします?♂️
- 投稿日:2019-11-29T21:56:26+09:00
libsassのalpine向けバイナリーの提供状況
node-sassにバンドルされるlibsassはalpine向けにもバイナリーを配布している。が条件あり。
- 利用してるNode.jsのversionによって、alpine向けに配布をしてるバージョンの範囲が変わる
- 開発版サポートが先に提供中止になる流れ
- 次回or 次々回リリースでは v11向けのalpineバイナリー提供がなくなるっぽい
Node v13: 最新版
v4.13.0
から配布https://github.com/sass/node-sass/releases/tag/v4.13.0
Node v12:
v4.12.0
から配布https://github.com/sass/node-sass/releases/tag/v4.12.0
Node v11:
v4.10.0
から配布https://github.com/sass/node-sass/releases/tag/v4.10.0
- おそらく
v4.13.0
が最後の配布versionにNode v10:
v4.9.0
から配布https://github.com/sass/node-sass/releases/tag/v4.9.0
Node v9:
v4.6.0
からv4.10.0
まで配布https://github.com/sass/node-sass/releases/tag/v4.6.0
v4.11.0
以降は提供されず- 次世代の開発バージョンに配布開始したversionが最後の配布versionに
v8:
v4.5.3~
備考
alpineを使う利点
- イメージサイズが公式イメージと比べて 1/10以下
10.15.1
だと、897MB
=>70.7MB
- インストール所要時間の削減
サポートしてないnode.js alpineイメージへnode-sassをインストールしたい
gypなどを入れればok
apk add --no-cache --virtual .gyp python make g++ \ && apk --no-cache add avahi-dev \ && yarn global add mdns \ && apk del .gyp
- 投稿日:2019-11-29T19:35:29+09:00
chromedriver/seleniumコンテナで.pfxキー認証が必要なサイトにアクセスできるdockerfileを書く
RでWEBスクレープ、慣れるとひょひょひょーいと書けてホントに便利です。
で、たまにあるんですよねちゃんとセキュリティしてらっしゃる会社さん。
実に素晴らしい事なのですが、レア過ぎてなかなか情報が無かったので突破法だけ書きたいと思います。なぜできないか
対策は:
1. dockerfile内でユーザレベルで追加する
2. chrome policyで、証明書の自動セレクトを有効にです。
dockerfile 作ろう
まずは dockerfile と同じ階層に下記のファイルを用意します。
/keys_dir.key_password.txt - .pfxファイルのパスワードを平文で key.pfx policy.json - chrome policy 設定ファイル (下記)Chrome policy ファイルの中身はこちら
policy.json{ "AutoSelectCertificateForUrls": ["{\"pattern\":\"*\",\"filter\":{}}"] }上記を用意したら、dockerfileを作成します。
FROM selenium/standalone-chrome-debug # chrome policy COPY keys/policies.json /etc/opt/chrome/policies/managed/ # key 関連 COPY keys/* /home/seluser/keys/ # 必要なツールをインストール RUN sudo apt-get update RUN sudo apt-get install libnss3-tools # 証明書をユーザに追加 RUN mkdir -p /home/seluser/.pki/nssdb RUN certutil -d /home/seluser/.pki/nssdb -N RUN pk12util -d sql:/home/seluser/.pki/nssdb -i /home/seluser/keys/key.pfx -w /home/seluser/keys/key_password.txtあとはお好きな名前をつけてビルドします
build.shdocker build --rm --force-rm -t mytools/selenium-withcert .実行しましょう。
僕はダウンロードに使うことが多いのでこのように -v でマウントします。run.shdocker run -d --restart always -v /dev/shm:/dev/shm -p 4444:4444 -p 5900:5900 -v ~/sel_dl:/home/seluser/Downloads --name selenium_cert mytools/selenium-withcert以上です!!!
けっこう情報が無くて調べるの苦労しました。
いつか誰かの役に立つはず...おまけ
たぶん関係ないと思うんですが、もし上でうまく行かなかった方のために、
参考までに他に僕がしてるprefs/argsの設定も晒しておきます。
(まさかのRだぞわっはっは。python/java他の方は読み替えをお願いします)RSelenium_chromedriver.Rchrome_prefs = list( "profile.default_content_settings.popups" = 0L, "download.prompt_for_download" = FALSE, "download.directory_upgrade" = TRUE, "safebrowsing.enabled" = FALSE, "safebrowsing.disable_download_protection" = TRUE, "acceptSslCerts" = TRUE ) chrome_args = c('--ignore-certificate-errors', '--ignore-urlfetcher-cert-requests', '--no-sandbox', '--disable-gpu', '--disable-web-security', '--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100') eCaps_withhead = list(chromeOptions = list( prefs = chrome_prefs, args = chrome_args ) ) # 初期化 remDr <- remoteDriver( remoteServerAddr = sel_ip, port = sel_port, browserName = "chrome", extraCapabilities = eCaps_withhead )[EOF]
- 投稿日:2019-11-29T19:13:26+09:00
【Rails】Docker+Rails環境でpryの`edit`コマンドが使えなかったので、使えるようにした
はじめに
DockerとRailsを使った開発環境でpryの
edit
コマンドが効かなかったので対処してみたときの記録です。※Docker環境下での話です。ローカルでは普通に動作しましたので、割愛します。
この記事が役に立つ方
- あれ?なんか
edit
コマンド効かなくね?と思っている方この記事のメリット
- Docker環境下でpryの
edit
コマンドが使えるようになる環境
- macOS Catalina 10.15.1
- zsh: 5.7.1
- Ruby: 2.6.5
- Rails: 5.2.3
- Docker: 19.03.5
- docker-compose: 1.24.1
pryの
edit
コマンドとは?以下、公式のWikiです。
Editor integration · pry/pry Wiki · GitHubThe edit command is used to invoke your default editor. This command will load your file once you have finished editing it (unless you pass the -n or --no-reload flag to edit).
pryの画面でそのままデフォルトのエディタを開き、ファイルの編集が出来るコマンドです。
これまでpryの画面上からファイルをいじったりはしていなかったのですが、デバッグ効率が上がるかなと思ったので導入します。
【事前準備】
こちらのドキュメントに従ってDocker環境下でgem pry-railsを使うための準備は済ませておきました。
Using pry-rails with Docker · GitHub
上記ドキュメントの流れは以下の通りです。
docker-compose.ymlapp: tty: true stdin_open: true上記設定を追加。
↓Gemfilegroup: :development gem 'pry-rails' endgemを追加。
↓docker-compose buildビルド。
↓docker-compose up起動。
↓docker psRailsアプリの
CONTAINER ID
かNAMES
を確認
↓docker attach `CONTAINER ID`か`NAMES`↓
binding.pry ※好きなところでこれで普通にpryでデバッグ可能な状態になります。
とりあえず
edit
コマンド使ってみようとする※Docker環境下です。
とりあえず
edit
コマンドを叩いてみます。[1] pry(main)> edit Error: Please set Pry.config.editor or export $VISUAL or $EDITORするとエラー発生。
Pry.config.editor
か、環境変数$VISUAL
か$EDITOR
を設定してねという内容。先程のWikiの、Setting the default editorのくだりに設定方法が記載されていたので、その通りに進めてみます。
1.
~/.pryrc
を作成・設定pryの設定ファイルは
.pryrc
です。
今回はなかったので作成しました。以下設定方法についてです。
Editor integration · pry/pry Wiki · GitHub今回エディタはvimを使いたかったので、以下のように設定。
~/.pryrcPry.config.editor = proc { |file, line| "vim #{file}:#{line}" }該当のファイルと行に飛んでくれる仕様に例にならってみましたが、うまくいきません。
ローカルの設定ファイルは読み込まれないんですね。
2.Railsアプリのディレクトリ内に
.pryrc
を配置する。下記記事を参照し、Railsアプリのルートディレクトリに
.pryrc
を配置してみることにしました。docker-compose上のRailsのデバッグを行う - My External Storage
./.pryrcPry.config.editor = proc { |file, line| "vim #{file}:#{line}" }※設定は先程と同様です。
もう一回試します。
[1] pry(main)> edit Error: `vim ファイル名:行数` gave exit status: 127別のエラー発生。
惜しい!コマンド自体は正しそうに見えますが、127
なるエラーが。何これ?と思って調べると、
「コマンドが見つからない、もしくはタイポ」
らしいと判明。...ということは、そもそも
vim
がない?3.
vim
をインストールするなければいくらコマンドが正しくても、どうしようもないですよね。
調べると、こちらの記事を発見しました。
Docker — docker コンテナの中で vim が使えない場合 - QiitaDockerfileapt-get install vim上記を追記。
↓docker-compose build↓
docker-compose up↓
rails c
などでpry起動。[1] pry(main)> edit #=>vim起動無事起動!
おわりに
最後まで読んで頂きありがとうございました
vimがないという環境もあるのかとびっくりしましたが、ローカルとDocker環境の境目を意識するいい経験になりました
これでデバッグ効率が上がりそうです
参考にさせて頂いたサイト(いつもありがとうございます)
- 投稿日:2019-11-29T18:43:57+09:00
稼働中のコンテナのシェルに入りたい~attachとexecの違い~
環境
・windows 10
・Docker version 19.03.5目的とゴール
・attachとexecの違いが分かるようになる
・起動中のコンテナのシェルに入れるようになるattachとexecの違い
attach
稼働中のコンテナに入るコマンド。
コンテナで実行中のプロセスが開始される。
つまり、docker ps
で表示されるCOMMAND
のコマンドが実行される。exec
現在稼働しているコンテナで新たなプロセスを開始できるコマンド。
シェルに入りたい場合は下記コマンドを実行する。
docker exec -it XXXXXXXXXX /bin/bash
つまり稼働中のシェルに入りたい場合は、
①docker psでCOMMANDが/bin/bash
の場合
②それ以外の場合の2パターンに分かれることになります。
パターン1:docker psでCOMMANDが/bin/bashの場合
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 72a12e05690c ubuntu "/bin/bash" 29 hours ago Up 8 seconds hungry_bassi実行中のプロセスは
/bin/bash
となります。
こういう時はattach
してあげればシェルに入れます。> docker attach 72a12e05690c root@72a12e05690c:/#ちなみにSTATUSが
Exited
の場合は、docker start -ai XXXXXXXX
で入れますね。
attachはあくまで稼働中のコンテナのプロセスに入るものであって、止まっているものについては再度スタートしてあげる必要があります。パターン2:それ以外の場合
docker psでCOMMANDが
/bin/bash
以外の場合はどうでしょうか。>docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 205974b714d2 httpd "httpd-foreground" 20 hours ago Up 5 seconds 0.0.0.0:80->80/tcp nostalgic_maxwellこの場合、attachしてもダメです。
稼働中のコンテナのコマンドは"httpd-foreground"
であって、シェルではないからです。こういう時は
exec
コマンドを使って新たにプロセスを開始します。
/bin/bashを指定してあげるわけです!>docker exec -it 205974b714d2 /bin/bashおまけ:稼働中"ではない"コンテナのシェルに入るには
パターン1 そもそもコンテナがない場合
docker run -it 【コンテナID】/bin/bash
/bin/bash
を指定して、イメージから新たに立ち上げてあげればいいですね。パターン2 コンテナがあるが、Exitedの場合
docker start -ai 【コンテナID】スタートしてあげる必要がありますね。
もちろんCOMMAND
が/bin/bash
であることが前提となります。
COMMAND
が/bin/bash
以外の場合には、一旦スタートしてその後
docker exec -it XXXXXXXXXX /bin/bash
でシェルに入りましょう!
- 投稿日:2019-11-29T17:22:37+09:00
kubernetes on minikubeで、DockerイメージがPullできない件について
Minikubeとは
ローカル環境で(比較的)簡単にkubernetes環境を構築できるツール・仮想環境で、VirtualBoxなどの上で動作します。
詳しくは、公式ドキュメント等をご確認くださいどハマりしたポイント
今回、なんと丸2日ハマった問題への対応策と、何をチェックすべきなのかの備忘録として記載します。
なので、説明不足とかあります。 追記の希望等々はコメント欄までよろしくお願いしますmm環境
- Minkube (with inside Docker) feat. Kubernetes
- MacOS Catalina
- Docker for MacOS
やりたかった事
- Minikubeを起動し、
eval $(minikube docker-env)
- ローカルディスク上にDockerイメージをbuild(docker build ...)
kubectl apply ...
kubectl get pod
でRunningになってればOKのはずだった。。。
PullError
なんてみたくなたかったうまく行かないポイント
1. docker build ...
-t xxxx
のxxxxが間違ってる
- これは単純でわかりやすいです。名前が不一致なので探しきれず、リモートを探すもさらに見つけきれず。。。って言う状態
- pruneコマンド等でイメージを削除して作り直しましょう
2. imagePullPolicyがAlwaysになってる
kubectl edit deployment xxxxx
でチェック- これがAlwaysになってると、ローカルのDockerイメージが古いかもしれないからと、リモートを検索してエラーになります。
IfNotPresent
(ローカルになかったらリモート探してね)。またはNever
(ローカルが正だ!)を設定する事で回避3.
eval $(minikube docker-env)
が無効になってる
- 意外と気づかない
- 契機はわからないけど、PCがスリープに入ったりしたくらいでも無効になる模様
- イメージ名も合ってる、IfNotPresentも設定したのにPullエラーが起きる様なら疑うべき
- 対応策
kubectl delete deployment xxxx
kubectl delete service xxxx
- kubectl get pod / service / deploymentでお亡くなりになっている事を確認
minikube stop
minikube start
eval $(minikube docker-env)
kubectl apply ...
終わり
仮想化技術はトラブルにずば抜けて強く、チーム開発でも導入にもたつかないメリットがとっても魅力的ですが、目に見えないしログにも現れない’繋がり’の問題が発生すると厄介だなと思い知らされました。。。
この問題は今回の様にローカルの開発環境だからこそ発生する問題で、通常通り稼働しているkubernetes環境では発生しないものと思われます。
トラブルシューティングツールか何か合ったら嬉しいけど、、、大体のケースでは上手くいくはずって事なのかな
作成した方がいたらコメントで教えてください(笑
- 投稿日:2019-11-29T16:16:47+09:00
今更Dockerの便利さに気がついたけど、最終的によく分からなくなった話
はじめに
現実逃避のために、自分の遊びの環境をsakura vpsに作ることにしたがsakuraでは環境が保存できないらしいので、代案手段として、Dockerでやってみようと思い立ちました。
やりたいこと
Docker上に、Nginxのサーバーを立ててSSL化する。
いつもの更地化。
Dockerのインストール
個人利用なので、無償版のDocker-ceを入れます。
- コンソールからログイン用のユーザを作って。
- 忘れちゃいけない。yumを更新。
$sudo yum update
- 必要なパッケージをインストールします。
$sudo yum install -y yum-utils device-mapper-persistent-data lvm2
- Docker CEをインストールするため、yumのリポジトリを追加します。
$sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- Dockerインストール
最新バージョン入れます。
$sudo yum install docker-ceインストール完了。
Dockerを起動します。
$ sudo systemctl start dockerNginxを入れて起動してみる。
Nginxイメージを使ってコンテナを起動します、外部からはポート:8080でアクセスするようにして起動。
$ sudo docker container run -itd --name nginx-container -p 8080:80 nginxDockerから状態をみるとNginxが起動してることが確認が取れました。
$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7a5f699f72db nginx "nginx -g 'daemon of…" 6 hours ago Up 6 hours 0.0.0.0:8080->80/tcp nginx-containerDockerのNginxを停止する。
$ docker stop 7a5f699f72db 7a5f699f72db $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7a5f699f72db nginx "nginx -g 'daemon of…" 6 hours ago Exited (0) 2 seconds ago nginx-containerSTATUSがExitedで停止してます。ブラウザから見ても停止していました。
ここでは、[CONTAINER ID]を指定しましたが、[NAMES]を指定してしても停止できます。Dockerからnginxのコンテナを削除する。
$ docker rm 7a5f699f72db 7a5f699f72db $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES停止と同様に、ここでは[CONTAINER ID]を指定しましたが、[NAMES]を指定してしても削除できます。
DockerからNginxのイメージを削除する。
現在のイメージを確認します。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 231d40e811cd 3 days ago 126MBNginxのイメージが存在しているので、削除します。
$ docker rmi 231d40e811cd Untagged: nginx:latest Untagged: nginx@sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566 Deleted: sha256:231d40e811cd970168fb0c4770f2161aa30b9ba6fe8e68527504df69643aa145 Deleted: sha256:dc8adf8fa0fc82a56c32efac9d0da5f84153888317c88ab55123d9e71777bc62 Deleted: sha256:77fcff986d3b13762e4777046b9210a109fda20cb261bd3bbe5d7161d4e73c8e Deleted: sha256:831c5620387fb9efec59fc82a42b948546c6be601e3ab34a87108ecf852aa15f $ docker images REPOSITORY TAG IMAGE ID CREATED SIZEイメージが削除されました。
ここでは[IMAGE ID]を指定しましたが、[REPOSITORY]を指定してしても削除できます。綺麗になりました。めっちゃ便利です。
なんで今まで使ってなかったのか悔やまれます。Dockerの構造
Dockerの構造として、イメージとコンテナという概念があり、イメージが概念で、コンテナが実態のようです。
クラスとインスタンスの関係と同様のようです。
NginxをHTTPS化したなと思って、Docker Hubを見てたら、Certbotはあったのですが、連携の仕方がわからず、なんかいい方法が無いものかと思って調べていたら、Docker HubにCentOSのイメージもあることに気が付きました。つまり、今までDockerの上にNginxやなんやらかんやらの載せて管理するのかなと思っていましたが、Dockerの上にOS載せて、その上でNginxを載せられる?もしそうならもっと楽に構築できるじゃないかと思い立ちました。
CentOSを起動する
イメージを取得する。
$ sudo docker pull centos:centos7 centos7: Pulling from library/centos ab5ef0e58194: Pull complete Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c Status: Downloaded newer image for centos:centos7 docker.io/library/centos:centos7 $sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos centos7 5e35e350aded 2 weeks ago 203MBイメージを起動して、ログインする。(exitするとDockerのCentOSから脱出できます。)
$ sudo docker run -it -d --name centos7 5e35e350aded docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9927906158a2 centos "/bin/bash" 10 seconds ago Up 9 seconds centos7 $ sudo docker exec -it centos7 /bin/bash [root@9927906158a2 /]# ls bin etc lib lost+found mnt proc run srv tmp var dev home lib64 media opt root sbin sys usrコンテナのCentOSにNginxをインストールする
Docker上のCentOS上のyumを更新します。
Nginxをインストールします。NginxのInstallation instructionsにしたがってインストールします。$ yum update $ yum install yum-utils/etc/yum.repos.d/nginx.repoファイルを作成します。
$ vi /etc/yum.repos.d/nginx.repo
記載内容
nginx.repo[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=trueNginxのインストールし、起動しようとした処で、D-Busの権限エラーが発生しました。
$ yum-config-manager --enable nginx-mainline $ yum install nginx $ systemctl start nginx Failed to get D-Bus connection: Operation not permitted調べて見ると、 docker runする際に、--privilegedのオプションと、公開するにあたってポートの公開が必要なようです。
そこで、今のイメージを保存して、上記の2つのオプションをつけて起動し直すことにしました。
手順としては、今のコンテナを停止させてから、イメージを作成します。$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4073d82ac893 5e35e350aded "/bin/bash" 9 minutes ago Up 9 minutes centos7 $ sudo docker stop 4073d82ac893 $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4073d82ac893 5e35e350aded "/bin/bash" 13 minutes ago Exited (137) 12 seconds ago centos7イメージのステータスがExitedになり、止まった状態になったので、イメージを作成します。
docker commit NAMES(または、CONTAINER ID) 作成イメージ名
$ sudo docker commit 4073d82ac893 centos7n $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos7n latest 0c30b8b87f37 19 seconds ago 347MB centos centos7 5e35e350aded 2 weeks ago 203MB作成したイメージの先程のオプションつけて起動します。Exitedを起動します。
$ sudo docker run -d --privileged -p 80:80 -p 443:443 centos7n /sbin/init $ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 550d5d2474b9 centos7n "/sbin/init" 9 seconds ago Up 8 seconds 0.0.0.0:80->80/tcp stupefied_moser 4073d82ac893 5e35e350aded "/bin/bash" 23 minutes ago Exited (137) 10 minutes ago centos7 $ sudo docker exec -it stupefied_moser /bin/bash $ systemctl start nginx今度は無事起動でき、外部からアクセスできことを確認しました。次にやりたいのはHTTPS化です。
以前、使ったLet's EncryptからSSL証明書を取得してHTTPS化します。HTTPS化する。
Certbotをインストールします。certbotの手順を見ながらインストールします。
$ yum -y install yum-utils $ yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional $ yum install certbot python2-certbot-nginx Loaded plugins: fastestmirror, ovl Loading mirror speeds from cached hostfile * base: ftp-srv2.kddilabs.jp * extras: ftp-srv2.kddilabs.jp * updates: ftp-srv2.kddilabs.jp No package certbot available. No package python2-certbot-nginx available. Error: Nothing to doなんかエラーが出ました。パッケージがないとのこと。
epelを追加して、再度インストールでうまくいきました。$ yum install epel-release $ yum install certbot python2-certbot-nginx証明書を取得します。
管理者のメールアドレスが求められるので入力します。$ certbot --nginx Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator nginx, Installer nginx Enter email address (used for urgent renewal and security notices) (Enter 'c' toライセンスに同意するか聞かれるので、Aを入力します。
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (A)gree/(C)ancel:
メールアドレスをシェアするとか言ってるので、Nを入力します。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Would you be willing to share your email address with the Electronic Frontier Foundation, a founding partner of the Let's Encrypt project and the non-profit organization that develops Certbot? We'd like to send you email about our work encrypting the web, EFF news, campaigns, and ways to support digital freedom. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ドメイン名を入力します。(Let's Encryptでドメイン指定する際はwwwをつけた状態にします。)
No names were found in your configuration files. Please enter in your domain
エラーが発生した。
Obtaining a new certificate Resetting dropped connection: acme-v02.api.letsencrypt.org Performing the following challenges: http-01 challenge for ドメイン名 Using default address 80 for authentication. Waiting for verification... Challenge failed for domain ドメイン名 http-01 challenge for ドメイン名 Cleaning up challenges Some challenges have failed. IMPORTANT NOTES: - The following errors were reported by the server: Domain: ドメイン名 Type: connection Detail: Fetching http://ドメイン名/.well-known/acme-challenge/dlxpxIAt0fMvR90N0bBWnTTcAvu_XTHSV6jyKOC872M: Connection refused To fix these errors, please make sure that your domain name was entered correctly and the DNS A/AAAA record(s) for that domain contain(s) the right IP address. Additionally, please check that your computer has a publicly routable IP address and that no firewalls are preventing the server from communicating with the client. If you're using the webroot plugin, you should also verify that you are serving files from the webroot path you provided. - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal.[http://ドメイン名/.well-known/acme-challenge/]にアクセスしようとしてるようなので、Nginx設定ファイルの編集して場所を設定します。
以下にアクセスの場所を作ります。
/var/www/acme-challenge設定ファイルをバックアップを作成し、編集します。
console
$ cp /etc/nginx/conf.d/default.conf default.conf.org
$ vi /etc/nginx/conf.d/default.conf
[location ^~ /.well-known/acme-challenge/]の振替先を追加
default.confserver { listen 80; server_name localhost; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } # 追加した location ^~ /.well-known/acme-challenge/ { root /var/www/acme-challenge; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { -- INSERT --Nginxをリスタートします。certbotを再び起動しドメイン名を登録します。
$ systemctl restart nginx $ certbot --nginx Saving debug log to /var/log/letsencrypt/letsencrypt.log Plugins selected: Authenticator nginx, Installer nginx Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org No names were found in your configuration files. Please enter in your domain name(s) (comma and/or space separated) (Enter 'c' to cancel): ドメイン名 Obtaining a new certificate Performing the following challenges: http-01 challenge for ドメイン名 Using default address 80 for authentication. Waiting for verification... Cleaning up challenges Could not automatically find a matching server block for ドメイン名. Set the `server_name` directive to use the Nginx installer. IMPORTANT NOTES: - Unable to install the certificate - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/ドメイン名/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/ドメイン名/privkey.pem Your cert will expire on 2020-02-27. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew"成功したら、再び設定ファイルを編集し、SSL接続の設定を追加します。
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/ドメイン名/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem;$ vi /etc/nginx/conf.d/default.conf
default.confserver { listen 80; server_name localhost; # 追加した listen 443 ssl; ssl_certificate /etc/letsencrypt/live/ドメイン名/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/ドメイン名/privkey.pem; #charset koi8-r; #access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } location ^~ /.well-known/acme-challenge/ { root /var/www/acme-challenge; } #error_page 404 /404.html;Nginxを再起動して、HTTPSで接続の確認します。
systemctl restart nginx
が、なんか違う…こんなに面倒な設定は、Dockerに任せたいはずだった。
自分がやりたかったことを一回整理
- 環境を破壊したりするので、状態を保存して、適度なタイミングで復帰したい。
- 自家製のコンテンツも環境と同じように切り替えられるようにしたい。
- ログは、コンテンツ扱いにすると消えるので、指定の場所に保存したい。
もう一回構成を含めて検討してきます。
- 投稿日:2019-11-29T15:10:08+09:00
Kubernetes v1.16
環境構築
クラスター構成管理ツールをインストール
kind, minikube, microkube などから、どれかを選択するか、
GKE, AKS, EKS などから、どれかを選ぶ。
Kubernetes v1.16 が選べるものの中から選ぶ。kind
iKind() { curl -sLo kind https://github.com/kubernetes-sigs/kind/releases/download/$( git ls-remote --tags --refs https://github.com/kubernetes-sigs/kind.git | tail -1 | awk -F/ '{print $3}' )/kind-$(uname)-amd64 chmod +x kind sudo mv kind /usr/local/bin } && iKindminikube
xdg-open https://kubernetes.io/ja/docs/tasks/tools/install-minikube/microk8s
xdg-open https://microk8s.io/docs/Docker をインストール
iDocker() { curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" sudo apt install -y docker-ce apt-transport-https sudo usermod -aG docker $(whoami) } && iDocker $SHELL -lkubectl をインストール
iKubectl() { curl -LO https://storage.googleapis.com/kubernetes-release/release/$( curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt )/bin/linux/amd64/kubectl chmod +x kubectl sudo mv kubectl /usr/local/bin } && iKubectlnodejs をインストール
iNodejs() { curl -o- https://raw.githubusercontent.com/creationix/nvm/$( git ls-remote --tags --refs https://github.com/nvm-sh/nvm.git | grep -P 'v0.\d\d' | tail -1 | awk -F/ '{print $3}' )/install.sh | bash . ~/.bashrc LATEST=$(nvm ls-remote | grep 'Latest LTS' | tail -1 | awk '{print $1}') nvm install $LATEST nvm alias default $LATEST nvm use $LATEST node --version npm --version id } && iNodejs環境変数
example() { export KINDNAME=example export KINDHTTP=80 export KINDHTTPS=443 export KINDCONFIG=multinode.yaml curl -O https://raw.githubusercontent.com/jobscale/_/master/cloud/k8s/multinode.yaml exposedDeployment() { kubectl create deployment $1 --image $2 kubectl expose deployment $1 --name $1 --type LoadBalancer --port $3 --target-port $4 [[ "$5" != "0" ]] && kubectl autoscale deployment $1 --cpu-percent 50 --min $5 --max 20 } } && exampleクラスターを作成
createKind() { rm -fr ~/.kube/config ln -sfn kind-config-$KINDNAME ~/.kube/config kind create cluster --config $KINDCONFIG --name $KINDNAME } && createKind全てのノードが Ready になるのを待つ
kubectl get nodes -o wide -w全てのポッドが Running になるのを待つ
kubectl get pods -A -o wide -w名前空間を設定
createNamespace() { kubectl create namespace standard kubectl config set-context $(kubectl config current-context) --namespace standard kubectl apply -f https://raw.githubusercontent.com/jobscale/_/master/cloud/k8s/limitrange-limits.yaml } && createNamespaceノードのリソースを確認
kubectl describe nodesメトリクスサーバーをデプロイ
metricsServer() { git clone https://github.com/kubernetes-sigs/metrics-server.git kubectl apply -f metrics-server/deploy/1.8+ } && metricsServerロードバランサーをデプロイ
metalLB() { METAL_VERSION=$(git ls-remote --tags --refs https://github.com/danderson/metallb.git | tail -1 | awk -F/ '{print $3}') echo -e "\n MetalLB ${METAL_VERSION} \n" kubectl apply -f https://raw.githubusercontent.com/google/metallb/${METAL_VERSION}/manifests/metallb.yaml kubectl apply -f https://git.io/km-config.yaml } && metalLBイングレスをデプロイ
ingressNginx() { kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml } && ingressNginx管理ダッシュボードをデプロイ
adminDashboard() { kubectl apply -f https://raw.githubusercontent.com/jobscale/_/master/cloud/k8s/kubernetes-dashboard.yaml kubectl apply -f https://raw.githubusercontent.com/jobscale/_/master/cloud/k8s/admin-user-service-account.yaml } && adminDashboardアプリをデプロイ
アプリをデプロイ
wetty をデプロイ
exposedDeployment wetty jobscale/wetty 443 3000 0laravel をデプロイ
exposedDeployment laravel jobscale/laravel 80 80 3ラーメンタイマーをデプロイ
exposedDeployment ramen-timer jobscale/ramen-timer 80 80 3wordpress をデプロイ
exposedDeployment wordpress jobscale/wordpress 80 80 3django をデプロイ
exposedDeployment django jobscale/django 80 80 3dokuwiki をデプロイ
exposedDeployment dokuwiki jobscale/dokuwiki 80 80 3tomcat をデプロイ
exposedDeployment tomcat tomcat 80 8080 3ポート転送
sudo -E kubectl port-forward --address 0.0.0.0 svc/tomcat 80:80 xdg-open http://127.0.0.1管理ダッシュボード
トークンの表示
token() { kubectl -n kube-system describe secret $( kubectl -n kube-system get secret | grep admin-user | awk '{print $1}' ) } && tokenポート転送
sudo -E kubectl -n kubernetes-dashboard port-forward --address 0.0.0.0 svc/kubernetes-dashboard 443:443google-chrome-stable
google-chrome-stable https://127.0.0.1おわりに
いらないやつもありますが、あえて書きました。
各自、自分の環境に合わせて読みかえてください。
以上
- 投稿日:2019-11-29T14:09:51+09:00
verdaccio + Docker + GCE でprivateなnpmレジストリを立てる
概要
社内のいくつかのアプリに共通で組み込むため、npmライブラリを作ったものの、
npmにpublishして全世界に公開する訳にもいかないので、verdaccioを使って社内に公開可能なnpmレジストリを作成するverdaccio
ローカルにnpmのレジストリを構築するためのツール。
docker-examples にdocker run
するだけで構築可能なサンプルが豊富にあるため、
今回はこの中から Docker + Apache + Verdaccio を選択してGCE上に構築していく構築手順
1. GCEインスタンスの起動
無料枠内で収めたいので、とりあえず1番小さいインスタンス
ディストリビューションはUbuntuを選択した
- MachineType: f1-micro
- Image: Ubuntu 18.04 LTS
- Allow HTTP traffic
gcloud beta compute --project=<your_project_id> instances create verdaccio \ --zone=asia-northeast1-b --machine-type=f1-micro --tags=http-server,https-server \ --image=ubuntu-1804-bionic-v20191113 --image-project=ubuntu-os-cloud \ --boot-disk-size=10GB --boot-disk-type=pd-standard --boot-disk-device-name=verdaccioGCEが起動したらSSH接続し、以降の作業はインスタンス内で実施する
2. docker + docker-compose をインストールする
3. verdaccioのサンプルをcloneし、docker-composeする
$> git clone https://github.com/verdaccio/docker-examples.git $> cd docker-examples/apache-verdaccio/ $> sudo docker-compose up -d . . . Creating verdaccio ... done Creating apache-verdaccio_apacheproxy_1 ... done4. 起動に成功したらブラウザからアクセスしてみる
httpsだとアクセスできないので、httpに修正してアクセスする
- こんな感じの画面が表示されたら成功
運用手順
- ここからはローカルPCに戻って作業する
1. npmライブラリをpublishしてみる
- ライブラリのdistフォルダ内で以下を実行してpublishする
$> npm set registry http://<external_ip> $> npm publish --registry http://<external_ip>2. レジストリを確認してみる
verdaccioに再度アクセスしてみる
publishしたライブラリが表示されていれば成功
3. ライブラリをインストールしてみる
$> npm install --save my-library --registry http://<external_ip>
- 正しくライブラリがインストールされたら成功
- 他の一般公開されているライブラリと同じように扱うことができる
- 投稿日:2019-11-29T13:13:58+09:00
kindで軽量テスト用Kubernetesクラスタを作る&運用する時のTIPS
この記事は、Kubernetes3 Advent Calendarの第1日目です。
Kubernetes最軽量構築ツール
kind
のよさ、初回起動方法、仕組み、TIPS(ホストディレクトリのマウント)、メンテナンス方法を紹介します。仕掛けがわかるととても楽しいですよ。
kind
のよさ以下のような良さがあるKubernetes最軽量構築ツールです。
- 軽量 = 前提としてDockerがインストールされたホストが一つあれば済む
- クリーン = ホスト環境を何も汚さない
- 作業ほぼゼロ = コマンド一発で作成、削除可能
まず
kind
を動かしてみるまで参考になるドキュメント
kind
を動かす環境の前提
- dockerがインストールされている
- kubectlがインストールされている
今回は検証のため、Windows上のVirtualBox上のVMでDocker本体を動かして確認しましたが、私自身Ubuntu上でもMacでも同じ構成を作った実績があります。
kind
コマンドのインストール以下はすべてDockerインストール済みのVM上で実行します。
curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.6.0/kind-$(uname)-amd64 chmod +x ./kind sudo mv ./kind /usr/bin/kindクラスタ構築
kind create clusterdocker上に一つだけコンテナが起動します。
これは、control-planeというKubernetesのマスターノードに相当するコンテナが起動した状態です。
Kubernetesでは、デフォルト設定でマスターノードにコンテナを配置しないように制御されますので、それ以外のワーカーノードも必要になります。
一度今のクラスタを削除して、再度ワーカーノード込みで作り直してみましょう。クラスタ削除
kind delete clusterはい、全部消えました。とてもクリーンです。
ワーカーノードを含めたインストール
kind
用の設定ファイルを新規作成し、ワーカーノードを追加することを記載します。kind.yamlkind: Cluster apiVersion: kind.sigs.k8s.io/v1alpha3 nodes: - role: control-plane - role: workerこの設定を使ってクラスタを作成します。
kind create cluster --config kind.yaml処理の中に
Joining worker nodes
処理が増えているのがわかります。
コンテナが2つ作成されています。
kubectl
で操作するクラスタ作成後に表示される
kubectl cluster-info
をたたくと、ちゃんとコンテキストが追加されていることがわかります。~$ kubectl cluster-info --context kind-kind Kubernetes master is running at https://127.0.0.1:38921 KubeDNS is running at https://127.0.0.1:38921/api/v1/namespaces/kube-system/services/kube-dns:dns/proxyではこのコンテキストを使って
kubectl
で操作しましょう。$ kubectl config use-context kind-kind Switched to context "kind-kind".実際にコンテナを起動してみます。
$ kubectl run --generator=run-pod/v1 test --image=nginx pod/test created動いたかどうかを確認してみます。
~$ kubectl get po NAME READY STATUS RESTARTS AGE test 1/1 Running 0 2m39sコンテナの中にも入ってみます。
$ kubectl exec -ti test /bin/bash root@test:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr varコンテナを消してみます。
$ kubectl delete po test pod "test" deleted
kind
の仕組み2重のコンテナエンジン
Dockerの中にKubernetesのマスターノード(
kind-control-plane
)やワーカーノード(kind-worker
)が起動し、それぞれの中にまたcontainerdというコンテナエンジンが起動する形になっています。ユーザがKubernetes上に作るPodなどのコンテナは、この内部のcontainerdの中に作られます。だから、クラスタを削除したいときはこのcontainerdをまるごと消せばよく、ホストのDockerを汚さないので非常にクリーンに運用できるわけです。
安定した構築方法を採用している
Kubernetesの構築の仕方の中では老舗に部類される、安定した構築ツール
kubeadm
を内部で使っています。
したがって、kubeadm
でできることはこのkind
でもできるという嬉しさもあります。
kind
のTIPSホストのディスクをkind上のpodに見せる
kind
の仕組みで説明した通り、kind
は2重のコンテナエンジン(Docker/containerd)で起動されています。コンテナエンジン自体はホストのディレクトリをコンテナに見せる機能を持っていますが、2重のコンテナエンジンの設定を一括でやってくれるわけではありません。
したがって、ホストのファイルをkind上のコンテナに見せるには、以下のような2重の設定が必要になります。
kind
自体が使っているdockerにホストのディレクトリAをBという名前でマウントする設定をするkind
内部のcontainerdに、BというディレクトリをCという名前でマウントするでは、ホスト上の
/mnt/test/
というディレクトリをコンテナに見せてみます。
/mnt/test/
はこうなっています。$ ls /mnt/test/ myfile.txtこの
myfile.txt
をPodに見せるのがゴールです。ではまず
kind
の設定です。extraMounts
というフィールドで設定します。kind2.yamlkind: Cluster apiVersion: kind.sigs.k8s.io/v1alpha3 nodes: - role: control-plane - role: worker extraMounts: - containerPath: /test hostPath: /mnt/test次にコンテナの設定です。
container.yamlapiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - image: nginx name: nginx volumeMounts: - mountPath: /test name: test-volume volumes: - name: test-volume hostPath: path: /test type: Directoryそれぞれは以下の①②に対応しています。
クラスタの作り直し
kind create cluster --config kind2.yaml確認
$ docker exec -it kind-worker ls /test myfile.txt$ kubectl apply -f container.yaml pod/nginx created $ kubectl exec pod/nginx -it ls /test myfile.txtちゃんとPodからホスト上の
myfile.txt
が見えました。
アプリのログなどのファイルを永続化したい場合に、このテクニックでホストのディレクトリに書き込むことで、kind
やその上のPodが消えてもファイルを残すことができます。ホストのディスクをkind上のapi-server等に見せる
api-serverなどKubernetes自身が持つサービスにもホストのディスクをマウントすることができます。api-serverなどはコンテナとして起動されるという仕組みになっているので、今回もやはり前節と同じで、2重コンテナ構造のため2階層にディレクトリをマウントするという設定がそれぞれ必要となります。
ただし、今回は
kind
起動時の設定ファイルkind3.yaml
のみで設定可能です。理由は、kubeadm
を利用しているkind
では、そのapi-serverなどへの設定も同じファイルで記述できるためです。kind3.yamlkind: Cluster apiVersion: kind.sigs.k8s.io/v1alpha3 nodes: - role: control-plane extraMounts: - containerPath: /test hostPath: /mnt/test - role: worker kubeadmConfigPatches: - | apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration metadata: name: config apiServer: extraVolumes: - name: "test" hostPath: /test mountPath: /testポイントは2つ。
- まず、
api-server
はcontrol-plane
というノードに配置されますので、今回はextraMounts
をcontrol-plane
に記載します。。- 次にこの
KubeadmConfigPatch
の部分です。ここにkubeadm
への設定の差分が書けるというのがkind
の嬉しさの一つでもあります。ディレクトリをマウントする設定のフィールドは、extraVolumes
です。このお作法は、kubeadm
のドキュメントを参考にできます。さて再掲ですが、ホストのディレクトリはこうなっています。
$ ls /mnt/test/ myfile.txtでは、実際にクラスタを構築して確認してみます。
$ kind create cluster --config kind3.yaml確認
$ kubectl exec -n kube-system kube-apiserver-kind-control-plane myfile.txtちゃんとマウントされましたね。api-serverからaudit logなどをホストに書き出したいときにぴったりです。
もうこんなに設定ファイル一個だけでかんたんにKubernetesクラスタがいじれると、楽しくてしょうがなくなりますね。もしVM上のDockerがこんなエラーをはいたら
docker: Error response from daemon: cgroups: cannot find cgroup mount destination: unknown.VMのcgroupの使われ方が少し変なようなので、以下をたたくと回避できます。
sudo mkdir /sys/fs/cgroup/systemd sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
kind
のメンテナンスコンテナイメージを追加する
ホスト上でアプリを開発して、アプリを同梱したコンテナをPodとしてkind上で実行したいときがあります。しかし、kind内のcontainerdはホストのdockerのイメージを直接読めませんので、そのままではPodが起動しません。
ホストのイメージをkind内のcontainerdにアップロードする便利コマンドがあるので、それを使います。kind load docker-image <image:tag>注意が必要なのは、これをすることによってcontrol-planeやworkerすべての内部にイメージがアップロードされるため、ノード数分ディスクを消費することです。
もし特定のノード、たとえばワーカーだけにイメージをアップロードしたい場合は以下のようにします。
kind load docker-image <image:tag> --nodes=<nodename>複数のノードにアップロードする場合には、ノード名をコンマで連結して入れればよいです。
kind load docker-image <image:tag> --nodes=<nodename1>,<nodename2>コンテナイメージを消す
ディスクを圧迫してきたら、使わないコンテナイメージを削除することをお勧めします。
まず確認する
$ docker exec kind-control-plane crictl images IMAGE TAG IMAGE ID SIZE k8s.gcr.io/coredns 1.6.2 bf261d1579144 44.2MB k8s.gcr.io/etcd 3.3.15-0 b2756210eeabf 248MB k8s.gcr.io/kube-apiserver v1.16.3 6750aac993260 185MB k8s.gcr.io/kube-controller-manager v1.16.3 74308f46cf2d3 128MB k8s.gcr.io/kube-proxy v1.16.3 2388adcec48cf 103MB k8s.gcr.io/kube-scheduler v1.16.3 0f7390a0dfb32 105MB docker.io/kindest/kindnetd <none> aa67fec7d7ef7 32.4MB k8s.gcr.io/pause 3.1 da86e6ba6ca19 746kB test 0.1 xxxxxxxxxxxxx 1.0GB見つけたイメージを消す
docker exec kind-control-plane crictl rmi test:0.1同じことをworkerに対しても実行する
kind-control-plane
のところをkind-worker-1
などに変えると同じ事が実行できます。ログを一括して吐き出す
Kubernetes周りのサービス(たとえばapi-server)のログを出力したいとき、便利コマンドが用意されています。
kind export logsまとめ
kind
は軽量、クリーンなKubernetesテスト環境で、とても便利です。さまざまなKubernetes関係の開発者が利用していることも知られています。
TIPSで紹介したように、うまくすればホストのディレクトリもマウントできます。
開発者は「本番系には使わないでね」、と言っていますので、使い方は気を付けたほうがよさそうです。参考情報
https://qiita.com/it__chago/items/c7d057d968da934199da
https://speakerdeck.com/ytaka23/cloud-native-developer-jp-13th
https://qiita.com/sourjp/items/281d2189516823950291
- 投稿日:2019-11-29T10:10:37+09:00
VSCode拡張機能の「Cloud Code」
概要
Googleが提供するVSCodeでkubernetes(GKE)の作成、デプロイなどを簡単に行えるようになるツールです。
日本語ではまだβになっていますが、英語版では正式リリースになっています。
Googleが開発していますが、AWSやAzureのマネージドKubernetesにも対応しているようです。
- 公式
環境
- MacOSX
- Catalina 10.15.1
- Visual Stadio Code
- Version: 1.40.2
- gcloud
- Google Cloud SDK 271.0.0
- 認証済み
- Docker
- version 19.03.5
- Skaffold
How to Use
インストールから実際の使い方まで
インストール
Cloud Codeで検索すると出てきます。
(画像はすでにインストール済み)
実際の動作
GKEクラスターの作成
コマンドパレットに
Cloud Code
と入力すると候補が出ます。
Cloud Code:Create GKE cluster
を選択します。
クラスターの設定画面が表示されるので順次設定していきます。
- Step1 プロジェクトIDの設定
クラスターを作成するプロジェクトIDを入力します。
- Step2 リージョン/ゾーンの選択
リージョンでasia-northeast1を選択します。
- Step3 詳細設定
クラスターの名前やノード数、ノードインスタンスの種類を設定します。入力したらCreate Clusterボタンを押下してしばらく待ちます。
作成したGKEクラスターの確認
インストールするとアイコンが追加されます。
これでKubernetesのクラスターを確認できます。
クラスター作っただけなんで中身は何もありません。新しいクラスターの作成
Cloud Code: New Application
を選択すると新しいクラスターが作成できます。
デフォルトでは${HOME}/cloudcode-projects/go-hellow-world-1になっていました。
VSCodeが今開いてるフォルダにしろ
ファイルが作成されます。
作成したクラスターの実行
ローカルのDockerを利用するためDefaultを選択します。
コンテナのビルドやリソースのデプロイが行われます
ビルドデプロイログ
Running: skaffold run --enable-rpc -v info --rpc-http-port 59310 --filename skaffold.yaml Running: skaffold dev -v info --rpc-http-port 59346 --filename skaffold.yaml Running: skaffold run --enable-rpc -v info --rpc-http-port 59353 --filename skaffold.yaml Running: skaffold run --enable-rpc -v info --rpc-http-port 59363 --filename skaffold.yaml starting gRPC server on port 50051 starting gRPC HTTP server on port 59363 Using kubectl context: docker-desktop Generating tags... - go-hello-world -> go-hello-world:latest Checking cache... Tags generated in 96.073µs - go-hello-world: Not found. Building Found [docker-desktop] context, using local docker daemon. Building [go-hello-world]... Cache check complete in 2.724232184s Sending build context to Docker daemon 57.34kB Step 1/8 : FROM golang:1.13 1.13: Pulling from library/golang 16ea0e8c8879: Pulling fs layer 50024b0106d5: Pulling fs layer ff95660c6937: Pulling fs layer 9c7d0e5c0bc2: Pulling fs layer 2a19d2e6789c: Pulling fs layer bd9cab5aeb31: Pulling fs layer 0ed236c95063: Pulling fs layer 2a19d2e6789c: Waiting bd9cab5aeb31: Waiting 0ed236c95063: Waiting 9c7d0e5c0bc2: Waiting ff95660c6937: Verifying Checksum ff95660c6937: Download complete 50024b0106d5: Verifying Checksum 50024b0106d5: Download complete 9c7d0e5c0bc2: Verifying Checksum 9c7d0e5c0bc2: Download complete 16ea0e8c8879: Verifying Checksum 16ea0e8c8879: Download complete 0ed236c95063: Verifying Checksum 0ed236c95063: Download complete 16ea0e8c8879: Pull complete 50024b0106d5: Pull complete ff95660c6937: Pull complete bd9cab5aeb31: Verifying Checksum bd9cab5aeb31: Download complete 2a19d2e6789c: Verifying Checksum 2a19d2e6789c: Download complete 9c7d0e5c0bc2: Pull complete 2a19d2e6789c: Pull complete bd9cab5aeb31: Pull complete 0ed236c95063: Pull complete Digest: sha256:f9de064473fb30c66bc0d2ddf2cf9a4a9bd38cbd2c5e59ce3bdf8af7b8747a57 Status: Downloaded newer image for golang:1.13 ---> a2e245db8bd3 Step 2/8 : RUN go get -u -v github.com/go-delve/delve/cmd/dlv ---> Running in e6193a3a906d [91mgithub.com/go-delve/delve (download) [0m[91mgithub.com/go-delve/delve/pkg/dwarf/loclist [0m[91mgithub.com/go-delve/delve/vendor/go.starlark.net/internal/spell [0m[91mgithub.com/go-delve/delve/vendor/github.com/mattn/go-isatty [0m[91mgithub.com/go-delve/delve/vendor/gopkg.in/yaml.v2 [0m[91mgithub.com/go-delve/delve/pkg/goversion [0m[91mgithub.com/go-delve/delve/vendor/golang.org/x/sys/unix [0m[91mgithub.com/go-delve/delve/vendor/github.com/cosiner/argv [0m[91mgithub.com/go-delve/delve/pkg/dwarf/util [0m[91mgithub.com/go-delve/delve/vendor/golang.org/x/arch/arm64/arm64asm [0m[91mgithub.com/go-delve/delve/pkg/dwarf/op [0m[91mgithub.com/go-delve/delve/pkg/dwarf/godwarf [0m[91mgithub.com/go-delve/delve/pkg/dwarf/frame [0m[91mgithub.com/go-delve/delve/pkg/config [0m[91mgithub.com/go-delve/delve/pkg/dwarf/line [0m[91mgithub.com/go-delve/delve/pkg/dwarf/reader [0m[91mgithub.com/go-delve/delve/vendor/golang.org/x/arch/x86/x86asm [0m[91mgithub.com/go-delve/delve/vendor/golang.org/x/crypto/ssh/terminal [0m[91mgithub.com/go-delve/delve/vendor/github.com/peterh/liner [0m[91mgithub.com/go-delve/delve/vendor/go.starlark.net/syntax [0m[91mgithub.com/go-delve/delve/vendor/github.com/sirupsen/logrus [0m[91mgithub.com/go-delve/delve/pkg/version [0m[91mgithub.com/go-delve/delve/vendor/github.com/spf13/pflag [0m[91mgithub.com/go-delve/delve/pkg/logflags [0m[91mgithub.com/go-delve/delve/vendor/go.starlark.net/resolve [0m[91mgithub.com/go-delve/delve/pkg/proc [0m[91mgithub.com/go-delve/delve/vendor/go.starlark.net/internal/compile [0m[91mgithub.com/go-delve/delve/vendor/github.com/spf13/cobra [0m[91mgithub.com/go-delve/delve/vendor/go.starlark.net/starlark [0m[91mgithub.com/go-delve/delve/pkg/proc/winutil [0m[91mgithub.com/go-delve/delve/pkg/proc/linutil [0m[91mgithub.com/go-delve/delve/service/api [0m[91mgithub.com/go-delve/delve/pkg/proc/core/minidump [0m[91mgithub.com/go-delve/delve/pkg/proc/gdbserial [0m[91mgithub.com/go-delve/delve/service [0m[91mgithub.com/go-delve/delve/pkg/proc/core [0m[91mgithub.com/go-delve/delve/pkg/proc/native [0m[91mgithub.com/go-delve/delve/service/debugger [0m[91mgithub.com/go-delve/delve/service/rpc1 [0m[91mgithub.com/go-delve/delve/service/rpc2 [0m[91mgithub.com/go-delve/delve/service/rpccommon [0m[91mgithub.com/go-delve/delve/pkg/terminal/starbind [0m[91mgithub.com/go-delve/delve/pkg/terminal [0m[91mgithub.com/go-delve/delve/cmd/dlv/cmds [0m[91mgithub.com/go-delve/delve/cmd/dlv [0m ---> 9c239a04a8c2 Step 3/8 : WORKDIR /src/hello-world ---> Running in 4d80d86a1faa ---> d787f60f40eb Step 4/8 : COPY go.mod go.sum ./ ---> 8b3ab925a778 Step 5/8 : RUN go mod download ---> Running in 28efd6611102 ---> 1c589d3b4d0a Step 6/8 : COPY . ./ ---> 5c6d6d2c96ef Step 7/8 : RUN go build -o /app -v ./cmd/hello-world ---> Running in 5ccba50bc0d6 [91mhello-world/cmd/hello-world [0m ---> df16dd9586b8 Step 8/8 : ENTRYPOINT ["dlv", "exec", "/app", "--continue", "--accept-multiclient", "--api-version=2", "--headless", "--listen=:3000", "--log"] ---> Running in c0e015fa2785 ---> 836c47e159b2 Successfully built 836c47e159b2 Successfully tagged go-hello-world:latest Build complete in 54.230696113s Tags used in deployment: - go-hello-world -> go-hello-world:836c47e159b26b333365a1c23efe5ffbf1a1ac4474ef19f94dae8c613a6278ee local images can't be referenced by digest. They are tagged and referenced by a unique ID instead Starting deploy... - deployment.apps/go-hello-world created - service/go-hello-world-external created Deploy complete in 618.346232ms You can also run [skaffold run --tail] to get the logs There is a new version (1.0.1) of Skaffold available. Download it at https://storage.googleapis.com/skaffold/releases/latest/skaffold-darwin-amd64 Waiting for Deployment 'go-hello-world' to rollout... Waiting for IP address of Service 'go-hello-world-external'. Publicly exposed service endpoints in the application: go-hello-world-external: http://localhost:80 No ingress endpoints found in the application. Application deployed successfully.最後にアクセスするためのアドレスが出ます。
go-hello-world-external: http://localhost:80このURLにアクセスするとデプロイされたアプリにアクセスできます。
デプロイ後の構成はKUBERNETES EXPLORERで見ることができます。
感想
kubernetesは単純に動作させたりするだけでもそこそこ長い(当社比)yaml書かなければならなかったり、動作後のログや構成なんか見るのも大変なのですが、こうして各モジュールの状態とか簡単に見られるようになります。
k9sというツールもあるみたいなので、そちらの方もチェックしてみようかと思います。
なんだこのアイコンは
k9s
- 投稿日:2019-11-29T10:10:13+09:00
DockerでGoのRestAPIを作ってみた(ホットリロード対応)
dockerでGolangのAPIを作りたいと思いましてやってみました。
ちなみに、dockerはホットリロードさせたかったので、docker-composeを使っています。環境
それぞれのバージョンはこちら。
Dockerについての説明とかは省きます。$ docker-compose --version docker-compose version 1.24.1, build 4667896b $ go version go version go1.13.4 darwin/amd64■ echo 4.1.11 (ルーティングが便利になるかな、と)
公式はこちら https://echo.labstack.com/guide
以下によると、RestAPIに最適化されているらしー。
https://rightcode.co.jp/blog/become-engineer/go-flamework■ oxequa/realize
ホットリロードを行うために入れてみた。ファイルの準備
適当なフォルダに以下の3ファイルを用意します。
Docker
Dockerfile
# 公式 golang ランタイムをイメージとして使用 FROM golang:1.13 # ソース入れる用のディレクトリ作成(名前はなんでもいいけど、この後の「app」は全部合わせる) RUN mkdir /app # ソース入ってるのここだよ WORKDIR /app # ホスト側のカレントにあるファイルをソースフォルダにコピーするよ COPY . /app # echo と oxequa/realize のライブラリ取ってくるよ(ぼちぼち時間かかるよ...) RUN go get -u github.com/labstack/echo/... RUN go get github.com/oxequa/realizedocker-compose.yml
docker-compose.ymlversion: '3' services: api: build: . #buildが指定されている場合は作成イメージの名前になる #build指定なし:このイメージを元に作成される(ex.mysqlとか) image: sample_api:0.1 # ポートフォワーディング(ホスト側:docker側) # ホスト側のブラウザで実行するときは http://localhost:1000 で見れるようになる ports: - "1000:1323" # (ホスト側:docker側)dockerの「/app」フォルダとホストのカレントを繋げるよ。 # ホストの変更が反映されるようになる volumes: - .:/app # デフォルトのコマンドをこれに変える。ホットリロードを有効にする? command: realize start --run --no-config tty: trueGolang
server.go
server.gopackage main import ( "net/http" "github.com/labstack/echo" ) func main() { e := echo.New() routing(e) e.Logger.Fatal(e.Start(":1323")) } /* ルーティングを行う */ func routing(e *echo.Echo) { e.GET("/", hello) e.GET("/:name", greeting) } /* http:/~/ の時 */ func hello(c echo.Context) error { return c.JSON(http.StatusOK, map[string]string{"message": "hello"}) } /* http:/~/(名前) の時 */ func greeting(c echo.Context) error { /* c.Param("name") とすることで、URLの:name と対応させて取得 */ return c.JSON(http.StatusOK, map[string]string{"message": "hello " + c.Param("name")}) }Docker起動
上記ファイルを保管したフォルダに移動して、コマンド実行
(「-d」オプションつけてバックグラウンド実行しない理由は後述。つけても大丈夫)$ docker-compose up
これで、ローカルのブラウザから
http://localhost:1000
ってしたら
{message:hello}
が。
http://localhost:1000/taro
ってしたら
{message:hello taro}
って帰ってくるはず。詰まった時の小ネタ
docker-compose up でやってみる
どういうことかというと、「-d」を取ることでエラーの内容を教えてくれる。あずきはコマンド実行後、ターミナルをそのまま使いたかったので、おまじないのように「-d」をつけてました。
で、エラーで動かないんだけど(docker ps にあがってこない)なんでか分かんなかった。原因は同じフォルダ内に「func main()~」が書かれたファイルがいたってことだった。
試行錯誤しながら作ってたので、バックグランド実行だと気づかなくて何時間も無駄にした。でも、苦労したことは忘れない。きっと。
参考
https://qiita.com/y-ohgi/items/671de11f094f72a058b1
https://www.fox-hound.tech/1179/
https://qiita.com/prgseek/items/e557a371d7bd1f57b9b1
https://qiita.com/TsutomuNakamura/items/7e90e5efb36601c5bc8a
http://docs.docker.jp/engine/articles/dockerfile_best-practice.html
https://qiita.com/zembutsu/items/9e9d80e05e36e882caaa
API関連
https://ken-aio.github.io/post/2019/01/30/golang-echo/
- 投稿日:2019-11-29T03:16:31+09:00
【Kotlin for Server-Side】KtorのプロジェクトをDockerで起動する
Kotlin for Server-Side
ServerSideの現状を以下に軽くまとめてみました。
Frameworks for Server-side Development with Kotlin
- Spring
- Javaでの有名なWebアプリケーションFramework
- Vert.x
- JVM上でReactiveアプリケーションを作成する為のToolkit
- Ktor
- JetBrains社が作成しているWebアプリケーションFramework
- kotlinx.html
- Kotlin DSL for HTML
今回は上記の中でも Ktor を試して見たいと思います。
環境構築
Ktor Project Generator で空のプロジェクトを作成し、ダウンロードします。
何も変更しない状態で「Build」を選択しプロジェクトをダウンロードします。
ダウンロードしたプロジェクトのディレクトリ構成は以下の様になってました。. ├── build.gradle ├── gradle │ └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── resources │ ├── application.conf │ └── logback.xml ├── settings.gradle └── src └── Application.kt※ ダウンロードしたプロジェクトのGradleのVerが
4.10
となっており、後述する Gradle Shadow を使用する際に
Versionが古いと怒られるのでgradle-wrapper.properties
のgradleのversionを5.6.4
に変更してます。また、
build.gradle
とApplication.kt
は以下の様になってました。build.gradlebuildscript { repositories { jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } apply plugin: 'kotlin' apply plugin: 'application' group 'com.example' version '0.0.1-SNAPSHOT' mainClassName = "io.ktor.server.netty.EngineMain" sourceSets { main.kotlin.srcDirs = main.java.srcDirs = ['src'] test.kotlin.srcDirs = test.java.srcDirs = ['test'] main.resources.srcDirs = ['resources'] test.resources.srcDirs = ['testresources'] } repositories { mavenLocal() jcenter() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" compile "io.ktor:ktor-server-netty:$ktor_version" compile "ch.qos.logback:logback-classic:$logback_version" testCompile "io.ktor:ktor-server-tests:$ktor_version" }package com.example import io.ktor.application.* import io.ktor.response.* import io.ktor.request.* fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args) @Suppress("unused") // Referenced in application.conf @kotlin.jvm.JvmOverloads fun Application.module(testing: Boolean = false) { }Dockerで起動できる様にする
こちらを参考に環境構築を行います。
Gradle Shadow
Jarを生成してくれる、GradleのPlugin。これを使ってjarを生成しDocker内で起動します。
build.gradle
を以下に修正buildscript { repositories { jcenter() maven { url 'https://plugins.gradle.org/m2/' } } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "com.github.jengelman.gradle.plugins:shadow:5.2.0" } } apply plugin: 'kotlin' apply plugin: 'application' apply plugin: 'com.github.johnrengelman.shadow' group 'com.example' version '0.0.1-SNAPSHOT' mainClassName = "io.ktor.server.netty.EngineMain" sourceSets { main.kotlin.srcDirs = main.java.srcDirs = ['src'] test.kotlin.srcDirs = test.java.srcDirs = ['test'] main.resources.srcDirs = ['resources'] test.resources.srcDirs = ['testresources'] } repositories { mavenLocal() jcenter() maven { url "https://dl.bintray.com/kotlin/ktor" } } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" compile "io.ktor:ktor-server-netty:$ktor_version" compile "ch.qos.logback:logback-classic:$logback_version" testCompile "io.ktor:ktor-server-tests:$ktor_version" } shadowJar { baseName = 'my-application' classifier = null version = null }以下のDockerfileをプロジェクト直下に追加
FROM openjdk:8-jdk RUN mkdir /app WORKDIR /app ADD . $WORKDIR RUN ./gradlew wrapper # gradle wrapper関連を諸々アップデート起動時にkickするshellを作成
bin/start_server.sh
#!/bin/bash set -e source ~/.bashrc ./gradlew build cp ./build/libs/my-application.jar . java -server -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:InitialRAMFraction=2 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=2 -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:+UseStringDeduplication -jar my-application.jar
docker-compose.yml
を以下の内容で作成する。version: '3' services: app: build: context: . dockerfile: ./Dockerfile ports: - '8080:8080' volumes: - .:/app command: bin/start_server.shあとは
docker-compose up
で起動し、http://0.0.0.0:8080
にアクセスできればOKです。
作成したプロジェクトはこちらにアップしてます。バッドノウハウ
* What went wrong: A problem occurred evaluating root project 'ktor-demo'. > Failed to apply plugin [class 'com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin'] > This version of Shadow supports Gradle 5.0+ only. Please upgrade.gradleのバージョンが古い。こちらを参考に、
gradle/wrapper/gradle-wrapper.properties
のversionを変更し、./gradlew wrapper
を実行する
gradleのversionはこちらで確認できる。
* What went wrong: Execution failed for task ':compileKotlin'. > Kotlin could not find the required JDK tools in the Java installation '/usr/lib/jvm/java-1.8-openjdk/jre' used by Gradle. Make sure Gradle is running on a JDK, not JRE.エラーメッセージの通りで、JREではなくJDKを指定する。
参考のリポジトリのDockerfileがROM openjdk:8-jre-alpine
になっている為、openjdk:8-jdk
に修正する。参考になったURL
- 投稿日:2019-11-29T02:11:33+09:00
WEBアプリケーション開発における旬の技術調査
はじめに
私は、約3年勤めたSIerを退職し、タイへ2ヶ月、オーストラリアへ1年の語学留学へ行ってました。
日本に戻ってきて、カンファレンスに参加したり、元職場の先輩と飲みに行って現状を探ったりしたところ、本当に1年ちょっとしか経ってないの!!?ってぐらい進化していたので、自分用にまとめようと思います。間違いもたくさんあるので、その都度直していこうと思います。
- 以下、今回まとめようと思っているもの
- Docker
- TypeScript
- spring-boot
- React
- Angular
- AWS
Docker
本当に衝撃的だった。
過去にアーキテクチャ設計メンバーとして働いていた自分にとって、こんな画期的なもの、がなぜ3年前には存在しなかったのか呪ったほどである。想像してみてほしい。
開発メンバー50人以上の大規模PJ、フロントエンドとバックエンドで異なるIDEによる開発環境と実行環境、協力会社と社員でセキュリティレベルが異なりダウンロードできないファイル。
地獄である。手間である。平気で1日の工数として割り当てられる。無駄。それがすべてDockerで解決される。
DockerFile、docker-composeファイルを作成して配布・起動すれば、一発で全く同じ仮想環境が作られる。TypeScript
ざっくりいうと、静的型付け言語のJavaScriptって感じ?
バックエンドメインで開発してきた自分としては、動的型付け言語の型推測とかは慣れないので助かるし、デバック前に型の不一致によるエラーが検出できるのはメリットだと思う。(行数は増えるけど)
また、babelでEcmaScriptのVersion?を気にしなくていいっていうのも大きいメリットだなって思う。
最終的に実装対象に合わせたJavaScriptに変換されるのも、すっごいJavaっぽい。spring-boot
Springの設定ファイル不要版?っていう風に聞いた。by元先輩社員
Springで最も理解できないxmlファイルを書かなくていいっていうだけで神に聞こえる。ただ、アノテーションなどの基本的なSpringの機能は同じみたい。まだ、あまり調べていないがすっごくきになるし、早く使ってみたい。React
Facebookが作ったJavaSpringフレームワークらしい。
対抗馬にAngularがあるが、最近はReactのほうが勢いがあるらしい。by元先輩社員
ただ、先日参加したJJUGではAngularとSpring-bootの開発デモが行われていたし、Angularの方がネットでもよく見るので、少し混乱気味。
実際触ってみて感触を確かめたいので、両方で試作アプリを作ってみる予定。ざっくり見た感じ、JavaScriptフレームワークでHTMLとJavaScript部分がJavaのインターフェースと実装みたいな関係になったのかなって印象。(器だけ作って中身は別ファイルでって意味)
個人的には大歓迎。
HTML内のidとか要素をわざわざ気にして、JavaScriptで取り出してーってしているの、、、馬鹿らしいなーって思ってたので。AWS
いたるところで見る。
これも抑えておきたい(抑えておかなければならない)技術の一つなのは間違いない。
ちょっと個人で触ってみるのと、企業で採用するのでは使用する機能や規模が大きく異なる気はするが、とりあえず個人で、無料で使用できる範囲で試してみたいと思う。まとめ
たった1年ちょっとで旬の変わるIT業界の恐ろしさを肌で感じた。
前職では、目の前にあるタスクをやっていくので精一杯で、カンファレンスに参加したり、技術について勉強したりする余裕がなかったんだけど、この機会にしっかり学んで、一人でもサーバーからフロントエンドまで開発できるようにしとこうと思う。
- 投稿日:2019-11-29T01:58:10+09:00
dockerコンテナ内で最新のgitをソースコードからインストールする
はじめに
本記事では、dockerコンテナ内でgitの最新版をソースコードからインストールする方法について説明します。
全体の流れ
以下の7ステップで、gitの最新版をソースコードからインストールします。
以下は作業は全てrootユーザで実施しています。
- apt-getをupdateとupgradeする
- コンテナに最初から入っているgitをアンインストールする
- ビルドに必要なパッケージをインストールする
- gitのソースコードを公式リポジトリからダウンロードする
- ビルドする
- gitのパスを通す
- 動作確認
apt-getをupdateとupgradeする
既に実施していれば以下は不要です。
# apt-get update # apt-get upgradeコンテナに最初から入っているgitをアンインストールする
# apt-get remove gitビルドに必要なパッケージをインストールする
# apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev unzipgitのソースコードを公式リポジトリからダウンロードする
任意の作業ディレクトリにgitの公式リポジトリから最新のソースコードをダウンロードします。
ダウンロードにはwgetコマンドを使います。
本記事では、 /tmp を作業ディレクトリとします。cd /tmp # wget https://github.com/git/git/archive/vX.X.X.zip「X.X.X」には最新のバージョンを入れてください。
最新のバージョンは、公式リポジトリの「branch master」→「tags」から確認できます。(例)
2019年11月29日時点での最新は、2.24.0なので、
v2.24.0
となります。ビルドする
# unzip vX.X.X.zip # cd git-X.X.X/ # make prefix=/usr/local all # make prefix=/usr/local installgitのパスを通す
.bashrcを編集するので、vimをインストールしておきます。
なお、編集さえできればよいので、エディタや手段は何でもよいです。# apt-get install vim # cd / # vim .bash_profile # source .bash_profile.bash_profileの中に以下の1行を書き込みます
export PATH=$PATH:/tmp/git動作確認
適当な場所で以下を入力し、意図するバージョンが返ってくれば成功です
# git --version