iPad でコードを書く Late 2019

ラップトップに比べるとかなり軽量な iPad。Cellular モデルなら出先や新幹線に持ち込んですぐコードが書けます。Magic Keyboard をペアリングしてるのでタイピングもノンストレスです。

blog.kondoumh.com

Blink で Ubuntu の仮想マシンに接続して Tmux + Emacs で使っています。macOS と同様 Zsh にスイッチしました。数年前に比べるとターミナルアプリも進化しました。Node.js や Go で CLI アプリ書く環境としては完成度高いです。iPadOS でマルチタスクが改善され、9.7インチ iPad でもブラウザとのタイル表示が使いやすくなりました。

f:id:kondoumh:20191130002056p:plain

そして今は何と言っても Gitpod でしょう。

blog.kondoumh.com

ほぼフルスペックの VS Code がブラウザの1タブ内に起動します。バックグラウンドに回ってもサーバー側でリサイクルされない限り作業を継続できます。CLI はもちろん Web UI 開発もできてしまいます*1

f:id:kondoumh:20191130094029p:plain

ちなみに Chrome だとターミナルへのコマンド入力中にブラウザのツールバーが出て被ってしまうので Safari で使う方がよいです。また Gitpod からのリポジトリへの push は設定ページで有効化する必要があります。

https://gitpod.io/access-control/

f:id:kondoumh:20191130195110j:plain:w350

先日 public beta が公開された Visual Studio Online。

visualstudio.microsoft.com

ベータテストには登録してますがまだ全然使ってません。iPadOS の Safari で起動するとちゃんと動作はしてそうです。「このブラウザは未対応だけど、すぐにサポート対象に追加するよ」というメッセージが出ているので期待できそうです。

f:id:kondoumh:20191201111119p:plain

以上のように、iPad は開発用のモバイル端末としてかなり実用的になってきていると感じます。僕はいまだに iPad Air 2 (2014年発売) を使っていますが、第7世代 iPad や第3世代 iPad Air ならブラウザも高速動作するし画面もちょっと大きくなってるのでさらに快適でしょう。

*1:Developer ツールが使えないのでデバッグはできませんが。

Emacs の go-mode 設定

最近わりと Go 書くようになってきたので Emacs の Go 環境を作ってみました。

company を使っているのでコード補完は company-go、godoc の表示は go-eldoc にしてみました。

~/.emacs.d/init.el の設定。タブ幅は2にしてます。保存時に gofmt かけています。

;; go-mode                                                                   
(use-package go-mode)
(add-hook 'go-mode-hook
          '(lambda ()
             (setq tab-width 2)))
(add-hook 'go-mode-hook 'go-eldoc-setup)
(add-hook 'before-save-hook 'gofmt-before-save)
(add-to-list 'company-backends 'company-go)

補完効いてミニバッファに API のシグネチャが表示されます。

f:id:kondoumh:20191128233400p:plain

goimports 使えばフォーマットついでに未使用の import 消してくれますが、自動保存にしているため追加直後に消されることになるので gofmt にしてます。

Terraform と GItHub Actions で DigitalOcean Droplets の CI/CD を作る

VPS は DigitalOcean の Droplets が安いのでたまに利用しています。

www.digitalocean.com

Terraform は DigitalOcean に対応していて専用のプラグインが HashiCorp から提供されています。

www.terraform.io

Terraform 用の GitHub Actions も公開されていました。

GitHub - hashicorp/terraform-github-actions: Terraform GitHub Actions

Droplet は Web 画面をポチポチして作るのも簡単ですが、Terraform の勉強を兼ねて Actions で CI/CD することにしました。

Droplet を作る tf ファイル。5$ / mo のマシンを指定しています。DigitalOcean プロバイダーを定義しておくと、terraform init 実行時に必要なプラグインをダウンロードしてくれます。API トークンは環境変数 DIGITALOCEAN_TOKEN に展開しておきます。

provider "digitalocean" {
  # export DIGITALOCEAN_TOKEN="Your API TOKEN"
}

data "digitalocean_ssh_key" "ssh_key" {
  name = "blink"
}

resource "digitalocean_droplet" "dev" {
  image = "${var.ubuntu}"
  name = "dev-01"
  region = "${var.do_sgp1}"
  size = "s-1vcpu-1gb"
  ssh_keys = [data.digitalocean_ssh_key.ssh_key.id]
}

