LoginSignup
11
4

More than 1 year has passed since last update.

【Kubernetes】NginxのIngress Controllerをビルド&デプロイする

Posted at

はじめに

Kubernetesでコンテナで動かしているサービスを公開する方法としてIngressがあります。
Ingressを動かすにはIngress Controllerが必要です。この記事ではNginxのIngress Controllerのコンテナイメージをビルドしてデプロイ(Kubernetesクラスタ上に作成)してみます。

使用するIngress Controller

Ingressではクラスタ内のサービスへのアクセス制御できます。

ingress

Ingressを動かすにはIngress Controllerが必要です。

Ingress Controllerにはオープンソースなもの、クラウド毎に提供しているものなどがあります。
今回はNginxを基にした無料版のIngress Controllerを使ってみます。
有料版ではWAFの機能を備えたNginx App Protectが使えます。

作成する構成図

以下の構成を作成します。

image.png

今回はminikubeでクラスタを作成します。インストール手順は省略しますがalias kubectl="minikube kubectl --"としています。
NginxのPODを作成し、Serviceでポート80を使ってアクセスできるようにします。VirtualServerはIngressと同じ役割で、ホスト名を定義してServiceへルーティングします。NodePort Serviceにてクラスタを動かしているノードのポートにマッピングして、クラスタ外からアクセスできるようにします。

VirtualServerではIngressよりも詳細にNginxの設定を行うことができるようになっています。

実践

Nginxサービスをデプロイする

$ kubectl create ns myns
namespace/myns created
$ kubectl run nginx --image=bitnami/nginx --port=8080 --namespace=myns
pod/nginx created
$ kubectl expose pod nginx -n myns --name=mysvc --port=80 --target-port=8080
service/mysvc exposed
$ kubectl get all -n myns
NAME        READY   STATUS    RESTARTS   AGE
pod/nginx   1/1     Running   0          116m

NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/mysvc   ClusterIP   10.96.165.72   <none>        80/TCP    20s

それますが、今回はyamlファイルを作成せずデプロイする練習をしています。Kubernetesの試験の勉強のためです。

この段階ではクラスタ内からアクセスできるようになっています。
以下のコマンドで一時的にPODを立ち上げてクラスタ内からアクセスできます。

$ kubectl run busybox --image busybox -it  --rm --restart=Never -- wget -O - mysvc.myns

Ingress Controllerのコンテナイメージをビルドする

ドキュメントに従ってビルドします。ビルド方法は複数種類あるので必要に応じてベースイメージ、ツールなどを変更します。今回はローカルにgoをインストールしてビルドしてみます。

gitをインストールします。

$ sudo yum install -y git-2.38.1

goをインストールします。

$ sudo amazon-linux-extras install epel -y
$ sudo yum install -y golang-1.18.8

gitリポジトリをクローンしてビルドします。

$ git clone https://github.com/nginxinc/kubernetes-ingress.git --branch v2.4.2
$ cd kubernetes-ingress
$ make debian-image TARGET=local

ビルドする方法はTARGETにて選べます。

TARGETの値 説明
local ローカルのgoを使ってビルドする
container goコンテナを使ってビルドする
download バイナリファイルのコンパイルを行わずにビルドする

NginxのIngress ControllerのGithubは以下の通りです。

minikubeでビルドしたイメージを使うため、ロードする。

$ minikube image load nginx/nginx-ingress:$(docker images | grep nginx-ingress | awk '{print $2}')

Ingress Controller関連リソースをデプロイする

コンテナやサービスなどのリソースを以下のドキュメントに従って作成する。
複数の方法がありますが、今回はyamlファイルから作成します。
また、ロードバランサーは作成しないため、ノードポートを使用します。

cd kubernetes-ingress
kubectl apply -f deployments/common/ns-and-sa.yaml
kubectl apply -f deployments/rbac/rbac.yaml
kubectl apply -f deployments/rbac/apdos-rbac.yaml
kubectl apply -f deployments/common/default-server-secret.yaml
kubectl apply -f deployments/common/nginx-config.yaml
kubectl apply -f deployments/common/ingress-class.yaml
kubectl apply -f deployments/common/crds/k8s.nginx.org_virtualservers.yaml
kubectl apply -f deployments/common/crds/k8s.nginx.org_virtualserverroutes.yaml
kubectl apply -f deployments/common/crds/k8s.nginx.org_transportservers.yaml
kubectl apply -f deployments/common/crds/k8s.nginx.org_policies.yaml
kubectl apply -f deployments/deployment/nginx-ingress.yaml
kubectl apply -f deployments/service/nodeport.yaml

コマンドが多いのでミスがないか確認したい場合は、Ingress ControllerのPODのログを見るとよいと思います。

$ kubectl logs -n nginx-ingress $(kubectl get pod -n nginx-ingress | grep nginx-ingress | awk '{print $1}')

注意点として、コンテナはminikube本体のコンテナ上で動いています。そのため、ノードポートはminikube本体のコンテナのポートにマッピングしています。
どのポートにマッピングしているかはNodePort Serviceを見るとわかります。
下記の場合、HTTPは32440ポート、HTTPSは30230ポートにマッピングしています。

$ kubectl get svc -n nginx-ingress
NAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
nginx-ingress   NodePort   10.104.212.55   <none>        80:32440/TCP,443:30230/TCP   62s

まだバックエンドの設定ができていませんが、404のレスポンスは取得できます。

$ sudo docker exec minikube curl -s localhost:32440
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.23.2</center>
</body>
</html>

VirtualServerをデプロイする

NginxのService用のVirtualServerのyamlファイルを作成します。

virtualserver.yaml
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
  name: mynginx-co-jp-vs #リソース名の定義
  namespace: myns
spec:
  host: mynginx.co.jp #ホスト名の定義
  tls:
    secret: mynginx-co-jp-cert #HTTPSで用いる証明書を入れたSecret名
  ingressClassName: nginx #使用するIngressClass名
  upstreams:
    - name: mynginx-co-jp #バックエンド名の定義
      service: mysvc #バックエンドのサービス名
      port: 80 #使用するポート
  routes:
    - path: / #パス「/」の場合にバックエンド「mynginx-co-jp」に送信する。
      action:
        pass: mynginx-co-jp

HTTPSのアクセスを受け付けるため、自己証明書を用意します。

$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout private.key \
-out server.crt \
-subj "/CN=mynginx.co.jp/O=mynginx.co.jp" &> /dev/null
$ kubectl create secret -n myns tls mynginx-co-jp-cert \
--key private.key \
--cert server.crt

その後、VirtualServerを作成します。

$ kubectl apply -f virtualserver.yaml

エラーが出ていないか確認します。VirtualServerのSTATEがValidになっていることを確認します。なっていない場合はdescribeコマンドで原因を調べます。

$ kubectl get vs -n myns
NAME               STATE   HOST            IP    PORTS   AGE
mynginx-co-jp-vs   Valid   mynginx.co.jp                 2m40s

これでNodePort Serviceを通してNginxのServiceにアクセスできるようになっているはずです。
HTTPSでアクセスしてみます。

$ sudo docker exec minikube curl -sk https://localhost:30230 -H"Host:mynginx.co.jp"
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

できました。
HTTPでも以下のようにアクセスできます。

$ sudo docker exec minikube curl -s http://localhost:32440 -H"Host:mynginx.co.jp"

おわりに

勉強するまでよくわからなかったNginxとIngress Controllerについて触れました。
まだまだ理解しきれていませんが、Nginxがわかればネットワーク関連でできることが増えるので勉強していきたいです。

11
4
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
11
4