0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MetalLB を利用した ingress-nginx 導入手順

0
Posted at

1 はじめに

この記事では、ingress-nginx(Ingress のルールに従ってリクエストを各 Service へ振り分けるコントローラ)を導入し、PC の Web ブラウザから ingress-nginx 経由でバックエンドの Web サーバー(nginx や httpd)へアクセスできる環境を構築します。

また、Ingress Controller を外部へ公開するために MetalLB を利用し、LoadBalancer 型 Service に外部 IP アドレスを割り当てることで、オンプレミス環境(本検証環境)でもクラウドの LoadBalancer 相当の機能を提供するサービスを公開します。

本記事で構築する環境は、以下のようになります。

+------------------------------------------------------+
| Ingress(ルーティングルール)                         |
|                                                      |
|  /httpd  →  Service(httpd)                           |
|  /nginx  →  Service(nginx)                           |
+------------------------------------------------------+
                         ▲
                         │ 参照
                         │
+------+  HTTP/HTTPS  +--------------------------------+
|  PC  | -----------> | Ingress Controller             |
+------+              +--------------------------------+
       192.168.116.200              │
                                    │
                          ┌─────────┴─────────┐
                          │                   │
                  +----------------+  +----------------+
                  | Service(httpd) |  | Service(nginx) |
                  +----------------+  +----------------+
                          │                   │
                  +-------+------+    +-------+------+
                  │              │    │              │
             httpd Pod1     httpd Pod2 nginx Pod1  nginx Pod2

なお、ingress-nginx は 2026 年 3 月にサポートを終了しており、新しい機能追加やセキュリティ修正は行われません。現在は Gateway API への移行が推奨されています。本記事では、Ingress の仕組みを理解することを目的として ingress-nginx を使用していますが、新規環境を構築する場合は Gateway API の採用も検討してください。

2 検証環境

2.1 ネットワーク構成

検証環境は、VMware Workstation Pro上に構築した3台の仮想マシンでKubernetesクラスタを構成しています。各仮想マシンはブリッジ接続により、PCと同じネットワーク(192.168.1.0/24)に接続されています。

一方、10.244.0.0/16 は、CalicoのCNIプラグインによってクラスタ内に作成されるPodネットワークです。各Podにはこのアドレス帯からIPアドレスが割り当てられ、異なるノード上のPod同士が相互に通信する際に使用されます。Calicoは各ノードに経路を設定することで、Pod間通信を透過的に実現しています。

+--- control ---+    +--- worker1 ---+   +--- worker2 ---+
|AlmaLinux 10.2 |    |AlmaLinux 10.2 |   |AlmaLinux 10.2 |
|               |    |               |   |               |
|      Pod      |    |      Pod      |   |      Pod      |
|       |       |    |       |       |   |       |       |
| 10.244.x.0/24 |    | 10.244.y.0/24 |   | 10.244.z.0/24 |
| ------------- |    | ------------- |   | ------------- |
|               |    |               |   |               |
+-------+-------+    +-------+-------+   +-------+-------+
        |.19                 |.20                |.22
        |                    |                   |
        |   192.168.1.0/24   |                   |
+--------------------------------------------------------+
|        VMware Workstation Pro(Bridged networking)    |
+--------------------------------------------------------+
                             |
                    +---------------+
                    |               |
                    |       PC      |
                    |               |
                    +---------------+

それぞれの役割は以下のとおりです。
1台をコントロールノード、2台をワーカーノードとして使用します。

ホスト名 名称 役割
control コントロールノード クラスタ(control、worker1、worker2)の状態を管理し、Pod をどのノードで実行するかを決定するノード
worker1 ワーカーノード Pod を実行するノード
worker2 ワーカーノード Pod を実行するノード

2.2 ソフトウェアのバージョン

各ノードのAlmaLinuxバージョンは以下のとおりです。

[root@control ~]# cat /etc/redhat-release
AlmaLinux release 10.2 (Lavender Lion)

各ノードのカーネルバージョンは以下のとおりです。

[root@control ~]# uname -r
6.12.0-211.7.3.el10_2.x86_64

Kubernetesのバージョンは以下のとおりです。

[root@contol ~]# kubectl version
Client Version: v1.36.3
Kustomize Version: v5.8.1
Server Version: v1.36.3

2.3 ノードのリソース

各ノードには4GBのメモリを割り当てています。

[root@control ~]#  free -h
               total        used        free      shared  buff/cache   available
Mem:           3.6Gi       1.3Gi       1.0Gi       5.8Mi       1.5Gi       2.3Gi
Swap:             0B          0B          0B

