- 投稿日:2019-09-15T23:11:18+09:00
dockerプライベートリポジトリの作り方
dokcer imageをプライベートリポジトリで利用する方法
目的
ローカル環境にプライベートコンテナリポジトリを作成する
なぜ?
dockerやkubernetesで使用するコンテナイメージを自分用にビルドしたものを保管、管理したい。
どのように?
コンテナイメージを管理する方法はいくつかありますので、以下の中から選択する必要があります。
1.Docker Hubの利用する(有料)
2.amazon ECRを利用する(有料)
3.ローカルオンプレ環境にOSSのリポジトリ環境を構築するこのページでは3の「ローカルオンプレ環境にOSSのリポジトリ環境を構築する」を説明します。
材料
- サーバ環境:CentOS Linux release 7.6.1810 (Core)
- ソフト:docker-distribution
- 作業時間 少々
- やる気:多め
レシピ1:レジストリサーバのインストール
ソフトウェアをインストール&サービスを起動する
# yum install docker-distribution # systemctl start docker-distribution.service # systemctl enable docker-distribution.serviceレシピ2:設定情報の変更
レジストリデータ保存先&待ち受けポートの変更
- 変更必要なら修正する
# vi /etc/docker-distribution/registry/config.yml version: 0.1 log: fields: service: registry storage: cache: layerinfo: inmemory filesystem: rootdirectory: /var/lib/registry http: addr: :5000hostsファイルの変更
以下の設定はbuild imageを取得したいノードにて作業が必要です。
- IPv6は無効にします
- ホスト名を登録します# vi /etc/hosts #::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 <レジストリサーバーのIPアドレス> kbmster接続情報を追加
# vi /etc/docker/daemon.json "insecure-registries": [ "kbmaster:5000" ]レシピ3:dockerの再起動
# systemctl daemon-reload # systemctl restart dockerレシピ4:buildイメージをリポジトリサーバにpushする
# docker build -t wp-tomcat:1.0 . # docker tag wp-tomcat:1.0 kbmaster:5000/wp-tomcat:1.0 # docker push kbmaster:5000/wp-tomcat:1.0レシピ5:buildイメージをリポジトリサーバからpullする
各ノードから以下を実行するとdocker imagesがダウンロードされます
# docker pull kbmaster:5000/wp-tomcat:1.0
※参考資料
https://sato-labo.mydns.jp/2018/07/install-docker-registry/
https://tracpath.com/works/devops/docker_hub_and_amazon_ec2_container_registry/#Docker_Hub
- 投稿日:2019-09-15T21:29:51+09:00
Docker導入後に使いそうな基本コマンド
Docker概念理解する際に読んだ以下の記事より、使いそうなコマンドをシンプルにまとめてみました。
イメージからコンテナ起動する基本コマンド
$ docker pull centos # Docker Hubからイメージ取得 $ docker create -name [作成コンテナ名] [イメージ名] # イメージからコンテナ作成 $ docker start [コンテナ名] # コンテナを起動 $ docker run hello-world # pull,create,startを同時実行イメージ
$ docker imaes # 一覧表示 $ docker rmi [イメージID] # 削除コンテナ
# 一覧表示(-a付きの場合、停止中も含む) $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 845e015b8f95 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago agitated_heisenberg # 起動、停止、削除、コンテナログイン $ docker restart # 再起動 $ docker stop # 停止 $ docker rm [コンテナID/名前] # コンテナ削除。不使用コンテナはHDを圧迫するので削除する $ docker exec -it [起動中コンテナ名] # 起動中コンテナにシェル接続、exitしてもコンテナは停止なし # コンテナからイメージ作成 $ docker commit [コンテナ名] [image名:tag名] # 現状コンテナの状態をイメージに保存する $ docker build -t [ビルドイメージ名] . # 独自イメージをビルド $ docker build -no-cache -t [ビルドイメージ名] # 独自イメージをキャッシュなしでビルド
- 投稿日:2019-09-15T21:19:15+09:00
FOSS4G 2019 Niigata で得たものの整理
ハンズオンマテリアル関係
こちらとこちらを用いて、柴本さん・松澤さんとともにハンズオンを行なった。
asciinema を使うようにしたい
ango の開発の際に検討はしていて採用はしていなかったのだが、やはりasciinema のような CUI のスクリーンキャストを使う等にすると良いと思う。
なぜなら、聴講者に対して「何がコマンド入力で、何がコマンド出力か」を確実に伝えるのは、スタティックな表示では難しいからだ。
modify.js や modify.sql の意義を丁寧に説明する
国連ベクトルタイルツールキットはストリーム志向のソフトウェアなのだが、その処理の中で modify.js や modify.sql が入る理由について、今回は質問をいただいた。
次のような理由を、積極的に説明していくことが適切だと思う。
- modify.js を使うことで、中間ファイルの保存を行わずに済ませ、ストレージを節約するとともに、処理速度を向上することができる。
- ベクトルタイルの生産担当者には、必ずしもマスターデータを変更する権限がない場合が多い。ベクトルタイル生産の都合によるデータの調整は、マスターデータに対しては行えないので、modify.js を使う。
そもそもベクトルタイルとは何かについて説明する
私は次のように説明します。
- ウェブ地図では地図を細切れに分けてストリームするが、その細切れのことをタイルと言い、タイルには画像タイルやベクトルタイルがある。画像タイルもベクトルタイルも表示された見た目は同じ。
- しかし、画像タイルはレンダリングした画像であり、ベクトルタイルは機械可読なデータである。
- 画像よりもデータの方が75%ほど軽い。その軽さがイノベーションをもたらす。
スマートな Raspberry Pi の使い方
PC に Raspberry Pi をイーサネットケーブルで直結して、 raspberrypi.local というホスト名に ssh するという方法がもっともスマートであるように思われる。
電源ケーブルとイーサネットケーブルを十分短いものにすれば、かなりスマートな提示ができると思われる。
実際には、PC 側に必ずしもイーサーネットポートがあるわけではないので、USB/イーサネット変換や、USB-C/イーサネット変換のアダプタもある程度の数持っておく必要があると考える。
Docker Toolbox ではポート転送が必要
Docker Toolbox を使う人に対しては、 Oracle VirtualBox でポート転送を設定してもらう必要がある。そのほかの場合には、既存の案内内容で十分にポート転送ができている。
自ホスト名をスマートに扱う
自ホスト名が localhost になるパターンと raspberrypi.local になるパターンが発生し、 style.(h)json を書き換える必要が発生した。
自ホスト名を config/default.hjson あたりに逃し、rake build の時に自ホスト名を style.json に埋め込むようにすると、面倒な編集が不要になる。
自ホスト名は、タイルのテンプレート URL、スプライトの URL、フォントの URL と三回使われることになるので、rake build のときに埋めるようにしたほうが安全、ということである。
tippecanoe のコマンドラインオプションは short form? long form?
ango では、私が long form のオプションを使い、柴本さんが short form のオプションを使った。統一できた方が良い。
私は rake にコマンドを書いて、研修の中で解説だけすることにしたので、long form を使った一方、柴本さんはコマンドを直接打ってもらうことにしたので、short form を使ったのである。よって、rake を使うかどうかの判断に合わせて、long か short かを決断すれば良いと思う。
地球地図に取り組んでいく
地球地図はすでにベクトルタイルにされているから、ハンズオンにそれをなぞるような感じになる。まずは、地球地図 GeoJSONS を optgeo の中に作るのも一つの方法だと思う。
レポジトリを私が作るとしたら Inazo という名前にすると思う。
サポート要員の数
サポート要員の必要数は、同時に発生するサポート要求の数に合わせれば良い。今回はサポート要員2名で16名程度への対応であったので、かなり余裕を持って対応することができた。最小のサポート要員数は1だと思う。サポート要員をゼロにして講師だけで対応しようとすると、ハンズオンの質がかなり下がる可能性がある。
プレゼンテーションの内容関係
こちらのプレゼンテーションを行なった。
適切なガバナンスの確保について
OSGeo Incubation Process への応募を長期的に目指していくことで、オープンソースプロジェクトとしての適切なガバナンスを得ていくことを目指す。
そのための課題は、ここでじわじわと検討していくことになる。
統制されたネットワークへの対応について
次の世代のハンズオンマテリアルについて作業をするにあたって、「インターネットから独立したウェブ地図」として動作するようになることをまず目指す。
FOSS4G Monthly Online について
Zoom を使って月例開催する方向で考えていくが、目標は10月の第三木曜日に初実施、というあたりだと考えている。
ツールの勉強
とりあえず、次の二つのツールについて、動き始める前に勉強をしておく必要があると認識している。
- Slack
- Zoom
- 投稿日:2019-09-15T18:33:31+09:00
未経験で新規案件でインターンして学んだこと(学生です)
どんな目的で記事を書いているか
・とにかくアドバイスが欲しいです(切実)
・技術がどう身についていったかの過程を示してエンジニアで人事をやっている方にいい情報が届くといいな
・今エンジニア目指してる人の就活のお助けにもなったらいいな自分のステータス
・理系大学院生
・開発経験なし、研究のためにプログラミングは少しやっていた
・触れたことある言語はjava,Ruby,ほんの少しC
・今開発で使っているのはphp(laravel),JavaScript(VueとJQuery)
・インターン初めて今ちょうど4ヶ月くらい何をどう学んだか
インターンで初めて本格的な環境開発した
インターンするまではDocker使ったことなかったです。もうなにも知らなかった。もちろんPHPも触ったことなし。
でも会社入ったら一番最初に環境開発して〜と言われて何もわからずめっちゃDocker勉強しました。開発の環境は先輩に教えてもらいながらなんとかできたけど、理解できていなかったからDockerの参考書使って自分で0から開発環境作ってみました。これでかなり理解深まった。
そして記念すべきQiita初投稿がこれ
Dockerでnginx+MySQL+Laravelの環境構築からプロジェクト作成・DBへのマイグレーションまでフレームワークってすごい
今までデータベースを扱ったことがなく、sql文とかも勉強しながら開発してたのですが、フレームワークというものがあったおかげでものすごく理解が早くなった。言語の中身・特徴理解する前にフレームワーク使うのはよくないと言われていますが、自分の場合はフレームワークから入って成長できたと思っています。とにかく実装できないことが恥ずかしいと思って必死に勉強した
これは環境にもよると思いますが、全く未経験なのにガンガンタスク振られて焦りました。できないです、とか間に合わなかったですを言いたくなくて死に物狂いで勉強しました。人のコード見て学べる、自分のコードのレビューがもらえる
サービス作ってない時は計算できていればいいやと思っていたものが、現場になると可読性や処理速度を気にするようになった。ただ動けば良いだけではないことを実感できた。コミュニケーションすごく大切
一人でやっていれば仕様に迷いはないですが、チームの開発だと要件にマッチした実装になっているかがすごく大事。「多分こうだろう」と思って実装したことが無駄になったことがあり、仕様の認識違いがないか都度確認することがとても重要だと学びました。使えるものは使いまくる
案件によるかもしれませんが、便利なライブラリはどんどん使うべきだと思います。最初は知らないものを使うことに抵抗がありましたが今では新しいものどんどん使いたくてたまらない!とうう感じになってます。その例がこの記事。
Lalavel ScoutでAlgoliaを使って全文検索を実装してみた!
ClosureTableを使って〇〇年のアニメを季節ごとに1テーブルで管理する公式ドキュメントは神!特に英語版!!!!!!
自分はとても英語が苦手だったのですが、物によっては英語のドキュメントしかない場合があります(Algoliaも英語しかない)。どうしても英語を読まなければいけない状況になってから、「英語の方がわかりやすい!」となりました。日本語にこだわらずになんでも英語で調べたり読んだりすると知識増えるなと思います。新しい情報に敏感になることが大事
ITの世界は多分他の業界より発展速度が速い。いつまでも昔のやり方にとらわれずにどんどん新しいもの使ってあわよくば自分が新しいツール開発するくらいの意気込みを持っていた方が良い。実年齢は年取っても技術の話では若くいたい!0から作ることは自信になる
まだリリースはしていないのですが、新規だからこそ今自分が作ったものがリリースされるのが楽しみで仕方ないです。ワクワクが止まらん!書籍は自分で持っていた方がいい
わからないことは調べれば出てくるという人もいますが、自分は本を買うことを勧めます。わからないことを調べているうちに別のことも学べるので絶対投資すべき!最後に
とにかくいろんな技術者の人と話していろんなことを吸収していきたいです。YYPHPいきたかったのに終わってしまたの悲しい。。。。。何かいいコミュニティあったら教えてください。
- 投稿日:2019-09-15T17:36:38+09:00
[備忘] Container RegistryにDocker Imageをpushする
完全に備忘
はじめに
プライベートにDocker Imageを管理したい場合は、Container Registryを使うことにした
費用はCloud Storageと下りの費用くらいなのでほぼ無視できる。はず。。。1. Dockerhubから自分が欲しいDocker Imageを取ってくる
dockerhubから自分が欲しいDocker Imageをpullしてくる
今回はnodejsの公式イメージをpullしてくる
docker pull node特にタグを指定してないので
latest
がpullされる2. gcloudでcloud container registryへの認証を通す
GoogleCloudPlatformの場合には、cloudshellで実施するのが楽で良い
Container RegistryのAPIを有効にしておくのを忘れずに
で、認証のコマンドはこれ
gcloud auth configure-docker3. Imageにタグをつける
ローカルにpullしてきたイメージを特定の場所にpushするにはタグ付けが必要なので、タグ付けする
docker tag node:latest gcr.io/{Project_name}/node:tag-first一応タグ付けされたかを確認しておく
docker imagesoutputREPOSITORY TAG IMAGE ID CREATED SIZE node latest d8c33ae35f44 3 days ago 907MB gcr.io/{Project_name}/node tag-first d8c33ae35f44 3 days ago 907MB4. Imageをpushする
最後にタグ付けされたImageをContainer Registryをpushする
docker push gcr.io/{Project_name}/node:tag-firstコンソールでContainer Registryに登録されているか確認する
確かに登録されていることを確認
5. いらないImageは削除する
少額とはいえ課金対象ではあるので、使わないImageは消しておきたい
gcloud container images delete gcr.io/{Project_name}/node:tag-first --force-delete-tags参考リンク
Googleの提供するDocker Registry の Google Container Registryを試す
Google Container Registry概要
Container Registry クイックスタートおしまい
- 投稿日:2019-09-15T17:11:05+09:00
Wiki.jsっていうWikiのOSSを使ってみる
以前とある件でwikiを作ってみようかなとツイートしたところ、
フォロワーさんよりWiki.jsいいぞ
って教えてもらったので、まずはちょっと試してみよう。
Beta版があるらしいので、そちらを使います。
ドキュメントがしっかりしているので、
英語とか全然問題ない方はこちらを参考にした方が早いかも。前提条件
Macを使用
Dockerがインストールされている環境構築
Dockerに既にイメージを作ってあるみたいなので、
このページの下にあるdocker-composeをコピペしてあげるだけです。
両方ともイメージがあるのでそのまま起動します。そうするとコンソールにこのように表示されました。$ docker-compose up
http://localhost:3000/ にアクセスすればいいみたいですね。
アクセスしたら管理者のログイン情報を入力する画面が表示されます。
Allow Telemetry
の項目は、開発者に開発のための情報を提供しますか?てきなものです。INSTALL
をクリックするとログイン画面に遷移し、ログインするとこのような画面になりました。
めっちゃUIが好みすぎる。
CREATE HOME PAGE
をクリック。
エディターを好みなものに選択できるようですね。
ただいろいろ表示されていますが、現状はMarkdown Editor
とVisual Editor
しか使えないみたい。
Markdownがあれば十分なのでMarkDownをクリック。 ページの詳細を設定できます。
タブにあるSCHEDULING
とSOCIAL
はまだ使えないみたい。
おおおかっけええ!
リアルタイムでプレビューがみれる。
画像などはサイドメニューから入れられるみたい。
フォルダー形式で管理できるのか。すぎょい。
編集できたらCREATE
をクリック。
このような感じになります。
管理画面から差分も見れるみたい。
感想
Wikiの基幹的なシステムは既にあるから使えるには使えそうですね。
UIも好みすぎるし、wikiつくるってことになったら是非使ってみたい。
これからもっと多機能化していくみたいですし、今後に期待。リンク集
- 投稿日:2019-09-15T13:54:58+09:00
cacheのヒット率を測定するツールを作成しました
Cacheのヒット率測定ツール
Webアプリケーションのインフラを考えるうえで、静的コンテンツ等をCDN配信にする選択肢を取ることが多いかと思います。
(例えば、さくらCDNやAWSならCloudFrontなど)運用していくうえで、画面ごと(URLごと)にキャッシュのヒット率やキャッシュされていないコンテンツを洗い出すツールを作成しました。
https://github.com/hirotoyoshidome/hit_rate
Docker化していますが、seleniumを利用していてchromediriverのバージョンによっては
上手く動かない場合があるようです。その場合は、申し訳ないですが、各自のローカル環境で動かしてみてください。
※そのうち直すかもです* selenium * requests ↑のみ利用していますもっと良いやり方があれば、ご教示ください!
では、今回はこのへんで!
- 投稿日:2019-09-15T10:46:14+09:00
WSLでdocker-ceを動作させる手順
設定済みWSL上にDockerをインストールして、hello-worldするところまで行います。
docker-compose(複数コンテナの連携)は、WSL上で、iptablesが完全にサポートされていないとのことなので、動作しません。Dockerは、17.09.1以上だと動作しないため、17.09.0-ceをインストールして動作させています。
WSLを使用可能にする設定と、Ubuntuの導入はこちらに書きました。
動作環境
- Microsoft Windows 10 Enterprise Evaluation ver:1809 build:17763.737
- Ubuntu 18.04.3
- Docker 17.09.0-ce
Ubuntuバージョン確認
ubuntuはWindows管理者権限で実行します。
$ head -n 2 /etc/os-release NAME="Ubuntu" VERSION="18.04.3 LTS (Bionic Beaver)"Dockerインストール
# 古いバージョンのdockerは、トラブルの原因になるので、アンインストール $ sudo apt-get remove docker docker-engine docker.io containerd runc $ sudo apt-get autoremove $ sudo rm -rf /var/lib/docker # イメージファイル等の格納先、uninstallでは消えないので直接削除 # Docker 17.09.1からWSL未サポートな機能があるため、Docker17.09.0をダウンロード&インストール $ curl -O https://download.docker.com/linux/debian/dists/stretch/pool/stable/amd64/docker-ce_17.09.0~ce-0~debian_amd64.deb $ sudo apt install libltdl7 -y # 依存pkgもインストール、ないとエラーになります。 $ sudo dpkg -i docker-ce_17.09.0\~ce-0\~debian_amd64.debDocker動作確認
# バージョン確認 $ docker -v Docker version 17.09.0-ce, build afdb6d4 # Doker起動 $ sudo service docker start $ sudo service docker status [sudo] password for user: * Docker is running # コンテナ起動 $ docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. ・ ・docker.ioのdockerでは動作しなかったり、古いバージョンのUbuntuで試してみたりと、いろいろ回り道しましたが、無事に起動できました。これからいろいろ遊んでみます。
## 参考URL
WSL上でDockerが動くという噂
どうしても Docker on Ubuntu 18.04 on WSL したかった
- 投稿日:2019-09-15T10:19:48+09:00
dockerの置き換えを目指す ルートレス&デーモンレスの podman 入門
OpenShiftのマニュアルには、dockerコマンドと共に podmanコマンド が利用できるとされている。OpenShift を触る様になるまで、podmanの存在を知らなかったので、調べたことをメモとして残しておく。
podman とは?
このpodmanという名前は、コンテナだけでなく、Kubernetesのポッドの形態でコンテナを起動できることを期待させてくれる。プロジェクトのウェブページから特徴を拾うと次の7つがある。そして、プロジェクトのページの前面には出ていないが、Podmanには、ポッドのマニフェストを生成したり、コンテナを起動する機能もある。Podmanロゴは、可愛いもの路線で、複数のコンテナが内部で動くポッドを実行できることを感じさてくれる。
Podman の特徴
(1) Docker互換のコマンドラインフロントエンドを提供
最も簡単にいうと、
alias docker = podman
ということだ。つまり、docker コマンドの代わりに、podmanで代用できることを意味する。(2) オープンソースプロジェクトであり、GitHub でコードが公開されている
このプロジェクトは Red Hat によって運営されており、Fedora、Red Hat Enterprise Linuxの最新リリースバージョン、および Ubuntuに対して、ビルドをテストしている。
- ホームページ https://podman.io/
- GitHub https://github.com/containers/libpod
podmanのバンドル状況について、調べたところ、2019年9月現在で、次の表の状況がわかった。問題なく動作するのは Fedora 30 だけで、RHEL8はバージョンが古くルートレスモードが実装されていないなどの問題があった。RHEL7/CentOS7 でも動作するとされているが、ルートレスで動作させることができなかった。
Distribution Status Podman version Remarks Fedora 30 GA 1.5.1 sudo なしの rootlessモードで実行可能 RHEL 8.0 GA 1.0.5 rootlessモード未実装 RHEL 7.6 GA 1.4.4 sudo podman で実行 CentOS 7.6 GA 1.4.4 同上 Ubuntu 18.04 GA 1.5.1 sudo なしの rootlessモードで実行可能 このことから、podman は Red Hat がオープンソース・プロジェクトとして、発展途上であると見なされ、dockerコマンドを置き換えるまでに熟成されるには、もう少し時間が必要と考えられる。
(3) OCIに準拠するコンテナイメージの開発、管理、および、コンテナとして実行
Docker Hubに登録されたコンテナを実行すること、podmanでビルドして、レジストリに登録したイメージを、dockerコマンドで実行することも可能であり、互換性に問題はないと見られる。
(4) デーモンレスのコンテナエンジン
podman は、Dockerデーモンの様な root で動作するデーモンを必要としない。つまり、podman コマンドだけで、デーモンの助けを必要とせずにコンテナを実行できる。
(5) コンテナはルートレスモードで実行可能
ルートレスのコンテナは、それらを起動したユーザーよりも多くの特権を持つことはない。もちろん、root権限で実行されるDockerデーモンでも、コンテナが起動したユーザー以上の権限を持つことが無い様に考慮されているが、もしも、悪意のあるプログラムに隔離が突破された場合のリスクは大きい。その点で、ルートレスは明白なため安心感がある。
次は、podman で実行した場合のコンテナホスト上のプロセスのリストで、この中でコンテナのプロセスは、PID 21710 とその子プロセスである。 これらのプロセスの USER は、rootではなく、vagrant という一般ユーザーになっている。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND vagrant 21729 0.0 0.1 4336 2760 pts/0 S 13:21 0:00 /usr/bin/slirp4netns --api-socket /run/user/1000/libpod/tmp/35de2a668cad2 vagrant 21710 0.0 0.0 80348 2012 ? Ssl 13:21 0:00 /usr/libexec/podman/conmon --api-version 1 -c 35de2a668cad28fa366c233a641 vagrant 21721 0.0 0.1 11688 2624 ? Ss 13:21 0:00 \_ bash -c while true; do /usr/bin/nc -l -p 3306 < /srv/hello.txt; done vagrant 21740 0.0 0.1 43988 3364 ? S 13:21 0:00 \_ /usr/bin/nc -l -p 3306 vagrant 21707 0.0 0.1 5756 3208 ? Ss 13:21 0:00 /usr/bin/fuse-overlayfs -o lowerdir=/home/vagrant/.local/share/containers vagrant 21478 0.0 1.8 80508 37540 ? S 13:19 0:00 podman対比のために、Docker で同じコンテナを実行した場合のコンテナホスト上のプロセスのリストである。コンテナは PID番号 5339 のプロセスとその子プロセスですが、USER は全て root になっている。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 5339 0.0 1.8 880444 37108 ? Ssl 13:46 0:00 /usr/bin/containerd root 7684 0.0 0.2 10744 4724 ? Sl 13:49 0:00 \_ containerd-shim -namespace moby -workdir /var/lib/containerd/io.conta root 7707 0.2 0.1 11692 2560 ? Ss 13:49 0:00 \_ bash -c while true; do /usr/bin/nc -l -p 3306 < /srv/hello.txt; d root 7757 0.0 0.1 43992 3452 ? S 13:49 0:00 \_ /usr/bin/nc -l -p 3306 root 5701 4.4 4.4 1114504 90648 ? Ssl 13:46 0:10 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock root 7678 0.0 0.1 305136 2964 ? Sl 13:49 0:00 \_ /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3306 -coDocker 19.03 から rootless のコンテナが実行できる様になったが、podman では、よりシンプルに、デーモンレス + ルートレス である。
(6) ほとんどのLinuxプラットフォームで利用できる
パッケージマネージャーでインストールするだけで、簡単に動くかは解らないが、Arch Linux & Manjaro Linux, Fedora, CentOS, Gentoo, MacOS, openSUSE のインストール手順が https://podman.io/getting-started/installation に公開されている。
(7) Kubernetes の Pod を扱える
前面に出されていないが、GitHub の Docs には、マニュアルが整備されていて、その中にはポッドに関するものが多数ある。
ポッド関連のサブコマンドのリストは、https://github.com/containers/libpod/blob/master/docs/podman-pod.1.md でみることができる。podmanの今後の計画(ロードマップ)
podmanは、バージョン 1.0 に到達しているものの、更なる開発を計画されている。
- Podman CLIが Varlinkバックエンドを使用して、MacおよびWindowsから、リモートPodmanインスタンスに接続を実装
- libpodをCRI-Oに統合して、既存のコンテナー管理バックエンドを置き換え
- podman podコマンドのさらなる機能追加
- ルートレスコンテナのさらなる改善
https://github.com/containers/libpod
Podman の Pod 関連の機能を試してみる
Podman のドキュメントを見ると、Kubernetes の pod のマニフェスト生成機能、 podマニフェストからpodの起動機能がある。https://github.com/containers/libpod/tree/master/docs
これは、試してみたくなるので、好奇心のままに、少し遊んでみる。
まずは、普通にnginxのコンテナを起動する。このコンテナから Kubernetesのマニフェストを生成してみたい。[vagrant@fedora30 ~]$ podman run -d -p 8080:80 nginx Trying to pull docker.io/library/nginx... Getting image source signatures Copying blob b8f262c62ec6 done Copying blob 22a7aa8442bf done Copying blob a6639d774c21 done Copying config ab56bba913 done Writing manifest to image destination Storing signatures e65c774464616011c27d419eb15ef38a7f95b9807bf19e81de926a2bb48bf18c [vagrant@fedora30 ~]$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e65c77446461 docker.io/library/nginx:latest nginx -g daemon o... 5 seconds ago Up 4 seconds ago 0.0.0.0:8080->80/tcp elated_taussig [vagrant@fedora30 ~]$ curl http://localhost:8080/ <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...podman で コンテナからポッドのマニフェストを生成
実行中のコンテナの名前、または、CONTIAINER ID を指定して、YAML形式のマニフェストを生成できる。
vagrant@fedora30 ~]$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e65c77446461 docker.io/library/nginx:latest nginx -g daemon o... 6 minutes ago Up 6 minutes ago 0.0.0.0:8080->80/tcp elated_taussig [vagrant@fedora30 ~]$ podman generate kube elated_taussig # Generation of Kubernetes YAML is still under development! # # Save the output of this file and use kubectl create -f to import # it into Kubernetes. # # Created with podman-1.5.1 apiVersion: v1 kind: Pod metadata: creationTimestamp: "2019-09-14T18:00:49Z" labels: app: elatedtaussig name: elatedtaussig spec: containers: - command: - nginx - -g - daemon off; env: - name: PATH value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - name: TERM value: xterm - name: HOSTNAME - name: container value: podman - name: NGINX_VERSION value: 1.17.3 - name: NJS_VERSION value: 0.3.5 - name: PKG_RELEASE value: 1~buster image: docker.io/library/nginx:latest name: elatedtaussig ports: - containerPort: 80 hostPort: 8080 protocol: TCP resources: {} securityContext: allowPrivilegeEscalation: true capabilities: {} privileged: false readOnlyRootFilesystem: false workingDir: / status: {}Kubernetesマニフェストから、コンテナを実行
マニフェストを生成して、既存のコンテナを停止させる。
[vagrant@fedora30 ~]$ podman generate kube elated_taussig > pod.yaml [vagrant@fedora30 ~]$ podman kill elated_taussig e65c774464616011c27d419eb15ef38a7f95b9807bf19e81de926a2bb48bf18c [vagrant@fedora30 ~]$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES生成されたマニフェストを指定して、コンテナを実行する
[vagrant@fedora30 ~]$ podman play kube pod.yaml a container exists with the same name (elatedtaussig) as the pod in your YAML file; changing pod name to elatedtaussig_pod Pod: 475a420c00e777182de6e294f83d68e48e646bc3c3b8912ebdcf8aa19f014ec7 Container: adbb48def6a8ed85db124f54e5b7d249006f6b1bf57fe303b5b8fa444d882fde以下の様に、コンテナとして起動していることを確認できる。
[vagrant@fedora30 ~]$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES adbb48def6a8 docker.io/library/nginx:latest nginx -g daemon o... 25 seconds ago Up 25 seconds ago 0.0.0.0:8080->80/tcp elatedtaussigポッドとして扱うコマンドも用意されている。
[vagrant@fedora30 ~]$ podman pod ps POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID 475a420c00e7 elatedtaussig_pod Running 37 seconds ago 2 3659edba15a5podmanは サイドカーを実行できるか?
サイドカーを持つポッドのマニフェストを利用して、podman のロゴが象徴する複数のコンテナを一まとめにして動作させることができるか、確認してみる。
GitHubからサイドカーを持つポッドのマニフェストをクローンして、podman play kube filename
で実行してみる。[vagrant@fedora30 ~]$ git clone https://github.com/takara9/codes_for_lessons [vagrant@fedora30 ~]$ cd codes_for_lessons/step07/sidecar/ [vagrant@fedora30 sidecar]$ ls Dockerfile contents-cloner webserver.yml次は、マニフェストのリストである。二つのコンテナ間は、emptyDir というストレージで連携する。
webserver.yml## サイドカーポッドのサンプル # apiVersion: v1 kind: Pod metadata: name: webserver spec: containers: ## メイン コンテナ - name: nginx image: nginx volumeMounts: - mountPath: /usr/share/nginx/html name: contents-vol readOnly: true - name: cloner ## サイドカー コンテナ image: maho/c-cloner:0.1 env: - name: CONTENTS_SOURCE_URL value: "https://github.com/takara9/web-contents" volumeMounts: - mountPath: /data name: contents-vol volumes: ## 共有ボリューム - name: contents-vol emptyDir: {}次は、
podman play kube webserver.yml
で実行した結果である。
残念ながら、サイドカーの中のコンテナを連携させるための 共有ボリュームで エラーが発生した。まだ、これからという感じだ。[vagrant@fedora30 sidecar]$ podman play kube webserver.yml Error: HostPath is currently the only supported VolumeSourceおそらく、共有ボリュームを必要としないタイプのサイドカーであれば、問題なく動作するであろう。しかし、その様な例は稀だと思う。
感想
Podman は、dockerコマンドを置き換える目的で、開発されている ルートレス、デーモンレスのコンテナ開発と実行環境である。また、その名前が示す様に、Kubernetesのポッドを実行できることも目指している。Red Hat が立ち上げたオープンソースプロジェクトであり、コミッターのリストをみると、Red Hatの社員が牽引している。そのためか、RHELよりも、Fedoraで最新のバージョンが利用できる。 また、様々な Linux Distribution にも対応すると宣言して、業界でよく知られたメジャーな存在となることを目指していることが伺われる。
個人的には、Dockerはコンテナの世界を幅広く世の中に知らしめ、コンテナの流通の仕組みを作るなど、IT業界への多大な貢献があるにも関わらず、どうして、ここまで置き換え様とされるのか、少々不敏な印象を受ける。 Dockerが非常に価値があることの裏返しでもあると思う。
これからのpodman の動向は注視していきたい。
その他の参考資料
- Red HatがCRI-OとPodmanに投資している理由(英語), https://www.redhat.com/en/blog/why-red-hat-investing-cri-o-and-podman
- 投稿日:2019-09-15T10:19:48+09:00
Dockerの置き換えを目指す ルートレス&デーモンレスの Podman 入門
OpenShiftのマニュアルには、dockerコマンドと共に podmanコマンド が利用できるとされている。OpenShift を触る様になるまで、Podmanの存在を知らなかったので、調べたことをメモとして残しておく。
Podman とは?
このpodmanという名前は、コンテナだけでなく、Kubernetesのポッドの形態でコンテナを起動できることを期待させてくれる。プロジェクトのウェブページから特徴を拾うと次の7つがある。そして、プロジェクトのページの前面には出ていないが、Podmanには、ポッドのマニフェストを生成したり、コンテナを起動する機能もある。Podmanロゴは、可愛いもの路線で、複数のコンテナが内部で動くポッドを実行できることを感じさてくれる。
Podman の特徴
(1) Docker互換のコマンドラインフロントエンドを提供
最も簡単にいうと、
alias docker = podman
ということだ。つまり、docker コマンドの代わりに、podmanで代用できることを意味する。(2) オープンソースプロジェクトであり、GitHub でコードが公開されている
このプロジェクトは Red Hat によって運営されており、Fedora、Red Hat Enterprise Linuxの最新リリースバージョン、および Ubuntuに対して、ビルドをテストしている。
- ホームページ https://podman.io/
- GitHub https://github.com/containers/libpod
podmanのバンドル状況について、調べたところ、2019年9月現在で、次の表の状況がわかった。問題なく動作するのは Fedora 30 だけで、RHEL8はバージョンが古くルートレスモードが実装されていないなどの問題があった。RHEL7/CentOS7 でも動作するとされているが、ルートレスで動作させることができなかった。
Distribution Status Podman version Remarks Fedora 30 GA 1.5.1 sudo なしの rootlessモードで実行可能 RHEL 8.0 GA 1.0.5 rootlessモード未実装 RHEL 7.6 GA 1.4.4 sudo podman で実行 CentOS 7.6 GA 1.4.4 同上 Ubuntu 18.04 GA 1.5.1 sudo なしの rootlessモードで実行可能 このことから、podman は Red Hat がオープンソース・プロジェクトとして、発展途上であると見なされ、dockerコマンドを置き換えるまでに熟成されるには、もう少し時間が必要と考えられる。
(3) OCIに準拠するコンテナイメージの開発、管理、および、コンテナとして実行
Docker Hubに登録されたコンテナを実行すること、podmanでビルドして、レジストリに登録したイメージを、dockerコマンドで実行することも可能であり、互換性に問題はないと見られる。
(4) デーモンレスのコンテナエンジン
podman は、Dockerデーモンの様な root で動作するデーモンを必要としない。つまり、podman コマンドだけで、デーモンの助けを必要とせずにコンテナを実行できる。
(5) コンテナはルートレスモードで実行可能
ルートレスのコンテナは、それらを起動したユーザーよりも多くの特権を持つことはない。もちろん、root権限で実行されるDockerデーモンでも、コンテナが起動したユーザー以上の権限を持つことが無い様に考慮されているが、もしも、悪意のあるプログラムに隔離が突破された場合のリスクは大きい。その点で、ルートレスは明白なため安心感がある。
次は、podman で実行した場合のコンテナホスト上のプロセスのリストで、この中でコンテナのプロセスは、PID 21710 とその子プロセスである。 これらのプロセスの USER は、rootではなく、vagrant という一般ユーザーになっている。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND vagrant 21729 0.0 0.1 4336 2760 pts/0 S 13:21 0:00 /usr/bin/slirp4netns --api-socket /run/user/1000/libpod/tmp/35de2a668cad2 vagrant 21710 0.0 0.0 80348 2012 ? Ssl 13:21 0:00 /usr/libexec/podman/conmon --api-version 1 -c 35de2a668cad28fa366c233a641 vagrant 21721 0.0 0.1 11688 2624 ? Ss 13:21 0:00 \_ bash -c while true; do /usr/bin/nc -l -p 3306 < /srv/hello.txt; done vagrant 21740 0.0 0.1 43988 3364 ? S 13:21 0:00 \_ /usr/bin/nc -l -p 3306 vagrant 21707 0.0 0.1 5756 3208 ? Ss 13:21 0:00 /usr/bin/fuse-overlayfs -o lowerdir=/home/vagrant/.local/share/containers vagrant 21478 0.0 1.8 80508 37540 ? S 13:19 0:00 podman対比のために、Docker で同じコンテナを実行した場合のコンテナホスト上のプロセスのリストである。コンテナは PID番号 5339 のプロセスとその子プロセスですが、USER は全て root になっている。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 5339 0.0 1.8 880444 37108 ? Ssl 13:46 0:00 /usr/bin/containerd root 7684 0.0 0.2 10744 4724 ? Sl 13:49 0:00 \_ containerd-shim -namespace moby -workdir /var/lib/containerd/io.conta root 7707 0.2 0.1 11692 2560 ? Ss 13:49 0:00 \_ bash -c while true; do /usr/bin/nc -l -p 3306 < /srv/hello.txt; d root 7757 0.0 0.1 43992 3452 ? S 13:49 0:00 \_ /usr/bin/nc -l -p 3306 root 5701 4.4 4.4 1114504 90648 ? Ssl 13:46 0:10 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock root 7678 0.0 0.1 305136 2964 ? Sl 13:49 0:00 \_ /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 3306 -coDocker 19.03 から rootless のコンテナが実行できる様になったが、podman では、よりシンプルに、デーモンレス + ルートレス である。
(6) ほとんどのLinuxプラットフォームで利用できる
パッケージマネージャーでインストールするだけで、簡単に動くかは解らないが、Arch Linux & Manjaro Linux, Fedora, CentOS, Gentoo, MacOS, openSUSE のインストール手順が https://podman.io/getting-started/installation に公開されている。
(7) Kubernetes の Pod を扱える
前面に出されていないが、GitHub の Docs には、マニュアルが整備されていて、その中にはポッドに関するものが多数ある。
ポッド関連のサブコマンドのリストは、https://github.com/containers/libpod/blob/master/docs/podman-pod.1.md でみることができる。Podmanの今後の計画(ロードマップ)
podmanは、バージョン 1.0 に到達しているものの、更なる開発を計画されている。
- Podman CLIが Varlinkバックエンドを使用して、MacおよびWindowsから、リモートPodmanインスタンスに接続を実装
- libpodをCRI-Oに統合して、既存のコンテナー管理バックエンドを置き換え
- podman podコマンドのさらなる機能追加
- ルートレスコンテナのさらなる改善
https://github.com/containers/libpod
Podman の Pod 関連の機能を試してみる
Podman のドキュメントを見ると、Kubernetes の pod のマニフェスト生成機能、 podマニフェストからpodの起動機能がある。https://github.com/containers/libpod/tree/master/docs
これは、試してみたくなるので、好奇心のままに、少し遊んでみる。
まずは、普通にnginxのコンテナを起動する。このコンテナから Kubernetesのマニフェストを生成してみたい。[vagrant@fedora30 ~]$ podman run -d -p 8080:80 nginx Trying to pull docker.io/library/nginx... Getting image source signatures Copying blob b8f262c62ec6 done Copying blob 22a7aa8442bf done Copying blob a6639d774c21 done Copying config ab56bba913 done Writing manifest to image destination Storing signatures e65c774464616011c27d419eb15ef38a7f95b9807bf19e81de926a2bb48bf18c [vagrant@fedora30 ~]$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e65c77446461 docker.io/library/nginx:latest nginx -g daemon o... 5 seconds ago Up 4 seconds ago 0.0.0.0:8080->80/tcp elated_taussig [vagrant@fedora30 ~]$ curl http://localhost:8080/ <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...podmanコマンド で コンテナからポッドのマニフェストを生成
実行中のコンテナの名前、または、CONTIAINER ID を指定して、YAML形式のマニフェストを生成できる。
vagrant@fedora30 ~]$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e65c77446461 docker.io/library/nginx:latest nginx -g daemon o... 6 minutes ago Up 6 minutes ago 0.0.0.0:8080->80/tcp elated_taussig [vagrant@fedora30 ~]$ podman generate kube elated_taussig # Generation of Kubernetes YAML is still under development! # # Save the output of this file and use kubectl create -f to import # it into Kubernetes. # # Created with podman-1.5.1 apiVersion: v1 kind: Pod metadata: creationTimestamp: "2019-09-14T18:00:49Z" labels: app: elatedtaussig name: elatedtaussig spec: containers: - command: - nginx - -g - daemon off; env: - name: PATH value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - name: TERM value: xterm - name: HOSTNAME - name: container value: podman - name: NGINX_VERSION value: 1.17.3 - name: NJS_VERSION value: 0.3.5 - name: PKG_RELEASE value: 1~buster image: docker.io/library/nginx:latest name: elatedtaussig ports: - containerPort: 80 hostPort: 8080 protocol: TCP resources: {} securityContext: allowPrivilegeEscalation: true capabilities: {} privileged: false readOnlyRootFilesystem: false workingDir: / status: {}Kubernetesマニフェストから、コンテナを実行
マニフェストを生成して、既存のコンテナを停止させる。
[vagrant@fedora30 ~]$ podman generate kube elated_taussig > pod.yaml [vagrant@fedora30 ~]$ podman kill elated_taussig e65c774464616011c27d419eb15ef38a7f95b9807bf19e81de926a2bb48bf18c [vagrant@fedora30 ~]$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES生成されたマニフェストを指定して、コンテナを実行する
[vagrant@fedora30 ~]$ podman play kube pod.yaml a container exists with the same name (elatedtaussig) as the pod in your YAML file; changing pod name to elatedtaussig_pod Pod: 475a420c00e777182de6e294f83d68e48e646bc3c3b8912ebdcf8aa19f014ec7 Container: adbb48def6a8ed85db124f54e5b7d249006f6b1bf57fe303b5b8fa444d882fde以下の様に、コンテナとして起動していることを確認できる。
[vagrant@fedora30 ~]$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES adbb48def6a8 docker.io/library/nginx:latest nginx -g daemon o... 25 seconds ago Up 25 seconds ago 0.0.0.0:8080->80/tcp elatedtaussigポッドとして扱うコマンドも用意されている。
[vagrant@fedora30 ~]$ podman pod ps POD ID NAME STATUS CREATED # OF CONTAINERS INFRA ID 475a420c00e7 elatedtaussig_pod Running 37 seconds ago 2 3659edba15a5Podmanは サイドカーを実行できるか?
サイドカーを持つポッドのマニフェストを利用して、podman のロゴが象徴する複数のコンテナを一まとめにして動作させることができるか、確認してみる。
GitHubからサイドカーを持つポッドのマニフェストをクローンして、podman play kube filename
で実行してみる。[vagrant@fedora30 ~]$ git clone https://github.com/takara9/codes_for_lessons [vagrant@fedora30 ~]$ cd codes_for_lessons/step07/sidecar/ [vagrant@fedora30 sidecar]$ ls Dockerfile contents-cloner webserver.yml次は、マニフェストのリストである。二つのコンテナ間は、emptyDir というストレージで連携する。
webserver.yml## サイドカーポッドのサンプル # apiVersion: v1 kind: Pod metadata: name: webserver spec: containers: ## メイン コンテナ - name: nginx image: nginx volumeMounts: - mountPath: /usr/share/nginx/html name: contents-vol readOnly: true - name: cloner ## サイドカー コンテナ image: maho/c-cloner:0.1 env: - name: CONTENTS_SOURCE_URL value: "https://github.com/takara9/web-contents" volumeMounts: - mountPath: /data name: contents-vol volumes: ## 共有ボリューム - name: contents-vol emptyDir: {}次は、
podman play kube webserver.yml
で実行した結果である。
残念ながら、サイドカーの中のコンテナを連携させるための 共有ボリュームで エラーが発生した。まだ、これからという感じだ。[vagrant@fedora30 sidecar]$ podman play kube webserver.yml Error: HostPath is currently the only supported VolumeSourceおそらく、共有ボリュームを必要としないタイプのサイドカーであれば、問題なく動作するであろう。しかし、その様な例は稀だと思う。
感想
Podman は、dockerコマンドを置き換える目的で、開発されている ルートレス、デーモンレスのコンテナ開発と実行環境である。また、その名前が示す様に、Kubernetesのポッドを実行できることも目指している。Red Hat が立ち上げたオープンソースプロジェクトであり、コミッターのリストをみると、Red Hatの社員が牽引している。そのためか、RHELよりも、Fedoraで最新のバージョンが利用できる。 また、様々な Linux Distribution にも対応すると宣言して、業界でよく知られたメジャーな存在となることを目指していることが伺われる。
個人的には、Dockerはコンテナの世界を幅広く世の中に知らしめ、コンテナの流通の仕組みを作るなど、IT業界への多大な貢献があるにも関わらず、どうして、ここまで置き換え様とされるのか、少々不敏な印象を受ける。 Dockerが非常に価値があることの裏返しでもあると思う。
これからのpodman の動向は注視していきたい。
その他の参考資料
- Red HatがCRI-OとPodmanに投資している理由(英語), https://www.redhat.com/en/blog/why-red-hat-investing-cri-o-and-podman
- 投稿日:2019-09-15T02:08:04+09:00
Django2環境をDocker使って整える
はじめに
興味本位で新しいフレームワークを試してみようと始めた『Laravel環境構築』
Docker構築にも慣れてきたので
改めてDjango2環境の開発環境としてDockerで作成してみました。環境
- Windows10 Pro
- docker for windows (docker desctop community) (ver.2.1.0.2)
- VSCode
Django2環境
Dockerの構成はこんな感じ
- django2_nginx:1.17.3 (based
nginx:1.17.3
)- django2_python:3.7.4 (based
python:3.7.4
)- django2_postgres:9.6.15 (based
postgres:9.6.15
)dockerの定義
ローカルのディレクトリ構成はこんな感じにしました。
├─ laravel/ ├─ postgres/ │ └─ Dockerfile # postgres用Dockerfile ├─ nginx/ │ ├─ etc/ │ │ ├─ conf.d/ │ │ │ └─ default.conf # nginxサイト定義 │ │ └─ nginx.conf # nginx基本定義 │ └─ Dockerfile # nginx用Dockerfile ├─ python/ │ ├─ apps/ │ │ │ : │ │ └─ setup.sh # migrate,createsuperuser用スクリプト │ └─ Dockerfile # php-fpm用Dockerfile ├─ .gitignore # pythonのキャッシュ除外用gitignore ├─ docker-compose.yaml # 全てのdocker定義docker-compose.yaml
全ての要、docker-compose.yamlはこんな形になりました。
ポートが微妙におかしいのは、先日のLaravevlと共存したいためです(笑)
- nginxはポート8088でlistenしています。
- nginxはdjango2プロジェクトの
apps/static
を/opt/apps/static
に腹持ちさせました。- postgresは5432番でlistenしています。
- postgresはデータ永続化のためdbvolumeコンテナを作成しました。
- pythonは
/opt/apps
にdjango2プロジェクトをあらかじめ生成したものを腹持ちさせています。- Django2はgunicornによりnginxからの通信を3031番で待ち受けします。
docker-compose.yamlversion: '3.3' services: postgres: container_name: django2_postgres build: ./postgresql/ image: django2_postgres:9.6.15 restart: always ports: - 5432:5432 volumes: - dbvolume:/var/lib/postgresql/data environment: - POSTGRES_DB=sample_db - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres@1234 - PGDATA=/var/lib/postgresql/data python: container_name: django2_python build: ./python/ image: django2_python:3.7.4 links: - postgres volumes: - ./python/apps:/opt/apps - ./python/app/static:/opt/apps/static expose: - 3031 environment: - DJANGO_ADMIN_USER=admin - DJANGO_ADMIN_EMAIL=admin@localhost.localdomain - DJANGO_ADMIN_PASSWORD=django2@1234 command: > /bin/bash -c "./setup.sh && gunicorn wsgi -b 0.0.0.0:3031" depends_on: - postgres nginx: container_name: django2_nginx build: ./nginx/ image: django2_nginx:1.17.3 ports: - 8088:80 links: - python depends_on: - python volumes: - ./python/app/static:/opt/apps/static volumes: dbvolume:それでは各Dockerの定義を見ていきましょう!
postgres:9.6.15用Docker定義
TZ変更のみのDockerfileとしています。
postgres/DockerfileFROM postgres:9.6.15 RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtimenginx:1.17.3用Docker定義
TZ変更およびログファイルのstdout,strerrリンク、設定ファイルのCOPYをするDockerfileとしています。
nginx/DockerfileFROM nginx:1.17.3 RUN ln -sf /usr/share/zoneinfo/Japan /etc/localtime RUN ln -sf /dev/stdout /var/log/nginx/access.log && \ ln -sf /dev/stderr /var/log/nginx/error.log && \ ln -sf /dev/stdout /var/log/nginx/host.access.log COPY ./etc/nginx.conf /etc/nginx/nginx.conf COPY ./etc/conf.d /etc/nginx/conf.dnginx.confの設定は、gzip、upstreamサーバ設定を行っています。
nginx/etc/nginx.confuser nginx; worker_processes 1; error_log /var/log/nginx/error.log debug; pid /var/run/nginx.pid; events { worker_connections 1024; } http { server_tokens off; include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; gzip on; gzip_types image/png image/gif image/jpeg text/javascript text/css; gzip_min_length 1000; gzip_proxied any; gzip_comp_level 9; upstream django2_server { server python:3031 fail_timeout=0; } include /etc/nginx/conf.d/*.conf; }default.confの設定は割とシンプル
nginx/etc/conf.d/default.confserver { listen 80; server_name _; root /opt/apps; index index.php; #charset koi8-r; access_log /var/log/nginx/host.access.log main; location /static/ { root /opt/apps/static; } location / { try_files $uri @proxy_to_django2; } location @proxy_to_django2 { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_redirect off; proxy_pass http://django2_server; } # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # location ~ /\. { deny all; } }python:3.7.4用Docker定義
TZ変更は他サーバーのDockerfileと同様ですが、
pythonモジュールのインストールをrequirements.txt
により指定し行っています。WORKDIRはDjango2プロジェクトの
apps
フォルダとしています。python/DockerfileFROM python:3.7.4 ENV APP_PATH /opt/apps RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime WORKDIR $APP_PATH COPY ./apps/requirements.txt $APP_PATH/ RUN pip install --no-cache-dir -r $APP_PATH/requirements.txtインストールするモジュールは以下の通りです。
作成するプロジェクトに応じて追加してください。python/apps/requirements.txtdjango==2.2.5 djangorestframework django-filter psycopg2 gunicornこの
setup.sh
によりDBのマイグレーションおよびスーパーユーザ作成を行っています。
ユーザ名、メールアドレス、パスワードはdocker-compose.yaml
の環境変数で指定しています。python/apps/setup.sh#!/bin/bash echo "##### setup django2 app #####" echo "-> migrate database" python manage.py makemigrations --noinput python manage.py migrate --noinput echo "-> create super user" python manage.py shell <<EOF from django.contrib.auth.models import User if not User.objects.filter(username='$DJANGO_ADMIN_USER'): User.objects.create_superuser('$DJANGO_ADMIN_USER', '$DJANGO_ADMIN_EMAIL', '$DJANGO_ADMIN_PASSWORD') print(' create super user: $DJANGO_ADMIN_USER') else: print(' user: $DJANGO_ADMIN_USER already exists, nothing to do')pythonが動作した際に作成されるキャッシュ達をgitにcommmitしないためのおまじない(^^♪
python/.gitignore__pycache__/ *.py[cod]Dockerの起動
ここまで準備ができたらdockerを起動します。
C:\Users\tak>cd C:\Git\docker\django2 C:\Git\docker\django2>docker-compose build C:\Git\docker\django2>docker-compose upいやDockerによる開発環境、手軽に作れて壊せて便利ですね!
- 投稿日:2019-09-15T00:16:55+09:00
怖くないよね?マルチステージビルド
会社の本番環境をAWSのEKSに移行することになりその際にgolangのアプリを配布する際に使用したマルチステージビルドについて備忘録を交えながら記事を書いていきます。
先に言うんですけど
すみません僕Docker自体初めてです
今まで特に自分でDockerなどで環境構築をしたことがなかったのでこれが初めてのDocker作成です。
ほとんど分かっていないのでこいつダメやなって思いながら見てくださいマルチステージビルドについて
https://github.com/moby/moby/pull/31257簡単に言うと、fromでから作られた2つの複数のFROMイメージ間のファイルを COPY --from で直接を参照できるようになったのと AS で中間イメージに名前が付けられるようになったと言うものです。
golangってクロスコンパイルなどでシングルバイナリさえあればgolangの実行環境不要ですもんね
(golangにいては割愛します。)早速やりましょうか
基本的なファイル構成はこちら
├build(ここにbuildの成果物が格納される) │ └ appname(実行バイナリ) ├cmd(実行ディレクトリ) │ └ main.go ├configs(設定ファイル関連) ├bitbucket-pipelines.yml ├.env(環境変数設定ファイル) ├docker-compose.yml ├Dockerfile ├go.mod ├go.sum ├Makefile(タスクランナー実行ファイル)Makefile
基本的には今回は
go build
なども含めて全てMakefile側に任せています。makefileに関しての設定はここで書きませんがちゃんとbuild配下にバイナリが入るように以下のように設定しました
build: @go build -ldflags="-w -s" -o build/appname ./cmd/main.goこれで
make build
のコマンドをターミナルで実行するとbuild配下にappnameと言うシングルバイナリが作成されますDockerfile
FROM golang:1.12.9 as builder ADD . /appname/ WORKDIR /appname/ ENV GO111MODULE=on COPY go.mod . COPY go.sum . RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 make build FROM alpine RUN apk update \ && apk add --no-cache COPY --from=builder /appname/build /app/build ENTRYPOINT [ "/app/build/appname" ]まずポイントを解説すると
FROM golang:1.12.9 as builderこれでgolangのbaseimageを作成しますこの
as builder
と言うのがこの後にこのimageを渡すためのエイリアスになりますENV GO111MODULE=on COPY go.mod . COPY go.sum . RUN go mod download COPY . .go.modはgolangのモジュール関連の設定ファイルです(jsのpackage.jsonみたいなもの)
https://qiita.com/propella/items/e49bccc88f3cc2407745
ENV GO111MODULE=on
はおまじないみたいなもので現行のgo1.13の環境では必要ないと思う(動かなかったらいれてください)RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 make buildここでgoのbuildを行います
make build
コマンドは先ほど作成したMakefile
のトリガーとしてbuild
を設定していたのでこのようなコマンドでタスクの実行が可能ですクロスコンパイルについてはこちらを参照してください
https://qiita.com/xshirade/items/abeb0d595be27cb6326eFROM alpineこちらはDockerの公式が提供している軽量なLinuxのイメージです。
https://alpinelinux.org/COPY --from=builder /appname/build /app/buildここで先ほどbuildした実行バイナリの格納ファイル等をこちらにCOPYしています
これでマルチステージビルドの完成です補足
これで
ducker build
などでもいいのですが開発環境等でmysqlに接続できる等などの確認が必要だと思うのでdokcer-compose.ymlで環境の構築を行いますdocker-compose.ymlversion: "3" services: mysql: image: mysql:5.7.26 container_name: db env_file: - .env ports: - "3306:3306" volumes: - db_data:/var/lib/mysql - ./mysql/scripts/init:/docker-entrypoint-initdb.d - ./mysql/config:/etc/mysql/conf.d api: build: . depends_on: - mysql env_file: - .env ports: - "8080:8080" volumes: db_data:これで
$ docker-composer build && docker-compose up -dこちらで接続ができているかなどの確認(go側にmysqlに接続などのプログラムは書いてくださいね)
最後に
僕自身初めてのDockerだったので探り探りでの実装だったのですがもし他にこれの方がいいよってものがありましたら是非教えて頂けますと幸いです。
最後まで読んで頂いてありがとうございました。次にbitbucket-pipelines.ymlを使用したECRへのPUSHをしたいと思います。