LoginSignup
6
6

More than 5 years have passed since last update.

Istio の Ingress の Path 設定における設定ルール

Last updated at Posted at 2017-07-10

Istio を用いた Blue Green / Canary Deployment その1

の過程で一つだけ気になったことがある。Ingress Controller の Path 設定がうまくいかない。
この設定のルールとかのドキュメントも見当たらない。せいぜいここぐらい。

https://kubernetes.io/docs/concepts/services-networking/ingress/
https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/extensions/types.go#L705

仕方がないので、いろいろなことを実験したメモを整理しておきたい。

作者注:下記でいろいろ試行錯誤していましたがわかりました!正規表現がOKです。自己解決しました

Istio のイングレスコントローラーのパス設定

こんな感じのnginx のコンテナがあったときの、Ingress の設定。

/index.html
/login.html
/logout.html
/auth/login.html
/auth/logout.html
/web/index.html
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: webservice-ingress
  annotations:
    kubernetes.io/ingress.class: istio
spec:
  rules:
  - http:
      paths:
      - path: /web/.*
        backend:
          serviceName: web-service
          servicePort: 80
      - path: /auth/.*
        backend:
          serviceName: web-service
          servicePort: 80

正規表現なので、単にワイルドカードではありません。先のテストコードを抜粋すると

        {"/api/v1/", false},
        {"/api/v1/.*", true},
        {"/api/.*/resource", true},
        {"/api/v[1-9]/resource", true},
        {"/api/.*/.*", true},

という感じで設定できるみたい。

ここから下は不要ですが、一端パブリッシュしたので、記録のため残しておきます。

作者注:当初は、サンプルのため、簡単な、nginxのコンテナを作って下記のような構成にした。

/index.html
/login.html
/logout.html
/auth/login.html
/auth/logout.html
/web/index.html

様々なパターンを試すためだ。Istio (というより、Kubernetes) の Ingress の設定は次の感じ。ポイントは、paths の下。これは初めにかいたもの。Istio の Ingress にある Path でリクエストが来たら、web-serviceに転送するというもの。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: webservice-ingress
  annotations:
    kubernetes.io/ingress.class: istio
spec:
  rules:
  - http:
      paths:
      - path: /web
        backend:
          serviceName: web-service
          servicePort: 80
      - path: /auth
        backend:
          serviceName: web-service
          servicePort: 80

きれいに全く動かなかった。 rules.http.paths.path に設定するパターンをいろいろ試してみた。
結果としてほとんど動くパターンがない。唯一いけるのは、path 自体を削除すると、すべてのリクエストが、backend に転送される。

|Ingress        |Container        |Result
/web            /web/index.html     404
/index.html     /index.html         404
/web/index.html  /web/index.html    404
設定なし           上記のとおり       200 (全てのパス)

ちなみに、pathを省略する場合の書き方は

  - http:
      paths:
      - backend:
          serviceName: web-service
          servicePort: 80

という感じ。どうやら、フルパスで指定するしかなく、しかも、それが、.とか入っているといけない様子。うーむ。
もっといいようにできないだろうか?(現在MLで問い合わせ中。何かわかればアップデートします)

結局サンプルをhtmlベースで書くのをあきらめてRuby ベースに変更。Ruby じゃなくても、とにかく、パスが、.等が含まれて
いなければいいのかなと想像した。つまり、アプリケーションサーバーでの使用を想定みたいな。HTMLの場合は、さっきのパスを指定しない方法を使ってほしいのかな。

さて、こんなプログラムを書いて Docker にパックした。ほぼ、HTMLを表示するためだけのサンプル。

#!/usr/bin/ruby
#
require 'webrick'

if ARGV.length < 1 then
    puts "usage: #{$PROGRAM_NAME} port"
    exit(-1)
end

port = Integer(ARGV[0])

server = WEBrick::HTTPServer.new :BindAddress => '0.0.0.0', :Port => port

trap 'INT' do server.shutdown end

index = '
<html>
<head>
    <title>Blue Version 1.0.0</title>
</head>
<body bgcolor="#0000FF">
    <H1>This is Blue Version 1.0.0</H1>
</body>
</html>
'

login = '
<html>
<head>
    <title>V2Tester Login</title>
    <meta http-equiv="Set-Cookie" content="NAME=v2tester"> 
</head>
<body>
    <H1>You logged in as a v2 Tester.</H1>
</body>
</html>
'

logout = '
<html>
<head>
    <title>V2Tester Logout</title>
    <meta http-equiv="Set-Cookie" content="NAME=v2tester; expires=Fri, 31-Dec-1999 23:59:59 GMT;"> 
</head>
<body>
    <H1>You logged out as a v2 Tester.</H1>
</body>
</html>

'

server.mount_proc '/webpage' do |req, res|
    res.status = 200
    res.body = index
    res['Content-Type'] = 'text/html'
end

server.mount_proc '/loginpage' do |req, res|
    res.body = login
    res['Content-Type'] = 'text/html'
end

server.mount_proc '/logoutpage' do |req, res|
    res.body = logout
    res['Content-Type'] = 'text/html'
end

server.start

これをDocker にパックして deploy するとうまくいった。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: webservice-ingress
  annotations:
    kubernetes.io/ingress.class: istio
spec:
  rules:
  - http:
      paths:
      - path: /webpage
        backend:
          serviceName: web-service
          servicePort: 80
      - path: /loginpage
        backend:
          serviceName: web-service
          servicePort: 80
      - path: /logoutpage
        backend:
          serviceName: web-service
          servicePort: 80      

しかし、気が利いていない。出来立てだからかな。ちなみに、不思議な挙動があって、実は当初は、webpage -> web, login -> login, logoutpage -> logout だった。web, login は動くがなぜかlogout だけ動かず。予約語か何かだろうか。また、Edge だと、web, log は動くが、chrome だと、/web と打つと、/web/ になぜか変更されてリクエストされるので、404に。 この辺に詳しい人に、なんでそんなことになるのか聞いてみようかな。

横道にそれましたが、次は、Istio のルーティングによる、Canary に取り組みたいと思います。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6