20200531のdockerに関する記事は19件です。

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=root

workers

Hadoop-slave 用に起動するコンテナのホスト名を記述しておきます。

doc-hslave101.local

Dockerfile をつくる

実際にはいきなり書き始めるのではなくて、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 SecondaryNameNode

Hadoop Slave 側プロセス

サービス起動用のスクリプト(start-dfs.sh と start-yarn.sh)を実行したのは、Hadoop Master 側のみですが、Hadoop Slave 側でのプロセスもきちんと起動していることが確認できます。

$ docker exec hslave101 jps
81 DataNode
264 Jps
175 NodeManager

dfsadmin により、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: 0

MapReduce で 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

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【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 object
docker-compose.yml
version: '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.yml
version: '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:
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker Portainerでコンテナ追加時のVolumeMapping(for Windows)

結論

hostがwindowsの場合、パスを次のように指定する。

CドライブのDockerShareフォルダを指定する場合

/host_mnt/c/DockerShare

画面キャプチャ

PortainerAddContainerWindows.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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-kms

aws 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.go
package 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: 1234567890

Dockerfileでgoのソースをビルドしたい場合

このような階層の簡素なプロジェクトがあることを想定します

tree -L 3 localkms/
localkms/
├── Dockerfile
└── src
    ├── go.mod
    ├── go.sum
    ├── localkms
    ├── localkms.go
    └── vendor
        ├── github.com
        └── modules.txt

DockerFile

マルチステージビルドの書き方が望ましいですが、とりあえず簡素に作ってみます

Dockerfile
FROM 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.mod
module 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

decryptコマンドリファレンス

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.yml

