だいごろうのブログ

熊本出身で大阪、東京、パリを転勤して、今は福岡でデータエンジニアです

[MEMO] katacodaでLearn Kubernetes ver7 Kompose / Helm + Helm周りを調べてみた

今回は、kubenetesのyamlの管理ツール系の話。KomposeとHelmを読んで見てる。

www.katacoda.com

https://github.com/kubernetes/kompose/releases

Kompose

docker-compose.yamlを用意し

kompose up

kompose upをすると自動で、kubernetesにそのdocker-composeにかかれている deployment,svc,pods,pvcなどを作成する。

kompose convert

kompose convertを利用することにより、 kubernetesyamlファイルに変換してくれる。

kompose --provider openshift convertこのようにして他のproviderをサポートすることも可能みたい。

Helm

標準的なkubernetesのいくつかのパッケージ(charts)を簡単にkubernetesで実行できるようなものかな?結構ないろいろな会社とコミュニティが運営してるみたいで、今後の発展性も良さそうだな。

www.katacoda.com

helm search {SEARCH_WORD}

chartsを検索する。

helm inspect {NAME}

対象のchartsの詳細を見る

helm install {NAME}

対象のchartsをkubernetes上で起動する。

helm ls

今helmから実行しているPodを確認

Helm in github

なんか、よくわからんから、githubを訳していく。 https://github.com/kubernetes/helm/releases

Helm Docs | Helm


HelmはKubernetesのchartsを管理するツール. Chartsはpre-configured Kubernetes resourcesのパッケージです.

こういったケースに使います。

  • よくあるパターンのソフトウェアのパッケージをHelm chartsでKubernetes上で実行したいとき
  • Helm chartsで自分のアプリをシェアしたいとき
  • Kubernetesのアプリケーションを再現可能なbuildにしたいとき。
  • かしこくKubernetesマニフェストを管理したい
  • Helm packagesを管理したい

Helmは Kubernetesのapplicationsの管理とインストールを簡略化するツールです。apt/yum/homebrewのKubernetes版だと思ってください。

  • Helmはclient (helm) and a server (tiller)のパーツに別れます
  • TillerはKubernetes内で動作し、chartsのインストールなどを管理します。
  • Helmは自分のPCやCI/CD上で起動します。
  • Chartsは以下の2つを最低限含むHelm packages:
    • パッケージの詳細 (Chart.yaml)
    • 一つ以上のKubernetesのmanifestのテンプレートファイル
  • ChartsはディスクやリモートChart repository(これなんだろう?) などに保存できます (like Debian or RedHat packages)

とりあえず、githubにのREADMEを訳してみた。わかるようなわからんような。 あとでここも、読んで理解しておこう。 helm.sh

自分で、Chartsを書くドキュメントも充実してるなぁ。 https://helm.sh/docs/developing_charts/#charts

なかなか良さそうだと思って、反論ブログも探してみた。 winderresearch.com まとめると、Securityの甘さと、管理の複雑さかな。 podとTillerあたりとsecretの保存周りが微妙かな。あと、gitopsでバージョン管理できてたのが、複雑になるとか、kubenetesのベストプラクティスではなくなるとか。テンプレートをしたかったらkustomizeとか、他のツールも検証してみなよって感じ。

所感

DockerのオーケストレーションKubernetesだと思って、勉強したけど、CROIなどの登場で、KubernetesでDocker以外を使う選択肢も出てきたり、Kubernetesのオブジェクトを管理するためのツールも多々出てきて、熟成が始まった感があって、学習意欲が掻き立てられますな。

[MEMO] katacodaでLearn Kubernetes ver6 manage Secrets

Use Kubernetes to manage Secrets

Use Kubernetes to manage Secrets | Kubernetes | Katacoda

Secrets

create secret

こんな感じでシークレット用のyamlを作成することが可能

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  user: {user-name base64}
  password: {password base64}

read from pod

podのyamlの中で、このように指定することでenvの中に埋め込むことが可能である。 ただ、メモリ上に配置することはセキュリティの観点からあまり好ましくない。

      env:
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: my-secret
              key: user

また、こんなvolumeと組み合わせでファイルとして読み込むことも可能みたい。

apiVersion: v1
kind: Pod
....
spec:
  volumes:
  - name: {great-name-of-volume}
    secret:
      secretName: {your secrete name}
  containers:
    - ....
      volumeMounts:
          - name: great-name-of-volume
            mountPath: /your/secret/path

Secrets from file

