

 **このページの改善にご協力ください** 

このユーザーガイドに貢献するには、すべてのページの右側のペインにある「**GitHub でこのページを編集する**」リンクを選択してください。

# Linux サンプルアプリケーションをデプロイする
<a name="sample-deployment"></a>

このトピックでは、サンプルアプリケーションを Linux ノードのクラスターにデプロイします。

## 前提条件
<a name="_prerequisites"></a>
+ 少なくとも 1 つのノードがある既存の Kubernetes クラスター。既存の Amazon EKS クラスターがない場合は、[Amazon EKS の使用を開始する](getting-started.md) のガイドの 1 つを使用して Amazon EKS クラスターをデプロイできます。
+  コンピュータに `Kubectl` がインストールされている。詳細については、「[`kubectl` および `eksctl` のセットアップ](install-kubectl.md)」を参照してください。
+  クラスターと通信できるように `Kubectl` が設定されている。詳細については、「[kubeconfig ファイルを作成して kubectl を EKS クラスターに接続する](create-kubeconfig.md)」を参照してください。
+ サンプルワークロードを Fargate にデプロイする予定の場合は、名前を変更しない限り、このチュートリアルで作成したのと同じ名前空間 `eks-sample-app` を含む既存の [Fargate プロファイル](fargate-profile.md)が必要です。[Amazon EKS の使用を開始する](getting-started.md) のいずれかを使用してクラスターを作成した場合は、新しいプロファイルを作成するか、既存のプロファイルに名前空間を追加する必要があります。これは、入門ガイドで作成されたプロファイルでは、このチュートリアルで使用される名前空間が指定されていないためです。VPC には、少なくとも 1 つのプライベートサブネットも必要です。

多くの変数は次のステップで変更できますが、変数値は、指定された場合のみ変更することをお勧めします。Kubernetes Pod、デプロイ、およびサービスへの理解を深めたら、他の値の変更を試すことができます。

## 名前空間を作成します。
<a name="_create_a_namespace"></a>

名前空間を使用すると、Kubernetes 内のリソースをグループ化できます。詳細については、Kubernetes ドキュメントの[名前空間](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)を参照してください。[AWS Fargate でコンピューティング管理を簡素化](fargate.md)するためにサンプルアプリケーションをデプロイする場合は、[起動時にどのポッドが AWS Fargate を使用するかを定義する](fargate-profile.md)の `namespace` の値が `eks-sample-app` であることを確認します。

```
kubectl create namespace eks-sample-app
```

## Kubernetes デプロイメントを作成する
<a name="_create_a_kubernetes_deployment"></a>

Kubernetes デプロイメントを作成します。このサンプルデプロイでは、パブリックリポジトリからコンテナイメージをプルし、コンテナイメージの 3 つのレプリカ (個別の Pod) をクラスターにデプロイします。詳細については、Kubernetes ドキュメントの[デプロイ](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)を参照してください。

