- 投稿日:2020-01-18T22:25:50+09:00
[Docker知識不要]Docker上でのHugo Extend環境の作り方
Docker上でのHugo Extend環境の作り方
こんにちは、ITエンジニアの田中です!
この記事を読むと下記の事ができるようになります。
- Docker上でHugo環境を作れる。
- Docker上のHugoのコンテナに入り新規記事を作る事ができる。
- Docker上のHugoの簡易サーバーを動かしホストOSのブラウザから閲覧できる。
下記のことが事前に完了していることが前提です。
- Dockerがインストールされている
- ホストOSでgitが使用できる
私の最初の失敗
Docker Hubにある下記のイメージを使用してHugo環境を作成しようとしました。
publysher/hugoしかし、起動に失敗。理由は多分事前にHugoのコンテンツがなかったことが原因です。
事前に環境がないから作りたいと思っていていたのでハードルが高い。。。。
もっと簡単に作りたい。そして、ローカル環境にgo開発環境を作らないで、かつあたかもローカルで記事を書いたりしたいと思っていました。事前知識もなくHugo環境をdockerで作れる!方法を見つけたので共有します。
フォルダ構成
docker-compose用の任意箇所にフォルダを作ってください。
フォルダ名をhugoとします。hugoフォルダ配下に下記のファイルを作成します。
- DockerFile
- docker-compose.ymlDockerfile内容
下記のDockerfileを作成します。
FROM debian:stretch LABEL maintainer "you1978 <you1978@hotmail.com>" # Install pygments (for syntax highlighting) RUN apt-get -qq update \ && DEBIAN_FRONTEND=noninteractive apt-get -qq install -y --no-install-recommends python-pygments git ca-certificates asciidoc \ && rm -rf /var/lib/apt/lists/* # Download and install hugo ENV HUGO_VERSION 0.62.0 ENV HUGO_BINARY hugo_extended_${HUGO_VERSION}_Linux-64bit.deb ADD https://github.com/spf13/hugo/releases/download/v${HUGO_VERSION}/${HUGO_BINARY} /tmp/hugo.deb RUN dpkg -i /tmp/hugo.deb \ && rm /tmp/hugo.deb # Create working directory RUN mkdir /usr/share/blog WORKDIR /usr/share/blog # Expose default hugo port EXPOSE 1313 # Automatically build site ONBUILD ADD site/ /usr/share/blog ONBUILD RUN hugo -d /usr/share/nginx/html/ # By default, serve site ENV HUGO_BASE_URL http://localhost:1313 CMD hugo server -b ${HUGO_BASE_URL} --bind=0.0.0.0docker-compose.yml
下記のdocker-compose.ymlファイルを作成します。
version: '3' services: web: build: . image: my/hugo volumes: - ./site:/usr/share/blog ports: - "1313:1313" stdin_open: true tty: trueHugoの新規サイトを作成する
ターミナルにて、Hugoフォルダに移動して、下記のコマンドを実行する。
> docker-compose run -w /usr/share web hugo new site blog実行するとHugoフォルダ直下siteというフォルダが作成されています。
Hugoのテーマを適用する
下記のコマンドを使用して
ホストOS上でsiteの下のthemeフォルダに移動します。
今回はanankeというテーマを例として使用します。> cd themes > git clone https://github.com/budparr/gohugo-theme-ananke.git下記のファイルを移動させてください.
移動元
site/themes/gohugo-theme-ananke/exampleSite/config.toml移動先
site/config.tomlconfig.tomlを開いて、下記の行をコメントアウトしてください。
# themesDir = "../.."Hugoの起動
下記のコマンドを実行しサイト
docker-compose up -dサイトにアクセスする
ブラウズを開いて、下記のURLをアドレスバーに入れてください。
http://localhost:1313/新しいページを作成する
下記のコマンドを実行すると新しいページが作成されます。
docker-compose run web hugo new post/page2.md下記のファイルを編集するとサイトも更新されます。
hugo/site/content/page2.md大きく変更するとサイトが更新されない時があります。
その場合は、コンテイナを再起動してくださいdocker-compose down docker-compose up以上、[Docker知識不要]Docker上でのHugo環境の作り方でした。
コメントお待ちしています。
- 投稿日:2020-01-18T21:02:38+09:00
k8s環境ハンズオン k8s基本学習編
k8s環境ハンズオン k8s基本編
もくじ
- k8sの概念を理解する。
- k8sの基本操作を覚える。
k8sの概念を理解する。
- Hello World !(Kubernetes)
- Kubernetesとは
- Kubernetesリソース
- Kubernetesネットワーク
- 学習環境のネットワーク
Hello World !(Kubernetes)
- helloworldイメージをk8s上で実行、確認、削除してみよう
kubectl run hello-world --image hello-world --restart=Never上記コマンド解説:
最初のhello-worldはk8sのpod名
次は実際に取ってくるドッカーイメージのhello-world
--restart=Never →podが存在しなくなったときに再起動しないようにする。podが作成されているか、下記のコマンドで確認。
kubectl get pod確認できたので、ログを確認してみる。
kubectl logs pod/hello-worlddockerコンテナの実行が確認できました。
最後に作成したpodを削除します。
kubectl delete pod/hello-worldKubernetesとは
Kubernetesとはコンテナオーケストレーション
下記のようなシステム運用で困った課題を解決できる。
課題 kubernetesができること システムリソースの利益率に無駄がある 複数コンテナの共存 突発的な大量アクセスでシステムが応答しない 水平スケール 突然一部システムがダウンした 監視&自動デプロイ リリースのたびにサービスが停止する ローリングデプロイ 使えるリソースを一元管理
kubectlでmasternodeに命令してmasternodeがworkernodeに命令して働かせる。Kubernetesリソース
主なリソースは4分類10種類のリソース
分類 種別 ワークロード (pod)(replicaset)(deployment)(statefulset) サービス (service)(ingress) 設定 (ConfigMap)(Secret) ストレージ (persistentvolume)(persistentvolumeclaim)
種別名 定義 ワークロード(pod) 最小単位、dockerコンテナの集合 ワークロード(replicaset) podの集合、podをスケールできる ワークロード(deployment) replicasetの集合、replicasetの世代管理が出来る ワークロード(statefulset) podの集合、podをスケールする際の名前が一定
種別名 定義 サービス(service) 外部公開、名前解決、L4ロードバランサ サービス(ingress) 外部公開、L7ロードバランサ
種別名 定義 設定(ConfigMap) 設定情報 設定(Secret) 機微情報
種別名 定義 ストレージ(persistentvolume) 永続データの実態 ストレージ(persistentvolumeclaim) 永続データの要求 Kubernetesネットワーク
NODEとpod
・nodeは実サーバに一致。
・リソースは各ワーカーノードに分散配置される。2つの異なるネットワーク
・kubernetes には異なる二つのネットワークがある。
(外部ネットワーク)(クラスタネットワーク)・「クラスタネットワーク」へ外から直接アクセスは出来ない。
コンテナへのアクセス
・管理端末は外部ネットワークに接続している。コンテナへのアクセス方法は下記の3つ
学習環境のネットワーク
DockerもKubernetesも仮想マシン(ゲストOS)の中に納まっています。また、操作するターミナルもゲストOSのものを使って操作していきます。
すべてが仮想マシンに納まっていますので、操作的にはイメージしやすい環境です。minikubeが作成するKubernetesクラスタはシングルノードなのでマスターやワーカーといった区別がありません。
minikubeをインストールした先で操作を行えば Kubernetes を操作できます。
k8sの基本操作を理解する。
- リソースの作成/確認/削除
- コマンドでSecretリソース作成
- マニフェストファイル (kind, metadata, spec)
- マニフェストファイル (command, args, env)
- kindに応じたapiVersioniの確認
- リソース種別名の省略記法
- Podに入ってコマンド実行
- Podとホスト間でファイル転送
- Podのログ確認
リソースの作成/確認/削除
リソース作成手順
「定義作成」→「定義適用」の2ステップ①「マニフェストファイル作成」:YAMLファイルを作成
apiVersion: v1 kind: Pod metadata: name: test namespace: default labels: env: study spec: containers: - name: hello-world image: hello-world②「kubernetes反映」:kubectlコマンド利用して反映
- リソース作成/変更コマンド↓
kubectl apply -f <filename> マニフェストファイルを指定してリソース作成変更します。 オプション -f<filename> マニフェストファイルパス
- リソース確認コマンド↓
kubectl get [-f <filename>][TYPE] 指定したリソースを確認します オプション -f<filename> マニフェストファイルパス TYPE リソース種別 (pod,resplicaset)
- リソース削除コマンド↓
kubectl delete [-f <filename>][TYPE/NAME][-o [wide|yaml]] 指定したリソースを削除します オプション -f<filename> マニフェストファイルパス TYPE/NAME -o [wide | yaml] 出力形式を指定します。 -wide:追加情報の表示 -yaml:YAML形式で表示演習:Podの作成/確認/削除
- hello-worldコンテナ含むpod作成
- podが起動していること確認
- podを削除ymlファイルを作業ディレクトリに配置してhello-worldコンテナ含むpod作成する
kubectl apply -f pod.ymlpodが出来ているか確認する。
kubectl get -f pod.ymlallでよく見るリソース一覧も表示できるpodが出来ているか確認する。
kubectl get allkubectl get pod ならpodリソース限定で表示する。
kubectl get pod指定したpodリソースを削除する。
kubectl delete -f pod.yml
コマンドでSecretリソース作成
マニフェストファイル (kind, metadata, spec)
今回はマニフェストファイルの書き方について学習します。
- マニフェストファイルの構成
- kind と apiVersion
- metadata.name
- matadata.labels
- spec.containers.name
- spec.containers.image
- 演習:nginxポッドの作成マニフェストファイルの構成は
種別、メタデータ、コンテナ定義の3構成。apiVersion: v1 kind: Pod metadata: name: nginx namespace: default labels: app: nginx env: study spec: containers: - name: nginx image: nginx:1.17.2-alpinekindとapiversion
kindはリソース種別。kindによってapiversionが決まる。metadata.name:
pod名はnamespaceと合わせて一意にする。medatada.labels:
ラベルは任意で付与できる。spec:containers:name:
podに含まれるコンテナ名を指定。spec:containers:image:
コンテナのイメージを指定するときはバージョンも指定する。バージョン指定がないとlatest指定になり誤動作に繋がる。演習:Podの作成/確認/削除
- nginxを含むpodのマニフェストファイル作成
- k8sリソース作成
- podが起動していること確認
- podを削除上記のnginxのイメージを定義したマニフェストファイルを作業ディレクトリに配置してpod作成する
kubectl apply -f pod.ymlpodが出来ているか確認する。
kubectl get -f pod.yml指定したpodリソースを削除する。
kubectl delete -f pod.yml
マニフェストファイル (command, args, env)
今回もマニフェストファイルの書き方について学習します。
- マニフェストファイル
- kind と apiVersion
- command, args
- env
演習:
- 終了しないポッドの作成今回はマニフェストファイルに記載する環境変数を学習する。
apiVersion: v1 kind: Pod metadata: name: debug namespace: default spec: containers: - name: debug image: centos:7 command: - "sh" - "-c" args: - | while true do sleep ${DELAY} done env: - name: "DELAY" value: "5"5秒ディレイ設定が入る。
commandとargs:
コンテナに対する処理を指定する。commandとargsに引数を入れておくと実行時のコマンドを指定できる。
k8sとdockerでマッピングは異なる。
dockerにおけるエントリポイントはk8sのコマンドに相当します。
dockerのコマンドはk8sではargsに指定します。
環境変数を指定したい場合、envにオブジェクトを指定します。
k8sでは環境変数でコンテナ設定を渡すケースが多いのでenvは良く使う。
演習:終了しないpod作成
- centos:7にコマンド渡して終了しないマニフェストファイル作成
- podを作成
- podが起動していること確認
- podを削除上記のcommandとargsを指定したマニフェストファイルを作業ディレクトリに配置してpod作成する
kubectl apply -f pod.ymlpodが出来ているか確認する。(-wで状態まで確認する。)
kubectl get pod -w指定したpodリソースを削除する。
kubectl delete -f pod.yml
kindに応じたapiVersioniの確認
リソース種別に応じたapiversionの確認する方法について学習する。
kindからどのapiversionなるか調べられるのはAPIドキュメントから探すこと。podのapiversionを確認する方法:
- k8sのAPIリファレンスを参照してする。podだったらcore/v1→coreは省略できる。
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#pod-v1-coreingressだったらnetworking.k8s.io/v1beta1
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#ingress-v1beta1-networking-k8s-io
リソース種別名の省略記法
詳しくは下記のURL参照:
https://kubernetes.io/docs/reference/kubectl/overview/#resource-types
Podに入ってコマンド実行
- コンテナへ入る
kubectl exec -it POD sh 指定したpodに入ってシェル操作を行えるようにします。 引数 POD 中に入りたいpod名
- コンテナから出る
exit #プロセス終了してコンテナからログアウト [ctrl] + [p] → [ctrl] + [q] #プロセスを残したままコンテナからログアウト演習:起動中のpodの中に入る
- centosとnginxを起動するマニフェストファイル作成
- centosとnginxのpodを起動
- podのipアドレス確認
- 起動したcentosコンテナ内に入る
- nginxに対してcurlを実行
- centosから出る
- centosとnginxのpodを削除①centosとnginxを起動するマニフェストファイル作成
一つのマニフェストファイルで2つのpodを作成する
pods.ymlapiVersion: v1 kind: Pod metadata: name: debug namespace: default spec: containers: - name: debug image: centos:7 command: - "sh" - "-c" args: - | while true do sleep ${DELAY} done env: - name: "DELAY" value: "86400" --- apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.17.2-alpine上記のマニフェストファイルを作業ディレクトリに配置してpod作成する
kubectl apply -f pods.yml今回はデバッグ用podからnginxにアクセスしたいので
作成したpodのIPアドレスを調べたいので-o wideオプション使用して実行kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES debug 1/1 Running 0 3m23s 172.17.0.3 minikube <none> <none> nginx 1/1 Running 0 3m11s 172.17.0.2 minikube <none> <none>ipが解ったのでdebugコンテナにログインを試し見る。
kubectl exec -it debug sh続いてcurlでipを使ってアクセス
curl http://172.17.0.2/<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>nginxのコンテナにhttpでリクエスト出来ていることが確認できる。
続いて、コンテナから脱出する。exit実行してるpodを削除する。
kubectl delete -f pod.yml
Podとホスト間でファイル転送
- ファイル転送
kubectl cp SRC DEST 指定されたファイルを指定された転送先に送ります。 引数 SRC 転送元ファイル DEST 転送先ファイル
- ファイル転送(ホスト→pod)
kubectl cp <src> <pod-name>:<dest> 指定されたファイルを指定された転送先に送ります。 引数 src 転送元ファイル名/フォルダ名 pod-name 転送先のpod名 dest 転送先フォルダ名/ファイル名演習:起動中のpodの中に入る
- centosのpodを起動
- ホスト上でファイル作成してpodへ転送
- podへ入って確認
- pod上でファイル作成
- podからホストへファイル転送して確認
- podからホストへファイルを転送して確認
- centosとpodの削除pod.ymlapiVersion: v1 kind: Pod metadata: name: debug namespace: default labels: env: study spec: containers: - name: debug image: centos:7 command: - "sh" - "-c" args: - | while true do sleep ${DELAY} done env: - name: "DELAY" value: "86400"上記のマニフェストファイルを作業ディレクトリに配置してpod作成する。
kubectl apply -f pod.yml作成したpodの動作確認をする。
kubectl get pod作業ディレクトリに1.txtを作成してdebugPodにファイル転送する。
kubectl cp ./1.txt debug:/var/tmp/1.txt作成出来たか確認するためdebugPodの中に入っていく。
kubectl exec -it debug sh lsでファイル存在確認 ls /var/tmp/ catでファイル中身確認 cat /var/tmp/1.txt続いてpodの中でファイルを作成してそれを取り出します。
cd ~; vi 2.txt 中身はお好みで exitdebugpodから作成した2.txtを取り出す。
kubectl cp debug:/root/2.txt ./2.txt 取り出せたら中身を確認 cat ./2.txtうまくいったらpodを削除。
kubectl delete -f pod.yml
Podのログ確認
podがうまく動作しない時のためのログの確認方法を学ぶ
- 状況(概況)を確認
- ログ(詳細)を確認
- 演習:nginxのアクセスログ確認
- 状況(概況)を確認
kubectl describe [TYPE/NAME] 指定したリソースの状態を確認します。 引数 [TYPE/NAME] リソース種別とリソース名を指定
- ログ(詳細)を確認
kubectl logs [TYPE/NAME][--tail=n] 指定したリソースの状態を確認します。 引数 [TYPE/NAME] リソース種別とリソース名を指定 [--tail=n] 直近のnレコードだけ取得kubectl logsコマンドはkubectl describeより詳細な情報を教えてくれる。
演習:nginxアクセスログを確認
- centosとnginxのpodを起動
- centosとnginxの状態を確認
- centosに入る
- curlでnginxにアクセス
- centosから出る
- nginxのログを確認
- centosとnginxのpodを削除pods.ymlapiVersion: v1 kind: Pod metadata: name: debug namespace: default spec: containers: - name: debug image: centos:7 command: - "sh" - "-c" args: - | while true do sleep ${DELAY} done env: - name: "DELAY" value: "86400" --- apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.17.2-alpine上記のマニフェストファイルを作業ディレクトリに配置してpod作成する
kubectl apply -f pods.ymldesclibeでpodの情報が何処まで確認できるか試す。
kubectl describe pod/debugeventsでどんな動きをしてるか確認する。
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 97s default-scheduler Successfully assigned default/debug to minikube Normal Pulled 83s kubelet, minikube Container image "centos:7" already present on machine Normal Created 81s kubelet, minikube Created container debug Normal Started 79s kubelet, minikube Started container debugnginxも見てみる。
kubectl describe pod/nginxcentosに入って、nginxにアクセスログを確認する。
今回はデバッグ用podからnginxにアクセスしたいので
作成したpodのIPアドレスを調べたいので-o wideオプション使用して実行kubectl get pod -o wideNAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES debug 1/1 Running 0 3m23s 172.17.0.2 minikube <none> <none> nginx 1/1 Running 0 3m11s 172.17.0.3 minikube <none> <none>ipが解ったのでdebugコンテナにログインを試し見る。
kubectl exec -it debug sh続いてcurlでipを使ってアクセス
curl http://172.17.0.3/続いて、コンテナから脱出する。
exitnginxのアクセスログを確認する。
kubectl logs pod/nginx172.17.0.2 - - [18/Jan/2020:06:28:22 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"使用したpodを削除する。
kubectl delete -f pods.yml
- 投稿日:2020-01-18T19:05:04+09:00
Run multiple processes in Use supervisor in docker on Ubuntu18.04
dockerで、1コンテナでNプロセス動かすのにsupervisordを使用する。
Dockerfile
# ubuntu is Official Image FROM ubuntu RUN apt update RUN apt install --no-install-recommends --no-install-suggests \ supervisor \ -y RUN apt clean CMD ["/usr/bin/supervisord", "--nodaemon", "-c", "/etc/supervisor/supervisord.conf"]起動するプログラムごとの設定ファイル
/etc/supervisor/conf.d/に用意する。
# cron example % cat /etc/supervisor/conf.d/cron.conf [program:cron] command=/usr/sbin/cron -f
- 投稿日:2020-01-18T18:40:24+09:00
Splashメモリ使いすぎ問題の回答(案)
弊研究室のアドベントカレンダーまさか無事に終わるとは思っていませんでした。
今回ははSplashのメモリ問題について書きます。結論
メモリ食いすぎたら勝手に落ちるから再起動
これは何か
以前にScrapyはいいぞぉって記事を書きました。しかしScrapyには一点問題があります。それは、当然のようにJavaScriptが動作しないことです。JavaScriptを使うページをScrapyでスクレイピングするときによく使うのがSplashというツールです。
Splashは、JavaScriptをレンダリングしてくれるサーバで、WebAPIを使ってアクセスすることで指定したサイトのJavaScript実行後のソースを取得することができます。中身はPythonで書かれていて、TwistedとQT3を使っているみたいです。
問題
そんな便利なSplashですが、1つ大きな問題があります。それは、メモリをめちゃくちゃ消費することです。
下の図は、Splashのメモリ消費量のグラフです。
リクエストをすればするほど消費するメモリが増えていきます。この調子ではいくらメモリを積んでもあっという間になくなってしまいます。
Githubにも同様のIssueは立っていますが、Pythonの仕様でメモリを解放することができないみたいです。
https://github.com/scrapinghub/splash/issues/674解決策
Pythonの問題は流石に手が打てません。もし知っている人がいたら教えてください。
上記のIssueにも書いてあるように、メモリを解放するには一回Splashを落とす以外に方法がありません。ただ、Splashを手動で落とすわけにはいかないので自動で落とす必要があります。cronとかで1分ごとに再起動みたいなスクリプトを書くのもアリですがめんどくさい。そんなときにどうすればいいか。メモリ不足で落ちるまで待ちましょう。そして自動で再起動させましょう
あまり頭がいい解決策ではないですがこれが一番楽です。
どうするか
以下のような状況を対象にします。
- SplashはDockerで動かしてる
- docker-composeを使っている
まず、SplashのDockerコンテナが使えるメモリの上限を設定します。docker-composeはversion3から
mem_limit
がなくなってしまったので2を使います。
また、落ちた時に自動で再起動するようにrestart:always
をつけてあげます。version: "2" services: splash: image: "scrapinghub/splash:3.3" ports: - "8050:8050" mem_limit: 2g restart: always command: --disable-browser-caches --maxrss 4000これでメモリを必要以上に食うことがなくなりました。
終わりに
途中でも言ったようにあまり頭のいい解決策ではないです。もっと賢く楽にできる方法があったら教えてください。
参考にしたサイト
- 投稿日:2020-01-18T18:26:27+09:00
Install Jenkins (docker based)
? How to install Jenkins based on docker.
Test environment
- Ubuntu 18.04
- docker 18.09.1
Install
Create host <-> container permanent volume
$ mkdir -p /app/jenkins $ chmod 777 /app/jenkinsRun Jenkins
$ docker run -d --name jenkins -p 8080:8080 -p 50000:50000 -v /app/jenkins:/var/jenkins_home \ -u root -e JAVA_OPTS='-Duser.timezone=Asia/Seoul -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8' leechungkyu/jenkinsContinue installation from web browser
?
http://<ip>:8080
connecting, and continue the installation.Input password
/var/jenkins_home/secrets/initialAdminPassword
$ docker exec -it jenkins /bin/bash $ cat /var/jenkins_home/secrets/initialAdminPassword 3830de413f4d49f7963223507527f02a # passwordPlugin installation
Install by default and wait for the ProgressBar to complete.
Create admin account
Enter your account name (login ID), password, name, and email address.
Jenkins URL Setting
Start Jenkins
Note
- ✅ Using the Jenkins official docker repository image, Locale and Timezone are not Korea setting. https://hub.docker.com/r/jenkins/jenkins
- So I used https://hub.docker.com/r/leechungkyu/jenkins image.
This is an image with Locale and Timezone related to Korea setting added to the existing official Dockerfile. Related Facebook Links$ cat Dockerfile... Skip # Set the locale ko_KR.UTF-8 RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y locales RUN sed -i -e 's/# ko_KR.UTF-8 UTF-8/ko_KR.UTF-8 UTF-8/' /etc/locale.gen && \ dpkg-reconfigure --frontend=noninteractive locales && \ update-locale LANG=ko_KR.UTF-8 ENV LANG ko_KR.UTF-8 RUN locale-gen ko_KR.UTF-8 ENV LANG ko_KR.UTF-8 ENV LANGUAGE ko_KR.UTF-8 ENV LC_ALL ko_KR.UTF-8 # Set TimeZone Seoul RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime ... Skip
- 投稿日:2020-01-18T18:08:47+09:00
WSL2でdockerが起動しないよう
なんかwindows updateしたらdockerが起動しなくなっちゃった
$ docker ps -a Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?どうして(電話猫)
https://github.com/docker/for-win/issues/5096
githubのissuesにこたえ発見。Settings > WSL Integratiion > {{distro}}
なんかのはずみでこれが外れちゃってることがあるみたい。こいつをオンにしたら無事起動しました。
Docker on WSL2さいこう。
- 投稿日:2020-01-18T17:50:57+09:00
データコンテナを作ってみるDockerミニハンズオン
「Dockerが何かは知っている・動かしてみたことはある」ぐらいの方以上を想定して
Dockerfile
でimageを自作docker-compose
で複数コンテナを立ち上げ- サイドカーパターン
をつまみ食いしながらまとめていきます。
サイドカーパターンの図をこちらのブログより転載させていただきました。
冒頭記載の対象読者層を超えてしまいますが、良い論文紹介記事です!データを他のコンテナが共用で使っている様子が、まるでサイドカーみたいですね(棒)
今回はこの共用データを持つ役割もコンテナに担当してもらいます(データコンテナ)。いきなり余談(?)
この記事を書くに至った経緯ですので飛ばしてもらっても構いません。
Composeファイルのフォーマットには2020年1月現在
1.0
、2.x
、3.x
と複数のバージョンがあります。
docker-compose.yaml
ファイルの最初にversion: '3'みたいに指定します。
インターンでデータコンテナを含む設計を触ることになったのでDockerの勉強から始め、docker-composeを3.x
系で何の疑いもなく作ろうとしました。しかし他のコンテナ名を指定して特定のボリュームを参照できる
volumes_from
が、3.x
では無くなっていました。
ここで悩んだ挙句に代替案が分からなかったので、一旦のまとめとしてこの記事を書いています。2つ以上のコンテナでデータを共用したい場合
- データ用のコンテナを1つ作り、特定のディレクトリを他のコンテナからも覗けるようにする
- ホスト側にデータを保存しみんなで参照する永続化ボリュームを確保する
のいずれかの構成にすることが多いかと思います。
業務ではKubernetesでサイドカーパターンのPodをスケーリングさせる予定だったので、2つめの永続化ボリュームを使う設計では新しいボリュームがどんどこ作られてつらい事態に陥りそうと考え1つめのデザインパターンを試しました。
なおKubernetesでは各Podに専用の空ディレクトリを作成すればよさそうなので、結局はDockerのおべんきょうができただけでした。
sample.yamlapiVersion: v1 kind: Pod metadata: name: test-pod-1 spec: containers: - image: centos:latest name: test1 volumeMounts: - mountPath: /test name: test-volume command: ["tail", "-f", "/dev/null"] - image: centos:latest name: test2 volumeMounts: - mountPath: /test name: test-volume command: ["tail", "-f", "/dev/null"] volumes: - name: sample-volume emptyDir: {}ハンズオン!
それでは
centos
コンテナDockerfile
でつくってみるオリジナルcentos-volume
コンテナdocker-compose
でまとめて立ち上げ- 確認・お片づけ
の順でさくさくと試していきましょう。
DockerfileでオリジナルのDocker imageを作る
ざっっっくり言うと、Dockerコンテナを作る型抜きの原型がDocker imageです。
Docker Hubに公開されているものだけでなく、元となるファイル(名前をDockerfile
にしておく)を自分で記述し新しいimageを作ることもできます。今回は共有したいデータを持つ方のデータコンテナを自作で定義してみます。
DockerfileFROM centos WORKDIR /mount-test RUN echo "volume mount test" > mount_test.txtなんとなくこういうルールなのかな、みたいなのは察していただけるかと思いますが
FROM
:CentOSのimageであるcentos
を元にして
WORKDIR
:作業ディレクトリを移って
RUN
:指定したコマンドを実行
のように順番に操作を書くのがDockerfile
です。
既存のimageをベースに敷き、各コマンドの層を積み重ねていく感じで作られていきます。
今回はデータコンテナとしての役割を確かめるため、/mount-test
ディレクトリとその中にmount_test.txt
ファイルを作成しています。この
FROM
やRUN
などの命令は全部で20種類くらいあります。詳しくは公式のドキュメントなどをまた適宜ご覧ください。こうして書いたDockerfileを
build
することで、Docker imageとして使えるようになります。$ docker build ./ -t centos-volumeここで
./
はDockerfile
が今のディレクトリ階層にあり、-t
はbuild
するimageに名前をつけることをそれぞれ指示しています。
以下のように表示されていれば成功です。Sending build context to Docker daemon 42.5kB Step 1/3 : FROM centos ---> <適当なハッシュ値1> Step 2/3 : WORKDIR /mount-test ---> Running in <適当なハッシュ値2> Removing intermediate container <適当なハッシュ値2> ---> <適当なハッシュ値3> Step 3/3 : RUN echo "volume mount test" > mount_test.txt ---> Running in <適当なハッシュ値4> Removing intermediate container <適当なハッシュ値4> ---> <適当なハッシュ値5> Successfully built <適当なハッシュ値5> Successfully tagged centos-volume:latestこれが最新バージョンだよ、と最後には
latest
タグまでつけてimage化してくれていますね。
タグとは例えば$ docker pull centos:centos7のように、Docker imageをバージョなどの情報つきで指定する時に併記するために使います。
数字などは中のミドルウェア・ソフトウェアのバージョンに対応してることが多いと思います。ここでタグを指定しない時には、
latest
タグがついたimageを表します。
latest
タグはそのimageを使いたい人みんなにとっていい感じの塩梅になるようなバージョンを選んでつけてくれている(?)とは思いますが、特定のバージョンを指定する必要がある場合も多いかと思います。また今回は行いませんが、
build
したオリジナルのimageは$ docker push
を行うことでDocker Hubに登録することでオープンに共有ができます。
逆に自分だけが使えるようにしておきたい、あるいは業務などで特定の人にだけ限定公開したい場合は
- Docker Hubにプライベートリポジトリを作成(2つ目以降は有料プラン)
- クラウドのマネージドサービス(AWSならECR、GCPならGCRなど)を利用
のどちらかを選びます。
そして上記の
build
プロセスを見てお気づきかもしれませんが、Dockerfile
から「コマンドを一行ずつ実行してはimage化」を繰り返して行われます。
そのため同じ命令がたくさんある場合には、中間生成されるimageが少なくて済むように\
や&&
で繋いでひとまとめの命令にしておきましょう。
以下の例のようにRUN
命令などが特に当てはまります。RUN apt-get update && apt-get install -y \ bzr \ cvs \ git \ mercurial \ subversion参考・参照
Dockerfileを書くベストプラクティスDocker Composeで複数コンテナをまとめて立ち上げる
Docker Composeは複数のコンテナをまとめて扱いたい時に使います。
ファイル名をdocker-compose.yaml
としてComposeファイルのバージョンと各コンテナの定義を書いていきます。docker-compose.yamlversion: '2' services: data-container: image: centos-volume container_name: data-container tty: true volumes: - /mount-test centos1: image: centos container_name: centos1 tty: true volumes_from: - data-container:roなんとなく
image
やcontainer_name
は分かりやすいかと思います。
version
はDockerではなくComposeファイルのバージョンです。
またtty: true
でポート待ち受けなど特に何もしないコンテナも立ち上げ後に起動させ続けることができます。
これが無いとコンテナがすぐに終了してしまいます。
そしてvolumes_from
ではマウント元となるボリュームを読み取り専用でマウントするため、後ろに:ro
(read only)とつけています。
マウント元のコンテナ名だけを書くか:rw
と付けると読み書きできる権限が付与されます。なおこのComposeファイルで指定できる項目はめちゃくちゃたくさんあるので、またドキュメントなどを適宜参照してください。
参考
Composeファイル バージョン2リファレンス
Composeファイル バージョン3リファレンスあとは
docker-compose.yaml
があるディレクトリで$ docker-compose up -dとすれば、
docker-compose.yaml
と名前がつけられたファイルを探して読み込んでコンテナを立ち上げてくれます。
-d
はバックグラウンド実行を指定しています。Creating data-container ... done Creating centos1 ... doneと表示されていればコンテナ作成は成功。
$ docker ps
で2つとも表示されていればちゃんと動いています。
続いて各コンテナが定義通り作られているかを確認してみましょう。
まずはデータコンテナの方に入り、Dockerfile
内で作ったはずのmount_test.txt
があるかを見てみます。$ docker exec -it data-container bash [root@<皆さんのコンテナID> mount-test]# cat mount_test.txt volume mount testファイルはちゃんと作成されており、作業(カレント)ディレクトリが
Dockerfile
の通り/mount-test
になっていますね。
またこのディレクトリではvimなどでmount_test.txt
を編集したり、新しいファイルを作ったりといった読み書き作業もできるかと思います。次に
exit
コマンドでデータコンテナから抜け、データを覗く側のコンテナに入ります。$ docker exec -it centos1 bash [root@<皆さんのコンテナID> /]# cat mount-test/mount_test.txt volume mount testデータコンテナ(
data-container
)のディレクトリとその中身がちゃんと見えていますね。
今回はdocker-compose.yaml
にてread onlyを指定しているので、マウントされたこの/mount-test
ディレクトリの中では既存ファイルの編集や新規ファイルの作成をしようとするとちゃんと怒られます。最後に立ち上げたコンテナたちを停止、削除しましょう。
片付けるまでがハンズオンです。$ docker-compose stop
で
docker-compose up
したコンテナ群をまとめて停止、$ docker-compose rmで削除できます。便利...。
さいごに
まだDocker始めて2週間ぐらいしか触ってないので、修正・追記すべき箇所などあるかと思います。
Compose3.x
系ではこうすればいいよなどのアドバイスも含めありましたらよろしくお願いします^^
- 投稿日:2020-01-18T16:31:33+09:00
RedmineプラグインをGitHub Actionsでテストする(Docker編)
以前に書いたRedmineプラグインをGitHub Actionsでテストするでの、以下の問題点を解消するために、Dockerイメージを使用した形に改良したまとめです。
- パッケージやRedmine自体のインストールも都度行われるため、時間がかかる。
- actions/setup-rubyで、Ruby v2.3.xはインストールできない。
改良後の結果
Redmine Auto Assign Group Pluginのテストを行うワークフローでの結果です。
テストにかかる時間
Redmine Auto Assign Group Pluginのテストに、GitHub ActionとしてRedmine plugin test actionを使用しています。改良前のv1と改良後のv2での比較は以下の通りで、大きく改善できました。
対象 実行時間(m:ss) v1-v2 v1(改良前) 6:28 ------ v2(改良後) 2:33 3:55 ※記事を書いている時点で最新の成功ビルド5件ずつの時間から、最大最小を除いた3件の平均で算出。
※Redmine-Rubyの組み合わせ10環境、テストは49 runs, 244 assertionsでMiniTestを使用。ただし、v1ではRuby v2.3.xは使用できないため、v2.3.xは除いた場合。Ruby v2.3.xでのテスト
dockerhubのruby:2.3-slimベースのイメージを作成することで、テストできるようになりました。
改良内容
Redmine plugin test actionのv1は、Github Actionsのubuntu-latestに対して環境を作っていくものでした。これだとテストまでの準備に時間がかかるため、あらかじめRedmineをインストールしたテストを実行するイメージをDockerHubに作成しておき、その上でプラグインのテストを実行する動きにしました。
流れをまとめると以下のとおりです。
プラグインのGitHubアクションワークフロー → DockerHubからイメージ取得 → プラグインのテスト実行プラグインのGitHubアクションワークフロー
Redmine Auto Assign Group Pluginでの変更は、このコミットのような感じです。
環境構築のための定義はバッサリなくなり、RedmineとRubyのバージョン、プラグイン名の指定のみとなりました。これに伴って、GitHubアクションとしてパラメータが変更になったため、v2に変更しています。DockerHubからイメージ取得
ベースのなる環境は、DockerHubのrubyのslimイメージを元にして、RedmineとChrome、ChromeDriverをインストールしたイメージを作っています。行っている事自体は、v1と同じです。DBはsqlite固定。Dockerfileのリポジトリはここ、DockerHubはここです。
RedmineとRubyのバージョン組み合わせの作成
以下の記事がとても参考になりました。
dockerhubのautomated buildで任意のdocker buildコマンドを利用し、単一のDockerfileから設定を動的に変えて複数イメージをビルドするDockerHubのビルド設定で行ったタグ名を元に、フックでRedmineとRubyのバージョンを取得して、ビルドを行っています。フックは以下のようなものです。
#!/bin/bash set -eux LIST=(${DOCKER_TAG/_/ }) RUBY_VERSION=${LIST[1]/ruby/} REDMINE_VERSION=${LIST[0]//trunk/master} LIST=(${REDMINE_VERSION//[.-]/ }) if [ ${#LIST[*]} -eq 2 ]; then LATEST_VER=LATEST_${REDMINE_VERSION/./_} if [ ${LATEST_VER} != "" ]; then eval REDMINE_VERSION=\$$LATEST_VER fi fi docker build --build-arg REDMINE_VERSION=${REDMINE_VERSION} --build-arg RUBY_VERSION=${RUBY_VERSION} -f $DOCKERFILE_PATH -t $IMAGE_NAME .DOCKER_TAG に、DockerHubのタグ名が入ってきます。 4.1_ruby2.6 などのような規則にしておき解析することで、バージョンを決定して以下のようにDockerfileへARGで渡しています。
ARG RUBY_VERSION FROM ruby:${RUBY_VERSION}-slim ARG REDMINE_VERSIONDockerHubのビルド設定は、 Builds - Configure Automated Builds の BUILD RULES に以下のような感じで追加しています。Sourceはすべてmasterにしていますが、 Docker Tag を変えて複数登録することで、組み合わせでイメージをビルドできます。
GitHubアクションからのイメージ使用
実際にテストを行うGitHubアクションである、Redmine plugin test actionは、Dockerコンテナのアクションとして作成するつもりでした。プラグイン側のアクションから受け取ったパラメータでDockerHubのイメージを指定できるかと思ったのですが、ARGの受け渡しができず、うまくいきませんでした。
このため、v1と同じくシェルスクリプトをキックして、DockerHubのイメージをベースにしたDockerfileをビルド、起動する形にしています。シェルスクリプトはこれです。GitHubのブランチ名の取得は環境変数から取得しますが、プルリクの場合とブランチへのコミットの場合で分けて取得する必要がありました。
if [ "${GITHUB_HEAD_REF}" = "" ]; then PLUGIN_BRANCH=$(echo ${GITHUB_REF#refs/heads/}) else PLUGIN_BRANCH=${GITHUB_HEAD_REF} fiあとはDockerfileにブランチ名やアクションのパラメータを渡してビルド、実行します。
docker build -t redmine-plugin-test \ --build-arg REDMINE_VERSION=${REDMINE_VERSION} \ --build-arg RUBY_VERSION=${RUBY_VERSION} . docker run -e "GITHUB_REPOSITORY=${GITHUB_REPOSITORY}" \ -e "PLUGIN_NAME=${PLUGIN_NAME}" \ -e "PLUGIN_BRANCH=${PLUGIN_BRANCH}" \ -t redmine-plugin-testプラグインのテスト実行
テスト自体はDockerfileのENTRYPOINTで実行するシェルスクリプトに書いています。
インストール→テスト→アンインストール のrakeを実行する内容になっています。まとめ
Redmine Auto Assign Group Pluginでの結果は、以下のような感じです。
Redmine plugin test actionのv1に比べて、だいぶ実行時間を短縮できました。プラグイン側のワークフローもシンプルになったので、使いやすくなったのではと思います。
- 投稿日:2020-01-18T16:08:09+09:00
windows10のdockerでのwordpress立ち上げでerror establishing a database connectionが表示される時
環境
- OS:Windows10 home(重要)
- Docker:Docker Toolbox(重要)
docker-composeを実施したときに、
毎回つまるエラーなのでメモ。Macでも何度か立ち上げているが、
そちらでは一度も詰まったことがないので
環境が違う場合は別の要因だと考えてほしい。
その場合はこの記事以外を参考にしてください。実施手順
docker-composeでwordpress環境をサクッと構築する - Qiita
↑こちらの記事を参考に、docker-compose.yml
を作成。docker-toolboxの画面に記載されている
docker is configured to use the default machine with IP 192.xxx.xx.xxx
を参考にして、
ブラウザで192.xxx.xx.xxx:9000
にアクセス。error establishing a database connectionの対処法
この場合よくある問題として、
mysql:latest
が指定されているのでmysql:5.7
を指定して回避することができるが、
今回は最初から5.7が指定されているので別の問題。今回の問題は、docker-compose.yml内の
wordpress、dbの二箇所の
restart: always
を
restart: unless-stopped
に変更して解決。この記事を参考にした。↓
docker-compose wordpress mysql connection refused - Stack Overflow
- 投稿日:2020-01-18T15:02:45+09:00
Dockerメモ
公式サイトでアカウント作成
作成完了したらDocker for Macをダウンロードしてインストール
### イメージ一覧 $ docker images ### コンテナ一覧 $ docker ps -a ### コンテナ停止、削除 $ docker stop {container_name} $ docker rm {container_name} ### イメージ削除 $ docker rmi {image_name}DockWikiを動かしてみる
$ docker pull bitnami/dokuwiki
- 投稿日:2020-01-18T14:40:54+09:00
WSL(Ubuntu) + Docker Desktop for Windows + docker-lambda + Python で AWS Lambda のローカル開発環境を構築
概要
AWS Lambda のローカル開発環境を Windows 上で構築しなければならなくなったため、
自分なりの構築手順を備忘録として記述していきます。
その通りやるだけで簡単に構築できる素晴らしい記事 を参考に進めていきたいと思います。
- WSL(Windows Subsystem for Linux)の環境を構築します。
- ローカルに Docker Desktop for Windows の環境を構築します。
- WSL からローカルの Docker Desktop for Windows を操作できるようにします。
- ローカル環境に AWS Lambda(Python) の開発環境を構築します。
環境情報
- Windows10 Pro(1909)
- WSL(Ubuntu 18.* LTS)
- bash
- Docker
- Python3.6
※ちなみに記事の内容は bash を想定して書いていますが
私の環境は fish ですので表示が間違っている可能性があります。
万が一、間違っている箇所がありましたら、
お手数ですがコメントで教えていただけると助かります。前提知識
- 基本的なLinux(Ubuntu, bash)の操作を理解している
- 仮想OS, WSL, Dockerに関する基本的な知識がある
- AWS Lambda の基本的な知識がある
WSLの構築
下記の素晴らしい記事を参考に「おまけ」「アンインストール」以外を実施
※下記の 初めにやっておく設定 の中で Hyper-V にチェックが無い場合は
一緒にチェックを入れて有効にしてください。Docker Desktop on Windows をインストール
下記の素晴らしい記事を参考に「おまけ」「アンインストール」以外を実施
docker desktop for windows + WSL で docker 環境ソースを準備
GitHub にこの記事で使用するソースのテンプレートを用意しました。
下記のリンクから MIT License で公開しています。
ご自由にお使いください。エイリアスを登録
新規のLambda関数はテンプレートのソースを基に作成していくため、
Dockerを実行する際のコマンドは常に一定になる想定です。
毎回入力するのは大変ですので、あらかじめ WSL にエイリアスを登録しておきます。.bash_aliases を vim で開く(無ければ新規作成)
~$ sudo vim ~/.bash_aliases && source ~/.bash_aliases.bash_aliases に下記コマンドを追加
.bash_aliasesalias docrun='docker run -v $(wslpath -m $PWD):/var/task --env-file .env lambci/lambda:python3.6 lambda_function.lambda_handler $(printf "%s" $(cat event.json))'簡単にですが
docrun
の内容を説明します。
docker run
Dockerイメージからコンテナを生成・実行
-v $(wslpath -m $PWD):/var/task
:
ホストOSのディレクトリ:コンテナのディレクトリ でボリュームを割り当てています。
※コンテナ上の/var/task
の中で、左に指定したホストOSのディレクトリの中が見えるということです。
ただし、WSL 上でローカル環境のディレクトリにいる時/mnt/d/Program/Python/AWS/docker-lambda $ echo $PWD /mnt/d/Program/Python/AWS/docker-lambdaとなっていますので、これをローカル環境のパスに変換するために
/mnt/d/Program/Python/AWS/docker-lambda $ echo $(wslpath -m $PWD) D:/Program/Python/AWS/docker-lambdaとしています。
--env-file .env
環境変数ファイルを読み込みます。
lambci/lambda:python3.6
Dockerイメージを指定しています。
lambda_function.lambda_handler
lambda_function.py の lambda_handler を実行するようにしています。
$(printf "%s" $(cat event.json))
event.json の内容を lambda_handler の引数 event に渡しています。Lambda関数を実行してみる
Windows
テンプレートのソースファイルを作業ディレクトリにコピーします。(ここでは
D:\Program\Python\AWS\docker-lambda
にします。)WSL
作業ディレクトリに移動
~$ cd /mnt/d/Program/Python/AWS/docker-lambda/Lambda関数を実行
/mnt/d/Program/Python/AWS/docker-lambda $ docrun START RequestId: c02ba91d-7783-1719-3b5e-269dfb11c807 Version: $LATEST event:{'Hello': 'World'} ENV:LOCAL END RequestId: c02ba91d-7783-1719-3b5e-269dfb11c807 REPORT RequestId: c02ba91d-7783-1719-3b5e-269dfb11c807 Init Duration: 439.63 ms Duration: 4.32 ms Billed Duration: 100 ms Memory Size: 1536 MB Max Memory Used: 39 MB "{\"message\": \"success\"}"初めて実行する時はDockerイメージのPullから始まります。
Pull完了後に関数が実行され、上記のような表示がされれば環境構築は完了です。参考
WSLのインストール・アンインストール方法
docker desktop for windows + WSL で docker 環境
docker-lambdaでAWS Lambda環境をお手軽に動かす
いまさらだけどDockerに入門したので分かりやすくまとめてみた最後に
なるべく初学者の方にもわかるように説明しているつもりですが、
分かりづらい点があったり、間違っている点がありましたら
コメントをいただけると助かります。
- 投稿日:2020-01-18T14:40:54+09:00
WSL + Docker Desktop for Windows + docker-lambda + Python でローカル開発環境を構築
概要
AWS Lambda のローカル開発環境を Windows 上で構築しなければならなくなったため、
自分なりの構築手順を備忘録として記述していきます。
その通りやるだけで簡単に構築できる素晴らしい記事 を参考に進めていきたいと思います。
- WSL(Windows Subsystem for Linux)の環境を構築します。
- ローカルに Docker Desktop for Windows の環境を構築します。
- WSL からローカルの Docker Desktop for Windows を操作できるようにします。
- ローカル環境に AWS Lambda(Python) の開発環境を構築します。
環境情報
- Windows10 Pro(1909)
- WSL(Ubuntu 18.* LTS)
- bash
- Docker
- Python3.6
※ちなみに記事の内容は bash を想定して書いていますが
私の環境は fish ですので表示が間違っている可能性があります。
万が一、間違っている箇所がありましたら、
お手数ですがコメントで教えていただけると助かります。前提知識
- 基本的なLinux(Ubuntu, bash)の操作を理解している
- 仮想OS, WSL, Dockerに関する基本的な知識がある
- AWS Lambda の基本的な知識がある
WSLの構築
下記の素晴らしい記事を参考に「おまけ」「アンインストール」以外を実施
※下記の 初めにやっておく設定 の中で Hyper-V にチェックが無い場合は
一緒にチェックを入れて有効にしてください。Docker Desktop on Windows をインストール
下記の素晴らしい記事を参考に「おまけ」「アンインストール」以外を実施
docker desktop for windows + WSL で docker 環境ソースを準備
GitHub にこの記事で使用するソースのテンプレートを用意しました。
下記のリンクから MIT License で公開しています。
ご自由にお使いください。エイリアスを登録
新規のLambda関数はテンプレートのソースを基に作成していくため、
Dockerを実行する際のコマンドは常に一定になる想定です。
毎回入力するのは大変ですので、あらかじめ WSL にエイリアスを登録しておきます。.bash_aliases を vim で開く(無ければ新規作成)
~$ sudo vim ~/.bash_aliases && source ~/.bash_aliases.bash_aliases に下記コマンドを追加
.bash_aliasesalias docrun='docker run -v $(wslpath -m $PWD):/var/task --env-file .env lambci/lambda:python3.6 lambda_function.lambda_handler $(printf "%s" $(cat event.json))'簡単にですが
docrun
の内容を説明します。
docker run
Dockerイメージからコンテナを生成・実行
-v $(wslpath -m $PWD):/var/task
:
ホストOSのディレクトリ:コンテナのディレクトリ でボリュームを割り当てています。
※コンテナ上の/var/task
の中で、左に指定したホストOSのディレクトリの中が見えるということです。
ただし、WSL 上でローカル環境のディレクトリにいる時/mnt/d/Program/Python/AWS/docker-lambda $ echo $PWD /mnt/d/Program/Python/AWS/docker-lambdaとなっていますので、これをローカル環境のパスに変換するために
/mnt/d/Program/Python/AWS/docker-lambda $ echo $(wslpath -m $PWD) D:/Program/Python/AWS/docker-lambdaとしています。
--env-file .env
環境変数ファイルを読み込みます。
lambci/lambda:python3.6
Dockerイメージを指定しています。
lambda_function.lambda_handler
lambda_function.py の lambda_handler を実行するようにしています。
$(printf "%s" $(cat event.json))
event.json の内容を lambda_handler の引数 event に渡しています。Lambda関数を実行してみる
Windows
テンプレートのソースファイルを作業ディレクトリにコピーします。(ここでは
D:\Program\Python\AWS\docker-lambda
にします。)WSL
作業ディレクトリに移動
~$ cd /mnt/d/Program/Python/AWS/docker-lambda/Lambda関数を実行
/mnt/d/Program/Python/AWS/docker-lambda $ docrun START RequestId: c02ba91d-7783-1719-3b5e-269dfb11c807 Version: $LATEST event:{'Hello': 'World'} ENV:LOCAL END RequestId: c02ba91d-7783-1719-3b5e-269dfb11c807 REPORT RequestId: c02ba91d-7783-1719-3b5e-269dfb11c807 Init Duration: 439.63 ms Duration: 4.32 ms Billed Duration: 100 ms Memory Size: 1536 MB Max Memory Used: 39 MB "{\"message\": \"success\"}"初めて実行する時はDockerイメージのPullから始まります。
Pull完了後に関数が実行され、上記のような表示がされれば環境構築は完了です。参考
WSLのインストール・アンインストール方法
docker desktop for windows + WSL で docker 環境
docker-lambdaでAWS Lambda環境をお手軽に動かす
いまさらだけどDockerに入門したので分かりやすくまとめてみた最後に
なるべく初学者の方にもわかるように説明しているつもりですが、
分かりづらい点があったり、間違っている点がありましたら
コメントをいただけると助かります。
- 投稿日:2020-01-18T13:14:38+09:00
docker-compose を CI で実行するとき, MySQL の起動完了まで確実に待つ
背景
- jwilder/dockerize: Utility to simplify running applications in docker containers
- ufoscout/docker-compose-wait: A simple script to wait for other docker images to be started while using docker-compose
この辺は全部試したが, PHP から接続しようとすると
Connection Refused
が多発する。TCP で接続可能になってから実際に利用可能になるまで若干のラグがあるため,もっと確実な方法を探していた。対処法
とりあえずこれを書いておけsh -c 'docker-compose logs -f <MySQLコンテナ名> | { sed "/mysqld: ready for connections/ q" && kill $$ ;}' || :YAMLのリストに書く場合はエスケープが必要なのでパイプから改行する- | sh -c 'docker-compose logs -f <MySQLコンテナ名> | { sed "/mysqld: ready for connections/ q" && kill $$ ;}' || :ログを見れば確実!ログに
ready for connections
と出ればアプリケーションレベルでも必ず有効な状態であることが保証される。
- 投稿日:2020-01-18T10:30:14+09:00
今日のdocker error : Error response from daemon: error while creating mount source path
macos/bash$ docker run -v /Users/administrator/Downloads/autosar:/tmp/docker -it kaizenjapan/autosar /bin/bash Unable to find image 'kaizenjapan/autosar:latest' locally latest: Pulling from kaizenjapan/autosar 5b7339215d1d: Already exists 14ca88e9f672: Already exists a31c3b1caad4: Already exists b054a26005b7: Already exists 637203abd9ed: Already exists c9d7543d434a: Already exists 86128d9220bb: Already exists 918db5bca014: Pull complete Digest: sha256:abf92757341bdaf40a3c83c56fb6779dc3fdf427742a174cf8b62c6b5fab5f30 Status: Downloaded newer image for kaizenjapan/autosar:latest docker: Error response from daemon: error while creating mount source path '/Users/administrator/Downloads/autosar': mkdir /Users/administrator: permission denied. ERRO[0146] error waiting for container: context canceled-vは、dockerを起動したOSとdockerで起動されたOSのフォルダのファイルを共有する仕組み。
dockerを起動したOSにないフォルダを指定するとエラーになる。
dockerで起動されたOSの側は存在しなくてもよいが、そのフォルダはdocker hubに登録する際に、消える。残しておきたければ、どこか存在するフォルダか、docker内でmkdirしておくとよい。
- 投稿日:2020-01-18T08:22:56+09:00
k8s環境ハンズオン、dockerとk8sの関係性の理解を深める
k8s環境構築ハンズオン、dockerとk8sの理解を深める
もくじ
- Dockerの概念を理解する。
- Dockerの基本操作を覚える。
- k8sの概念を理解する。
- k8sの基本操作を覚える。
- k8sリソースの役割・用途を覚える。
①minikubeコマンドでk8sの理解を深める
minikubeとはk8sをローカルで実行できるコマンド
クラスタ実行/停止/状態確認
k8sクラスタを操作するコマンド
ちなみにk8sクラスタはdockerコンテナの外層を包んで制御するイメージ
操作 コマンド 実行 minikube start 停止 minikube stop 状態確認 minikube status バーチャルボックスを使用していない場合は実行に下記オプションが必要
minikube start --vm-driver=noneアドオン追加削除一覧確認
アドオンを操作するコマンド
操作 コマンド 追加 minikube addons enable ADDON_NAME 削除 minikube addons disable ADDON_NAME 一覧確認 minikube addons list minikubeの状態を確認する:
minikube statusrunningになっていればk8sクラスタが実行されてることが解る。
minikubeを停止させてみる:
minikube stopminikube statusで止まっているか確認しよう。
#minikubeの再起動を行う: minikube start --vm-driver=nonehost:runningになっていれば起動している。
minikubeのaddonsの有効無効を確認する:
minikube addons listこれから下記のlistが何を指しているか学習していく。
Dockerの概念を理解する
dockerコンテナ実行してdockerの理解を深める
hello-worldというdockerコンテナを実行:
docker run hello-world
ちなみにrunには(コンテナの起動・プロセスの確認・停止)の3つを連続で行う意味がある。
コンテナ実行後はゴミがたまるので不要なキャッシュを削除する:
docker container prune
[y]コンテナと仮想マシン
コンテナと仮想マシンの違いはカーネルを共有しているかどうか。
カーネルを共有していれば、スピードが速く、バグも少なくできる。イメージとコンテナ
DOCKERイメージ:
・実行環境を定義したもの
・docker hubなどのリポジトリに保管
(dockerイメージ=実行環境のテンプレート)DOCKERコンテナ:
・dockerイメージをじっこうして出来る実行環境
(dockerコンテナ=dockerイメージを実行した実際の実行環境)※プログラムだとイメージはクラス、コンテナはインスタンス
おさらい
Dockerの基本操作を覚える。
イメージ検索(DockerHub)
イメージ取得/一覧/削除
コンテナ実行/停止/一覧/削除
省略コマンド
イメージ作成
イメージ公開(DockerHub)
k8sの概念を理解する。
- Hello World !(Kubernetes)
- Kubernetesとは
- Kubernetesリソース
- Kubernetesネットワーク
- 学習環境のネットワーク
k8sマニフェストファイルの書き方とデプロイ方法
containersについての解説
Hello World !(Kubernetes)
Kubernetesとは
Kubernetesリソース
主なリソースは4分類10種類のリソース
- ワークロード:(pod)(replicaset)(deployment)(statefulset)
- サービス:(service)(ingress)
- 設定:(ConfigMap)(Secret)
- ストレージ:(persistentvolume)(persistentvolumeclaim)ワークロード(pod) = 最小単位、dockerコンテナの集合
ワークロード(replicaset) = podの集合、podをスケールできる。
ワークロード(deployment) = replicasetの集合、replicasetの世代管理が出来る。
ワークロード(statefulset) = podの集合、podをスケールする際の名前が一定。
サービス(service):外部公開、名前解決、L4ロードバランサ
サービス(ingress):外部公開、L7ロードバランサ
設定(ConfigMap):設定情報
設定(Secret):機微情報
ストレージ(persistentvolume)永続データの実態
ストレージ(persistentvolumeclaim)永続データの要求
Kubernetesネットワーク
podへの接続がわからなくなった時はここに立ち返ってください。
NODEとpod
・nodeは実サーバに一致。
・リソースは各ワーカーノードに分散配置される。2つの異なるネットワーク
・kubernetes には異なる二つのネットワークがある。
(外部ネットワーク)(クラスタネットワーク)・「クラスタネットワーク」へ外から直接アクセスは出来ない。
コンテナへのアクセス
・管理端末は外部ネットワークに接続している。①kubectlで直接コンテナにアクセス
②踏み台を経由してコンテナにアクセス学習環境のネットワーク
k8sの基本操作を理解する。
- リソースの作成/確認/削除
- コマンドでSecretリソース作成
- マニフェストファイル (kind, metadata, spec)
- マニフェストファイル (command, args, env)
- kindに応じたapiVersioniの確認
- リソース種別名の省略記法
- Podに入ってコマンド実行
- Podとホスト間でファイル転送
- Podのログ確認
リソースの作成/確認/削除
リソース作成手順
「定義作成」→「定義適用」の2ステップ①「マニフェストファイル作成」:YAMLファイルを作成
↓
②「kubernetes反映」:kubectlコマンド利用して反映マニフェストファイル(yamlファイルにリソースの定義を記載する。)
aaa:cmd
apiversion
リソース作成/変更コマンド↓
kubectl apply -f
マニフェストファイルを指定してリソース作成変更します。オプション
-f マニフェストファイルパスリソース確認コマンド↓
kubectl get [-f ][TYPE]
指定したリソースを確認しますオプション
-f マニフェストファイルパス
TYPE リソース種別 (pod,resplicaset)リソース削除コマンド↓
kubectl delete [-f ][TYPE/NAME][-o [wide|yaml]]
指定したリソースを削除しますオプション
-f マニフェストファイルパス
TYPE/NAME-o [wide | yaml] 出力形式を指定します。
-wide:追加情報の表示
-yaml:YAML形式で表示~~~~~~~
演習:Podの作成/確認/削除
1.hello-worldコンテナ含むpod作成
2.podが起動していること確認
3.podを削除
kubectl apply -f pod.yml
コマンドでSecretリソース作成
マニフェストファイル (kind, metadata, spec)
マニフェストファイル (command, args, env)
kindに応じたapiVersioniの確認
リソース種別名の省略記法
Podに入ってコマンド実行
Podとホスト間でファイル転送
Podのログ確認
Kubernetesネットワーク
podへの接続がわからなくなった時はここに立ち返ってください。
NODEとpod
・nodeは実サーバに一致。
・リソースは各ワーカーノードに分散配置される。2つの異なるネットワーク
・kubernetes には異なる二つのネットワークがある。
(外部ネットワーク)(クラスタネットワーク)・「クラスタネットワーク」へ外から直接アクセスは出来ない。
コンテナへのアクセス
・管理端末は外部ネットワークに接続している。①kubectlで直接コンテナにアクセス
②踏み台を経由してコンテナにアクセス30. リソースの作成/確認/削除
リソース作成手順
「定義作成」→「定義適用」の2ステップ
①「マニフェストファイル作成」:YAMLファイルを作成
↓
②「kubernetes反映」:kubectlコマンド利用して反映マニフェストファイル(yamlファイルにリソースの定義を記載する。)
aaa:cmd
apiversion
リソース作成/変更コマンド↓
kubectl apply -f
マニフェストファイルを指定してリソース作成変更します。オプション
-f マニフェストファイルパスリソース確認コマンド↓
kubectl get [-f ][TYPE]
指定したリソースを確認しますオプション
-f マニフェストファイルパス
TYPE リソース種別 (pod,resplicaset)リソース削除コマンド↓
kubectl delete [-f ][TYPE/NAME][-o [wide|yaml]]
指定したリソースを削除しますオプション
-f マニフェストファイルパス
TYPE/NAME-o [wide | yaml] 出力形式を指定します。
-wide:追加情報の表示
-yaml:YAML形式で表示~~~~~~~
演習:Podの作成/確認/削除
1.hello-worldコンテナ含むpod作成
2.podが起動していること確認
3.podを削除
kubectl apply -f pod.yml
k8sリソースの役割・用途を覚える
k8sリソースの役割用途一覧をざっくり理解する
Pod
ReplicaSet
Deployment
Service
ConfigMap
Secret
永続データ(PersistentVolume,PersistentVolumeClaim)
StatefulSet
Ingress
- 投稿日:2020-01-18T08:22:56+09:00
k8s環境ハンズオン docker学習編
k8s環境ハンズオン docker学習編
もくじ
- Dockerの概念を理解する。
- Dockerの基本操作を覚える。
Dockerの概念を理解する
dockerコンテナ実行してdockerの理解を深める
hello-worldというdockerコンテナを実行:
docker run hello-world
ちなみにrunには(コンテナの起動・プロセスの確認・停止)の3つを連続で行う意味がある。
コンテナ実行後はゴミがたまるので不要なキャッシュを削除する:
docker container prune
[y]コンテナと仮想マシン
コンテナと仮想マシンの違いはカーネルを共有しているかどうか。
カーネルを共有していれば、スピードが速く、バグも少なくできる。イメージとコンテナ
DOCKERイメージ:
・実行環境を定義したもの
・docker hubなどのリポジトリに保管
(dockerイメージ=実行環境のテンプレート)DOCKERコンテナ:
・dockerイメージをじっこうして出来る実行環境
(dockerコンテナ=dockerイメージを実行した実際の実行環境)※プログラムだとイメージはクラス、コンテナはインスタンス
おさらい
Dockerの基本操作を覚える。
イメージ検索(DockerHub)
イメージ検索
ドッカーイメージの検索方法について学習する。
ドッカーイメージはイメージレジストリにある。
ドッカーイメージ保存先は「amazon」「google」「azure」「dockerhub」などが提供している。今回はdockerhubを検索する。
https://hub.docker.com/dockerhubはドッカーがイメージレジストリを探すデフォルトに設定されている。
ドッカーイメージにはtag とimageidがある。
tagにはOSとそのver情報が記載されている。
nodeでtagを検索するとalpineというosが見つかる。
これはdocker向けの軽量なosです。「
イメージが軽量でないとダウンロードできないので軽量であることは必須条件。
検索イメージに書いてあるタグをクリックするとgithubに飛ぶ。
そこにはdockerfileがある。
dockerfileはそのイメージがどのように構成されているか定義しているファイル。「
イメージ取得/一覧/削除
- イメージ取得には下記のコマンドを使います。
docker image pull NAME[:TAG] 指定されたイメージを取得します。 #引数 #NAME Dockerイメージ名 #TAG タグ名。省略した場合はlatest。
- イメージ一覧の取得には下記のコマンドを使います。
docker image ls #取得済みdockerイメージ一覧を表示します。 #引数 なし
- イメージ削除には下記のコマンドを使います。
docker image rm IMAGE 指定されたイメージを削除します。 引数 IMAGE DockerイメージIDdocker image prune 使われていないイメージを一括削除します。 引数 なし演習としてdockerイメージ取得・一覧・削除の操作を行う。
- ①centosをdockerhubでイメージ取得
- ②取得したイメージ一覧でイメージID確認
- ③イメージ削除①centosをdockerhubでイメージ取得
- centosのイメージ検索してタグを取得。
- タグを元にcentosのイメージをダウンロードしてみる。docker image pull centos:7
- ②取得したイメージ一覧確認してイメージ削除
IMAGE Docker 5e35e350aded
コンテナ実行/停止/一覧/削除
- コンテナ実行には下記のコマンドを使います。
docker container run [OPTION] NAME[:TAG] [COMMAND] #指定されたイメージを実行します。 #引数 OPTION オプション NAME dockerイメージ名 TAG タグ名。省略した場合はlatest COMMAND 実行時にdockerコンテナに与えるコマンド
オプション 説明 -d バックググランド実行させる -it Shell実行する際に合わせて指定 -e KEY=VALUE環境変数を与える --name NAME実行時のコンテナ名 -p container:host コンテナポートのホストにマッピング
- コンテナ停止には下記のコマンドを使います。
docker container stop CONTAINER #指定したコンテナを停止します。 #引数 CONTAINER コンテナID
- コンテナ停止には下記のコマンドを使います。
docker container ls [OPTION] #コンテナを一覧表示します。 #引数 OPTION-a 指定せば全て
- コンテナ削除には下記のコマンドを使います。
docker container rm CONTAINER #指定されたコンテナを削除します。 #引数 CONTAINER Dockerコンテナ名
- コンテナ削除とイメージ削除するには下記のコマンドを使います。
docker system prune #使用されていないデータを削除します。 #引数 なし演習としてコンテナ実行一覧停止削除の操作を行う。
- ①nginxイメージ実行
- ②実行中コンテナ一覧の確認
- ③コンテナ指定して停止
- ④停止中コンテナ含めた一覧確認
- ⑤不要なコンテナ削除①nginxイメージ実行
- nginxイメージを探し、タグを取得。
- 取得した[]タグを使ってnginxイメージ実行
docker container run -d nginx:1.17.2-alpine↓
イメージが手元にないと自動でダウンロードして起動します。②実行中コンテナ一覧の確認
docker container ls -a でnginx起動しているか確認
↓
動いてるのを確認できる。③コンテナ指定して停止
nginxを停止するdocker container stop agitated_satoshi
オプションにはdocker container lsで確認したNAMESを指定する。
docker system prune
使用されていないデータを削除します。
イメージ作成
dockerイメージ作成方法について学ぶ
-イメージ作成の基本
-dockerfile
-ビルドイメージ作成の基本はプログラムと同じ
「
dockerfile
Doker特有のコマンドを利用してイメージ構築手順を定義。dockerfileサンプル
FROM centos:7 COPY docker-entrypoint.sh /var/tmp RUN mv /var/tmp/docker-entrypoint.sh /usr/local/bin/; \ chmod +x /usr/local/bin/docker-entrypoint.sh; ENTRYPOINT ["docker-entrypoint.sh"] CMD ["echo", "Hello World"]FROM <IMAGE>[<:TAG>] ←元となるイメージ名を指定 COPY <SRC>...<DEST> ←ホストからファイルにイメージ転送 RUN <COMMAND> ←イメージ内でコマンド実行 ENTRYPOINT [<COMMAND>,....] ←デフォルト実行、初期化処理などのコマンド CMD [<COMMAND>,....] ←メインとなるコマンド
オプション 説明 -t イメージ名を指定する -f Dockerfileの名前を指定する -ビルド
docker build [OPTION] PATH #指定されたDockerfileを利用してdockerイメージを作成します。 引数 OPTION オプション PATH Dockerfileが保存されているパス。演習としてDockerイメージの作成、実行を行う
- ①Dockerfileの作成(ベースはCentos7)
- ②環境変数を表示するシェルを作成、コピー
- ③echoコマンドを実行させる
- ④ビルド
- ⑤実行・動作確認①Dockerfileの作成(ベースはCentos7)
構築したVMの/root/study直下にDockerfile作成。vi dockerfile
FROM centos:7 COPY docker-entrypoint.sh /var/tmp RUN mv /var/tmp/docker-entrypoint.sh /usr/local/bin/; \ chmod +x /usr/local/bin/docker-entrypoint.sh; ENTRYPOINT ["docker-entrypoint.sh"] CMD ["echo", "Hello World"]上記シェルの処理:
RUNにまとめることで複数のコマンドを実行できる。
chmod +x:実行権限を付与
ENTRYPOINTで ["docker-entrypoint.sh"]を起動②環境変数を表示するシェルを作成、コピー
構築したVMの/root/study直下にシェルを作成。vi docker-entrypoint.sh
docker-entrypoint.sh#! /bin/sh env exec "$@"上記シェル解説:
env←環境変数表示するコマンド
exec "$@"←cmdで引数に渡されたものを無条件に実行する、④ビルドする。
docker build -t test .docker image ls を使用するとtestというイメージが作成出来ている。
testコンテナを実行してみる。docker run testシェルに指定された環境変数・ハローワルドが表示される。
続いて、コンテナイメージを削除する。docker container pruneイメージ公開(DockerHub)
作成したDockerイメージを(DockerHub)に公開する。
- ①Dockerfileの作成(ベースはCentos7)
- ②環境変数を表示するシェルを作成、コピー
- ③echoコマンドを実行させる
- ④ビルド
- ⑤実行・動作確認DockerHubへ公開する手順
- Dockerイメージへ付与するタグ名
- Dockerイメージのタグ追加
- DockerHubへログイン
- DockerHubへ公開
Dockerイメージへ付与するタグ名のルールは以下の通り
基本構成:ユーザ名/イメージ名:タグ
全角と記号は文字列として使用できない
ユーザ名はdockerアカウント公開するためには必須
- Dockerイメージのタグ追加
docker tag SRC_NAME[:TAG] TRG_NAME[:TAG] 引数 SRC_NAME タグ付けしたいdockerイメージ名 TRG_NAME 追加したいタグ名
- DockerHubへログイン
docker login [-u USER] [-p PASSWORD] 引数 -u USER ユーザ名 -p PASSWORD パスワード
- DockerHubへ公開
docker push IMAGE_NAME[:TAG] 引数 IMAGE_NAME 公開したいdockerイメージ名続いて演習で作成したイメージのビルド・公開・確認を行う。
前提条件:
先ほど作ったdockerfileとdocker-entrypoint.shがあるdockerfileをユーザーネーム付きでビルドする。
docker build -t <username>/test:v.1.0.0 .ビルドが完了したので、出来ているか、確認する。
docker image ls出来ているので、試しにビルドしたイメージを実行させる。
docker run <username>/test:v.1.0.0公開するためログインする
docker loginユーザ名、パスワードを入力する。
ログインが出来たらdocker pushで公開する。
docker push <username>/test:v.1.0.0成功したので、実際にサインインして公開されているかどうか見てみる。
testイメージがアップロードされているのが解る。
- 投稿日:2020-01-18T06:09:48+09:00
Dockerについて part1
Dockerのimageとは
Dockerのimageとはある実行環境のスナップショットみたいなもので、これを共有することで環境構築を簡単にすることができる。
dockerのimageはdockerhubというサイトから様々なものをインストールすることができる。
Dockerfileとは
自分でimageを作成するときに使うファイル。vimとかでも書くことができる。
Dockerfile.ci1 FROM ubuntu 2 COPY hello.txt /tmp/hello.txt 3 CMD ["cat", "/tmp/hello.txt"] 4こんな感じのファイル。
catコマンドとは
一番よく使われるのはファイルの閲覧。
$ cat fileA
このようにして使う。buildとは
docker buildコマンドではDockerfileからdockerimageを作成する。
次のコマンドをみてみよう
$ docker build -t hello .-t hello オプションは「Docker Imageを hello という名前にする」という意味です。
. はdocker build 実行時のコンテキストの指定です。 . は COPY コマンドを実行する際にどのディレクトリを起点とするかを指定します。(入門dockerより)docker images
インストールしたり作成したimageはdocker imagesというコマンドで確認することができる。
$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello latest 98d66d64d276 13 seconds ago 64.2MB ubuntu latest ccc6e87d482b 28 hours ago 64.2MB nginx latest c7460dfcab50 7 days ago 126MB ruby latest fb53c5f433da 10 days ago 842MB python 2.7 426ba9523d99 2 weeks ago 896MBdocker buildで作成したdocker imageを実行してみよう
$ docker run hello hello docker !実行中のコンテナを確認しよう
docker container ls -aで確認することができる。
$ docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 429c028bcf74 ubuntu "echo hoge" 16 seconds ago Exited (0) 15 seconds ago stoic_greider実行中のコンテナを削除しよう
docker image prune -aで削除することができる。
$ docker image prune -a WARNING! This will remove all images without at least one container associated to them. Are you sure you want to continue? [y/N] y Deleted Images:Dockerhubから作成したimageの取得をしよう
$docker pull yokotadaiki/hello
これでdocker run yokotadaiki/helloを実行できるようになった。
Dockerfileの基本的なコマンド
基本的なコマンド¶
個人的に、Dockerfileを本番のワークロードで使用する場合以下の7つのコマンドを覚えるだけで十分だと考えています。FROM , COPY , RUN , CMD , WORKDIR , ENV , USER
(入門dockerより)FROM
ベースとなるDocker Image を指定します。
DockerはベースとなるDocker Image の上に COPY や RUN のようなコマンドを重ねてDocker Image を作成します。
ベースとなるDocker Image は公式で提供されているImageを使用するのが一般的です。また、ここで設定したイメージを「ベースイメージ」と呼びます。
ENV
Docker内で使用する環境変数を定義します。
NODE_ENV のようなDockerの起動時にデフォルトで定義されていてほしい環境変数を定義すると良いでしょう。ENV NODE_ENV=productionWORKDIR
Dockerfileでコマンドを実行する際に基準となるディレクトリを設定します。
このとき存在しないディレクトリを指定すると自動的にディレクトリが作成されます。
デフォルトだと / が設定されているため、最悪の場合既存のディレクトリを上書きしてしまいコンテナが起動しなくなります。WORKDIR /scriptsCOPY
Docker内へホストのファイル/ディレクトリをコピーします。
COPY は基本的に2つの引数を設定します。1つ目はホスト側のディレクトリ、2つ目はDocker側のディレクトリです。
ホスト側のディレクトリは docker build . で指定したディレクトリです。この場合 . を指定しており、カレントディレクトリが参照されます。
Docker側は WORKDIR で定義されたディレクトリを参照します。RUN
Docker内でコマンドを実行します。
ここでコンテナへ依存するライブラリやパッケージのインストールやユーザーの設定などの処理を実行します。RUN npm install \ && groupadd app \ && useradd -g app app \ && chown -R app:app /scriptsUSER
作成したDocker Image を起動時にログインするユーザーを指定します。
デフォルトは root が設定されているため、セキュリティリスクを回避するために別のユーザーを指定するのが良いでしょう。USER appCMD
Docker起動時にデフォルトで実行されるコマンドを定義します。
Dockerはここで設定したコマンドがフォアグラウンドで実行されている間が生存期間になります。
そのため、プロセスの処理が走っている間はフォアグラウンドで実行するように記述します(バックグラウンドで起動するとDockerが終了してしまう)。CMD ["npm", "run", "start"]EXPOSE
コンテナ起動時に公開することを想定されているポートを記述します。
EXPOSE を記載することで他の人から「このDockerはポートをどの使用するのか」がわかりやすくなるため、記述すると丁寧でしょう。VOLUME
Data Volumeを作成するためのコマンドです。Volumeについては後の章で説明します。
永続的なデータや共有するためのデータ、更新頻度の激しいファイルを扱うために使用されます。
基本的に永続的なデータはDockerで管理することは推奨されないため、基本的にログのような更新頻度の激しいファイルで使用すると良いでしょう。VOLUME ["/app/log"]Docker Containerとは
Docker Image がスナップショットだとしたらDocker Container はその 「スナップショットから起動したプロセス」 です。
より具体的にいうと docker run を実行するとDocker Image をもとにしてDocker Containerが作成され、隔離された環境が作成されます。
Docker Container は Docker Imageを元にして作成され、リソースの許す限り立ち上げることができます。意識する点として、Docker Container は1つのコマンドをフォアグラウンドで動かすように設計されていることです。
Docker Containerは1つのコマンドを隔離された環境で実行し、そのコマンドの実行がフォアグラウンドで終了するまで生存します。Dockerのライフサイクル
Dockerコンテナは大きく5つの状態に分けられる。
image
指定したdocker imageからコンテナを起動する。
RUNNING
Docker Containerが起動した状態です。
Dockerfileの CMD もしくは ENTRYPOINT で指定したコマンドがフォアグラウンドで動いている間がRUNNINGの状態です。
例えば docker run -P nginx のようにnginxを起動した場合、nginxが起動してアクセスを待ち受けてる間はRUNNINGの状態となりますSTOPPED
起動したContainerが終了した状態です。
正常終了・異常終了、どのような形であっても終了したContainerはSTOPPEDへ遷移します。PAUSED
Containerが停止した状態です。
ユーザーが docker pause を実行すると、現在の状態を保持して一時停止します。
docker unpause で一時停止したコンテナIDを指定することで再開することが可能です。
ユーザーが明示的に指定しない限りこの状態へは遷移しません。DELETED
Docker Container は明示的に削除を行わない限り停止した状態で残り続けます。
docker rm で明示的に削除するとDELETEDの状態へ遷移し、削除されます。ここまでの重要なポイント
・コンテナは隔離された環境で実行される
・Dockerコンテナは1つのコマンドを実行してプロセスを実行する
・基本的に「1コンテナ1プロセス」
・ライフサイクルは実行されたコマンドがフォアグラウンド上で実行されている期間
・バックグラウンドでプロセスが立ち上げられていてもフォアグラウンドでコマンドが終了したらコンテナは停止するNetworkを利用する
dockerコンテナは、1コンテナ1プロセスが基本だった。
そのため、railsとmysqlなど複数のコンテナを協調して動作させるにはnetworkを利用する必要がある。$ docker network ls
このコマンドで現在dockerが管理しているnetwork一覧を出力することができる。$ docker network ls NETWORK ID NAME DRIVER SCOPE 3d295ce0594e bridge bridge local 0539a1b864dd host host local 30c3217049fb none null local次は新しいBRIDGEネットワークを作成しよう。
$ docker network create myapp 6dbd1262d023114e349e2f12e843044327cc2d870bd41cc4d74103ad68d24725作成したnetworkにnginxを参加させる
通信を受けるためのサーバーとしてnginxを構築します。
$ docker run --name nginx --network=myapp -d nginxAmazonLinux2を起動し、Nginxコンテナへ接続する
Bridgeネットワークの場合、同一ネットワークのコンテナにはコンテナ名で名前解決が可能です。
Nginxと疎通できるか myapp ネットワーク内にAmazonLinux2 イメージでコンテナを起動し、 curl を実行してみましょう。
$ docker run --network=myapp -it amazonlinux:2 curl nginx:80ここまでの重要ポイント
・1プロセス1コンテナ、復数プロセスはネットワークを通して通信を行う。
・Bridgeを基本的に使用する。Volumeとは
ボリュームはデータを永続化するための機能です。
Docker Containerは基本的にエフェメラルなもので、コンテナ上で作成されたファイルはコンテナのライフサイクルの終了と共に消えてしまいます。
Volumeはデータ保持・永続化のために設計されており、コンテナのライフサイクルとは独立してファイルの管理を行います。ここは難しい。。。
デバッグ(dockerの動作確認方法)
そもそも、dockerは実行されるたびに新しいコンテナが立ち上がる。そのため、dockerimageが1つでも複数のコンテナが立ち上がっているという状況がある。
コンテナの状態を確認するコマンドとして
$ docker container ls -aとしてきた。
ちなみに実行中のコンテナだけ確認したいときは
$ docker container lsとすれば良い。
コンテナの停止~imageの削除
###コンテナの停止 $ docker stop $(docker container ls -q) ###コンテナの削除 $ docker rm $(docker container ls -aq) ###imageの削除 $ docker rmi $(docker images -q)Dockerfileのベストプラクティス
例えばPHPの環境を構築するのにCentOSのベースイメージで、phpenvを入れて、MySQLを入れて、、といったことは非推奨です。
DockerはいままでのVMとは思想が異なります。1コンテナ1プロセスになるように設計を行いましょう。
復数のプロセスを使用したい場合はそれぞれコンテナに分け、オーケストレーションツールを使用してコンテナを協調させて動かしましょう。.dockerignoreを使う
Dockerのビルド時に無視するファイル/ディレクトリを指定することができます。
".git" のようなコンテナ内に不要な情報、 "node_modules" のような上書きされると困るものを記述します。
.dockerignore は基本的に .gitignore と同じ書き方が可能です。ここも難しい。
オーケストレーションツール
複数のDockerを動かすためのツール。
docker-composeもその中の1つだと思う。docker-composeについて
docker-composeはローカルでDockerのオーケストレーションを行うためのツールです。
DockerのビルドからNetworkやVolumeの管理をコードベースで定義して行ってくれます。docker-composeはDockerの構成をyamlを定義し、そのyamlを元に起動します。
例えばnginxを起動し、ホストの8080ポートへコンテナの80ポートをフォワードする設定は以下のyamlになります。例えば以下のようなファイル
version: '3.7' services: nginx: image: nginx ports: - 8080:80docker run -p 8080:80 nginx とほぼ同じ動きをします(異なる点としては、docker-composeでは専用のNetworkを作成・使用する点です)。
単純なnginxの起動であれば素のdockerコマンドで問題ありませんが、ここにPHP, MySQL...と増えていくとその威力を発揮します。つまり、数が増えるほどymlファイルにまとめて記載してdocker-composeでまとめてコンテナを立ち上げた方が簡単じゃない?って話だと思う。
Lalavelのサンプルで雰囲気を掴む
dockerでLalavelをのサーバーを起動する。
$ git clone https://github.com/y-ohgi/introduction-docker.git $ cd introduction-docker/handson/laravel $ docker-compose upこの状態はrailsでいうrails sを実行したのと同じ。
docker-compose.ymlを読む。
docker-compose.ymlversion: '3.7' services: nginx: build: context: . dockerfile: docker/nginx/Dockerfile volumes: - ./public:/var/www/html/public:ro ports: - 8080:80 environment: PHP_HOST: app app: build: context: . dockerfile: Dockerfile env_file: - .env.example # volumes: # - .:/var/www/html:cached mysql: image: mysql:5.7 volumes: - ./mysql:/var/lib/mysql:delegated command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci environment: MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' ports: - 13306:3306version
docker-composeのバージョンを指定する。
特にこだわりがなければ最新のものを。services
起動するコンテナの定義を行います。
このdocker-compose.yamlでは nginx , app , mysql の3つが定義されています。build
docker buildの実行情報を記述します。
ここで定義された情報を元にDockerをビルドし、そのビルドしたイメージ使用してコンテナを起動します。
image もしくは build どちらかを記述する必要があります。
コマンドの場合、 docker build -f docker/nginx/Dockerfile . と同一です。volumes
ボリュームのマウントを行います。 コマンドの場合、 -v $(pwd)/public:/var/www/html/public:ro オプションと同一です。
ports
ポートの開放を行います。
左にホストのポートを、右にコンテナのポートを指定します。
コマンドの場合、 -p 8080:80 オプションと同一です。command
Dockerfileで定義されている CMD の上書きを行います。
Docker-composeのコマンド集
1.カレントディレクトリに存在する docker-compose.yaml を参照してdocker-composeの起動 $ docker-compose up 2.カレントディレクトリの docker-compose.yaml に紐付いているContainerとNetworkを削除 $ docker-compose down 3.Imageも削除 $ docker-compose down --rmi all 4.volumeを削除 $ docker-compose rmプロダクションへの導入
新規開発なら最初からDockerで開発していきましょう。
既存のVMからの移行であればステップを踏んで行くのが良いでしょう。
1.ローカル環境のDocker化
まずはローカル環境での導入から行います
チームの開発環境をDockerで統一し、Dockerに慣れていくところから始めていきましょう2.テスト/CIへの導入
次にテスト/CI環境への導入を行います
また、CIを導入してないのであればDockerとの相性が良いのでこの機会に導入するのもありでしょう。3.ステージングへの導入
本番へいきなり導入する前にステージング環境でDockerの動作を確認しましょう4.本番への導入
最後に本番環境への導入を行いましょうtools
全てのcontainerを停止、削除します。関連するvolumeとnetworksも削除します。
$ docker-clean stopDockerのリソース全てを削除する。起動中のcontainerも削除される点に注意。
$ docker-clean all開発スタート
あとは、コンテナが起動している時は、以下のようにexec webに続いてrailsのコマンドを実行していけば、scaffoldやmigrationの実行が可能です。
$ docker-compose exec web bin/rails g scaffold User first_name:string last_name:string
マイグレーションの場合は、以下のような感じです。
$ docker-compose exec web bin/rails db:migrateコンテナを終了させたい場合は、以下のコマンドになります。
$ docker-compose downGemを追加したときは、イメージを再構築する必要があるので、以下のコマンドを実行してください。
$ docker-compose build web
- 投稿日:2020-01-18T00:37:52+09:00
ruby 2.7.0 + Rails 5.2.4 + mysql 5.7.28 でDocker開発環境を構築する備忘録
流れ
- Dockerfileを作成
- docker-compose.ymlを作成
- Gemfile,Gemfile.lockを作成
- イメージ・コンテナの作成
- Rails初期設定
- Githubにリモートリポジトリ作成
ディレクトリ構成
application_root/ - Dockerfile - docker-compose.yml - Gemfile - Gemfile.lock - その他Railsアプリケーションファイル群Dockerfileを作成
application_root下に下記のファイルを作成
# イメージのベースラインにRuby2.7.0を指定 FROM ruby:2.7.0 # Railsに必要なパッケージをインストール RUN apt-get update -qq && apt-get install -y build-essential nodejs RUN gem install bundler # ルートディレクトリを作成 RUN mkdir /app # 作業ディレクトリを指定 WORKDIR /app # ローカルのGemfileとGemfile.lockをコピー COPY ./Gemfile /app/Gemfile COPY ./Gemfile.lock /app/Gemfile.lock # Gemのインストール実行 RUN bundle install # カレントディレクトリの内容をコピー COPY . .docker-compose.ymlを作成
同様に下記のファイルを作成。
DBはmysqlで、ローカルにデータストアを設けて永続化している。# docker-compose.ymlフォーマットのバージョン指定 version: '3' services: # Railsコンテナ定義 web: # Dockerfileを使用してイメージをビルド build: . # ポート3000が来たらrailsサーバーが応答 command: bundle exec rails s -p 3000 -b '0.0.0.0' # ローカルのsrcをコンテナにマウント volumes: - .:/app ports: - 3000:3000 # dbコンテナが先に起動するよう設定 depends_on: - mysql tty: true stdin_open: true # MySQLコンテナ定義 mysql: # mysqlを使用してコンテナ作成 image: mysql:5.7.28 volumes: # データストアからマウント - ./tmp/mysql:/var/lib/mysql # コンテナ内の環境変数を定義 environment: # mysqlのルートユーザーのパスワード設定 MYSQL_ROOT_PASSWORD: password ports: - "3306:3306" restart: alwaysGemfile,Gemfile.lockの作成
以下のコマンドでGemfileを作成。
bundle init下記のように編集。
# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "rails", "~> 5.2.4"Gemfile.lockは空で作成しておく。
touch Gemfile.lockイメージ・コンテナの作成
Railsプロジェクトを作成する。
docker-compose run web rails new . --force --database=mysqlDockerイメージを作成する。(で合っているよね?)
docker-compose build作成されたイメージを確認できる。
コンテナはまだない。# イメージのリスト docker image list # 動作しているコンテナ一覧 docker psここまでがうまくいかなかった時は削除してやり直す。
docker rm -f [container_id] docker rmi -f [image_id]いよいよコンテナを立ち上げる。
-dをつけるとデーモン実行できるが、ログを見たいのでそのまま実行。docker-compose upRails初期設定
config/database.ymlのpassword, hostを編集する。
default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password # docker-compose.ymlに記載したパスワード host: mysql # docker-compose.ymlに記載したホスト名コンテナ内に入って、DBを作成する。
docker exec -it [container_name] bash rake db:create下記URLで動作が確認できる。
http://localhost:3000Github設定(ついでに)
Githubアカウントは作ってある前提で・・・
まずはSSHキーを作成。もうある場合は不要。
内容をGithubの設定から、SSH keysにアップロードする。ssh-keygen -t rsa cat .ssh/id_rsa.pubあとはリモートリポジトリのSSHアドレスを設定してPush。
# ユーザー名の設定 git config --global user.name [ユーザー名] # リモートリポジトリの設定 git remote add origin git@github.com:xxxxxxxx/xxxxxxxxx.git # アプリケーションの初期状態をPush git add -A git commit -m "create application" git push origin master
- 投稿日:2020-01-18T00:06:13+09:00
ハンズオンでVM(CENTOS7)→docker→k8sの順で環境を構築していく
ハンズオンでVM(CENTOS7)→docker→k8sの順で環境を構築していく
dockerやk8sの技術を体系的に得たいが時間がない!
ならまずは箱庭作りから始めよう!バーチャルボックスでlinux環境構築
ハイパーバイザーのバーチャルボックスとCENTOS7をダウンロードする。
CENTOS7
https://www.centos.org/download/・バーチャルボックスを起動する。
①新規仮想マシンの作成をクリック
②バーチャルボックスのディスクにCENTOS7をセッティングする!
③仮想ディスクの設定
- 仮想HDDは20Gに設定
- 仮想ディスクを複数ファイルに分割を選択④ハードウェアカスタマイズ選択
- メモリを4Gに設定
- プロセッサを2コアに設定⑤バーチャルボックスをCENTOS7をインストールする!
- 言語は「j」を入力し日本語を選択
ネットワークとホスト名→オンに設定(インターネットに接続できる状態にする)
上記の設定が完了したらインストール開始!
インストール中にrootパスワード設定とユーザ作成する。
インストールが完了したら再起動を行う。
※VM画面からカーソルを外す操作方法。
VmwarePlayerであればCtrl+ALTキーでVM画面からカーソルを外せる。
Vercalboxであると右のCtrlキーでVM画面からカーソルを外せる。
初回起動操作↓
- ライセンス同意にチェック→設定の完了
CENTOS7環境のGUIセッティング
CENTOSのGUI画面からアプリケーション→端末を起動
・下記のコマンドで使用IPを調べる
ip -f inet a
ネットワークアダプターのIPアドレスを確認できる。
- WinscpでVM側のrootディレクトリに下記の環境構築用シェルを転送
minikube-installer.sh#! /bin/sh # Install "Docker" yum install -y yum-utils \ device-mapper-persistent-data \ lvm2 yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo yum install -y \ docker-ce-19.03.1 \ docker-ce-cli-19.03.1 \ containerd.io systemctl enable docker systemctl start docker # Install "kubectl" curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.15.1/bin/linux/amd64/kubectl chmod +x ./kubectl mv ./kubectl /usr/local/bin # Install "minikube" curl -Lo minikube https://storage.googleapis.com/minikube/releases/v1.2.0/minikube-linux-amd64 chmod +x minikube install minikube /usr/local/bin rm -f minikube # stop firewall systemctl disable firewalld systemctl stop firewalld # Add addons minikube start --vm-driver=none minikube addons enable heapster minikube addons enable ingress
VMでないほうからテラタームを実行→先ほどのIPと作成したユーザ名を使用しログイン
teratermで下記のコマンドで環境構築用シェルをインストール
sh minikube-installer.shこれでインストールは完了したので下記の確認コマンドを打ってみよう!
コマンド 定義 docker version dockerのバージョンを確認する。 kubectl version k8sのバージョンを確認する。 ここまで確認すればdockerとk8sの環境は完成です。
試しにインストールされたかminikubeコマンドを試してみましょう。minikubeコマンドを打ってk8sの理解を深める
- minikubeとはk8sをローカルで実行できるコマンド
クラスタ実行/停止/状態確認
k8sクラスタを操作するコマンド
ちなみにk8sクラスタはdockerコンテナの外層を包んで制御するイメージ
操作 コマンド 実行 minikube start 停止 minikube stop 状態確認 minikube status バーチャルボックスを使用していない場合は実行に下記オプションが必要
minikube start --vm-driver=noneアドオン追加削除一覧確認
アドオンを操作するコマンド
操作 コマンド 追加 minikube addons enable ADDON_NAME 削除 minikube addons disable ADDON_NAME 一覧確認 minikube addons list minikubeの状態を確認する: minikube statusrunningになっていればk8sクラスタが実行されてることが解る。
動いていることを確認したらminikubeを停止させてみよう。minikubeを停止させる: minikube stopminikube statusで止まっているか確認しよう。
#minikubeの再起動を行う: minikube start --vm-driver=nonehost:runningになっていれば起動している。
# minikubeのaddonsの有効無効を確認する: minikube addons list【補足ハイパーバイザーにてvmware workstation 15 を使う場合】
ip -f inet a ipでアドレスを調べる。
右のctrlでカーソル脱出させる。
※ + を使って[anaconda root@localhost]# のようなコンソール画面に切り替える。
+ + のキー シーケンスを使用して、ゲスト OS をシャットダウンまたはログオフできます。
またvi テキスト編集:で下記のようなエラーが発生する。
↓
E20: Mark not set言語設定が原因
「E20: Mark not set」と表示されいくつかのViコマンドが使えない。によるとキーボードの言語設定が原因。キーボードの設定を日本語にするとなおった
(方法は各自で調べて)編集状態ならShift + ;で:が入力できる
https://ameblo.jp/ca-engineer/entry-10102519347.html■キーボードの設定は/etc/sysconfig/keyboardで変更する。
https://ameblo.jp/ca-engineer/entry-10102546292.htmlKEYBORDTYPE="pc" KEYTABLE="jp106"vimは で保存
Ctrl + Alt を押してマウスとキーボードを解放しようとすると、ノート型コンピュータがサスペンドする。
デフォルトでは、Ctrl + Alt キーの組み合わせで Workstation Pro からマウスとキーボードが解放されます。