サカナ未遂

プログラミング、筋トレ、子育て

CloudRunを使ってみた

GCPのCloudRunというサービスを使うことがあったので簡単な使い方をメモっときます。

CloudRunとは

公式URLより https://cloud.google.com/run?hl=ja

コンテナ化されたアプリケーションをすばやく安全にデプロイ、スケーリングできる、フルマネージド型のコンピューティング プラットフォーム

とあります。 コンテナに入れたwebアプリを、そのままデプロイできるってことですね。 GCPのContainerRegistoryにコンテナをpushし、CloudRunでデプロイするだけで動かせます。

CloudRunの料金

https://cloud.google.com/run/pricing?hl=ja f:id:tera_chan3700:20200618212128p:plain

ちょっと試すくらいならほぼ無料で使えます。

あとContainerRegistoryの料金がかかりますが、これも微々たるものです。 https://cloud.google.com/container-registry/pricing?hl=ja 個人で試すには懐が痛まなくて好きそうです。

注意

CloudRunからCloudRun、または他のサーバレスを無限ループで呼ぶような処理があると危険です。そこは個人で気をつけてください。 例:https://blog.mmmcorp.co.jp/blog/2019/12/25/lambda-cloud-bankruptcy/ これはAWSですが、GCPでも起こりえます。

サンプル

GOで簡単なエコーサーバーを作ります

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httputil"
)

func handler(w http.ResponseWriter, r *http.Request) {
    dump, err := httputil.DumpRequest(r, true)
    if err != nil {
        http.Error(w, fmt.Sprint(err), http.StatusInternalServerError)
        return
    }
    fmt.Println(string(dump))
    fmt.Fprintf(w, "<html><body>hello Cloud Run!!!</body></html>")
}

func main() {
    var httpServer http.Server
    http.HandleFunc("/", handler)
    log.Println("start http listening :8080")
    httpServer.Addr = ":8080"

    log.Println(httpServer.ListenAndServe())
}

8080ポートにアクセスすると、「hello Cloud Run!!!」の文字列を返すサーバーです。 実行して確認します。

$ go run main.go
2020/06/18 20:01:04 start http listening :8080

サーバーが起動したのでアクセスしてみる f:id:tera_chan3700:20200618213242p:plain

レスポンスが帰ってきました。

次にこれをビルドして実行するDockerfileを作ります。

FROM golang:latest

#ディレクトリ作成
WORKDIR /go/src/go-image
#ホストOSのmain.goをWORKDIRにコピー
COPY main.go .

#バイナリを生成
RUN go install -v .

#バイナリを実行
CMD ["go-image"]

これをビルドします。

$ docker build -t gcr.io/<自分のプロジェクトID>/cloudrun-test:v1 .

ローカルで実行してみます

$ d run -p 8080:8080  gcr.io/<自分のプロジェクトID>/cloudrun-test:v1

アクセスします。 f:id:tera_chan3700:20200618213636p:plain 動きました。ちゃんとコンテナの中で起動することが確認できました。

コンテナレジストリへのpush

今回はステージングをかります。 gcloudコマンドで事前にログインしています。

GCPにpushする。

docker push gcr.io/<自分のプロジェクトID>/cloudrun-test:v1

入ったことを確認 f:id:tera_chan3700:20200618213808p:plain

CloudRunへのデプロイと実行

サービスを作成をクリック f:id:tera_chan3700:20200618213957p:plain

適当に入力して「次へ」をクリック f:id:tera_chan3700:20200618214119p:plain

さっきpushしたイメージを選択して作成ボタンをクリック f:id:tera_chan3700:20200618214315p:plain

しばらくするとデプロイが完了し、エンドポイントが作成されます。 f:id:tera_chan3700:20200618214521p:plain

ここにアクセスします。 f:id:tera_chan3700:20200618214609p:plain

動きました。 ローカルで作ったコンテナが簡単にデプロイでき、動かすことができます。 タイムアウトなど制限もありますが、ローカルで動いてるコンテナを簡単にデプロイできるのは便利です。

gRPCについて学んだこと

会社の業務でgRPC触ることがあったのですが、そもそもRPCってなんぞやって状態でしたので、勉強してみることにしました。

まずgRPCを勉強しようと思った時に、不明な用語があったのでそれらを整理してから進めることにしました。  

