このトピックでは、Container Service for Kubernetes(ACK)クラスタへのワークロードデプロイに関するよくある質問への回答を提供します。
ACK クラスタにコンテナ化アプリケーションをデプロイするにはどうすればよいですか?
アプリケーションコードは、クラウドまたはオンプレミスのマシンにデプロイできます。すべてのプログラミング言語のコードをコンテナにデプロイし、コンテナを使用してアプリケーションを実行および配信できます。ACK クラスタでのアプリケーション開発には、次のフェーズが含まれます。
ビジネスコードを作成します。
Dockerfile を使用してイメージをビルドします。
イメージをイメージリポジトリにアップロードします。 Container Registry を使用してイメージをホストできます。 Container Registry は、イメージのバージョン管理を提供し、イメージの配布とプルを可能にします。 Container Registry には、Personal Edition と Enterprise Edition の 2 つのエディションがあります。 Personal Edition は個々の開発者向けに設計されています。 Enterprise Edition は企業ユーザー向けに設計されています。詳細については、「Container Registry とは」をご参照ください。
イメージを使用して、ACK クラスタにワークロードをデプロイします。これにより、ワークロードでコンテナ化アプリケーションを実行できます。また、ACK が提供する機能を使用して、コンテナ化アプリケーションを管理することもできます。詳細については、「ワークロード」をご参照ください。
イメージのプルに時間がかかる場合、またはイメージのプルが失敗した場合はどうすればよいですか?
この問題をトラブルシューティングするには、次の手順を実行します。
Container Registry のリポジトリからイメージをプルする場合は、使用しているユーザー名とパスワードが有効かどうかを確認します。 aliyun-acr-credential-helper コンポーネントを使用することをお勧めします。詳細については、「シークレットを使用せずに Container Registry インスタンスからイメージをプルする」をご参照ください。
クライアントがインターネットにアクセスできるかどうかを確認します。クライアントがインターネットにアクセスできない場合は、クライアントのインターネットアクセスを構成する必要があります。
ACK でアプリケーションの問題をトラブルシューティングするにはどうすればよいですか?
ほとんどの場合、ACK でのアプリケーションの問題は、ポッド、コントローラー(デプロイメント、ステートフルセット、またはデーモンセット)、およびサービスから発生します。次のタイプの問題が存在するかどうかを確認します。
ポッドの問題
ポッドの問題のトラブルシューティング方法の詳細については、「ポッドのトラブルシューティング」をご参照ください。
コントローラーの問題
デプロイメント、デーモンセット、ステートフルセット、ジョブなどのコントローラーを作成すると、ポッドの問題が発生する可能性があります。詳細については、「ポッドのトラブルシューティング」をご参照ください。
コントローラー(デプロイメントなど)のイベントとログを確認して、コントローラーのポッドの問題をトラブルシューティングできます。
次の手順は、デプロイメントのイベントとログを確認する方法を示しています。同様の手順を実行して、デーモンセット、ステートフルセット、またはジョブのイベントとログを確認できます。
ACK コンソール にログインします。左側のナビゲーションウィンドウで、[クラスタ] をクリックします。
[クラスタ] ページで、管理するクラスタを見つけて、その名前をクリックします。左側のペインで、 を選択します。
[デプロイメント] ページで、表示するデプロイメントの名前をクリックします。 [イベント] タブと [ログ] タブをクリックして、デプロイメントのイベントとログを表示します。
ステートフルセットの作成時に問題が発生した場合は、「強制ロールバック」をご参照ください。
サービスの問題
サービスは、一連のポッド全体で負荷分散を提供します。次の手順は、サービスの問題を特定する方法を示しています。
サービスのエンドポイントを確認します。
サービスが属するクラスタのマスターノードにログインします。詳細については、「クラスタの kubeconfig ファイルを取得し、kubectl を使用してクラスタに接続する」をご参照ください。
次のコマンドを実行して、サービスのエンドポイントを表示します。
[$Service_Name]を実際のサービス名に置き換えます。kubectl get endpoints [$Service_Name]エンドポイントの数がバックエンドポッドの数と同じであるかどうかを確認します。たとえば、3 つのポッドをプロビジョニングするデプロイメントによってデプロイされたアプリケーションを公開するためにサービスが使用される場合、サービスには 3 つのエンドポイントがあります。
サービスエンドポイントが見つからない
サービスのエンドポイントが見つからない場合は、サービスのセレクターをクエリしてから、セレクターを使用してバックエンドポッドがサービスに関連付けられているかどうかを確認します。次の手順を実行します。
次の図は、YAML ファイルのサンプルを示しています。

