cert-managerでさくらのクラウドDNSを使ってワイルドカード証明書を発行する

cert-managerのさくらのクラウド対応版

Kubernetes上で証明書の発行/更新の自動化を行えるcert-managerをフォークしてさくらのクラウド対応版をリリースしました。

github.com

これを利用することでさくらのクラウドDNSを利用して証明書の発行/更新が行えるようになります。

今回はこのさくらのクラウド対応版cert-managerを利用して証明書を発行する方法をご紹介します。

なお今回は現時点(2019/10/3)の最新版のv0.11.0-alpha.0を利用します。
v0.11系はまだalpha版となっており、今後細かな仕様変更などがあるかもしれない点には留意ください。

発行までの手順

以下のような流れとなります。

準備しておくもの

最後のさくらのクラウドDNSヘのゾーン登録ですが、証明書を発行したいドメインさくらのクラウドDNSへあらかじめ登録しておくということです。
(レコードは登録しておかなくても構いません)

ゾーン登録後に表示されるDNSサーバに対して権限移譲を行うところまでは済ませておいてください。

manual.sakura.ad.jp

さくらのクラウド対応版cert-managerのインストール

Helm Chartを用意していますのでこちらを利用してインストールします。

helm init

まずはhelm initしておきます。
(以下はRBACが有効なクラスタhelm initする場合の例です。)

kubectl create serviceaccount --namespace kube-system tiller
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
helm init --service-account tiller

helm lsなどを実行してエラーが出ないことを確認しておきます。

もしError: could not find a ready tiller podが表示されたら少し待ちましょう。

cert-managerのインストール

まずCRDの作成とNameSpaceの作成を行い、その後helm installを実行します。

# CRDの登録
kubectl apply -f https://raw.githubusercontent.com/sacloud/cert-manager/sacloud/v0.11.0-alpha.0/deploy/manifests/00-crds.yaml

# NameSpaceの作成
kubectl apply -f https://raw.githubusercontent.com/sacloud/cert-manager/sacloud/v0.11.0-alpha.0/deploy/manifests/01-namespace.yaml

# sacloudリポジトリの追加
helm repo add sacloud https://sacloud.github.io/helm-charts/

# cert-managerのインストール
helm install --name cert-manager --namespace cert-manager --version v0.11.0-alpha.0 sacloud/cert-manager

これでcert-managerのインストールができました。

さくらのクラウドAPIキーをSecretに格納

次にcert-managerからさくらのクラウドDNSAPIを通じて操作する際に利用するAPIキーをSecretとして作成します。

まず以下のようなyamlファイルを作成します。 (ここではsecret.yamlというファイル名にしました)

apiVersion: v1
kind: Secret
metadata:
  name: sakuracloud-dns
  namespace: cert-manager
type: Opaque
data:
  access-token: <BASE64エンコードしたAPIトークン>
  access-secret: <BASE64エンコードしたAPIシークレット>

APIキーのトークン/シークレットはBASE64エンコードした値に置き換えてください。
(BASE64エンコードecho '<APIトークン>' | base64などのコマンドでOK)

その後kubectlで登録します。

kubectl apply -f secret.yaml

今回は後ほどClusterIssuerを利用するつもりですのでSecretのNameSpaceをcert-managerにしています。
ClusterIssuerではなくIssuerを利用する場合は適宜修正してください。

参考: https://docs.cert-manager.io/en/release-0.11/reference/clusterissuers.html

Issuer or ClusterIssuerの作成

次にIssuer、またはClusterIssuerを作成します。

参考: - https://docs.cert-manager.io/en/release-0.11/reference/issuers.html - https://docs.cert-manager.io/en/release-0.11/reference/clusterissuers.html

今回はClusterIssuerを作成します。

まず以下のようなyamlファイルを作成します。 (今回はissuer.yamlというファイル名にしました)

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  name: example-issuer
spec:
  acme:
    email: <メールアドレス>
    # ステージング
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    # 本番
    #server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: example-issuer-account-key
    solvers:
      - dns01:
          sakuracloud:
            accessTokenSecretRef:
              name: sakuracloud-dns
              key: access-token
            accessSecretSecretRef:
              name: sakuracloud-dns
              key: access-secret

メールアドレスの部分は適宜修正してください。

その後kubectlで登録します。

kubectl apply -f issuer.yaml

これで証明書の発行を行う準備が整いました。続いて早速証明書の発行を行います。

Certificateリソースを作成して証明書を発行

以下のようなyamlファイルを作成します。
(今回はcert.yamlというファイル名にしました)

apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
 name: example-tls
 namespace: default
spec:
  secretName: example-tls
  commonName: '*.<ゾーン名>'
  dnsNames:
    - '*.<ゾーン名>'
  issuerRef:
    name: example-issuer
    kind: ClusterIssuer    

ゾーン名の部分は各自で適切に置き換えてください。
例えばexample.comというゾーン名に対し*.hoge.example.comというワイルドカード証明書を発行する場合、spec.commonNamespec.dnsNames[*]には*.hoge.example.comを指定します。

あとはkubectlで登録するだけです。

kubectl apply -f cert.yaml