RPCとは

まずRPCは、Remote Procedure Call(遠隔手続き呼び出し)の略で、プログラムから別のアドレス空間にあるサブルーチンや手続きを実行することを可能にする技術のこと。

でgRPCは、Google社内で使われていたRPCフレームワークOSS化され、gRPCと名前がついたもののことだそうです。 ちなみにgRPCのgはGoogleのgではないです。バージョン毎にいろいろg縛りの言葉がついてるようです。 ここに書いてた GRPC Core: g_stands_for

Protocol Buffersとは

gRPCはデータをProtocol Buffersにシリアライズしてやりとりを行う。 Protocol BuffersもGoogleが開発したフォーマットで、XMLとの比較で、3〜10倍小さく、20〜100倍高速であると主張しているとのこと。

ProtocolBuffersは、protoファイルを作成します。 ファイルをコンパイルすると任意の言語用のコードを自動で作成してくれます。 GoやRubyなど様々な言語に対応しています。 現在はproto3です(いつから3なのか、2との違いは何なのかちゃんと調べてない)

試してみる

公式のチュートリアルの通りにやってみる。 まずサンプルをダウンロードし、ディレクトリ移動

$ git clone -b v1.28.1 https://github.com/grpc/grpc
$ cd grpc
$ cd examples/ruby

サーバーを起動する。

$ ruby greeter_server.rb

別のターミナルでクライアントを起動

$ ruby greeter_client.rb
# 結果が帰ってくる
"Greeting: Hello world"

どういう仕組みかコードを確認。

まずgreeter_client.rb

# GreeterServer is simple server that implements the Helloworld Greeter server.
class GreeterServer < Helloworld::Greeter::Service
  # say_hello implements the SayHello rpc method.
  def say_hello(hello_req, _unused_call)
    Helloworld::HelloReply.new(message: "Hello #{hello_req.name}")
  end
end

# main starts an RpcServer that receives requests to GreeterServer at the sample
# server port.
def main
  s = GRPC::RpcServer.new
  s.add_http2_port('0.0.0.0:50051', :this_port_is_insecure)
  s.handle(GreeterServer)
  # Runs the server with SIGHUP, SIGINT and SIGQUIT signal handlers to 
  #   gracefully shutdown.
  # User could also choose to run server via call to run_till_terminated
  s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT'])
end

mainでRPCサーバーを0.0.0.0:50051で起動しハンドラーにGreeterServerを設定している。 GreeterServersay_helloというメソッドを持ち、 Helloworld::HelloReply.new(message: "Hello #{hello_req.name}")(これはhelloworld_services_pb.rbに定義されていた。) を実行する。 Hello + リクエストのnameプロパティの値を返す

クライアント側

def main
  stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure)
  user = ARGV.size > 0 ?  ARGV[0] : 'world'
  message = stub.say_hello(Helloworld::HelloRequest.new(name: user)).message
  p "Greeting: #{message}"
end

gRPCのスタブを生成し、say_helloメソッドに"world"を渡す。 サーバから帰ってきたメッセージにGreetingを付加して出力している。

所感

まずはこんな感じってのがわかった。 クライアントからサーバーのメソッドを呼び出すという概要は理解できた。 チュートリアルの最初の最初をやっただけなので、protoファイルの作り方やストリーミング など、もっと学習していこうと思います。

参考にさせていただいた資料

booth.pm

grpc.io

k8sで複数環境を触るときに便利なツール

kubernetesで操作する環境が増えてくると、想定外の環境にデプロイするような事故が増えてくるので、少しでも事故を減らすためのツールを紹介します。

kubectx

コンテキストを簡単に切り替えてくれるツール

インストール

$ brew install kubectx

コンテキスト切り替え

# 特定の環境に切り替え
$ kubectx gke_my-project-development_asia-northeast1-a_sample-cluster

、、、、コンテキストが長い…

別名をつけることができる。

$ kubectx MYDEV=gke_my-project-development_asia-northeast1-a_sample-cluster

これで、別名で切り替えることができる。

# 開発環境に切り替え
$ kubectx MYDEV
# 本番に切り替え(本番の別名をつけておく)
$ kubectx PROD

kube-ps1

実行中のコンテキストをプロンプトに表示させることができる。 https://github.com/jonmosco/kube-ps1

