自己構築 Kubernetes クラスターを Container Service for Kubernetes に移行する場合、デフォルトのシステムイメージとサービスを使用して Container Service for Kubernetes クラスターを作成することを推奨します。 カスタムイメージを使用して、ビジネス要件に基づいて Container Service for Kubernetesクラスターを作成することもできます。 本ページでは、カスタムイメージを使用して Container Service for Kubernetes クラスターを作成する方法について説明します。

このタスクについて

自己構築 Kubernetes クラスターを Container Service for Kubernetes に移行する場合、CentOS 7.6 または Aliyun Linux 2.1903 のデフォルトシステムイメージ、およびオペレーティングシステムカーネル、ドメインネームシステム (DNS) サービスなどのデフォルトシステムサービスと Yum リポジトリを使用することを推奨します。 Container Service for Kubernetes は、特別なビジネス要件を満たすためにカスタムイメージもサポートしています。 Alibaba Cloud では、オープンソースのツールの『 ack-image-builder』を提供し、Container Service for Kubernetes の要件を満たすカスタムイメージをすばやく作成できます。

Container Service for Kubernetes クラスターを作成

最初に、ワーカーノードなしの専用 Kubernetes クラスター、または 2 つのワーカーノードを持つ管理対象の Kubernetes クラスターを作成してから、カスタムイメージを使用するワーカーノードをクラスターに追加することを推奨します。 これにより、時間が節約され、エラーの確率が減少します。

  1. デフォルトのシステムイメージを使用して、3 つまたは 5 つのマスターノードを備え、ワーカーノードを持たない専用 Kubernetes クラスターを作成します。 詳細については、「Kubernetes クラスターの作成」をご参照ください。
    管理対象 Kubernetes クラスターを作成する場合、少なくとも 2 つのワーカーノードを選択します。 詳細については、「 マネージド Kubernetes クラスターの作成」をご参照ください。
  2. カスタムイメージを使用するワーカーノードをクラスターに追加します。 詳細については、「Kubernetes クラスターをスケール アウトする」をご参照ください。
    ワーカーノードをクラスターに追加した後に初期化スクリプトを実行する場合、Elastic Compute Service (ECS) インスタンスのユーザーデータを設定することができます。
    カスタムイメージ を使用するには、 ユーザーデータ を設定して、チケットを起票します。

次のセクションでは、ack-image-builder を使用してカスタムイメージを作成する方法について説明します。

ack-image-builder を使用

ack-image-builder ツールは、オープンソースツール『 HashiCorp Packer』に基づいて開発されています。 ack-image-builder ツールは、カスタムイメージを作成するためのデフォルト設定テンプレートと検証スクリプトを提供しています。