各ノードは 4コアのCPU(4 vCPU) を搭載しています。

[root@control ~]# lscpu -xe
CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE
  0    0      0    0 0:0:0:0          yes
  1    0      1    1 1:1:1:1          yes
  2    0      2    2 2:2:2:2          yes
  3    0      3    3 3:3:3:3          yes

lscpuコマンドの詳しい使い方は、以下のページをご覧ください。

3 事前準備

本章では、PC のブラウザと Ingress Controller 間で HTTPS 通信を行うための証明書を作成します。作成する証明書は、Ingress Controller 用のサーバ証明書と、自己署名した CA 証明書の 2 つです。サーバ証明書は Kubernetes の Secret として登録し、CA 証明書は Windows の証明書ストアへインポートします。これにより、ブラウザから Ingress Controller へ HTTPS でアクセスできるようになります。

3.1 証明書の作成

証明書を作成するために作業用のディレクトリをコントロールノードに作成します。

[root@control ~]# mkdir ingress-tls
[root@control ~]# cd ingress-tls/
[root@control ingress-tls]#

3.1.1 CA証明書の作成

CA(Certificate Authority:認証局)は、サーバ証明書を発行・署名する機関です。ブラウザは、サーバ証明書を受け取ると、その証明書が信頼できる CA によって署名されているかを確認することで、接続先のサーバが正しいことを検証します。本記事では、検証環境で使用するため、自己署名の CA 証明書を作成し、その CA を使用して Ingress Controller 用のサーバ証明書を発行します。

CAの秘密鍵を作成します。

[root@control ingress-tls]# openssl genpkey \
    -algorithm RSA \
    -pkeyopt rsa_keygen_bits:4096 \
    -out ca.key

CAの秘密鍵(ingress.key)が作成されたことを確認します。

[root@contol ingress-tls]# ls -l
合計 4
-rw-------. 1 root root 3272  7月 31 19:42 ca.key

作成した CA 秘密鍵を使用して、自己署名の CA 証明書を作成します。

[root@control ingress-tls]# openssl req \
    -new \
    -x509 \
    -days 3650 \
    -sha256 \
    -key ca.key \
    -out ca.crt \
    -subj "/C=JP/ST=Tokyo/L=Tokyo/O=Example/OU=Example/CN=Example Root CA"

CA 証明書(ca.crt)が作成されたことを確認します。 作成したCA証明書はPCに転送します。

[root@contol ingress-tls]# ls -l
合計 8
-rw-r--r--. 1 root root 2041  7月 31 19:42 ca.crt
-rw-------. 1 root root 3272  7月 31 19:42 ca.key

3.1.2 Ingress Controllerのサーバ証明書の作成

Ingress Controller の秘密鍵を作成します。

[root@control ingress-tls]# openssl genpkey \
    -algorithm RSA \
    -pkeyopt rsa_keygen_bits:2048 \
    -out ingress.key

秘密鍵(ingress.key)が作成されたことを確認します。

[root@contol ingress-tls]# ls -l
合計 12
-rw-r--r--. 1 root root 2041  7月 31 19:42 ca.crt
-rw-------. 1 root root 3272  7月 31 19:42 ca.key
-rw-------. 1 root root 1708  7月 31 19:44 ingress.key

作成した秘密鍵を使用して、CSR(Certificate Signing Request:証明書署名要求)を作成し、ingress.csr に保存します。

[root@control ingress-tls]# openssl req \
    -new \
    -key ingress.key \
    -out ingress.csr \
    -subj "/C=JP/ST=Tokyo/L=Tokyo/O=Example/OU=Example/CN=ingress.home.lab"

CSR を保存したファイル(ingress.csr)が作成されたことを確認します。CSR はサーバ証明書の発行を CA に依頼するためのデータであり、ingress.csr はその内容を保存したファイルです。

[root@contol ingress-tls]# ls -l
合計 16
-rw-r--r--. 1 root root 2041  7月 31 19:42 ca.crt
-rw-------. 1 root root 3272  7月 31 19:42 ca.key
-rw-r--r--. 1 root root 1009  7月 31 19:44 ingress.csr
-rw-------. 1 root root 1708  7月 31 19:44 ingress.key

拡張情報ファイルを作成します。このファイルは、サーバ証明書に付与する拡張情報を指定します。

[root@control ingress-tls]# vi ingress.home.lab.ext
[root@control ingress-tls]# cat ingress.home.lab.ext
authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE

keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

subjectAltName = @alt_names

