新卒デザイナー US出張体験記

こんにちはサイボウズの新卒デザイナーの王子田(おーじ)です。

3月に大学を卒業して、UX/UIデザイナーとしてサイボウズに入社しました。新卒1年目ですが、7月にサンフランシスコに行き、リサーチをしてきました。

今回は人生初の海外出張で感じたこと、そして現地で行ったことについて書いていきたいと思います。 現地、日本のメンバーが盛り上がって話している様子

続きを読む

TeleportでKubernetesクラスタへのユーザーアクセスを管理する

こんにちは、Necoプロジェクトの池添(@zoetro)です。

今回はTeleportというツールを利用して、Kubernetesクラスタへのユーザーアクセスを管理する方法を紹介します。

TL;DR

TeleportとKubernetesを連携させることで、以下のような仕組みを実現することができます。

  • ユーザーが踏み台サーバーを経由してKubernetesクラスタにアクセスできる
  • Kubernetesリソースへのアクセス権を統合的に管理することができる
  • kubectl execの内容はセッションレコードとして保存されリプレイ再生することも可能
  • kubectlの証明書の有効期限を短くすることでリスクを低減
続きを読む

Kubernetesアプリケーションの開発、デバッグを高速化するツール、Telepresenceの紹介

こんにちは、Necoプロジェクトのsatです。

本記事ではKubernetes(以下K8sと記載)アプリケーション(以降アプリと記載)の開発を高速化するツール、Telepresenceを紹介します。

最初に結論を書いておくと、Telepresenceは次のようなツールです。

  • ローカルで動くプロセスやコンテナをk8sクラスタの中で動かせる
  • 既存のDeployment内のコンテナを上記ローカルコンテナで置き換えられる
  • テストやデバッグのためにいちいちコンテナイメージをレジストリにpush,そこからpull…とする必要がないので開発速度が上げられる

Telepresenceは現在Cloud Native Computing FoundationのSandBoxプロジェクトです。

Telepresence登場の背景

前節において"開発を高速化する"と書きましたが、まずはTelepresenceを使わないときの開発、デバッグはどのようになっているのかについて述べます。あるアプリがKubernetesクラスタにdeployされている状態を初期状態とすると、次のようになります。

  1. アプリのソースに変更を加える
  2. アプリのコンテナイメージを作る
  3. Dockerhubなどのレジストリにコンテナイメージをpushする
  4. deploymentの変更やkubectl set imageなどによってアプリが変更後のコンテナイメージを使うようにする
  5. アプリのPodを変更後のコンテナイメージを使って再起動する

このときコンテナイメージのpushからPodの再起動までにはそれなりの時間待たされるため、一回ソースを変更してからそれを動かすまでのサイクルが長くなりがちというのがK8sアプリ開発の大きな問題です。コンテナイメージのサイズが大きいほどこのサイクルは長くなります。この部分を高速化してくれるのがTelepresenceです。

次節以降はTelepresenceがどういうものなのかを実際に使いながら紹介します。

インストール方法

公式サイトの手順に従ってインストールします。Ubuntu 18.04の場合は次のコマンドを使います。

$ curl -s https://packagecloud.io/install/repositories/datawireio/telepresence/script.deb.sh | sudo bash
$ sudo apt install --no-install-recommends telepresence

サンプル1: ローカルコンテナをK8sクラスタ内で動かす

まずはTelepresenceの基本機能である、ローカルコンテナをK8sクラスタ内で動かす方法について書きます。

step 1: K8sクラスタの作成

kindを使ってK8sクラスタを作ります。ここではクラスタの作成にkindを使います。kindのインストール方法については以前紹介したkindについての記事を参照ください。

$ kind create cluster
$ export KUBECONFIG="$(kind get kubeconfig-path)"

step 2: サービスをdeploy

以下のhello.yamlというマニフェストを使ってhellow-world-web-serverというアプリをクラスタ上で動かします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world-web-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-world-web-server
  template:
    metadata:
      labels:
        app: hello-world-web-server
    spec:
      containers:
      - name: hello-world-web-server
        image: quay.io/satoru_takeuchi/hello-world-web-server:0.1
        ports:
        - containerPort: 8000
---
apiVersion: v1
kind: Service
metadata:
  name: hello-world-web-server