ack-image-builder を使用すると、手動操作によるエラーの確率を減らすことができます。 さらに、ack-image-builder ツールはトラブルシューティングを支援するためにイメージの変更を記録します。 ack-image-builder ツールを使用して、Container Service for Kubernetes クラスターのカスタムイメージを作成するには、次の手順に従います。

  1. Packer をインストールします。
    Packer を『 official website』からダウンロードします。 バージョンがお使いのオペレーティングシステムと互換性があることをご確認ください。 『 Installation documentation』に従い、Packer をインストールして、確認します。

    packer version コマンドを実行します。 Packer のバージョン番号が返される場合、Packer は正常にインストールされています。

    $ packer version
    Packer v1.4.1
  2. Packer テンプレートを作成します。
    Packer を使用してカスタムイメージを作成するには、JSON 形式でテンプレートを作成する必要があります。 テンプレートでは、カスタムイメージを作成するのに使用した『 image builder 』と『 provisioner』を指定する必要があります。 この例では、Alicloud Image Builder とシェルプロビジョナー機能が使用されています。
    {
      "variables": {
        "region": "cn-hangzhou",
        "image_name": "test_image{{timestamp}}",
        "source_image": "centos_7_06_64_20G_alibase_20190711.vhd",
        "instance_type": "ecs.n1.large",
        "access_key": "{{env `ALICLOUD_ACCESS_KEY`}}",
        "secret_key": "{{env `ALICLOUD_SECRET_KEY`}}"
      },
      "builders": [
        {
          "type": "alicloud-ecs",
          "access_key": "{{user `access_key`}}",
          "secret_key": "{{user `secret_key`}}",
          "region": "{{user `region`}}",
          "image_name": "{{user `image_name`}}",
          "source_image": "{{user `source_image`}}",
          "ssh_username": "root",
          "instance_type": "{{user `instance_type`}}",
          "io_optimized": "true"
        }
      ],
      "provisioners": [
        {
          "type": "shell",
          "scripts": [
            "config/default.sh",
            "scripts/updateDNS.sh",
            "scripts/reboot.sh",
            "scripts/verify.sh"
          ],
          "expect_disconnect": true
        }
      ]
    }
    パラメーター 説明 
    access_key AccessKey ID。
    secret_key AccessKey シークレット
    region カスタムイメージの作成に使用される中間インスタンスのリージョン
    image_name カスタムイメージの名前
    source_image カスタムイメージの作成に使用する、ソースイメージの名前 このパラメーターを Alibaba Cloud が提供するパブリックイメージの名前に設定します。
    instance_type カスタムイメージの作成に使用する、中間インスタンスのタイプを設定します。
    プロビジョナー カスタムイメージの作成に使用されるプロビジョナー
  3. リソースアクセス管理 (RAM) ユーザーを作成し、Access Key を生成します。
    カスタムイイメージを作成するには、高いアクセス権限が必要です。 RAM ユーザーを作成し、『 RAM policy』を使用して Packer に必要なアクセス権限を RAM ユーザーに付与することを推奨します。 RAM ユーザーの AccessKey を生成します。 詳細については、「 t13782.html#concept_53045_zh」をご参照ください。
  4. AccessKey 情報をテンプレートに追加し、カスタムイメージを作成します。
    1. 次のコマンドを実行して、AccessKey 情報を追加します。
      export ALICLOUD_ACCESS_KEY=XXXXXX
      export ALICLOUD_SECRET_KEY=XXXXXX
    2. カスタムイメージを作成するには、次のコマンドを実行します。
      packer build alicloud.json
      alicloud-ecs output will be in this color.
      
      ==> alicloud-ecs: Prevalidating source region and copied regions...
      ==> alicloud-ecs: Prevalidating image name...
          alicloud-ecs: Found image ID: centos_7_06_64_20G_alibase_20190711.vhd
      ==> alicloud-ecs: Creating temporary keypair: packer_xxx
      ==> alicloud-ecs: Creating vpc
          alicloud-ecs: Created vpc: xxxxxx
      ==> alicloud-ecs: Creating vswitch...
          alicloud-ecs: Created vswitch: xxxxxx
      ==> alicloud-ecs: Creating security groups...
          alicloud-ecs: Created security group: xxxxxx
      ==> alicloud-ecs: Creating instance.
          alicloud-ecs: Created instance: xxxxxx
      ==> alicloud-ecs: Allocating eip
          alicloud-ecs: Allocated eip: xxxxxx
          alicloud-ecs: Attach keypair packer_xxx to instance: i-xxx
      ==> alicloud-ecs: Starting instance: i-xxx
      ==> alicloud-ecs: Using ssh communicator to connect: 47.111.127.54
      ==> alicloud-ecs: Waiting for SSH to become available...
      ==> alicloud-ecs: Connected to SSH!
      ==> alicloud-ecs: Provisioning with shell script: scripts/verify.sh
          alicloud-ecs: [20190726 11:04:10]: Check if kernel version >= 3.10.  Verify Passed!
          alicloud-ecs: [20190726 11:04:10]: Check if systemd version >= 219.  Verify Passed!
          alicloud-ecs: [20190726 11:04:10]: Check if sshd is running and listen on port 22.  Verify Passed!
          alicloud-ecs: [20190726 11:04:10]: Check if cloud-init is installed.  Verify Passed!
          alicloud-ecs: [20190726 11:04:10]: Check if wget is installed.  Verify Passed!
          alicloud-ecs: [20190726 11:04:10]: Check if curl is installed.  Verify Passed!
          alicloud-ecs: [20190726 11:04:10]: Check if kubeadm is cleaned up.  Verify Passed!
          alicloud-ecs: [20190726 11:04:10]: Check if kubelet is cleaned up.  Verify Passed!
          alicloud-ecs: [20190726 11:04:10]: Check if kubectl is cleaned up.  Verify Passed!
          alicloud-ecs: [20190726 11:04:10]: Check if kubernetes-cni is cleaned up.  Verify Passed!
      ==> alicloud-ecs: Stopping instance: xxxxxx
      ==> alicloud-ecs: Waiting instance stopped: xxxxxx
      ==> alicloud-ecs: Creating image: test_image1564110199
          alicloud-ecs: Detach keypair packer_xxx from instance: i-xxx
      ==> alicloud-ecs: Cleaning up 'EIP'
      ==> alicloud-ecs: Cleaning up 'instance'
      ==> alicloud-ecs: Cleaning up 'security group'
      ==> alicloud-ecs: Cleaning up 'vSwitch'
      ==> alicloud-ecs: Cleaning up 'VPC'
      ==> alicloud-ecs: Deleting temporary keypair...
      Build 'alicloud-ecs' finished.
      
      ==> Builds finished. The artifacts of successful builds are:
      --> alicloud-ecs: Alicloud images were created:
      
      cn-hangzhou: m-bp1aifbnupnaktj00q7s
      scripts/verify.sh』スクリプトは、カスタムイメージを認証するために使用されます。

