Skip to content

Instantly share code, notes, and snippets.

@hMatoba
Created May 10, 2020 14:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hMatoba/c2842764dd2de5e708cdff07b7689344 to your computer and use it in GitHub Desktop.
Save hMatoba/c2842764dd2de5e708cdff07b7689344 to your computer and use it in GitHub Desktop.

aksでチープな構成のk8sクラスタを組む

@hMatoba
Copy link
Author

hMatoba commented May 10, 2020

 cert-managerによる証明書更新が止まっていたので、クラスタをAzure Portalから作り直した。
 一週間後、1000円刻みに設定している料金アラートが、それまで鳴らなかったのに鳴った。コスト分析を見たところ、VMのストレージとロードバランサがbasicより上のstandardであるためにコストが増していることがわかった。

 Azure Portalからポチポチで作り直し、VMのストレージを変更することはできた。しかしロードバランサを変更しようとしたところで、作成時と別のSKUのロードバランサは割り当てられない、と。Azure Portalで作成時にSKUがbasicのロードバランサを割り当てることはできない。Azure CLIを使ってくれと。

 Azure CLIを使ってVMのストレージを安く、ロードバランサのSKUも安くで作ってみたところ、作成されるリソースが少なくてダッシュボードに到達できない。

@hMatoba
Copy link
Author

hMatoba commented May 10, 2020

 ARM(Azure Resource Template)を使ってみる。一度AKSでクラスタを作ってみて、そのテンプレートを再利用して目的のクラスタ作成にトライ。
 aks2で保存されているテンプレートでちょっと設定すれば作成できた。ただこれまでRBAC抜きでやっていたので、これを機にRBACでいってみるかと考え直す。

 次はRBAC込みでいく。

@hMatoba
Copy link
Author

hMatoba commented May 16, 2020

RBACはめんどそうなのでやっぱやめ。ネットワークをベーシックにして、ダッシュボードアクセスとアプリ配置までにしておく

@hMatoba
Copy link
Author

hMatoba commented May 16, 2020

k8sクラスタを作る→k8s操作でアプリを立ち上げる→Azureコストダウンのための操作

Azureのテンプレート機能を利用してk8sクラスタを作成

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "resourceName": {
            "type": "String",
            "metadata": {
                "description": "The name of the Managed Cluster resource."
            }
        },
        "location": {
            "defaultValue": "japaneast",
            "type": "String",
            "metadata": {
                "description": "The location of AKS resource."
            }
        },
        "dnsPrefix": {
            "type": "String",
            "metadata": {
                "description": "Optional DNS prefix to use with hosted Kubernetes API server FQDN."
            }
        },
        "osDiskSizeGB": {
            "defaultValue": 32,
            "minValue": 0,
            "maxValue": 1023,
            "type": "Int",
            "metadata": {
                "description": "Disk size (in GiB) to provision for each of the agent pool nodes. This value ranges from 0 to 1023. Specifying 0 will apply the default disk size for that agentVMSize."
            }
        },
        "kubernetesVersion": {
            "defaultValue": "1.16.7",
            "type": "String",
            "metadata": {
                "description": "The version of Kubernetes."
            }
        },
        "networkPlugin": {
            "defaultValue": "kubenet",
            "allowedValues": [
                "azure",
                "kubenet"
            ],
            "type": "String",
            "metadata": {
                "description": "Network plugin used for building Kubernetes network."
            }
        },
        "maxPods": {
            "defaultValue": 30,
            "type": "Int",
            "metadata": {
                "description": "Maximum number of pods that can run on a node."
            }
        },
        "enableRBAC": {
            "defaultValue": true,
            "type": "Bool",
            "metadata": {
                "description": "Boolean flag to turn on and off of RBAC."
            }
        },
        "vmssNodePool": {
            "defaultValue": false,
            "type": "Bool",
            "metadata": {
                "description": "Boolean flag to turn on and off of VM scale sets"
            }
        },
        "windowsProfile": {
            "defaultValue": false,
            "type": "Bool",
            "metadata": {
                "description": "Boolean flag to turn on and off of VM scale sets"
            }
        },
        "servicePrincipalClientId": {
            "defaultValue": "",
            "type": "SecureString",
            "metadata": {
                "description": "Client ID (used by cloudprovider)."
            }
        },
        "servicePrincipalClientSecret": {
            "defaultValue": "",
            "type": "SecureString",
            "metadata": {
                "description": "The Service Principal Client Secret."
            }
        },
        "enablePrivateCluster": {
            "defaultValue": false,
            "type": "Bool",
            "metadata": {
                "description": "Enable private network access to the Kubernetes cluster."
            }
        },
        "aadSessionKey": {
            "defaultValue": "",
            "type": "SecureString"
        },
        "enableHttpApplicationRouting": {
            "defaultValue": false,
            "type": "Bool",
            "metadata": {
                "description": "Boolean flag to turn on and off http application routing."
            }
        }
    },
    "resources": [
        {
            "type": "Microsoft.ContainerService/managedClusters",
            "apiVersion": "2020-02-01",
            "name": "[parameters('resourceName')]",
            "location": "[parameters('location')]",
            "dependsOn": [],
            "tags": {},
            "properties": {
                "kubernetesVersion": "[parameters('kubernetesVersion')]",
                "enableRBAC": "[parameters('enableRBAC')]",
                "dnsPrefix": "[parameters('dnsPrefix')]",
                "agentPoolProfiles": [
                    {
                        "name": "agentpool",
                        "osDiskSizeGB": "[parameters('osDiskSizeGB')]",
                        "count": 1,
                        "vmSize": "Standard_B2s",
                        "osType": "Linux",
                        "storageProfile": "ManagedDisks",
                        "type": "AvailabilitySet",
                        "mode": "System"
                    }
                ],
                "networkProfile": {
                    "loadBalancerSku": "basic",
                    "networkPlugin": "[parameters('networkPlugin')]"
                },
                "servicePrincipalProfile": {
                    "ClientId": "[parameters('servicePrincipalClientId')]",
                    "Secret": "[parameters('servicePrincipalClientSecret')]",
                    "aadSessionKey": "[parameters('aadSessionKey')]"
                },
                "apiServerAccessProfile": {
                    "enablePrivateCluster": "[parameters('enablePrivateCluster')]"
                },
                "addonProfiles": {
                    "httpApplicationRouting": {
                        "enabled": "[parameters('enableHttpApplicationRouting')]"
                    }
                }
            }
        }
    ],
    "outputs": {
        "controlPlaneFQDN": {
            "type": "String",
            "value": "[reference(concat('Microsoft.ContainerService/managedClusters/', parameters('resourceName'))).fqdn]"
        }
    }
}