別途、ファイルを保存することも可能なようだ コマンドだと、こんな感じで。

kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt

yamlだと、こんな感じになるみたい。(from version 1.14)

secretGenerator:
- name: db-user-pass
  files:
  - username.txt
  - password.txt
EOF

こんな感じ。

Etc

Secretの更新

Secretの更新頻度などはConfigMapAndSecretChangeDetectionStrategyで設定されてるみたい。更新までは、Cacheに乗ってるデータが使われるので、applyしてから反映まで少し時間かかるみたい。デフォルトどれくらいかは、調べてない。 https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/kubelet/config/v1beta1/types.go#L679-L684

SSH Keyの例

https://kubernetes.io/docs/concepts/configuration/secret/#use-case-pod-with-ssh-keys

Best Practice

あとで読む https://kubernetes.io/docs/concepts/configuration/secret/#best-practices

[MEMO] katacodaでLearn Kubernetes ver5 CRI-O and Kubeadm / Stateful Services on Kubernetes

Getting Started With CRI-O and Kubeadm

Container Runtime Interface (CRI) らしい。

なんで、CRIって必要なんだろうと思って調べてみた。これがわかりやすい。 コンテナランタイムの動向を整理してみた件 - Qiita

Docker以外のContainer RuntimeをKubernetesに導入、実装しようと思うと、現状敷居が高いらしく、1枚間に挟むことで、HighLevelのレイヤーができるみたい。

まぁ、いまのところ深くは勉強しないつもりだけど、Docker以外にもRuntimeはいろいろと出てきているみたいで、KubernetesがDocker以外にも導入しやすくしたことで、今後議論の余地が生まれそうだなぁ。

Running Stateful Services on Kubernetes

Running Stateful Services on Kubernetes | Kubernetes | Katacoda

このチャプターは、DockerでNFSのサーバを立てて、--net=hostとすることで、NFSののプロトコルをローカルホストで受けれるようにし、k8sからマウントするみたいだ。

引用

docker run -d --net=host \
   --privileged --name nfs-server \
   katacoda/contained-nfs-server:centos7 \
   /exports/data-0001 /exports/data-0002

PersistentVolume

まだ、今回は読んでないけど、あとで読む Persistent Volumes - Kubernetes

PersistentVolumeで、NFSのサーバをマウントしてる感じかな

  • persistentVolumeReclaimPolicyは選べる Retainedだとのこり、 Recycled だと消える。
kind: PersistentVolume
metadata:
  name: your-nfs
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    server: ${IP}
    path: ${PATH}

PersistentVolumeClaim

自動でPersistentVolumeをマウントするっぽい?

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: your-claim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

で次に、podの定義にこれを追加する。

  spec:
      volumeMounts:
        - name: mount-volume-name
          mountPath: /mount/path
  volumes:
    - name: mount-volume-name
      persistentVolumeClaim:
        claimName: your-claim

もし、PersistentVolumeClaimにPersistentVolumeがアサインされておらず、Pendingなら、PodもPending状態になる。

[MEMO] katacodaでLearn Kubernetes ver4 Liveness and Readiness

# Liveness and Readiness Healthchecks

Configure Liveness and Readiness Probes - Kubernetes

Liveness and Readiness Healthchecks | Kubernetes | Katacoda



## Liveness
Livenessはそのポッドのhealth checkをするための機能です。いわゆる、死活監視。
この条件を満たせなければ、podの再起起動を行う。
tcp,httpやファイルのアクセスなどでを設定することが可能


```
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 1
timeoutSeconds: 1
```


## Readiness
Readinessは、ポッドがアクセス可能になる条件を設定できる。ここに書いた条件を満たせば、Serviceがトラフィックを流すようになる。


## Prove parameter
ココらへんが、設定値。readinessもlivenessもパラメータは同じ。

initialDelaySeconds: コンテナがスタートして、何秒間待つか。
periodSeconds: 何秒ごとにテストするか
timeoutSeconds: 毎回とテストのタイムアウト
successThreshold: 何回成功したら、良いのかのしきい値。最低1
failureThreshold: 何回失敗したら、Podが落ちてると判断するか。デフォルト3、最低1

[MEMO] katacodaでLearn Kubernetes ver3 ingress

Create Ingress Routing

Create Ingress Routing | Kubernetes | Katacoda

Ingress - Kubernetes

Ingressとは

Ingresskubernetes外部にHTTP/HTTPSプロトコルアクセスを公開するためのものです。もし、それ以外を公開したければ、 Service.Type=NodePortかService.Type=LoadBalancerを使うことが多いです。