spec:
  selector:
    app: hello-world-web-server
  ports:
  - protocol: TCP
    port: 8000
    targetPort: 8000

これはport 8000にアクセスすると"hello, world!"という文字列を返すというアプリです。

次のようにdeployした上でservice化します。

$ kubectl create -f hello.yaml
...
$ kubectl get service
NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
hello-world-web-server   ClusterIP   10.109.22.168   <none>        8000/TCP   37s
kubernetes               ClusterIP   10.96.0.1       <none>        443/TCP    104m
$ 

ここまでで、クラスタ内部からはこのアプリにhello-world-web-serverという名前、ないし10.109.22.168によってアクセスできます。その一方でこの設定ではクラスタの外からはアクセスできません。

step 3: telepresenceによってクラスタ上でローカルプロセス/コンテナを実行

ローカルプロセスcurlからhello-world-web-serverのport 8000にアクセスしてみます。

$ curl http://hello-world-web-server:8000
curl: (6) Could not resolve host: hello-world-web-server
$ 

クラスタの外からのアクセスなので失敗しました。これは想定通りの動きです。

ローカルプロセスからクラスタにアクセスできない
ローカルプロセスからクラスタにアクセスできない

続いてTelepresenceを介して同じプロセスを動作させるとどうなるでしょうか。

$ telepresence --run curl http://hello-world-web-server:8000
T: Starting proxy with method 'vpn-tcp', which has the following limitations: All processes are affected, only one telepresence can run per machine, and you can't use other VPNs. You may need to add cloud hosts and headless services with --also-proxy. For a full list of method limitations see
T: https://telepresence.io/reference/methods.html
T: Volumes are rooted at $TELEPRESENCE_ROOT. See https://telepresence.io/howto/volumes.html for details.
T: Starting network proxy to cluster using new Deployment telepresence-1562306285-3227046-17962

T: No traffic is being forwarded from the remote Deployment to your local machine. You can use the --expose option to specify which ports you want to forward.

T: Setup complete. Launching your command.
Hello world!                         ☆ サービスにアクセスできている
T: Your process has exited.
T: Exit cleanup in progress
T: Cleaning up Deployment telepresence-1562306285-3227046-17962

アクセスが成功しました。本節冒頭で述べたようにTelepresenceによってローカル環境にあるプロセス(および後述するコンテナ)がクラスタ内にいるかのように扱えることがわかりました。

ローカルプロセスからクラスタにアクセスできる
ローカルプロセスからクラスタにアクセスできる

このときTelepresenceは実行ログをtelepresence.logに出力します。

同様にクラスタ内でshellを動かすこともできます。

$ telepresence --run-shell
T: Starting proxy with method 'vpn-tcp', which has the following limitations: All processes are affected, only one telepresence can run per machine, and you can't use other VPNs. You may need to add cloud hosts and headless services with --also-proxy. For a full list of method limitations see
T: https://telepresence.io/reference/methods.html
T: Volumes are rooted at $TELEPRESENCE_ROOT. See https://telepresence.io/howto/volumes.html for details.
T: Starting network proxy to cluster using new Deployment telepresence-1562306514-402358-21367

T: No traffic is being forwarded from the remote Deployment to your local machine. You can use the --expose option to specify which ports you want to forward.

T: Setup complete. Launching your command.
$ curl http://hello-world-web-server:8000
Hello world!

shellを含むプロセスだけではなく、クラスタ内でコンテナを動かすこともできます。

$ telepresence --docker-run -it --rm pstauffer/curl curl http://hello-world-web-server:8000
T: Volumes are rooted at $TELEPRESENCE_ROOT. See https://telepresence.io/howto/volumes.html for details.
T: Starting network proxy to cluster using new Deployment telepresence-1562306747-6756666-25541

T: No traffic is being forwarded from the remote Deployment to your local machine. You can use the --expose option to specify which ports you want to forward.

T: Setup complete. Launching your container.
Hello world!
T: Your process has exited.
T: Exit cleanup in progress
T: Cleaning up Deployment telepresence-1562306747-6756666-25541
$ 

ローカルコンテナからクラスタにアクセスできる
ローカルコンテナからクラスタにアクセスできる

サンプル2: deployment内のコンテナをローカル環境で動作するコンテナで差し替える