インストール

$ brew install kube-ps1

.bashrcの設定

# .bashrc
PS1='\u:\W\$'   # プロンプト表示を、ユーザ名とカレントディレクトリのみにしている(ここは各自の好みで)
source "/<インストールパス>/kube-ps1/share/kube-ps1.sh"
PS1='$(kube_ps1)'$PS1
kubeoff      # デフォルトでオフにしておく
# 表示
$ kubeon

# 非表示
$ kubeoff

こんな感じで表示される

$ kubeon
# ステージングに切り替え
$ kubectx STAGE
(⎈ |STAGE:default)username:workspace$

# 本番に切り替え
$ kubectx PROD
(⎈ |PROD:default)jusername:workspace$

$ kubeoff
username:workspace$

これで自分が操作中のコンテキストを確認しながら作業できるので、少しは安全になります。

転職して約半年が経ちました

5月も終わりになってきて、転職して約半年が経ちます。

 

当初の目標としては、業務以外でももっとたくさんコードを書いてるつもりだっんですが、思った以上に知らないことが多すぎて、そのキャッチアップに追われ、なんとも自身を無くしています。

 

特にインフラ周りの知識がほとんどなく、Docker、k8sGCP、terraformなどのツールやサービスの情報収集に終われ、自身の英語力のなさから来る公式リファレンスを読む遅さと相まって、思った以上に捗らず仕事に追われています。

 

またプライベートでも、妻がフルタイムで働き始めたことによる家事の増加、娘が小学校に入学したことで、出発の時間がこれまでより遅くなり、その分出社が遅れ、退社時間がずれるなど色々ドタバタしていて、仕事以外でなかなかスキルアップの時間が取れない日々が続きました。

 

その対処として、食器洗浄器と、衣類乾燥機を買うことで家事にかかる時間の削減を行いました。

特に衣類乾燥機は、洗濯の後の、「干す」、「取り込む」の二つのプロセスをなくすことができるので(完全には無理ですが)相当の時間短縮になります。

食器洗浄器は、洗う量に対して洗ってる時間が長いので、手で洗った方がいいかと思ったりしますが、洗い終わった後の疲労感がなくなるので、とりあえず毎回使っています。

そんなこんなで、一日1時間半は自分の時間が作れそうなので、まあ焦らず地道にスキルアップしていこうと思います。

 

RubyKaigi2019に参加してきました。

久々にブログを書きます。

タイトルの通り、RubyKaigi2019に参加してきました。 4/18〜20で福岡で開催で、特に一緒にいく同僚もいないので一人ぼっちで行ってきました。

去年Rubyを始めたので、RubyKaigiがどういうものか全然知りませんでした。 あまり詳しくないのですが、相当レベルが高く、自分が行ってもどうなんだろうと思っていました。 去年の末くらいにチケットが発売された後も、行こうか迷っていたのですが、去年末の品川で開催された「Ruby Business Users Conference 2018 Winter」でRuby開発者のMatz(まつもとゆきひろ)さんとお話する機会があり、Ruby会議は楽しいし、初心者でも大丈夫と言っていたので、参加することに決めました。
実際Ruby歴1年ちょっとでは、セッションの内容は高度で、さらに国外のエンジニアの英語スピーチは理解が追いつきませんでしたが、Rubyコミッターの方々の、もっとRubyをよくしていこうという熱い思いは感じ取ることができました。 ぼっちで参加しましたが、東京で顔見知りの方々にアフターパーティで混ぜてもらったり、なんだかんだで楽しく過ごすことができました。 来年は長野県の松本ということで、また絶対に行きたいと思います。

転職後の勉強について

新しい会社に入社し、もうすぐ1ヶ月が経ちます。

まだ不慣れなこともあり、毎日2時間近く残業しているので、業務中以外のインプットもアウトプットも転職後にかなり滞っています。

 

今年は、RubyRailsももっと深く理解したいと思っているし、AWSGCP、DockerやK8sなどインフラ周りの勉強を進めようと思っていたのですが、なかなか時間が取れない状態となっています。

 

ただ自習の時間が取れなくても、業務でDockerやGoogleCloud周りを結構こねくり回したのでかなり理解が進みました。

自習では、ある程度わからないことがあると理解しないまま進んだり、別のことやったりと逃げることもできましたが、業務だと逃げる訳にも行かないので、必死にドキュメントを読み、手を動かし試行錯誤を繰り返して、なんとか業務を進めて行きました。

この後は、テストコードの整備とRuboCopの導入タスクを一人で行なっていくので、この辺りのスキルも業務中に身に着けることができると思っています。

仕事しているだけで、勉強している様なものなので、業務に慣れるまで、自習時間が取れなくても仕方がないと割り切る様にしています。

 

この先は会社がリモートワークを導入するとのことなので、通勤時間がなくなった分、自習に当てられるので、業務+自習で去年以上のスピードで成長できそうな感じがしています。

(去年までは業務で使う技術が古すぎて勉強にならなかった、、、)

 

身につけたDockerとかCloudBuildの知識も、ブログにアウトプットして行きたいなと思っているので、時間が取れたらまとめて公開します。

新しい会社に入社して1週間が経ちました。

2019年が始まりました。
去年末で前の会社を退職し、今年から新しい会社で働き始めました。


入社して1週間が経ち、少しは慣れてきたので、新しい会社について感想を書いていきます。
まず、今の会社は、自社製のクラウドサービスを提供している会社です。

(会社に許可取ってないので、会社名と詳しい業種は伏せます)

 会社は自社オフィスではなくてコワーキングスペースに入居していて、他の会社の人や一般の方なんかも出入りしています。

なので、基本的にフリーアドレスで、座りたいところに座っています。

マシンはMacBookPr13インチ、メモリ16GBの新品を支給してもらいました。

去年末にHHKBを買ったので尊師スタイルで業務を行なっています。

でも、もう少ししたらディスプレイを買ってくれるらしいので、そうなったら席は固定されるかもしれません。


社員は10人くらいでしょうか、時短の方や、インターン、週2、3の方もいて、よく把握していません。

創業して4年くらいの会社で良くも悪くもルールとかあまり決まってなくゆるい感じです。遅刻の連絡がslackで「遅れまーす」見たいな感じでくるので、これがWeb系スタートアップか!とカルチャーショックを受けています。

 

勤怠管理はジョブカン、労務系はSmartHR、会社の業務タスクはTrello、開発のタスクはGitHubにissueあげて、ZenHubで管理しています。

全くのペーパレスだし、どこでも作業ができます。

現在、定時9:30〜18:30の8時間労働となっていますが、フレックスを導入するか、リモートワークをどこまで許可するかなどの就業規則を作っているところとのことです。

 僕はあんまり通勤は苦ではないし、家だと家事とか気になって集中できないのでそんなにリモートワークにはこだわってないのですが、子供が熱出したり、保育園の面談なので一日休まないといけないことがあるので、そんな時はリモートワークができると嬉しいので、リモートワーク制度は作って欲しいところです。

 

使用している技術ですが、フロントがVue.jsでバックエンドをRailsで作っています。

クラウドGCPで、GoogleCloudBuildを使ってDockerイメージを作ってデプロイし、

K8sでDockerイメージを管理しています。 

その他ワークフローエンジンはdigdag、Node.jsやGolangでできたアプリもあります(まだ全体をつかめていない。)

前にRubyで作っていたアプリを理由あってNode.jsに置き換えたみたいです(Ruby好きとしては残念です)

担当はこの辺り全般をやることになりそうなので、しばらくは忙しい日々になりそうです。

あらかたできるようになったらフルスタックエンジニアとか名乗れちゃうかな〜なんて思ったりしています。

 

この1週間の作業としては、最初に3日ほどは環境構築とコードリーディングして、そのあと開発作業に入りました。

新しく作った機能をプルリクしたら、マージされその日のうちに本番環境にデプロイされました、、、

SIerにいた時はたった1行の修正でも、リリースの資料とテストケース、エビデンス作って、上長のハンコもらい、偉い人に説明に行って許可もらい、休日前の深夜のシステムが止まっている時間に出社して二人体制でリリースし、翌営業日のシステム稼働前に出社して待機し、稼働確認取れたら、また偉い人に報告してリリース完了資料を作成して終わり!って流れだったのに、このスピード感半端ないっす、、、

 

ってことでしばらくは会社で使う技術の深掘りをして、余裕が出てきたら新しい技術の勉強なんかも続けて行きたいと思っています。