リージョンや OS は変数用の tf ファイルに書いて参照しています。

# Datacenter regions
variable "do_sgp1" {
  description = "Digital Ocean Singapore Data Center 1"
  default     = "sgp1"
}

# OS
variable "ubuntu" {
  description = "Eoan Ermine"
  default     = "ubuntu-19-10-x64"
}

GitHub Actions のワークフロー定義。PR 作成時に tf ファイルを検証して plan を出力、レビューできるようにします。

各 step で terraform のサブコマンド、init / validate / plan を実行しています。PR を編集するための GitHub アクセストークンと、DigitalOcean の API トークンは Secrets に格納して環境変数に渡しています。

name: Terraform Plan for droplet

on:
  pull_request:
    types: [opened]

jobs:
  terraform:
    name: 'Terraform'
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout'
        uses: actions/checkout@master
      - name: 'Terraform Init'
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: 0.12.15
          tf_actions_subcommand: 'init'
          tf_actions_working_dir: 'droplet'
          tf_actions_comment: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TF_TOKEN }}
          DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
      - name: 'Terraform Validate'
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: 0.12.15
          tf_actions_subcommand: 'validate'
          tf_actions_working_dir: 'droplet'
          tf_actions_comment: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TF_TOKEN }}
          DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
      - name: 'Terraform Plan'
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: 0.12.15
          tf_actions_subcommand: 'plan'
          tf_actions_working_dir: 'droplet'
          tf_actions_comment: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TF_TOKEN }}
          DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}

この状態で branch を作成し tf ファイルを更新して PR を作成すると、ワークフローが実行され PR の画面で実行結果をレビューすることができます。

f:id:kondoumh:20191119215754p:plain

plan の結果も表示できます。

f:id:kondoumh:20191119215828p:plain

PR がマージされる時に実行するワークフローです。init の後続でサブコマンド apply を指定しているのと、PR がマージされたかどうか (github.event.pull_request.merged == true) を判定する if を入れています。

name: Terraform Apply droplet

on:
  pull_request:
    types: [closed]

jobs:
  terraform:
    name: 'Terraform'
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout'
        uses: actions/checkout@master
      - name: 'Terraform Init'
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: 0.12.15
          tf_actions_subcommand: 'init'
          tf_actions_working_dir: 'droplet'
          tf_actions_comment: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TF_TOKEN }}
          DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
      - name: 'Terraform Apply'
        if: github.event.pull_request.merged == true
        uses: hashicorp/terraform-github-actions@master
        with:
          tf_actions_version: 0.12.15
          tf_actions_subcommand: 'apply'
          tf_actions_working_dir: 'droplet'
          tf_actions_comment: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TF_TOKEN }}
          DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}

PR をマージするとワークフローが実行されました。

f:id:kondoumh:20191119222408p:plain

そして無事 Droplet が作成されました。

f:id:kondoumh:20191119222440p:plain

文字通り Infrastructure as Code / GitOps を地で行くようなワークフローです。

単体の Droplet 作成には羊頭狗肉感は否めませんが、業務で AWS の複雑な依存関係を持つリソースを Terraform で作っているような場合にはかなり役立ちそうです。

ChangeLog メモが Emacs に回帰

ChangeLog メモ書きをかなり前に Emacs から VS Code に移行しました。

blog.kondoumh.com

自分用に VS Code 拡張も作ってました。

blog.kondoumh.com

自宅で MacBook 使う時はデスクトップの片隅に ChangeLog メモ用 VS Code が常駐してます。コード書き用の VS Code が常に数個起動してるので、ChangeLog メモ用環境は分離したくなってきました。

今年のはじめに Rust 環境を Emacs で構築した時にかなり設定をアップデートしてました。

blog.kondoumh.com

  • パッケージの使用宣言を require から use-package
  • 補完機能を auto-complete から company に
  • サーチを Anything から counsel に

メモ書きはやっぱり Emacs に戻そうと思ったら CUI 版しか入ってないことに気付きました。ターミナルも常に起動しっぱなしなので GUI 版を使ってターミナルとも分離したいところです。Homebrew で導入する際に brew install emacs だとターミナル版が入るようです。ということで、

% brew cask install emacs

これで GUI 版が入ります。

元々 ChangeLog 用環境がビルドインだし、自分用 elisp も書いていたので戻るのは簡単でした。さらに auto-complete や counsel がかなり賢く入力を補助してくれるのでメモ書きも楽になっています。

