20190711のGoに関する記事は2件です。

ISUCON8を練習してみてる。

ISUCON8予選問題を解いてみる!

随時更新していく。

目的

  • DeNAインターン(プロダクト開発コース)で優勝したい。
  • ISUCON9に参加したい。
  • 自信を取り戻したい。

環境構築

https://github.com/isucon/isucon8-qualify

事前調査

https://blog.okashoi.net/entry/2018/09/18/183423
https://blog.zoe.tools/entry/2018/09/16/192835

やること

計測ツールの使い方を学ぶ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

KubernetesのPod内からObjectを生成する

kubernetes便利ですよね。

golangでkubernetesを操作するときはclient-goという便利なライブラリがあるので、基本的にはこれを見れば完結します。
しかし、最近CRD(Custom Resource Definition)という自作Objectを作成したときに色々ハマったので、記事として残しておきます。

Objectとは

要はDeploymentとかServiceとかのことです。
今回は簡単のために、Jobを使います。
適宜自分が使いたいものに変えてください。

CRDを使わない場合

1つ目の方法はclient-goを使うものです。
client-goは名前そのままでkubernetesと通信をするためのクライアントのライブラリです。
以下のコードは簡単なJobを起動するためのコードです。

package main

import (
    "log"

    batchv1 "k8s.io/api/batch/v1"
    apiv1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
)

func main() {
    config, err := rest.InClusterConfig()
    if err != nil {
        panic(err.Error())
    }

    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }

    jobClient := clientset.BatchV1().Jobs("default")

    job := &batchv1.Job{
        // 省略...
    }

    job, err = jobClient.Create(job)
    if err != nil {
        log.Printf("Failed to create job: %v", err)
    }
}

この方法の欠点としては k8s.io/client-go/kubernetesに存在しているものしか作ることは出来ません。(DeploymentとかJobとか)
なので、もしCRD(Custom Resource Definition)を使う場合は上の方法では作成することは出来ないようです。(* 後ろの方にCRDでも実装する方法を書いています。)
その場合は以下の方法で作成してみてください。

CRDを使う場合

こっちもclient-goは使ってはいるのですが、メインはcontroller-runtime/pkg/clientです。

package main

import (
    "context"
    "fmt"
    "log"

    batchv1 "k8s.io/api/batch/v1"
    apiv1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/runtime"
    "k8s.io/client-go/rest"
    clientPkg "sigs.k8s.io/controller-runtime/pkg/client"
)

func main() {
    // Kubernetesの設定
    config, err := rest.InClusterConfig()
    if err != nil {
        panic(err.Error())
    }

    scheme := runtime.NewScheme()
    batchv1.AddToScheme(scheme)
    option := clientPkg.Options{
        Scheme: scheme,
    }

    client, err := clientPkg.New(config, option)
    if err != nil {
        fmt.Println(err)
        return
    }

    job := &batchv1.Job{
        // 省略...
    }

    ctx := context.Background()

    err = client.Create(ctx, job)
    if err != nil {
        log.Printf("Failed to create job %v\n", err)
    }
}

気をつけるポイントとしては、

batchv1.AddToScheme(scheme)

の部分です。ここを適宜CRDのディレクトリのSchemeとして指定すると良いです。

ちなみにCRDを使って最初の方法で実装出来るらしいです。

参考記事

上の記事はちゃんと見たわけでは無いですが、自分でClientを自作して呼び出している感じですね。

地味にハマったポイント

今回は client-goのv11.0.0を使っていたんですが、以下のようなエラーが結構出てきました。
ググればすぐに解決策が出てくるのですが、念の為ここにも書いておきます。

# k8s.io/client-go/rest
../pkg/mod/k8s.io/client-go@v11.0.0+incompatible/rest/request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
    have (*versioned.Decoder)
    want (watch.Decoder, watch.Reporter)

Go modulesを使っている場合は以下のようになると思います。
引用元: client-go/INSTALL.md

$ go get k8s.io/client-go@v11.0.0              # replace v11.0.0 with the required version (or use kubernetes-1.x.y tags if desired)
$ go get k8s.io/api@kubernetes-1.14.0          # replace kubernetes-1.14.0 with the required version
$ go get k8s.io/apimachinery@kubernetes-1.14.0 # replace kubernetes-1.14.0 with the required version

実装したリポジトリ

https://github.com/kitagry/kube-test

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む