次のコマンドを実行して、セレクターに一致するポッドをクエリします。
kubectl get pods --selector=app=[$App] -n [$Namespace]説明[$App]をバックエンドポッドの名前に置き換えます。[$Namespace]をサービスの名前空間に置き換えます。サービスがデフォルトの名前空間に属している場合は、このパラメータを空のままにすることができます。
アプリケーションポッドが返された場合、サービスは間違ったポートを使用している可能性があります。サービスがバックエンドポッドに公開されていないポートでリッスンしている場合、ポッドはサービスのエンドポイントに追加されません。次のコマンドを実行して、サービスポートを使用してポッドにアクセスできるかどうかを確認します。
curl [$IP]:[$Port]説明[$IP]を、手順 1 の YAML ファイルで指定されたクラスタ IP アドレスに置き換えます。[$Port]を、手順 1 の YAML ファイルで指定されたポートに置き換えます。テスト方法は、実際の環境によって異なります。
トラフィック転送エラー
クライアントがサービスにアクセスでき、サービスのエンドポイントの IP アドレスが有効であるが、サービスに接続した直後にクライアントがサービスから切断される場合。原因は、リクエストがバックエンドポッドに転送されなかった可能性があります。次の手順を実行して、この問題をトラブルシューティングします。
バックエンドポッドが想定どおりに実行されているかどうかを確認します。
ポッドの問題を特定します。詳細については、「ポッドのトラブルシューティング」をご参照ください。
バックエンドポッドの IP アドレスにアクセスできるかどうかを確認します。
次のコマンドを実行して、バックエンドポッドの IP アドレスをクエリします。
kubectl get pods -o wideノードにログインし、ping コマンドを実行して、ポッドの IP アドレスにアクセスできるかどうかを確認します。
サービスがバックエンドアプリケーションに公開されているポートでリッスンしているかどうかを確認します。
アプリケーションにポート 80 が公開されている場合は、サービスのリスニングポートとしてポート 80 を指定する必要があります。ノードにログインし、
curl [$IP]:[$Port]コマンドを実行して、サービスポートを使用してポッドにアクセスできるかどうかを確認します。
Helm を手動で更新するにはどうすればよいですか?
kubectl を使用してクラスタに接続します。詳細については、「クラスタの kubeconfig ファイルを取得し、kubectl を使用してクラスタに接続する」をご参照ください。
次のコマンドを実行して、Tiller をインストールします。 Tiller イメージのアドレスには、クラスタがデプロイされている VPC のエンドポイントを含めることができます。たとえば、クラスタが中国(杭州)リージョンにデプロイされている場合は、次のイメージアドレスを指定できます:
registry-vpc.cn-hangzhou.aliyuncs.com/acs/tiller:v2.11.0。helm init --tiller-image registry.cn-hangzhou.aliyuncs.com/acs/tiller:v2.11.0 --upgradetiller ヘルスチェックが成功したら、
helm versionコマンドを実行して更新結果を表示できます。helm version説明上記のコマンドは、Helm のサーバー側コンポーネントである Tiller のみを更新します。クライアント側コンポーネントを更新するには、Alibaba Cloud でサポートされている最新のクライアントバージョンである Helm client 2.11.0 をダウンロードします。
予期される出力:
Client: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b****", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.11.0", GitCommit:"2e55dbe1fdb5fdb96b75ff144a339489417b****", GitTreeState:"clean"}
プライベートイメージをプルするにはどうすればよいですか?
次のコマンドを実行して、シークレットを作成します。
kubectl create secret docker-registry regsecret --docker-server=registry-internal.cn-hangzhou.aliyuncs.com --docker-username=abc****@aliyun.com --docker-password=**** --docker-email=abc****@aliyun.comregsecret:シークレットのキー。カスタムキーを入力できます。--docker-server:Docker レジストリのアドレス。--docker-username:Docker レジストリのユーザー名。--docker-password:Docker レジストリのパスワード。オプション:
--docker-email:メールアドレス。
次のいずれかの方法でプライベートイメージをプルできます。
プライベートイメージを手動でプルする
YAML ファイルにシークレット構成を追加します。
containers: - name: foo image: registry-internal.cn-hangzhou.aliyuncs.com/abc/test:1.0 imagePullSecrets: - name: regsecret説明imagePullSecretsパラメータは、イメージのプルに使用するシークレットを指定します。作成したシークレットの名前を指定する必要があります。この例では、シークレットの名前は
regsecretです。imageパラメータで指定された Docker レジストリは、--docker-serverで指定された Docker レジストリと同じである必要があります。
詳細については、「プライベートレジストリを使用する」をご参照ください。
シークレットなしでプライベートイメージを自動的にプルする
説明プライベートイメージをプルするたびにシークレットを使用する必要がないようにするには、使用する名前空間のデフォルトサービスアカウントにシークレットを追加します。詳細については、「サービスアカウントに ImagePullSecrets を追加する」をご参照ください。
次のコマンドを実行して、プライベートイメージのプルに使用するシークレットを表示します。
kubectl get secret regsecret予期される出力:
NAME TYPE DATA AGE regsecret kubernetes.io/dockerconfigjson 1 13mこの例では、イメージプルシークレット が、使用する名前空間の デフォルト サービスアカウントに追加されます。
sa.yaml という名前のファイルを作成し、デフォルトサービスアカウントの構成をファイルに追加します。
kubectl get serviceaccounts default -o yaml > ./sa.yaml次のコマンドを実行して、sa.yaml ファイルの構成をクエリします。
cat sa.yaml予期される出力:
apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2015-08-07T22:02:39Z name: default namespace: default resourceVersion: "243024" # セルフリンクに注意してください:/api/v1/namespaces/default/serviceaccounts/default。 uid: 052fb0f4-3d50-11e5-b066-42010af0**** secrets: - name: default-token-uudgeoken-uudgevim sa.yamlコマンドを実行して sa.yaml ファイルを開きます。次に、resourceVersion パラメータを削除し、imagePullSecrets パラメータを追加してイメージプルシークレットを指定します。次のコンテンツに基づいてファイルを修正します。apiVersion: v1 kind: ServiceAccount metadata: creationTimestamp: 2015-08-07T22:02:39Z name: default namespace: default selfLink: /api/v1/namespaces/default/serviceaccounts/default uid: 052fb0f4-3d50-11e5-b066-42010af0**** secrets: - name: default-token-uudge imagePullSecrets: # このパラメータを追加します。 - name: regsecret次のコマンドを実行して、デフォルトサービスアカウントの構成を sa.yaml ファイルの構成に置き換えます。
kubectl replace serviceaccount default -f ./sa.yaml予期される出力:
serviceaccount "default" replacedTomcat アプリケーションを作成します。
tomcat.yaml という名前のファイルを作成し、次のコンテンツをファイルにコピーします。
apiVersion: apps/v1 kind: Deployment metadata: name: tomcat-deployment labels: app: tomcat spec: replicas: 1 selector: matchLabels: app: tomcat template: metadata: labels: app: tomcat spec: containers: - name: tomcat image: registry-internal.cn-hangzhou.aliyuncs.com/abc/test:1.0 # 値をプライベートイメージのアドレスに置き換えます。 - containerPort: 8080次のコマンドを実行して、Tomcat アプリケーションを作成します。
kubectl create -f tomcat.yamlポッドが起動したら、次のコマンドを実行してポッド構成をクエリします。
kubectl get pod tomcat-**** -o yaml予期される出力:
spec: imagePullSecrets: - name: regsecret
中国本土内のリージョンにデプロイされている Container Registry Enterprise Edition インスタンスから、中国本土外のリージョンにデプロイされている ACK クラスタにイメージをプルするにはどうすればよいですか?
まず、中国本土のリージョンで Standard または Advanced Edition の Container Registry Enterprise Edition インスタンスを購入する必要があります。次に、中国本土外のリージョンで Basic Edition の Container Registry Enterprise Edition インスタンスを購入します。
購入が完了したら、中国本土の Container Registry インスタンスから中国本土外の Container Registry インスタンスにイメージを同期できます。詳細については、「同じアカウント内でイメージを複製する」をご参照ください。次に、中国本土外の Container Registry インスタンスからプルするイメージのアドレスを取得します。このようにして、イメージを ACK クラスタにプルし、イメージを使用してアプリケーションをデプロイできます。
Container Registry Personal Edition を使用する場合、イメージの同期プロセスに時間がかかります。セルフマネージドイメージリポジトリを使用する場合は、Global Accelerator(GA)インスタンスを購入する必要があります。
セルフマネージドリポジトリと GA インスタンスの合計コストが高いため、Container Registry Enterprise Edition を使用することをお勧めします。
Container Registry Enterprise Edition の課金については、「請求ルール」をご参照ください。
サービスを中断せずにアプリケーションのローリングアップデートを実行するにはどうすればよいですか?
古いアプリケーションバージョンが削除された後、新しいアプリケーションバージョンをデプロイすると、5XX エラーが短時間持続します。 5XX エラーが発生するのは、ローリングアップデート中にポッドの更新を Classic Load Balancer(CLB)インスタンスに同期するのに数秒かかるためです。この問題を解決するには、接続ドレインを構成します。このようにして、サービスを中断せずにアプリケーションのローリングアップデートを実行できます。
イメージを取得するにはどうすればよいですか?
パブリックイメージリポジトリを使用する場合は、既存の ACK クラスタがインターネットにアクセスできるようにする 必要があります。
カスタムイメージを管理する場合は、Container Registry を使用してイメージを管理およびプルできます。詳細については、「イメージの管理」をご参照ください。
コンテナを再起動するにはどうすればよいですか?
個々のコンテナを個別に再起動することはできません。コンテナを再起動するには、次の手順を実行します。
次のコマンドを実行して、クラスタ内のポッドのステータスをクエリします。出力からポッドを選択できます。
kubectl get pods選択したポッドを削除します。次に、対応するコントローラー(デプロイメントやデーモンセットなど)が自動的に新しいポッドを作成します。このようにして、ポッド内のコンテナが再起動されます。ポッドを削除するには、次のコマンドを実行します。
kubectl delete pod <pod-name>ポッドを削除すると、対応するコントローラーが自動的に新しいポッドを作成します。
説明本番環境でポッド内のコンテナを管理または更新する場合は、レプリカセットやデプロイメントなどのコントローラーを使用することをお勧めします。一貫性のある通常のクラスタ状態を確保するために、ポッドで手動操作を実行しないことをお勧めします。
次のコマンドを実行して、新しいポッドが Running 状態であるかどうかを確認します。
kubectl get pods
デプロイメントの名前空間を変更するにはどうすればよいですか?
デプロイメントをある名前空間から別の名前空間に移行する場合、デプロイメントが属する名前空間を変更する必要があります。この場合、デプロイメントで使用される永続ボリューム(PV)、ConfigMap、シークレット、およびその他の依存関係の名前空間も手動で変更する必要があります。
kubectl getコマンドを実行して、デプロイメントの YAML テンプレートをクエリします。kubectl get deploy <deployment-name> -n <old-namespace> -o yaml > deployment.yaml要件に基づいて
namespaceパラメータの値を変更して、deployment.yaml ファイルを変更します。変更を保存して終了します。apiVersion: apps/v1 kind: Deployment metadata: annotations: generation: 1 labels: app: nginx name: nginx-deployment namespace: new-namespace # 新しい名前空間を指定します。 ... ...kubectl applyコマンドを実行して、新しい名前空間にデプロイメントをデプロイします。kubectl apply -f deployment.yamlkubectl getコマンドを実行して、新しい名前空間のデプロイメントをクエリします。kubectl get deploy -n new-namespace
実行中のコンテナにポッド情報を公開するにはどうすればよいですか?
ACK はオープンソース Kubernetes と完全に互換性があり、オープンソース Kubernetes の仕様に準拠しています。次のいずれかの方法を使用して、実行中のコンテナにポッド情報を公開できます。