

 **協助改進此頁面** 

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

若要為本使用者指南貢獻內容，請點選每個頁面右側面板中的**在 GitHub 上編輯此頁面**連結。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 Linux 上部署範例應用程式
<a name="sample-deployment"></a>

在這個主題中，您要部署範例應用程式至 Linux 節點上的叢集。

## 先決條件
<a name="_prerequisites"></a>
+ 一個現有的 Kubernetes 叢集至少會有一個節點。如果尚無現有 Amazon EKS 叢集，可以使用 [開始使用 Amazon EKS](getting-started.md) 中的其中一項指南來部署叢集。
+  安裝在電腦上的 `Kubectl`。如需詳細資訊，請參閱 [設定 `kubectl` 和 `eksctl`](install-kubectl.md)。
+  設定好的 `Kubectl`，以便與叢集通訊。如需詳細資訊，請參閱 [透過建立 kubeconfig 檔案將 kubectl 連線至 EKS 叢集](create-kubeconfig.md)。
+ 如果打算將範例工作負載部署至 Fargate，則必須擁有現有的 [Fargate 設定檔](fargate-profile.md)，其中包含在本教學課程中建立的相同命名空間，也就是 `eks-sample-app`，除非您變更名稱。如果您使用 [開始使用 Amazon EKS](getting-started.md) 中的其中一項入門指南來建立叢集，則必須建立新的設定檔，或將命名空間新增至現有設定檔，因為在入門指南中建立的設定檔不會指定本教學課程中使用的命名空間。您的 VPC 也必須至少有一個私有子網路。

雖然許多變數可在下列步驟中變更，但建議只在指定的位置變更變值。更加了解 Kubernetes Pod、部署和服務後，您可以嘗試變更其他值。

## 建立命名空間。
<a name="_create_a_namespace"></a>

命名空間可讓您將 Kubernetes 中的資源分組。如需詳細資訊，請參閱 Kubernetes 文件中的[命名空間](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)。若您計劃部署您的範例應用程式，以便[使用 AWS Fargate 來簡化運算管理](fargate.md)，請確認[定義啟動時哪些 Pod 使用 AWS Fargate](fargate-profile.md) 的 `namespace` 值為 `eks-sample-app`。

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

## 建立 Kubernetes 部署
<a name="_create_a_kubernetes_deployment"></a>

建立 Kubernetes 部署。此範例部署會從公有儲存庫提取容器映像，並將其三個複本 (個別 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 帳戶建立關聯。指定服務帳戶後，您的 Pod 僅能擁有您為它們指定與其他服務互動所需的最低許可。如需詳細資訊，請參閱 [服務帳戶的 IAM 角色](iam-roles-for-service-accounts.md)。

1. 將下列內容儲存到名為 `eks-sample-service.yaml` 的檔案中。Kubernetes 會為服務指派自己的 IP 地址，這些地址只能從叢集內存取。若要從叢集外部存取服務，請部署 [AWS Load Balancer 控制器](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
   ```

   在輸出中，您會看到在先前步驟中所部署範例清單檔案中指定的服務和部署。您也會看到三個 Pod。這是因為範例清單檔案中指定了 `3` 個 `replicas`。如需 Pod 的詳細資訊，請參閱 Kubernetes 文件中的 [Pod](https://kubernetes.io/docs/concepts/workloads/pods/pod/)。Kubernetes 會自動建立 `replicaset` 資源，即使其未在範例清單檔案中指定。如需 `ReplicaSets` 的詳細資訊，請參閱 Kubernetes 文件中的 [ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/)。
**注意**  
Kubernetes 會維護清單檔案中指定的複本數量。如果這是生產部署，並且您希望 Kubernetes 橫向擴展複本數量或垂直擴展 Pod 的運算資源，請使用[透過水平 Pod 自動擴展器來擴展 Pod 部署](horizontal-pod-autoscaler.md)和[透過垂直 Pod 自動擴展器來調整 Pod 資源](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)時，請檢視輸出中列出的其中一個 Pod 詳細資訊。使用其中一個 Pod 傳回的值來取代 *776d8f8fd8-78w66*。

   ```
   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:` 的值是唯一的 IP，從指派給節點所在子網路的 CIDR 區塊指派給 Pod。如果希望從不同的 CIDR 區塊指派 Pod IP 地址，則可以變更預設行為。如需詳細資訊，請參閱 [使用自訂聯網在替代子網路中部署 Pod](cni-custom-network.md)。您也可以看到 Kubernetes 排程器使用 IP 位址 *192.168.45.132* 排定了 `Node` 上的 Pod。
**提示**  
若不使用命令列，您可以在 AWS 管理主控台 中檢視有關 Pod、服務、部署和其他 Kubernetes 資源的許多詳細資訊。如需詳細資訊，請參閱 [在 中檢視 Kubernetes 資源 AWS 管理主控台](view-kubernetes-resources.md)。

## 在 Pod 上執行 Shell
<a name="_run_a_shell_on_a_pod"></a>

1. 在先前步驟中描述的 Pod 上執行 Shell，將 *65b7669776-m6qxz* 取代為其中一個 Pod 的 ID。

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

1. 在 Pod Shell 中，檢視在先前步驟中與部署一起安裝的 Web 伺服器輸出。您只需要指定服務名稱。CoreDNS 會將服務名稱解析為服務的 IP 位址；CoreDNS 預設會與 Amazon EKS 叢集一起部署。

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

   範例輸出如下。

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

1. 從 Pod Shell 中檢視 Pod 的 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` 會自動指派為讓所有 Pod 部署至叢集的 `nameserver`。

1. 透過輸入 `exit` 中斷從 Pod 的連線。

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) 