初期状態はサンプル1の終了時点であるとします。

通常は実行中のアプリのコンテナを差し替えるには前述のようにコンテナイメージをビルドした後に次のような手順が必要です。

  1. コンテナイメージをレジストリにpush
  2. deploymentを書き換え or kubectl set imageによってアプリが使うコンテナを変更する
  3. アプリのpodを再起動してコンテナをリロード

これに対してTelepresenceを使う場合はアプリが使うコンテナをローカルで動くものに差し替えられます。別のいいかたをすると上記の手順をすべて省略できます。

step 1: 変更版のコンテナをビルドする

step 1.1: ソースの準備

hello-world-web-serverコンテナのソースをダウンロードしてhello-world-web-server:0.1に相当するバージョンをチェックアウトします。

$ git clone https://github.com/satoru-takeuchi/hello-world-web-server.git
...
$ cd hello-world-web-server
$ git checkout v0.1
...
$ 

step 1.2: メッセージを差し替え

アプリのソースコード変更によって"Hello world!"というメッセージを"Hello telepresence!"で差し替えます。

$ cat index.html
Hello world!
$ sed -i -e s/world/Telepresence/ index.html
$ cat index.html
Hello Telepresence!
$ 

step 1.3: コンテナイメージをビルド

次のようにコンテナイメージをビルドします。

$ docker build -t hello-world-web-server:dev .
...
Successfully tagged hello-world-web-server:dev
...
$ 

step 2: アプリ内のコンテナをローカルのものと差し替える

次のようなコマンドを発行します。

$ telepresence --swap-deployment hello-world-web-server --docker-run --rm -it hello-world-web-server:dev
T: Volumes are rooted at $TELEPRESENCE_ROOT. See https://telepresence.io/howto/volumes.html for details.
T: Starting network proxy to cluster by swapping out Deployment hello-world-web-server with a proxy
T: Forwarding remote port 8000 to local port 8000.

T: Setup complete. Launching your container.
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
...

この後、別端末でk8sクラスタ内からhello worldサービスにアクセスすると差し替え後のコンテナを使っているのがわかります。

$ export KUBECONFIG="$(kind get kubeconfig-path)"
$ kubectl run access-hello-world-web-server -it --rm --image=pstauffer/curl --restart=Never -- curl http://hello-world-web-server:8000
Hello Telepresence!                           ☆ メッセージが変更されている
pod "access-hello-world-web-server" deleted
$ 

下図において、通常は点線の矢印のようにアクセスするはずですが、Telepresenceによって実線の矢印のようにアクセスするようになります。

変更したコンテナとDeployment内のコンテナを差し替えられる
変更したコンテナとDeployment内のコンテナを差し替えられる

最後に環境を綺麗にしておきましょう。

$ kubectl delete -f hello.yaml

サンプル3: 複数コンテナから成るdeployment内のコンテナの差し替え

サンプル2の最後の状態で次に示すmulti-container.yamlというマニフェストを読み込みます。このDeploymentの中にはhello.yamlの場合に加えてsleepし続けるdummyというコンテナが存在します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world-web-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-world-web-server
  template:
    metadata:
      labels:
        app: hello-world-web-server
    spec:
      containers:
      - name: hello-world-web-server
        image: quay.io/satoru_takeuchi/hello-world-web-server:0.1
        ports:
        - containerPort: 8000
      containers:
       - name: dummy
         image: quay.io/satoru_takeuchi/hello-world-web-server:0.1
         command: ["/bin/sh"]
         args: ["-c", "while sleep 1000 ; do : ; done"]
---
apiVersion: v1
kind: Service
metadata:
  name: hello-world-web-server
spec:
  selector:
    app: hello-world-web-server
  ports:
  - protocol: TCP
    port: 8000
    targetPort: 8000

Telepresenceはコンテナを特定するためにdeployemt名を指定する際に<deployment名>:<コンテナ名>という書き方ができます。

$ kubectl create -f multi-container.yaml
...
$ telepresence --swap-deployment hello-world-web-server:hello-world-web-server --docker-run --rm -it hello-world-web-server:dev
...
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

ここで別端末からhello-world-web-serverにアクセスすると変更後のコンテナが見えます。

