はじめに
Oracle Cloud の勉強の一環で、公式のチュートリアルを基に進めていきます。公式のチュートリアルでは日本語、かつ、GUI操作の内容となっています。わかりやすく書かれているので、基本はこちらを参照していただけるとよいと思います。
このQiitaの記事は、上記のチュートリアルを CLI であえて実施した備忘録として書きます。
CLI の理由は、GUIと比べて再現性や再実行性が高いのと、なんとなくかっこいいから
今回のテーマ
ロードバランサーでWebサーバーを負荷分散する
https://community.oracle.com/docs/DOC-1019312
前提作業
oci cliの導入
oci cli と jq コマンドを使用可能なこと。次のQiita記事で導入した手順を書いています
https://qiita.com/sugimount/items/63a8cfe1163030ae8804
OCI DNSでドメイン連携済み
お名前.com などで購入したドメインと、OCI DNSを連携している必要があります
参照:https://qiita.com/sugimount/items/7d14ca7185d87c9763ff
仮想ネットワーク(VCN)の作成
前回 の記事を参考に、Public Subnet を2個作成します。
2個のInstance作成して Apache を導入
Instance作成
こちらも、前回 の記事を参考に、2個のInstanceを作成します。
参考:自分の環境でのコマンド
set vcn_ocid (oci network vcn list | jq -r '.data | map(select(.["display-name"] == "TutorialVCN"))[].id')
set subnet2_ocid (oci network subnet list --vcn-id $vcn_ocid | jq -r '.data | map(select(.["display-name"] == "tutorial_subnet2"))[].id')
set subnet3_ocid (oci network subnet list --vcn-id $vcn_ocid | jq -r '.data | map(select(.["display-name"] == "tutorial_subnet3"))[].id')
set oraclelinux76_ocid (echo ocid1.image.oc1.iad.aaaaaaaawufnve5jxze4xf7orejupw5iq3pms6cuadzjc7klojix6vmk42va)
set ubuntu1804_ocid (echo ocid1.image.oc1.iad.aaaaaaaahh6wjs5qp2sieliieujdnih7eyxt32ets3nuiifzjjfkqnbelcra)
1個目
oci compute instance launch \
--availability-domain AJtg:US-ASHBURN-AD-2 \
--fault-domain FAULT-DOMAIN-1 \
--shape VM.Standard2.1 \
--display-name web_1 \
--hostname-label web-1 \
--image-id $oraclelinux76_ocid \
--subnet-id $subnet2_ocid \
--assign-public-ip true \
--private-ip 172.16.2.2 \
--ssh-authorized-keys-file ~/.ssh/id_rsa.pub
2個目
oci compute instance launch \
--availability-domain AJtg:US-ASHBURN-AD-3 \
--fault-domain FAULT-DOMAIN-1 \
--shape VM.Standard2.1 \
--display-name web_2 \
--hostname-label web-2 \
--image-id $oraclelinux76_ocid \
--subnet-id $subnet3_ocid \
--assign-public-ip true \
--private-ip 172.16.3.2 \
--ssh-authorized-keys-file ~/.ssh/id_rsa.pub
Apache 導入
作成した2台の Oracle Linux 7.6 の Instance へ Apache を導入します
sudo yum -y install httpd
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload
sudo systemctl start httpd
sudo systemctl enable httpd
htmlファイルをそれぞれのhostがわかるように作成します
sudo su -
echo 'Web Server 1' >> /var/www/html/index.html
exit
sudo su -
echo 'Web Server 2' >> /var/www/html/index.html
exit
LoadBalancer用のSubnet作成
Instance側のSecurity Listを更新
http 80 を通すために更新します。oci cli による更新は、既存のルールと追加したいルールの両方ともを指定する必要があるため、まずは既存のルールを確認します。
> oci network security-list list --vcn-id $vcn_ocid --display-name "Default Security List for TutorialVCN" | jq -r '.data[0]."ingress-security-rules"'
[
{
"icmp-options": null,
"is-stateless": false,
"protocol": "6",
"source": "0.0.0.0/0",
"source-type": "CIDR_BLOCK",
"tcp-options": {
"destination-port-range": {
"max": 22,
"min": 22
},
"source-port-range": null
},
"udp-options": null
},
{
"icmp-options": {
"code": 4,
"type": 3
},
"is-stateless": false,
"protocol": "1",
"source": "0.0.0.0/0",
"source-type": "CIDR_BLOCK",
"tcp-options": null,
"udp-options": null
},
{
"icmp-options": null,
"is-stateless": false,
"protocol": "1",
"source": "172.16.0.0/16",
"source-type": "CIDR_BLOCK",
"tcp-options": null,
"udp-options": null
}
]
上記結果の "ingress-security-rules" の値を残しつつ、http80とhttp443を通信許可する設定を入れます
mkdir ~/workdir
string trim '
[
{
"icmp-options": null,
"is-stateless": false,
"protocol": "6",
"source": "0.0.0.0/0",
"source-type": "CIDR_BLOCK",
"tcp-options": {
"destination-port-range": {
"max": 22,
"min": 22
},
"source-port-range": null
},
"udp-options": null
},
{
"icmp-options": {
"code": 4,
"type": 3
},
"is-stateless": false,
"protocol": "1",
"source": "0.0.0.0/0",
"source-type": "CIDR_BLOCK",
"tcp-options": null,
"udp-options": null
},
{
"icmp-options": null,
"is-stateless": false,
"protocol": "1",
"source": "172.16.0.0/16",
"source-type": "CIDR_BLOCK",
"tcp-options": null,
"udp-options": null
},
{
"icmp-options": null,
"is-stateless": false,
"protocol": "6",
"source": "172.16.0.0/16",
"source-type": "CIDR_BLOCK",
"tcp-options": {
"destination-port-range": {
"max": 80,
"min": 80
},
"source-port-range": null
},
"udp-options": null
},
{
"icmp-options": null,
"is-stateless": false,
"protocol": "6",
"source": "172.16.0.0/16",
"source-type": "CIDR_BLOCK",
"tcp-options": {
"destination-port-range": {
"max": 443,
"min": 443
},
"source-port-range": null
},
"udp-options": null
}
]
' > ~/workdir/update-default-securitylist.json
Update対象のSecurity ListのOCIDを変数に格納
set securitylist_ocid (oci network security-list list --vcn-id $vcn_ocid --display-name "Default Security List for TutorialVCN" | jq -r '.data[0].id')
Security List を更新します
oci network security-list update --security-list-id $securitylist_ocid --ingress-security-rules file://~/workdir/update-default-securitylist.json --force
Security Listの作成
LB用のSecurity List を作成します。
ちなみに、LBに設定を行うことで、適切なルールが自動設定されるとチュートリアルに書いていましたが、自分の環境では動作しませんでした(なぜ・・・)
IngressとEgress ルール用のJSONファイルを生成します。
mkdir ~/workdir
string trim '
[
{
"icmp-options": null,
"is-stateless": false,
"protocol": "6",
"source": "0.0.0.0/0",
"source-type": "CIDR_BLOCK",
"tcp-options": {
"destination-port-range": {
"max": 80,
"min": 80
},
"source-port-range": null
},
"udp-options": null
},
{
"icmp-options": null,
"is-stateless": false,
"protocol": "6",
"source": "0.0.0.0/0",
"source-type": "CIDR_BLOCK",
"tcp-options": {
"destination-port-range": {
"max": 443,
"min": 443
},
"source-port-range": null
},
"udp-options": null
}
]
' > ~/workdir/create-httplb1-securitylist-ingress.json
string trim '
[
{
"destination": "0.0.0.0/0",
"destination-type": "CIDR_BLOCK",
"icmp-options": null,
"is-stateless": false,
"protocol": "all",
"tcp-options": null,
"udp-options": null
}
]
' > ~/workdir/create-httplb1-securitylist-egress.json
Security List の作成
oci network security-list create --display-name http_securitylist --egress-security-rules file://~/workdir/create-httplb1-securitylist-egress.json --ingress-security-rules file://~/workdir/create-httplb1-securitylist-ingress.json --vcn-id $vcn_ocid
作成した security list の OCID を変数に格納します
set security_list_ocid (oci network security-list list --vcn-id $vcn_ocid --display-name "http_securitylist" | jq -r '.data[0].id')
Route Tableの作成
作成済みのInternetGatewayのIDを取得します
set ig_ocid (oci network internet-gateway list --display-name "tutorial-int-gw1" --vcn-id $vcn_ocid | jq -r '.data[0].id')
RuleのJSON作成
mkdir ~/workdir
string trim '
[
{
"cidrBlock":"0.0.0.0/0",
"destination": "0.0.0.0/0",
"destination-type": "CIDR_BLOCK",
"networkEntityId":"sedstring"
}
]
' > ~/workdir/routetable_rule.json
sed -i "s/sedstring/$ig_ocid/g" ~/workdir/routetable_rule.json
確認
> cat routetable_rule.json
[
{
"cidrBlock":"0.0.0.0/0",
"destination": "0.0.0.0/0",
"destination-type": "CIDR_BLOCK",
"networkEntityId":"ocid1.internetgateway.oc1.iad.aaaaaaaaknm4us55oouldxwrk5oi7hmyjeju6vb5wgrixrk5tk6pp76gnkhq"
}
]
作成
oci network route-table create --display-name lb_routetable --vcn-id $vcn_ocid --route-rules file://~/workdir/routetable_rule.json
確認
> oci network route-table list --vcn-id $vcn_ocid
{
"data": [
{
"compartment-id": "mask",
"defined-tags": {},
"display-name": "lb_routetable",
"freeform-tags": {},
"id": "ocid1.routetable.oc1.iad.aaaaaaaa7xe6ufwopliid7gqc766gdsd27gdeom6gwooxfek3szsq23tutia",
"lifecycle-state": "AVAILABLE",
"route-rules": [
{
"cidr-block": "0.0.0.0/0",
"destination": "0.0.0.0/0",
"destination-type": "CIDR_BLOCK",
"network-entity-id": "ocid1.internetgateway.oc1.iad.aaaaaaaaknm4us55oouldxwrk5oi7hmyjeju6vb5wgrixrk5tk6pp76gnkhq"
}
],
"time-created": "2019-02-09T03:20:25.918000+00:00",
"vcn-id": "ocid1.vcn.oc1.iad.aaaaaaaamqjvjlxum3t2p727i2akoeltk2z2tk4wxukoqlmbskf27lzollna"
}
]
変数に格納します
set routetable_ocid (oci network route-table list --vcn-id $vcn_ocid --display-name "lb_routetable" | jq -r '.data[0].id')
LB用のsubnet作成
Instanceと同じサブネットでもOKですが、別のSubnetとして動かしてみます
set vcn_ocid (oci network vcn list | jq -r '.data | map(select(.["display-name"] == "TutorialVCN"))[].id')
oci network subnet create --availability-domain AJtg:US-ASHBURN-AD-1 --cidr-block 172.16.11.0/24 --vcn-id $vcn_ocid --display-name lb_subnet1 --dns-label lbsubnet1 --prohibit-public-ip-on-vnic false --route-table-id $routetable_ocid --security-list-ids "[\"$security_list_ocid\"]"
oci network subnet create --availability-domain AJtg:US-ASHBURN-AD-2 --cidr-block 172.16.12.0/24 --vcn-id $vcn_ocid --display-name lb_subnet2 --dns-label lbsubnet2 --prohibit-public-ip-on-vnic false --route-table-id $routetable_ocid --security-list-ids "[\"$security_list_ocid\"]"
変数に格納します
set lbsubnet1 (oci network subnet list --vcn-id $vcn_ocid --display-name "lb_subnet1" | jq -r '.data[0].id')
set lbsubnet2 (oci network subnet list --vcn-id $vcn_ocid --display-name "lb_subnet2" | jq -r '.data[0].id')
Load Balancer の作成
LoadBalancerの作成
oci lb load-balancer create --display-name "httplb1" --shape-name "100Mbps" --is-private false --subnet-ids "[\"$lbsubnet1\",\"$lbsubnet2\"]"
LoadBalancerのIDを取得
set lb_ocid (oci lb load-balancer list --display-name "httplb1" | jq -r '.data[0].id')
backend-setの作成
backendのパラメータを指定するためにJSONファイルを作成。作成した2台のInstanceの情報を指定します。
string trim '
[
{
"backup": false,
"drain": false,
"ip-address": "172.16.2.2",
"offline": false,
"port": 80,
"weight": 1
},
{
"backup": false,
"drain": false,
"ip-address": "172.16.3.2",
"offline": false,
"port": 80,
"weight": 1
}
]
' > ~/workdir/backends.json
Backend-set を作成します。Instanceに設定した Apache に沿うようにパラメータを指定します。
oci lb backend-set create \
--name "httplb1_backend1" \
--load-balancer-id $lb_ocid \
--backends file://~/workdir/backends.json \
--health-checker-interval-in-ms 100000 \
--health-checker-port 80 \
--health-checker-protocol "HTTP" \
--health-checker-response-body-regex "" \
--health-checker-retries 3 \
--health-checker-return-code 200 \
--health-checker-timeout-in-ms 3000 \
--health-checker-url-path "/" \
--policy "ROUND_ROBIN"
確認します
> oci lb backend-set list --load-balancer-id $lb_ocid
{
"data": [
{
"backends": [
{
"backup": false,
"drain": false,
"ip-address": "172.16.2.2",
"name": "172.16.2.2:80",
"offline": false,
"port": 80,
"weight": 1
},
{
"backup": false,
"drain": false,
"ip-address": "172.16.3.2",
"name": "172.16.3.2:80",
"offline": false,
"port": 80,
"weight": 1
}
],
"health-checker": {
"interval-in-millis": 100000,
"port": 80,
"protocol": "HTTP",
"response-body-regex": "",
"retries": 3,
"return-code": 200,
"timeout-in-millis": 3000,
"url-path": "/"
},
"name": "httplb1_backend1",
"policy": "ROUND_ROBIN",
"session-persistence-configuration": null,
"ssl-configuration": null
}
],
"etag": "142338114"
}
listener の作成
listenerの作成
oci lb listener create --default-backend-set-name "httplb1_backend1" --port 80 --protocol "HTTP" --name "httplb1_listener1" --load-balancer-id $lb_ocid
LoadBalancer経由で InstanceにHTTPアクセス(Global IP)
アクセスするたびに、ラウンドロビンでアクセス先が切り替わっていることを確認できます。
> curl http://129.213.171.71/
Web Server 1
> curl http://129.213.171.71/
Web Server 2
LoadBalancerをhostname経由でアクセス
OCI DNSで名前解決用のAレコードを作成します。
まずは、JSONのパラメータファイルを生成します。IP Address は LoadBalancer の GlobalIP を指定しています。
string trim '
[
{
"domain": "test.sugi.tokyo",
"is-protected": false,
"rdata": "129.213.171.71",
"rrset-version": "2",
"rtype": "A",
"ttl": 30
}
]
' > ~/workdir/test.sugi.tokyo.json
ZoneにA Record を作成します
oci dns record domain patch --zone-name-or-id "sugi.tokyo" --domain "test.sugi.tokyo" --items file://~/workdir/test.sugi.tokyo.json
LoadBalancer経由で InstanceにHTTPアクセス(Hostname)
アクセスするたびに、ラウンドロビンでアクセス先が切り替わっていることを確認できます。
> curl http://test.sugi.tokyo/
Web Server 1
> curl http://test.sugi.tokyo/
Web Server 2