はじめに
5月15日はJリーグの日。 1993年の今日(5月15日)Jリーグが開幕しました。Jリーグ開幕試合はヴェルディ川崎 vs 横浜マリノス、場所は旧国立霞ヶ丘競技場。 キックオフは19:29だったそうです。 そんな歴史的な日を記念してこの記事は5月15日19:29に投稿しています。
前置きはこれくらいにして、突然ですがみなさんはIngress controllerに何をご利用でしょうか? よく利用されるのはnginx ingress controllerだと思います。 普通のReverse proxyとしてnginx ingress controllerは十分な機能を提供しています。 ただ「もうちょっと高機能だったらいいのに」と感じるケースもあるかと思います。
最近、まさにその「もうちょっと」なことを実現したいなというケースに遭遇しました。
こうしたときに選択肢の1つとして挙げられるのがContourというIngress controllerです。 ContourはEnvoy proxyをベースにしたL7 reverse proxyで、2017年にHeptioが開発、公開しました。現在はCNCFのIncubating projectとなっています。 Heptio社がVMware社に買収されたこともあり、VMWare Tanzuでも利用可能なIngress controllerです。 またMicrosoftが主要開発元となっているOpen service meshでもサポートするIngress controllerの1つでもあります。 Ingress v1もサポートしていますが、独自にCRDも提供しておりEnvoyの様々な機能を利用することができるという 特徴を持っています。たとえば以下のような機能が利用できます。
これがすべてではありません。そう考えるとだんだん「使ってみようかな」と思えてきたのではないでしょうか。
今回はContour ingress controllerのAKSクラスターへの導入方法を紹介していきたいと思います。
想定システムイメージ
アプリケーション部分は以前Daprの紹介の際に利用したものを使います。
(HTTP呼出しならば、設定を変更するだけでDaprの有無にかかわらず動作する、というのはDaprの利点でもありますね)
構成は以前の記事と同様です(もちろん、Ingress controllerがContourになります)。
インストール
Contourのインストール
まずContourをインストールします。ここではhelmを利用します。
インストール先のnamespaceは ingress-system
とします。chartはこちらを利用します。
また、ContourはPrometheusによるメトリックス収集に対応しています。 そちらも有効にしたいと思います。 設定はこちらの内容となります。
config.yaml
contour: podAnnotations: # see https://projectcontour.io/guides/prometheus/ prometheus.io/scrape: "true" prometheus.io/path: "/metrics" prometheus.io/port: "8000" envoy: podAnnotations: # see https://projectcontour.io/guides/prometheus/ prometheus.io/scrape: "true" prometheus.io/path: "/stats/prometheus" prometheus.io/port: "8002"
実行コマンドは以下のとおりです。
helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update helm upgrade --install ingress-contour bitnami/contour \ --namespace ingress-system --create-namespace \ --values config.yaml
これでContourのインストールは完了です。
アプリケーションのデプロイ
想定システムイメージのところでも説明したとおり、アプリケーションはdapr-sampleのものを利用します。
appinsights-agent
とaks-helloworld
、aggregator
、 timefeed
アプリケーションのコンテナイメージをあらかじめ作成しContena Registryにプッシュしておいてください。
それをそれぞれ指定したnamespaceにデプロイします。参考として aggregator
用の設定をご紹介します。
aggregator.yaml
apiVersion: v1 kind: Namespace metadata: name: web --- apiVersion: v1 kind: Secret metadata: name: instrumentation-string namespace: web type: Opaque data: instrumentationString: ${BASE64_INSTRUMENTATION_STRING} --- apiVersion: apps/v1 kind: Deployment metadata: name: aggregator namespace: web labels: app: aggregator spec: selector: matchLabels: app: aggregator template: metadata: labels: app: aggregator spec: containers: - name: aggregator image: ${ACR_NAME}.azurecr.io/dapr-sample/aggregator:0.1.0-SNAPSHOT imagePullPolicy: Always ports: - containerPort: 8080 volumeMounts: - mountPath: /shared/java-agent name: java-agent readOnly: true env: - name: JAVA_TOOL_OPTIONS value: "-javaagent:/shared/java-agent/applicationinsights-agent.jar -Dreactor.netty.http.server.accessLogEnabled=true" - name: TIMEFEED_HOST value: http://timefeed:8080 - name: TIMEFEED_BASE value: / - name: SPRING_MAIN_BANNER-MODE value: "off" - name: APPLICATIONINSIGHTS_ROLE_NAME value: aggregator-web - name: APPLICATIONINSIGHTS_CONNECTION_STRING valueFrom: secretKeyRef: name: instrumentation-string key: instrumentationString initContainers: - name: init-agent image: ${ACR_NAME}.azurecr.io/applicationinsights-agent:${APPINSIGHTS_JAVA_AGENT_VER} command: ["cp", "applicationinsights-agent.jar", "/shared/java-agent/applicationinsights-agent.jar"] volumeMounts: - mountPath: /shared/java-agent name: java-agent volumes: - name: java-agent emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: aggregator namespace: web spec: type: ClusterIP ports: - port: 8080 selector: app: aggregator
このあたりは普通のアプリケーションでも同様ですので、説明は省略します。デプロイ方法は以下のとおりです。
export APPINSIGHTS_JAVA_AGENT_VER=3.2.10 export BASE64_INSTRUMENTATION_STRING=`echo -n ${AI_INSTRUMENTATION_STRING} | base64` cat aggregator.yaml | envsubst | kubectl apply -f -
Ingressによるルーティング
それではまず、kubernetesのIngressを使用したルーティングを設定してみましょう。
ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cont-ingress namespace: default annotations: kubernetes.io/ingress.class: contour nginx.ingress.kubernetes.io/ssl-redirect: "false" spec: defaultBackend: service: name: aks-helloworld port: number: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cont-ingress namespace: web annotations: kubernetes.io/ingress.class: contour nginx.ingress.kubernetes.io/ssl-redirect: "false" spec: rules: - host: aggregator.${DOMAIN_NAME} http: paths: - path: / pathType: Prefix backend: service: name: aggregator port: number: 8080
こちらの内容もnginx ingress controllerを利用した時と変わりません。唯一違うとすれば ingress.classの指定が contour
になっていることでしょうか。
こちらもdeployします。
cat ingress.yaml | envsubst | kubectl apply -f -
これで aks-helloworldやaggregatorにアクセスできるようになると思います。
curl -v http://aks-helloworld.${DOMAIN_NAME}/ curl -v http://aggregator.${DOMAIN_NAME}/service
通常のingressがサポートされているということがこれでわかります。
HTTPProxyによるルーティング
ContourではIngressの設定以外にもHTTPProxyという設定によってルーティングを設定できます。 さまざまな付加機能がありますが、 ingressでそれを指定することはできません。ということでContourを利用する場合にはIngressではなく、 このHTTPProxyを利用することが多いようです。
さきほどのIngressの設定と同等のものをHTTPProxyで指定してみましょう。 まずはIngressの設定を削除します。
cat ingress.yaml | envsubst | kubectl delete -f -
つづいてHTTPProxyの設定です。
http-proxy.yaml
apiVersion: projectcontour.io/v1 kind: HTTPProxy metadata: name: aggregator namespace: web spec: virtualhost: fqdn: aggregator.${DOMAIN_NAME} routes: - services: - name: aggregator port: 8080 --- apiVersion: projectcontour.io/v1 kind: HTTPProxy metadata: name: aks-helloworld namespace: default spec: virtualhost: fqdn: aks-helloworld.${DOMAIN_NAME} includes: - name: default-web namespace: default --- apiVersion: projectcontour.io/v1 kind: HTTPProxy metadata: name: default-web namespace: default spec: routes: - services: - name: aks-helloworld port: 80
HTTPProxyではVirtulaHost単位で1つのHTTPProxy設定をします。 1つのファイルで複数のVirtualHostを定義できるIngressとはこの点が異なります。
こちらもデプロイしてみましょう。
cat http-proxy.yaml | envsubst | kubectl apply -f -
結果確認はIngressの時と同様です。
curl -v http://aks-helloworld.${DOMAIN_NAME}/ curl -v http://aggregator.${DOMAIN_NAME}/service
設定内容もそれほど難しいものはなく、IngressとHTTPProxyでまったく同じ動作が確認できます。
アプリケーション動作
今回の内容とは関係ありませんが、Application InsightsのJavaAgentも前回のDaprサンプル同様導入していますので、分散トレーシングも確認することができます。 残念ながらContourのDistributed Tracing対応についてはまだ確認できていませんので設定できていません。 したがってトレーシングの起点はAggregatorアプリケーションからとなっています。
ここまでは比較的簡単に実現できました。
お知らせ
今回はAKSにインストールし、一般的なReverse proxy機能だけを実現しました。 次回は 「もうちょっと(プラスアルファ)」な機能を加えていきたいと思います。 どんな機能を追加するはは次回のお楽しみということで。
利用した設定ファイル等は以下のGitHub repository にて公開しています。
最後に宣伝。 私たちは、Azure・AKSを活用したシステムのSIや内製化のお手伝いをさせていただいております。 Azureやコンテナ技術の知見を持つエンジニアが対応いたします。ご相談等ありましたらぜひご連絡ください。
それではまた。