すべてのプロダクト
Search
ドキュメントセンター

:カスタムイメージを使用してエラスティックノードプールを構築する方法

最終更新日:Dec 17, 2024

クラウド上でノードがReady状態に達するまでの時間を短縮するために、カスタムイメージを使用して必要なソフトウェアパッケージを事前にインストールして、必要な時間を大幅に短縮し、システムの起動効率を向上させることをお勧めします。 このトピックでは、カスタムイメージを使用して登録済みクラスターのエラスティックノードプールを構築する方法について説明します。

前提条件

ステップ

image
説明
  • この例では、CentOS 7.9オペレーティングシステムを使用して、カスタムイメージを持つエラスティックノードプールを構築します。 Kubernetesクラスターバージョン1.28.3は、バイナリファイルを使用して接続されています。

  • 既存のカスタムイメージを使用する準備ができている場合は、手順3に進みます。

手順1: クラウドノードプールを作成してノードを追加する

  1. OSSバケットを選択し、join-ecs-node.shという名前のファイルを作成し、次のコンテンツをファイルにコピーしてアップロードします。

    echo "The node providerid is $ALIBABA_CLOUD_PROVIDER_ID"
    echo "The node name is $ALIBABA_CLOUD_NODE_NAME"
    echo "The node labels are $ALIBABA_CLOUD_LABELS"
    echo "The node taints are $ALIBABA_CLOUD_TAINTS"
  2. join-ecs-node.shファイルのURLを取得し (署名付きURLを使用できます) 、クラスター内のカスタム設定スクリプトを変更します。

    1. 次のコマンドを実行して、ack-agent-configを編集します。

      kubectl edit cm ack-agent-config -n kube-system
    2. addNodeScriptPathフィールドを変更します。 更新された設定は次のとおりです。

      apiVersion: v1
      data:
        addNodeScriptPath: https://kubelet-****.oss-cn-hangzhou-internal.aliyuncs.com/join-ecs-nodes.sh
      kind: ConfigMap
      metadata:
        name: ack-agent-config
        namespace: kube-system
  3. cloud-testという名前のクラウドノードプールを作成し、[期待されるノード] パラメーターを1に設定します。 詳細については、「ノードプールの作成とスケールアウト」をご参照ください。

    image

    重要

    新しいノードは、ノードソフトウェアパッケージのインストールなどのセットアップタスクで初期化されていないため、Failed状態になります。 さらに、SSHを使用してノードにログインし、後続の手順で初期化できることを確認します。