[alt_names]
DNS.1 = ingress.home.lab
IP.1 = 192.168.1.200

Ingress Controller が HTTPS 通信で使用するサーバ証明書(ingress.crt)を作成します。

[root@control ingress-tls]# openssl x509 \
    -req \
    -in ingress.csr \
    -CA ca.crt \
    -CAkey ca.key \
    -CAcreateserial \
    -out ingress.crt \
    -days 365 \
    -sha256 \
    -extfile ingress.home.lab.ext
Certificate request self-signature ok
subject=C=JP, ST=Tokyo, L=Tokyo, O=Example, OU=Example, CN=ingress.home.lab

作成したサーバ証明書(ingress.crt)を確認します。

-rw-r--r--. 1 root root 2041  7月 31 19:42 ca.crt
-rw-------. 1 root root 3272  7月 31 19:42 ca.key
-rw-r--r--. 1 root root   41  7月 31 19:45 ca.srl
-rw-r--r--. 1 root root 1789  7月 31 19:45 ingress.crt
-rw-r--r--. 1 root root 1009  7月 31 19:44 ingress.csr
-rw-r--r--. 1 root root  240  7月 31 19:45 ingress.home.lab.ext
-rw-------. 1 root root 1708  7月 31 19:44 ingress.key

サーバ証明書の SAN(Subject Alternative Name)を確認します。SAN には、サーバ証明書の有効なホスト名や IP アドレスが登録されます。今回作成した証明書では、DNS:ingress.home.lab および IP Address:192.168.1.200 が設定されています。ブラウザは、アクセス先のホスト名または IP アドレスが SAN に含まれていることを確認することで、接続先のサーバが正しいことを検証します。

[root@control ingress-tls]# openssl x509 -in ingress.crt -noout -text | grep -A1 "Subject Alternative Name"
            X509v3 Subject Alternative Name:
                DNS:ingress.home.lab, IP Address:192.168.1.200

ingress-nginx Namespaceを作成します。

[root@contol ingress-tls]# kubectl create namespace ingress-nginx
namespace/ingress-nginx created

Ingress Controllerのsecretを作成します。secretにはIngress Controller が HTTPS 通信で使用するサーバ証明書および秘密鍵を Secret として登録します。

[root@contol ingress-tls]# kubectl create secret tls ingress-tls \
  --cert=ingress.crt \
  --key=ingress.key \
  -n ingress-nginx
secret/ingress-tls created

作成したsecret(ingress-tls)を確認します。

[root@contol ingress-tls]# kubectl get secrets -n ingress-nginx
NAME          TYPE                DATA   AGE
ingress-tls   kubernetes.io/tls   2      16s

3.2 PC側の作業

PC のブラウザから Ingress Controller へ HTTPS でアクセスすると、Ingress Controller からブラウザへサーバー証明書が送信されます。ブラウザは送信されてきたサーバー証明書を検証するために、CA 証明書に含まれる公開鍵を使用します。そのため、事前に CA 証明書を PC へインポートしておく必要があります。ここでは、CA 証明書を Windows へインポートする手順を説明します。

3.2.1 hostsファイルの編集

PCからホスト名でアクセスできるよう、Windowsのhostsファイル(C:\Windows\System32\drivers\etc\hosts)に以下の内容を追記します。

192.168.1.200  ingress.home.lab

3.2.2 CA証明書のインポート

コントロールノードで作成したCA証明書(ca.crt)をWindows PCへコピーします。次に、転送したCA証明書をWindowsの証明書ストア(信頼されたルート証明機関)へインポートします。ChromeやMicrosoft EdgeはWindowsの証明書ストアを利用するため、この設定を行うことで、ブラウザから Ingress Controller へ HTTPS でアクセスできるようになります。

まず、[Windows]キー + [R] を押して 「ファイル名を指定して実行」 を開きます。そして、「certmgr.msc」 と入力し、「OK」 をクリックします。
aa-01.jpg

証明書マネージャー(Certmgr)が起動したら、「信頼されたルート証明機関」→「証明書」 を右クリックし、「すべてのタスク」→「インポート」 を選択します。その後、ウィザードに従って転送したCA証明書を選択し、Windowsへインポートします。
aa-02.jpg

「次へ」をクリックする。
aa-03.jpg

作成したCA証明書(ca.crt)を指定して「次へ」をクリックします。
aa-04.jpg

「証明書をすべて次のストアに配置する(P)」から「信頼されたルート証明機関」を選択して「次へ」をクリックする。
aa-05.jpg

