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」 をクリックします。

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

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

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

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

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 を入力すると、以下の画面が表示されます。

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