ステップ2: ノードを設定し、カスタムイメージをエクスポートする

  1. ノードにログインし、次のコマンドを実行してノード情報を確認します。

    cat /var/log/acs/init.log

    期待される出力:

    The node providerid is cn-zhangjiakou.i-xxxxx
    The node name is cn-zhangjiakou.192.168.66.xx
    The node labels are alibabacloud.com/nodepool-id=npf9fbxxxxxx,ack.aliyun.com=c22b1a2e122ff4fde85117de4xxxxxx,alibabacloud.com/instance-id=i-8vb7m7nt3dxxxxxxx,alibabacloud.com/external=true
    The node taints are

    期待される出力は、カスタムスクリプトがノード情報を取得できることを示します。 この情報を記録し、次の手順でkubeletの起動パラメーターに追加します。

  2. 次のコマンドを実行して、基本環境を設定します。

    # Install tool packages.
    yum update -y && yum -y install  wget psmisc vim net-tools nfs-utils telnet yum-utils device-mapper-persistent-data lvm2 git tar curl
    
    # Disable the firewall.
    systemctl disable --now firewalld
    
    # Disable SELinux.
    setenforce 0
    sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
    
    # Disable swap partition.
    sed -ri 's/.*swap.*/#&/' /etc/fstab
    swapoff -a && sysctl -w vm.swappiness=0
    
    # Network configuration.
    systemctl disable --now NetworkManager
    systemctl start network && systemctl enable network
    
    # Time synchronization.
    ln -svf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    yum install ntpdate -y
    ntpdate ntp.aliyun.com
    
    # Configure ulimit.
    ulimit -SHn 65535
    cat >> /etc/security/limits.conf <<EOF
    * soft nofile 655360
    * hard nofile 131072
    * soft nproc 655350
    * hard nproc 655350
    * seft memlock unlimited
    * hard memlock unlimitedd
    EOF
    説明

    上記の環境設定が完了したら、カーネルをバージョン4.18以降にアップグレードし、ipvsadmをインストールします。

  3. containerdをインストールします。

    1. 次のコマンドを実行して、ネットワークプラグインとcontainerdパッケージをダウンロードします。

      wget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz
      mkdir -p /etc/cni/net.d /opt/cni/bin 
      # Extract the cni binary package
      tar xf cni-plugins-linux-amd64-v*.tgz -C /opt/cni/bin/
      wget https://github.com/containerd/containerd/releases/download/v1.7.8/containerd-1.7.8-linux-amd64.tar.gz
      tar -xzf cri-containerd-cni-*-linux-amd64.tar.gz -C /
    2. 次のコマンドを実行して、サービスの起動構成ファイルを作成します。

      cat > /etc/systemd/system/containerd.service <<EOF
      [Unit]
      Description=containerd container runtime
      Documentation=https://containerd.io
      After=network.target local-fs.target
      
      [Service]
      ExecStartPre=-/sbin/modprobe overlay
      ExecStart=/usr/local/bin/containerd
      Type=notify
      Delegate=yes
      KillMode=process
      Restart=always
      RestartSec=5
      LimitNPROC=infinity
      LimitCORE=infinity
      LimitNOFILE=infinity
      TasksMax=infinity
      OOMScoreAdjust=-999
      
      [Install]
      WantedBy=multi-user.target
      EOF
    3. 次のコマンドを実行して、containerdに必要なモジュールを設定します。

      cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
      overlay
      br_netfilter
      EOF
      systemctl restart systemd-modules-load.service
    4. 次のコマンドを実行して、containerdに必要なカーネルを設定します。

      cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
      net.bridge.bridge-nf-call-iptables  = 1
      net.ipv4.ip_forward                 = 1
      net.bridge.bridge-nf-call-ip6tables = 1
      EOF
      
      # Load the kernel
      sysctl --system
    5. 次のコマンドを実行して、containerdの構成ファイルを作成します。

      mkdir -p /etc/containerd
      containerd config default | tee /etc/containerd/config.toml
      
      # Modify the containerd configuration file
      sed -i "s#SystemdCgroup\ \=\ false#SystemdCgroup\ \=\ true#g" /etc/containerd/config.toml
      cat /etc/containerd/config.toml | grep SystemdCgroup
      sed -i "s#registry.k8s.io#m.daocloud.io/registry.k8s.io#g" /etc/containerd/config.toml
      cat /etc/containerd/config.toml | grep sandbox_image
      sed -i "s#config_path\ \=\ \"\"#config_path\ \=\ \"/etc/containerd/certs.d\"#g" /etc/containerd/config.toml
      cat /etc/containerd/config.toml | grep certs.d
      
      # Configure the accelerator
      mkdir /etc/containerd/certs.d/docker.io -pv
      cat > /etc/containerd/certs.d/docker.io/hosts.toml << EOF
      server = "https://docker.io"
      [host."https://hub-mirror.c.163.com"]
        capabilities = ["pull", "resolve"]
      EOF
    6. 次のコマンドを実行して、システム起動時に実行するようにcontainerdを設定します。

      systemctl daemon-reload
      # Used to reload systemd-managed unit files. When you add or modify a unit file (such as a .service file, .socket file, etc.), you need to run this command to refresh systemd configuration of the file.
      
      systemctl enable --now containerd.service
      systemctl start containerd.service
      systemctl status containerd.service
    7. crictlコマンドを設定するには、次のコマンドを実行します。

      wget https://mirrors.chenby.cn/https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.28.0/crictl-v1.28.0-linux-amd64.tar.gz
      tar xf crictl-v*-linux-amd64.tar.gz -C /usr/bin/
      # Generate the configuration file
      cat > /etc/crictl.yaml <<EOF
      runtime-endpoint: unix:///run/containerd/containerd.sock
      image-endpoint: unix:///run/containerd/containerd.sock
      timeout: 10
      debug: false
      EOF
      
      # Test
      systemctl restart  containerd
      crictl info
  4. kubeletとkube-proxyをインストールします。

    1. バイナリファイルを取得し、Masterノードにログインしてから、バイナリファイルをノードにコピーします。

      scp /usr/local/bin/kube{let,-proxy} $NODEIP:/usr/local/bin/
    2. 証明書を取得し、次のコマンドを実行して、証明書ストレージディレクトリをローカルに作成します。

      mkdir -p /etc/kubernetes/pki

      マスターノードにログインし、証明書をノードにコピーします。

      for FILE in pki/ca.pem pki/ca-key.pem pki/front-proxy-ca.pem bootstrap-kubelet.kubeconfig kube-proxy.kubeconfig; 
        do scp /etc/kubernetes/$FILE $NODE:/etc/kubernetes/${FILE}; done
    3. 次のコマンドを実行して、kubeletサービスを設定します。 ステップ2で取得したノードプールに関連する変数を入力します。

      mkdir -p /var/lib/kubelet /var/log/kubernetes /etc/systemd/system/kubelet.service.d /etc/kubernetes/manifests/
      
      # Configure kubelet service on all k8s nodes
      cat > /usr/lib/systemd/system/kubelet.service << EOF
      
      [Unit]
      Description=Kubernetes Kubelet
      Documentation=https://github.com/kubernetes/kubernetes
      After=network-online.target firewalld.service containerd.service
      Wants=network-online.target
      Requires=containerd.service
      
      [Service]
      ExecStart=/usr/local/bin/kubelet \\
          --node-ip=${ALIBABA_CLOUD_NODE_NAME} \\
          --hostname-override=${ALIBABA_CLOUD_NODE_NAME} \\
          --node-labels=${ALIBABA_CLOUD_LABELS} \\
          --provider-id=${ALIBABA_CLOUD_PROVIDER_ID} \\
          --register-with-taints=${ALIBABA_CLOUD_TAINTS} \\
          --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig  \\
          --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
          --config=/etc/kubernetes/kubelet-conf.yml \\
          --container-runtime-endpoint=unix:///run/containerd/containerd.sock
      
      [Install]
      WantedBy=multi-user.target
      EOF
    4. 次のコマンドを実行して、kubeletの起動設定ファイルを作成します。

      cat > /etc/kubernetes/kubelet-conf.yml <<EOF
      apiVersion: kubelet.config.k8s.io/v1beta1
      kind: KubeletConfiguration
      address: 0.0.0.0
      port: 10250
      readOnlyPort: 10255
      authentication:
        anonymous:
          enabled: false
        webhook:
          cacheTTL: 2m0s
          enabled: true
        x509:
          clientCAFile: /etc/kubernetes/pki/ca.pem
      authorization:
        mode: Webhook
        webhook:
          cacheAuthorizedTTL: 5m0s
          cacheUnauthorizedTTL: 30s
      cgroupDriver: systemd
      cgroupsPerQOS: true
      clusterDNS:
      - 10.96.0.10
      clusterDomain: cluster.local
      containerLogMaxFiles: 5
      containerLogMaxSize: 10Mi
      contentType: application/vnd.kubernetes.protobuf
      cpuCFSQuota: true
      cpuManagerPolicy: none
      cpuManagerReconcilePeriod: 10s
      enableControllerAttachDetach: true
      enableDebuggingHandlers: true
      enforceNodeAllocatable:
      - pods
      eventBurst: 10
      eventRecordQPS: 5
      evictionHard:
        imagefs.available: 15%
        memory.available: 100Mi
        nodefs.available: 10%
        nodefs.inodesFree: 5%
      evictionPressureTransitionPeriod: 5m0s
      failSwapOn: true
      fileCheckFrequency: 20s
      hairpinMode: promiscuous-bridge
      healthzBindAddress: 127.0.0.1
      healthzPort: 10248
      httpCheckFrequency: 20s
      imageGCHighThresholdPercent: 85
      imageGCLowThresholdPercent: 80
      imageMinimumGCAge: 2m0s
      iptablesDropBit: 15
      iptablesMasqueradeBit: 14
      kubeAPIBurst: 10
      kubeAPIQPS: 5
      makeIPTablesUtilChains: true
      maxOpenFiles: 1000000
      maxPods: 110
      nodeStatusUpdateFrequency: 10s
      oomScoreAdj: -999
      podPidsLimit: -1
      registryBurst: 10
      registryPullQPS: 5
      resolvConf: /etc/resolv.conf
      rotateCertificates: true
      runtimeRequestTimeout: 2m0s
      serializeImagePulls: true
      staticPodPath: /etc/kubernetes/manifests
      streamingConnectionIdleTimeout: 4h0m0s
      syncFrequency: 1m0s
      volumeStatsAggPeriod: 1m0s
      EOF
    5. 次のコマンドを実行してkubeletを起動します。

      systemctl daemon-reload
      # Used to reload systemd-managed unit files. When you add or modify a unit file (such as a .service file, .socket file, etc.), you need to run this command to refresh systemd's configuration of the file.
      
      systemctl enable --now kubelet.service
      systemctl start kubelet.service
      systemctl status kubelet.service
    6. 次のコマンドを実行して、クラスター情報を確認します。

      kubectl  get node
    7. マスターノードにログインし、kube-proxyに必要なKubeConfigを取得します。

      scp /etc/kubernetes/kube-proxy.kubeconfig $NODE:/etc/kubernetes/kube-proxy.kubeconfig
    8. 次のコマンドを実行して、kube-proxy Serviceの設定を追加します。

      cat >  /usr/lib/systemd/system/kube-proxy.service << EOF
      [Unit]
      Description=Kubernetes Kube Proxy
      Documentation=https://github.com/kubernetes/kubernetes
      After=network.target
      
      [Service]
      ExecStart=/usr/local/bin/kube-proxy \\
        --config=/etc/kubernetes/kube-proxy.yaml \\
        --v=2
      Restart=always
      RestartSec=10s
      
      [Install]
      WantedBy=multi-user.target
      
      EOF
    9. 次のコマンドを実行して、kube-proxyの起動設定を追加します。

      cat > /etc/kubernetes/kube-proxy.yaml << EOF
      apiVersion: kubeproxy.config.k8s.io/v1alpha1
      bindAddress: 0.0.0.0
      clientConnection:
        acceptContentTypes: ""
        burst: 10
        contentType: application/vnd.kubernetes.protobuf
        kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
        qps: 5
      clusterCIDR: 172.16.0.0/12,fc00:2222::/112
      configSyncPeriod: 15m0s
      conntrack:
        max: null
        maxPerCore: 32768
        min: 131072
        tcpCloseWaitTimeout: 1h0m0s
        tcpEstablishedTimeout: 24h0m0s
      enableProfiling: false
      healthzBindAddress: 0.0.0.0:10256
      hostnameOverride: ""
      iptables:
        masqueradeAll: false
        masqueradeBit: 14
        minSyncPeriod: 0s
        syncPeriod: 30s
      ipvs:
        masqueradeAll: true
        minSyncPeriod: 5s
        scheduler: "rr"
        syncPeriod: 30s
      kind: KubeProxyConfiguration
      metricsBindAddress: 127.0.0.1:10249
      mode: "ipvs"
      nodePortAddresses: null
      oomScoreAdj: -999
      portRange: ""
      udpIdleTimeout: 250ms
      EOF
    10. 次のコマンドを実行してkube-proxyを起動します。

      systemctl daemon-reload
      # Used to reload systemd-managed unit files. When you add or modify a unit file (such as a .service file, .socket file, etc.), you need to run this command to refresh systemd configuration of the file.
      
      systemctl enable --now kube-proxy.service
      systemctl restart kube-proxy.service
      systemctl status kube-proxy.service
  5. ノードプールのステータスを同期します。

    1. ACKコンソールにログインします。 左側のナビゲーションウィンドウで、[クラスター] をクリックします。

    2. [クラスター] ページで、管理するクラスターの名前をクリックします。 左側のウィンドウで、[ノード] > [ノードプール] を選択します。

    3. [ノードプール] ページの右側で、[ノードプールの同期] をクリックします。 同期が完了するまで待ち、ノードが障害状態になっていないことがわかります。

      image

  6. カスタムイメージをエクスポートします。

    1. にログインします。ECSコンソール.

    2. 左側のナビゲーションウィンドウで、インスタンス&画像 > インスタンス.

    3. [インスタンスID] をクリックし、[インスタンスの詳細] タブに移動し、[カスタムイメージの作成] をクリックします。

      image

    4. 左側のナビゲーションウィンドウで、インスタンス&画像 > イメージ.

    5. [イメージ] ページに、[ステータス] 列が [使用可能] で作成された [カスタムイメージ] が表示されます。