「完了」をクリックする。
aa-06.jpg

「はい」をクリックする
aa-07.jpg

「正しくインポートされました」のポップアップ画面を確認する。
aa-08.jpg

3.3 firewalld の設定

本検証ではCNI(Container Network Interface)にCalicoを使用しており、ノード間のPod通信にはIPIPカプセル化方式(tunl0インターフェース)を使用しています。firewalldを有効にした環境では、Calicoが使用するトンネルインターフェースやPodネットワークに対する通信がfirewalldによって許可されていない場合、Pod間通信が正常に行えず、Harborなどのアプリケーションが正常に動作しないことがあります。そのため、この後の手順(MetalLB、Harborのインストール)を正常に進めるため、事前に以下の設定を行います。設定は全てのノード(コントロールノード、ワーカノード)で実施します。

3.3.1 tunl0 の状態確認

tunl0が現在どのゾーンに属しているか確認します。no zoneと表示された場合、以降の設定が必要です。

[root@control ~]# firewall-cmd --get-zone-of-interface=tunl0
no zone

firewall-cmdコマンドの詳しい使い方は、以下のページをご覧ください。

3.3.2 trustedゾーンへの追加

firewalldのtrustedゾーンは、そのゾーンに属する通信を許可する、最も信頼度の高いゾーンです。今回は、Calicoが使用するトンネルインターフェース(tunl0)と、Podネットワーク(10.244.0.0/16)からの通信を許可するため、これらをtrustedゾーンへ追加します。

tunl0インターフェースをtrustedゾーンへ追加します。

[root@control ~]# firewall-cmd --permanent --zone=trusted --add-interface=tunl0
success

Podネットワーク(10.244.0.0/16)をtrustedゾーンへ追加します。この設定により、Calicoが構成するPodネットワークの通信がfirewalldによって遮断されることを防ぎます。

[root@control ~]# firewall-cmd --permanent --zone=trusted --add-source=10.244.0.0/16
success

クラスタを構成するノードが接続されているネットワーク(192.168.1.0/24)をtrustedゾーンへ追加します。

[root@control ~]# firewall-cmd --permanent --zone=trusted --add-source=192.168.1.0/24
success

永続設定を反映するため、firewalldの設定をリロードします。

[root@control ~]# firewall-cmd --reload
success

3.3.3 設定確認

tunl0がtrustedゾーンに追加されたことを確認します。

[root@control ~]# firewall-cmd --get-zone-of-interface=tunl0
trusted

trustedゾーンの設定内容を確認します。interfacesにtunl0 が登録されていれば、設定は正しく反映されています。

[root@control ~]# firewall-cmd --zone=trusted --list-all
trusted (active)
  target: ACCEPT
  ingress-priority: 0
  egress-priority: 0
  icmp-block-inversion: no
  interfaces: tunl0
  sources: 10.244.0.0/16 192.168.1.0/24
  services:
  ports:
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

4 MetalLB のインストール手順

クラウド環境では、LoadBalancer 型 Service を作成すると、クラウドプロバイダーによって外部 IP アドレスが自動的に割り当てられます。一方、オンプレミス環境(本記事の場合)ではクラウドプロバイダーが存在しないため、そのままでは EXTERNAL-IP は のままとなります。

この問題を解決するのが MetalLB です。MetalLB を導入すると、指定した IP アドレス範囲から LoadBalancer 型 Service に外部 IP アドレスを割り当てられるようになり、オンプレミス環境でも Ingress Controller を外部へ公開できます。

4.1 Helmリポジトリの追加

MetalLBのHelmリポジトリを追加します。

[root@control ~]# helm repo add metallb https://metallb.github.io/metallb
"metallb" has been added to your repositories

helm repo list で登録済みのリポジトリを確認します。以下のようにmetallbが追加されていれば成功です。

[root@control ~]# helm repo list
NAME            URL
metallb         https://metallb.github.io/metallb

4.2 リポジトリ情報の更新

ローカルにキャッシュされているチャート情報を最新の状態に更新します。この操作を行わないと、最新のチャート情報がローカルに反映されず、最新バージョンの検索や取得ができない場合があるため、事前に実行します。