$ kubectl run access-hello-world-web-server -it --rm --image=pstauffer/curl --restart=Never -- curl http://hello-world-web-server:8000
Hello Telepresence!                    ☆ メッセージが変わっている
pod "access-hello-world-web-server" deleted

最後に環境を綺麗にしておきます。

$ kubectl delete -f multi-container.yaml

おわりに

弊社におけるTelepresenceを用例を一つ紹介しておきます。弊社には日本国内のインフラ基盤を刷新するNecoプロジェクトとは別に、US向けのインフラ基盤を刷新するYakumoというプロジェクトもあります。こちらでもTelepresenceがすでに活発に使われています。

Yakumoで提供されるkintoneは国内のデータセンターで提供されていたkintoneと構成が異なるため、AWS移行と同時にkintoneのテストケースの修正も発生します。Yakumo上でのkintoneのテストはKubernetes Jobとして実行しています。このテストのテストケース数は数千にも及ぶので、テストを修正する度にJobをデプロイしてると確認に時間がかかります。そこでYakumoチームではTelepresenceを使って特定のテストケースだけをローカル環境で実行することによって、待ち時間を大幅に削減できています。

Necoプロジェクトにおいても開発が進むにしたがってk8sアプリのサイズが多く、かつ、それぞれのサイズ大きくなってきたことにより、今後ますますTelepresenceを使う場面が増えていく見込みです。

最後になりますが、K8sアプリの開発において本記事で述べたような問題をかかえているみなさまは、ぜひTelepresenceを試していただきたいとおもいます。

Test Everything: データセンター仮想化と自動テストの取り組み

こんにちは。Necoプロジェクトの池添(@zoetro)です。

Necoプロジェクトでは、自社データセンター上のインフラ構築の仕組みを開発しており、サーバーのプロビジョニング、Kubernetesクラスタの構築、Kubernetes上で動くアプリケーションのデプロイ、各種ソフトウェアやOSのアップグレードなどをすべて自動化しています。

blog.cybozu.io

このプロジェクトでは「データセンターの機能をすべてテストすること」を設計方針のひとつとしており、データセンターをまるごと仮想化してテストし、人の手を介することなく成果物の継続的インテグレーションとデリバリーを実現しています。 最初にこの方針を決めたとき、チーム内でも議論がありました。本当にデータセンターをまるごと自動テストできるのか?QAチームの手動テストをおこなわずに品質を保証することができるのか?など多くの疑問が湧きました。

私自身もプロジェクト開始時には半信半疑だったのですが、現在ではテストを自動化することが当たり前になっており、日々たくさんのテストを書いて不具合を検出しています。 本記事では、我々がどのようにデータセンターをまるごと仮想化し、自動テストの仕組みを構築していったのかを紹介します。

続きを読む

kintoneのポータルデザイン開発ストーリー

デザイン&リサーチグループの篠原です。昨年から携わってきたプロジェクトが来週正式リリースということで、メイキング的な話をしたいと思います!

このプロジェクトとは?

2019年7月版搭載予定のkintoneポータルカスタマイズ機能を活用して、ポータルを手軽にカスタマイズできるようにするプロジェクトです。 カスタマイズされたポータルのサンプル画像

続きを読む

やっと UIWebView から WKWebView に乗り換えられる話

こんにちは〜! モバイルチームの向井田です。

iOS の UIWebView が deprecated になって数年、弊社の iOS アプリもようやく WKWebView に移行できるようになりました。 そこで、今回は私たちが WKWebView に乗り換えられるようになった理由を語っていきます。

TL;DR

iOS12 から WKWebView でクライアント証明書を使ったSSL通信が正常に動作するようになりました。

続きを読む

お手軽Kubernetesクラスタ作成ツール "kind"の紹介

こんにちは、Necoプロジェクトのsatです。今回はKubernetesクラスタお手軽に作れるkindというツールを紹介します。kindはKubernetes In Dockerの略です。

本記事の要約

  • kindとはKubernetesクラスタを簡単に作れるツール
  • インストール、およびクラスタ作成がそれぞれたった1コマンドを実行するだけで完了
  • 他の類似ツールには存在しないマルチノードクラスタ作成機能がある
  • Kubernetesの公式プロジェクトかつ、Kubernetesそのもののテストにも用いられているため、実績や将来性は十分
続きを読む