テーマは misterioso、フォントは Menlo 14pt に設定してみました。

f:id:kondoumh:20191110080403p:plain

ところで、ChangeLog じゃないテキスト作成には最近 Kibela を一人プロジェクトで使ってます。

kibe.la

Slack の自分専用チャンネルに書いてたこともあったのですが、Kibela は Markdown で書けるのと Windows / macOS / iOS / Android の各プラットフォームで PWA として専用アプリのように動作するところが便利です。コードスニペットや ToDo リストの管理もできます。ただ、ちょっと動作がバギーなところがあって長い文章には適してない気がしてます。

macOS Catalina にアップデート - Zsh にスイッチ

年末も近いし32bit アプリも使ってないし、そろそろいいかなと思って MacBook Pro Early 2015 でアップデートしました。

40分ほどで起動してきました。BetterTouchTool や Karabiner-Elements などでパーミッションの許可が必要でしたが問題なく使えるようになりました。Mojave の時は非 Retina ディスプレイのフォントレンダリングがちょっと話題になってましたが、設定を引き継いでいるからか問題ないように見えます。

Night Shift と外観モード

iOS 13と同様、Night Shift の設定に合わせてダークモードとライトモードを切り替える機能が実装されてました。久々のライトモード、明るいうちは悪くありません。日没後はダークになってくれます。この機能 Android にも実装されて欲しいところです。

f:id:kondoumh:20191109115519p:plain

Bash から Zsh へ

ターミナルを起動すると zsh がデフォルトになったよとメッセージが。

f:id:kondoumh:20191109115750p:plain

これまでも zsh は使おうと思えば使えましたが、bash が標準だし会社でも bash だしということで敬遠していました。せっかく macOS では zsh が標準となったのでメッセージに従って zsh に切り替えます。

ターミナル再起動して bash の path 設定などを .zshenv にコピー。oh-my-zsh も入れてみました。

% curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sh

oh-my-zsh ではデフォルトで Git のプラグインが有効になっていて、Git リポジトリ内ではブランチ名の表示や Git コマンド補完もしてくれます。Powerline フォント入れて、agnoster テーマを有効にしてみました。いい感じです。

f:id:kondoumh:20191109153537p:plain

Kubernetes 用のプラグインもあるようなので、複数のクラスターを切り替えて kubectl コマンドを叩く場合など、オペミス防止のためにも使いたいところです。

VS Code の統合ターミナルは bash のままだったので、settings.json に設定を直書きしました。

{
    "terminal.integrated.shell.osx": "/bin/zsh",
    "terminal.integrated.fontFamily": "Noto Mono for Powerline",
    "terminal.integrated.fontSize": 14
}

f:id:kondoumh:20191109175542p:plain

VMware Fusion アップデート

VMware Fusion は High Sierra の時からアップデートしておらず、v10 を使い続けていたのですが、Catalina では仮想マシンの画面が表示されなくなってしまいました。ということで2年ぶりのお布施。使用頻度が落ちているとはいえたまに使うことがあるので。

f:id:kondoumh:20191109135645p:plain

Sidecar

iPad をセカンドディスプレイにする Sidecar を試そうと思ったら、MacBook Pro は 2016年以降のモデルが必要。iPad Air 2nd gen も対応していないことが判明しました。Duet もすぐ使わなくなったのであまり使わなそうですがちょっと残念。

https://support.apple.com/ja-jp/HT210380#systemrequirements

ということで、今年の OS アップデート作業完了です。

野良 Scrapbox アプリ - ヒストリ機能とタブ幅調整

開いたページのヒストリ機能を追加しました。

f:id:kondoumh:20191109065744p:plain

f:id:kondoumh:20191109065814p:plain

ただこの機能ちょっと問題があって、Scrapbox ではタイトルの編集で URL が変わり WebView のイベント ("load-commit") が emit されてしまうので、編集途中のタイトルまで履歴に残ってしまいます。履歴にゴミを入れないようにする方法が思いつきませんでした。

2019.11.13 追記) ページの ID でユニーク化することで履歴のゴミが増えないように対応しました。

あと、これまでは長いタイトルの場合も全て表示していましたが、一定の幅で切り詰めるようにしました。データとしては持っているので、ツールチップでは全ての文字が表示されます。

