進捗はありません

備忘録や研究メモ、日々の雑談や意見も

Kubernetes完全ガイド読了

TL;DR

  • Kubernetes初学者〜中級者には最適な本だと感じた
  • 基本的なk8sの説明から、helm,Prometheus,Spinnaker, Istioといった周辺サービスまで一通り網羅されており、この本から更に学習を進められる
  • 買ってよかった1冊。k8s学びたい人は買って損はない本だと思う

概要

  • 最近、業務でk8sを触ることが多くなってきて、今までなんとなくで触ってきたので改めて1から勉強し直そうと考え、この本に出会った

Kubernetes完全ガイド (impress top gear)

Kubernetes完全ガイド (impress top gear)

  • 自分のインフラ周りの知識で言うと、Dockerをちょっと触ったことある、くらいのものだった
  • もともとデータサイエンスをやるつもりで入社したが、データプロダクトのSREや基盤開発が楽しくなり、Jobチェンジ中といった感じの状況

この本のいいところ

  • k8sの概念の基本的なところはコードを書きながら理解できる
  • k8sデバッグやログ調査等のコマンドも丁寧に乗っているので、このあたりのコマンドは業務でも活かせる

この本には乗っていないこと

  • k8s周辺のOSSの細かい説明やチュートリアル
    • helmとかPrometheusとかそのあたりは、公式ドキュメントを読みながら進めたほうがいいかもしれない
    • ただ、この本でもサラッとは紹介されており、どんな問題を解決するためのOSSなのかみたいなことはつかめるはず
    • 2019/03/17現在、Istio on GKEがBetaになっており、この本のInstall方法ではなく、Istio-Enabledなclusterを利用して自分はIstioを試していた。実行自体は特に問題なかった

terraform google providerの2.0へのUpgradeでBigtableをふっ飛ばした話

TL;DR

  • bigtable_instancecontainer_node_poolの記法が大きく変わったから、同じResource名を利用して、variableで環境分けている場合は注意しよう
  • plan結果をしっかり見て、v2へ上げたときにresourceの再作成が行われないようにしよう

概要

terraform-google-providerのv2が正式にリリースされました www.terraform.io github.com

これにともなって、いくつかのResource定義の記法が変更されており、特に注意しなければならない変更があります。 それは、google_container_node_poolgoogle_bigtable_instanceです

google_container_node_poolについて

こちらで大きく変わったのは、name_prefixを利用できなくなったことです。

従来、以下のように記述していたものが

resource "google_container_node_pool" "example" {
  name_prefix               = "example-np-"
  zone                           = "us-central1-a"
  cluster                        = "${google_container_cluster.example.name}"
  node_count                = 1

  node_config {
    machine_type = "${var.machine_type}"
  }

  lifecycle {
    create_before_destroy = true
  }
}

prefixを利用する場合はrandom_idというリソースから名前を生成する形がGuideに記述されています

variable "machine_type" {}

resource "google_container_cluster" "example" {
  name               = "example-cluster"
  zone               = "us-central1-a"
  initial_node_count = 1

  remove_default_node_pool = true
}

resource "random_id" "np" {
  byte_length = 11
  prefix      = "example-np-"
  keepers = {
    machine_type = "${var.machine_type}"
  }
}

resource "google_container_node_pool" "example" {
  name               = "${random_id.np.dec}"
  zone               = "us-central1-a"
  cluster            = "${google_container_cluster.example.name}"
  node_count         = 1

  node_config {
    machine_type = "${var.machine_type}"
  }

  lifecycle {
    create_before_destroy = true
  }
}

これによって、従来の記法で定義されていたNode_poolと、v2の記法で書かれたNode_poolが同一のものではなくなり、再作成となります。 回避方法は、Variable等を利用して、すでに作成されているnode_poolの名前をhard codingしてnameを定義する必要があります

google_bigtable_instance

これが非常に厄介で、Guideを引用すると

resource "google_bigtable_instance" "instance" {
  name         = "tf-instance"
  cluster_id   = "tf-instance-cluster"
  zone         = "us-central1-b"
  num_nodes    = 3
  storage_type = "HDD"
}

のような記法が

resource "google_bigtable_instance" "instance" {
  name = "tf-instance"
  cluster {
    cluster_id   = "tf-instance-cluster"
    zone         = "us-central1-b"
    num_nodes    = 3
    storage_type = "HDD"
  }
}