前提

Ingress controlerを作る必要があります。ingress-nginxが一番有名っぽい?かな。 複数持つことも可能。ただ、複数の種類を使うのは少し難しい。

Ingress Controllers - Kubernetes

Kind ingress

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: index-ingress
spec:
  rules:
  - http:
      paths:
      - path: /indexpage
        backend:
          serviceName: index
          servicePort: 80
      - backend: # pathを指定しなければ、他全部あつかい
          serviceName: no-page
          servicePort: 80

[MEMO] katacodaでLearn Kubernetes ver2 Service / Networking

Deploy Containers Using YAML

memo

apiVersion: extensions/v1beta1
kind: Deployment
kind: Service
spec:
  type: NodePort
kubectl create -f {file}
kubectl apply -f {file}

Service

  • kubernetes内部でお互いのpodsにselectorを使って、ポートを割り当てることができる。selectorを使わずに、Endpointsを使って、外部に対するアクセスを割り当てることができる。基本的には、kubenetesのpods通しでのアクセスをサポートするために使われる。

https://kubernetes.io/docs/concepts/services-networking/service/#services-without-selectors

Type

読んだことメモ。

  • ClusterIP: クラスター内でアクセスできるIPを作る。デフォルト
  • NodePort: StaticPortを割り当てる。外部からもそのNodeのIPとPortを指定すればアクセスできる。 :.
  • LoadBalancer: クラウドプロバイダーのLBを使って外部に公開できる。(?)NodePortとClusterIPが自動で作られる
  • ExternalName: サービスを外部のドメインに紐付ける。

https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

Networking Introduction

f:id:daigorowhite:20190711081933p:plain

  • Cluster IP

ClusterIPは内部のPodに対して、内部からのアクセスをロードバランスするIP、ポートを用意すること

portだけをしているすると、podのポートとserviceのポート両方が同じポートになる。 targetPortを指定すると、podのポートはtargetPortが利用される。

 spec:
  ports:
  - port: 8080
    targetPort: 80
  • NodePort

ClusterIPとTargetPortは内部からのアクセスに対応した手法である。NodePortは外部からのアクセスを可能にするStaticIPを用意する。すべてのノードのPortを専有するかも?要検証。

spec:
  type: NodePort
  ports:
  - port: 80
    nodePort: 30080

同じポートを指定するNodePortを作ろうとしたが、エラー出たのでたぶん、全Nodeであってる。

master $ cat nodeport2.yaml  | grep nodePort -A2 -B2
  ports:
  - port: 80
    nodePort: 30080
  selector:
    app: webapp2-nodeport
master $ cat nodeport.yaml  | grep nodePort -A2 -B2
  ports:
  - port: 80
    nodePort: 30080
  selector:
    app: webapp1-nodeport
master $ kubectl create -f nodeport2.yaml
Error from server (Invalid): error when creating "nodeport2.yaml": Service "webapp2-nodeport-svc" is invalid: spec.ports[0].nodePort: Invalid value: 30080: provided port is already allocated
Error from server (AlreadyExists): error when creating "nodeport2.yaml": deployments.extensions "webapp2-nodeport-deployment" already exists
  • External IPs

指定のIPのポートを外部公開し、内部のPodにアクセスする。

spec:
  ports:
  - port: 80
  externalIPs:
  - {NODE_IP}
  • Load Balancer

GCPやAzure、AWSなどで外部のロードバランサーを通してLBSする機能。それがない場合でも、quay.io/munnerz/keepalived-cloud-provider:0.0.1このimageを使うことで、cloudproviderを内部に作成できるみたい。 https://github.com/munnerz/keepalived-cloud-provider

spec:
  type: LoadBalancer
  ports:
  - port: 80

リモートでのモブプログラミングの紹介

リモートチームでモブプログラミングを導入してみてうまく動き出したので、ご紹介したいと思います。モブプログラミングの記事は多いけどリモートでの記事はまだ少ないので何かしら、感じ取ってもらえると嬉しいです。最初に言っておきますが、チームの数だけモブプログラミングの形はあると思うので、参考程度に見てください。

(読書メモ) モブプログラミング・ベストプラクティス まとめ・感想 - だいごろうのブログ

モブプログラミングとは

