Upgrade to Pro — share decks privately, control downloads, hide ads and more …

microservices-infrastructure-with-hashicorp-suite

shuhei
July 02, 2020

 microservices-infrastructure-with-hashicorp-suite

HashiTalks: Japan 2020 での発表資料です

shuhei

July 02, 2020
Tweet

Other Decks in Technology

Transcript

  1. Shuhei Kunikane @ LINE Corporation at HashiTalks: Japan 2020 (2020.7.2)

    Hashicorp Suiteで実現する マイクロサービス基盤 – Nomad編
  2. • Shuhei Kunikane 国兼 周平 @shuheikun_i (twitter) • LINE Corporation

    フィナンシャル開発センター SREチーム • 主にLINE証券の基盤を担当 ABOUT ME
  3. LINE証券 ABOUT OUR SERVICE • 2019.08 OTCでの株式取引サービス開始 • 2019.10 かんたん本⼈確認(eKYC)開始

    • 2019.11 投資信託サービス開始 • 2020.03 FXサービス開始 • 2020.05 取引所取引および信⽤取引サービス開始 • 2020.06 投資信託のつみたて投資サービス開始 ←本⽇紹介する基盤の運⽤開始
  4. 構成要素 l Hashicorp社のService Networking⽀援ツール l Service Discovery / Healthcheck システム内で稼働するサービスの状態を収集し状態を監視

    リクエストに応じてクライアントにサービス情報を提供 l KVS Key-Valueで構成されるデータストア アプリケーションのconfiguration repositoryとしても利⽤可能
  5. 構成要素 l Hashicorp社のSecret Managementツール l Tokenやパスワードの⽣成 / 配布 / 管理

    l 機密情報の安全な保存 / 提供 l PKI CAとしてサービス提供
  6. 構成要素 l ⾼機能・⾼性能 Proxy Server l xDS Listener, Route, Cluster,

    Endpoint, Secret など、様々な設定を管理サー バ(Control Plane)から動的に取得し動的に反映
  7. Subsystem-B Subsystem-A Service Mesh Router Cluster API-Gateway-A Cluster Client Hardware

    LoadBalancer Envoy Envoy Envoy Application Envoy Service-A1 Cluster Application Envoy Service-A2 Cluster Application Envoy API-Gateway-B Cluster Application Envoy Service-B1 Cluster Application Envoy All of about 30 Services in 4 Subsystems are running as Nomad Job Traffic between envoys is protected by mTLS using Vault-issued certificates External Services DB MQ
  8. Service Discovery Node Docker Bridge Network Task Group Application Container

    Envoy Container Task Group Application Container Envoy Container Other Sercvices (Envoys) Control Plane Consul Client Consul Server Nomad Client Nomad Server Ansible/AWX kick job allocate start TaskGroup with service port assign register service propagate service info (Blocking Query) propagate config by xDS (gRPC stream) Dynamic Service Port Business Traffic propagate service info Dynamic Service Port Business Traffic make envoy config propagate config template (Blocking Query) register envoy config template for each service to KVS health check
  9. Task 2 Sidecar Task 1 Application Sidecar PatternのService定義 Ingress Port

    (Static) App Admin Port (Static Port) Service Endpoint (Static Port) Healthcheck Endpoint (Static Port) Consul Other Service Application Task publishes no service directly. Watching if upsterams are healthy (ex: DB) Main Service Ingress Port (Dynamic) App Admin Port (Dynamic) Healthcheck Business Request
  10. Sidecar PatternのService定義 task "sample-service-sidecar" { config { port_map { ingress

    = 3001 appadmin = 9902 } } resources { network { port "ingress" {} port "appadmin" {} } } service { name = "sample-service" port = ”ingress" address_mode = "host" check { name = "sample-service-alive" type = "http" method = "GET" port = "appadmin" path = "/health" interval = "5s" timeout = "5s" } } } Task2 (Sidecar) l Task2(Sidecar)でのみserviceを公開 l config.port_mapでコンテナのサービスポートにLabel をつける l resources.network.portで動的ポートを払い出しLabel 付けされたポートにマップする l service.portで当該serviceが公開するポートを指定 l service.checkでappadminポートへのhealthcheckを定 義する(サービスポートとhealthcheckのポートは同⼀ でなくてもOK) l メトリクス取集などの⽬的でappadminポートを個別 のserviceとしても公開
  11. Node Tasks間の通信 Docker Bridge Network (user-defined) Task Group Task 1

    Application Container Task 2 Sidecar Container 192.168.200.aaa (by DHCP) 192.168.200.bbb (by DHCP) Docker Embedded DNS Server Lookup <name-of-task1> Lookup <name-of-task2> ENV EGRESS_HOST= <name-of-task2> ENV EGRESS_PORT= 3101 <name-of-task1>. IN A 192.168.200.aaa <name-of-task2>. IN A 192.168.200.bbb ENV LOCAL_APP_HOST= <name-of-task1> ENV LOCAL_APP_SERVICE_PORT= 8080 To be registered when Job started Necessary to use user-defined bridge network to enable embedded DNS Server. (not default bridge network)
  12. Tasks間の通信 task " sample-service-sidecar" { driver = "docker" config {

    image = ”ourregistry.com/ourproject/sidecar-envoy:1.0.0" network_mode = ”custom_bridge” network_aliases = ["${NOMAD_TASK_NAME}-${NOMAD_ALLOC_INDEX}"] } env { LOCAL_APP_HOST = " sample-service-app-${NOMAD_ALLOC_INDEX}" LOCAL_APP_SERVICE_PORT = ”8080" } } task ”sample-service-app" { driver = "docker" config { image = ”ourregistry.com/ourproject/sample-service:1.0.0" network_mode = ”custom_bridge” network_aliases = ["${NOMAD_TASK_NAME}-${NOMAD_ALLOC_INDEX}"] } env { EGRESS_HOST = " sample-service-sidecar-${NOMAD_ALLOC_INDEX}" EGRESS_PORT = ”3101" } } Task1 (Application) Task2 (Sidecar) l config.network_modeでユーザ定義bridge networkを指定(事前に各nodeにsetupしておく) l config.network_aliasesでcontainerに別名をつけておく(これがDNSに登録される) NOMAD_TASK_NAME や NOMAD_ALLOC_INDEX などのNomad環境変数を利⽤し、TaskGroup内 の他のTaskから予測可能な値とする l envで通信相⼿となるTaskの宛先情報をContainerに伝える
  13. Updateパラメータのチューニング Before Update Alloc1 Other Service Consul Control Plane Request

    Update Started Alloc1 Other Service Consul Control Plane Deregister Service Request Service Info (Alloc1,Alloc2) Update Kicked l UpdateがKickされると、Nomad Jobは最初にConsulからサービス情報を削除する l この時点でUpdate中のAllocationの情報はConsulのService Discoveryで提供されなくなるが、他サー ビスのRouting情報までは反映されておらず、 Requestは継続して届く Alloc2 Alloc2 Service Info (Alloc1,Alloc2) Service Info (Alloc1,Alloc2) Service Info (Alloc1,Alloc2)
  14. Nomad Server Nomad Client Vault連携 - Task Server Token Task

    Client Token Issued and injected when agent started Issued and injected when job started l Nomad Server Agentの起動時にServer Tokenを注⼊する l Nomad ServerはJobの起動時にServer Tokenを使ってClient Tokenを発⾏しTaskに注⼊する l TaskはClient Tokenを使ってVaultにアクセスしSecretを取得する Secret Secret Secret Approle Vault
  15. Vault連携 - Task l Nomad ServerがClient Tokenを発⾏する際に使うToken l Nomad Server

    Agentの起動時に注⼊される l Serverが起動している間は⾃動的にrenewする l Client Tokenを管理するためのcapabilitiesが要求される Server Token path "kv/*" { capabilities = ["read","list"] } path "auth/token/create/nomad-client" { capabilities = ["update"] } path "auth/token/roles/nomad-client" { capabilities = ["read"] } path "auth/token/lookup" { capabilities = ["update"] } path "auth/token/revoke-accessor" { capabilities = ["update"] } path "sys/capabilities-self" { capabilities = ["update"] } path "auth/token/renew-self" { capabilities = ["update"] } nomad-server-policy.hcl (vault)
  16. Vault連携 - Task l Nomad Client上で動くTaskがVaultにアクセスする際に使うToken l Job起動時にNomad Serverにより発⾏/注⼊される l

    Taskが起動している間は⾃動的にrenewする l どのroleから発⾏するかはserver agentのconfigで指定 ※1 l 適⽤するpolicyはTask単位で指定 ※2 Client Token vault { enabled = true address = "https://example-vault.com:8200" create_from_role = "nomad-client" } job "example-job" { group "example-group" { task "example-task" { vault { policies = ["nomad-client-1"] } } } ※1 agent.hcl (nomad) ※2 job.hcl (nomad) path "kv/*" { capabilities = ["read","list"] } nomad-client-policy-1.hcl (vault)
  17. Vault連携 - Task job "example-job" { group "example-group" { task

    "example-task" { vault { policies = ["nomad-client"] change_mode = "noop" } template { data = <<EOH {{ with secret "kv/data/example" }} EXAMPLE_SECRET_1="{{ .Data.data.secret1 }}" EXAMPLE_SECRET_2="{{ .Data.data.secret2 }}" {{ end }} EOH destination = "secrets/file.env" env = true change_mode = "noop" } } } } job.hcl (nomad) l template stanza でsecret取得のScriptを埋め込む l vault.change_mode は Client Tokenが新しくなったときの挙 動を設定する Defaultはrestart(Tsakの再起動) 主にrenew失敗したときに発⽣する l template.change_mode は取得したsecretにvault側で変化が あった場合の挙動を設定する Defaultはrestart(Tsakの再起動) NomadTaskはVault内のSecretをポーリングにより監視する l 起動時にだけSecretアクセスが発⽣するような場合は、どち らもnoopに設定しておいた⽅が安全 Task Definition
  18. Vault連携 - ACL l Nomad ACL には Tokenの有効期限を管理する機能がない l Vaultに対してNomad

    ACLの管理権限を委譲することにより有効期限の制御が可能になる l Nomad ACL Tokenに関する運⽤上のリクエストはVaultが受付ける l Vaultには様々なツール⽤のSecret Engineが⽤意されている 当然Consulも同じことができる Nomad Vault Nomad Secret Engine ACL Token Role Issue / Revoke creds request Policy TTL Control