このような変更となり、clusterのfield内に定義するようになりました。

これだけならまぁ、対応可能な範疇です。

しかし問題なのは、instance_typeを定義していた場合です。

例えば、v1のときに、以下のような記法で開発環境と本番環境を作成していたとします


# dev.tfvars
bigtable = {
  instance_type = "DEVELOPMENT"
  num_nodes = "0"
}
# prod.tfvars
bigtable = {
  instance_type = "PRODUCTION"
  num_nodes = "3"
}
### この2つを環境ごとに切り分けて読み込む
variable bigtable {
  type = "map"
  default = {
    instance_type = "OVERWRITE"
    num_nodes = "OVERWRITE"
  }
}

resource "google_bigtable_instance" "instance" {
  name         = "tf-instance"
  instance_type = "${var.bigtable["instance_type"]}"
  cluster_id   = "tf-instance-cluster"
  zone         = "us-central1-b"
  num_nodes    = "${var.bigtable["num_nodes"]}"
  storage_type = "HDD"
}

ところが、v2系ではDEVELOPMENTの場合、そもそもnum_nodesを定義してはいけません。以下、公式抜粋

num_nodes - (Optional) The number of nodes in your Cloud Bigtable cluster. Required, with a minimum of 3 for a PRODUCTION instance. Must be left unset for a DEVELOPMENT instance.

つまり、このように定義していた場合、devとprdでresourceを2つ定義しなければなりません。


# dev.tfvars
bigtable = {
  instance_type = "DEVELOPMENT"
}
# prod.tfvars
bigtable = {
  instance_type = "PRODUCTION"
  num_nodes = "3"
}
### この2つを環境ごとに切り分けて読み込む
### countを利用して、条件分岐させる
variable bigtable {
  type = "map"
  default = {
    instance_type = "OVERWRITE"
    num_nodes = "OVERWRITE"
  }
}

resource "google_bigtable_instance" "instance" {
  count = "${var.bigtable["instance_type"] == "PRODUCTION" ? 1 : 0}"  

  name          = "tf-instance"
  instance_type = "${var.bigtable["instance_type"]}"

  cluster {
    cluster_id   = "tf-instance-cluster"
    zone         = "us-central1-b"
    num_nodes    = "${var.bigtable["num_nodes"]}"
    storage_type = "HDD"
  }
}

# devはnum_nodesを定義しない
resource "google_bigtable_instance" "instance_dev" {
  count = "${var.bigtable["instance_type"] == "DEVELOPMENT" ? 1 : 0}"  
  
  name          = "tf-instance"
  instance_type = "${var.bigtable["instance_type"]}"

  cluster {
    cluster_id   = "tf-instance-cluster"
    zone         = "us-central1-b"
    storage_type = "HDD"
  }
}

同一resourceは定義できないので、devとprodで2つのresourceを定義します。 そうなると、resource名が変更として扱われ、同一のnamecluster_idだったとしても再作成となります。(これを見逃していてふっ飛ばしました。しっかりplan見ようねって話なのですが...) 上記の例の場合、prodはresource名を変更していないので、changed扱い、devは新規作成及び旧instanceの削除となります。

オレ的開発環境管理(Docker)

個人のPCの開発環境の管理ってどうしてますか?

Dockerを利用して複数人の開発環境を統一できたり、簡単に環境を再構築したりWebアプリのテストができたりと、Dockerの開発環境の恩恵を大いに受けています。
個人での開発や分析でも特にこの恩恵は強く、どのマシンでも、例えばPythonやRの分析環境を持ち歩いたり、jupyterのextensionも含めてimageにしてしまえば本当に分析環境をまるっと持ち出せるのが便利でずっとDocker使ってますが、しばしばこんな問題にあたりませんか?

MacWindowsのvolume周りのコマンドが違ってつらい

例えば、Docker for Macでは、

docker run -v ./:/home/user/ <image>

のような指定で簡単にカレントディレクトリとコンテナのデータ共有ができると思いますが、Docker for windowsだとどうでしょうか。ご存知の方も多いでしょうが、これでは動きません。Windows(cmd)でカレントディレクトリの共有をしようとすると、基本的にフルパスを指定します(C:hogehogeみたいな感じで)
これ、めちゃくちゃ不便ですよね。私は家だとWindowsがメインで、研究室だとMacなので、同じDockerfileやdocker-composeでも、volume周りだけどうしても環境の統一ができない状態でした。