カスタムオペレーティングシステムカーネルを使用

Container Service for Kubernetes には、V3.10 以降のカーネルを備えた Linux オペレーティングシステムが必要です。 カスタマイズする RPM パッケージのみを更新することを推奨します。 カーネルのブートパラメーターを設定する必要があります。

サンプルコードは次のとおりです。
$ cat scripts/updateOSKernel.sh
#! /bin/bash
VERSION_KERNEL="3.10.0-1062.4.3.el7"
yum  localinstall -y  http://xxx.xxx.xxx.xxx/kernel-${VERSION_KERNEL}.x86_64.rpm   http://xxx.xxx.xxx.xxx/kernel-devel-${VERSION_KERNEL}.x86_64.rpm   http://xxx.xxx.xxx.xxx/kernel-headers-${VERSION_KERNEL}.x86_64.rpm
grub_num=$(cat /etc/grub2.cfg |awk -F\' '$1=="menuentry " {print i++ " : " $2}' |grep $VERSION_KERNEL |awk -F ':' '{print $1}')
grub2-set-default $grub_num
yum update -y コマンドを実行して、RPM パッケージのすべてを更新することは推奨しません。

オペレーティングシステムカーネルをカスタマイズする

カーネルパラメーターをカスタマイズするときは、次のパラメーターを上書きしないでください。
["vm.max_map_count"]="262144"
["kernel.softlockup_panic"]="1"
["kernel.softlockup_all_cpu_backtrace"]="1"
["net.core.somaxconn"]="32768"
["net.core.rmem_max"]="16777216"
["net.core.wmem_max"]="16777216"
["net.ipv4.tcp_wmem"]="4096 12582912 16777216"
["net.ipv4.tcp_rmem"]="4096 12582912 16777216"
["net.ipv4.tcp_max_syn_backlog"]="8096"
["net.ipv4.tcp_slow_start_after_idle"]="0"
["net.core.netdev_max_backlog"]="16384"
["fs.file-max"]="2097152"
["fs.inotify.max_user_instances"]="8192"
["fs.inotify.max_user_watches"]="524288"
["fs.inotify.max_queued_events"]="16384"
["net.ipv4.ip_forward"]="1"
["net.bridge.bridge-nf-call-iptables"]="1"
["fs.may_detach_mounts"]="1"
["net.ipv4.conf.default.rp_filter"]="0"
["net.ipv4.tcp_tw_reuse"]="0"
["net.ipv4.tcp_tw_recycle"]="0"
上記のパラメーターの一部を変更する必要がある場合は、Alibaba Cloud エンジニアにチケットを起票して、効果の分析についてお問合せください。 上記のパラメーターを変更する権限が付与されたら、クラスターを作成またはスケールアウトするためのページに移動して、 [詳細オプションを表示] をクリックして、 [ユーザーデータ] フィールドにスクリプトを入力します。

カスタム DNS サービスを使用

カスタム DNS サービスを使用する場合、次の点にご注意ください。
  • Alibaba Cloud ネームサーバーをアップストリームネームサーバーに追加します。
    cat /etc/resolv.conf
    options timeout:2 attempts:3 rotate single-request-reopen
    ; generated by /usr/sbin/dhclient-script
    nameserver 100.XX.XX.136
    nameserver 100.XX.XX.138
  • /etc/resolve.conf ファイルを変更後にロックします。 それ以外の場合、cloud-init は ECS インスタンスの再起動後にファイルをデフォルト設定に復元します。 サンプルコードは次のとおりです。
    $ cat scripts/updateDNS.sh
    #! /bin/bash
    # unlock DNS file in case it was locked
    chattr -i /etc/resolv.conf
    
    # カスタムネームサーバーを使用して xxx.xxx.xxx.xxx を置き換える
    echo -e "nameserver xxx.xxx.xxx.xxx\nnameserver xxx.xxx.xxx.xxx" > /etc/resolv.conf
    
    # cloudinit/NetworkManager による上書きを防ぐために解決をロックしたままにする
    chattr +i /etc/resolv.conf
  • カスタム DNS サービスの適切なパフォーマンスを保証します。

    クラスターに多数のノードが含まれる場合、カスタム DNS サービスのパフォーマンスが要件を満たしていることをご確認ください。

カスタム Yum リポジトリを使用する

カスタム Yum リポジトリを使用する場合、次の点にご注意ください。
  • すべての RPM パッケージを更新しないでください。

    インストールする RPM パッケージのみを更新します。 すべての RPM パッケージを更新する yum update -y コマンドを実行しないでください。

  • Yum リポジトリの適切なパフォーマンスを保証します。
    一度に多数のワーカーノードをクラスターに追加し、Yum リポジトリから RPM パッケージを更新する必要がある場合、Yum リポジトリのパフォーマンスがビジネス要件を満たしていることをご確認ください。 サンプルコードは次のとおりです。
    $ cat scripts/add-yum-repo.sh
    #! /bin/bash
    cat << EOF > /etc/yum.repos.d/my.repo
    [base]
    name=CentOS-\$releasever
    enabled=1
    failovermethod=priority
    baseurl=http://mirrors.cloud.aliyuncs.com/centos/\$releasever/os/\$basearch/
    gpgcheck=1
    gpgkey=http://mirrors.cloud.aliyuncs.com/centos/RPM-GPG-KEY-CentOS-7
    EOF

DaemonSet コンポーネントのコンテナイメージをプリロード

一度に 1,000 を超えるワーカーノードをクラスターに追加する場合は、カスタムイメージを作成するときに DaemonSet コンポーネントのコンテナイメージをプリロードすることを推奨します。 これにより、ノードの起動時にこれらのコンテナイメージをプルする操作が節約され、クラスタースケールアウトの効率が向上します。

  1. 必要なコンテナイメージを TAR パッケージに圧縮し、カスタムイメージに保存します。
    Container Service for Kubernetes クラスターは、Terway ネットワークプラグインとコンテナストレージインターフェイス (CSI) ストレージプラグインを使用し、中国 (杭州) リージョンに存在すると仮定します。 上記のプラグインのコンテナイメージをプリロードするためのサンプルスクリプトは次のとおりです。
    $ cat scripts/prepare-images.sh
    #! /bin/bash
    set -x -e
    EXPORT_PATH=/preheated
    
    # Docker をインストールします。
    yum install -y docker
    systemctl start docker
    
    # イメージを取得して保存します。
    images=(
    registry-vpc.cn-hangzhou.aliyuncs.com/acs/csi-plugin:v1.14.5.60-5318afe-aliyun
    registry-vpc.cn-hangzhou.aliyuncs.com/acs/terway:v1.0.10.78-g97729ee-aliyun
    )
    
    mkdir -p ${EXPORT_PATH}
    
    for image in "${images[@]}"; do
        echo "preheating ${image}"
        docker pull ${image}
        docker save -o ${EXPORT_PATH}/$(echo ${image}| md5sum | cut -f1 -d" ").tar ${image}
    done
    
    # Docker をアンインストールします。
    yum erase -y docker
    mkdir /var/lib/docker
  2. Container Service コンソールにログインします。 クラスター作成ページに移動し、[詳細オプションを表示] をクリックして、次のスクリプトを [ユーザーデータ] フィールドに入力します。
    ls /preheated/ | xargs -n 1 -i docker load -i /preheated/{}
    rm -rf /preheated

カスタムイメージの設定ファイルを編集

カスタムイメージを作成するために、alicloud.json ファイルへ provisioners に関する次の設定を追加します。

  "provisioners": [
    {
      "type": "shell",
      "scripts": [
        "config/default.sh",
        "scripts/updateOSKernel.sh",
        "scripts/updateDNS.sh",
        "scripts/add-yum-repo.sh",
        "scripts/prepare-images.sh",
        "scripts/reboot.sh",
        "scripts/verify.sh"
      ],
      "expect_disconnect": true
    }
  ]
config/default.shscripts/reboot.shscripts/verify.sh スクリプトは、実行する必要があるデフォルトのスクリプトです。 その他はユーザー定義のスクリプトです。

config/default.sh スクリプトはタイムゾーンを設定し、スワップパーティションを無効にします。

scripts/verify.sh スクリプトは、カスタムイメージが Container Service for Kubernetes の要件を満たしているかどうかを確認します。

カスタムイメージの設定ファイルを編集した後に、カスタムイメージを作成し、それを使用して Container Service for Kubernetes クラスターを作成またはスケールアウトすることができます。