- 投稿日:2020-05-31T23:41:47+09:00
Docker で debian 9 をベースに Hadoop(version3.1.3) コンテナ作成
目的
- ローカルで手軽に Hadoop のテストができる環境を構築したい
- centos 7 をベースに作成した際に課題があったので、debian 9 ベースで作成してみたい
ディレクトリ構造
├── base │ ├── config │ │ ├── core-site.xml │ │ ├── hadoop-env.sh │ │ ├── hdfs-site.xml │ │ ├── mapred-site.xml │ │ ├── workers │ │ └── yarn-site.xml │ ├── Dockerfile │ └── script │ └── start.sh ├── docker-compose.yml設定ファイルの準備
core-site.xml
とりあえず、fs.default.name だけ定義していればサービスの起動は可能なはずです。
<configuration> <property> <name>fs.default.name</name> <value>hdfs://localhost:9000</value> </property> </configuration>hdfs-site.xml
データの保存先として、/hadoop-data を指定しています。
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.name.dir</name> <value>file:///hadoop-data/dfs/name</value> </property> <property> <name>dfs.data.dir</name> <value>file:///hadoop-data/dfs/data</value> </property> </configuration>yarn-site.xml
- 低スペックのローカルマシンで動作させるため、デフォルトのメモリ割り当て量(8192MB)とコア割当数(8)から減らしています。
- yarn.nodemanager.aux-services の設定は、エラー "org.apache.hadoop.yarn.exceptions.InvalidAuxServiceException: The auxService:mapreduce_shuffle does not exist" を回避するために必要。
<configuration> <property> <name>yarn.resourcemanager.hostname</name> <value>doc-hmaster101.local</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>4098</value> </property> <property> <name>yarn.nodemanager.resource.memory-mb</name> <value>4098</value> </property> <property> <name>yarn.nodemanager.resource.cpu-vcores</name> <value>4</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> </configuration>mapred-site.xml
Java8 から Virtual Memory の使用量が増えたことにより、container が kill されてしまう可能性があるので、設定によりを抑制する必要があります。
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>yarn.app.mapreduce.am.env</name> <value>HADOOP_MAPRED_HOME=/opt/hadoop/current</value> </property> <property> <name>mapreduce.map.env</name> <value>HADOOP_MAPRED_HOME=/opt/hadoop/current</value> </property> <property> <name>mapreduce.reduce.env</name> <value>HADOOP_MAPRED_HOME=/opt/hadoop/current</value> </property> <!-- To avoid 2.4 GB of 2.1 GB virtual memory used. Killing container--> <property> <name>mapreduce.map.java.opts</name> <value>-XX:ReservedCodeCacheSize=100M -XX:MaxMetaspaceSize=256m -XX:CompressedClassSpaceSize=256m -Xmx1536m -Xms512m</value> </property> <property> <name>mapreduce.reduce.java.opts</name> <value>-XX:ReservedCodeCacheSize=100M -XX:MaxMetaspaceSize=256m -XX:CompressedClassSpaceSize=256m -Xmx1536m -Xms512m</value> </property> </configuration>hadoop-env.sh
HDFS_XXXX_USER や YARN_XXXX_USER の定義は必須。Hadoop 2.x では必要なかった気がします。
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/ export HADOOP_HOME=/opt/hadoop/current export HADOOP_CONF_DIR=/opt/hadoop/current/etc/hadoop/ export HADOOP_HDFS_HOME=$HADOOP_HOME export HADOOP_MAPRED_HOME=$HADOOP_HOME export HADOOP_YARN_HOME=$HADOOP_HOME export HADOOP_OPTS=-Djava.net.preferIPv4Stack=true export HDFS_NAMENODE_USER=root export HDFS_DATANODE_USER=root export HDFS_SECONDARYNAMENODE_USER=root export YARN_RESOURCEMANAGER_USER=root export YARN_NODEMANAGER_USER=rootworkers
Hadoop-slave 用に起動するコンテナのホスト名を記述しておきます。
doc-hslave101.localDockerfile をつくる
実際にはいきなり書き始めるのではなくて、docker run -it debian:9 /bin/bash でコンテナを起動し、そのコンテナ上で各種インストールや動作確認を進めています。
その上で動作確認できたコマンドを Dockerfile に落としています。FROM debian:9 LABEL maintainer "blueskyarea" # Set login shell as bash SHELL ["/bin/bash", "-c"] # install dev tools RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ vim \ systemd \ net-tools \ curl \ netcat \ gnupg \ telnet \ rsync \ openssh-server \ openssh-client # passwordless ssh RUN ssh-keygen -q -N "" -t dsa -f /etc/ssh/ssh_host_dsa_key <<< y RUN ssh-keygen -q -N "" -t rsa -f /etc/ssh/ssh_host_rsa_key <<< y RUN ssh-keygen -q -N "" -t rsa -f /root/.ssh/id_rsa <<< y RUN cp /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys # Java RUN apt-get install -y openjdk-8-jdk ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/ ENV PATH $PATH:$JAVA_HOME/bin # Hadoop ENV HADOOP_VERSION 3.1.3 ENV HADOOP_URL https://www.apache.org/dist/hadoop/common/hadoop-$HADOOP_VERSION/hadoop-$HADOOP_VERSION.tar.gz RUN mkdir /opt/hadoop RUN set -x \ && curl -fSL "$HADOOP_URL" -o /tmp/hadoop.tar.gz --insecure \ && tar -xvf /tmp/hadoop.tar.gz -C /opt/hadoop/ \ && rm -f /tmp/hadoop.tar.gz* RUN ln -nfs /opt/hadoop/hadoop-$HADOOP_VERSION /opt/hadoop/current RUN ln -s /opt/hadoop/current/etc/hadoop /etc/hadoop RUN mkdir /opt/hadoop/current/logs RUN mkdir /hadoop-data ENV HADOOP_HOME /opt/hadoop/current ENV PATH $PATH:$HADOOP_HOME/bin ENV HDFS_NAMENODE_USER root ENV HDFS_DATANODE_USER root ENV HDFS_SECONDARYNAMENODE_USER root ENV YARN_RESOURCEMANAGER_USER root ENV YARN_NODEMANAGER_USER root COPY base/config/core-site.xml $HADOOP_HOME/etc/hadoop/core-site.xml COPY base/config/hdfs-site.xml $HADOOP_HOME/etc/hadoop/hdfs-site.xml COPY base/config/mapred-site.xml $HADOOP_HOME/etc/hadoop/mapred-site.xml COPY base/config/yarn-site.xml $HADOOP_HOME/etc/hadoop/yarn-site.xml COPY base/config/hadoop-env.sh $HADOOP_HOME/etc/hadoop/hadoop-env.sh COPY base/config/workers $HADOOP_HOME/etc/hadoop/workers COPY base/script/start.sh $HADOOP_HOME/start.sh RUN chmod +x $HADOOP_HOME/start.sh RUN rm -rf /var/lib/apt/lists/* EXPOSE 8020 8040 8088 9000 9870 19888 50070 CMD ["/opt/hadoop/current/start.sh"]docker-compose.xml をつくる
Hadoop-master と Hadoop-slave のコンテナを作成します。
元になるイメージは同じ(hadoop-base)ですが、動作させるプロセスが異なってきます。version: '2' services: # Hadoop-master hmaster101: build: context: . dockerfile: ./base/Dockerfile image: hadoop-base hostname: doc-hmaster101.local container_name: hmaster101 ports: - "8040:8040" - "8088:8088" - "9000:9000" - "9870:9870" - "19888:19888" - "50070:50070" mem_limit: 1g networks: hadoop_nw: ipv4_address: 172.30.0.2 extra_hosts: - "doc-hslave101.local:172.30.0.3" environment: TAG: HMASTER # Hadoop-slave hslave101: build: context: . dockerfile: ./base/Dockerfile image: hadoop-base hostname: doc-hslave101.local container_name: hslave101 mem_limit: 2g networks: hadoop_nw: ipv4_address: 172.30.0.3 extra_hosts: - "doc-hmaster101.local:172.30.0.2" environment: TAG: HSLAVE networks: hadoop_nw: driver: bridge ipam: driver: default config: - subnet: 172.30.0.0/16 gateway: 172.30.0.254起動用スクリプトをつくる
- namenode などを起動するためには、ssh サービスが必要となるため、最初に ssh サービスをスタートさせています。
- Hadoop-slave(TAGがHSLAVE) のコンテナ上では特にスクリプトは実行させません。
- Hadoop-master(TAGがHMASTER) のコンテナ上で "start-hdfs" と "start-yarn" を実行します。
- コンテナを起動し続けるために、とりあえず while ループを回しています(docker-compose 上で tty: true を指定しても動作しなかったため)
#!/bin/bash set -e /etc/init.d/ssh start if [ "${TAG}" = 'HSLAVE' ]; then while true; do sleep 1000; done fi if [ "${TAG}" = 'HMASTER' ]; then echo "start-hdfs" && rm -rf /hadoop-data/dfs/* && ${HADOOP_HOME}/bin/hadoop namenode -format && ${HADOOP_HOME}/sbin/start-dfs.sh echo "start-yarn" && ${HADOOP_HOME}/sbin/start-yarn.sh while true; do sleep 1000; done fi動作確認
Hadoop Master 側プロセス
$ docker exec hmaster101 jps 1088 Jps 756 ResourceManager 278 NameNode 487 SecondaryNameNodeHadoop Slave 側プロセス
サービス起動用のスクリプト(start-dfs.sh と start-yarn.sh)を実行したのは、Hadoop Master 側のみですが、Hadoop Slave 側でのプロセスもきちんと起動していることが確認できます。
$ docker exec hslave101 jps 81 DataNode 264 Jps 175 NodeManagerdfsadmin により、1台の Datanode が active になっていることが確認できます。
$ docker exec hmaster101 hdfs dfsadmin -report Configured Capacity: 66355564544 (61.80 GB) Present Capacity: 12480409600 (11.62 GB) DFS Remaining: 12480385024 (11.62 GB) DFS Used: 24576 (24 KB) DFS Used%: 0.00% Replicated Blocks: Under replicated blocks: 0 Blocks with corrupt replicas: 0 Missing blocks: 0 Missing blocks (with replication factor 1): 0 Low redundancy blocks with highest priority to recover: 0 Pending deletion blocks: 0 Erasure Coded Block Groups: Low redundancy block groups: 0 Block groups with corrupt internal blocks: 0 Missing block groups: 0 Low redundancy blocks with highest priority to recover: 0 Pending deletion blocks: 0 ------------------------------------------------- Live datanodes (1): Name: 172.30.0.3:9866 (doc-hslave101.local) Hostname: doc-hslave101.local Decommission Status : Normal Configured Capacity: 66355564544 (61.80 GB) DFS Used: 24576 (24 KB) Non DFS Used: 50473996288 (47.01 GB) DFS Remaining: 12480385024 (11.62 GB) DFS Used%: 0.00% DFS Remaining%: 18.81% Configured Cache Capacity: 0 (0 B) Cache Used: 0 (0 B) Cache Remaining: 0 (0 B) Cache Used%: 100.00% Cache Remaining%: 0.00% Xceivers: 1 Last contact: Sun May 31 10:27:33 UTC 2020 Last Block Report: Sun May 31 10:25:40 UTC 2020 Num of Blocks: 0MapReduce で PI の計算処理
よくテスト実行で使われる処理です。
もし JVM オプションにてネイティブ領域の使用最大量を制限していなかった場合、MapReduce の処理時に "2.4 GB of 2.1 GB virtual memory used. Killing container" のようなエラーが発生します。$ docker exec hmaster101 /opt/hadoop/current/bin/hadoop jar /opt/hadoop/current/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar pi 2 100 Number of Maps = 2 Samples per Map = 100 (省略) 2020-MM-dd 14:02:32,055 INFO mapreduce.Job: Running job: job_1590928186996_0002 2020-MM-dd 14:02:54,990 INFO mapreduce.Job: Job job_1590928186996_0002 running in uber mode : false 2020-MM-dd 14:02:54,993 INFO mapreduce.Job: map 0% reduce 0% 2020-MM-dd 14:03:08,413 INFO mapreduce.Job: map 50% reduce 0% 2020-MM-dd 14:03:18,688 INFO mapreduce.Job: map 100% reduce 0% 2020-MM-dd 14:03:31,866 INFO mapreduce.Job: map 100% reduce 100% 2020-MM-dd 14:03:32,895 INFO mapreduce.Job: Job job_1590928186996_0002 completed successfully (省略) Job Finished in 65.878 seconds 2020-MM-dd 14:03:33,387 INFO sasl.SaslDataTransferClient: SASL encryption trust check: localHostTrusted = false, remoteHostTrusted = false Estimated value of Pi is 3.12000000000000000000結果
- 処理速度は遅いですが、軽量な MapReduce のジョブであれば動作することが確認できました。
- ローカルテスト用のため、root で全部処理してしまっています。hadoop ユーザなど作成して権限を分けたい。
- centos7 ベースで作成するよりも制約が少なくスムーズに実現ができました。 ※より軽量のベースを使うため、alpine をベースに挑戦もしましたが ash でスクリプトを実行しようとするため、シンタックスの問題で Hadoop の各サービスを開始することができませんでした
- Hadoop Web UI (http://localhost:8088/cluster) にもアクセスできます
参考
Hadoop 2.7.1を擬似分散モードで動かす
How to Setup Apache Hadoop 3.1.1
org.apache.hadoop.yarn.exceptions.InvalidAuxServiceException: The auxService:mapreduce_shuffle does not exist
Hadoop2をJava8で動かしたときにハマった
[Java 8] Over usage of virtual memory
- 投稿日:2020-05-31T23:20:21+09:00
【docker-compose】「Unsupported config option for services.~~」の解決方法
docker-compose.ymlを作成し、railsアプリケーションを立ち上げようとしたとき、題名のようなエラーが発生しました。
また、このときのdocker-compose.ymlファイルは以下のようにしていました。ターミナルdocker-compose run --rm app rails new . --force --database=mysql --skip-bundleエラー内容ERROR: The Compose file './docker-compose.yml' is invalid because: Unsupported config option for services.app: 'context' Unsupported config option for services.web: 'context' Unsupported config option for services.volumes: 'db-data' services.app.build contains an invalid type, it should be a string, or an object services.web.build contains an invalid type, it should be a string, or an objectdocker-compose.ymlversion: '3' services: app: build: context: . env_file: - ./environments/db.env command: bundle exec puma -C config/puma.rb volumes: - .:/webapp - public-data:/webapp/public - tmp-data:/webapp/tmp - log-data:/webapp/log depends_on: - db db: image: mysql:5.7 env_file: - ./environments/db.env volumes: - db-data:/var/lib/mysql web: build: context: containers/nginx volumes: - public-data:/webapp/public - tmp-data:/webapp/tmp ports: - 80:80 depends_on: - app volumes: public-data: tmp-data: log-data: db-data:解決方法
結論からいうと、インテンドのやり方がまずかったようです。
エラーが出た箇所のインテンドのやり方が違うようで、意識せずにインテンドをずらしていたので心当たりがありました。
これを以下のように直すと、無事コードが走りました。docker-compose.ymlversion: '3' services: app: build: context: . env_file: - ./environments/db.env command: bundle exec puma -C config/puma.rb volumes: - .:/webapp - public-data:/webapp/public - tmp-data:/webapp/tmp - log-data:/webapp/log depends_on: - db db: image: mysql:5.7 env_file: - ./environments/db.env volumes: - db-data:/var/lib/mysql web: build: context: containers/nginx volumes: - public-data:/webapp/public - tmp-data:/webapp/tmp ports: - 80:80 depends_on: - app volumes: public-data: tmp-data: log-data: db-data:
- 投稿日:2020-05-31T21:55:31+09:00
Docker Portainerでコンテナ追加時のVolumeMapping(for Windows)
- 投稿日:2020-05-31T19:50:23+09:00
aws-sdk-goを通してlocal-kmsを使う
この記事を書いた経緯
aws-sdk-goを用いた案件ソース中にkmsを用いた暗号・復号化の実装があり
kmsという概念すらわからなかった私が、ローカル環境での検証に四苦八苦した時の覚書を認めたものですコマンドだけ知りたい人へ
local-kmsコンテナを立ち上げる
そのままdev環境・本番環境のKMSに作られている鍵を使おうとしても、IAMの認証をかけられてしまうので
権限のないローカル環境では暗号化・復号操作を行うことができません。ローカル環境においてkmsを用いた処理をデバッグしたい場合、local-kmsというdocker imageを用いて実現することが可能です。
他コンテナとポートが重複する場合は、環境変数PORT
を用いることで競合を回避できます$ docker run -p 8080:8081 -e PORT=8081 nsmithuk/local-kmsaws configureの作成
local-kmsを使用する際も通常のインスタンスを用いる場合と同様にクレデンシャル情報が参照されますが
適当なダミーデータで問題ありません
すでに何かしらのconfigureがローカルに作成されていればスルーで問題ないと思います$ aws configure AWS Access Key ID [None]: dummy AWS Secret Access Key [None]: dummy Default region name [None]: ap-northeast-1 Default output format [None]:create-key コマンドによりCMKを作成する
暗号・復号化に必要な、いわゆるCMK(Customer Master Key)と呼ばれるものを作成します。
この時出力されるAccountID・KeyIDなどは適当なダミー値になります$ aws kms create-key --endpoint-url http://localhost:8080 { "KeyMetadata": { "AWSAccountId": "111122223333", "KeyId": "23aeebbd-cb83-43a3-8870-a6f9ee5a4ace", "Arn": "arn:aws:kms:eu-west-2:111122223333:key/23aeebbd-cb83-43a3-8870-a6f9ee5a4ace", "CreationDate": 1590853469, "Enabled": true, "KeyUsage": "ENCRYPT_DECRYPT", "KeyState": "Enabled", "Origin": "AWS_KMS", "KeyManager": "CUSTOMER", "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT", "EncryptionAlgorithms": [ "SYMMETRIC_DEFAULT" ] } }ここで出力された
KeyID
を用いて、kms encryptを実行しますaws-sdk-goからlocal-kmsを介してkms encryptとdecryptを使う
aws-sdk-goのこちらのドキュメントに記載されているサンプルソースを拝借し、若干加筆しました。
WithEndPoint()
へlocal-kmsのコンテナのアドレスを持たせ、WithDisableSSL(true)
を使ってhttpへのアクセスを前提とさせたものを
aws.NewConfig()へメソッドチェーンさせることで、local-kmsを用いた暗号・復号化を可能としますlocalkms.gopackage main import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/kms" "fmt" "os" ) func main() { sess, err := session.NewSession() if err != nil { fmt.Println("aws newsession error: ", err) os.Exit(1) } svc := kms.New(sess, aws.NewConfig().WithRegion("ap-northeast-1").WithEndpoint("localhost:8080").WithDisableSSL(true)) keyId := "arn:aws:kms:eu-west-2:111122223333:key/23aeebbd-cb83-43a3-8870-a6f9ee5a4ace" text := "1234567890" //kms encrypt encResult, err := svc.Encrypt(&kms.EncryptInput{ KeyId: aws.String(keyId), Plaintext: []byte(text), }) if err != nil { fmt.Println("got error encrypting data: ", err) os.Exit(1) } //kms decrypt decResult, err := svc.Decrypt(&kms.DecryptInput{ CiphertextBlob: encResult.CiphertextBlob, }) if err != nil { fmt.Println("got error decrypting data: ", err) os.Exit(1) } fmt.Println("decoded Plaintext:") fmt.Println(string(decResult.Plaintext)) }ソースのビルド
$ go build localkms.goソースの実行
$ go run localkms.go decoded Plaintext: 1234567890Dockerfileでgoのソースをビルドしたい場合
このような階層の簡素なプロジェクトがあることを想定します
tree -L 3 localkms/ localkms/ ├── Dockerfile └── src ├── go.mod ├── go.sum ├── localkms ├── localkms.go └── vendor ├── github.com └── modules.txt
DockerFile
マルチステージビルドの書き方が望ましいですが、とりあえず簡素に作ってみます
DockerfileFROM golang:1.13.0 ADD ./src /go/src/local-kms WORKDIR /go/src/local-kms RUN cd /go/src/local-kms ENV AWS_ACCESS_KEY_ID=dummy ENV AWS_SECRET_ACCESS_KEY=dummy RUN go build -mod=vendor localkms.go ENTRYPOINT ["./localkms"]go.mod
ファイルを作成後、go mod vendorを実行し、srcディレクトリの下にvendorディレクトリを作成します
go.modmodule src/localkms go 1.13 require github.com/aws/aws-sdk-go v1.25.14-0.20200528180948-645efefb5bceソースの修正
コンテナの中からは
localhost
でlocal-kmsを参照できなくなるので
WithEndPointの記述を下記のように変更します(コンテナ名を記載することでそのコンテナのIPアドレスにリクエストが飛ぶようになります)19行目- svc := kms.New(sess, aws.NewConfig().WithRegion("ap-northeast-1").WithEndpoint("localhost:8080").WithDisableSSL(true)) + svc := kms.New(sess, aws.NewConfig().WithRegion("ap-northeast-1").WithEndpoint("local-kms:8081").WithDisableSSL(true))ソースのビルド
$ docker build ./ -t go-containerソースの実行
local-kmsコンテナと連携するため
--link
オプションを利用します$ docker run --link local-kms:local-kms go-container decoded Plaintext: 1234567890
ここから参考文献など
aws cliのインストール
aws kms コマンドの実行にはaws cliのインストールが必要となります
AWS CLI バージョン 1 のインストールkmsとは?
データの暗号化に利用されるCMK(Customer Master Key)の作成と管理を容易にするマネージド型サービスです。
kms encryot
CMKのKeyIDを用いて平文を暗号化します
encryptコマンドリファレンス暗号化されたテキストは、
EncryptionAlgorithm
でのエンクリプションを行った結果ががさらに
base64エンコードされて出力されます。local-kmsを使ったencryptの一例$ aws kms encrypt --key-id arn:aws:kms:eu-west-2:111122223333:key/23aeebbd-cb83-43a3-8870-a6f9ee5a4ace --plaintext "hoge" --endpoint-url http://localhost:8080 { "CiphertextBlob": "S2Fybjphd3M6a21zOmV1LXdlc3QtMjoxMTExMjIyMjMzMzM6a2V5LzIzYWVlYmJkLWNiODMtNDNhMy04ODcwLWE2ZjllZTVhNGFjZQAAAADmlRx1OQCCTk5LQoIkNseoCofCRhLXo3iPpQ2lwx8E5A==", "KeyId": "arn:aws:kms:eu-west-2:111122223333:key/23aeebbd-cb83-43a3-8870-a6f9ee5a4ace", "EncryptionAlgorithm": "SYMMETRIC_DEFAULT" }kms decrypt
CMKにより暗号化されたCiphertextを復号します。
encryptコマンドと異なり、この時keyIDを指定する必要はありません
(ciphertextblobに含まれているメタデータからこの情報を取り込むため、明示的に指定する必要がありません)また、この時の復号結果の出力である
Plaintext
はbase64エンコードされて出てくるため
本来の平文を得るためにはbase64デコードする必要がありますlocal-kmsを使ったdecryptの一例$ aws kms decrypt --ciphertext-blob fileb://<(echo 'S2Fybjphd3M6a21zOmV1LXdlc3QtMjoxMTExMjIyMjMzMzM6a2V5LzIzYWVlYmJkLWNiODMtNDNhMy04ODcwLWE2ZjllZTVhNGFjZQAAAADmlRx1OQCCTk5LQoIkNseoCofCRhLXo3iPpQ2lwx8E5A==' | base64 --decode) --endpoint-url http://localhost:8080 | jq .Plaintext --raw-output | base64 --decode hoge
- 投稿日:2020-05-31T18:07:01+09:00
WSL2+Ubuntu+Docker+Laravel+MariaDB
下記の記事を参考に、動かなかった部分などを調整しながら実施。
https://qiita.com/A-Kira/items/1c55ef689c0f91420e81
https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4最終的に以下のように実行してうまくいった。
開発環境のセットアップ
前提として、前回の記事を参考に実行環境を準備しておく。
Windows10+WSL2+Ubuntu+Dockerディレクトリ・ファイル構成
以下のように、Windows側でフォルダおよびファイルを作った。
project
├── docker
│ ├── app
│ │ ├── Dockerfile
│ │ ├── php-fpm.d
│ │ │ └── zzz-www.conf
│ │ └── php.ini
│ ├── db
│ │ ├── my.cnf
│ └── nginx
│ └── default.conf
├── server
└── docker-compose.ymldocker-compose.ymlversion: '3' services: app: container_name: app build: ./docker/app volumes: - ./server:/var/www/html nginx: image: nginx container_name: nginx ports: - 80:80 volumes: - ./server:/var/www/html - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - app db: image: mariadb:10.4 container_name: db environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: laravel_db MYSQL_USER: laravel MYSQL_PASSWORD: secret TZ: Asia/Tokyoa volumes: - ./docker/db/data:/var/lib/mysql - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf - ./docker/db/sql:/docker-entrypoint-initdb.d ports: - 3306:3306app/DockerfileFROM php:7.4-fpm COPY php.ini /usr/local/etc/php/ RUN apt-get update \ && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libpng-dev \ libzip-dev \ zlib1g-dev \ unzip \ vim \ && docker-php-ext-configure gd --with-freetype --with-jpeg \ && docker-php-ext-install \ gd \ zip \ pdo_mysql ENV TZ=Asia/Tokyo \ COMPOSER_ALLOW_SUPERUSER=1 \ COMPOSER_HOME=/composer COPY --from=composer /usr/bin/composer /usr/bin/composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin WORKDIR /var/www/htmlapp/php-fpm.d/zzz-www.conf[www] listen = /var/run/php-fpm/php-fpm.sock listen.owner = www-data listen.group = www-data listen.mode = 0666app/php.inizend.exception_ignore_args = off expose_php = on max_execution_time = 30 max_input_vars = 2000 upload_max_filesize = 32M post_max_size = 32M memory_limit = 512M error_reporting = E_ALL display_errors = on display_startup_errors = on log_errors = on error_log = /dev/stderr default_charset = UTF-8 [Date] date.timezone = ${TZ} [mysqlnd] mysqlnd.collect_memory_statistics = on [Assertion] zend.assertions = 1 [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"db/my.cnf[mysqld] character_set_server = utf8mb4 # Error Log log-error = mariadb_error.log # Slow Query Log slow_query_log = 1 slow_query_log_file = mariadb_slow.log long_query_time = 1.0 log_queries_not_using_indexes = 0 # General Log general_log = 1 general_log_file = mariadb_general.log [mysql] default-character-set = utf8mb4 [client] default-character-set = utf8mb4nginx/default.confserver { listen 80; index index.php index.html; server_name localhost; error_log /var/log/nginx/error.log; access_log /var/log/nginx/access.log; root /var/www/html/public; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass app:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }Docker環境の起動
docker-compose up -d # 上記完了後、appコンテナに入る docker-compose exec app bashLaravelのセットアップ
composer create-project "laravel/laravel=6.*" . chmod 766 storage -R chmod 766 bootstrap/cache -R chown www-data:www-data storage -R chown www-data:www-data bootstrap/cache -R vim .env.envDB_HOST=db DB_PORT=3306 DB_DATABASE=laravel_db DB_USERNAME=laravel DB_PASSWORD=secretphp artisan config:cache php artisan migrateWindows側のブラウザで、http://localhost/にアクセスすると、Laravelページが表示される。これが完了。
分からなかったこと
app/Dockerfileのところで、Laravelアプリを直接インストールしようとしてエラーは出なかったけど、コンテナが起動したあと見に行ったら無かった。
以下の文を入れたらいけるかなーと思ったのだけど。
RUN composer create-project "laravel/laravel=6.18" .
- 投稿日:2020-05-31T16:27:10+09:00
standard_init_linux.go:211: exec user process caused "no such file or directory" の直し方
はじめに
Windows環境でDockerコンテナを起動すると稀に
standard_init_linux.go:211: exec user process caused "no such file or directory"
というエラーに遭遇する。ベースイメージにalpineを使っている場合の記事はよく見るが今回の件では別の問題だったので共有。ちなみに、alpineの場合は
bash
をash
に変更すれば良いらしい。(コメント、修正等あったらコメントにて教えていだたきたいです)
解決方法
結論から言うと、以下のファイルの改行コードを
CRLF
からLF
に変更すれば解決する。
- Dockerfile
- docker-compose.yml
- 1,2で呼び出している
*.sh
ファイルどうやら改行コードがWindows標準の
CRLF
になっているのが原因らしい。gitコマンドの設定
上記の修正で問題は解決するが、再発防止のために確認すべきポイントがあるので紹介する。
Windowsでgitコマンドを使っていると、
git clone
等のコマンドを叩いた時に自動でLF
をCRLF
に自動で変換してくれる場合がある。この場合タイトルのエラーが出るため、自動変換をオフにしたい。この機能をオフにするには以下のコマンドを叩けば良い。
git config --global core.autocrlf inputautocrlfの細かい挙動については参考3の記事を参照されたい。
参考
- 投稿日:2020-05-31T16:24:31+09:00
Docker Desktop ( Docker for Windows (with WSL2) / Docker for Mac ) インストール, Kubernetes 有効化, Docker / Kubernetes テスト実行
はじめに
Docker / Kubernetes の開発・試験環境として手元 PC に簡易に用意できる Docker Desktop がある
ゼロ準備で Docker / Kuberenetes をスタートし、軽い動作確認までできるように、
Docker Desktop の下記方法を主にまとめる
- Docker ID 取得方法
- Docker Desktop の Windows / Mac 両 OS のインストール方法
- Windows は、WSL2, Hyper-V不要でインストールする
- Kubernetes 有効化の方法
- Docker テスト実行
- Nginx コンテナを起動してブラウザアクセスする
- Docker Desktop Dashboard 操作概要
- Kubernetes テスト実行
- Nginx コンテナの Pod と外部向け Service(NodePort) を構築してブラウザアクセスする
- レプリカの手動スケールアウト、オートヒーリング
Docker Desktop
https://www.docker.com/products/docker-desktop
- Docker 社が提供している Desktop 環境で Docker を利用できる環境
- インストーラが優秀で Docker 構築がデスクトップ上に簡単に構築できる
- DockerCon EU 17 で Docker for Mac での Kubernetes サポートが発表され、ローカルマシン上でも Docker Desktop の機能有効化をするだけで、 Kubernetes が起動できるようになった (のちに Docker for Windows でも対応)
Docker for Windows
- 従来は Hyper-V が必要だったが、WSL2 を有効化することで不要になる
- Hyper-V が不要のため Home でもインストールが可能 (Home は Hyper-V 利用不可)のはず
システム要件
公式サイト抜粋. WSL2 で実施の場合は Hyper-V は有効化不要.
- Windows 10 64-bit: Pro, Enterprise, or Education (Build 15063 or later).
- Hyper-V and Containers Windows features must be enabled.
- The following hardware prerequisites are required to successfully run Client Hyper-V on Windows 10:
- 64 bit processor with Second Level Address Translation (SLAT)
- 4GB system RAM
- BIOS-level hardware virtualization support must be enabled in the BIOS settings. For more information, see Virtualization.
公式ドキュメント: https://docs.docker.com/docker-for-windows/
今回は、Hyper-V不要の手順を試すため、Windows 10 を Version 2004 までアップデートする
Docker for Mac
システム要件
公式サイト抜粋. 2010年以降のモデルで、OS を Update していれば大体入れること可能.
- Mac hardware must be a 2010 or a newer model
- macOS must be version 10.13 or newer
- At least 4 GB of RAM.
- VirtualBox prior to version 4.3.30 must not be installed as it is not compatible with Docker Desktop.
公式ドキュメント: https://docs.docker.com/docker-for-mac/
実行端末スペック
Windows
- Surface Go
- OS: Windows10 Pro Version 2004
- プロセッサ: Intel Pentium Gold 4415Y (1.65GHz 2コア4スレッド)
- メモリ: 4GB
Mac
- MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
- OS: macOS Catalina Version 10.15.4
- プロセッサ:3.1 GHz デュアルコアIntel Core i5
- メモリ:16 GB 2133 MHz LPDDR3
Docker Desktop インストールバージョン
インストールバージョンは 2.3.0.3(45519) (2020.05.30時点最新)
インストールステップ
- Docker アカウント作成
- Docker Desktop インストール
- Docker for Windows インストール
- Docker for Mac インストール
- Kubernetes 有効化
「1.Docker アカウントの作成」は、インストール時は使用しないが、
今後のイメージアップロードなどに備えて取得方法を記載しておく。実行したいだけならスキップ可能インストール後に、docker と Kubernetes のテスト実行も記載する。
1. Docker アカウント作成
Docker Hub のトップページへアクセスしてアカウントを作成する
トップページ: https://hub.docker.com/プラン選択画面になるので、無料で利用したい場合は、Free プラン Continue with Free をクリックする。
プラン選択が終わると、下記画面に遷移して、Verify メールが来るので
Verify メールが登録した Email アドレスへ来るので、受信メールを確認し、Verify email address をクリックする。
下記ページが開いて Docker Hub ID 作成が完了
以上で、アカウント作成完了
2. Docker Desktop インストール
Docker Desktop のインストール方法を、OS 別に記載する
2.1. Docker for Windows インストール
Windows 10 で実施する場合は下記のステップで実行する。
- Windows 10 Update
- WSL2 有効化
- Docker Desktop for Windows をインストール
※今回は Hyper-V 不要でも対応できる方法を記載したかったので、上記方法を使用しているが、Windows 10 Pro で Hyper-V を有効化できる環境ではアップデートせずに Hyper-V 有効化してインストールも可能
2.1.1 Windows 10 Update
Windows 10 は Version 2004 (2020.05.27リリース) で、
WSL2 が正式リリースされ、Hyper-V 無しでも Linux バイナリがネイティブに動作できるようになったWindows Update の方法は、通常の Update を利用するか、更新アシスタントを利用して実施する。
(2020.05.30時点で、バグがあったせいで OS 直接の Update が止まっていたので、更新アシスタントを使用して Update した)すでに Version が 2004 以降であれば実施不要。
更新アシスタントは下記ページからダウンロードして実行すると、アップデート可能。
https://www.microsoft.com/ja-jp/software-download/windows10
ダウンロード完了したら実行。
アップデート完了後の状態例は下記。(バージョンが2004になっている.2004以降ならOK)
2.1.2 WSL2 有効化
公式ドキュメントにインストール方法が記載されている。
管理者として PowerShell を開いて、下記の3コマンド実施,間に一度再起動すれば良い。PowerShell を管理者として実行 (「Windows メニュー」→「Windows PowerShell」→右クリックでメニュー開き「管理者として実行」
2.1.2.1 PowerShell の起動. WSL, VirtualMachinePlatform有効化. 再起動
Windows Subsystem for Linux のインストール
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart仮想マシン プラットフォーム のオプションコンポートネント有効化
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestartWindows を再起動します。
2.1.2.2 カーネル更新
x64 マシン用の最新の WSL2 Linux カーネルパッケージをダウンロードして実行する(参考)
・下記ダウンロード URL. 下記をクリックしてダウンロードして実行し、更新する。
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi2.1.2.3 WSL 2 をデフォルト設定
下記コマンドで、WSL のデフォルトバージョンを 2 に指定する
wsl --set-default-version 2以上で、WSL 2 有効化完了
2.1.3 Docker for Windows のインストール
2.1.3.1 ダウンロード
Docker ID を持っていれば下記で取得も可能(チュートリアルも色々あり、この通りに実行してみるの良い)
https://hub.docker.com/?overlay=onboarding今回は、下記で取得する (上のダウンロードと落とせるのは同じ)
https://hub.docker.com/editions/community/docker-ce-desktop-windows2.1.3.2 インスール
2.1.3.1 でダウンロードしてきた「Docker Desktop installer.exe」を開く
Configuration が出るので、下記の通りデフォルトのチェック状態(どちらもチェック)のまま OK する
下記操作でログアウトとなるので注意
インストールが完了すると Installtion succeeded となるので、Close and log out をクリックするログアウトするので、ログインし直すと、Docker が起動し始めてる
Docker の起動状況は下記のように確認できる起動完了 (Docker Desktop is running)
PowerShell で >
docker version
を入力すると、docker コマンドが使え下記が表示できることが確認できる。Docker Desktop の Dashboard は Docker アイコン右クリックから Dashboard で開ける
Dashboard が開けると下記のような画面が出る
以上で、Docker for Windows のインストール完了
2.2. Docker for Mac インストール
下記でダウンロード可能。
https://hub.docker.com/editions/community/docker-ce-desktop-macダウンロードした「Docker.dmg」を起動
起動すると、下記画面が出るので、画面通りドラッグ&ドロップする。
Finder でアプリケーションを開いて、Docker を開く (Docker起動)
上記で起動すると、メニューバーに Dokcer アイコンが出て起動が確認できる
Docker アイコンをクリックすると状態やメニューが確認できる
Docker Desktop is runningとなっていれば起動完了
Docker Desktop の Dashboard は同じくメニューの Dashboard で開くことが可能
Dashboard が起動すると下記画面が出る
ターミナルソフトで
docker version
を実施した例は下記の通り。(dockerコマンドが利用可能になっている)以上で、Docker for Mac のインストール完了
3. Kubernetes 有効化 (Windows/Mac 共通)
Dashboard を開いて、右上の歯車マークから設定を開く
設定の Kubernetes 項目を選択して、Enable Kubernetes をチェックしてApply & Restart をクリックして起動する
Kubernetes が Start する。(Dashboard の下の方を見ると起動中。起動完了がわかる)
Kubernetes が有効化され、kubectl が CLI (PowerShell(Windows), Terminal(Mac)) で使えるようになっている。
下記は CLI でkubectl version
,kubectl get node
,kubectl get pod --all-namespaces
などを入力して起動していることを確認している例。以上で、 Kubernetes 有効化完了
Docker テスト実行
Docker でのコンテナ実行例として Nginx の web サーバをコンテナ起動・操作する。
$ docker run -d -p 8080:80 --name webserver nginxコンテナ起動での表示結果は下記. (OS にかかわらず同じ)
ブラウザにて localhost ポート 8080 でアクセスする
http://localhost:8080Dashboard による操作
Docker Desktop の Dashboard はコンテナに対する様々な操作・確認ができる。
起動した Nginx コンテナを例に、下記に Dashboard による操作例を記載する例で実行している webserver コンテナは下記のようにダッシュボードに表示される
対象のコンテナにマウスカーソルを合わせるとコンテナに対するメニューが出る
メニューアイコンごとに内容を記載していくOPEN IN BROWSER
一番左の「OPEN IN BROWSER」 (コンテナが web サービスの場合) をクリックすると、
ブラウザが自動で開いてコンテナのサービスが表示されるクリックすると下記の通り自動でブラウザが開き表示される
CLI
左から2番目の CLI (>-) をクリックすると、ターミナルソフトが起動し、
コンテナ内部へアクセスできる
(コマンドで言うと、docker exec -it [container id] /bin/sh; exit
と同じ)クリックすると下記の通り自動でターミナルが開きコンテナ内部のシェルにアクセスできる
STOP / START / RESTART / DELETE
左から3番目の STOP をクリックすると、コンテナを停止できる
停止すると下記の状態になり、START を押すことで、再度コンテナを再開できる
左から4番目の RESTART を押すと、コンテナを再起動できる
最後に、一番右の DELETE を押すと、コンテナを削除できる (Dashboard からも削除される)
削除の場合は、確認画面が表示されるので、Removeを再度クリックして削除する
Logs / Inspect / Stats
メニューアイコン以外の箇所をクリックすると、対象コンテナの詳細をみることができる
Logs をクリックするとコンテナのログを表示できる (ここでは Nginx の Web アクセスログが見えている)
Inspect をクリックするとコンテナの実行パスやバージョン、外部ポートなどを表示できる
Stats をクリックすると CPU / Memory / DISK / NETWORK (I/O) の使用率が表示できる
以上、Dashboard 操作によるコンテナの基本操作例となり、
コンテナの確認や操作などがダッシュボードでコマンド無しでもある程度管理可能なことが確認できたKubernetes テスト実行
Kubernetes でのアプリケーション実行例として Docker と同じく Nginx の web サーバ構築を実施する
3つのテストを実施する
- Nginx Web サーバ構築
- Nginx サーバのレプリカ数の変更
- Nginx サーバのレプリカを 1 つ削除しオートヒーリング
1. Nginx Web サーバ構築
Kubernetes はマニフェストと呼ばれる Yaml ファイルで、コードによるリソース作成・管理ができる
テストで使用する Nginx のマニフェスト (Yaml) 例を下記に記載するnginx-deploy-nodeport.yaml--- apiVersion: apps/v1 kind: Deployment metadata: name: webserver spec: replicas: 1 selector: matchLabels: app: sample-nginx template: metadata: labels: app: sample-nginx spec: containers: - name: webserver image: nginx:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: sample-nodeport spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 nodePort: 30080 selector: app: sample-nginx上記ファイル (Yaml) を下記コマンド (kubectl apply -f) で実行する
> kubectl apply -f nginx-deploy-nodeport.yaml実行すると下記のように表示される
上記も同じだが、以下からも結果は同じのため OS 別表示は省略する
ブラウザで下記 URL にアクセスすると Kubernetes で構築した Pod へ Nodeport 経由で外部からアクセスができる
※ Nodeport は作成した Kubernetes サービスに外部からアクセスする方法のひとつPods の状態は
kubectl get pods
,
Deployment の状態はkubectl get deployment
Service の状態はkubectl get service
,
で確認した例が下記の通り。Pod が
webserver-986476f4c-5ccsf
と言う名前が付与されRunning
となっており、
Deployment はwebserver
として1/1 READY
でレプリカ数1で作成・維持されており、
Service はTYPE:NodePort
で 外部向けポートは30080
で提供していることがわかる最後に、作成したリソースを削除する。
削除にはkubectl delete -f
で作成時ど同じ Yaml を指定すればよい> kubectl delete -f nginx-deply-nodeport.yaml実行すると、作成されていたリソースが削除できていることが確認できる
2. Nginx サーバのレプリカ数の変更
1で利用したマニフェストをもう一度 kubectl apply して起動する
kubectl apply -f nginx-deploy-nodeport.yaml変更前の状態を
kubectl get pod
で Pod の状態と、
kubectl get deployment
でdeployment の状態 (1/1) であることを確認する% kubectl get pod NAME READY STATUS RESTARTS AGE webserver-986476f4c-gwqmz 1/1 Running 0 59m % kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE webserver 1/1 1 1 7h27mレプリカ数を変更する(ここでは 1 -> 3)
マニフェストのreplicas: 1
を、replicas: 3
に書き換える
※下記は書き換え前の old との比較. repolicas の数だけ変更すればよい% diff nginx-deploy-nodeport.yaml nginx-deploy-nodeport.yaml.old 7c7 < replicas: 1 --- > replicas: 3再度 kubectl apply する
kubectl apply -f nginx-deploy-nodeport.yaml再度事前のものと同じ確認をして、
webserver-xxx
(xxxは環境により異なる) の Pod が 3つに増えたこと、
deployment が 3/3 になったことを確認できる% kubectl get pod NAME READY STATUS RESTARTS AGE webserver-986476f4c-gwqmz 1/1 Running 0 60m webserver-986476f4c-j458r 1/1 Running 0 13s webserver-986476f4c-znlft 1/1 Running 0 13s % kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE webserver 3/3 3 3 7h28m下記実行状況の確認例(gif)。自動で Pod が徐々に生成され、レプリカ数が 3 に変更されたことが見える
3. Nginx サーバのレプリカを 1 つ削除しオートヒーリング
作成されている Pod を 1 つ試しに手動削除して、3/3へオートヒーリングすることを確認する
kubectl delete pod [Pod NAME]今回のテストでは、下記コマンドで削除し、表示された例を下記に示す
% kubectl delete pod webserver-986476f4c-znlft pod "webserver-986476f4c-znlft" deleted
kubectl get pod
,kubectl get deployment
で確認すると、
別の NAME で新規のwebserver-xxx
(xxxは状況による) が作成され、3つになっていることがわかる% kubectl get pod NAME READY STATUS RESTARTS AGE webserver-986476f4c-bmkfx 1/1 Running 0 47s webserver-986476f4c-gwqmz 1/1 Running 0 67m webserver-986476f4c-j458r 1/1 Running 0 7m17s % kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE webserver 3/3 3 3 7h35m下記実行状況の確認例。Pod の手動削除後、自動で別のwebserver pod が作成され、
一時的に 2/3 に減ったレプリカが 3/3 にオートヒーリングされたことがわかる最後に、テストに使用したリソースを削除しておわりにする
kubectl delete -f nginx-deploy-nodeport.yaml以上で、Kubernetes の Nginx を使ったテストは完了
おわりに
Docker Desktop のインストールから Docker / Kubernetes の Nginx での簡単な実行例を記載した
手元で簡単に Docker / Kubernetes 実行環境の準備ができ、開発・試験にはもってこいだと思う
複数ノードでのクラスタを組んだ環境を、手元で作成したい場合は、kubespray での kubernetes クラスタ構築メモを参照してください
- 投稿日:2020-05-31T16:24:31+09:00
Docker Desktop インストール (Docker for Windows (with WSL2) / Docker for Mac), Kubernetes 有効化, Docker / Kubernetes テスト実行
はじめに
Docker / Kubernetes の開発・試験環境として手元 PC に簡易に用意できる Docker Desktop がある
ゼロ準備で Docker / Kuberenetes をスタートし、軽い動作確認までできるように、
Docker Desktop の下記方法を主にまとめる
- Docker ID 取得方法
- Docker Desktop の Windows / Mac 両 OS のインストール方法
- Windows は、WSL2, Hyper-V有効化不要でインストールする
- Kubernetes 有効化の方法
- Docker テスト実行
- Nginx コンテナを起動してブラウザアクセスする
- Docker Desktop Dashboard 操作概要
- Kubernetes テスト実行
- Nginx コンテナの Pod と外部向け Service(NodePort) を構築してブラウザアクセスする
- レプリカの手動スケールアウト、オートヒーリング
Docker Desktop
https://www.docker.com/products/docker-desktop
- Docker 社が提供している Desktop 環境で Docker を利用できる環境
- 無償で利用できる
- インストーラが優秀で Docker 構築がデスクトップ上に簡単に構築できる
- DockerCon EU 17 で Docker for Mac での Kubernetes サポートが発表され、ローカルマシン上でも Docker Desktop の機能有効化をするだけで、 Kubernetes が起動できるようになった (のちに Docker for Windows でも対応)
Docker for Windows
- 従来は Hyper-V が機能の有効化が必要(Pro以上の機能)だったが、WSL2 を使用することで不要でも可能になった
- Hyper-V が不要のため Home でもインストールが可能 (Home は Hyper-V 有効化利用不可)のはず
システム要件
公式サイト抜粋. WSL2 で実施の場合は Hyper-V は有効化不要.
- Windows 10 64-bit: Pro, Enterprise, or Education (Build 15063 or later).
- Hyper-V and Containers Windows features must be enabled.
- The following hardware prerequisites are required to successfully run Client Hyper-V on Windows 10:
- 64 bit processor with Second Level Address Translation (SLAT)
- 4GB system RAM
- BIOS-level hardware virtualization support must be enabled in the BIOS settings. For more information, see Virtualization.
公式ドキュメント: https://docs.docker.com/docker-for-windows/
今回は、Hyper-V不要の手順を試すため、Windows 10 を Version 2004 までアップデートする
Docker for Mac
システム要件
公式サイト抜粋. 2010年以降のモデルで、OS を Update していれば大体入れること可能.
- Mac hardware must be a 2010 or a newer model
- macOS must be version 10.13 or newer
- At least 4 GB of RAM.
- VirtualBox prior to version 4.3.30 must not be installed as it is not compatible with Docker Desktop.
公式ドキュメント: https://docs.docker.com/docker-for-mac/
実行端末スペック
Windows
- Surface Go
- OS: Windows10 Pro Version 2004
- プロセッサ: Intel Pentium Gold 4415Y (1.65GHz 2コア4スレッド)
- メモリ: 4GB
Mac
- MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
- OS: macOS Catalina Version 10.15.4
- プロセッサ:3.1 GHz デュアルコアIntel Core i5
- メモリ:16 GB 2133 MHz LPDDR3
Docker Desktop インストールバージョン
インストールバージョンは 2.3.0.3(45519) (2020.05.30時点最新)
インストールステップ
- Docker アカウント作成
- Docker Desktop インストール
- Docker for Windows インストール
- Docker for Mac インストール
- Kubernetes 有効化
「1.Docker アカウントの作成」は、インストール時は使用しないが、
今後のイメージアップロードなどに備えて取得方法を記載しておく。実行したいだけならスキップ可能インストール後に、docker と Kubernetes のテスト実行も記載する。
1. Docker アカウント作成
Docker Hub のトップページへアクセスしてアカウントを作成する
トップページ: https://hub.docker.com/プラン選択画面になるので、無料で利用したい場合は、Free プラン Continue with Free をクリックする。
プラン選択が終わると、下記画面に遷移して、Verify メールが飛ぶ
Verify メールが登録した Email アドレスへ来るので、受信メールを確認し、Verify email address をクリックする。
下記ページが開いて Docker Hub ID 作成が完了
以上で、アカウント作成完了
2. Docker Desktop インストール
Docker Desktop のインストール方法を、OS 別に記載する
2.1. Docker for Windows インストール
Windows 10 で実施する場合は下記のステップで実行する。
- Windows 10 Update
- WSL2 有効化
- Docker Desktop for Windows をインストール
※今回は Hyper-V 不要でも対応できる方法を記載したかったので、上記方法を使用しているが、Windows 10 Pro で Hyper-V を有効化できる環境ではアップデートせずに Hyper-V 有効化してインストールも可能
2.1.1 Windows 10 Update
Windows 10 は Version 2004 (2020.05.27リリース) で、
WSL2 が正式リリースされ、Hyper-V 無しでも Linux バイナリがネイティブに動作できるようになったWindows Update の方法は、通常の Update を利用するか、更新アシスタントを利用して実施する。
(2020.05.30時点で、バグがあったせいで OS 直接の Update が止まっていたので、更新アシスタントを使用して Update した)すでに Version が 2004 以降であれば実施不要。
更新アシスタントは下記ページからダウンロードして実行すると、アップデート可能。
https://www.microsoft.com/ja-jp/software-download/windows10
ダウンロード完了したら実行。
アップデート完了後の状態例は下記。(バージョンが2004になっている.2004以降ならOK)
2.1.2 WSL2 有効化
公式ドキュメントにインストール方法が記載されている。
管理者として PowerShell を開いて、下記の3コマンド実施,間に一度再起動すれば良い。PowerShell を管理者として実行 (「Windows メニュー」→「Windows PowerShell」→右クリックでメニュー開き「管理者として実行」
2.1.2.1 PowerShell の起動. WSL, VirtualMachinePlatform有効化. 再起動
Windows Subsystem for Linux のインストール
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart仮想マシン プラットフォーム のオプションコンポートネント有効化
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestartWindows を再起動します。
2.1.2.2 カーネル更新
x64 マシン用の最新の WSL2 Linux カーネルパッケージをダウンロードして実行する(参考)
・下記ダウンロード URL. 下記をクリックしてダウンロードして実行し、更新する。
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi2.1.2.3 WSL 2 をデフォルト設定
下記コマンドで、WSL のデフォルトバージョンを 2 に指定する
wsl --set-default-version 2以上で、WSL 2 有効化完了
2.1.3 Docker for Windows のインストール
2.1.3.1 ダウンロード
Docker ID を持っていれば下記で取得も可能(チュートリアルも色々あり、この通りに実行してみるの良い)
https://hub.docker.com/?overlay=onboarding今回は、下記で取得する (上のダウンロードと落とせるのは同じ)
https://hub.docker.com/editions/community/docker-ce-desktop-windows2.1.3.2 インスール
2.1.3.1 でダウンロードしてきた「Docker Desktop installer.exe」を開く
Configuration が出るので、下記の通りデフォルトのチェック状態(どちらもチェック)のまま OK する
下記操作でログアウトとなるので注意
インストールが完了すると Installtion succeeded となるので、Close and log out をクリックするログアウトするので、ログインし直すと、Docker が起動し始めてる
Docker の起動状況は下記のように確認できる起動完了 (Docker Desktop is running)
PowerShell で >
docker version
を入力すると、docker コマンドが使え下記が表示できることが確認できる。Docker Desktop の Dashboard は Docker アイコン右クリックから Dashboard で開ける
Dashboard が開けると下記のような画面が出る
以上で、Docker for Windows のインストール完了
2.2. Docker for Mac インストール
下記でダウンロード可能。
https://hub.docker.com/editions/community/docker-ce-desktop-macダウンロードした「Docker.dmg」を起動
起動すると、下記画面が出るので、画面通りドラッグ&ドロップする。
Finder でアプリケーションを開いて、Docker を開く (Docker起動)
上記で起動すると、メニューバーに Dokcer アイコンが出て起動が確認できる
Docker アイコンをクリックすると状態やメニューが確認できる
Docker Desktop is runningとなっていれば起動完了
Docker Desktop の Dashboard は同じくメニューの Dashboard で開くことが可能
Dashboard が起動すると下記画面が出る
ターミナルソフトで
docker version
を実施した例は下記の通り。(dockerコマンドが利用可能になっている)以上で、Docker for Mac のインストール完了
3. Kubernetes 有効化 (Windows/Mac 共通)
Dashboard を開いて、右上の歯車マークから設定を開く
設定の Kubernetes 項目を選択して、Enable Kubernetes をチェックしてApply & Restart をクリックして起動する
Kubernetes が Start する。(Dashboard の下の方を見ると起動中。起動完了がわかる)
Kubernetes が有効化され、kubectl が CLI (PowerShell(Windows), Terminal(Mac)) で使えるようになっている。
下記は CLI でkubectl version
,kubectl get node
,kubectl get pod --all-namespaces
などを入力して起動していることを確認している例。以上で、 Kubernetes 有効化完了
Docker テスト実行
Docker でのコンテナ実行例として Nginx の web サーバをコンテナ起動・操作する。
$ docker run -d -p 8080:80 --name webserver nginxコンテナ起動での表示結果は下記. (OS にかかわらず同じ)
ブラウザにて localhost ポート 8080 でアクセスする
http://localhost:8080Dashboard による操作
Docker Desktop の Dashboard はコンテナに対する様々な操作・確認ができる。
起動した Nginx コンテナを例に、下記に Dashboard による操作例を記載する例で実行している webserver コンテナは下記のようにダッシュボードに表示される
対象のコンテナにマウスカーソルを合わせるとコンテナに対するメニューが出る
メニューアイコンごとに内容を記載していくOPEN IN BROWSER
一番左の「OPEN IN BROWSER」 (コンテナが web サービスの場合) をクリックすると、
ブラウザが自動で開いてコンテナのサービスが表示されるクリックすると下記の通り自動でブラウザが開き表示される
CLI
左から2番目の CLI (>-) をクリックすると、ターミナルソフトが起動し、
コンテナ内部へアクセスできる
(コマンドで言うと、docker exec -it [container id] /bin/sh; exit
と同じ)クリックすると下記の通り自動でターミナルが開きコンテナ内部のシェルにアクセスできる
STOP / START / RESTART / DELETE
左から3番目の STOP をクリックすると、コンテナを停止できる
停止すると下記の状態になり、START を押すことで、再度コンテナを再開できる
左から4番目の RESTART を押すと、コンテナを再起動できる
最後に、一番右の DELETE を押すと、コンテナを削除できる (Dashboard からも削除される)
削除の場合は、確認画面が表示されるので、Removeを再度クリックして削除する
Logs / Inspect / Stats
メニューアイコン以外の箇所をクリックすると、対象コンテナの詳細をみることができる
Logs をクリックするとコンテナのログを表示できる (ここでは Nginx の Web アクセスログが見えている)
Inspect をクリックするとコンテナの実行パスやバージョン、外部ポートなどを表示できる
Stats をクリックすると CPU / Memory / DISK / NETWORK (I/O) の使用率が表示できる
以上、Dashboard 操作によるコンテナの基本操作例となり、
コンテナの確認や操作などがダッシュボードでコマンド無しでもある程度管理可能なことが確認できたKubernetes テスト実行
Kubernetes でのアプリケーション実行例として Docker と同じく Nginx の web サーバ構築を実施する
3つのテストを実施する
- Nginx Web サーバ構築
- Nginx サーバのレプリカ数の変更
- Nginx サーバのレプリカを 1 つ削除しオートヒーリング
1. Nginx Web サーバ構築
Kubernetes はマニフェストと呼ばれる Yaml ファイルで、コードによるリソース作成・管理ができる
テストで使用する Nginx のマニフェスト (Yaml) 例を下記に記載するnginx-deploy-nodeport.yaml--- apiVersion: apps/v1 kind: Deployment metadata: name: webserver spec: replicas: 1 selector: matchLabels: app: sample-nginx template: metadata: labels: app: sample-nginx spec: containers: - name: webserver image: nginx:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: sample-nodeport spec: type: NodePort ports: - name: "http-port" protocol: "TCP" port: 8080 targetPort: 80 nodePort: 30080 selector: app: sample-nginx上記ファイル (Yaml) を下記コマンド (kubectl apply -f) で実行する
> kubectl apply -f nginx-deploy-nodeport.yaml実行すると下記のように表示される
上記も同じだが、以下からも結果は同じのため OS 別表示は省略する
ブラウザで下記 URL にアクセスすると Kubernetes で構築した Pod へ Nodeport 経由で外部からアクセスができる
※ Nodeport は作成した Kubernetes サービスに外部からアクセスする方法のひとつPods の状態は
kubectl get pods
,
Deployment の状態はkubectl get deployment
Service の状態はkubectl get service
,
で確認した例が下記の通り。Pod が
webserver-986476f4c-5ccsf
と言う名前が付与されRunning
となっており、
Deployment はwebserver
として1/1 READY
でレプリカ数1で作成・維持されており、
Service はTYPE:NodePort
で 外部向けポートは30080
で提供していることがわかる最後に、作成したリソースを削除する。
削除にはkubectl delete -f
で作成時ど同じ Yaml を指定すればよい> kubectl delete -f nginx-deply-nodeport.yaml実行すると、作成されていたリソースが削除できていることが確認できる
2. Nginx サーバのレプリカ数の変更
1で利用したマニフェストをもう一度 kubectl apply して起動する
kubectl apply -f nginx-deploy-nodeport.yaml変更前の状態を
kubectl get pod
で Pod の状態と、
kubectl get deployment
でdeployment の状態 (1/1) であることを確認する% kubectl get pod NAME READY STATUS RESTARTS AGE webserver-986476f4c-gwqmz 1/1 Running 0 59m % kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE webserver 1/1 1 1 7h27mレプリカ数を変更する(ここでは 1 -> 3)
マニフェストのreplicas: 1
を、replicas: 3
に書き換える
※下記は書き換え前の old との比較. repolicas の数だけ変更すればよい% diff nginx-deploy-nodeport.yaml nginx-deploy-nodeport.yaml.old 7c7 < replicas: 1 --- > replicas: 3再度 kubectl apply する
kubectl apply -f nginx-deploy-nodeport.yaml再度事前のものと同じ確認をして、
webserver-xxx
(xxxは環境により異なる) の Pod が 3つに増えたこと、
deployment が 3/3 になったことを確認できる% kubectl get pod NAME READY STATUS RESTARTS AGE webserver-986476f4c-gwqmz 1/1 Running 0 60m webserver-986476f4c-j458r 1/1 Running 0 13s webserver-986476f4c-znlft 1/1 Running 0 13s % kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE webserver 3/3 3 3 7h28m下記実行状況の確認例(gif)。自動で Pod が徐々に生成され、レプリカ数が 3 に変更されたことが見える
3. Nginx サーバのレプリカを 1 つ削除しオートヒーリング
作成されている Pod を 1 つ試しに手動削除して、3/3へオートヒーリングすることを確認する
kubectl delete pod [Pod NAME]今回のテストでは、下記コマンドで削除し、表示された例を下記に示す
% kubectl delete pod webserver-986476f4c-znlft pod "webserver-986476f4c-znlft" deleted
kubectl get pod
,kubectl get deployment
で確認すると、
別の NAME で新規のwebserver-xxx
(xxxは状況による) が作成され、3つになっていることがわかる% kubectl get pod NAME READY STATUS RESTARTS AGE webserver-986476f4c-bmkfx 1/1 Running 0 47s webserver-986476f4c-gwqmz 1/1 Running 0 67m webserver-986476f4c-j458r 1/1 Running 0 7m17s % kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE webserver 3/3 3 3 7h35m下記実行状況の確認例。Pod の手動削除後、自動で別のwebserver pod が作成され、
一時的に 2/3 に減ったレプリカが 3/3 にオートヒーリングされたことがわかる最後に、テストに使用したリソースを削除しておわりにする
kubectl delete -f nginx-deploy-nodeport.yaml以上で、Kubernetes の Nginx を使ったテストは完了
おわりに
Docker Desktop のインストールから Docker / Kubernetes の Nginx での簡単な実行例を記載した
手元で簡単に Docker / Kubernetes 実行環境の準備ができ、開発・試験にはもってこいだと思う
複数ノードでのクラスタを組んだ環境を、手元で作成したい場合は、kubespray での kubernetes クラスタ構築メモを参照してください
- 投稿日:2020-05-31T15:18:12+09:00
Docker mysql sqlファイル実行されない
はじめに
おっちょこちょい事件でした、、、
結論から言うと、コンテナを最初に作成するときにsqlファイル実行されるので、
コンテナ削除までしましょうってことでした!!
コンテナストップまでではなくコンテナ削除まで!
ちなみに、イメージの削除までは行わなくて良いっぽいですね!なので行う処理は以下みたいな感じです!
sqlコンテナ削除で再度コンテナ構築まで
a725b2d62fceは自分のものを
$ docker ps
$ docker stop a725b2d62fce
$ docker rm a725b2d62fce
$ docker-compose up --build -d
sqlコンテナ入る
602a4868b08bは自分のものを
$ docker exec -i -t 602a4868b08b bash
sqlログインする
$ mysql -u root -p
パスワード以下のものならexampleコンテナ入っての確認
$ SHOW DATABASES;
$ use mydb01;
$ SHOW TABLES;
本文引用
When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.
google翻訳
コンテナが初めて起動されると、指定された名前の新しいデータベースが作成され、提供された構成変数で初期化されます。 さらに、/ docker-entrypoint-initdb.dにある拡張子.sh、.sql、.sql.gzのファイルを実行します。 ファイルはアルファベット順に実行されます。 SQLダンプをそのディレクトリにマウントすることでmysqlサービスを簡単に作成し、提供されたデータを含むカスタムイメージを提供できます。 SQLファイルは、デフォルトでMYSQL_DATABASE変数で指定されたデータベースにインポートされます。
大事なところ
コンテナが初めて起動されると、指定された名前の新しいデータベースが作成され、提供された構成変数で初期化されます。さらに、/ docker-entrypoint-initdb.dにある拡張子.sh、.sql、.sql.gzのファイルを実行します。
構成ファイル(必要部分のみ)
docker-compose.ymlの記述。以下ピンポイントのみ
docker-compose.ymlversion: '3' services: mysql: container_name: sample-mysql1 #作成されていると出来ないので新しく作成する場合ここの名前を変更 build: ./mysql/ #mysqlのDockerfileを使用してコンテナ volumes: - ./mysql/initdb.d:/docker-entrypoint-initdb.d # ./mysql/initdb.dは入れたいフォルダ名パス。 environment: MYSQL_DATABASE: mydb01 #はじめに作成します!データベース MYSQL_ROOT_PASSWORD: example # これでmysqlのrootユーザー exampleパスで入れる restart: alwaysmysql/initdb.d/Sample.sqlの中 Sample.sqlだけ書いているが複数あっても良い
Sample.sqlCREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, email VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, created DATETIME, modified DATETIME ); INSERT INTO users (email, password, created, modified) VALUES ('cakephp@example.com', 'secret', NOW(), NOW());
- 投稿日:2020-05-31T14:06:19+09:00
Kubernetesの仕組みのまとめ
Kubernetesの仕組み
マスター
API Server
Kubernetesのリソース情報を管理するためのフロントエンドのRESTAPI。
- 各コンポーネントからリソースの情報を受け取り、データストア(etcd)に格納。
- 他のコンポーネントはこのetcdの情報にAPI Serverを介してアクセス。
- GUIツールやコマンドでアクセス可能。
- アプリケーション内からAPIServerを呼び出すことも可能。
- 認証/認可の機能ありScheduler
Podをどのノードで動かすかを制御するバックエンドコンポーネント。
ノードに割り当てられていないPodに対して、Kubernetesクラスタの状態を確認し、空きスペースを持つノードを探してPodを実行されるスケジュールリングを行う。Controller Manager
Kubernetesクラスタの状態を常に監視するバックエンドコンポーネント。
定義ファイルで指定したものと実際のノードやコンテナで動作している状態をまとめて管理。データストア
Kubernetesのクラスタの構成を保持する分散KVS。
ノード
kubelet
ノードではkubeletというエージェントが動作している。
- Podの定義ファイルにしたがってDockerコンテナを実行したり、ストレージをマウントしたりする機能を持つ
- ノードのステータスを定期的に監視する機能をもちステータスが変わると、APIServerに通知参考
- 投稿日:2020-05-31T13:22:58+09:00
Windows10 バージョン2004 ビルド19041に上げてみた
はじめに
Windows 10大型更新「May 2020 Update」が提供開始という記事が出ていたので、早速、Windows Updateしてみた。お目当てはWSL(Windows Subsystem for Linux)からWSL2へのアップグレード。WSL2では次のようなメリットが得られるが、DockerがWSL2上で稼働するようになる。VirtualBoxの領域が解放されるという、長年の夢がようやく実現されようとしている。
- Docker Desktop WSL 2 backendで得られるメリット
- Hyper-Vが不要
- パフォーマンス向上
- Windows 10 Home EditionでDocker Desktopを使用可能
- パス記法の違いを考慮しなくて済む
- PowerShellの学習コストが不要になる
必須要件
ネットワーク速度、マシンスペック、ディスク領域の空き容量に依存しますが、おおよそ3時間コースでした。SDカードなどの外部記憶装置を事前に用意しておけば、混乱なく、スムーズにアップデート可能だと思います。
- Windows 10 バージョン1909 ビルド18363以降が稼働するPC
- ハードディスクに空きが10GB以上あること
- ハードディスクの空き容量との合計が10GB以上になるくらい空いているSDカード
Windows Updateの手順
- Download Windows 10にアクセスする。
- 今回は1台のPCをアップグレードしたいだけなので、
[Update now]
ボタンをクリックした。Windows10Upgrade9252.exe
ファイルがダウンロードされる。Windows10Upgrade9252.exe
ファイルをダブルクリックして起動する。- 次の画面が表示されるので、
[今すぐ更新]
ボタンをクリックする。CPU
、メモリ
、ディスク領域
のうち、ディスク領域
が不足すると警告されたので、[やり直す]
ボタンをクリックした。- 空き領域を12GBまで増やして、再度チャレンジし、今度は条件をクリア。
[次へ]
ボタンをクリックする。- ダウンロードが開始する。
- 順調かと思いきや、問題が発生!
[やり直す]
ボタンをクリックした。- どうやら、ディスク領域の空き容量にご不満だったらしく、外部記憶装置を要求された。最初から言ってくれ!途方に暮れて、
[外部記憶装置を使用しません]
リンクをクリックしてみた。- 急いで32GBのSDカードを空けて、
[代わりに外部記憶装置を使用する]
リンクをクリックした。- SDカードをPCに挿して、右側のプルダウンから選択し、
[次へ]
ボタンをクリックする。 ※筆者の環境では、SDカードの使用量が3.34GBになっていた。空き容量に合わせてSDカードを選んで欲しい。- ようやく、Windows Updateが開始される。
- 更新完了!
[今すぐ再起動]
ボタンをクリックする。- 再起動時にもいくつか設定が実行され、Windows10が起動する。
winver
コマンドでバージョンを確認する。バージョン1909 ビルド18363
???- もう一度、最初からやり直す...。
Windows10Upgrade9252.exe
ファイルをダブルクリックして起動するところから...。- 更新処理を終え、Windowsにログオンすると、次の画面が表示されたので、今度こそ成功を確信!
winver
コマンドでバージョンを確認し、めでたく、バージョン2004 ビルド19041
にアップデートされました!さいごに
この後、WSL2にアップグレードし、Docker Toolboxをアンインストールして、Docker Desktop WSL 2 backendをインストールしよう!
Windows10 HomeのWSLをWSL2にアップグレードしてみたに続く。
- 投稿日:2020-05-31T12:50:10+09:00
WSL2 + Ubuntu:18.04 + DockerCompose でCLI開発環境構築の備忘録
タイトル通り。
- WSL2導入、設定。
- Windows Terminal導入、設定。
- Docker、DockerCompose導入。windows->WSL2へのポートフォワーディング設定
- (その他)Dockerのユーザ定義ネットワークの謎の名前解決不具合対処。
WSL2導入
やった事がこちらの記事にほぼ載ってたので割愛。
完全新規に導入する場合は、WSL2の設定後に、
CMD
かPowerShell
から、wsl --set-default-version 2
を実行後に、Microsoft Storeからインストールする。WSL2設定
メモリ上限設定、localhostでの通信許可設定
デフォルトだと、WSL2が無限にメモリを食い尽くそうとしてきた。
あと、WindowsからWSL2環境にアクセスするときにlocalhost
を使いたい。
C:\Users\<yourUserName>\.wslconfig
をつくって、設定をする。
memory=2GB
とlocalhostForwarding=true
だけ作って、あとは未検証。日本語化
WSL2関係ない普通のubuntuの日本語化だけど、一応。
Linuxの日本語化の仕組みを良く分かってないから、言われた通りにしただけ。Ubuntu用ファイルへのショートカットを作成
\\wsl$\[ディストリビューション名]
で、ディストリビューションのディレクトリを見る事が出来る。デスクトップにショートカットを作っておくと、何かと便利。Windows Terminal導入
ここ
Microsoft謹製の、Linuxのターミナルっぽい奴。タブも分割表示もできるし、CMD
もPowerShell
も一緒に扱えるんで、便利。
フォントも指定できるんで、Source Han Code JPを入れてみた。OSにインストールしてから、Windows Terminal
の設定を選択するとひらくsettings.json
のprofiles: defaults:
に`"fontFace" : "Souce Han Code JP"を指定。Docker、DockerCompose導入
Dockerを、公式に言われるがままにインストール。
DockerComposeを、公式に言われるがままにインストール。Dockerデーモンについての 注意点
WSL2では、
systemd
が使えない(原理的にpid 1 が占有されるから使えない、とかなんとからしい)から、Dockerデーモンは自分で起動させる必要がある。
立ち上げるたびにsudo service docker start
してるけど、大変面倒臭いんで、その内自動化したい。Windows -> WSL2のポートフォワーディング設定
今の状態でも、WindowsからWSL2へのアクセスは、
localhost
を使えば出来る様になっているのだけれど、直接127.0.0.1
を使いたい事もある。
なので、Windowsへの特定のポートへのリクエストを、WSLにポートフォワードさせる設定をする。問題になった事例(飛ばしてよい)
AndroidStudio
で立ち上げたエミュレーターから、WSL2のDockerComopse
で立ち上げたサーバに通信したい時に問題が発生。
AndroidStudio
のエミュレーターから、ホスト機(Windows)への通信は、10.0.2.2
を使って実現出来るのだけれど、、この通信はホスト機側では127.0.0.1
として解釈されるっぽい。
WindowsからWSL2にアクセス出来るのがlocalhost
だけのままだと、当然エミュレータ(10.0.2.2)⇒Windows(127.0.0.1、not localhost)だから、Dockerで立ち上げたサーバまでは届かない。
なので、127.0.0.1
が来た場合でもWSL2側にポートフォワードさせる必要があった。設定
こちらを参照させてもらって、スクリプトを作成。
listenport
を開発中サービスの待ち受けポートに変更。- ついでに
ifconfig
をip a
に合わせて変更- 開発用の設定は開発用のgitの中に閉じ込めたいので、windowsでのタスクスケジューラの設定は無しにして、
docker-compose up
前に手でスクリプトを叩く運用にする。set_port_forwardings_for_wsl2.sh#!/bin/bash -x # !注意!:実行には管理者権限が必要なので、ターミナルを管理者権限で立ち上げる事。 # WSL2での起動時に、windows側から'127.0.0.1'でもアクセス可能にするための設定。 IP=$(ip -4 addr show dev eth0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1) netsh.exe interface portproxy delete v4tov4 listenport=3000 netsh.exe interface portproxy add v4tov4 listenport=3000 connectaddress=$IP netsh.exe interface portproxy show v4tov4注意点
WSL2のアドレスは再起動の度に変わるから、スクリプトをしょっちゅう叩かないといけない。大変面倒なんで自動化したい。
(その他)Dockerの名前解決不具合の対処
WSL2とは関係ないかもしれないけど、コンテナからの名前解決時に変な挙動が発生して、githubとの連携が出来ない現象が発生した。
開発環境としては致命的なんで、是が非でも解決する必要がある。
結論としては、Dockerに追加DNSサーバとしてパブリックなもの(8.8.8.8とか)を設定して回避可能。現象
- ユーザ定義ネットワークを使ったコンテナ内からの、
github.com
の名前解決をする時にだけ、挙動がおかしい。google.com
とかは大丈夫。dig
では普通に名前解決が出来る。curl
やping
やgit clone
では、出来たり出来なかったりする。(大抵はCould not resolve host: github.com
で出来ない)tcpdump
でパケットを確認すると、ユーザ定義ネットワーク用の内部DNSサーバまでは、ちゃんとレコードが帰って来てるのに、内部DNSサーバでレコードだけが消滅している。DNSのレスポンス自体は返ってくる。- 内部DNSのキャッシュ機能があるなら変な動きをしてそう。が、内部DNSなんで細かいところが見えず、これ以上は追えない。
WSL2というより、Dockerの内部DNSのバグなんじゃないかって気がする。
バージョンはDocker version 19.03.9, build 9d988398e7
以下の手順で再現出来る(かもしれない)
docker network create test docker run --net="test" -it ubuntu:16.04 /bin/bash apt update && apt install curl -y curl github.com最初は成功したりもするが、何度か繰り返したり時間をおいてから再実行したりすると、
curl: (6) Could not resolve host: github.com
が出る。解決
理由は全くわからないから追うのを諦め、必要な機能が達成出来ていれば良い事にした。
ユーザ定義ネットワークは、DockerCompose
で立ち上げた各コンテナ同士が、サービス名で名前解決して連携するために使うから、必須。
ただ、怪しい動きをしてるユーザ定義ネットワークの内部DNSサーバーは、最低限サービス名での名前解決機能だけ提供してくれれば良いので、内部DNSサーバが名前解決(この場合はgithub.com)に失敗した時用に、別途ちゃんとしたDNSサーバを追加すれば良い。(今回は8.8.8.8)Dockerなら、
docker run --net="test" --dns=8.8.8.8 -it ubuntu:16.04 /bin/bash
、DockerComposeならymlにdsn: 8.8.8.8
を追加する事で、問題を回避出来た。WSL2開発環境所感
これまでの環境が、
Vagrant -> virtualbox -> centos -> DockerCompose
だったんで、1段階減って、Windowsとの連携がしやすくなっただけでもとても便利。
Windows側のリソースもあんまり取らないし、体感速度も大分上がってる。今のところVimでしか触ってないんだけど、
Docker for Desktop
とかVSCode
を連携す有ればさらに快適になるのかもしれないという予感は抱かせてくれる。
Windows Terminal
も良い感じだし、今のMicrosoftはほんと良いなぁ。
- 投稿日:2020-05-31T12:16:07+09:00
Kubernetesのサーバ構成、アプリケーションの構成を基礎をまとめる
Kubernetesとは?
複数のホストを束ねてDockerを利用するためのオーケストレーションツール。
分散環境において、透過的にコンテナにアクセスすることができる。Kubernetesの主な機能
- 複数サーバでのコンテナ管理
- コンテナ間のネットワーク管理
- コンテナの負荷分散
- コンテナの監視
- 無停止でのアップデート
Kubernetesのサーバ構成
マスターサーバ
Kubernetesクラスタ内のコンテナを操作するサーバ。
コマンドを使って、クラスタの構成やリソース操作をする。
複数台からなる分散したノードをまとめて管理することができる。バックエンドデータベース
etcdと呼ばれる分散キーバリューストア(KVS)を使って、クラスタの構成情報を管理。
クラスタを構築するための設定情報が書き込まれている。
マスターサーバ上に構築するケースもある。ノード
実際に、Dockerコンテナを動作させるサーバ。
アプリケーションの構成管理
Pod
Kubernetesでは、複数のコンテナをまとめて「Pod」として管理する。
- Podがアプリケーションのデプロイの単位になり、Podの単位でコンテナの作成、開始、停止、削除などの操作を行う。 そのため、Webフロントサーバとデータベースサーバなどの役割の異なる機能を1つのPodに格納してはいけない。
- Pod内の複数のコンテナで仮想NICを共有する構成をとるため、コンテナ同士がlocalhost経由で通信できる。
- 共有ディレクトリを介してログ情報をやりとりすることもできる。
- ノードの中には、複数のPodが配置
ReplicaSet
Kubernetesクラスタ上であらかじめ指定されたPodを作成/起動しておく仕組み
= 「クラス上に決められた数のPodを必ず起動しておくもの」
- ReplicaSetは起動中のPodを監視し、障害など何らかの理由で停止してしまった場合、該当のPodを削除し、新たなPodを起動 = Podが必要な数だけ起動した状態をクラスタ内に作る役目
- クラスタ内にPodをいくつ起動しておくかの値を「レプリカ数」と呼ぶ
- Podの数を動的に変更してオートスケールを実現することも可能
- ReplicaSetにより、アプリケーション開発者はデプロイしたPodがどのような状態かを気にすることが必要なく、常に指定した個数だけPodが起動した状態をKubernetesが維持してくれる
Deployment
PodとReplicaSetをまとめたもので、ReplicaSetの履歴を管理する。
- ReplicaSetのテンプレートを持って、それでReplicaSetを作る。
- 履歴を管理できるので、バージョンを戻すっていったこともできる
- ReplicaSetの作成や更新を定義する
ネットワークの管理
Kubernetesクラスタ内で起動したPodに対して、外部からアクセスするときはサービスを定義する
サービスはKubernetesのネトワークを管理するもの。サービスによって割り当てられるIPアドレスには、ClusterIPとExternalIPがある。
Cluster IP
クラスタ内のPod同士で通信するためのプラベートIPアドレス。
クラスタ内のPodからClusterIPに向けたバケットは、後述するノード上のProxyデーモンを受け取って、宛先のPodに転送される。External IP
外部のクライアントから接続するためのパブリックIPアドレス。
新規にPodを起動すると、既存のサービスのIPアドレスとポート番号は、環境変数として参照できるようになる。Labelによるリソースの識別
Kubernetesではリソースを識別するためにランダムな名前が内部で自動に付与される。
それだと、わかりにくいので、Labelを付けて管理ができます。参考
- 投稿日:2020-05-31T11:29:02+09:00
Dockerでbuildを実行したら、名前解決が出来ずにエラー
Ubuntu 20.04で
$ docker build .
を実行したら、以下のようなエラーが複数回発生してタイムアウトした。
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'NewConnectionError(': Failed to establish a new connection: [Errno -3] Temporary failure in name resolution')': /simple/pipenv/
$ sudo vi /etc/default/docker
でDockerの設定ファイルを開きDOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"
をコメントアウトした後
$ sudo service docker restart
でエラーが解消された。
- 投稿日:2020-05-31T11:00:36+09:00
DockerMachineとは?Docker Machineのコマンドについてのまとめ
Docker Machineとは
ホストマシン/クラウド/仮想環境などにDockerの実行環境を作成できるコマンドラインツール
公式サイト
github
- Amanzon Web Service
- Microsoft Azuru などいろいろな環境をサポートしている。
Docker Machineの基本コマンド
バージョン確認
$ docker-machine --version実行環境の作成
$ docker-machine create --driver ドライバー名 作成するDockerマシン名指定できるドライバー
ドライバー名 作成する環境 amazonec2 Amanzon Web Servies EC2 azure Microsoft Azure 他にもいろいろ、、。
他のドライバー一覧実行環境の一覧表示
$ docker-machine ls [オプション]
オプション 説明 --quiet, -q マシン名のみ表示する --filter 表示するマシンをフィルタする 実行環境のステータスの確認
$ docker-machine status マシン名
実行環境のURLの確認
$ docker-machine url マシン名
実行環境へのSSH接続
$ docker-machine ssh マシン名
実行環境の起動
$ docker-machine start マシン名
実行環境の停止
$ docker-machine stop マシン名
実行環境の再起動
$ docker-machine restart マシン名
実行環境からのファイルダウンロード
$ docker-machine scp
実行環境の削除
$ docker-machine rm動作中の実行環境を強制的に削除するときは、-fオプションを指定する
強制的に停止したい場合は、
$ docker-machine killを行う。
実行環境のIPアドレス確認
$ docker-machine ip
実行環境の情報確認
$ docker-machine inspect [オプション] マシン名参考
- 投稿日:2020-05-31T02:34:25+09:00
ローカル kubernetes 開発環境での永続 Volume 共有
TL;DR
- 手元の docker for desktop の k8s 内で shell を使って何かしたい。
- k8s 内のPod間でファイルを共有したい、さらに作成したファイルを永続化したい。
- サンプルは全てこちらにあります https://github.com/Bugfire/k8s-workspace
はじめに
自分は k8s を使って開発を行ったことがなく、ドキュメントを読みながら手探りで試しています。一般的用法から外れている、記法がよろしくない、簡潔にかける等、コメントがあるととても助かります!
kubectl は以下の版です
$ kubectl version Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.5", GitCommit:"20c265fef0741dd71a66480e35bd69f18351daea", GitTreeState:"clean", BuildDate:"2019-10-15T19:16:51Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"} Server Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.5", GitCommit:"20c265fef0741dd71a66480e35bd69f18351daea", GitTreeState:"clean", BuildDate:"2019-10-15T19:07:57Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}目的
Docker を使った開発で、複数コンテナ間で永続的な Volume で開発・テストを行う。これを k8s で実現したい。
自分は Docker 内のみに存在する Volume で開発を行うのが好きです。これと、一般的なホスト側のファイルを用いるケースと両方で作ってみます。
実装
Docker内Volume - NFS
ドキュメントをみた感じ local, hostPath Volume は、永続的ですがホスト側FSにマッピングされ、emptyDir はホストFSに依存しませんが Pod の寿命に依存するので、永続性がないので目的を果たせません。
k8s からすでに外れますが、k8s 外の NFS を用いることにしました。k8s 外であれば Volume は Pod の寿命に依存せず、NFS Persistent Volume を用いることで k8s からマウントして利用します。
便利な NFS 用の Docker image があります、それをそのまま使います。
$ docker run -d --rm --name nfs -p 2049:2049 -v nfs:/nfs --privileged -e SHARED_DIRECTORY=/nfs itsthenetwork/nfs-server-alpine:latest注意、NFSへのアクセス制限はかかっていません。ファイアウォールの設定を確認してください。
ファイアウォールで外部からの2049ポートへのアクセスを全て落とすか、
NFS 側で-e PERMITTED="192.168.*.*"
等の制限をかけてください。上のワンライナーで nfs と言う名前の Volume を提供する NFS を起動し、
apiVersion: v1 kind: PersistentVolume metadata: name: local-volume spec: capacity: storage: 5Gi accessModes: - ReadWriteMany storageClassName: nfs persistentVolumeReclaimPolicy: Retain nfs: server: 192.168.x.x path: /このような NFS の Persistent Volume を生成することにしました。
PVC は以下の通り
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: local-volume-claim spec: accessModes: - ReadWriteMany storageClassName: nfs resources: requests: storage: 5Giホスト側ファイルを用いたVolume
これは、ホスト側をそのまま用います。特にひねりはありません。
apiVersion: v1 kind: PersistentVolume metadata: name: local-volume spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-storage local: path: /PATH-TO-SHARE nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - docker-for-desktop - docker-desktopPVC はこちら
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: local-volume-claim spec: accessModes: - ReadWriteOnce storageClassName: local-storage resources: requests: storage: 5GiConfigMap
複数の ConfigMap を合成したり、Immutable な ConfigMap にしたいと、いろいろな記事を参考に、ファイルを合成した上で hash の suffix を追加などを試していたりしました。
しかし kustomize が kubectl に入っていることに気がつき、これを利用することにしました。
k8s は変化が速いので、ググって出た記事が最近の情勢にあってるともかぎらないですね。
ConfigMapGenerator
base 側に
configMapGenerator: - name: common-env env: common.envを記述しておき、overlay 側で
configMapGenerator: - name: common-env behavior: merge env: common.envとしておくとマージされます、便利ですね。
最終的に base 側で
apiVersion: v1 kind: Pod metadata: name: workspace labels: app: k8s-workspace spec: containers: - name: workspace image: node:lts-stretch command: [ "/bin/bash", "-c", "while true; do sleep 1; done" ] resources: requests: cpu: 1000m memory: 1000Mi envFrom: - configMapRef: name: common-envとすることで、環境変数にマージ後のものを読み込んでいます。
Kustomize
Kustomize をせっかく使うので、上の Volume 等も合わせて、階層構造化してみました
- base_common
- kustomization.yaml
- 共通設定
- common.env
- 共通環境変数
- workspace.yaml
- Pod の共通設定
- base_volume_localpath
- base_volume_nfs
- config
- kustomization.yaml
- base_common 及び base_volume_localpath もしくは base_volume_nfs を派生した上でディレクトリ・IP・環境変数を独自に設定します。
- volume-nfs.yaml.sample
- オーバレイ設定 volume-nfs.yaml のサンプル。
- volume-localpath.yaml.sample
- オーバレイ設定 volume-localpath.yaml のサンプル。
- common.env
- ユーザ設定環境変数
- workspace.yaml
- workspace Pod のオーバレイ設定。今回は base_common 側に記述しても問題はないが、Volume を使用していることを明示したいので、こちらに記述しました。
Helm
せっかくなので、helm
$ helm version version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"}を用いた版を、https://github.com/Bugfire/k8s-workspace/blob/master/helm に作りました。
ここでは、ほぼテンプレートエンジンとしてだけ使い、config.yaml を定義して使う形になります。
- 投稿日:2020-05-31T02:00:42+09:00
dockerのインストールで「"C:\Program Files\Docker\Docker\installationmanifest.json" が見つからない」エラーが出たときの対処
発端
ソフトウェアエンジニアとしてまだ弱々だったころ,Dockerを興味本位でインストール,ちょっと触って適当に消した私が,改めてDockerをインストールしようとして出会ったエラーを後学のために残します.
問題
「"C:\Program Files\Docker\Docker\installationmanifest.json" が見つからない」
といった内容のエラーが出ていた.
(エラー内容をちゃんと残していませんでした,ごめんなさい)推測される原因
Dockerを以前インストールして,正規の手段以外でDockerのアンインストールをした.アホ.
対処方法
Dockerのサクセスセンターに対処法はありました.以下説明はこちらのトラブルシューティングの日本語訳です.こちらのおかげで対処できました.Thank you Docker developers and success center.
Dockerサクセスセンター - Docker.For.Win - Install fails on installationmanifest.json
注意
この対処方法はレジストリを編集します.というかゴッソリ削除します.
実行は自己責任でお願いいたします.対処方法
実行中のDockerプロセスをKillする
レジストリエディター(Regedit)を実行します
Win + r で検索窓を開き,「regedit」で開きましょう.レジストリのバックアップを取ります.
- 「ファイル」→「エクスポート」
- 「エクスポート範囲」は「すべて」
- 適当な名前をつけて保存
レジストリエディターの中で以下の階層へ移動します.
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
「Docker for Windows」や「Docker Desktop」のようなDockerに関するレジストリを全て削除します.
※目的以外の項目は削除しないように注意Dockerのインストーラを起動します.これでインストールできたら成功です.
あとがき
生半可な知識でファイルやディレクトリの削除は行っちゃだめですね.反省.
- 投稿日:2020-05-31T01:42:32+09:00
Dockerを使って軽量なFastAPIの開発環境を構築
はじめに
最近FastAPIを使う機会がよくあり,Dockerでサクッと構築して使い捨てしたかったので
メモとして軽量で構築する方法を残したいと思います.準備
- Docker及びDocker Composeが使える環境
バージョン$ docker --version Docker version 19.03.8, build afacb8b7f0
- ファイル構成はこんな感じにします
ファイル構成. ├── Dockerfile ├── docker-compose.yml ├── main.py └── requirements.txt
ソース
ここからcloneできます
https://github.com/sattosan/sample-fastapi-alpineDockerfile
alpineベースで作っています
DockerfileFROM python:3.8-alpine WORKDIR /app ADD requirements.txt . # コンテナ内で必要なパッケージをインストール RUN apk add --no-cache build-base mariadb-connector-c-dev # requirements.txtにリストされたPythonパッケージをインストールする RUN pip install --no-cache-dir --trusted-host pypi.python.org -r requirements.txt ADD main.py . # FastAPIを8000ポートで待機 CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]Docker Compose
docker-compose.ymlversion: "3.0" services: # FastAPI api: container_name: "api" build: . restart: always tty: true ports: - 8000:8000必要なパッケージをまとめています
requirements.txtuvicorn fastapiサンプルコード
FastAPIのドキュメントにあるサンプルコードを用意しました
main.pyfrom fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"}実行
$ docker-compose up -d --buildDocker Imageサイズの確認
- alpineベースのImageサイズ
docker images | grep api latest bff0158b61ca 29 minutes ago 275MB
- 本家のImageサイズ 本家様を参考に構築した結果です
$ docker images | grep api latest 878110f2207f 11 seconds ago 1.02GB本家に比べて3.6倍軽減出来たことがわかります
動作確認
FastAPIで生成したAPIはSwaggerで自動的にドキュメント化されています
Swaggerで見てみる
ドメイン/docs
にアクセスするとドキュメントを見ることが出来ますAPI叩いてみる
curlで叩くとこんな感じで返って来ます
結果$ curl localhost:8000 {"Hello":"World"}おわりに
今回はalpineベースで軽量な開発環境を構築してみました.
本家より3.6倍軽量になるので,使い捨てには十分な環境だとは思います.
最近ではNetflixを始め様々なプロジェクトでFastAPIが使われ始めているので,
まだ使っていない人は是非使って見てください!参考サイト
- 投稿日:2020-05-31T01:42:32+09:00
Dockerを使った軽量なFastAPIの開発環境を構築
はじめに
最近FastAPIを使う機会がよくあり,Dockerでサクッと構築して使い捨てしたかったので
メモとして軽量で構築する方法を残したいと思います.準備
- Docker及びDocker Composeが使える環境
バージョン$ docker --version Docker version 19.03.8, build afacb8b7f0
- ファイル構成はこんな感じにします
ファイル構成. ├── Dockerfile ├── docker-compose.yml ├── main.py └── requirements.txt
ソース
ここからcloneできます
https://github.com/sattosan/sample-fastapi-alpineDockerfile
alpineベースで作っています
DockerfileFROM python:3.8-alpine WORKDIR /app ADD requirements.txt . # コンテナ内で必要なパッケージをインストール RUN apk add --no-cache build-base mariadb-connector-c-dev # requirements.txtにリストされたPythonパッケージをインストールする RUN pip install --no-cache-dir --trusted-host pypi.python.org -r requirements.txt ADD main.py . # FastAPIを8000ポートで待機 CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]Docker Compose
docker-compose.ymlversion: "3.0" services: # FastAPI api: container_name: "api" build: . restart: always tty: true ports: - 8000:8000必要なパッケージをまとめています
requirements.txtuvicorn fastapiサンプルコード
FastAPIのドキュメントにあるサンプルコードを用意しました
main.pyfrom fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"}実行
$ docker-compose up -d --buildDocker Imageサイズの確認
- alpineベースのImageサイズ
docker images | grep api latest bff0158b61ca 29 minutes ago 275MB
- 本家のImageサイズ
本家様を参考に構築した結果です
$ docker images | grep api latest 878110f2207f 11 seconds ago 1.02GB本家に比べて3.6倍軽減出来たことがわかります
動作確認
FastAPIで生成したAPIはSwaggerで自動的にドキュメント化されています
Swaggerで見てみる
ドメイン/docs
にアクセスするとドキュメントを見ることが出来ますAPI叩いてみる
curlで叩くとこんな感じで返って来ます
結果$ curl localhost:8000 {"Hello":"World"}おわりに
今回はalpineベースで軽量な開発環境を構築してみました.
本家より3.6倍軽量になるので,使い捨てには十分な環境だとは思います.
最近ではNetflixを始め様々なプロジェクトでFastAPIが使われ始めているので,
まだ使っていない人は是非使って見てください!参考サイト