モブプログラミングとは、1箇所にチームで集まり、1台のPCを用いて、複数に同じ課題に取り組む手法。少しだけルールがあります。

  • 基本は役割が2つあり
    • ナビゲーター:問題に対し、考え、意見し、タスクの解決のために全力を注ぐ人たち
    • ドライバー:別名タイピストであり、キーボードを触る唯一の人。ナビゲーターの意見に対し、手を動かす人。
  • ドライバーの人は短いサイクル(15分とか)でローテーションする。

基本的には、これだけです。このブログが非常によくまとまってると思います。 medium.com

リモートのモブプログラミングでは、このブログが非常に良い。 www.remotemobprogramming.org

リモートにモブプログラミングは向いているのか?

この議論は非常に重要な部分だと思います。

どのモブプログラミングの本などを見ても、前提条件にチームが1箇所または1部屋に集まれることということが必ず書いてあります。これはメンバー全員が1つのタスクに集中するため、邪魔を極力減らすためなど、重要な要素です。では、リモートで、ビデオ会議で同じような環境を再現できるのか。ここができなければ、モブプログラミングの恩恵を受けることが難しくなるでしょう。

僕が導入しようと決意した経緯

リモートチームで仕事をしていると、チーム全体で知識共有やコミュニケーションがすくなることが課題となってくる。モブプログラミングの良いところは、全員でタスクに集中し、知識や手法などをオンタイムで共有しながら、お互いをより深く知ることができる点であるので、リモートチームこそ、モブプログラミングなどを用いて、より密にチーム作りをする必要があると思っている。もちろん、チャットなどでもそういったことは可能だが、やはりまとまった密な時間はその恩恵を何倍にも増やせると思っている。また、リモートだとチームメンバー同士のコミュニケーションが疎かになることがあるので、全員がお互いを”知っている”と実感するのに1役買うと思う。

僕たちのリモートモブプログラミング

リモート

リモートチームでは、チームコミュニケーションをいかに補うかが非常に重要となってくる。そのため、こういったことを意識しなければいけない。

  • コミュニケーションの量を増やせるようにすること
  • お互いに干渉するのを苦に思わないように状況を整理すること。
  • 情報伝達を行い認識合わせを行うこと。
  • ありがとうとごめんなさいを伝えること

ちなみにリモートは場所にいるメンバー限定ではなく、仕事を一緒にしたいメンバーでチーム構成できるのですごく良いです。

リモートで1箇所に集まる

ビデオ会議をするアプリというのは最近多くなっています。それらを利用して、できたらカメラでお互いの顔を見ながら会話できる状況を作ります。顔を見ながら話すことはコミュニケーションにおいて非常に重要です。顔が見えたら、モブプログラミングに集中してるか一目瞭然ですし。

ドライバーとナビゲーターをローテーションすること

これがモブプログラミングの基礎だが、意外とこれが難しい。作業に集中してると時間が経つのは早すぎる。 まず、リモートだとローテーションの時間が来たことを全員が周知することを時計などで知らせるのが意外と難しい。時間を管理する人を作ってもいいが、それ自体がその人のモブプログラミングへの集中力を下げてしまう。また、口頭で「時間だよ」っと言っても、「すぐ終わるから、ここまでやらせてくれ」っと言うメンバーがいる、それに「すぐ」には終わらない。 解決策としては、ツールを導入すると良い。チームではmobsterを使ってる。時間を測り、全画面を強制的に mobsterの画面にしてくれるし、ローテーションも管理してくれる。「だれかが、時間だよ!」っていう心理的に大変な作業を代わりにやってくれるし。画面が強制遷移すると、あ、交代だって全員思う。これを導入してから、みんな時間を守れるようになった。

Mobster - Pair and Mob Programming Timer for Mac, Windows, and Linux

リモートコントロールを利用したローテーション

リモートのモブプログラミングをしている人の多くがgitにpush/pullして、コードをドライバーから次のドライバーへ継承していくことが多い。しかし、このやり方は交代時のオーバヘッドがあるし、gitの問題によって時間をロスすることが多々ある。(gitになれない人が間違えて、他の修正をコミットしちゃったり)。また、作業時のコード以外のターミナルのログやブラウザの状態は、失われてしまう。 そこで僕たちはzoomのリモートコントロールを利用している。一人のPCをマスターPCとし、全員がそのPCとZoomでVideo会議をする。で、作業はそのマスターPCで行い、ドライバーのローテーションに合わせてリモートコントロールを権限を移していく。こうすることで、作業中のすべてを次のドライバーへ引き継いでいる。