[root@contol ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "metallb" chart repository
Update Complete. ?Happy Helming!?

4.3 MetalLB のインストール

helm search repo metallb でインストール可能なMetalLBのバージョンを確認します。今回は 0.16.1 が利用可能であることが確認できます。

[root@contol ~]# helm search repo metallb
NAME            CHART VERSION   APP VERSION     DESCRIPTION
metallb/metallb 0.16.1          v0.16.1         A network load-balancer implementation for Kube...

以下のコマンドでMetalLBをインストールします。--namespace metallb-system でインストール先のNamespaceを指定し、--create-namespace オプションを付けることで、Namespaceが存在しない場合でも自動的に作成されます。STATUS: deployed と表示されればインストールは成功です。

[root@contol ~]# helm install metallb metallb/metallb --namespace metallb-system --create-namespace
I0731 19:49:37.809574    8585 warnings.go:107] "Warning: unrecognized format \"cidr\""
NAME: metallb
LAST DEPLOYED: Fri Jul 31 19:49:37 2026
NAMESPACE: metallb-system
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
MetalLB is now running in the cluster.

Now you can configure it via its CRs. Please refer to the metallb official docs
on how to use the CRs.

helm list でインストール済みのChartを確認します。-n metallb-system オプションで対象Namespaceを指定します。STATUS が deployed であることを確認します。

[root@contol ~]# helm list -n metallb-system
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
metallb metallb-system  1               2026-07-31 19:49:37.157538541 +0900 JST deployed        metallb-0.16.1  v0.16.1

4.4 インストール結果の確認

MetalLBのPodやServiceの状態を確認します。すべてのPodが Running になっていれば正常に動作しています。

[root@contol ~]# kubectl get all -n metallb-system
NAME                                                 READY   STATUS    RESTARTS   AGE
pod/metallb-controller-bc9cbb54b-vkm8n               1/1     Running   0          3m28s
pod/metallb-frr-k8s-4lzjb                            5/5     Running   0          3m28s
pod/metallb-frr-k8s-kqr79                            5/5     Running   0          3m28s
pod/metallb-frr-k8s-statuscleaner-75b695f48d-95rdr   1/1     Running   0          3m28s
pod/metallb-frr-k8s-wsvbv                            5/5     Running   0          3m28s
pod/metallb-speaker-2kwt5                            1/1     Running   0          3m28s
pod/metallb-speaker-9tkhh                            1/1     Running   0          3m28s
pod/metallb-speaker-k5fpz                            1/1     Running   0          3m28s

NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/frr-k8s-webhook-service   ClusterIP   10.106.84.187   <none>        443/TCP   3m29s
service/metallb-webhook-service   ClusterIP   10.98.140.9     <none>        443/TCP   3m29s

NAME                             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/metallb-frr-k8s   3         3         3       3            3           kubernetes.io/os=linux   3m29s
daemonset.apps/metallb-speaker   3         3         3       3            3           kubernetes.io/os=linux   3m29s

NAME                                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/metallb-controller              1/1     1            1           3m28s
deployment.apps/metallb-frr-k8s-statuscleaner   1/1     1            1           3m28s

NAME                                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/metallb-controller-bc9cbb54b               1         1         1       3m28s
replicaset.apps/metallb-frr-k8s-statuscleaner-75b695f48d   1         1         1       3m28s

5 MetalLB の設定

5.1 IPアドレスプールの設定

MetalLBの IPAddressPool に指定するIPアドレスは、各ノード(control、worker1、worker2)が接続されているネットワークと同じセグメントから選択する必要があります。たとえば、本記事の環境では各ノードが 192.168.1.0/24 ネットワークに接続されているため、同セグメント内の 192.168.1.200?192.168.1.210 を割り当て範囲として指定します。

以下の内容でマニフェストファイル metallb-pool.yaml を作成します。IPAddressPool でMetalLBが払い出すIPアドレスの範囲を定義し、L2Advertisement によってそのプールをL2モード(ARP)でアドバタイズする設定を行います。

[root@control ~]# vi metallb-pool.yaml
[root@control ~]# cat metallb-pool.yaml
# metallb-pool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.1.200-192.168.1.210
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2advertisement
  namespace: metallb-system

kubectl apply でマニフェストをクラスタに適用します。ipaddresspool と l2advertisement の両リソースが created と表示されれば設定完了です。

[root@control ~]# kubectl apply -f metallb-pool.yaml
ipaddresspool.metallb.io/first-pool created
l2advertisement.metallb.io/l2advertisement created

5.2 設定内容の確認

kubectl get IPAddressPool で、作成したIPアドレスプールの設定内容を確認します。ADDRESSES 列に 192.168.1.200-192.168.1.210 が表示され、AUTO ASSIGN が true となっていることを確認します。AUTO ASSIGN が true の場合、LoadBalancer タイプのServiceが作成された際にプール内のIPアドレスが自動的に割り当てられます。

