本トピックでは、ACK クラスター内でのワークロードデプロイに伴う一般的な課題とその解決方法について説明します。
ACK クラスターでコンテナ化されたアプリケーションをデプロイするにはどうすればよいですか?
アプリケーションコードは、オンプレミス環境またはクラウド環境のいずれかでデプロイできます。あらゆるプログラミング言語で記述されたコードをコンテナ化し、デプロイ、配信、運用が可能です。コンテナ化されたアプリケーションの実行には、以下の 4 つの主要フェーズがあります。
-
ビジネスコードを作成します。
-
Dockerfile を使用してコンテナイメージをビルドします。
-
イメージをイメージリポジトリにアップロードします。Container Registry (ACR) を使用して、イメージの保存、管理、配布、プルが可能です。
ACR は、個人開発者向けの Personal Edition と、企業顧客向けの Enterprise Edition を提供しています。詳細については、「Container Registry (ACR) とは」をご参照ください。
-
ACK クラスター内でワークロードをデプロイしてコンテナ化アプリケーションを実行し、ACK が提供する多様なアプリケーション管理機能を利用します。詳細については、「ワークロード」をご参照ください。
イメージのプルに時間がかかりすぎる、または失敗する理由は何ですか?
症状
コンテナーがイメージをプルするのに過度な時間がかかる、またはプルに失敗します。
原因
これらの問題は、以下のいずれかの理由によって引き起こされる可能性があります:
-
パブリックネットワーク経由でイメージをプルする場合、クラスターがパブリックネットワークへのアクセスを持っていない、またはパブリック IP の帯域幅が低すぎる設定になっている可能性があります。
-
ACR からイメージをプルする場合、イメージシークレットが不正である、またはパスワードレスコンポーネントの設定が誤っている可能性があります。
解決方法
-
パブリックネットワーク経由でイメージをプルするには、クラスターとイメージリポジトリの両方がパブリックネットワークへのアクセスを持っている必要があります。「クラスターのパブリックネットワークアクセスを有効化する」をご参照ください。ACR の例については、「ACR のパブリックネットワークアクセス制御を設定する」をご参照ください。
-
パスワードレスコンポーネントの設定方法については、「同一アカウントからのイメージプル」および「アカウント間でのイメージプル」をご参照ください。
-
イメージプルシークレットの使用方法については、「imagePullSecrets の使用方法」をご参照ください。
ACK におけるアプリケーションのトラブルシューティング方法
ACK におけるアプリケーション障害は、主に Pod、コントローラー(Deployment、StatefulSet、DaemonSet など)、およびサービスの問題によって引き起こされます。以下の種類の問題を確認してください。
Pod の確認
Pod の異常をトラブルシューティングする方法については、「Pod の異常のトラブルシューティング」をご参照ください。
Deployment の確認
-
Deployment、DaemonSet、StatefulSet、Job などのコントローラーを作成する際に、Pod の問題が発生することがあります。「Pod の異常のトラブルシューティング」をご参照ください。
-
Deployment 関連のイベントおよびログを確認することで、問題の原因を特定できます:
本トピックでは Deployment を例として説明します。DaemonSet、StatefulSet、または Job におけるイベントおよびログの表示手順も同様です。
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
-
クラスターリスト ページで、管理対象のクラスターを探し、その名前をクリックします。左側のナビゲーションウィンドウで、 を選択します。
-
[デプロイメント] ページで、対象の Deployment の名前をクリックします。その後、[イベント] または [ログ] をクリックして、例外情報に基づいて問題を特定します。
サービスの確認
サービスは、一連の Pod に対してロードバランシングを提供します。以下に、サービスに関連する一般的な問題を特定する方法を示します:
-
サービスのエンドポイントを確認します。
-
以下のコマンドを実行して、サービスのエンドポイントを表示します。
以下のコマンドでは、
<service_name>を対象サービスの名前に置き換えます。kubectl get endpoints <service_name>ENDPOINTS 値内のアドレス数が、サービスに期待される Pod 数と一致することを確認します。たとえば、Deployment が 3 つのレプリカを持つ場合、ENDPOINTS 値には 3 つのアドレスが含まれている必要があります。
サービスのエンドポイントが存在しない場合
サービスにエンドポイントアドレスがない場合は、サービスのセレクターを照会して、サービスが Pod と関連付けられているかどうかを確認できます。以下の手順を実行します:
-
サービスの YAML ファイルに以下の情報が含まれていると仮定します:

-
以下のコマンドで
<app>および<namespace>を置き換え、コマンド出力にサービスと関連付けられた Pod が含まれていることを確認します。kubectl get pods -l app=<app> -n <namespace>説明-
<app>は、Pod のappラベルの値です。 -
<namespace>は、サービスが存在する名前空間です。サービスがデフォルト名前空間に属する場合は、指定する必要はありません。
-
-
コマンド出力に関連付けられた Pod が含まれているにもかかわらず、Pod にエンドポイントアドレスがない場合、サービスのポート設定が誤っている可能性があります。Pod がサービスで指定されたポートをリッスンしていない場合、Pod は ENDPOINTS リストに追加されません。したがって、サービスで指定されたコンテナーのポートが Pod 内でアクセス可能であることを確認する必要があります。以下の手順を実行します:
curl <ip>:<port>説明-
<ip>は、ステップ 1 の YAML ファイルで指定された clusterIP です。 -
<port>は、ステップ 1 の YAML ファイルで指定されたポート値です。 -
具体的なテスト方法は、ご利用の環境によって異なります。
-
ネットワーク転送の問題
クライアントがサービスに接続でき、エンドポイントアドレスが正しいにもかかわらず、接続が直ちに切断される場合、トラフィックが Pod に転送されていない可能性があります。この場合、以下のチェックを実行します:
-
Pod は正常に動作していますか?
Pod の問題を特定できます。「Pod の異常のトラブルシューティング」をご参照ください。
-
Pod のアドレスにアクセスできますか?
-
以下のコマンドを実行して、Pod の IP アドレスを取得します。
kubectl get pods -o wide -
任意のノードにログインし、ping コマンドを実行して Pod の IP アドレスをテストし、ネットワーク接続を確認します。
-
-
アプリケーションはポートを正しくリッスンしていますか?
アプリケーションがポート 80 をリッスンしている場合、サービスでコンテナーのポートを 80 として指定する必要があります。任意のノードで
curl <ip>:<Port>コマンドを実行し、Pod 内のコンテナーのポートが期待通りに動作していることを確認します。
Helm を手動で更新する方法
Helm v2 の Tiller サーバーサイドコンポーネントには、攻撃者が Tiller を使用してクラスター内に不正なアプリケーションをインストールできる既知のセキュリティ問題があります。Helm v3 へのアップグレードを推奨します。「Helm v2 から Helm v3 へのアップグレード」をご参照ください。
中国本土にデプロイされた Container Registry Enterprise Edition インスタンスから、中国本土以外にデプロイされた ACK クラスターへイメージをプルする方法
このシナリオでは、中国本土のリージョンに Container Registry Enterprise Edition の標準またはプレミアムインスタンスを購入し、中国本土以外のリージョンに Container Registry Enterprise Edition のベーシックインスタンスを購入する必要があります。
購入が完了したら、同期インスタンスを使用して、中国本土のリージョンから中国本土以外のリージョンへイメージを同期できます。「同一アカウントの同期インスタンス」をご参照ください。その後、中国本土以外のリージョンにある Container Registry Enterprise Edition インスタンスからレジストリアドレスを取得し、そのアドレスを使用して ACK クラスター内にアプリケーションを作成します。
ACR Personal Edition では同期速度が遅くなります。自己管理型リポジトリの場合、イメージプルの高速化のために GA の購入が必要です。自己管理型リポジトリおよび GA の両方ともコストが高くなります。そのため、Container Registry Enterprise Edition の使用を推奨します。課金に関する詳細については、「課金情報」をご参照ください。
サービス中断なしでアプリケーションのローリングアップデートを実行する方法
古いアプリケーションを削除して新しいアプリケーションを作成する際、一時的な 5XX アクセスエラーが発生することがあります。これは、Pod の変更が CLB インスタンスに同期されるまで数秒の遅延が発生するためです。グレースフルシャットダウンを設定することで、この問題を解決し、Kubernetes におけるゼロダウンタイムのローリングアップデートを実現できます。「K8s におけるゼロダウンタイムローリングアップデートの実装方法」をご参照ください。
コンテナーイメージの取得方法
ワークロード用のコンテナーイメージをプルする際の事前準備および注意事項については、「イメージのプル」をご参照ください。
コンテナーを再起動する方法
個別のコンテナーを直接再起動することはできません。ただし、以下の方法で同様の効果を得ることができます:
-
以下のコマンドを実行してコンテナーのステータスを表示し、再起動したいコンテナーを特定します。
kubectl get pods -
Pod を削除します:Pod を削除すると、Deployment や DaemonSet などのコントローラーが新しい Pod を作成するようトリガーされます。これにより、実質的にコンテナーが再起動されます。単一の Pod を削除するには、以下のコマンドを実行します:
kubectl delete pod <pod-name> -
Pod を削除すると、Kubernetes は対応するコントローラーに基づいて自動的に新しい Pod を作成して置き換えます。
説明本番環境では、Pod を手動で操作しないことを推奨します。代わりに、ReplicaSet や Deployment などのオブジェクトを使用してコンテナーを管理・更新し、クラスターの状態の一貫性を確保してください。
-
以下のコマンドを実行してコンテナーのステータスを確認し、再起動後にコンテナーが Running 状態であることを確認します。
kubectl get pods
Deployment の名前空間を変更する方法
サービスをある名前空間から別の名前空間に移動する場合、割り当てられた名前空間を変更する必要があります。名前空間を変更する際には、永続ボリューム要求 (PVC)、ConfigMap、シークレットなどの依存リソースの名前空間も手動で変更し、サービスが期待どおりに機能することを保証する必要があります。
-
kubectl getコマンドを実行して、YAML 形式でリソース構成をエクスポートします。kubectl get deploy <deployment-name> -n <old-namespace> -o yaml > deployment.yaml -
deployment.yaml ファイルを編集し、
namespaceパラメーターの値を新しい名前空間に置き換えます。変更を保存してファイルを終了します。apiVersion: apps/v1 kind: Deployment metadata: annotations: generation: 1 labels: app: nginx name: nginx-deployment namespace: new-namespace # 新しい名前空間を指定します。 ... ... -
kubectl applyコマンドを実行して、サービスを新しい名前空間に更新します。kubectl apply -f deployment.yaml -
kubectl getコマンドを実行して、新しい名前空間内のサービスを一覧表示します。kubectl get deploy -n new-namespace
実行中のコンテナーに Pod 情報を公開する方法
ACK はネイティブ Kubernetes と整合しており、コミュニティ仕様に準拠しています。Pod 情報をコンテナーに公開する方法は、以下の 2 つがあります:
imagePullSecrets の使用方法
2024 年 9 月 9 日以降に作成された ACR Personal Edition インスタンスでは、aliyun-acr-credential-helper がサポートされていません。新しく作成された ACR Personal Edition インスタンスを使用する場合、ユーザー名およびログインパスワードをシークレットに格納し、imagePullSecrets フィールドでそのシークレットを参照することを推奨します。
-
パスワードレスコンポーネントでは、
imagePullSecretsフィールドを手動で指定することはサポートされていません。 -
シークレットは、ワークロードと同じ名前空間に存在する必要があります。
-
以下のコマンドを実行し、プロンプトに従ってユーザー名およびパスワードを含むシークレットを作成します。
kubectl create secret docker-registry image-secret \ --docker-server=<ACR-registry> \ --docker-username=<username> \ --docker-password=<password> \ --docker-email=<email@example.com>-
docker-server:ACR インスタンスのエンドポイントを入力します。これは、レジストリアドレスのネットワークタイプ(内部またはパブリックネットワークアドレス)と一致する必要があります。 -
docker-username:ACR アクセス認証情報のユーザー名です。 -
docker-password:ACR アクセス認証情報のパスワードです。 -
docker-email:任意項目です。
-
-
シークレットを作成した後、ServiceAccount またはワークロードの
imagePullSecretsフィールドを設定して、ユーザー名およびパスワードを使用できます。ServiceAccount を使用する場合
ServiceAccount に
imagePullSecretsフィールドを追加します。たとえば、defaultという名前のデフォルト ServiceAccount をdefault名前空間で使用できます:apiVersion: v1 kind: ServiceAccount metadata: name: default namespace: default imagePullSecrets: - name: image-secret # ACR シークレットを入力しますワークロードがこの ServiceAccount を使用する場合、ワークロードはイメージをプルできます。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-test namespace: default labels: app: nginx spec: serviceAccountName: default # 名前空間のデフォルト Service Account を使用する場合、指定する必要はありません。 replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: <acrID>.cr.aliyuncs.com/<repo>/nginx:latest # ACR インスタンスのリンクに置き換えますワークロード内で直接使用する場合
ワークロードで
imagePullSecretsフィールドを指定してキーを使用します。apiVersion: apps/v1 kind: Deployment metadata: name: nginx-test namespace: default labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: imagePullSecrets: - name: image-secret # 前のステップで作成したシークレットを使用します containers: - name: nginx image: <acrID>.cr.aliyuncs.com/<repo>/nginx:latest # ACR リポジトリのレジストリアドレスに置き換えます
パスワードレスコンポーネントを設定済みでも、プルが失敗する理由
考えられる理由として、パスワードレスコンポーネントの設定が誤っていることが挙げられます。たとえば:
-
パスワードレスコンポーネント内のインスタンス情報が、ACR インスタンスと一致していない。
-
イメージをプルするために使用されるイメージアドレスが、パスワードレスコンポーネントのインスタンス情報内のドメイン名と一致していない。
問題のトラブルシューティングについては、「同一アカウント内でのイメージプル」の手順に従ってください。
コンポーネントの設定が正しくてもイメージプルが失敗する場合、ワークロードの YAML ファイルで手動で指定した imagePullSecrets フィールドがパスワードレスコンポーネントと競合している可能性があります。この問題を解決するには、imagePullSecrets フィールドを手動で削除し、その後 Pod を削除して再作成します。
ノードプールのコンテナーイメージ高速化を有効化した後に、新しいノード上でコンテナーが起動できない理由
ノードプールで コンテナのイメージアクセラレーション を有効化した後、コンテナーが起動せず、以下のエラーメッセージが返されます:
failed to create containerd container: failed to attach and mount for snapshot 46: failed to enable target for /sys/kernel/config/target/core/user_99999/dev_46, failed:failed to open remote file as tar file xxxx
この問題は、コンテナのイメージアクセラレーション を有効化した後、[aliyun-acr-acceleration-suite] コンポーネントをインストールし、非公開イメージをプルするためのプル資格情報を設定する必要があるために発生します。詳細については、「コンテナーイメージのプル資格情報を設定する」をご参照ください。
コンポーネントをインストールしても問題が解消されない場合、まず [コンテナーイメージ高速化] を無効化してサービスを復旧させ、その後再度設定を試行することを推奨します。