*ちなみに、過去にslackがscreenheroという会社を買収し、screenheroのリモートコントロールの非常に優秀な機能を取り込んだが、複雑でメンテナンスが難しいという理由で機能の削除をした。なので、今はZoomを利用している。

Removal of remote screen control in Slack Calls – Slack Help Center

振り返り

この振り返りは非常に重要である。リモートチームではチームのコミュニケーションが密になる場面が足りないことが多いので、モブプログラミングをするとチームの問題点が浮上することがある。しかし、それはタックマンモデルの混乱期に差し掛かったといういい状態なので、ちゃんと振り返りをしチームでそれを乗り越える良い機会である。

タスクの選定はメンバーと共に。

リモートのモブプログラミングのタスク選定は慎重にメンバーと共にやったほうが良い。選び基準としては

  • 全員の学習となるようなタスクである
  • 全員に恩恵のあるようなタスクであるとなお良い。 また、この利用としては
  • リモートでのモブプログラミングだと、それぞれ1台ずつPCを持っていることになるので、モブプログラミング中でも別作業ができてしまう。それは人の心理なので止めれないので、できるだけ全員がモチベーションが高いタスクでないと行けない。
  • また、リモートでのモブプログラミングは非常に貴重な時間なので、お互いに学習になるようなタスクを選ぶことでコミュニケーションの量を蜜にし、無駄な時間を使わないようにする。
  • 自分たちで選んだほうが楽しいし、より技術的なことをタスクにしやすい。

疲れることを認知する

ビデオチャットでの共同作業も、モブプログラミングも疲れる作業だ。なので、定期的に長めの休憩時間を儲けよう。リモートだと、メンバーがつかれたタイミングを知るのが難しい。あと、コーヒーのおかわりほしいし。 あと、なれない頃は長すぎるモブプログラミングは控えましょう。それだけで、モブプログラミングが苦痛なイメージになってしまうので。

素人やエキスパートのどちらでもが安心して意見できること

リモートかつモブプログラミングだと、意見を言うことに対しての敷居が上がってしまう。なので、モブプログラミングの目的は、作業を進めることだけでなく、メンバーの全員の成長も含まれていることを周知します。エキスパートに先生になってくれとお願いし、素人の意見にはまず意見を言ってくれたことに感謝する。つまりは、心理的安全性のコンセプトを理解することは非常に大事だ。

場所にこだわらない

モブプログラミングの難しい理由の一つは、定期的にメンバー全員が集まれるスペースを用意し、大きなディスプレイを用意することである。しかし、リモートの場合、ビデオチャットのアプリがあれば、ほかは何もいらない。特にMTGルームを確保するのが大変な会社だと、これは大きな恩恵になる。

より実験的に。

モブプログラミングの導入自体が実験的であるのに、リモートチームでモブプログラミングをすることはより実験的であることをメンバーにも上司にも通知しておくことが非常に大事である。そのため、メンバーからのフィードバックは定期的にたくさんもらって、常に自分たちに合う方法にたくさん改良したほうがいい。

お互い信頼すること

最後に、もっとも重要なことだが、リモートチームであること、モブプログラミングをすること両方とも信頼関係を気づくことが大事である。なんでも意見を言い合って、いけるように頑張ろう。

最後に

リモートチームでは、どのようにチーム作りをしメンバー同士の関係性を向上させるかが非常に重要になってくる。お互いを信頼し、顔が見えない中でも、コミュニケーションを取らなければいけない。モブプログラミングは、それらを改善するのに非常に重要なやり方だし、僕らのチームでも上手に作用しているし、メンバーの成長とチームの成熟に貢献していると思う。

最後に、Googleが提唱しているReWorkの「イノベーションが生まれる職場環境をつくる」の中で、コラボレーションについての記述について紹介したいと思う。

つながりとコラボレーション - 従業員が仲間を見つけやすく、協業しやすい環境をつくる。

Google re:Work - ガイド: イノベーションが生まれる職場環境をつくる

ベテラン、新入社員問わずいろいろな人とつながりを持ち、アイデアを出しやすい、成熟させやすい環境を作ることはイノベーションを生むことに繋がる。 モブプログラミングはリモートチームで、チーム内での関係性を向上させ、より面白いイノベーションを生むために非常に強いツールだと思っている。なので、もっとモブプログラミングを楽しく実行していければ、ビジネス価値やアイデアも生まれるのではないかと思っています。リモートでもそれは大丈夫です。

これからも、どんどんリモートでもモブプログラミングを実験していこうと思います。

ハッピーモビング!!