2019年05月13日(月)

RubyKaigi 2019 Day3 k8s&Istioチャレンジ

kengo-kuwahara

GMO kitaQ勤務の桑原です。
RubyKaigi 2019 Day3は私と中村槙吾がチャレンジャーになります。
今回はk8sとIstioの設定に関するお題にチャレンジします。

そもそもk8s自体二人とも業務でもプライベートでも経験はありませんが、
なんとかなるだろ精神で頑張ります!

朝9時に会場到着して朝食ゲット。
福岡人だけど、ここの明太子うめえ!

力もつけたところで、本日のお題はコチラ。
Q0 ~ Q2までの3問クリアでチャレンジ成功。

まず用語が分からねぇ・・・

ちなみに本日のチャレンジャー2名のスキルセットはこんな感じ。
-K: 小規模ながらDockerで社内向けサービス構築経験アリ。k8sは前日にkubesprayで初めて構築したレベル。
istio,サービスメッシュはwhat?レベル。
-N: k8sをチャレンジ3日前にまともに触り始めました。istio,サービスメッシュは今回のチャレンジが初。

10時になったので、これから目標3問クリアを目指して頑張ろー!

まずはQ0
80番ポートをlistenするgoのアプリをコンテナ上で実行せよ、とのお題。
# RubyKaigiでGoを使う勇気が試される
それを3つのコンテナで行い、80番ポートにアクセスしたら、それぞれ
RubyKaigi,{1}
RubyKaigi,{2}
RubyKaigi,{3}
とリプライしてくれればお題クリア。

Kの頭の中
マルチステージでビルドしてイメージ作ろう。
3つあるからdocker-compose使うほうが利口だろうか?
でもdocker-composeでマルチステージビルドできるのか?
分からんからmain.goとDockerfile、それぞれ3つ作るか。

てことで、3つ用意。以下の感じで3つ分dockerビルド。
main1.go


package main
import (
        "fmt"
        "log"
        "net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "RubyKaigi,{1}")
}
func main() {
        http.HandleFunc("/", handler)
        log.Fatal(http.ListenAndServe(":80", nil))
}

Dockerfile


FROM golang:latest as builder1
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
WORKDIR /work
COPY . .
RUN go build main1.go

# runtime image
FROM alpine
RUN apk add --no-cache ca-certificates
COPY --from=builder1 /work /app
EXPOSE 80
CMD /app/main1

# docker build -t my/myapp1 .
# docker run -p 8181:80 -d -t myapp1

ローカルの8181から80ポートにフォワードしてRubyKaigi,{1} のレスポンスあり。
Q1以降でk8sからrunするので、確認用にrunした上記は削除。

実は最初はhttp-serverというnameでbuildしていました。
しかし、Q1以降でk8s上にdeploymentをcreateしようとすると、
DockerHubからpullしようとしてエラーになったため、
ローカルからpullする際のお作法に従いmy/myapp1にrenameしています。

11時前にQ0クリア!
今のところ順風満帆か!?

しかしQ1以降は完全にワカメ。

ひとまずQ0でbuildしたmy/myapp{1,2,3}たちをrunしよう。
ただし、google先生曰く、istio-injection=enabledをラベルしたnamespace上で
コンテナを起動させないと、自動でistioがサイドカーとしてpod内に作られないようだ。
まあ、istioctlを使用して狙いうちでサイドカーをinjectすることもできるらしいが。


# kubectl get namespace -L istio-injection
NAME              STATUS   AGE     ISTIO-INJECTION
default           Active   2d12h   enabled
istio-system      Active   2d12h   disabled
kube-node-lease   Active   2d12h
kube-public       Active   2d12h
kube-system       Active   2d12h

してみると、default namespaceで既にistio-injection=enabled済みなので、
ここでコンテナ起動することにしよう。

てことでまずはdeploymentのyamlを作成。
myapp1-deploy.yml


apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: myapp1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: myapp1
    spec:
      containers:
      - name: myapp1
        image: my/myapp1:1.0
        ports:
        - containerPort: 80

# kubectl apply -n default -f myapp1-deploy.yml

kubectl get deploy, kubectl get podsして
deploymentもpodも正常に構築できていること確認。
これを3つ分作成。

次にgateway/virtualserviceのyamlを作成してapplyする必要があるようだ。 by google先生。
(注)この時点ではgateway/virtualserviceの役割分かってない。何ならserviceの役割も分かってない。

見よう見まねで以下のyamlを作成して、それぞれapply。
gateway.yml


apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: myapp-gateway
  namespace: default
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      name: http
      number: 80
      protocol: HTTP
    hosts:
    - "*"

virtualservice.yml


apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: myapp-vsvc
  namespace: default
spec:
  gateways:
  - "myapp-gateway"
  hosts:
  - "*"
  http:
  - match:
    route:
    - destination:
        host: "*"
        port:
          number: 8181

kubectl get gateway/virtualgatewayして、構築できたことを確認。

localhost:8181にcurlしてみるが失敗…


# curl http://localhost:8181
curl: (7) Failed to connect to localhost port 8181: Connection refused

ここから泥沼にはまる。

serviceをapplyしていないとダメっぽいので、以下のserviceをtype=cluster ipも起動するも、
やっぱりcurlで8181からデータ取れない。


apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
  namespace: default
  labels:
    name: myapp
spec:
  selector:
    app: myapp
#  type: NodePort
  ports:
  - name: myapp
    protocol: TCP
    port: 80
    targetPort: 8181

 

結局、解決できずにこのままタイムアップ!
残念ながらistioの問題は1問も解けず…不完全燃焼という感じ。

k8s/istioのネットワーク周りの概念がよく分かってないまま構築したことが敗因。
service/gateway/virtualgatewayココら辺。
理解できないまま突っ込んだので、エラーが出てもその対処すらも見当がつかなかった。
ネットワーク周りを理解したうえで、再チャレンジしてみたい。
さらなるアップデートを乞うご期待!!!

 

Rubykaigi Day1/Day2の記事は下記

RubyKaigi 2019 Day1 コンテナ軽量化チャレンジ

RubyKaigi 2019 Day2

この記事をシェアする

関連のおすすめ記事

CAREERS
エンジニア積極採用中

GMOインターネットグループでは、積極的な採用活動も行っています。GMOインターネットグループのエンジニア採用情報は下記リンクからご覧になれます。