[root@control ~]# kubectl get IPAddressPool -n metallb-system
NAME         AUTO ASSIGN   AVOID BUGGY IPS   ADDRESSES
first-pool   true          false             ["192.168.1.200-192.168.1.210"]

kubectl get L2Advertisement で、L2Advertisementリソースが作成されていることを確認します。

[root@control ~]# kubectl get L2Advertisement -n metallb-system
NAME              IPADDRESSPOOLS   IPADDRESSPOOL SELECTORS   INTERFACES
l2advertisement

6 ingress-nginxのインストール手順

6.1 Helm リポジトリへの ingress-nginx の追加

helm repo add コマンドを実行して、Helm のローカル設定に ingress-nginx のチャートリポジトリを登録します。
これにより、Helm を使用して ingress-nginx のチャートを取得・インストールできるようになります。

[root@control ~]# helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
"ingress-nginx" has been added to your repositories

6.2 リポジトリ情報の更新

ローカルにキャッシュされているチャート情報を最新の状態に更新します。この操作を行わないと、最新のチャート情報がローカルに反映されず、最新バージョンの検索や取得ができない場合があるため、事前に実行します。

[root@contol ~]# helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "ingress-nginx" chart repository
...Successfully got an update from the "metallb" chart repository
Update Complete. ?Happy Helming!?

helm repo list コマンドを実行して、現在 Helm に登録されているリポジトリを確認します。ingress-nginx が一覧に表示されていれば、リポジトリの追加は正常に完了しています。

[root@control ~]# helm repo list
NAME            URL
metallb         https://metallb.github.io/metallb
ingress-nginx   https://kubernetes.github.io/ingress-nginx

6.3 ingress-nginxのインストール

ingress-nginx を Helm でインストールします。ingress-nginx 名前空間を新規作成し、Service タイプを LoadBalancer、デフォルトの SSL 証明書として ingress-nginx/ingress-tls を指定しています。

[root@contol ~]# helm install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.service.type=LoadBalancer \
  --set controller.extraArgs.default-ssl-certificate=ingress-nginx/ingress-tls
NAME: ingress-nginx
LAST DEPLOYED: Fri Jul 31 20:14:02 2026
NAMESPACE: ingress-nginx
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
It may take a few minutes for the load balancer IP to be available.
You can watch the status by running 'kubectl get service --namespace ingress-nginx ingress-nginx-controller --output wide --watch'

An example Ingress that makes use of the controller:
  apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    name: example
    namespace: foo
  spec:
    ingressClassName: nginx
    rules:
      - host: www.example.com
        http:
          paths:
            - pathType: Prefix
              backend:
                service:
                  name: exampleService
                  port:
                    number: 80
              path: /
    # This section is only required if TLS is to be enabled for the Ingress
    tls:
      - hosts:
        - www.example.com
        secretName: example-tls

If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:

  apiVersion: v1
  kind: Secret
  metadata:
    name: example-tls
    namespace: foo
  data:
    tls.crt: <base64 encoded cert>
    tls.key: <base64 encoded key>
  type: kubernetes.io/tls

6.4 インストール結果の確認

ingress-nginx Namespace にインストールされている Helm リリースの一覧を確認します。

[root@contol ~]# helm list -n ingress-nginx
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                   APP VERSION
ingress-nginx   ingress-nginx   1               2026-07-31 20:14:02.182963112 +0900 JST deployed        ingress-nginx-4.15.1    1.15.1

7 nginxのインストール手順

7.1 nginxのDeployment作成

nginx をデプロイするための Deployment マニフェスト(nginx-deployment.yaml ) を作成します。この設定では、nginx コンテナを 2つの Pod で起動し、nodeSelector により worker1 ノード上に配置するよう指定しています。

[root@control ~]# vi nginx-deployment.yaml
[root@control ~]# cat nginx-deployment.yaml
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeSelector:
        kubernetes.io/hostname: worker1
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

kubectl apply コマンドを実行して、作成した マニフェストを Kubernetes クラスタへ適用します。これにより、Deployment が作成され、指定した設定に基づいて nginx Pod が起動します。

[root@control ~]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created

kubectl get pods -o wide コマンドを実行して、作成された Pod の状態と配置先ノードを確認します。-o wide オプションを付けることで、Pod の IP アドレスや実行ノードなどの詳細情報も表示できます。2つの Pod がともに Running 状態となっており、NODE 列に worker1 と表示されていることから、nodeSelector の設定どおり worker1 ノード上で nginx コンテナが正常に稼働していることを確認できます。