確認

取得できているか確認してみます。

$ kubectl describe cert example-tls

Name:         example-tls
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"cert-manager.io/v1alpha2","kind":"Certificate","metadata":{"annotations":{},"name":"example-tls","namespace":"default"},"sp...
API Version:  cert-manager.io/v1alpha2
Kind:         Certificate
Metadata:
  Creation Timestamp:  2019-10-03T06:26:57Z
  Generation:          5
  Resource Version:    2951
  Self Link:           /apis/cert-manager.io/v1alpha2/namespaces/default/certificates/example-tls
  UID:                 ccde4ca9-e5a6-11e9-a60d-9ca3ba2833af
Spec:
  Common Name:  *.example.com
  Dns Names:
    *.example.com
  Issuer Ref:
    Kind:       ClusterIssuer
    Name:       example-issuer
  Secret Name:  example-tls
Status:
  Conditions:
    Last Transition Time:  2019-10-03T06:29:12Z
    Message:               Certificate is up to date and has not expired
    Reason:                Ready
    Status:                True
    Type:                  Ready
  Not After:               2020-01-01T05:29:11Z
Events:
  Type    Reason        Age    From          Message
  ----    ------        ----   ----          -------
  Normal  GeneratedKey  2m44s  cert-manager  Generated a new private key
  Normal  Requested     2m43s  cert-manager  Created new CertificateRequest resource "example-tls-2800673269"
  Normal  Issued        29s    cert-manager  Certificate issued successfully

Eventsの部分にIssuedが表示されたら発行完了してます。

発行された証明書を確認してみます。

$ kubectl get secret 

apiVersion: v1
data:
  ca.crt: null
  tls.crt: ...
  tls.key: ...
kind: Secret
metadata:
  annotations:
    cert-manager.io/alt-names: '*.example.com'
    cert-manager.io/certificate-name: example-tls
    cert-manager.io/common-name: '*.example.com'
    cert-manager.io/ip-sans: ""
    cert-manager.io/issuer-kind: ClusterIssuer
    cert-manager.io/issuer-name: example-issuer
  creationTimestamp: "2019-10-03T06:26:57Z"
  name: example-tls
  namespace: default
  resourceVersion: "2949"
  selfLink: /api/v1/namespaces/default/secrets/example-tls
  uid: cd15196e-e5a6-11e9-a60d-9ca3ba2833af
type: kubernetes.io/tls

data.tls配下にBASE64エンコードされた証明書データが格納されているはずです。

これでワイルドカード証明書を発行することができました。

さくらのクラウド対応版cert-managerの利用上の注意

さくらのクラウド対応版のcert-managerはオリジナルのcert-manager v0.11系以降のみに対応予定です。
それ以前のバージョンには対応しませんのでご注意ください。

終わりに

さくらのクラウド対応版cert-managerを利用することで、さくらのクラウドDNSを用いてワイルドカード証明書の発行が行えます。
さくらのクラウド上でKubernetesを利用する場合などに便利だと思います。 ぜひご利用ください。

以上です。

Terraformerで既存のさくらのクラウド環境からリバースTerraformする

UPDATE: 2022-06 コメントでご指摘いただいたtypoを修正(from: resource= to resources=)

既に存在するリソースの情報からTerraformのコード(tfファイル + tfstateファイル)を生成できるterraformerというツールがあります。

github.com

このTerraformerをフォークしてさくらのクラウド対応を行ったものをリリースしました。

github.com

これを使えばさくらのクラウド上に存在するサーバやディスクなどのリソースからTerraformのコードを生成できます。

Terraformerとは

Terraformerとは前述の通り既存のリソースからTerraformのコードを生成してくれるツールです。
様々なプラットフォームに対応しており、現時点での最新版(0.7.9)では以下のようなものに対応しています。

Terraformerの大まかな処理の流れは次の通りです。

  • 1) 対象プラットフォームのAPIを呼ぶなどして実リソースの情報を取得
  • 2) 取得したリソース毎にTerraformプロバイダーのRefresh(terraform refreshコマンド相当の処理)を実行
  • 3) 得られたtfstateの情報からtfファイルを生成

1)と3)がTerraformer側で実装されており、2)はgRPCなどでTerraformプロバイダーの実行ファイルを利用する形になっています。 また、1)は対象プラットフォーム毎にプロバイダーという仕組み(インターフェース)で拡張できるようになっており、さくらのクラウド対応はこれを実装して行いました。

さくらのクラウド対応版Terraformer

さくらのクラウド対応版Terraformerを利用するには

  • ローカルマシンにインストールする方法
  • Dockerを利用する方法(推奨)

の2つの方法があります。

ローカルマシンにインストールする場合

terraformerコマンドとTerraform/Terraformプロバイダーそれぞれの実行ファイルをローカルマシンにダウンロードしておく必要があります。

それぞれバージョンに注意してダウンロードしてください。

なおterraformerの次のバージョンからTerraform v0.12対応される見込みです。 それまではTerraform v0.11系を利用しておくのが無難です(使えないこともないがエラーが出る箇所がいくつかある)。