イングレスコントローラを作成

kubectl create namespace ingress-basic

# Add the official stable repo
helm repo add stable https://kubernetes-charts.storage.googleapis.com/

# Use Helm to deploy an NGINX ingress controller
helm install nginx stable/nginx-ingress \
    --namespace ingress-basic \
    --set controller.replicaCount=2 \
    --set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \
    --set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux \
   --set controller.service.externalTrafficPolicy=Local

Public IPを確認

kubectl get service -l app=nginx-ingress --namespace ingress-basic

↑で確認したIPでドメインレコード設定をしておく。IPを踏んでみて、サーバにアクセスできることを確認する。404か503あたりがレスポンスになるはず。

ingressコントローラを適用する

kubectl apply -f ingress.yml

cert-managerをインストールする

kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.13/deploy/manifests/00-crds.yaml

# Label the ingress-basic namespace to disable resource validation
kubectl label namespace ingress-basic cert-manager.io/disable-validation=true

# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io

# Update your local Helm chart repository cache
helm repo update

# Install the cert-manager Helm chart
helm install \
  cert-manager \
  --namespace ingress-basic \
  --version v0.13.0 \
  jetstack/cert-manager

issuerを適用する

kubectl -f apply issuer.yml

その他も適用

kubectl apply -f certificate.yml
kubectl apply -f service.yml
kubectl apply -f dep.yml

k8sのノードプールのディスクを安いものにする。
デフォルトがPremium SSDの100GBになっている。HDDの32GBに切り詰める。

k8sクラスタを構成しているリソースグループを覗いて、Virtual Machineリソースを選ぶ。その中をたどってディスクを開くとスナップショット取得ボタンがあるのでプッシュ。
スナップショット作成が完了されたら、新しいリソースとしてマネージドディスクを作成する。作成時に、スナップショットのデータを使う選択をする。
新しいマネージドディスクが作成されたら、Virtual Machineのディスクのところにもどる。Swap Diskというボタンがあるので、作成したディスクを入れる。
ディスクのスワップが完了したら取り外されたディスクを削除する。作業によってVirtual Machineが停止していたら起動しなおす。
完了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment