Screaming Loud

日々是精進

goaでXMLを生成する

goaとはgoのWebフレームワークです。

goa.design

goでリクエストとレスポンスを定義してあげると、APIとswagger周りを生成してくれるので、便利なライブラリです。

詳しくはこちら

The goa API Design Language · goa :: Design-first API Generation

今回goaでjsonの例はあるのですが、XMLの生成のサンプルがないので作りました。 基本的にはgoの encodign/xml を参考にすればできました。

design

基本的には Attribute を追加すると、タグの間に挿入されます。

属性やCDATAなど内容以外のものはMetadataとしてAttributeに定義してあげると反映されます。

design

xmlとそれに対応したgoaの書き方をまとめます。

ベース

<User></User>
var User = MediaType("vnd.application/user+xml", func() {
    TypeName("User")
    ContentType("application/xml")
})

属性

<User id="1234"></User>
var User = Type("User", func() {
    Attribute("ID", String, "user id", func() {
        Metadata("struct:tag:xml", "id,attr")
    })
    Required("ID")
})

Metadata内の id が属性名で、attrは属性であることを明示している。

内容

<User>
  <Name>太郎</Name>
</User>
var User = Type("User", func() {
    Attribute("Name", String)
})

CDATA

<URL><![CDATA[http://www.google.com]]></URL>
var URL = Type("URL", func() {
    Attribute("CDATA", String, func() {
        Metadata("struct:tag:xml", ",cdata")
    })
})

属性と同じように cdata はcdataであることを示している。 キー名はないので空。

配列

<User>
   <Friend>次郎</Friend>
   <Friend>三郎</Friend>
</User>
var User = Type("User", func() {
    Attribute("Friend", ArrayOf(String))
})

CircleCI上でdockerの上でdockerを動かす

AWS ECRのイメージ上でCIを実行したかったからこんなことをしてた。

CirclCI 2.1の機能を一部つかってます。

commands定義

railsのbundle install を実行する例 adminというディレクトリにrailsのファイルを入れている想定

commands:
  build_on_docker:
    parameters:
      env: 
        type: string
    steps:
      - setup_remote_docker 
      - run: |
          Image={accountID}.dkr.ecr.ap-northeast-1.amazonaws.com/test-image:<< parameters.env >>
          docker pull ${Image}
          docker create -v /data --name mounter alpine:latest /bin/true
          docker cp  ~/admin mounter:/data
          docker run --volumes-from mounter --name builder bundle install --path /data/admin/vendor/bundle --gemfile=/data/admin/Gemfile
          docker cp builder:/data/admin/vendor /root/admin/

最初普通の -v でjob作ったんだけど、mountされなかった。 あと、volumes-fromは実際mountしてるわけでないのか?

以下リンクにrwでもマウントできると書いてあるけど、volumes-fromでrunしたcontainer上の変更が反映されないからcpでホスト側にコピーしてる

docker run | Docker Documentation

machine trueにしないと、普通の-vではmountできないようなので、以下のようにした。

  • alpine上に/data を作る
  • ~/adminをalpine上にcpする
  • ecr imageをvolumes_fromで見ながらcontainer up
  • ホスト側に変更情報が共有されないから再度containerからホスト側へcp

job

jobs:
  docker:
    - image: ruby:2.5
  build-job:
    - checkout
    - $(aws ecr get-login --no-include-email)
    - build_on_docker:
         env: 'staging'

後日談

実はこんなことをしなくてもcontextsを使って付与してあげるなり、access_keyを使うなりすればECRのイメージをbuildに使うdockerとして使えることがわかった。

参考URL

stackoverflow.com

circleci.com

envoyのsidecarでgRPCを受ける with docker-compose

スマブラのオンラインにあんま入ってなかったら、めっちゃ世界は強くなってて萎えてます。

envoyを触っているので、そのメモです。

envoyとは

いわゆるproxyです。簡単に言うとリクエストを受けて、いろいろ処理をしてからバックエンドに流すやつですね。

gPRCをリクエストで受けて、そのリクエストをLBのように分散することができます。

似た役割ではnginxなどがあてはまり、他にもいくつか似たようなツールが紹介されています。

www.envoyproxy.io

envoyに関しては、kubernetes文脈ではdata planeとして語られることが多いですが、ただのproxyなのでkubernetesでなくてももちろん使えます。

対応しているリクエストの種類も多く、Mongo、Dynamo、Redisの負荷分散などもできます。

www.envoyproxy.io

その他にも機能がかなり豊富なので、調べてみると面白いかもしれません。

あとは、envoyはシングルプロセス、マルチスレッドで動くためnginxのようなマルチプロセスよりもcontainerに向いていると思っています。

www.envoyproxy.io

envoyという選択は、AWSのAppMeshでも使われるので、今後メインのsidecar proxyとして使われることが予想されるでしょう。

aws.amazon.com

やりたいこと

やりたいことは以下です。

  • envoyをsidecar *1 に乗せて、goのアプリケーションを動かしたい。
  • front serverとbackend serverの通信はgRPC

図で表すと以下のような形になります。

f:id:yuutookun:20190203182310j:plain

実際の設定

以下のページでサンプルがあるのですが、sidecar形式ではなくbackendのアプリケーションと同じcontainerにenvoyを乗せていました。

www.envoyproxy.io

なので、sidecar形式にするようforkして作りました。 以下のレポジトリの examples/grpc-bridge 以下です。

github.com

動かし方

本家とほぼ同じです。GOPATHがちゃんと設定されていれば、以下手順で動くはず。 docker-composeが複数あるので、 build.sh にまとめています。

$ pwd
envoy/examples/grpc-bridge
$ script/bootstrap
$ script/build
$ script/build.sh

envoyの設定

基本的にenvoyの設定は以下です。

static_resource
 - listener: 受け側の設定
 - cluster: 流し先の設定

listenersのfiltersの中でどのclusterに流すかという設定をします。 例えば、python containerからsidecar containerへは routes にて、prefixやclusterの設定をすることでどこに流すかを決めます。

clusterの設定では、typeでIPの解決をどうするかを決めます。

- static: 単一のホストのみ
- strict DNS: DNSで解決されたIPのみ
- logical DNS: DNSで返される一つのIPを利用。ホスト全IPは取らず、初回接続のみIP解決

詳しくはこちら service_discovery

まとめ

docker-composel環境で動かすというのを説明を交えながら、解説してみました。

*1:sidecarに関しては、ここが詳しい https://docs.microsoft.com/ja-jp/azure/architecture/patterns/sidecar

新宿カレーポーク中辛

今回は「新宿カレーポーク中辛」です


f:id:yuutookun:20190201085655j:image

京王線などの駅の近くに出店しているC&C が提供しているカレーです。

食べた感じはまさにあの店舗の味という感じでした。

 

食べる前からあまり期待していなかったので、逆に期待以上でした。