バージョンに気をつけてダウンロードするのはなかなか大変なので次のDockerを利用する方法が推奨です。

Dockerを利用する場合(推奨)

さくらのクラウド対応版terraformerとTerraform/TerraformプロバイダーをセットにしたDockerイメージを公開しています。

https://hub.docker.com/r/sacloud/terraformer

以下のように利用します。

$ docker run -it --rm -v $PWD:/work sacloud/terraformer

さくらのクラウドAPIキーの指定

APIキーはコマンドラインオプション、または環境変数で指定します。

コマンドラインオプションで指定する場合は--token/--secretAPIトークン/シークレットを指定します。

$ terraformer import sakuracloud --token=APIトークン --secret=APIシークレット --resources=server,disk,icon

環境変数の場合はSAKURACLOUD_ACCESS_TOKEN/SAKURACLOUD_ACCESS_TOKEN_SECRETを指定します。
(UsacloudやTerraformなどと同じ環境変数です)

$ export SAKURACLOUD_ACCESS_TOKEN=APIトークン
$ export SAKURACLOUD_ACCESS_TOKEN_SECRET=APIシークレット
$ terraformer import sakuracloud --resources=server,disk,icon

Dockerの場合は以下のような感じで指定します。

$ docker run -it --rm -v $PWD:/work -e SAKURACLOUD_ACCESS_TOKEN=APIトークン -e SAKURACLOUD_ACCESS_TOKEN_SECRET=APIシークレット sacloud/terraformer

使い方

基本的な使い方

対象となるリソースの種別を指定してterraformerコマンドを実行します。
例えばサーバを対象とする場合以下のように--resourcesオプション(または-r)を指定して実行します。

$ terraformer import sakuracloud --resources=server 

複数のリソース種別を対象にする場合は以下のように--resourcesオプションにカンマ区切りで指定します。

# サーバとディスクを対象にする場合
$ terraformer import sakuracloud --resources=server,disk

指定できるリソース種別はGitHubのREADME.mdを参照してください。

https://github.com/sacloud/terraformer#サポートしているリソース

またデフォルトではカレントディレクトリ配下にgenerated/sakuracloud/{リソース種別}/というディレクトリがリソース種別毎に作成され、その中にtfファイル/tfstateファイルが生成されます。(オプションで変更可能)

例として、シンプル監視を対象にコード生成した場合、以下のようなコードが生成されます。

# シンプル監視を対象にコード生成
$ terraformer import sakuracloud --resources=simpleMonitor

# 生成されたコードを確認
$ cat generated/sakuracloud/simpleMonitor/simple_monitor.tf
resource "sakuracloud_simple_monitor" "simpleMonitor-000-example" {
  description = "example"
  enabled     = true

  health_check {
    delay_loop     = "1800"
    host_header    = "example.usacloud.jp"
    path           = "/status"
    protocol       = "https"
    status         = "200"
  }

  notify_email_enabled = false
  notify_email_html    = false
  notify_slack_enabled = true
  notify_slack_webhook = "https://hooks.slack.com/services/xxx/xxxx/xxxx"
  target               = "example.usacloud.jp"
}

対象リソースを限定する場合

現在は対象リソースをIDで指定することでコード生成の対象リソースを限定できます。
--filterオプションにTerraformでのリソース種別+リソースのIDをコロン区切りで指定するようになっています。

# IDがid1,id2,id4のリソースのみを対象とする場合
$ terraformer import sakuracloud --resources=server --filter=sakuracloud_server=id1:id2:id4

利用上の注意

残念ながら一部の項目は入力専用となっており、Terraformerから生成できません。例えばサーバの管理者パスワードなどです。
このため、これらの項目については生成されたコードを手作業で修正する必要があります。

出力されない項目はこちらに一覧がありますのでこれを参考に修正してください。

https://github.com/sacloud/terraformer#サポートしない項目

これ以外にもいくつか注意事項がありますのでREADME.mdの利用上の注意を読んだ上でご利用ください。

https://github.com/sacloud/terraformer#利用上の注意

運用上の注意

前述の利用上の注意の通り、出力されない項目がいくつかある問題があるため、DNSレコードの管理やVPCルータの設定を管理するといったシンプルな用途以外は出力されたコードをそのまま実運用するのはなかなか難しいと思います。

出力されたコードは参考程度と割り切って利用するというのも手だと思います。 1からtfファイルを手作業で記載するよりは楽だと思いますのであくまでも道具の一つとしての利用がオススメです。

まとめ

既存のリソースからTerraformのコード生成を行えるTerraformerのさくらのクラウド対応版を紹介しました。
バージョンの縛りがあるためDockerから利用するのがオススメです。

また、いくつか出力されない項目があるなど利用上の注意点が結構あり、出力されたコードをそのまま実運用するというのは難しいです。
とはいえ1からtfファイルを書くより楽になると思いますので利用できる場面では便利にご利用いただけると思います。

ぜひ使ってみてください!

以上です。

Pulumi+さくらのクラウドでjs/ts/py/goを使ってInfrastructure as Codeする

f:id:febc_yamamoto:20190912110915p:plain

はじめに