現在の開発/分析環境の管理方法

簡単にいうと、Makefileを使ってMacでもWindowsでも動くコマンドを管理して、make経由でコマンドを実行するようにしています。

分析環境の管理例(python)

ディレクトリ構成

workspace/
      ├Dockerfile
      ├dev.mk

まずはDockerfile。個人の設定そのまま入れているので、 パッケージ群とjupyterのextension設定を反映している。 パッケージとして注意していることは、tensorflowが入っていることでこれはインストール順でnumpy等の依存関係が上書きされるため、tensorflowだけ最後にインストールするようにしている。 個人の開発環境なのでrootで使っているが、外部サーバーに置く場合などはuserやセキュリティ設定は変えてます。

FROM python:3.6

MAINTAINER kyo-bad

RUN apt-get update \
    && apt-get install -y screen vim \
    && pip3 install --upgrade pip \
    && pip3 install --upgrade jupyter pandas matplotlib seaborn scikit-learn jupyter_nbextensions_configurator jupyterthemes \
    && pip3 install --upgrade tensorflow \
    && jupyter nbextensions_configurator enable --user \
    && git clone https://github.com/lambdalisue/jupyter-vim-binding $(jupyter --data-dir)/nbextensions/vim_binding \
    && jt -t monokai -T -N -altmd -vim

WORKDIR /root/workspace

続いて、dev.mkというmakefileを作成する。中身はこんな感じ

