---
title: 定規なしで kubernetes manifestを書こう
author: yckao
tags: CAMPHOR-, advent calendar
langs: ja-jp
description: 今回紹介したいのは以前インターンした時のチームリーダーが作ったkoskoです。簡単に言うと「TypeScriptでKubernetesのDeploymentやServiceなど簡単に書く」ツールです。
image: https://i.imgur.com/7ivYW2C.jpg
disqus: hackmd
GA: UA-148730743-1
---
# 定規なしで kubernetes manifestを書こう

▲ 定規を使って yaml を書く。[@caged](https://twitter.com/caged/status/1039937162769096704)
この記事は [CAMPHOR- Advent Calendar](https://advent.camph.net/) の 18 日目の記事です。
[TOC]
## はじめに
こんにちは、[@yckao](https://yckao.io) です。台湾から京都へ留学している留学生です。
日本語はまたまた勉強中ですから、もしこの記事の内容や文法が意味不明なことがあったら、コメントしてもらえるのが幸いです。
今回紹介したいのは以前インターンした時のチームリーダーが作った[kosko](https://github.com/tommy351/kosko)です。
簡単に言うと「TypeScriptでKubernetesのDeploymentやServiceなど簡単に書く」ツールです。
中国語が分かる方なら[こちら](https://zespia.tw/blog/2019/03/02/kosko-kubernetes-in-javascript/)は原作者が書いた記事です。

▲ Koskoと言う名称の由来。台湾ではCOSTCOの読み方が一つのネタになっています。
## 最初は問題の確認
### 環境によって設定が違うから、一元管理できない
プロダクション環境とステージング環境二つあるため。二つのブランチで管理していました。新しいサビースを実裝する時、各環境で別々の設定を書ければならない。だから毎回二つのブランチを作成し別々でプルリクエストすることになった。
例えば marquee api を実装する時こんなことになった。
```
marquee-api -> master
marquee-api-prod -> prod
```
### 同じ設定や環境変数再利用できない
50個以上のマイクロサービスがあるから、例えばこのような内容を40個以上のファイルに使っていました。
```yaml
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: pg-secret
key: user
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: pg-secret
key: password
```
読み難いしややこしい。
### 設定の検証は難しい
yamlを書く時インデントはなかなか把握できない。一つ間違いたら大問題だ。
その上、kubectl自体はvalidate出来ないから¥ [kubeval](https://github.com/instrumenta/kubeval)とか他のツールを頼なければならない。
## 幾つあるソリューション
### kustomize
#### 良い点
- [sig-cli](https://github.com/kubernetes/community/blob/master/sig-cli/README.md) から作ったツール。開発中止の可能性が低い。
- yaml を使って、簡単に使える。
- Overlay と言う概念を使って、各環境が基本の設定をパッチできる。
#### 悪い点
- 設定の検証ができない。
### ksonnet
#### 良い点
- 変数と関数がある。
- Helmも使いえる。
- 設定の検証ができる。
#### 悪い点
- jsonnetを使うから。学習が必須。資料も少ない。
- 開発中止になった。
### kapitan
#### 良い点
- secretを管理するができる。
- ドキュメントや[terraform](https://www.terraform.io/)の設定、scriptsなど作成できる。
- Inventory と言う概念で環境設定を管理できる。
#### 悪い点
- jsonnet を使う。
- jsonnet を使うのに、また jinja2 を template engine として使う。 必要がある?
## Kosko
### Typescriptで書くのかどんな感じ
{%youtube CFAhIFmVNoU %}
### 機能
- Javascriptを使うでyamlを生成する
- YAMLを生成と検証たけ。クラスターを接続しない
- Tamplating ができる
### 使い方
#### インストール
```
npm i -g kosko
```
#### まず、初期化する
```bash
kosko init example
cd example && npm install
```
#### 次、環境を設置する
kosko.tomlを書く(全部 optional)
```toml
# グローバル設定
# require = ["a"]
## kosko 実行する時必要なパッケージ
## typescript の場合は require = ["ts-node/register"]
components = ["*"]
## 生成する components
## ["*"], ["foo", "bar"], ["nginx_*"], ["!foo", "!bar"] とか使えます
# 環境設定
# [environments.dev]
# require = ["c"]
# components = ["d"]
# [environments.prod]
# require = ["e"]
# components = ["f"]
[paths.environment]
global = "environments/#{environment}"
component = "components/#{component}/#{environment}"
```
:::warning
path.environmentを注意。
私のオススメは
component = "components/#{component}/#{environment}"
その場合は componentとenvironment は同じフォルダになります。
この方が管理やすいと思う。
:::
#### そして、componentを書く
この例ては直接 @kosko/template-deployed-service を生成する
templateを書く方法は[こちら](https://github.com/tommy351/kosko/blob/master/docs/templates.md)
```bash
npx @kosko/template-deployed-service --name nginx --image nginx
```
#### 最後、yamlを生成する
```bash
kosko generate
```
直接使いたい時
```bash
kosko generate | kubectl apply -f -
```
## おわりに
manifest を Typescriptで書くは本当に便利たと思っています。
vscode の completion を使えるし間違い部分もちゃんとエラーをハイライトする。
もし kubernetes をつかているなら、kosko を是非試してくだせい。
絶対役に立つから。
もっと詳しく情報は [tommy351/kosko](https://github.com/tommy351/kosko) ご覧ください。
## おまげに
この記事は [HackMD](https://hackmd.io/) で書いています。
これは台湾のエンジニアコミュニティで一番人気の markdown コラボレーションサビースです。
便利な[機能](https://hackmd.io/features-jp)がたくさんあるので、是非試してくだせい。