JavaScript/TypeScript/Python/Goを用いてInfrastructure as Codeできるpulumiさくらのクラウドに対応するためのプロバイダー(プラグインSDK)を公開しました。

www.pulumi.com

github.com

このプロバイダーを用いることで、以下のようなコードでさくらのクラウド上のリソースを操作可能になります。

さくらのクラウド上にサーバ(CentOS)を作成する例(TypeScript)

import * as sakuracloud from "@sacloud/pulumi_sakuracloud";

// CentOSパブリックアーカイブのIDを参照
const centOSArchive = sakuracloud.getArchive({osType: "centos"});

// CentOSパブリックアーカイブをコピー元とするディスクを作成
const disk = new sakuracloud.Disk("pulumi-example", {
    name: "pulumi-example",
    sourceArchiveId: centOSArchive.id,
});

// ディスクを接続したサーバを作成、ディスクの修正機能を利用してrootユーザーのパスワードを指定
const server = new sakuracloud.Server("pulumi-example", {
    name: "pulumi-example",
    disks: [disk.id],
    password: "YourPassword01",
});

// Outputとして作成したIDを指定
export const serverID = server.id;
export const diskID = disk.id;

この記事ではこのさくらのクラウドプロバイダーについて紹介します。

Pulumiについて

PulumiとはJavaScriptやTypeScript、Python、Goを利用してインフラの定義をコードで行えるプラットフォームです。
各種プログラミング言語を用いて宣言的にインフラのプログラミングを行うためのSDKやランタイム、CLIなどがオープンソースとして提供されています。

マルチクラウド対応を謳っており、AWS/Azure/GCP/Kubernetesなどに対応しています(他にも多数サポートしています)。
また、Pulumi社はCNCFのSilverメンバーでもあり、そのプロダクトPulumiもCNCF Landscapeに載ってたりします。

https://landscape.cncf.io/selected=pulumi f:id:febc_yamamoto:20190912121541p:plain

Pulumiについての概要は以下の記事などを参照ください。

Pulumiのファウンダー/CEOであるJoe Duffy氏のブログ

joeduffyblog.com

先日v1.0に到達

このPulumiですが、2019/9/5に正式版となるv1.0がリリースされました。

www.pulumi.com

Publickeyさんでも取り上げられていました。 www.publickey1.jp

この記事の執筆段階で早速v1.1がリリースされていましたので活発な開発が行われているようです。

Pulumiのさくらのクラウド対応

Pulumiでの操作対象は拡張可能

Pulumiで操作する対象となるインフラ/プラットフォームはプロバイダーという仕組みで拡張できるようになっています。

TerraformプロバイダーがあればPulumiプロバイダーを容易に作成可能

TerraformのプロバイダーからPulumiのプロバイダーを生成できるPulumi-Terraformブリッジというツールが提供されており、Terraformプロバイダーが用意されている環境であれば容易にPulumiプロバイダーを作成して利用できるようになっています。

参考: Pulumi vs. Terraform

github.com

余談ですがPulumiには元HashiCorp社のメンバーもJoinしてたりしますのでこの辺の連携が充実しているのも納得ですね。

今回リリースしたさくらのクラウド向けプロバイダーもTerraformプロバイダーを元に作成しました。
なのでさくらのクラウド向けのTerraformプロバイダーが対応しているリソースであればPulumiから利用可能となっています。

参考: Terraformのさくらのクラウドプロバイダー

Pulumi+さくらのクラウドプロバイダーの使い方

それでは早速利用方法についてみていきます。

Pulumiの基本的な使い方

Pulumiの基本的な使い方については公式ドキュメントのチュートリアルや以下の記事などを参照ください。

www.pulumi.com

dev.classmethod.jp

さくらのクラウドを使うための設定

Pulumiでさくらのクラウドを利用するにはPulumiプラグインのインストールが必要です。
以下のコマンドでプラグインをインストールできます。

$  pulumi plugin install resource sakuracloud 0.0.1 --server https://github.com/sacloud/pulumi-sakuracloud/releases/download/0.0.1

プロジェクトの作成 & さくらのクラウド向けSDKのインストール

次にプロジェクトを作成してさくらのクラウド向けSDKをインストールします。
空のプロジェクトを作ってnpmyarnpip3などを実行しても良いのですが、これらを簡単に行えるようにテンプレートを用意していますのでこちらを利用します。

Pulumiプロジェクトの作成

ディレクトリを作成してpulumi newコマンドを実行します。
pulumi newにはテンプレートの名前 or URLを指定します。

さくらのクラウド向けには以下のURLでテンプレートを提供しています。

  • JavaScript: https://github.com/sacloud/pulumi-sakuracloud/tree/master/templates/javascript
  • TypeScript: https://github.com/sacloud/pulumi-sakuracloud/tree/master/templates/typescript
  • Python: https://github.com/sacloud/pulumi-sakuracloud/tree/master/templates/python

例えばTypeScriptの場合は以下のようにします。

# ディレクトリの作成
$ mkdir example && cd example

# プロジェクトの作成
$ pulumi new https://github.com/sacloud/pulumi-sakuracloud/tree/master/templates/typescript

