Part.1からの続きです。
VPC Gen2対応のIKSでPrivateなクラスターを動かす Part.1
試してみたこと(サマリー)
Part.1の続きで、以下の項目に関して試してみました。
操作はPart.1の時点で用意していた、Bastion(踏み台)サーバー上で実施しました。
- Private Endpoint Onlyな状態でアプリを公開する(Public/Private両方)
注意1: Privateに閉じたネットワークでのイメージの準備
今回はPrivate Endpoint Onlyな構成をとっており、IKSのWorker Nodeが所属するネットワークはインターネット接続はできません。(インターネット接続するためには、Public Gatewayを用意する必要があります。)
そのためアプリの公開に関して、DockerHubからコンテナ・イメージを持ってくる処理は今回行えません。
今回の構成のようにPrivate Networkに閉じた環境の場合、事前にICR(IBM Cloud Container Registry)に事前にイメージを保管しておき、そのイメージを使う方法が考えられます。
本記事では、イメージ「us.icr.io/<NAMESAPCE名>/nginx:alpine」を事前にICRに登録してあるものとして以下手順をまとめています。
注意2: 利用するドメインに関して
今回はIBM提供のドメインを使用します。「company.com」のようなカスタム・ドメインを利用したい場合、例えばIBM Cloud DNSサービスで、使用したいドメインをIBM提供のドメインに対しCNAMEで紐づける設定を行えば良い認識です。またそのうち試したいかなと。
Step 4. アプリの公開(Public編)
IKS上にアプリをデプロイし、まずはインターネットにアプリを公開します。
デフォルトで、IKSに対しPublic側にVPC Load Balancerが構成されており、与えられたIngress Subdomainを利用する場合はすぐに利用することが可能です。
Deployment, Serviceの作成
以下のDeployment作成用のリソース・ファイルを用意します。
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
run: my-nginx
name: my-nginx
spec:
replicas: 10
selector:
matchLabels:
run: my-nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
run: my-nginx
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: "kubernetes.io/zone"
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
run: my-nginx
- maxSkew: 1
topologyKey: "kubernetes.io/hostname"
whenUnsatisfiable: ScheduleAnyway
# whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
run: my-nginx
containers:
- image: us.icr.io/ra1nmaker/nginx:alpine
name: my-nginx
resources: {}
status: {}
このファイルを用いてDeploymentを作成し、サービスを公開します。
# Deploymentの作成
[root@ra1n-bastion1 ~]# kubectl apply -f deployment.yaml
deployment.apps/my-nginx created
# Podの状態確認
[root@ra1n-bastion1 ~]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-nginx-5f96bcb545-2w4xs 1/1 Running 0 66s 172.31.253.195 192.168.130.5 <none> <none>
my-nginx-5f96bcb545-5cp54 1/1 Running 0 66s 172.31.243.131 192.168.110.6 <none> <none>
my-nginx-5f96bcb545-7xp5c 1/1 Running 0 66s 172.31.217.3 192.168.120.4 <none> <none>
my-nginx-5f96bcb545-g9k5q 1/1 Running 0 66s 172.31.65.70 192.168.110.4 <none> <none>
my-nginx-5f96bcb545-k99lj 1/1 Running 0 66s 172.31.148.205 192.168.110.5 <none> <none>
my-nginx-5f96bcb545-qqjm5 1/1 Running 0 66s 172.31.154.131 192.168.130.4 <none> <none>
my-nginx-5f96bcb545-t7zkr 1/1 Running 0 66s 172.31.123.131 192.168.120.6 <none> <none>
my-nginx-5f96bcb545-ttssx 1/1 Running 0 66s 172.31.10.194 192.168.120.5 <none> <none>
my-nginx-5f96bcb545-tzt9g 1/1 Running 0 66s 172.31.154.130 192.168.130.4 <none> <none>
my-nginx-5f96bcb545-xwcf4 1/1 Running 0 66s 172.31.191.131 192.168.130.6 <none> <none>
# サービスを公開
[root@ra1n-bastion1 ~]# kubectl expose deploy/my-nginx --port=8080 --target-port=80 --name my-svc
service/my-svc exposed
アプリケーションの公開(Public)
Ingressを利用してPublic(インターネット)側にアプリケーションの公開を行います。本記事ではデフォルトで提供されるIngress Subdomainを利用したアプリケーションの公開を行います。
1. Ingress Subdomainの確認
以下のようにコマンドラインで確認するのが楽だと思います。
Ingress Subdomainや付属するSSL証明書がどのNamespace/Secret名で登録されているか確認できます。
[root@ra1n-bastion1 ~]# ibmcloud ks nlb-dns ls --cluster ra1n-cluster-1
OK
サブドメイン ロード・バランサーのホスト名 SSL 証明書の状況 SSL 証明書の秘密名 秘密の名前空間
ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.us-south.containers.appdomain.cloud 76790e10-us-south.lb.appdomain.cloud created ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-0000 default
2. Ingressリソースの作成
以下のようにIngressのリソース・ファイルを作成します。
ing-pub.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: demo-ingress
spec:
tls:
- hosts:
- nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-0000.us-south.containers.appdomain.cloud
secretName: ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-0000
rules:
- host: nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-0000.us-south.containers.appdomain.cloud
http:
paths:
- path: /
backend:
serviceName: my-svc
servicePort: 8080
ファイルの準備が完了したら、Ingressリソースを作成します
[root@ra1n-bastion1 ~]# kubectl apply -f ing-pub.yaml
ingress.networking.k8s.io/demo-ingress created
[root@ra1n-bastion1 ~]# kubectl get ing
NAME HOSTS ADDRESS PORTS AGE
demo-ingress nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-0000.us-south.containers.appdomain.cloud 76790e10-us-south.lb.appdomain.cloud 80, 443 8s
3. アプリへのアクセス
完了したらcurlコマンドなどでアクセスします。ここではアプリケーションをPublicに公開しているので、インターネット経由でアクセスができます。
$ curl https://nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-0000.us-south.containers.appdomain.cloud
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
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>
以上でPublic側にアプリケーションを公開することができました。
補足. VPC Gen2のIKSのアプリ公開の実装を調べてみる
VPC Gen2対応のIKSの場合、以下のようにL4のVPC Load BalancerがPublic側有効で作成されています。
Ingress SubdomainはLoad Banalcerに登録されているPublic IPで名前解決されるので、Public側からのアクセスの場合はこのLoad Balancerをまず経由します。
[root@ra1n-bastion1 ~]# ibmcloud is load-balancers
ユーザー XXXX@gmail.com としてアカウント XXXX の下でリソース・グループ prod と地域 us-south 内の世代 2 コンピュートの ロード・バランサー をリストしています...
ID 名前 ホスト名 パブリックです パブリック IP プライベート IP サブネット プロビジョン状況 作動状況 リソース・グループ
r006-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX4d22 kube-brs18a4d04f1bjdkdm1g-b16c81b658744ca7983d05f508c7a901 7679aaaa-us-south.lb.appdomain.cloud yes 52.XXX.XXX.99,169.XXX.XXX.85 192.168.130.7,192.168.120.7 iks-subnet-3,iks-subnet-2,iks-subnet-1 active online prod
IngressはL7で処理できますが、上記だとL4です。L7のALB(Application Load Balancer)機能は
IKSのPodとしてWorker Node上で稼働しているALBと組み合わせることで実現しています。
ALBとVPC Load Balancerとの紐付けは「ibmcloud ks albs」コマンドで確認できます。
(ロード・バランサーのホスト名で紐付けが確認できます。)
[root@ra1n-bastion1 ~]# ibmcloud ks albs --cluster ra1n-cluster-1
OK
ALB ID 有効化 状況 タイプ ロード・バランサーのホスト名 ゾーン ビルド
public-crbrs18a4d04f1bjdkdm1g-alb1 true enabled public 7679aaaa-us-south.lb.appdomain.cloud us-south-1 ingress:642/ingress-auth:413
public-crbrs18a4d04f1bjdkdm1g-alb2 true enabled public 7679aaaa-us-south.lb.appdomain.cloud us-south-2 ingress:642/ingress-auth:413
public-crbrs18a4d04f1bjdkdm1g-alb3 true enabled public 7679aaaa-us-south.lb.appdomain.cloud us-south-3 ingress:642/ingress-auth:413
アプリケーションの公開(Private)
続いて、Privateに閉じたアプリケーションの公開を行います。
デフォルトでは、Private用のALBやIngress Subdomainが提供されていないので、作成します。
1. private ALBの有効化
以下のように、デフォルトでは「private-」のプリフィックスのALBは無効(disabled)です。
[root@ra1n-bastion1 ~]# ibmcloud ks albs --cluster ra1n-cluster-1
OK
ALB ID 有効化 状況 タイプ ロード・バランサーのホスト名 ゾーン ビルド
private-crbrs18a4d04f1bjdkdm1g-alb1 false disabled private - us-south-1 ingress:/ingress-auth:
private-crbrs18a4d04f1bjdkdm1g-alb2 false disabled private - us-south-2 ingress:/ingress-auth:
private-crbrs18a4d04f1bjdkdm1g-alb3 false disabled private - us-south-3 ingress:/ingress-auth:
public-crbrs18a4d04f1bjdkdm1g-alb1 true enabled public 7679aaaa-us-south.lb.appdomain.cloud us-south-1 ingress:642/ingress-auth:413
public-crbrs18a4d04f1bjdkdm1g-alb2 true enabled public 7679aaaa-us-south.lb.appdomain.cloud us-south-2 ingress:642/ingress-auth:413
public-crbrs18a4d04f1bjdkdm1g-alb3 true enabled public 7679aaaa-us-south.lb.appdomain.cloud us-south-3 ingress:642/ingress-auth:413
private側のALBを有効(enabled)にします。
[root@ra1n-bastion1 ~]# ibmcloud ks alb configure vpc-gen2 --alb-id private-crbrs18a4d04f1bjdkdm1g-alb1 --enable
ALB を構成中...
OK
[root@ra1n-bastion1 ~]# ibmcloud ks alb configure vpc-gen2 --alb-id private-crbrs18a4d04f1bjdkdm1g-alb2 --enable
ALB を構成中...
OK
[root@ra1n-bastion1 ~]# ibmcloud ks alb configure vpc-gen2 --alb-id private-crbrs18a4d04f1bjdkdm1g-alb3 --enable
ALB を構成中...
OK
しばらく待ってからALBの状態を確認します。
[root@ra1n-bastion1 ~]# ibmcloud ks albs --cluster ra1n-cluster-1
OK
ALB ID 有効化 状況 タイプ ロード・バランサーのホスト名 ゾーン ビルド
private-crbrs18a4d04f1bjdkdm1g-alb1 true enabled private deee1111-us-south.lb.appdomain.cloud us-south-1 ingress:642/ingress-auth:413
private-crbrs18a4d04f1bjdkdm1g-alb2 true enabled private deee1111-us-south.lb.appdomain.cloud us-south-2 ingress:642/ingress-auth:413
private-crbrs18a4d04f1bjdkdm1g-alb3 true enabled private deee1111-us-south.lb.appdomain.cloud us-south-3 ingress:642/ingress-auth:413
public-crbrs18a4d04f1bjdkdm1g-alb1 true enabled public 7679aaaa-us-south.lb.appdomain.cloud us-south-1 ingress:642/ingress-auth:413
public-crbrs18a4d04f1bjdkdm1g-alb2 true enabled public 7679aaaa-us-south.lb.appdomain.cloud us-south-2 ingress:642/ingress-auth:413
public-crbrs18a4d04f1bjdkdm1g-alb3 true enabled public 7679aaaa-us-south.lb.appdomain.cloud us-south-3 ingress:642/ingress-auth:413
この時点で、Private OnlyなVPC Load Balancerも作成されます。
[root@ra1n-bastion1 ~]# ibmcloud is load-balancers
ユーザー XXXX@gmail.com としてアカウント XXXX の下でリソース・グループ prod と地域 us-south 内の世代 2 コンピュートの ロード・バランサー をリストしています...
ID 名前 ホスト名 パブリックです パブリック IP プライベート IP サブネット プロビジョン状況 作動状況 リソース・グループ
r006-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX4d22 kube-brs18a4d04f1bjdkdm1g-b16c81b658744ca7983d05f508c7a901 7679aaaa-us-south.lb.appdomain.cloud yes 52.XXX.XXX.99,169.XXX.XXX.85 192.168.130.7,192.168.120.7 iks-subnet-3,iks-subnet-2,iks-subnet-1 active online prod
r006-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX198e kube-brs18a4d04f1bjdkdm1g-80a7c874535d42c49f017edbc8f45411 deee1111-us-south.lb.appdomain.cloud no 192.168.130.8,192.168.120.8 iks-subnet-3,iks-subnet-2,iks-subnet-1 active online prod
Hint & Tips
Public ALBは不要であれば同様の手順でdisabledにすれば、IngressでのPublic側からのアプリケーションの公開をさせないように設定できます
2. private側Ingress Subdomainの登録
次に、作成されたVPC Load Balancerに対し、使用するIngress Subdomainを作成します。
「--lb-host」は上記で確認したVPC Load Balancerのホスト名を指定します。
[root@ra1n-bastion1 ~]# ibmcloud ks nlb-dns create vpc-gen2 --cluster ra1n-cluster-1 --lb-host deee1111-us-south.lb.appdomain.cloud --type private
NLB DNS を作成中...
OK
こちらも実行してからしばらく時間がかかりますが、以下のコマンドで登録が完了したことが確認できます。
サブドメインのホスト部の末尾の4桁が「i」から始まるものがprivate, そうでないものはpublicのドメインを表しています。
[root@ra1n-bastion1 ~]# ibmcloud ks nlb-dns ls --cluster ra1n-cluster-1
OK
サブドメイン ロード・バランサーのホスト名 SSL 証明書の状況 SSL 証明書の秘密名 秘密の名前空間
ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-0000.us-south.containers.appdomain.cloud 7679aaaa-us-south.lb.appdomain.cloud created ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-0000 default
ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-i001.us-south.containers.appdomain.cloud deee1111-us-south.lb.appdomain.cloud created ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-i001 default
3. Ingressでの公開
Publicの場合と同様に、Ingressのリソース・ファイルを作成します。
annotationとして「ingress.bluemix.net/ALB-ID」を指定するのがポイントで、「;」区切りでprivate ALBのIDを指定するのがポイントです。
ing-pri.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: demo-ingress-pri
annotations:
ingress.bluemix.net/ALB-ID: "private-crbrs18a4d04f1bjdkdm1g-alb1;private-crbrs18a4d04f1bjdkdm1g-alb2;private-crbrs18a4d04f1bjdkdm1g-alb3"
spec:
tls:
- hosts:
- nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-i001.us-south.containers.appdomain.cloud
secretName: ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-i001
rules:
- host: nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-i001.us-south.containers.appdomain.cloud
http:
paths:
- path: /
backend:
serviceName: my-svc
servicePort: 8080
ファイルを作成したら、Ingressリソースを作成します。
[root@ra1n-bastion1 ~]# kubectl apply -f ingress-pri.yaml
ingress.networking.k8s.io/demo-ingress-private created
4. アプリへのアクセス
では、実際にアクセスしてみましょう。
まずは、インターネット越しにアクセスできるかですが、今回はPrivateにのみ公開しているため、Public側からはアクセスできません。
$curl https://nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-i001.us-south.containers.appdomain.cloud/
curl: (7) Failed to connect to nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-i001.us-south.containers.appdomain.cloud port 443: Operation timed out
Private Addressに名前解決されているので、当然といえば当然ですね。
$nslookup nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-i001.us-south.containers.appdomain.cloud
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-i001.us-south.containers.appdomain.cloud canonical name = deee1111-us-south.lb.appdomain.cloud.
Name: deee1111-us-south.lb.appdomain.cloud
Address: 192.168.130.8
Name: deee1111-us-south.lb.appdomain.cloud
Address: 192.168.120.8
一方で、Transit Gateway経由でIKSのVPCにアクセスが可能なBastion(踏み台)からはアクセスできます。
$curl https://nginx.ra1n-cluster-1-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-i001.us-south.containers.appdomain.cloud/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
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>
以上で、Private側のみアプリケーションを公開することもできました。
Part.2のまとめ
以上で、Private Endpoint OnlyなIKSクラスターでアプリケーションの公開までを実施することができました。
カスタム・ドメインでの公開はもう少しステップが必要ですが、そのうち補記したいと思います。