ujunのブログ

KubernetesクラスタにHetzner Cloud Controller ManagerをデプロイしてLoad Balancerをプロビジョニングする

KubernetesクラスタをHetznerCloudに秒で作ることができるようになった。また、Hetznerの永続ボリュームをプロビジョニングできるようになったので、LoadBalancer ServiceでLoad Balancerをプロビジョニングできるようにします。

github.com

前提 : kubeletの起動パラメータ

kubelet起動時に --cloud-provider=external のパラメータを渡す必要があります。RancherでKubernetesクラスタを構成する場合、以下のように In-Tree Cloud Provider の部分で External を選択すると良さそうです。

f:id:ujun:20201231211421p:plain

これをやらないと、後述するようなエラーが出ます。

Secretの登録

以下でHetzner CloudのAPI トークンをSecretを作ります。また、Private Network経由でトラフィックをバランシングしたいので、経由するVirtual Network名も登録します。

$ kubectl -n kube-system create secret generic hcloud --from-literal=token=<TOKEN> --from-literal=network=<NETWORK NAME>
secret/hcloud created

Hetzner Cloud Controller Managerのデプロイ

まずは、以下のデプロイ用マニフェストたちをローカルに保存します。

https://github.com/hetznercloud/hcloud-cloud-controller-manager/tree/master/deploy

そして、ccm-networks.yaml 内の --cluster-cidr の部分を、自分の環境に合わせて変更(デフォルトは 10.224.0.0/16 )。

     containers:
        - image: hetznercloud/hcloud-cloud-controller-manager:v1.8.1
          name: hcloud-cloud-controller-manager
          command:
            - "/bin/hcloud-cloud-controller-manager"
            - "--cloud-provider=hcloud"
            - "--leader-elect=false"
            - "--allow-untagged-cloud"
            - "--allocate-node-cidrs=true"
            - "--cluster-cidr=10.224.0.0/16" 

その後、以下でデプロイ。

$ kubectl apply -f /path/to/ccm-networks.yaml
  serviceaccount/cloud-controller-manager created
  clusterrolebinding.rbac.authorization.k8s.io/system:cloud-controller-manager created
  deployment.apps/hcloud-cloud-controller-manager created

LoadBalancer Serviceを作る

試しにてきとうなDeploymentをデプロイしておく。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sample-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: sample-app
      template:
        metadata:
          labels:
            app: sample-app
        spec:
          containers:
          - name: nginx-container
            image: amsy810/echo-nginx:v2.0

そして、ここで起動したPodをSelectorの対象にするようにLoadBalancerの定義を記載します。

    apiVersion: v1
    kind: Service
    metadata:
      name: sample-service
      annotations:
        load-balancer.hetzner.cloud/location: nbg1
        load-balancer.hetzner.cloud/use-private-ip: "true"
    spec:
      type: LoadBalancer
      ports:
        - port: 80
          nodePort: 30080
      selector:
        app: sample-app

上記では、annotationsに外部LBを作成するリージョンとプライベートIPを使うことを記載していますが、他にも豊富な属性を定義できます

これをデプロイすると、外部LBが作成され、TargetとServiceも上記の定義により自動作成されます。

以下のようにHetzner Cloud ConsoleからLBができていることが確認できます。LBの名前がランダムな文字列ですが、annotationsに load-balancer.hetzner.cloud/name を指定すれば任意の名前が設定できる)

f:id:ujun:20201231220635p:plain

ちなみに、前提のところでkubeletの起動パラメータとして --cloud-provider=external を付与していないと、以下のようなエラーが出て、外部LBは作成できるのですが、TargetとServiceが作成されないことになるので注意。

reason: 'SyncLoadBalancerFailed' Error syncing load balancer: failed to ensure load balancer: hcloud/loadBalancers.EnsureLoadBalancer: hcops/LoadBalancerOps.ReconcileHCLBTargets: hcops/providerIDToServerID: missing prefix hcloud://:

まとめ

ボリュームのプロビジョニングはできるし外部LBのプロビジョニングはできるし、Hetzner CloudでいろいろKubernetesの検証をする準備がこれで整ってきました。

参考