これを実行するとプロジェクト名やスタック名などの入力が求められます。
入力するとnpn installなどが実行されさくらのクラウド向けSDKのインストールが行われます。

注: Pythonの場合

Pythonの場合はpulumi new実行後に以下のように表示されます。任意のコマンドを実行してSDKをインストールしてください。

f:id:febc_yamamoto:20190912141228p:plain

APIキーの設定

(2019/9/12追記: 書き忘れてたため追記)

続いてさくらのクラウドAPIキーを設定します。 設定はpulumi config setコマンドや環境変数などで行えます。

今回は環境変数で行います。以下のコマンドで環境変数を設定しておきます。

$ export SAKURACLOUD_ACCESS_TOKEN=APIトークン
$ export SAKURACLOUD_ACCESS_TOKEN_SECRET=APIシークレット

プレビュー & デプロイ

あとは任意のコードを書いてプレビュー&デプロイするだけです。 先ほどのテンプレートはスイッチリソースを作成する内容となってますのでそのままプレビュー&デプロイ可能となっています。

プレビュー

$ pulumi preview

プレビューを実行すると実際にどのようなリソースが作成されるかが確認できます。

f:id:febc_yamamoto:20190912142320p:plain

デプロイ

次はpulumi upを実行して実際にリソースのデプロイを行ってみます。

f:id:febc_yamamoto:20190912142424p:plain

デプロイして良いか尋ねられますのでyesを選択するとデプロイされます。

f:id:febc_yamamoto:20190912142530p:plain

これでデプロイできましたね!!

お片づけ

pulumi destroyコマンドでリソースの削除ができます。 お試しの場合は忘れずに削除しておきましょう。

f:id:febc_yamamoto:20190912142656p:plain

おまけ: Terraformからの移行について

PulumiではtfファイルからPulumiのコードを生成できるtf2pulumiというツールも提供されており、Terraformからの移行を楽にしてくれています。

github.com

一からコードを書いても良いですが、こういったツールを利用することでコーディングが多少楽になるかもしれません。

終わりに

様々なプログラミング言語からInfrastructure as CodeができるPulumiとさくらのクラウドプロバイダーについて紹介しました。

リリースしたばかりでドキュメントなどが追いついていない場面もありますがぜひ使ってみてください!

以上です。

Terraform Cloud + さくらのクラウド プロバイダーを動かしてみる

Terraform Cloudがリリースされましたね!!

www.publickey1.jp

早速さくらのクラウドプロバイダーをTerraform Cloud上で動かしてみました。

Terraform Cloud事始め

通常のプロバイダーを使う手順はこちらに記事がありました。

dev.classmethod.jp

ワークスペースの作成〜VCS連携〜apply実行までの一通りの流れはこれに従えばOKです。

さくらのクラウドプロバイダーを使うには?

さくらのクラウドプロバイダーのような3rd プロバイダーを利用するにはちょっとした手順が必要になります。
この辺は以下にドキュメントがあります。

www.terraform.io

こちらによると、ワーキングディレクトリにterraform.d/plugins/linux_amd64/というディレクトリを作り、その中にlinux_amd64プラグインのバイナリを入れておけば良いとのことです。

他にもterraform-bundleを使う方法も用意されていますがこちらはTerraform Enterpriseのみですね。

febc-yamamoto.hatenablog.jp

ということでプラグインを配置した例を以下のリポジトリにおいてます。

github.com

tfファイル達と合わせるとこんな感じのレイアウトになりました。

f:id:febc_yamamoto:20190911115856p:plain

実行!!

あとはVariablesの設定などを行なってRunするだけです。今回はTerraform CloudのWebコンソールからRunしてみました。

まずはPlan

f:id:febc_yamamoto:20190911120120p:plain

問題なく動いているようです。このままApplyしてみました。

Apply

f:id:febc_yamamoto:20190911120146p:plain

ちゃんと作成されましたね!

Destroy

Destroyは不用意に削除されるのを防ぐためCONFIRM_DESTROY環境変数の設定が必要とのことでした。

f:id:febc_yamamoto:20190911120314p:plain

環境変数を設定すれば画面左下のボタンが押せるようになります。

あとはApplyと同じくPlan->Destroyするだけです。

f:id:febc_yamamoto:20190911120403p:plain

f:id:febc_yamamoto:20190911120427p:plain

終わりに

1チームあたり5ユーザーまで無料、それ以上の場合は有償版で$20/monthという価格となっています。

これはTerraformの実行環境として有力な選択肢となりそうですね!!
どんどん使っていこうと思っています。

以上です。

sakuracloud_exporter v0.7.0 − コレクターごとの無効化/fakeモードの追加 など

Prometheusのさくらのクラウド向けExporterであるsakuracloud_exporterのv0.7.0をリリースしました。

github.com

v0.7.0での主な変更/修正点は以下の通りです。

今回の修正はちょっと特殊な状況向けではありますが、ハマれば非常に便利なものだと思います。 順に紹介します。

コレクターごとの有効/無効切り替え

sakuracloud_exporterではさくらのクラウドAPIでリソース一覧を取得〜必要に応じて各リソースごとに詳細取得のためにさらにAPI呼び出し、という処理を行なっています。 このため、さくらのクラウド上に大量のリソースを持つようなケースでは一連のAPI呼び出しに長い時間がかかってしまうことがあります。

そこでこの問題への対応の一環としてコレクターごとに有効/無効を指定できるようになりました。
以下のフラグを用いて各コレクターごとに設定が可能となっています。

  • --no-collector.auto-backup: 自動バックアップ
  • --no-collector.coupon : クーポン
  • --no-collector.database: データベース
  • --no-collector.internet : スイッチ+ルータ
  • --no-collector.load-balancer: ロードバランサ
  • --no-collector.mobile-gateway: モバイルゲートウェイ
  • --no-collector.nfs: NFS
  • --no-collector.proxy-lb: エンハンスドロードバランサ
  • --no-collector.server: サーバ
  • --no-collector.sim: SIM
  • --no-collector.vpc-router: VPCルータ
  • --no-collector.zone: ゾーン情報

デフォルトでは全コレクターが有効となっています。

特定のコレクターだけ無効にするようなケースや、特定のコレクターだけ有効にして複数のexporterを起動するようなケースなどにご利用いただけると思います。

さくらのクラウドAPI呼び出しの代わりにローカルファイルから値を取得する「fakeモード」

このバージョンからGo言語向けさくらのクラウドAPIライブラリ libsacloud v2.0が利用されるようになりました。

libsacloud v2.0では主にテスト用の機能として、さくらのクラウドAPI呼び出しをラップしてダミーの応答を返す「fakeドライバー」という仕組みが導入されました。fakeドライバーはステートフルな処理(リソースの登録〜登録したリソースを後から参照、など)を行うためにステートを保持しています。ステートは保存先をインメモリ or ファイルから選べるようになっています。

このfakeドライバーを利用することでsakuracloud_exporterでサーバがダウンした状況やメンテナンスがスケジュールされた状況などを意図的に作り出すことを容易にするのが今回導入された「fakeモード」です。

fakeモードはibsacloudのfakeドライバーを利用してさくらのクラウドAPI呼び出しの代わりにステートファイルから値を取得してメトリクスを算出するモードです。

fakeモードの有効化

fakeモードの有効化は

  • 起動時のオプション--fake-modeの指定
  • 環境変数FAKE_MODEの指定

の何れかで可能です。

値はステートファイルのパスを指定します。

例えばカレントディレクトリのfake-store.jsonというファイルを利用する場合は以下のように指定します。

$ sakuracloud_exporter --fake-mode fake-store.json

ファイルが存在しない場合は新規作成されます。 (とはいえその状態だと何もリソースが存在しないためあまり意味はないでしょうが)

fakeモードではこのファイルからサーバやディスクといったリソースの情報を読み取ってメトリクスを出力します。

ステートファイルはJSONとなっており、以下のようなものです。

[
    {
        "Availability": "available",
        "CPU": 1,
        "CreatedAt": "2019-08-05T11:35:39.075614+09:00",
        "Description": "desc",
        "ID": "100000000022",
        "InstanceHostInfoURL": "",
        "InstanceHostName": "sac-is1a-svXXX",
        "InstanceStatus": "up",
        "InterfaceDriver": "virtio",
        "Interfaces": [
            {
                "HostName": "",
                "ID": 100000000028,
                "IPAddress": "",
                "MACAddress": "00:00:5e:00:53:01",
                "PacketFilterID": "",
                "PacketFilterName": "",
                "PacketFilterRequiredHostVersion": 0,
                "SubnetBandWidthMbps": 0,
                "SubnetDefaultRoute": "",
                "SubnetNetworkAddress": "",
                "SubnetNetworkMaskLen": 0,
                "SwitchID": 100000000008,
                "SwitchName": "",
                "SwitchScope": "",
                "UpstreamType": "",
                "UserIPAddress": "",
                "UserSubnetDefaultRoute": "",
                "UserSubnetNetworkMaskLen": 0
            }
        ],
        "MemoryMB": 1024,
        "Name": "example",
        "ResourceType": "Server",
        "ServerPlanCommitment": "standard",
        "ServerPlanGeneration": 100,
        "ServerPlanID": 100001001,
        "ServerPlanName": "世代:100 メモリ:001 CPU:001",
        "Tags": [
            "example",
            "server"
        ],
        "ZoneName": "is1a"
    }
]

ステートファイルの例として、sakuracloud_exporterが利用する各種リソースが登録されているものを以下に用意しています。

sakuracloud_exporter/example-fake-store.json at 0.7.0 · sacloud/sakuracloud_exporter · GitHub

ステートファイルはテキストファイルですのでエディタなどで編集することができるようになっています。

fakeモードの利用例: サーバのメンテナンス情報の登録

ここでは通常だと手動で発生させるのが難しい、サーバのメンテナンス情報の登録をfakeモードで行なってみます。

さくらのクラウドでのメンテナンス情報とは?

さくらのクラウドではサーバが稼働しているホストの不調などでサーバの再起動が必要になる場合があります。 (再起動することで別のホストで稼働させる)

