headless serviceを使ってVIPを使わずに各podのIPに直接アクセスする

kubernetesはserviceの仕組みの中でVIPを使って背後の複数podへのルーティングを管理していて、多くのケースではよしなにやってくれるので便利なのだが、以前Nettyを使ってservice間のコネクションを管理していて、背後にある複数podへの接続が偏る問題に悩んでいた。やりたいこととしては、背後のpod達に完全に均等に接続を振りたいのに、serviceを使うとランダム要素を排除することができず、一定の確率でコネクションがかたよってしまう。

そのときは接続数を増やす(たとえば3バックエンドに対して3コネクションだとどこかに偏ってしまう可能性大だが、3バックエンドに対して300コネクションはれば平均に回帰するのでだいたい均等になる)&一定時間ごとに接続を貼り直すという対策をとったが、headless serviceを使う手もあるというのを最近知った。

きっかけとしてはこの記事で、gRPCも似たような問題に遭遇することがある。

Kubernetes上でgRPCサービスを動かす | SOTA

  • 公式ドキュメント

kubernetes.io

  • headless serviceについて(日本語)

qiita.com

上記の記事を読むと、serviceのclusterIPをNoneで起動すればheadless serviceになるみたいなので、試してみた。

まずは普通にサービスを起動する場合。

ローカルのminikubeを立ち上げておいて、

minikube start
helm init

ingress controller + バックエンドnginxの組み合わせの公式のhelm chartで試してみる

helm install stable/nginx-ingress --set defaultBackend.replicaCount=3

ingress-controllerのpodが1つ、backendのpodが1つできている。

ᐅ kubectl get pods                                                                                                                                                        
NAME                                                              READY     STATUS    RESTARTS   AGE
opinionated-saola-nginx-ingress-controller-7b64bf5b74-gk6pw       0/1       Running   0          9s
opinionated-saola-nginx-ingress-default-backend-759d876cd-pkgsr   1/1       Running   0          9s
opinionated-saola-nginx-ingress-default-backend-759d876cd-sbdnr   1/1       Running   0          9s
opinionated-saola-nginx-ingress-default-backend-759d876cd-zr8ng   1/1       Running   0          9s
ᐅ kubectl get services                                                                                                                                                     
NAME                                              TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
kubernetes                                        ClusterIP      10.96.0.1        <none>        443/TCP                      15m
opinionated-saola-nginx-ingress-controller        LoadBalancer   10.100.231.194   <pending>     80:32561/TCP,443:32723/TCP   24s
opinionated-saola-nginx-ingress-default-backend   ClusterIP      10.97.231.34     <none>        80/TCP                       24s

今回はClusterIPが貼られているのでheadlessではない。この場合はnslookupで引いてもClusterIPが返ってくる。

# nslookup opinionated-saola-nginx-ingress-default-backend
Server:     10.96.0.10
Address:    10.96.0.10#53

Non-authoritative answer:
Name:   opinionated-saola-nginx-ingress-default-backend.default.svc.cluster.local
Address: 10.97.231.34

次にheadless serviceで起動した場合。

helm install stable/nginx-ingress --set defaultBackend.replicaCount=3 --set defaultBackend.service.clusterIP=None

backendのClusterIPをNoneにした。

ᐅ kubectl get service                                                                                                                                                      
NAME                                         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
kubernetes                                   ClusterIP      10.96.0.1       <none>        443/TCP                      19m
original-pig-nginx-ingress-controller        LoadBalancer   10.108.233.23   <pending>     80:30045/TCP,443:30788/TCP   6s
original-pig-nginx-ingress-default-backend   ClusterIP      None            <none>        80/TCP                       6s
# nslookup original-pig-nginx-ingress-default-backend
Server:     10.96.0.10
Address:    10.96.0.10#53

Name:   original-pig-nginx-ingress-default-backend.default.svc.cluster.local
Address: 172.17.0.5
Name:   original-pig-nginx-ingress-default-backend.default.svc.cluster.local
Address: 172.17.0.6
Name:   original-pig-nginx-ingress-default-backend.default.svc.cluster.local
Address: 172.17.0.8

この場合には、3つのアドレスが返ってくる。

headless serviceを使えば各podのIPに直接アクセスできるので、接続の偏りの問題があるときに、クライアント側での対処方法として使えそう。

人工知能が金融を支配する日

人工知能が金融を支配する日

人工知能が金融を支配する日

金融が人工知能によって大きく変わる、という本にタイトルテーマ真正面の内容も扱われている一方で、海外のロボトレーダーの進化に対して日本社会としてどう対峙すべきかというような社会への提言も書かれている。筆者は東京銀行出身の理工系出身の数理ファイナンスの専門家で、その立場を色濃く反映したような内容になっている。

直近、金融分野を仕事としてやる予定はないのだけど、金融はAIがもっとも劇的に業界を変えていっている業界であること、その流れはいずれマーケティングの世界にも来るであろうこと、 また、個人的に投資を少し始めたこともあって、業界の動向には興味がある。RTBが金融取引を参考にして生まれたように、新たなモデルが広告に持ち込まれる日がそう遠くない日に来るだろうと思っている。

この分野の本というと、「フラッシュ・ボーイズ」の印象が強くあるが、本書も分野的にはかぶっていて、米国や英国のヘッジファンドが、数学・統計・ITの技術を駆使して大きな利益をあげて成長している動向を時系列にまとめてくれている。技術にも詳しいため、AI関連の個々の手法や定義も整理されてわかりやすく書かれていて、その点はすごくよかった。

例えば、ベイズ推定とは何かを考えたときに、定義としては

ベイズ推定(ベイズすいてい、英: Bayesian inference)とは、ベイズ確率の考え方に基づき、観測事象(観測された事実)から、推定したい事柄(それの起因である原因事象)を、確率的な意味で推論することを指す。

(出典:Wikipedia

というような感じで、けっこう一言でいうのが難しいというか、腑に落ちる端的な説明というのが難しい。 本書では、

適当に設定した事前分布から出発して実際の観測値を使って、推定の精度を徐々に上げていくことによって、最終的に精度の高い推定値にたどり着くというのがベイズ推定の神髄です。

というように、ある一面でやや言い過ぎ感はあるものの、それを読者が自分の中で咀嚼する余裕がある前提とすれば、腑に落ちる説明がうまいというか、すっと頭に入ってくる説明が多くて良書だと思った。

話題は金融に閉じておらず、チューリングエニグマの話があったり、ワトソンやアルファ碁にも触れられていたりと、AIや機会学習のメジャーなテーマをさらってくれているので、その中での金融のポジションという感じで俯瞰的に見れて良い構成だと感じる。

後半は人間の仕事がロボットに代替されるという話から、日本が(特に金融分野について)そのへんの進歩についていけてないという展開になり、縦割りな会社文化への批判や過去の護送船団方式の反省もされる。そこに微妙な距離を置いての記述は、東京銀行出身で、三菱東京UFJ銀行に買収された過去と、筆者がソニーに転職しソニー銀行設立にも関わっている経歴と深くリンクしている気がしながら読んだ。

むすびとしての筆者の主張は、一部のヘッジファンドが技術とそこからあがる利益を独占する未来ではなく、公共的な方向に技術が活用される未来に期待するというものとなっている。ただ、そこで日本のとるべき道として、オールジャパン的な横の連帯と制度づくりが重要という主張だったのは違和感があった。金融は法律の縛りもきついだろいうから、そういう文脈では官民共同の取り組みが必要というのもわかるが...。

機械より人間らしくなれるか?

機械より人間らしくなれるか?: AIとの対話が、人間でいることの意味を教えてくれる

機械より人間らしくなれるか?: AIとの対話が、人間でいることの意味を教えてくれる

チューリング・テストに関するエピソードを軸に、コンピュータと比較したときの「人間らしさ」について考える本。 Amazonのレビューにも近い意見があるが、雑多なエピソードが無秩序に散りばめられている印象を受ける。 個々のエピソードはそれなりに面白いが、本の中で中心のテーマとどれくらい関わってくるのかが不明だし、たとえもわかりにくい。 第5章あたりで読むのを中断。

MacOS SierraでSSHのパスフレーズをキーチェーンに保存させる

Sierraを使っていると、SSH接続するときに毎回パスフレーズ入力を求められる。 以前のOSでは自動でやってくれたはずなのに。

h2ham.net

www.reddit.com

.ssh/configで下記の行があればOK。

AddKeysToAgent yes
UseKeychain yes

カイゼン・ジャーニー

スクラムの本はいくつか読んでいるが、この本は最近出版されて、Kindleで体験版を読んでみたら面白かったので読んだ。

数あるスクラムの本の中でも、ストーリー仕立てになっていること、日本の開発会社の現場を舞台にしたストーリー仕立てになっていて、親しみやすかった。2018年2月に出たばかりの本ということもあって、モブプロなどの比較的新しい?トピックまで含んでいる。 ただ、多くの要素をストーリーの中にいれようとするあまり、無理矢理感が多少出てしまっているのが苦笑したポイント。

いくつか印象に残った部分をメモ。

重要度x緊急度のマトリックス

f:id:road288:20180326081423p:plain

「緊急度が低いが、重要なもの」に取り組めるよう時間をつくる。

建設的相互作用(constructive interaction)

2人で考えることで、理解が促進される 「他者と一緒に考えて理解が進む」建設的相互作用について調べてみた - 学んだことの記録

学習する組織(氷山モデル)

f:id:road288:20180326083138p:plain

出来事はパターンから発生し、パターンには構造が存在し、根底にはメンタルモデルがある。 何か問題が起きたときは、事象だけを見るのではなく、背後にある構造や、メンタルモデルを考える。

それぞれの持ち場でがんばれ。

スクラム関係ないんだけれど、いま自分が置かれた状況に思いを馳せて思い出した。 自分が高校生のときに教えてもらった近い(ようで違うけど)言葉が、「自分で落とし前つけろよ」。

むきなおり

f:id:road288:20180326083122p:plain

  • ふりかえりは、過去を顧みて現在を正す
  • むきなおりは、進むべき先を捉えて現在を正す 大きく変えないといけないときはふりかえってばかりでもダメ。むきなおりが必要

リードタイムとプロセスタイム

最近これがポイントだと気付かされることが多かった。

  • プロセスタイム:事実上そのプロセスを実行している作業時間(=実作業時間)
  • リードタイム:プロセスが次のプロセスに移行するまでの所要時間(≒待ちの時間を含む)

JavaでスレッドとかメソッドのCPU使用率見るときも同じだが、分けて考える必要がある。

ECRS

  • Eliminate
  • Combine
  • Rearrange
  • Simplify

価値と原則

 

価値

  • 越境
  • 自分たちから始める
  • フィードバック
  • フレーミング
  • 巻き込み巻き込まれる

原則

  • 思考
    • Whyから始めよ
    • 自分は何者か
    • 意味を問う
    • 視座を変える
    • 制約から捉える
    • 思いやりファースト
  • チーム

    • 全員で考え抜く
    • 共通認識を持つ
    • みんなのゴールを決める
    • 自分たりでやり方もあり方も変える
    • お互いに学ぶ
    • 期待マネジメント
    • みんながヒーロー
  • 時間

    • リズム
    • 遅すぎるということはない
    • 見直すことをいとわない
    • 立ち止まって考える
    • 時間を味方につける
  • プロセス
    • 見える化
    • 全体を俯瞰する
    • 小さく試みる
    • 一個流し
    • 分割統治
    • 外に出る
    • 場をつくる
    • 全員同席

ネットワーク経済の法則

内藤さんのおすすめ本ということで読み始めた。

「ネットワーク経済」の法則―アトム型産業からビット型産業へ…変革期を生き抜く72の指針

「ネットワーク経済」の法則―アトム型産業からビット型産業へ…変革期を生き抜く72の指針

  • 作者: カールシャピロ,ハル・R.バリアン,Carl Shapiro,Hal R. Varian,千本倖生,宮本喜一
  • 出版社/メーカー: IDGコミュニケーションズ
  • 発売日: 1999/06
  • メディア: 単行本
  • 購入: 2人 クリック: 33回
  • この商品を含むブログ (26件) を見る

第2章あたりまで進んで、そこから進まず、いったん返却。 百科事典について述べているところで、Microsoftが出した百科事典がブリタニカのそれを凌駕して置き換わったみたいな話が書いてあって、いまはWikipediaの時代になっているので、時代の流れを感じた。

もう20年近く前に書かれた本なので、古く感じるのは当然だが、法則としては現在でも有効なものがある。 また気が向いたら読むのを再開したい。

helmを使ってminikube上にcoucourseを起動する

新しいミドルウェアを触ってみたい場合、まず実際に動かしてみたいと思うことが多いけど、minikubeはそれを実現するツールとして便利そうだった。 今回はそれをさらに進めて、helmを使ってみる。

いま仕事で使っているconcourseで試してみた。

まず前回の分を消してから

ᐅ minikube delete

再度新規作成する。

ᐅ minikube start
Starting local Kubernetes v1.9.0 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.

helmを初期化する。これによってtillerというpodがkube-system ネームスペースの中に作成される。これがk8sクラスタ内でhelmを管理しているみたい。

ᐅ helm init         
$HELM_HOME has been configured at /Users/xxx/.helm.

Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Happy Helming!

helmの個々のパッケージのことをchartというが、

Charts are packages of pre-configured Kubernetes resources.

chartはk8sのリソースをまとめてパッケージ化して、これをinstallすることで、あるパッケージをそのまま利用可能にするための1つのまとまり、みたいなイメージでよさそう。

concourseのhelm chartは公式にある。

github.com

公式によると

helm install stable/concourse

これだけで実行できそうだが、実際にMacのminikube上でやると失敗する。

ᐅ helm install --name concourse stable/concourse

Error: release concourse failed: clusterroles.rbac.authorization.k8s.io "concourse-web" is forbidden: attempt to grant extra privileges: [PolicyRule{Resources:["secrets"], APIGroups:[""], Verbs:["get"]}] user=&{system:serviceaccount:kube-system:default 788772bb-27fb-11e8-96cb-0800274e6818 [system:serviceaccounts system:serviceaccounts:kube-system system:authenticated] map[]} ownerrules=[] ruleResolutionErrors=[]

RBACの関係でうまくいかないらしい。

RBACとは https://kubernetes.io/docs/admin/authorization/#rbac-mode このへんなのだろうが、ひとまずアクセス権限周りは使わずに試したいので、values.ymlを編集して起動する。

https://github.com/kubernetes/charts/blob/master/stable/concourse/values.yaml#L506

このファイルを落としてきて、rbacをenableにしているこの行をfalseにする。

これで起動する。

ᐅ helm install --name concourse -f values.yaml stable/concourse

NAME:   concourse
LAST DEPLOYED: Thu Mar 15 12:58:16 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/Service
NAME                  TYPE       CLUSTER-IP   EXTERNAL-IP  PORT(S)            AGE
concourse-postgresql  ClusterIP  10.106.7.53  <none>       5432/TCP           0s
concourse-web         ClusterIP  10.97.28.26  <none>       8080/TCP,2222/TCP  0s
concourse-worker      ClusterIP  None         <none>       <none>             0s

==> v1beta1/Deployment
NAME                  DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
concourse-postgresql  1        1        1           0          0s
concourse-web         1        1        1           0          0s

==> v1beta1/StatefulSet
NAME              DESIRED  CURRENT  AGE
concourse-worker  2        2        0s

==> v1beta1/PodDisruptionBudget
NAME              MIN AVAILABLE  MAX UNAVAILABLE  ALLOWED DISRUPTIONS  AGE
concourse-worker  1              N/A              0                    0s

==> v1/Pod(related)
NAME                                   READY  STATUS             RESTARTS  AGE
concourse-postgresql-664df7c4cc-4nzc8  0/1    ContainerCreating  0         0s
concourse-web-7f45c95c94-zthqq         0/1    ContainerCreating  0         0s
concourse-worker-0                     0/1    ContainerCreating  0         0s
concourse-worker-1                     0/1    ContainerCreating  0         0s

==> v1/Namespace
NAME            STATUS  AGE
concourse-main  Active  0s

==> v1/Secret
NAME                  TYPE    DATA  AGE
concourse-postgresql  Opaque  1     0s
concourse-concourse   Opaque  7     0s

==> v1/PersistentVolumeClaim
NAME                  STATUS  VOLUME                                    CAPACITY  ACCESS MODES  STORAGECLASS  AGE
concourse-postgresql  Bound   pvc-172f7f10-2805-11e8-96cb-0800274e6818  8Gi       RWO           standard      0s


NOTES:

* Concourse can be accessed:

  * Within your cluster, at the following DNS name at port 8080:

    concourse-web.default.svc.cluster.local

  * From outside the cluster, run these commands in the same shell:

    export POD_NAME=$(kubectl get pods --namespace default -l "app=concourse-web" -o jsonpath="{.items[0].metadata.name}")
    echo "Visit http://127.0.0.1:8080 to use Concourse"
    kubectl port-forward --namespace default $POD_NAME 8080:8080

* Login with the following credentials

  Username: concourse
  Password: concourse

* If this is your first time using Concourse, follow the tutorial at https://concourse.ci/hello-world.html

*******************
******WARNING******
*******************

You are using the "naive" baggage claim driver, which is also the default value for this chart. This is the default for compatability reasons, but is very space inefficient, and should be changed to either "btrfs" (recommended) or "overlay" depending on that filesystem's support in the Linux kernel your cluster is using. Please see https://github.com/concourse/concourse/issues/1230 and https://github.com/concourse/concourse/issues/1966 for background.

podの存在を確認。

ᐅ kubectl get pods                                                                                
NAME                                    READY     STATUS              RESTARTS   AGE
concourse-postgresql-664df7c4cc-4nzc8   1/1       Running             0          46s
concourse-web-7f45c95c94-zthqq          0/1       ContainerCreating   0          46s
concourse-worker-0                      0/1       ContainerCreating   0          46s
concourse-worker-1                      1/1       Running             0          46s

port-forwardでつないでみる。

ᐅ export POD_NAME=$(kubectl get pods --namespace default -l "app=concourse-web" -o jsonpath="{.items[0].metadata.name}")
ᐅ kubectl port-forward --namespace default $POD_NAME 8080:8080 
Forwarding from 127.0.0.1:8080 -> 8080
Handling connection for 8080
Handling connection for 8080
Handling connection for 8080
Handling connection for 8080

http://localhost:8080にアクセス。 デフォルトのID/Passはvalues.yamlのにも書いてあったが、concourse/concourseでログインできる。

f:id:road288:20180315132652p:plain

この後はflyコマンドを使って実際にパイプラインを作ってみる。