スタンドアロンKubernetesクラスタにIngressを設定しWebサーバを公開する
はじめに
余ったPC1台を使ってKubernetesクラスタを構築してみるでKubernetesの検証環境を構築できました。
せっかくできたこの環境を使って外部からアクセス可能なWebサーバを構築し、公開してみたいと思います。
Ingressとは
Ingressとは、Kubernetesで利用できるL7(HTTP/HTTPS)ロードバランサです。
クラスタ内のコンテナ(正確にはPod)を外部に公開できます。
似たようなものとしてLoad Balancer Serviceというものがあります。
こちらはL4(TCP/UDP)ロードバランサです。
後々やってみたいと思っているTLSターミネーションやURLマップができません。
したがって、Ingressを使ってみたいと思います。
セットアップ
検証環境
前回のエントリの続きのため、Ubuntu環境を利用しました。
$ uname -v
40~18.04.1-Ubuntu SMP Thu Nov 14 12:06:39 UTC 2019
Ingress Nginx Controller
Ingressとは先程触れたとおり、Kubernetesで利用できるL7(HTTP/HTTPS)ロードバランサです。
Ingressの内部実装はIngress Controllerと呼ばれており、GCPで動作するもの、AWSで動作するものなど色々あります。
ここではオンプレミス環境でも利用できるIngress Nginx Controllerをインストールします。
Ingress Nginx ControllerをHelmというツールを使ってセットアップを行います。
*Helm**を利用する理由は、クラスタ外からアクセスするためのIPアドレス(external_ip
)の設定が容易なためです。
Helmのインストール
公式ページに記載されている方法でインストールします。
# Install
$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
$ chmod 700 get_helm.sh
$ ./get_helm.sh
# Initialize
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com/
次に外部からアクセスする際のクラスタのIPについて確認します。
スタンドアローンのクラスタなので、 マスタサーバ で ip addr
を実行した結果のIPアドレスを利用します。
$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp4s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether 50:e5:49:c3:03:57 brd ff:ff:ff:ff:ff:ff
3: wlx0024a54f427c: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:24:a5:4f:42:7c brd ff:ff:ff:ff:ff:ff
inet 192.168.0.201/24 brd 192.168.0.255 scope global noprefixroute wlx0024a54f427c
...(省略)...
今回構築したサーバは wifi
環境に接続させているため(サーバなのにwifi)、上記の一番下に表示されている 192.168.0.201
のIPアドレスを利用することになります。
それではHelmを使って、Ingress Nginx Controllerをインストールします。
# ネームスペースを作成しているが作成しなくても問題はない
kubectl create ns nginx-ingress
helm install stable/nginx-ingress \
--namespace nginx-ingress \
--generate-name \
--set 'controller.service.externalIPs={192.168.0.201}'
一点だけ注意点として、ufwが有効になっていた場合、起動がうまくいきませんでした。sudo ufw disable
で無効にした上で実行したところうまくいきました。
Ingressを設定してみる
Ingressを利用できるようになったため、以下のような構成でWebサーバを公開してみます。
sample-app
という名前のWebサーバPod(ここではコンテナと読み替えてもOK)を作成sample-app
Podを公開するためのServiceを作成(9000ポートで公開)- ここまでくれば、
curl
コマンドを使ってPodにアクセスできる
- ここまでくれば、
sample-app.local
というドメインでクラスタ外にServiceを公開するためのIngressを作成(80ポートで公開)
# Podを生成
$ kubectl run --port 80 --image=httpd --labels="app=sample-app" sample-app
# Serviceのマニフェスト(定義ファイル)を生成
$ cat <<EOF > service-sample-app.yml
apiVersion: v1
kind: Service
metadata:
name: service-sample-app
spec:
type: NodePort
selector:
app: sample-app
ports:
- name: "http-port"
protocol: "TCP"
port: 9000
targetPort: 80
EOF
# Serviceを生成
$ kubectl apply -f service-sample-app.yml
この状態では、クラスタの外からはまだアクセスできないが、クラスタ内(サーバ自身)からはアクセスできます。
試してみます。
# Serviceで生成されたIPアドレスを取得
$ IP=$(kubectl describe service/service-sample-app | sed -n 's/^IP:\s*//p')
# IPアドレスが取得できたか確認
$ echo $IP
10.96.97.188
# アクセスしてみる
$ curl service-sample-app:9000
<html><body><h1>It works!</h1></body></html>
最後にIngressを作成します。
ここではApacheのVirtualHost方式を用います。sample-app.local
というホスト名でアクセスされた場合にのみ、Serviceへと転送させます。
$ cat <<EOF > ingress.yml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress
spec:
rules:
- host: sample-app.local
http:
paths:
- path:
backend:
serviceName: service-sample-app
servicePort: 9000
EOF
$ kubectl apply -f ingress.yml
Ingressリソースが正しく作成されているかは以下のコマンドで確認できます。
$ kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
ingress sample-app.local 80 3s
それではクラスタ外のPCから以下のコマンドを実行して、正しいレスポンスが帰ってくるかを確認してみます。
$ curl -H 'Host: sample-app.local' 192.168.0.201
<html><body><h1>It works!</h1></body></html>
ホスト名が不明だった場合はどうなるでしょう?
$ curl 192.168.0.201
default backend - 404
これでクラスタ外からアクセスできるようになりました。
ひとこと
自分でもまだ用語が整理できていない部分もあり、きれいなエントリとなっていませんが、参考になれば幸いです。
ディスカッション
コメント一覧
まだ、コメントがありません