メンテナンスは通常事前に通知され、期限までにユーザーが任意のタイミングでサーバの再起動を行うことが可能となっています。 また、メンテナンス情報はウェブサイト上で公開されているほか、APIからも参照できるようになっています。

これを利用してsakuracloud_exporterではメンテナンス情報を取得するためのメトリクスを提供しており、これらを利用して独自に監視/通知の仕組みを整えることができます。 (詳しくは以下で紹介させていますので参照ください)

medium.com

このメンテナンス情報ですが、当然ながらメンテナンスを任意に発生させるというのは困難です。
たまたまメンテナンス対象のサーバが手元にあればよいですが、そうでない場合がほとんどだと思います。

このためPrometheusでメンテナンス情報を監視/通知する仕組みを用意しても動作確認がすぐには出来ません。 これは困りますよね。

このような場面でfakeモードが役に立ちます。

ということでfakeモードでのexporterの起動〜メンテナンス情報の登録までをやってみます。

fakeモードを有効にしてexporterを起動

まずはfakeモードでexporterを起動してみます。 ステートファイルは先ほど紹介したGitHub上に公開されている例を用います。

# exampleステートファイルをGitHubからダウンロード
$ curl -sLO https://raw.githubusercontent.com/sacloud/sakuracloud_exporter/0.7.0/examples/fake/generate-fake-store-json/example-fake-store.json

# fake-modeオプションを指定してexporterを起動
$ sakuracloud_exporter --fake-mode example-fake-store.json

Prometheusのコンソールからサーバの情報を参照(sakuracloud_server_info)すると2台のサーバが存在することが確認できるはずです。

f:id:febc_yamamoto:20190806094126p:plain

ID: 100000000022と ID: 100000000035の2台ですね。

また、メンテナンス情報は sakuracloud_server_maintenance_infoで確認できます。

f:id:febc_yamamoto:20190806094434p:plain

ID:100000000035にはすでにメンテナンス情報が登録されていますね。 これはメンテナンス確認用として最初から登録されているやつです。 単にメンテナンス情報としてどのようなメトリクスが参照できるか確認したいだけの場合はこちらを利用すればOKです。

今回はメンテナンス情報の登録されていないID: 100000000022の情報を操作してメンテナンス情報を登録してみます。

ステートファイルを操作してメンテナンス情報を登録

次にステートファイルexample-fake-store.jsonをエディタなどで修正してメンテナンス情報を登録します。 JSON内のID: 100000000022のサーバの部分を探し出し、InstanceHostInfoURLというフィールドにhttp://support.sakura.ad.jp/mainte/mainteentry.php?id=26595という値を設定します。

JSONは以下のようになっているはずです。