docker-compose.yml
version: '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:3306
app/Dockerfile
FROM 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/html
app/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 = 0666
app/php.ini
zend.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 = utf8mb4
nginx/default.conf
server {
  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 bash

Laravelのセットアップ

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
.env
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=laravel
DB_PASSWORD=secret
php artisan config:cache
php artisan migrate

Windows側のブラウザで、http://localhost/にアクセスすると、Laravelページが表示される。これが完了。

分からなかったこと

app/Dockerfileのところで、Laravelアプリを直接インストールしようとしてエラーは出なかったけど、コンテナが起動したあと見に行ったら無かった。
以下の文を入れたらいけるかなーと思ったのだけど。
RUN composer create-project "laravel/laravel=6.18" .

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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の場合はbashashに変更すれば良いらしい。

(コメント、修正等あったらコメントにて教えていだたきたいです)

解決方法

結論から言うと、以下のファイルの改行コードをCRLFからLFに変更すれば解決する。

  1. Dockerfile
  2. docker-compose.yml
  3. 1,2で呼び出している*.shファイル

どうやら改行コードがWindows標準のCRLFになっているのが原因らしい。

gitコマンドの設定

上記の修正で問題は解決するが、再発防止のために確認すべきポイントがあるので紹介する。

Windowsでgitコマンドを使っていると、git clone等のコマンドを叩いた時に自動でLFCRLFに自動で変換してくれる場合がある。この場合タイトルのエラーが出るため、自動変換をオフにしたい。

この機能をオフにするには以下のコマンドを叩けば良い。

git config --global core.autocrlf input

autocrlfの細かい挙動については参考3の記事を参照されたい。

参考

  1. Dockerでalpineイメージ使用時に発生したstandard_init_linux.go:211: exec user process caused "no such file or directory" を解決
  2. Windows Docker Error - standard_init_linux.go:211: exec user process caused "no such file or directory" #9
  3. 気をつけて!Git for Windowsにおける改行コード
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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_for_desktop_version.png

インストールステップ

  1. Docker アカウント作成
  2. Docker Desktop インストール
    1. Docker for Windows インストール
    2. Docker for Mac インストール
  3. Kubernetes 有効化

「1.Docker アカウントの作成」は、インストール時は使用しないが、
今後のイメージアップロードなどに備えて取得方法を記載しておく。実行したいだけならスキップ可能

インストール後に、docker と Kubernetes のテスト実行も記載する。

1. Docker アカウント作成

Docker Hub のトップページへアクセスしてアカウントを作成する
トップページ: https://hub.docker.com/

下記画面の通り必要事項を入力して Sign Up する
スクリーンショット 2020-05-30 14.35.31.png

プラン選択画面になるので、無料で利用したい場合は、Free プラン Continue with Free をクリックする。
スクリーンショット 2020-05-30 14.08.22.png

プラン選択が終わると、下記画面に遷移して、Verify メールが来るので

スクリーンショット 2020-05-30 14.09.47.png

Verify メールが登録した Email アドレスへ来るので、受信メールを確認し、Verify email address をクリックする。

スクリーンショット 2020-05-30 14.11.04.png

下記ページが開いて Docker Hub ID 作成が完了

スクリーンショット 2020-05-30 14.12.09.png

以上で、アカウント作成完了

2. Docker Desktop インストール

Docker Desktop のインストール方法を、OS 別に記載する

2.1. Docker for Windows インストール

Windows 10 で実施する場合は下記のステップで実行する。

  1. Windows 10 Update
  2. WSL2 有効化
  3. 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

windows_update.png

ダウンロード完了したら実行。

windows_update2.png

アップデート完了後の状態例は下記。(バージョンが2004になっている.2004以降ならOK)

仕様.png

2.1.2 WSL2 有効化

公式ドキュメントにインストール方法が記載されている。
管理者として PowerShell を開いて、下記の3コマンド実施,間に一度再起動すれば良い。

PowerShell を管理者として実行 (「Windows メニュー」→「Windows PowerShell」→右クリックでメニュー開き「管理者として実行」

2.1.2.1 PowerShell の起動. WSL, VirtualMachinePlatform有効化. 再起動

PowerShell管理者として実行.png

Windows Subsystem for Linux のインストール

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

仮想マシン プラットフォーム のオプションコンポートネント有効化

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

Windows を再起動します。

2.1.2.2 カーネル更新

x64 マシン用の最新の WSL2 Linux カーネルパッケージをダウンロードして実行する(参考)

・下記ダウンロード URL. 下記をクリックしてダウンロードして実行し、更新する。
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

2.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

windows_tutorial1___.png

今回は、下記で取得する (上のダウンロードと落とせるのは同じ)
https://hub.docker.com/editions/community/docker-ce-desktop-windows

スクリーンショット 2020-05-30 22.08.39.png

2.1.3.2 インスール

2.1.3.1 でダウンロードしてきた「Docker Desktop installer.exe」を開く

dockerforwindosinstall__.png

Configuration が出るので、下記の通りデフォルトのチェック状態(どちらもチェック)のまま OK する

dockerforwindosinstall2_.png

下記操作でログアウトとなるので注意
インストールが完了すると Installtion succeeded となるので、Close and log out をクリックする

dockerforwindosinstall3_.png

ログアウトするので、ログインし直すと、Docker が起動し始めてる
Docker の起動状況は下記のように確認できる

起動中 (Docker is starting)
dockerstating.png

起動完了 (Docker Desktop is running)
dockerrunning.png

PowerShell で >docker version を入力すると、docker コマンドが使え下記が表示できることが確認できる。

dockerversion.png

Docker Desktop の Dashboard は Docker アイコン右クリックから Dashboard で開ける

docker_dashboard__.png

Dashboard が開けると下記のような画面が出る

docker_dashboard2.png

以上で、Docker for Windows のインストール完了

2.2. Docker for Mac インストール

下記でダウンロード可能。
https://hub.docker.com/editions/community/docker-ce-desktop-mac

スクリーンショット 2020-05-30 23.26.47.png

ダウンロードした「Docker.dmg」を起動

起動すると、下記画面が出るので、画面通りドラッグ&ドロップする。

DockerForMacInstall.gif

Finder でアプリケーションを開いて、Docker を開く (Docker起動)

スクリーンショット 2020-05-31 0.04.39.png

上記で起動すると、メニューバーに Dokcer アイコンが出て起動が確認できる

スクリーンショット 2020-05-31 0.07.23.png

Docker アイコンをクリックすると状態やメニューが確認できる

スクリーンショット 2020-05-31 0.10.04.png

Docker Desktop is runningとなっていれば起動完了

Docker Desktop の Dashboard は同じくメニューの Dashboard で開くことが可能

スクリーンショット 2020-05-31 0.26.33.png

Dashboard が起動すると下記画面が出る

スクリーンショット 2020-05-31 0.29.24.png

ターミナルソフトで docker version を実施した例は下記の通り。(dockerコマンドが利用可能になっている)

スクリーンショット 2020-05-31 0.15.59.png

以上で、Docker for Mac のインストール完了

3. Kubernetes 有効化 (Windows/Mac 共通)

Dashboard を開いて、右上の歯車マークから設定を開く

docker_setting.png

設定の Kubernetes 項目を選択して、Enable Kubernetes をチェックしてApply & Restart をクリックして起動する

k8s_enable2_.png

Kubernetes が Start する。(Dashboard の下の方を見ると起動中。起動完了がわかる)

起動中 (starting)
k8s_enable3.png

起動完了 (running)
k8s_enable4_.png

Kubernetes が有効化され、kubectl が CLI (PowerShell(Windows), Terminal(Mac)) で使えるようになっている。
下記は CLI で kubectl version , kubectl get node, kubectl get pod --all-namespaces などを入力して起動していることを確認している例。

Windows PowerShell での実行例
k8s_enable_5.png

Mac Terminal での実行例
スクリーンショット 2020-05-31 0.37.10.png

以上で、 Kubernetes 有効化完了

Docker テスト実行

Docker でのコンテナ実行例として Nginx の web サーバをコンテナ起動・操作する。

$ docker run -d -p 8080:80 --name webserver nginx

コンテナ起動での表示結果は下記. (OS にかかわらず同じ)

Windows での実行例
dockerrun.png

Macでの実行例
スクリーンショット 2020-05-31 5.03.42.png

ブラウザにて localhost ポート 8080 でアクセスする
http://localhost:8080

スクリーンショット 2020-05-31 5.04.33.png

Dashboard による操作

Docker Desktop の Dashboard はコンテナに対する様々な操作・確認ができる。
起動した Nginx コンテナを例に、下記に Dashboard による操作例を記載する

例で実行している webserver コンテナは下記のようにダッシュボードに表示される

スクリーンショット 2020-05-31 6.57.12.png

対象のコンテナにマウスカーソルを合わせるとコンテナに対するメニューが出る
メニューアイコンごとに内容を記載していく

OPEN IN BROWSER

一番左の「OPEN IN BROWSER」 (コンテナが web サービスの場合) をクリックすると、
ブラウザが自動で開いてコンテナのサービスが表示される

スクリーンショット 2020-05-31 6.58.53.png

クリックすると下記の通り自動でブラウザが開き表示される

スクリーンショット 2020-05-31 5.04.33.png

CLI

左から2番目の CLI (>-) をクリックすると、ターミナルソフトが起動し、
コンテナ内部へアクセスできる
(コマンドで言うと、docker exec -it [container id] /bin/sh; exitと同じ)

スクリーンショット 2020-05-31 6.59.24.png

クリックすると下記の通り自動でターミナルが開きコンテナ内部のシェルにアクセスできる

スクリーンショット 2020-05-31 7.01.39.png

STOP / START / RESTART / DELETE

左から3番目の STOP をクリックすると、コンテナを停止できる

スクリーンショット 2020-05-31 6.59.58.png

停止すると下記の状態になり、START を押すことで、再度コンテナを再開できる

スクリーンショット 2020-05-31 7.02.14.png

左から4番目の RESTART を押すと、コンテナを再起動できる

スクリーンショット 2020-05-31 7.00.25.png

最後に、一番右の DELETE を押すと、コンテナを削除できる (Dashboard からも削除される)

スクリーンショット 2020-05-31 7.00.55.png

削除の場合は、確認画面が表示されるので、Removeを再度クリックして削除する

スクリーンショット 2020-05-31 7.02.36.png

Logs / Inspect / Stats

メニューアイコン以外の箇所をクリックすると、対象コンテナの詳細をみることができる

スクリーンショット 2020-05-31 7.22.32.png

Logs をクリックするとコンテナのログを表示できる (ここでは Nginx の Web アクセスログが見えている)
スクリーンショット 2020-05-31 7.20.35.png

Inspect をクリックするとコンテナの実行パスやバージョン、外部ポートなどを表示できる
スクリーンショット 2020-05-31 7.20.58.png

Stats をクリックすると CPU / Memory / DISK / NETWORK (I/O) の使用率が表示できる
スクリーンショット 2020-05-31 7.21.19.png

以上、Dashboard 操作によるコンテナの基本操作例となり、
コンテナの確認や操作などがダッシュボードでコマンド無しでもある程度管理可能なことが確認できた

Kubernetes テスト実行

Kubernetes でのアプリケーション実行例として Docker と同じく Nginx の web サーバ構築を実施する
3つのテストを実施する

  1. Nginx Web サーバ構築
  2. Nginx サーバのレプリカ数の変更
  3. 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

実行すると下記のように表示される

Windows
win_kubectl_apply.png

Mac
スクリーンショット 2020-05-31 7.57.28.png

上記も同じだが、以下からも結果は同じのため OS 別表示は省略する

ブラウザで下記 URL にアクセスすると Kubernetes で構築した Pod へ Nodeport 経由で外部からアクセスができる
※ Nodeport は作成した Kubernetes サービスに外部からアクセスする方法のひとつ

http://localhost:30080

スクリーンショット 2020-05-31 7.48.02.png

Pods の状態は kubectl get pods,
Deployment の状態は kubectl get deployment
Service の状態は kubectl get service,
で確認した例が下記の通り。

スクリーンショット 2020-05-31 7.51.26.png

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

スクリーンショット 2020-05-31 7.56.42.png

実行すると、作成されていたリソースが削除できていることが確認できる

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 に変更されたことが見える

repolica_test.gif

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 にオートヒーリングされたことがわかる

delete_tests.gif

最後に、テストに使用したリソースを削除しておわりにする

kubectl delete -f nginx-deploy-nodeport.yaml

以上で、Kubernetes の Nginx を使ったテストは完了

おわりに

Docker Desktop のインストールから Docker / Kubernetes の Nginx での簡単な実行例を記載した

手元で簡単に Docker / Kubernetes 実行環境の準備ができ、開発・試験にはもってこいだと思う

複数ノードでのクラスタを組んだ環境を、手元で作成したい場合は、kubespray での kubernetes クラスタ構築メモを参照してください

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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_for_desktop_version.png

インストールステップ

  1. Docker アカウント作成
  2. Docker Desktop インストール
    1. Docker for Windows インストール
    2. Docker for Mac インストール
  3. Kubernetes 有効化

「1.Docker アカウントの作成」は、インストール時は使用しないが、
今後のイメージアップロードなどに備えて取得方法を記載しておく。実行したいだけならスキップ可能

インストール後に、docker と Kubernetes のテスト実行も記載する。

1. Docker アカウント作成

Docker Hub のトップページへアクセスしてアカウントを作成する
トップページ: https://hub.docker.com/

下記画面の通り必要事項を入力して Sign Up する
スクリーンショット 2020-05-30 14.35.31.png

プラン選択画面になるので、無料で利用したい場合は、Free プラン Continue with Free をクリックする。
スクリーンショット 2020-05-30 14.08.22.png

プラン選択が終わると、下記画面に遷移して、Verify メールが飛ぶ

スクリーンショット 2020-05-30 14.09.47.png

Verify メールが登録した Email アドレスへ来るので、受信メールを確認し、Verify email address をクリックする。

スクリーンショット 2020-05-30 14.11.04.png

下記ページが開いて Docker Hub ID 作成が完了

スクリーンショット 2020-05-30 14.12.09.png

以上で、アカウント作成完了

2. Docker Desktop インストール

Docker Desktop のインストール方法を、OS 別に記載する

2.1. Docker for Windows インストール

Windows 10 で実施する場合は下記のステップで実行する。

  1. Windows 10 Update
  2. WSL2 有効化
  3. 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

windows_update.png

ダウンロード完了したら実行。

windows_update2.png

アップデート完了後の状態例は下記。(バージョンが2004になっている.2004以降ならOK)

仕様.png

2.1.2 WSL2 有効化

公式ドキュメントにインストール方法が記載されている。
管理者として PowerShell を開いて、下記の3コマンド実施,間に一度再起動すれば良い。

PowerShell を管理者として実行 (「Windows メニュー」→「Windows PowerShell」→右クリックでメニュー開き「管理者として実行」

2.1.2.1 PowerShell の起動. WSL, VirtualMachinePlatform有効化. 再起動

PowerShell管理者として実行.png

Windows Subsystem for Linux のインストール

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

仮想マシン プラットフォーム のオプションコンポートネント有効化

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

Windows を再起動します。

2.1.2.2 カーネル更新

x64 マシン用の最新の WSL2 Linux カーネルパッケージをダウンロードして実行する(参考)

・下記ダウンロード URL. 下記をクリックしてダウンロードして実行し、更新する。
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

2.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

windows_tutorial1___.png

今回は、下記で取得する (上のダウンロードと落とせるのは同じ)
https://hub.docker.com/editions/community/docker-ce-desktop-windows

スクリーンショット 2020-05-30 22.08.39.png

2.1.3.2 インスール

2.1.3.1 でダウンロードしてきた「Docker Desktop installer.exe」を開く

dockerforwindosinstall__.png

Configuration が出るので、下記の通りデフォルトのチェック状態(どちらもチェック)のまま OK する

dockerforwindosinstall2_.png

下記操作でログアウトとなるので注意
インストールが完了すると Installtion succeeded となるので、Close and log out をクリックする

dockerforwindosinstall3_.png

ログアウトするので、ログインし直すと、Docker が起動し始めてる
Docker の起動状況は下記のように確認できる

起動中 (Docker is starting)
dockerstating.png

起動完了 (Docker Desktop is running)
dockerrunning.png

PowerShell で >docker version を入力すると、docker コマンドが使え下記が表示できることが確認できる。

dockerversion.png

Docker Desktop の Dashboard は Docker アイコン右クリックから Dashboard で開ける

docker_dashboard__.png

Dashboard が開けると下記のような画面が出る

docker_dashboard2.png

以上で、Docker for Windows のインストール完了

2.2. Docker for Mac インストール

下記でダウンロード可能。
https://hub.docker.com/editions/community/docker-ce-desktop-mac

スクリーンショット 2020-05-30 23.26.47.png

ダウンロードした「Docker.dmg」を起動

起動すると、下記画面が出るので、画面通りドラッグ&ドロップする。

DockerForMacInstall.gif

Finder でアプリケーションを開いて、Docker を開く (Docker起動)

スクリーンショット 2020-05-31 0.04.39.png

上記で起動すると、メニューバーに Dokcer アイコンが出て起動が確認できる

スクリーンショット 2020-05-31 0.07.23.png

Docker アイコンをクリックすると状態やメニューが確認できる

スクリーンショット 2020-05-31 0.10.04.png

Docker Desktop is runningとなっていれば起動完了

Docker Desktop の Dashboard は同じくメニューの Dashboard で開くことが可能

スクリーンショット 2020-05-31 0.26.33.png

Dashboard が起動すると下記画面が出る

スクリーンショット 2020-05-31 0.29.24.png

ターミナルソフトで docker version を実施した例は下記の通り。(dockerコマンドが利用可能になっている)

スクリーンショット 2020-05-31 0.15.59.png

以上で、Docker for Mac のインストール完了

3. Kubernetes 有効化 (Windows/Mac 共通)

Dashboard を開いて、右上の歯車マークから設定を開く

docker_setting.png

設定の Kubernetes 項目を選択して、Enable Kubernetes をチェックしてApply & Restart をクリックして起動する

k8s_enable2_.png

Kubernetes が Start する。(Dashboard の下の方を見ると起動中。起動完了がわかる)

起動中 (starting)
k8s_enable3.png

起動完了 (running)
k8s_enable4_.png

Kubernetes が有効化され、kubectl が CLI (PowerShell(Windows), Terminal(Mac)) で使えるようになっている。
下記は CLI で kubectl version , kubectl get node, kubectl get pod --all-namespaces などを入力して起動していることを確認している例。

Windows PowerShell での実行例
k8s_enable_5.png

Mac Terminal での実行例
スクリーンショット 2020-05-31 0.37.10.png

以上で、 Kubernetes 有効化完了

Docker テスト実行

Docker でのコンテナ実行例として Nginx の web サーバをコンテナ起動・操作する。

$ docker run -d -p 8080:80 --name webserver nginx

コンテナ起動での表示結果は下記. (OS にかかわらず同じ)

Windows での実行例
dockerrun.png

Macでの実行例
スクリーンショット 2020-05-31 5.03.42.png

ブラウザにて localhost ポート 8080 でアクセスする
http://localhost:8080

スクリーンショット 2020-05-31 5.04.33.png

Dashboard による操作

Docker Desktop の Dashboard はコンテナに対する様々な操作・確認ができる。
起動した Nginx コンテナを例に、下記に Dashboard による操作例を記載する

例で実行している webserver コンテナは下記のようにダッシュボードに表示される

スクリーンショット 2020-05-31 6.57.12.png

対象のコンテナにマウスカーソルを合わせるとコンテナに対するメニューが出る
メニューアイコンごとに内容を記載していく

OPEN IN BROWSER

一番左の「OPEN IN BROWSER」 (コンテナが web サービスの場合) をクリックすると、
ブラウザが自動で開いてコンテナのサービスが表示される

スクリーンショット 2020-05-31 6.58.53.png

クリックすると下記の通り自動でブラウザが開き表示される

スクリーンショット 2020-05-31 5.04.33.png

CLI

左から2番目の CLI (>-) をクリックすると、ターミナルソフトが起動し、
コンテナ内部へアクセスできる
(コマンドで言うと、docker exec -it [container id] /bin/sh; exitと同じ)

スクリーンショット 2020-05-31 6.59.24.png

クリックすると下記の通り自動でターミナルが開きコンテナ内部のシェルにアクセスできる

スクリーンショット 2020-05-31 7.01.39.png

STOP / START / RESTART / DELETE

左から3番目の STOP をクリックすると、コンテナを停止できる

スクリーンショット 2020-05-31 6.59.58.png

停止すると下記の状態になり、START を押すことで、再度コンテナを再開できる

スクリーンショット 2020-05-31 7.02.14.png

左から4番目の RESTART を押すと、コンテナを再起動できる

スクリーンショット 2020-05-31 7.00.25.png

最後に、一番右の DELETE を押すと、コンテナを削除できる (Dashboard からも削除される)

スクリーンショット 2020-05-31 7.00.55.png

削除の場合は、確認画面が表示されるので、Removeを再度クリックして削除する

スクリーンショット 2020-05-31 7.02.36.png

Logs / Inspect / Stats

メニューアイコン以外の箇所をクリックすると、対象コンテナの詳細をみることができる

スクリーンショット 2020-05-31 7.22.32.png

Logs をクリックするとコンテナのログを表示できる (ここでは Nginx の Web アクセスログが見えている)
スクリーンショット 2020-05-31 7.20.35.png

Inspect をクリックするとコンテナの実行パスやバージョン、外部ポートなどを表示できる
スクリーンショット 2020-05-31 7.20.58.png

Stats をクリックすると CPU / Memory / DISK / NETWORK (I/O) の使用率が表示できる
スクリーンショット 2020-05-31 7.21.19.png

以上、Dashboard 操作によるコンテナの基本操作例となり、
コンテナの確認や操作などがダッシュボードでコマンド無しでもある程度管理可能なことが確認できた

Kubernetes テスト実行

Kubernetes でのアプリケーション実行例として Docker と同じく Nginx の web サーバ構築を実施する
3つのテストを実施する

  1. Nginx Web サーバ構築
  2. Nginx サーバのレプリカ数の変更
  3. 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

実行すると下記のように表示される

Windows
win_kubectl_apply.png

Mac
スクリーンショット 2020-05-31 7.57.28.png

上記も同じだが、以下からも結果は同じのため OS 別表示は省略する

ブラウザで下記 URL にアクセスすると Kubernetes で構築した Pod へ Nodeport 経由で外部からアクセスができる
※ Nodeport は作成した Kubernetes サービスに外部からアクセスする方法のひとつ

http://localhost:30080

スクリーンショット 2020-05-31 7.48.02.png

Pods の状態は kubectl get pods,
Deployment の状態は kubectl get deployment
Service の状態は kubectl get service,
で確認した例が下記の通り。

スクリーンショット 2020-05-31 7.51.26.png

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

スクリーンショット 2020-05-31 7.56.42.png

実行すると、作成されていたリソースが削除できていることが確認できる

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 に変更されたことが見える

repolica_test.gif

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 にオートヒーリングされたことがわかる

delete_tests.gif

最後に、テストに使用したリソースを削除しておわりにする

kubectl delete -f nginx-deploy-nodeport.yaml

以上で、Kubernetes の Nginx を使ったテストは完了

おわりに

Docker Desktop のインストールから Docker / Kubernetes の Nginx での簡単な実行例を記載した

手元で簡単に Docker / Kubernetes 実行環境の準備ができ、開発・試験にはもってこいだと思う

複数ノードでのクラスタを組んだ環境を、手元で作成したい場合は、kubespray での kubernetes クラスタ構築メモを参照してください

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker mysql sqlファイル実行されない

はじめに

おっちょこちょい事件でした、、、

参考dockerhub_mysql

結論から言うと、コンテナを最初に作成するときにsqlファイル実行されるので、
コンテナ削除までしましょうってことでした!!
コンテナストップまでではなくコンテナ削除まで!
ちなみに、イメージの削除までは行わなくて良いっぽいですね!

なので行う処理は以下みたいな感じです!

:older_man_tone3:sqlコンテナ削除で再度コンテナ構築まで

a725b2d62fceは自分のものを

$ docker ps
$ docker stop a725b2d62fce
$ docker rm a725b2d62fce
$ docker-compose up --build -d

:older_man_tone3:sqlコンテナ入る

602a4868b08bは自分のものを

$ docker exec -i -t 602a4868b08b bash

:older_man_tone3:sqlログインする
$ mysql -u root -p
パスワード以下のものならexample

:older_man_tone3:コンテナ入っての確認

$ 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.yml
version: '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: always

mysql/initdb.d/Sample.sqlの中 Sample.sqlだけ書いているが複数あっても良い

Sample.sql
CREATE 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());
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Kubernetesの仕組みのまとめ

Kubernetesの仕組み

スクリーンショット 2020-05-31 12.29.02.png

マスター

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に通知

参考

https://www.amazon.co.jp/dp/B017UGA7NG/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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の手順

  1. Download Windows 10にアクセスする。
  2. 今回は1台のPCをアップグレードしたいだけなので、[Update now]ボタンをクリックした。
  3. Windows10Upgrade9252.exeファイルがダウンロードされる。
  4. Windows10Upgrade9252.exeファイルをダブルクリックして起動する。
  5. 次の画面が表示されるので、[今すぐ更新]ボタンをクリックする。 コメント 2020-05-28 190402.png
  6. CPUメモリディスク領域のうち、ディスク領域が不足すると警告されたので、[やり直す]ボタンをクリックした。 コメント 2020-05-28 190415.png
  7. 空き領域を12GBまで増やして、再度チャレンジし、今度は条件をクリア。[次へ]ボタンをクリックする。 コメント 2020-05-28 190429.png
  8. ダウンロードが開始する。 コメント 2020-05-28 190443.png
  9. 順調かと思いきや、問題が発生![やり直す]ボタンをクリックした。 コメント 2020-05-28 194937.png コメント 2020-05-28 200836.png
  10. どうやら、ディスク領域の空き容量にご不満だったらしく、外部記憶装置を要求された。最初から言ってくれ!途方に暮れて、[外部記憶装置を使用しません]リンクをクリックしてみた。 コメント 2020-05-28 202027.png
  11. 急いで32GBのSDカードを空けて、[代わりに外部記憶装置を使用する]リンクをクリックした。 コメント 2020-05-28 203450.png
  12. SDカードをPCに挿して、右側のプルダウンから選択し、[次へ]ボタンをクリックする。 ※筆者の環境では、SDカードの使用量が3.34GBになっていた。空き容量に合わせてSDカードを選んで欲しい。 コメント 2020-05-28 203235.png
  13. ようやく、Windows Updateが開始される。 コメント 2020-05-28 204119.png
  14. 更新完了![今すぐ再起動]ボタンをクリックする。 コメント 2020-05-28 210032.png
  15. 再起動時にもいくつか設定が実行され、Windows10が起動する。
  16. winverコマンドでバージョンを確認する。 コメント 2020-05-28 224120.png
  17. バージョン1909 ビルド18363??? コメント 2020-05-28 224153.png
  18. もう一度、最初からやり直す...。Windows10Upgrade9252.exeファイルをダブルクリックして起動するところから...。
  19. 更新処理を終え、Windowsにログオンすると、次の画面が表示されたので、今度こそ成功を確信! コメント 2020-05-29 003147.png
  20. winverコマンドでバージョンを確認し、めでたく、バージョン2004 ビルド19041にアップデートされました! コメント 2020-05-29 003106.png

さいごに

この後、WSL2にアップグレードし、Docker Toolboxをアンインストールして、Docker Desktop WSL 2 backendをインストールしよう!
Windows10 HomeのWSLをWSL2にアップグレードしてみたに続く。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WSL2 + Ubuntu:18.04 + DockerCompose でCLI開発環境構築の備忘録

タイトル通り。

  • WSL2導入、設定。
  • Windows Terminal導入、設定。
  • Docker、DockerCompose導入。windows->WSL2へのポートフォワーディング設定
  • (その他)Dockerのユーザ定義ネットワークの謎の名前解決不具合対処。

WSL2導入

やった事がこちらの記事にほぼ載ってたので割愛。

完全新規に導入する場合は、WSL2の設定後に、CMDPowerShellから、wsl --set-default-version 2を実行後に、Microsoft Storeからインストールする。

WSL2設定

メモリ上限設定、localhostでの通信許可設定

デフォルトだと、WSL2が無限にメモリを食い尽くそうとしてきた。
あと、WindowsからWSL2環境にアクセスするときにlocalhostを使いたい。
C:\Users\<yourUserName>\.wslconfigをつくって、設定をする。

memory=2GBlocalhostForwarding=trueだけ作って、あとは未検証。

日本語化

WSL2関係ない普通のubuntuの日本語化だけど、一応。
Linuxの日本語化の仕組みを良く分かってないから、言われた通りにしただけ。

Ubuntu用ファイルへのショートカットを作成

\\wsl$\[ディストリビューション名]で、ディストリビューションのディレクトリを見る事が出来る。デスクトップにショートカットを作っておくと、何かと便利。

Windows Terminal導入

ここ
Microsoft謹製の、Linuxのターミナルっぽい奴。タブも分割表示もできるし、CMDPowerShellも一緒に扱えるんで、便利。
フォントも指定できるんで、Source Han Code JPを入れてみた。OSにインストールしてから、Windows Terminalの設定を選択するとひらくsettings.jsonprofiles: 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を開発中サービスの待ち受けポートに変更。
  • ついでにifconfigip 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では普通に名前解決が出来る。curlpinggit 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はほんと良いなぁ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Kubernetesのサーバ構成、アプリケーションの構成を基礎をまとめる

Kubernetesとは?

複数のホストを束ねてDockerを利用するためのオーケストレーションツール。
分散環境において、透過的にコンテナにアクセスすることができる。

Kubernetesの主な機能

  • 複数サーバでのコンテナ管理
  • コンテナ間のネットワーク管理
  • コンテナの負荷分散
  • コンテナの監視
  • 無停止でのアップデート

Kubernetesのサーバ構成

スクリーンショット 2020-05-31 11.31.23.png

マスターサーバ

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を付けて管理ができます。

参考

https://www.amazon.co.jp/dp/B017UGA7NG/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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
でエラーが解消された。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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 [オプション] マシン名

参考

https://www.amazon.co.jp/dp/B017UGA7NG/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ローカル 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-desktop

PVC はこちら

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: local-volume-claim
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: local-storage
  resources:
    requests:
      storage: 5Gi

ConfigMap

複数の 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 等も合わせて、階層構造化してみました

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 を定義して使う形になります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

注意

この対処方法はレジストリを編集します.というかゴッソリ削除します.
実行は自己責任でお願いいたします.

対処方法

  1. 実行中のDockerプロセスをKillする

  2. レジストリエディター(Regedit)を実行します
    Win + r で検索窓を開き,「regedit」で開きましょう.

  3. レジストリのバックアップを取ります.

    1. 「ファイル」→「エクスポート」
    2. 「エクスポート範囲」は「すべて」
    3. 適当な名前をつけて保存
  4. レジストリエディターの中で以下の階層へ移動します.
    Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

  5. 「Docker for Windows」や「Docker Desktop」のようなDockerに関するレジストリを全て削除します.
    ※目的以外の項目は削除しないように注意

  6. Dockerのインストーラを起動します.これでインストールできたら成功です.

あとがき

生半可な知識でファイルやディレクトリの削除は行っちゃだめですね.反省.

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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-alpine

Dockerfile

alpineベースで作っています

Dockerfile
FROM 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.yml
version: "3.0"

services:
  # FastAPI
  api:
    container_name: "api"
    build: .
    restart: always
    tty: true
    ports:
      - 8000:8000

必要なパッケージをまとめています

requirements.txt
uvicorn
fastapi

サンプルコード

FastAPIのドキュメントにあるサンプルコードを用意しました

main.py
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}

実行

$ docker-compose up -d --build

Docker 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にアクセスするとドキュメントを見ることが出来ます

http://localhost:8000/docs

キャプチャ.PNG

API叩いてみる

curlで叩くとこんな感じで返って来ます

結果
$ curl localhost:8000
{"Hello":"World"}

おわりに

今回はalpineベースで軽量な開発環境を構築してみました.

本家より3.6倍軽量になるので,使い捨てには十分な環境だとは思います.
最近ではNetflixを始め様々なプロジェクトでFastAPIが使われ始めているので,
まだ使っていない人は是非使って見てください!

参考サイト

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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-alpine

Dockerfile

alpineベースで作っています

Dockerfile
FROM 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.yml
version: "3.0"

services:
  # FastAPI
  api:
    container_name: "api"
    build: .
    restart: always
    tty: true
    ports:
      - 8000:8000

必要なパッケージをまとめています

requirements.txt
uvicorn
fastapi

サンプルコード

FastAPIのドキュメントにあるサンプルコードを用意しました

main.py
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
def read_root():
    return {"Hello": "World"}

実行

$ docker-compose up -d --build

Docker 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にアクセスするとドキュメントを見ることが出来ます

http://localhost:8000/docs

キャプチャ.PNG

API叩いてみる

curlで叩くとこんな感じで返って来ます

結果
$ curl localhost:8000
{"Hello":"World"}

おわりに

今回はalpineベースで軽量な開発環境を構築してみました.

本家より3.6倍軽量になるので,使い捨てには十分な環境だとは思います.
最近ではNetflixを始め様々なプロジェクトでFastAPIが使われ始めているので,
まだ使っていない人は是非使って見てください!

参考サイト

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む