[root@contol ~]# kubectl get pods -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP               NODE      NOMINATED NODE   READINESS GATES
nginx-deployment-b6ddd7558-dpfk5   1/1     Running   0          15s   10.244.235.131   worker1   <none>           <none>
nginx-deployment-b6ddd7558-fclwg   1/1     Running   0          14s   10.244.235.130   worker1   <none>           <none>

7.2 nginxのService作成

nginx-service.yaml ファイルを作成し、nginx Deployment に対してアクセスするための Service を定義します。この Service は ClusterIP 型として作成され、クラスタ内部から nginx Pod へアクセスできるようになります。selector により、前の手順で作成した nginx Deployment の Pod が自動的に Service の接続先として関連付けられます。

[root@control ~]# vi nginx-service.yaml
[root@control ~]# cat nginx-service.yaml
# nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80

kubectl apply コマンドを実行して、作成した Service 定義を Kubernetes クラスタへ適用します。これにより、nginx Pod にアクセスするための仮想 IP(ClusterIP)が割り当てられます。

[root@control ~]# kubectl apply -f nginx-service.yaml
service/nginx-service created

kubectl get svc -o wide コマンドを実行して、作成された Service の状態を確認します。-o wide オプションにより、ClusterIP やセレクタ情報などの詳細を確認できます。

[root@contol ~]# kubectl get svc -o wide
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE     SELECTOR
kubernetes      ClusterIP   10.96.0.1        <none>        443/TCP   5h11m   <none>
nginx-service   ClusterIP   10.102.255.112   <none>        80/TCP    7s      app=nginx

8 httpdのインストール

8.1 httpdのDeployment作成

httpd をデプロイするための Deployment マニフェスト(httpd-deployment.yaml) を作成します。この設定では、httpd コンテナを 2つの Pod で起動し、nodeSelector により worker2 ノード上に配置するよう指定しています。

[root@control ~]# vi httpd-deployment.yaml
[root@control ~]# cat httpd-deployment.yaml
# httpd-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpd-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: httpd
  template:
    metadata:
      labels:
        app: httpd
    spec:
      nodeSelector:
        kubernetes.io/hostname: worker2
      containers:
      - name: httpd
        image: httpd:latest
        ports:
        - containerPort: 80

kubectl apply コマンドを実行して、作成した マニフェストを Kubernetes クラスタへ適用します。これにより、Deployment が作成され、指定した設定に基づいて httpd Pod が起動します。

[root@control ~]# kubectl apply -f httpd-deployment.yaml
deployment.apps/httpd-deployment created

kubectl get pods -o wide コマンドを実行して、作成された Pod の状態と配置先ノードを確認します。2つの httpd Pod がともに Running 状態となっており、NODE 列に worker2 と表示されていることから、nodeSelector の設定どおり worker2 ノード上で httpd コンテナが正常に稼働していることを確認できます。また、先に作成した nginx の Pod も worker1 ノード上で稼働を継続していることがあわせて確認できます。

[root@contol ~]# kubectl get pods -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP               NODE      NOMINATED NODE   READINESS GATES
httpd-deployment-89c46bd8f-dhr99   1/1     Running   0          22s   10.244.189.68    worker2   <none>           <none>
httpd-deployment-89c46bd8f-hztdl   1/1     Running   0          22s   10.244.189.69    worker2   <none>           <none>
nginx-deployment-b6ddd7558-dpfk5   1/1     Running   0          98s   10.244.235.131   worker1   <none>           <none>
nginx-deployment-b6ddd7558-fclwg   1/1     Running   0          97s   10.244.235.130   worker1   <none>           <none>

8.2 httpdのService作成

httpd-service.yaml ファイルを作成し、httpd Deployment に対してアクセスするための Service を定義します。この Service は ClusterIP 型として作成され、クラスタ内部から httpd Pod へアクセスできるようになります。selector により、前の手順で作成した httpd Deployment の Pod が自動的に Service の接続先として関連付けられます。

[root@control ~]# vi httpd-service.yaml
[root@control ~]# cat httpd-service.yaml
# httpd-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: httpd-service
spec:
  selector:
    app: httpd
  ports:
  - port: 80
    targetPort: 80

kubectl apply コマンドを実行して、作成した Service 定義を Kubernetes クラスタへ適用します。これにより、httpd Pod にアクセスするための仮想 IP(ClusterIP)が割り当てられます。

[root@control ~]# kubectl apply -f httpd-service.yaml
service/httpd-service created