.PHONY: build run docker/*

WORK_DIR := $(CURDIR)
LOG_DIR := $(CURDIR)

BUILDER_IMAGE := python:myenv
BUILDER_WORK_DIR := /root/workspace
BUILDER_CMD := docker run --rm -it -v $(WORK_DIR):$(BUILDER_WORK_DIR) -w $(BUILDER_WORK_DIR) -p 6006:6006 -p 8888:8888 $(BUILDER_IMAGE)

setup:
  docker build -t $(BUILDER_IMAGE) .

rebuild-image:
  docker rmi $(BUILDER_IMAGE)
  docker build -t $(BUILDER_IMAGE) .

attach:
  $(BUILDER_CMD) bash

jupyter:
  $(BUILDER_CMD) jupyter notebook --ip 0.0.0.0 --no-browser --port 8888 --allow-root

tensorboard:
  $(BUILDER_CMD) tensorboard --logdir=$(LOGDIR)

Makefileで管理することのメリット

WIndowsでもMacでも同じコマンドで動く

これが一番大きいです。カレントディレクトリを共有する場合のコマンドの違いを、makeのCURDIRで隠蔽することで参照方法を統一している。 注意点としては、WORK_DIRをユーザのホームディレクトリにしてはいけないこと。これは、volume共有によってbashのログとかドットファイル類がホストにも共有されてしまうため。

長ったらしいコマンドを打たなくていい。

例えば、イメージのビルドだったら、

make -f dev.mk setup

これでいいし、jupyterの起動だったら

make -f dev.mk jupyter

でホストにサーバが立ち上がる。

angularでも似たような管理をしているので参考までに

Dockerfile(dev)

FROM node:8-alpine

MAINTAINER kyo-bad

RUN apk update \
    && apk add --no-cache --update alpine-sdk build-base python yarn \
    && yarn cache clean \
    && yarn global add @angular/cli@1.6.6 \
    && ng set --global packageManager=yarn \
    && apk del alpine-sdk \
    && rm -rf /tmp/* *.tar.gz ~/.npm \
    && yarn cache clean \
    && adduser -D appuser

COPY --chown=appuser:appuser project /home/appuser/app
ENV HOME=/home/appuser
USER appuser
WORKDIR ${HOME}/app
CMD [ "yarn && ng serve --host 0.0.0.0" ]

Makefileは以下

.PHONY: build run new yarn serve docker/* 

BUILDER_IMAGE := angular-yarn-alpine:myenv
BUILDER_WORK_DIR := /home/appuser/app
BUILDER_APP_NAME := app
BUILDER_CMD := docker run --rm -it -v $(CURDIR)/$(BUILDER_APP_NAME)/$(BUILDER_APP):$(BUILDER_WORK_DIR) -w $(BUILDER_WORK_DIR) -p 4200:4200 $(BUILDER_IMAGE)

setup:
  docker build -t $(BUILDER_IMAGE) .

rebuild-image:
  docker rmi $(BUILDER_IMAGE)
  docker build -t $(BUILDER_IMAGE) .

new:
  docker run --rm -v $(CURDIR):$(BUILDER_WORK_DIR) -w $(BUILDER_WORK_DIR) $(BUILDER_IMAGE) ng new $(BUILDER_APP_NAME) --routing

yarn:
  $(BUILDER_CMD) yarn

serve:
  $(BUILDER_CMD) ng serve --host 0.0.0.0 --poll 2000

attach:
  $(BUILDER_CMD) sh

Container SIG Meet-up 2017 Fallに参加してきました

10/31に行われた、Container SIG Meet-upに参加してきました。

connpass.com

twitter.com

個人の開発環境やクラウドでコンテナを動かしたりして遊んでいて、コンテナ技術に興味を持ったのがきっかけでした。「俺の環境では動く」問題を解決するために使っているだけなので、超にわかではありましたが、面白い話が聞けて良かったです。

DockerとKubernetesとRancher当たりの話から、DC/OSの話まで聞けて、自分でももう少し勉強してみようと思いました。 アプリ開発側として、

Tori (@toricls) | Twitter

この方の話は参考になりました(話が上手いっていうのもあるが)。自分はAnsibleを使っているが、確かにべき等性保つコードが書けているかとか非常に気を使うが、そんなことしなくても、Vagrant+VirtualBoxでContainer Linux(CoreOS)のVMを一枚ラップして、コンテナで環境を作ることでWinでもMacでもどこでも同じ環境かつ継続的なアップデート対応などができるって話で、私も今からローカル開発環境を見直そうと思っている (研究室の環境も一度見直したほうがいいかもしれん...)

わかっている範囲での関連資料一覧

www.creationline.com

qiita.com

www.slideshare.net

www.slideshare.net

www.slideshare.net

speakerdeck.com

github.com

github.com

初海外(学会です)

先週は、イタリアで行われたMMEDIA2017という学会で発表してきました。

https://www.iaria.org/conferences2017/MMEDIA17.html

就活とインターンバイトと学会の準備で、非常に忙しい中、つかの間の休息という感じで、イタリアで羽を伸ばしてきました(もちろん学会も参加してました)

実は、これが私にとっての初海外だったので、海外経験が豊富な先生方と行けたのは、とてもありがたかったと思います。

 

今回、初の国際学会だったわけですが、これを機会に、学生の金銭事情について率直な感想を話そうと思う

 

今回初めて国際会議に参加して思ったのだが、とにかくお金がかかる。航空券で約20万円、学会参加費やホテル代で約15万円、その他諸々考えると、40万円近くのお金がかかる訳だ。

指導教員は、国際会議に行け行けと言う訳だが、どうも学生の金銭事情を理解していないようだった。学生カードなんて、普通は上限10万円程度で、上限なんてあっという間にオーバーしてしまう。航空券すら買えない始末だ。私は上限引き上げでなんとか対応したが、それでも、学生に40万近くの額を建て替えろなんて、普通は無理な話だ。

もちろん、学会でのお金は大学から支給されるが、それは原則後払いだったので、どうしようかと悩み、大学の会計課に相談したところ、前払い制度があるというのをそこで初めて知った。

今回は大学からの前払いの振込とクレジットカードの引き落とし日のタイミングが良かったので、なんとかなったが、この制度を知らなかったらおそらく学会にも行けなかっただろう。

このような、金銭的なバックアップ体制があることは学生にはしっかり言ってほしかったし、先生の金銭感覚で物事を進めないでほしかったというのが今回の学会参加で思ったことだった。

 

もちろん、英語での発表経験や海外経験は、非常に自分にとって素晴らしいものになったので、そこに関してどうこう言うことはない。

 

ただ、研究以外の障害になりうるものへの対応と言うものを、国際会議未経験の学生が知っているわけもないので、その辺りの理解とサポートを、今後海外に行く後輩たちに少しでもできたらいいなと思うことができた経験でした。

 

少し愚痴っぽくなってしまったので、最後に観光の写真でも

 


f:id:kyo-bad:20170430163716j:image

ベネチア。今回の会場

 


f:id:kyo-bad:20170430163807j:image

イタリアといえばパスタ(貝にパスタを添えてと言った感じだったが)


f:id:kyo-bad:20170430165110j:image

こちらも同じく、貝にパスタを添えた料理

 
f:id:kyo-bad:20170430165203j:image

カンファレンスディナーで、よくわからないけど地元の民謡的なのを聞いた

 
f:id:kyo-bad:20170430165235j:image

イタリアで中国人がやっている日本食料理屋というダイバーシティに溢れた店にトライしてみたが、案外普通だった

 
f:id:kyo-bad:20170430165332j:image

夜のメストレ。おしゃれ

宇宙科学情報解析シンポジウムに参加

2月10日に行われた宇宙科学情報解析に参加してきました

平成28年度宇宙科学情報解析シンポジウムプログラム

情報分野と惑星科学を融合した研究を幅広く発表できる場です。

発表について

このシンポジウムのメインはやはり惑星科学の人たちで、情報を専攻とする人は私たちだけでした。

結論からいうと、惑星科学の人たちに厳しい意見を多数いただきました。

物理的解釈や導出を意識した応用を行わないと、機械学習等を用いても惑星科学には貢献できないということを痛感させられました

懇親会について

懇親会では様々な方にアドバイスをもらえました。(なぜか就活相談乗ってくれたりしてくれた)

尊敬できる方々から有意義な話が聞けて満足でした(11時近くまで結局飲んでた)

Docker for Windowsでのvolumeマウント問題にぶち当たっている

Docker for mac では動くのに Docker for Windows では動かない件について

Dockerを使い始めて数か月がたつが、Docker for macでは動くのにDocker for Windowsではエラーをはいてコンテナが停止するようなものが何件かある。 そのほとんどが、volumeのマウントに関してだ。

postgresやmysqlのデータ永続化のために、ホストにマウントする際にエラーが起こる 例えば、このようなdocker-composeを起動するとする(Redmineサーバの立ち上げ)

version: '2'

services:
  redmine:
    image: redmine
    ports:
      - 8080:3000
    environment:
      REDMINE_DB_MYSQL: db
      REDMINE_DB_PASSWORD: example
    volumes:
        - ./redmine-data/redmine:/usr/src/redmine/files
    depends_on:
      - db
    restart: always

  db:
    image: mysql
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: redmine_db
    volumes:
        - ./redmine-data/db:/var/lib/mysql
    restart: always

これがとにかく意味不明なログをはいて止まる。 Macだと問題なく動くのにWindowsだと止まってしまう

こちらも止まる

FROM kyobad/anaconda3-alpine

MAINTAINER K.Kato

RUN conda install -y seaborn psycopg2 networkx\
&& pip install chainer \
&& conda install -y -c https://conda.anaconda.org/andrewannex spiceypy

WORKDIR /root/notebook

CMD ["/bin/sh", "-c", "jupyter notebook --no-browser --port=8888 --ip=0.0.0.0"]
version: '2'
services:
    db:
        image:
            postgres
        restart:
            always
        environment:
            POSTGRES_USER:
                pythonist
            POSTGRES_PASSWORD:
                password
            POSTGRES_DB:
                mypyenv
        ports:
            - "5432"
        container_name:
            postgres-db
        volumes:
            - ./postgres-db:/var/lib/postgresql/data
            - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
    python:
        build: .
        volumes:
            - ./workdir:/root/notebook/
        ports:
            - "8888:8888"
        links:
            - db
        depends_on:
            - db

こちらはownerが違うと怒られる。

postgres-db | HINT:  The server must be started by the user that owns the data directory.
postgres-db | FATAL:  data directory "/var/lib/postgresql/data" has wrong ownership
postgres-db | HINT:  The server must be started by the user that owns the data directory.
postgres-db | FATAL:  data directory "/var/lib/postgresql/data" has wrong ownership
postgres-db | HINT:  The server must be started by the user that owns the data directory.
postgres-db | FATAL:  data directory "/var/lib/postgresql/data" has wrong ownership
postgres-db | HINT:  The server must be started by the user that owns the data directory.
postgres-db exited with code 1

ほかにも、Permission deniedであったり、httpsがどうのこうのみたいなエラーをはいて止まったり、 Macで問題なく動くものがWindowsでは動かないという現象が多々見られる。 githubのissueにもこれらのことが結構上がったりしているみたいなので、まだ改善はされてない...? github.com

現状、Dockerで困りたくないならMac使ったほうが無難なのかな...