f:id:kondoumh:20191109070205p:plain

Release v1.3.0 · kondoumh/sbe · GitHub

開発用 Kubernetes 環境構築ツールの比較

Kubernetes は GKE / EKS / AKS などで提供されているマネージドなサービスを使うのが楽ですが、課金もありますし開発時はローカルの環境が欲しくなります。

シングルノード構成のツールはオートスケーリングなどの機能が使えないという制約はあるものの、アプリの開発・動作確認環境としては十分使えます。マルチノード構成可能なツールもあります。

メジャーと思われるツールを比較してみました。

Docker Desktop

Docker Desktop for Mac and Windows | Docker

macOS と Windows で提供されている Docker を GUI で導入可能なソフトウェア。Docker が主で Kubernetes はオプションで有効化することで利用可能です。

macOS の場合は HyperKit が、Windows の場合は Hyper-V がノード用の仮想マシンとして使われます。Windows では VirtualBox との共存ができないという問題がありましたが、VirtualBox 6.0 以降 Hyper-V 対応されたので解消されていくものと思われます。

リリースごとに Kubernetes バージョンも上がっていきます。

Minikube

GitHub - kubernetes/minikube: Run Kubernetes locally

定番のローカル Kubernetes 環境です。ノードの仮想マシンとして HyperVisor を利用可能な他、VirtualBox や Docker を指定することもできます。

blog.kondoumh.com

kubeadm を内部的に利用しているため、Kubernetes バージョンの設定も可能です。

Dashboard や EFK など多くの機能がアドオンとして有効化可能です。

Addons | minikube

Windows / macOS / Linux 全てのプラットフォームをサポートしています。

MicroK8s

MicroK8s - Fast, Light, Upstream Developer Kubernetes

Ubuntu の Canonical が提供する Kubernetes パッケージ。APT ではなく Snap パッケージとして、Ubuntu 以外の Linux ディストリビューションでも利用可能です。

KVM などの HpyerVisor は利用していません。

microk8s.kubectl などコマンドにプレフィクスが付いていますが、snap alias microk8s.kubectl kubectl と snap コマンドで alias 指定すれば標準コマンドと同じように使えます。

アドオンで多くのパッケージが簡単に利用できるようになっています。

MicroK8s Addons | MicroK8s

macOS / Windows では Multipass で仮想マシンを使って動かす方法がガイドされています。

Multipass - Orchestrates virtual Ubuntu instances

インストールオプションで kubernetes バージョンを指定可能です。Minikube のようにクラスター作成時に指定はできないのですが、インストール・アンインストールが簡単なので、あまり環境を切り替える必要がないのであれば十分でしょう。

マルチノードにも対応しています(自前で MicroK8s をインストールしたマシンか VM を用意する必要があります)。

Multi-node MicroK8s | MicroK8s

Ubuntu 19.10 では MicroK8s のサポートが厚くなり、セキュア環境構築が楽になる他エッジ環境でも動作するようになるようです。

Ubuntu 19.10 delivers Kubernetes at the edge, multi-cloud infrastructure economics and an integrated AI/ML developer experience | Ubuntu

開発環境だけでなく実行環境としても普及を目指しているようです。当然 WSL2 でもサポートされると思われるので、今後ユーザーが増えていくかもしれません。

kind

GitHub - kubernetes-sigs/kind: Kubernetes IN Docker - local clusters for testing Kubernetes

Docker コンテナをノードとして利用し、マルチノードの環境を簡単に構築できることが特徴です。この特性を活かして CI 環境でマルチノードでしかできないテストケースを実行することもできます。マルチノードの指定は起動オプションで簡単にできます。

内部的に kubeadm を利用しているので、Kubernetes バージョンの指定も可能です。

blog.kondoumh.com

Windows / macOS / Linux 全てサポートしているのに加え、kind は積極的に WSL2 対応をしています。

まとめ

以上、各ツールの特徴でした。最後に比較表です。

Docker Desktop Minikube MicroK8s kind
Use HyperVisor
Select K8s version △※1
Multi node △※2
Support addons
Linux
Windows △※3
macOS △※3
  • ※1:インストール時のみ可能
  • ※2:Worker ノードの事前準備が必要
  • ※3:Multipass で利用可能

個人的には Docker Desktop と Minikube を併用し、Docker Desktop の Kubernetes は無効化しておくのが使いやすいかなと思っています。