1. 次の内容を `eks-sample-deployment.yaml` という名前のファイルに保存します。サンプルアプリケーションのコンテナではネットワークストレージを使用しませんが、それを使用する必要があるアプリケーションが存在する場合があります。詳細については、「[クラスターのアプリケーションデータストレージを使用する](storage.md)」を参照してください。
   + `kubernetes.io/arch` キーの下の `amd64` または `arm64` `values` は、アプリケーションをいずれかのハードウェアアーキテクチャにデプロイできることを意味します (クラスター内に両方がある場合)。これは、このイメージがマルチアーキテクチャイメージであるため可能ですが、すべてがそうであるわけではありません。イメージを取得するリポジトリ内の[イメージの詳細](https://gallery.ecr.aws/nginx/nginx)を表示することで、イメージがサポートされているハードウェアアーキテクチャを判別できます。ハードウェアアーキテクチャのタイプをサポートしないイメージをデプロイする場合、またはイメージをデプロイしない場合は、そのタイプをマニフェストから削除します。詳細については、Kubernetes ドキュメントの[よく知られているラベル、注釈、テイント](https://kubernetes.io/docs/reference/labels-annotations-taints/)を参照してください。
   + `kubernetes.io/os: linux` `nodeSelector` は、クラスターに、たとえば、Linux ノードと Windows ノードがある場合、イメージは Linux ノードにのみデプロイされることを意味します。詳細については、Kubernetes ドキュメントの[よく知られているラベル、注釈、テイント](https://kubernetes.io/docs/reference/labels-annotations-taints/)を参照してください。

     ```
     apiVersion: apps/v1
     kind: Deployment
     metadata:
       name: eks-sample-linux-deployment
       namespace: eks-sample-app
       labels:
         app: eks-sample-linux-app
     spec:
       replicas: 3
       selector:
         matchLabels:
           app: eks-sample-linux-app
       template:
         metadata:
           labels:
             app: eks-sample-linux-app
         spec:
           affinity:
             nodeAffinity:
               requiredDuringSchedulingIgnoredDuringExecution:
                 nodeSelectorTerms:
                 - matchExpressions:
                   - key: kubernetes.io/arch
                     operator: In
                     values:
                     - amd64
                     - arm64
           containers:
           - name: nginx
             image: public.ecr.aws/nginx/nginx:1.23
             ports:
             - name: http
               containerPort: 80
             imagePullPolicy: IfNotPresent
           nodeSelector:
             kubernetes.io/os: linux
     ```

1. デプロイマニフェストをクラスターに適用します。

   ```
   kubectl apply -f eks-sample-deployment.yaml
   ```

## サービスを作成する
<a name="_create_a_service"></a>

サービスを利用すると、単一の IP アドレスまたは名前を使用して、すべてのレプリカにアクセスできます。詳細については、Kubernetes ドキュメントの[サービス](https://kubernetes.io/docs/concepts/services-networking/service/)を参照してください。サンプルアプリケーションには実装されていませんが、他の AWS サービスとやり取りする必要があるアプリケーションがある場合、Pod の Kubernetes サービスアカウントを作成し、AWS IAM アカウントに関連付けることをお勧めします。サービスアカウントを指定すると、ポッドには、他のサービスとやり取りするために指定した最小限のアクセス許可だけが与えられます。詳細については、「[サービスアカウントの IAM ロール](iam-roles-for-service-accounts.md)」を参照してください。

1. 次の内容を `eks-sample-service.yaml` という名前のファイルに保存します。Kubernetes は、クラスター内からのみアクセスできる独自の IP アドレスをサービスに割り当てます。クラスターの外部からサービスにアクセスするには、[AWS Load Balancer Controller](aws-load-balancer-controller.md) をデプロイして、[アプリケーション](alb-ingress.md)または[ネットワーク](network-load-balancing.md)トラフィックをサービスに負荷分散します。

   ```
   apiVersion: v1
   kind: Service
   metadata:
     name: eks-sample-linux-service
     namespace: eks-sample-app
     labels:
       app: eks-sample-linux-app
   spec:
     selector:
       app: eks-sample-linux-app
     ports:
       - protocol: TCP
         port: 80
         targetPort: 80
   ```

1. サービスマニフェストをクラスターに適用します。

   ```
   kubectl apply -f eks-sample-service.yaml
   ```

## 作成されたリソースを確認する
<a name="sample-app-view-namespace"></a>

1. `eks-sample-app` 名前空間内に存在するすべてのリソースを表示します。

   ```
   kubectl get all -n eks-sample-app
   ```

   出力例は次のとおりです。

   ```
   NAME                                               READY   STATUS    RESTARTS   AGE
   pod/eks-sample-linux-deployment-65b7669776-m6qxz   1/1     Running   0          27m
   pod/eks-sample-linux-deployment-65b7669776-mmxvd   1/1     Running   0          27m
   pod/eks-sample-linux-deployment-65b7669776-qzn22   1/1     Running   0          27m
   
   NAME                               TYPE         CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
   service/eks-sample-linux-service   ClusterIP    10.100.74.8     <none>        80/TCP    32m
   
   NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
   deployment.apps/eks-sample-linux-deployment 3/3     3            3           27m
   
   NAME                                                      DESIRED   CURRENT   READY   AGE
   replicaset.apps/eks-sample-linux-deployment-776d8f8fd8    3         3         3       27m
   ```

   出力では、前の手順でデプロイしたサンプルマニフェストで指定されたサービスとデプロイが表示されます。また、3 つのポッドも表示されます。これは、サンプルマニフェストで `3` `replicas` が指定されたためです。ポッドの詳細については、Kubernetes ドキュメントの [Pods (ポッド)](https://kubernetes.io/docs/concepts/workloads/pods/pod/) を参照してください。Kubernetes では、サンプルマニフェストで指定されていなくても自動的に `replicaset` リソースが作成されます。`ReplicaSets` の詳細については、「Kubernetes ドキュメント」の「[ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/)」を参照してください。
**注記**  
Kubernetes では、マニフェストで指定したレプリカの数を維持できます。本稼働デプロイで、Kubernetes を使用してレプリカ数を水平にスケーリングしたり、Pod のコンピューティングリソースを垂直にスケーリングしたりする場合は、「[Horizontal Pod Autoscaler を使用してポッドデプロイをスケールする](horizontal-pod-autoscaler.md)」と「[Vertical Pod Autoscaler を使用してポッドリソースを調整する](vertical-pod-autoscaler.md)」を使用します。

1. デプロイされたサービスの詳細を表示します。

   ```
   kubectl -n eks-sample-app describe service eks-sample-linux-service
   ```

   出力例は次のとおりです。

   ```
   Name:              eks-sample-linux-service
   Namespace:         eks-sample-app
   Labels:            app=eks-sample-linux-app
   Annotations:       <none>
   Selector:          app=eks-sample-linux-app
   Type:              ClusterIP
   IP Families:       <none>
   IP:                10.100.74.8
   IPs:               10.100.74.8
   Port:              <unset>  80/TCP
   TargetPort:        80/TCP
   Endpoints:         192.168.24.212:80,192.168.50.185:80,192.168.63.93:80
   Session Affinity:  None
   Events:            <none>
   ```

   前の出力では、`IP:` の値は、クラスター内のどのノードまたは Pod からもアクセスできる一意の IP アドレスですが、クラスターの外からはアクセスできません。`Endpoints` の値は、VPC 内からサービスの一部である Pod に割り当てられる IP アドレスです。

1. 前の手順で[名前空間を表示](#sample-app-view-namespace)したときに、出力にリストされたポッドのうちの 1 つの詳細を表示します。*776d8f8fd8-78w66* を、Pod の 1 つに対して返された値に置き換えます。

   ```
   kubectl -n eks-sample-app describe pod eks-sample-linux-deployment-65b7669776-m6qxz
   ```

   簡略化された出力例

   ```
   Name:         eks-sample-linux-deployment-65b7669776-m6qxz
   Namespace:    eks-sample-app
   Priority:     0
   Node:         ip-192-168-45-132.us-west-2.compute.internal/192.168.45.132
   [...]
   IP:           192.168.63.93
   IPs:
     IP:           192.168.63.93
   Controlled By:  ReplicaSet/eks-sample-linux-deployment-65b7669776
   [...]
   Conditions:
     Type              Status
     Initialized       True
     Ready             True
     ContainersReady   True
     PodScheduled      True
   [...]
   Events:
     Type    Reason     Age    From                                                 Message
     ----    ------     ----   ----                                                 -------
     Normal  Scheduled  3m20s  default-scheduler                                    Successfully assigned eks-sample-app/eks-sample-linux-deployment-65b7669776-m6qxz to ip-192-168-45-132.us-west-2.compute.internal
   [...]
   ```

   前の出力では、`IP:` の値は CIDR ブロックから Pod に割り当てられる一意の IP です。CIDR ブロックは、ノードが存在するサブネットに割り当てられています。異なる CIDR ブロックからのポッド IP アドレスを割り当てたい場合は、デフォルトの動作を変更できます。詳細については、「[カスタムネットワーキングを使用して代替サブネットに Pod をデプロイする](cni-custom-network.md)」を参照してください。また、Kubernetes スケジューラが IP アドレス *192.168.45.132* を使用して`Node`上の Pod をスケジュールしたことも確認できます。
**ヒント**  
コマンドラインを使用する代わりに、Pod、サービス、デプロイ、その他の Kubernetes リソースに関する多くの詳細を AWS マネジメントコンソール に表示できます。詳細については、「[AWS マネジメントコンソール に Kubernetes リソースを表示する](view-kubernetes-resources.md)」を参照してください。

## ポッドでシェルを実行する
<a name="_run_a_shell_on_a_pod"></a>

1. 前のステップで説明したポッドでシェルを実行し、*65b7669776-m6qxz* をいずれかのポッドの ID で置き換えます。

   ```
   kubectl exec -it eks-sample-linux-deployment-65b7669776-m6qxz -n eks-sample-app -- /bin/bash
   ```

1. Pod シェルから、前の手順でデプロイと共にインストールされたウェブサーバーからの出力を表示します。サービス名のみ指定する必要があります。デフォルトでは、Amazon EKS クラスターと共にデプロイされる CoreDNS によって、サービスの IP アドレスに解決されます。

   ```
   curl eks-sample-linux-service
   ```

   出力例は次のとおりです。

   ```
   <!DOCTYPE html>
   <html>
   <head>
   <title>Welcome to nginx!</title>
   [...]
   ```

1. ポッドシェルから、ポッドの DNS サーバーを表示します。

   ```
   cat /etc/resolv.conf
   ```

   出力例は次のとおりです。

   ```
   nameserver 10.100.0.10
   search eks-sample-app.svc.cluster.local svc.cluster.local cluster.local us-west-2.compute.internal
   options ndots:5
   ```

   前の出力では、クラスターにデプロイされたすべてのポッドに対して `10.100.0.10` が `nameserver` として自動的に割り当てられています。

1. `exit` を入力して、ポッドの接続を切断します。

1. サンプルアプリケーションの使用が終了したら、次のコマンドを使用して、サンプルの名前空間、サービス、デプロイを削除できます。

   ```
   kubectl delete namespace eks-sample-app
   ```

## 次のステップ
<a name="sample-deployment-next-steps"></a>

サンプルアプリケーションをデプロイしたら、次の演習の一部を試すことができます。
+  [Application Load Balancer を使用してアプリケーションと HTTP トラフィックをルーティングする](alb-ingress.md) 
+  [Network Load Balancer を使用して TCP および UDP トラフィックをルーティングする](network-load-balancing.md) 