ステップ3: カスタムイメージを使用してクラウドノードプールを変更または作成する

説明

既存のカスタムイメージを使用し、ステップ1とステップ2をスキップした場合、最初にカスタムイメージを使用してノードプールを作成する必要があります。 詳細については、「」をご参照ください。ノードプールの作成

  1. [クラスター] ページで、管理するクラスターの名前をクリックします。 左側のウィンドウで、[ノード] > [ノードプール] を選択します。

  2. [ノードプール] ページで、[ノードプール] を見つけ、右側の [操作] 列の [編集] をクリックし、[詳細オプション] を展開し、[カスタムイメージ] の横にあるカスタムイメージを選択してノードプールイメージを変更します。

    image

  3. [ノードプール] ページの [オペレーティングシステム] 列が [カスタムイメージ] に更新されていることがわかります。image

ステップ4: ノードがAlibaba Cloudに関連するパラメータを受信するための初期化スクリプトを変更する

説明
  • スクリプトの7行目に示すように、カスタムイメージ内の残りのkubelet証明書をクリーンアップする必要があります。

  • 既存のカスタムノードプールがある場合は、手順1を参照して、カスタムスクリプトのダウンロードURLを設定します。

  1. 次のコンテンツを使用して、ファイルjoin-ecs-node.shを作成または更新します。 カスタムイメージにはノードに必要なツールパッケージと依存関係が含まれているため、カスタムスクリプトはノードプールのパラメーターのみを受け取り、更新します。

    echo "The node providerid is $ALIBABA_CLOUD_PROVIDER_ID"
    echo "The node name is $ALIBABA_CLOUD_NODE_NAME"
    echo "The node labels are $ALIBABA_CLOUD_LABELS"
    echo "The node taints are $ALIBABA_CLOUD_TAINTS"
    systemctl stop kubelet.service
    echo "Delete old kubelet pki" # Need to delete old node certificates
    rm -rf /var/lib/kubelet/pki/*
    echo "Add kubelet service config"
    # Configure kubelet service
    cat > /usr/lib/systemd/system/kubelet.service << EOF
    
    [Unit]
    Description=Kubernetes Kubelet
    Documentation=https://github.com/kubernetes/kubernetes
    After=network-online.target firewalld.service containerd.service
    Wants=network-online.target
    Requires=containerd.service
    
    [Service]
    ExecStart=/usr/local/bin/kubelet \\
        --node-ip=${ALIBABA_CLOUD_NODE_NAME} \\
        --hostname-override=${ALIBABA_CLOUD_NODE_NAME} \\
        --node-labels=${ALIBABA_CLOUD_LABELS} \\
        --provider-id=${ALIBABA_CLOUD_PROVIDER_ID} \\
        --register-with-taints=${ALIBABA_CLOUD_TAINTS} \\
        --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.kubeconfig  \\
        --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \\
        --config=/etc/kubernetes/kubelet-conf.yml \\
        --container-runtime-endpoint=unix:///run/containerd/containerd.sock
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    systemctl daemon-reload
    # Start Kubelet Service
    systemctl start kubelet.service
  2. OSS上のスクリプトjoin-ecs-node.shを更新します。

ステップ5: ノードプールのスケールアウト

  1. [クラスター] ページで、管理するクラスターの名前をクリックします。 左側のウィンドウで、[ノード] > [ノードプール] を選択します。

  2. [ノードプール] ページに移動し、ノードプールを見つけ、右側の [操作] 列の [詳細] > [スケール] をクリックして、新しいノードを追加します。

    image

    ステータスは、両方のノードが正常であることを示します。これは、エラスティックノードプールが構築されていることを示します。

  3. ノードプールの自動スケーリングポリシーを設定できます。 詳細については、「自動スケーリングの設定」をご参照ください。