// 該当部分だけ抜粋
    {
        "ID": "100000000022",
        "InstanceHostInfoURL": "http://support.sakura.ad.jp/mainte/mainteentry.php?id=26595",

ファイルを編集して保存するとexporterにより自動で再読み込みが行われます。 その後(Prometheusによるスクレイピングの後に)Prometheusのコンソールで再度メンテナンス情報を確認するとID: 100000000022のサーバにもメンテナンス情報が登録されたことが確認できます。

f:id:febc_yamamoto:20190806095559p:plain

これでメンテナンス情報を登録することができました。 逆にメンテナンス情報のクリアもできますのでアラートルールの確認などに便利にお使いいただけると思います。

終わりに

sakuracloud_exporter v0.7.0の紹介でした。 徐々に便利になってきてますのでぜひご利用&フィードバックいただけると嬉しいです。

以上です。

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング

【小ネタ】Terraformで子リソースに分割されたリソース定義をdynamic blockを使って書き直す例

GitHubで質問もらったやつが例として手頃だったのでブログ書いておきました。

github.com

やりたいこと

Terraform v0.11以前までの親リソース/子リソースに分けて定義していたリソースをv0.12で導入されたdynamic blockに書き直す

v0.11以前

ここではrke_clusterリソースの子リソースとしてdata rke_node_parameterを定義しています。

# locals to allow us to control which nodes get assigned manager roles vs. controlplane and workers
locals {
  mgr_roles    = ["controlplane","etcd"]
  worker_roles = ["worker"]
}

# rke_clusterリソースに対する子リソース(node)の定義
data rke_node_parameter "nodes" {
  count   = "${var.NODE_COUNT}"
  address = "${azurestack_public_ip.vmpip.*.ip_address[count.index]}"
  user    = "myuser"
  role    = "${split(",", count.index < var.nbr_managers ? join(",", local.mgr_roles) : join(",", local.worker_roles))}"
  ssh_key = "${file("path/to/sshkey")}"
}

resource rke_cluster "cluster" {
  depends_on = ["azurestack_public_ip.vmpip", "azurestack_virtual_machine.vm"]

  # 子リソースの定義
  nodes_conf = ["${data.rke_node_parameter.nodes.*.json}"]
}

v0.12のdynamic blockを使って書き直し

子リソースdata rke_node_parameterrke_clusternodesにdynamic blockを使って書き直してます。

# locals to allow us to control which nodes get assigned manager roles vs. controlplane and workers
locals {
  mgr_roles    = ["controlplane","etcd"]
  worker_roles = ["worker"]
}

resource rke_cluster "cluster" {
  depends_on = ["azurestack_public_ip.vmpip", "azurestack_virtual_machine.vm"]

  dynamic nodes {
    for_each = azurestack_public_ip.vmpip.*
    content {
      address = nodes.value.ip_address
      user    = "myuser"
      role    = split(",", nodes.key < var.nbr_managers ? join(",", local.mgr_roles) : join(",", local.worker_roles))
      ssh_key = file("path/to/sshkey")
    }
  }
}

ポイント

まずはこちらのドキュメントには目を通しておきましょう。

www.terraform.io

その上で書き換えのポイントとしては、

  • for_eachにはvariable以外にもresourceやdataも指定できる
  • for_eachにリスト要素を指定した場合、contentブロック内で<element>.keyとすればインデックスを、<element>.valueで値を参照できる

あたりでしょうか。

contentブロック内でイテレート対象の値を参照する際は<element>.valuevalueをつける必要がある点に注意です。(よく間違える)

なお、書き直しするにはプロバイダー側で親リソース内に子リソースの定義を書けるようになっていることが必要です。
(例: azurerm_virtual_machineリソースのstorage_data_diskみたいにブロックでもリソースでも定義できるようになっていること)

終わりに

この類の書き換えはterraform 0.12upgradeで自動置き換えできないので手動で書き換える必要があります。 (書き換える必要があるかは別問題として)

dynamic blockを使えばより簡潔に書ける or 処理が早くなる(反映処理時のロックが不要になったり)などの恩恵を受けられる可能性もありますので使いすぎに注意しつつどんどん使いましょう

以上です。

さくらのクラウド: k3OSパブリックアーカイブなら手軽にRioが使える

f:id:febc_yamamoto:20190627152947p:plain

k3OSがパブリックアーカイブ

さくらのクラウドにk3OSのパブリックアーカイブが追加されましたね!

cloud-news.sakura.ad.jp

ISOイメージと違い、パブリックアーカイブであれば「ディスクの修正」という機能でIPアドレスの設定やSSH公開鍵の設定が行えるようになります。

これを使えば非常に手軽にk3sによるKubernetes環境が手に入りますね。

さらにk3sが動くということはRioが動くということです。
Rioが動かせればKnative/Istio/Prometheus/Grafana/Kiali/BuildKit/イメージレジストリなどを内包していますのでこれらも使えるようになります。

(Rioについては以下スライドを参照ください)

speakerdeck.com

ということで早速試してみました。

パブリックアーカイブからk3OSをインストールしてみる

早速k3OSパブリックアーカイブを用いてサーバ作成を行ってみます。

CLIであるUsacloudは本日リリースされたv0.25.0からk3OSに対応しましたのでこちらを利用します。

github.com

$ export PASSWORD=your-password
$ usacloud server build --os-type k3os --core 2 --memory 4 --password "$PASSWORD" --name k3os -y

もちろんコンパネから作成してもOKです。

SSHで接続

作成したらSSHで接続してみます。rancherユーザーで接続できるはずです。

$ usacloud server ssh --user rancher k3os

接続できたら各種コンポーネントが動いているのが確認できるはずです。

$ kubectl cluster-info

$ kubectl get cs

これでKubernetesが使えるようになりましたね。

Rioのダウンロード

次にRioをインストールします。まずrioコマンドをダウンロードします。

$ sudo curl -L -o /usr/local/bin/rio https://github.com/rancher/rio/releases/download/v0.1.1/rio-linux-amd64
$ sudo chmod +x /usr/local/bin/rio

これでrioコマンドが使えるようになります。

rio installの実行

次にRioの各コンポーネントKubernetes上にデプロイします。

$ rio install

しばらく待つと以下のようなメッセージが表示されデプロイが完了するはずです。

Welcome to Rio!

Run `rio run https://github.com/rancher/rio-demo` as an example

Rioを動かしてみる

まずはRioの各コンポーネントがデプロイされているか確認してみます。 確認はrio -s psを用います。 (-sまたは--systemオプションはRioのシステムコンポーネントを表示するためのオプションです。)

$ rio -s ps

手元の環境では以下のように表示されました。

f:id:febc_yamamoto:20190627150633p:plain

動いているようですね!GrafanaとKialiについては表示されたURLをブラウザで開けるようになってます。 (Grafana/Kialiともユーザー名とパスワードはadminになってます)

f:id:febc_yamamoto:20190627150822p:plain

f:id:febc_yamamoto:20190627151011p:plain

あとはrio runなどをお好みで試してみましょう!

片付け

使い終わったら不要な課金を防ぐために以下のコマンドでサーバの削除を忘れずに行っておきましょう。

$ usacloud server rm -f k3os

終わりに

k3OS+パブリックアーカイブで非常に手軽にKubernetes環境を使えるようになりましたね!
k3sが動けばRioのようなKubernetes上で動くプロダクトもちゃんと使えるはずです。 夢が広がりますね!!

ぜひお試しください!

以上です。