kubectl get svc -o wide コマンドを実行して、作成された Service の状態を確認します。httpd-service が ClusterIP 型で作成され、SELECTOR に app=httpd が設定されていることから、httpd Deployment の Pod と正しく関連付けられていることを確認できます。また、先に作成した nginx-service も引き続き稼働していることがあわせて確認できます。

[root@contol ~]# kubectl get svc -o wide
NAME            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE     SELECTOR
httpd-service   ClusterIP   10.96.70.15      <none>        80/TCP    6s      app=httpd
kubernetes      ClusterIP   10.96.0.1        <none>        443/TCP   5h12m   <none>
nginx-service   ClusterIP   10.102.255.112   <none>        80/TCP    88s     app=nginx

kubectl get svc -n ingress-nginx コマンドを実行して、ingress-nginx namespace 上で稼働している Service の状態を確認します。-n オプションにより、対象の namespace を指定して Service 一覧を表示できます。ingress-nginx-controller の TYPE が LoadBalancer となっており、EXTERNAL-IP に 192.168.1.200 が割り当てられていることから、クラスタ外部からのアクセスを受け付けるための準備が整っていることを確認できます。

[root@contol ~]# kubectl get svc -n ingress-nginx
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.99.17.113    192.168.1.200   80:30428/TCP,443:31215/TCP   3m57s
ingress-nginx-controller-admission   ClusterIP      10.100.175.18   <none>          443/TCP                      3m57s

9 Ingressリソースの作成

Ingressリソースとは、クラスタ外からのHTTPリクエストをURLパスに応じて適切なServiceへ振り分けるルールを定義するリソースです。

以下の内容でマニフェストファイル ingress.yaml を作成します。
https://ingress.home.lab/nginx へのリクエスト → nginx-service へ転送
https://ingress.home.lab/httpd へのリクエスト → httpd-service へ転送

[root@control ~]# vi ingress.yaml
[root@control ~]# cat ingress.yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /nginx
        pathType: Prefix
        backend:
          service:
            name: nginx-service
            port:
              number: 80
      - path: /httpd
        pathType: Prefix
        backend:
          service:
            name: httpd-service
            port:
              number: 80

kubectl apply でマニフェストをクラスタに適用します。

[root@control ~]# kubectl apply -f ingress.yaml
ingress.networking.k8s.io/path-ingress created

kubectl get ingress で作成したIngressリソースの状態を確認します。ADDRESS 列にIPアドレスが割り当てられていることを確認します。

[root@contol ~]# kubectl get ingress
NAME           CLASS   HOSTS   ADDRESS         PORTS   AGE
path-ingress   nginx   *       192.168.1.200   80      2m

kubectl describe ingress で詳細な設定内容を確認します。Rules セクションに /nginx と /httpd のパスルールが正しく登録されており、それぞれのバックエンドPodのIPアドレスが表示されていることを確認します。また、Address に 192.168.1.200 が割り当てられていることを確認します。

[root@contol ~]# kubectl describe ingress path-ingress
Name:             path-ingress
Labels:           <none>
Namespace:        default
Address:          192.168.1.200
Ingress Class:    nginx
Default backend:  <default>
Rules:
  Host        Path  Backends
  ----        ----  --------
  *
              /nginx   nginx-service:80 (10.244.235.131:80,10.244.235.130:80)
              /httpd   httpd-service:80 (10.244.189.68:80,10.244.189.69:80)
Annotations:  nginx.ingress.kubernetes.io/rewrite-target: /
Events:
  Type    Reason  Age                  From                      Message
  ----    ------  ----                 ----                      -------
  Normal  Sync    94s (x2 over 2m18s)  nginx-ingress-controller  Scheduled for sync

kubectl get svc で ingress-nginx Namespaceのサービス一覧を確認します。ingress-nginx-controller の TYPE が LoadBalancer、EXTERNAL-IP に 192.168.1.200 が割り当てられており、ポート80および443で外部からのアクセスを受け付けていることを確認します。

[root@contol ~]# kubectl get svc -n ingress-nginx
NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.99.17.113    192.168.1.200   80:30428/TCP,443:31215/TCP   7m14s
ingress-nginx-controller-admission   ClusterIP      10.100.175.18   <none>          443/TCP                      7m14s

10 動作確認

(1) nginx
ブラウザのURL欄に https://ingress.home.lab/nginx を入力すると、以下の画面が表示されます。
aa-01.jpg

(2) httpd
ブラウザのURL欄に https://ingress.home.lab/httpd を入力すると、以下の画面が表示されます。
aa-02.jpg

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?