Ingress Controllerとは
- 必要になったらALBを作成してくれるPodのこと
- いずれかのNodeで起動する
- Ingressを使う場合GCPでは意識しなくて良いが、AWSではこのように手動で作成する必要がある
- ALBを作成せずにクラスター内にNginxを配備することでサービス公開するNginx Ingressというのもあるみたい
参考
https://dev.classmethod.jp/cloud/aws/eks-aws-alb-ingress-controller/
クラスタ作成
1 2 |
eksctl create cluster --name = k8s-cluster --nodes = 2 --node-type = t2.medium |
出力結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
[ℹ] eksctlバージョン0.7.0 [ℹ]リージョンus-east-2を使用 [ℹ]可用性ゾーンを[us-east-2c us-east-2a us-east-2b]に設定する [ℹ] us-east-2cのサブネット-public:192.168.0.0/19 private:192.168.96.0/19 [ℹ] us-east-2aのサブネット-public:192.168.32.0/19 private:192.168.128.0/19 [ℹ] us-east-2bのサブネット-public:192.168.64.0/19 private:192.168.160.0/19 [ℹ]ノードグループ「ng-ac8bfd87」は「ami-082bb518441d3954c」を使用します [AmazonLinux2 / 1.14] [ℹ] Kubernetesバージョン1.14を使用 [ℹ]「us-east-2」リージョンにEKSクラスター「k8s-cluster」を作成しています [ℹ]クラスター自体と初期ノードグループ用に2つの個別のCloudFormationスタックを作成します [ℹ]問題が発生した場合は、CloudFormationコンソールを確認するか、 「eksctl utils describe-stacks --region = us-east-2 --name = k8s-cluster」を試してください [ℹ] CloudWatchロギングは、「us-east-2」のクラスター「k8s-cluster」では有効になりません [ℹ] 'eksctl utils update-cluster-logging --region = us-east-2 --name = k8s-cluster'で有効にできます [ℹ] 2つの順次タスク:{クラスターコントロールプレーン "k8s-cluster"を作成し、 ノードグループ "ng-ac8bfd87"を作成します} [ℹ]クラスタスタック「eksctl-k8s-cluster-cluster」を構築しています [ℹ]スタック「eksctl-k8s-cluster-cluster」をデプロイしています [ℹ]ノードグループスタック「eksctl-k8s-cluster-nodegroup-ng-ac8bfd87」を 構築しています [ℹ] --nodes-min = 2がノードグループng-ac8bfd87に自動的に設定されました [ℹ] --nodes-max = 2がノードグループng-ac8bfd87に自動的に設定されました [ℹ]スタック「eksctl-k8s-cluster-nodegroup-ng-ac8bfd87」をデプロイしています [✔]「k8s-cluster」のすべてのEKSクラスターリソースが作成されました [✔] kubeconfigを「/Users/yuta/.config/k3d/k3s-default/kubeconfig.yaml」 として保存しました [ℹ] ID「arn:aws:iam :: 241161305159:role / eksctl-k8s-cluster-nodegroup -ng-a-NodeInstanceRole-MPUARSLLOYNO」を認証ConfigMapに追加 [ℹ]ノードグループ「ng-ac8bfd87」には0個のノードがあります [ℹ]「ng-ac8bfd87」で少なくとも2つのノードの準備が整うのを待つ [ℹ]ノードグループ「ng-ac8bfd87」には2つのノードがあります [ℹ]ノード「ip-192-168-39-153.us-east-2.compute.internal」の準備ができています [ℹ]ノード「ip-192-168-75-177.us-east-2.compute.internal」の準備ができています [ℹ] kubectlコマンドは「/Users/yuta/.config/k3d/k3s-default/kubeconfig.yaml」 で機能するはずです。'kubectl--kubeconfig = / Users / yuta / .config / k3d / k3s-default / kubeconfig .yaml getノード ' [✔]「us-east-2」リージョンのEKSクラスター「k8s-cluster」の準備ができています |
サービスアカウント作成、ロールのバインド
1 2 |
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs /aws-alb-ingress-controller/v1.0.0/docs/examples/rbac-role.yaml |
出力結果
1 2 3 4 |
clusterrole.rbac.authorization.k8s.io/alb-ingress-controller構成済み clusterrolebinding.rbac.authorization.k8s.io/alb-ingress-controller 設定済み serviceaccount / alb-ingressが作成されました |
AWS ALB Ingress Controllerのデプロイ
マニュフェストファイルをダウンロード
1 2 3 |
curl -sS "https://raw.githubusercontent.com/kubernetes-sigs/aws-alb -ingress-controller/v1.0.0/docs/examples/alb-ingress-controller.yaml" > alb-ingress-controller.yaml |
cluster-nameの部分をデプロイしているクラスタ名へ変更
1 2 3 4 |
#クラスタの名前。作成されたリソースに名前を付けるときに使用されます #ALBイングレスコントローラーによって、 #個のクラスター。 ---cluster-name = k8s-cluster |
展開
1 |
kubectl apply -f alb-ingress-controller.yaml |
展開確認
AWS ALB IngressController用のポッドが作成されている
1 2 |
kubectl get pod --all-namespaces | grep alb-ingress kube-system alb-ingress-controller-574db97b5f-2j7hb 1/1 Running 0 32s |
サンプルアプリケーションデプロイメント
ECR経由でEKSへ展開する
ECR作成
1 |
aws ecr create-repository --repository-name eks-test-app |
出力結果
1 2 3 4 5 6 7 8 9 10 11 12 |
{ "リポジトリ":{ "repositoryUri": "241161305159.dkr.ecr.us-east-2.amazonaws.com /eks-test-app"、 "レジストリID": "241161305159"、 "imageTagMutability": "MUTABLE"、 "repositoryArn": "arn:aws:ecr:us-east-2:241161305159:repository / eks-test-app"、 "リポジトリ名": "eks-test-app"、 「createdAt」:1571584240.0 } } |
ECRログイン情報を取得
1 |
aws ecr get-login --no-include-email |
上記の出力結果を実行する
1 |
Dockerログイン-u AWS -p XXXXXX |
ローカルにサンプルアプリケーションを作成
server.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="k">パッケージ</span> <span class="n">メイン</span> <span class="k">インポート</span> <span class="p">(</span> <span class="s">"fmt" </span> <span class="s">"log" </span> <span class="s">"net / http" </span> <span class="s">"os" </span> <span class="p">)</span> <span class="k">func </span> <span class="n">main </span><span class="p">()</span> <span class="p">{ </span> <span class="n">http </span><span class="o">。</span><span class="n">HandleFunc </span><span class="p">(</span><span class="s">"/" </span><span class="p">、</span> <span class="k">FUNC </span><span class="p">(</span><span class="n">W </span> <span class="n">HTTP </span><span class="o">。</span><span class="n">ResponseWriter </span><span class="p">、</span> <span class="n">R </span> <span class="o">* </span><span class="n">HTTP </span><span class="o">。</span><span class="n">リクエスト</span><span class="p">)</span> <span class="p">{ </span> <span class="n">FMT </span><span class="o">。</span><span class="n">fprintfの</span><span class="p">(</span><span class="n">W </span><span class="p">、</span> <span class="s">"健康な!" </span><span class="p">)</span> <span class="p">})</span> <span class="n">http </span><span class="o">。</span><span class="n">HandleFunc </span><span class="p">(</span><span class="s">"/ターゲット1" </span><span class="p">、</span> <span class="k">FUNC </span><span class="p">(</span><span class="n">W </span> <span class="n">HTTP </span><span class="o">。</span><span class="n">ResponseWriter </span><span class="p">、</span> <span class="n">R </span> <span class="o">* </span><span class="n">HTTP </span><span class="o">。</span><span class="n">リクエスト</span><span class="p">)</span> <span class="p">{ </span> <span class="n">FMT </span><span class="o">。</span><span class="n">fprintfの</span><span class="p">(</span><span class="n">W </span><span class="p">、</span> <span class="s">"/ターゲット1:" </span> <span class="o">+ </span> <span class="n">OS </span><span class="o">。</span><span class="n">GETENV </span><span class="p">(</span><span class="s">"POD_NAME" </span><span class="p">))</span> <span class="p">})</span> <span class="n">ログ</span><span class="o">。</span><span class="n">致命的</span><span class="p">(</span><span class="n">HTTP </span><span class="o">。</span><span class="n">ListenAndServe </span><span class="p">(</span><span class="s">":8080" </span><span class="p">、</span> <span class="no">nilの</span><span class="p">))</span> <span class="p">}</span> |
Dockerfile
1 2 3 4 5 |
<span class="k">FROM </span><span class="s">golang</span> <span class="k">追加</span><span class="s">。/ go / src / </span> <span class="k">EXPOSE </span><span class="s">8080 </span> <span class="k">CMD </span><span class="s">["/ usr / local / go / bin / go"、 "run"、 "/go/src/server.go"]</span> |
ビルド
1 |
docker build -t eks-test-app:target1。 |
タグ変更
1 2 |
Dockerタグeks-test-app:target1 XXXXXXXXXXXX.dkr.ecr.us-east-2. amazonaws.com/eks-test-app:target1 |
ECRへのプッシュ
1 2 |
docker push XXXXXXXXXXXX.dkr.ecr.us-east-2.amazonaws.com /eks-test-app:target1 |
target2用のアプリも同じ手順で作成
1 2 3 |
docker build -t eks-test-app:target2。 Dockerタグeks-test-app:target2 XXXXXXXXXXXX.dkr.ecr.us-east-2.amazonaws.com/eks-test-app:target2 docker push XXXXXXXXXXXX.dkr.ecr.us-east-2.amazonaws.com/eks-test-app:target2 |
Pushされているイメージ一覧
マニュフェスト作成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
apiVersion:v1 種類:名前空間 メタデータ: 名前:「test-app」 --- apiVersion:extensions / v1beta1 種類:展開 メタデータ: 名前:「test-app-deployment-target1」 名前空間:「test-app」 スペック: レプリカ:2 テンプレート: メタデータ: ラベル: app: "test-app-target1" スペック: コンテナ: -画像:XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com /eks-test-app:target1 imagePullPolicy:常に 名前:「test-app-target1」 ポート: -containerPort:8080 env: -名前:POD_NAME valueFrom: fieldRef: fieldPath:metadata.name --- apiVersion:extensions / v1beta1 種類:展開 メタデータ: 名前:「test-app-deployment-target2」 名前空間:「test-app」 スペック: レプリカ:2 テンプレート: メタデータ: ラベル: app: "test-app-target2" スペック: コンテナ: -画像:XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com /eks-test-app:target2 imagePullPolicy:常に 名前:「test-app-target2」 ポート: -containerPort:8080 env: -名前:POD_NAME valueFrom: fieldRef: fieldPath:metadata.name --- apiVersion:v1 種類:サービス メタデータ: 名前:「test-app-service-target1」 名前空間:「test-app」 スペック: ポート: -ポート:80 targetPort:8080 プロトコル:TCP タイプ:NodePort セレクタ: app: "test-app-target1" --- apiVersion:v1 種類:サービス メタデータ: 名前:「test-app-service-target2」 名前空間:「test-app」 スペック: ポート: -ポート:80 targetPort:8080 プロトコル:TCP タイプ:NodePort セレクタ: app: "test-app-target2" |
アプリケーションの展開
1 |
kubectl apply -f test-app.yaml |
出力結果
1 2 3 4 5 |
名前空間/テストアプリが作成されました deployment.extensions / test-app-deployment-target1が作成されました deployment.extensions / test-app-deployment-target2が作成されました service / test-app-service-target1が作成されました service / test-app-service-target2が作成されました |
展開確認
1 |
kubectl get all --all-namespaces | grepテストアプリ |
出力結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
test-app pod / test-app-deployment-target1-66498868db-67zdw 1/1 Running 0 56s test-app pod / test-app-deployment-target1-66498868db-tvfgx 1/1 Running 0 56s test-app pod / test-app-deployment-target2-646fd4978f-282qj 1/1 Running 0 55s test-app pod / test-app-deployment-target2-646fd4978f-xjqw7 1/1 Running 0 55s test-app service / test-app-service-target1 NodePort 10.100.82.136 <なし> 80:31922 / TCP 55s test-app service / test-app-service-target2 NodePort 10.100.208.75 <none> 80:32280 / TCP 55s test-app deployment.apps / test-app-deployment-target1 2/2 2 2 57s test-app deployment.apps / test-app-deployment-target2 2/2 2 2 56s test-app replicaset.apps / test-app-deployment-target1-66498868db 2 2 2 57s test-app replicaset.apps / test-app-deployment-target2-646fd4978f 2 2 2 56s |
ALB作成
ingress.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="na">apiVersion </span><span class="pi">:</span> <span class="s">拡張/ v1beta1の</span> <span class="na">種類</span><span class="pi">:</span> <span class="s">イングレスの</span> <span class="na">メタデータ</span><span class="pi">:</span> <span class="na">名</span><span class="pi">:</span> <span class="s2">「</span><span class="s">入」</span> <span class="na">の名前空間</span><span class="pi">:</span> <span class="s2">「</span><span class="s">テストアプリ」</span> <span class="na">の注釈</span><span class="pi">:</span> <span class="s">kubernetes.io/ingress.class </span><span class="pi">:</span> <span class="s">ALB </span> <span class="s">alb.ingress.kubernetes.io/scheme </span><span class="pi">:</span> <span class="s">インターネットに面した</span> <span class="na">ラベル</span><span class="pi">:</span> <span class="na">アプリ</span><span class="pi">:</span> <span class="s">テストアプリ</span> <span class="na">仕様</span><span class="pi">:</span> <span class="na">ルール</span><span class="pi">:</span> <span class="pi">- </span> <span class="na">HTTP </span><span class="pi">:</span> <span class="na">パス</span><span class="pi">:</span> <span class="pi">- </span> <span class="na">パス</span><span class="pi">:</span> <span class="s">/ターゲット1 </span> <span class="na">バックエンド</span><span class="pi">:</span> <span class="na">serviceNameを</span><span class="pi">:</span> <span class="s2">" </span><span class="s">テストアプリサービス・ターゲット1" </span> <span class="na">SERVICEPORT </span><span class="pi">:</span> <span class="m">80 </span> <span class="pi">- </span> <span class="na">パス</span><span class="pi">:</span> <span class="s">/ TARGET2 </span> <span class="na">バックエンド</span><span class="pi">:</span> <span class="na">serviceNameを</span><span class="pi">:</span> <span class="s2">" </span><span class="s">テストアプリサービス-TARGET2" </span> <span class="na">SERVICEPORT </span><span class="pi">:</span> <span class="m">80</span> |
ALBマニュフェストのapply
1 |
kubectl apply -f ingress.yaml |
ALBが作成されないっぽい
ログ確認
1 |
kubectlログ-n kube-system alb-ingress-controller-5bfd896bd9-hctqk |
怪しいエラー
1 2 3 4 5 6 7 8 9 |
E1020 16:46:07.820806 1:0] kubebuilder / controller "msg" = "Reconciler error" "error" = "AWSタグの取得に失敗したため、LoadBalancer構成の構築に 失敗しましたエラー:AccessDeniedException:ユーザー:arn:aws:sts :: 241161305159:assumed-role / eksctl-k8s-cluster-nodegroup-ng-a -NodeInstanceRole-MPUARSLLOYNO / i-0c18a25d7a5c8e53cの実行は 許可されていません:タグ:GetResources \ n \ tステータスコード:400、 リクエストID:7225892f-f803 -4a10-86a3-c4769ff83a2d "" Controller "=" alb-ingress-controller "" Request "= {" Namespace ":" test-app "、" Name ":" ingress "} |
1 2 3 4 |
export REGION = us-east-2 ALB_POLICY_ARN = $(aws iam create-policy --region = $ REGION --policy-name aws-alb-ingress-controller --policy-document "https://raw.githubusercontent.com/kubernetes-sigs/aws- alb-ingress-controller / master / docs / examples / iam-policy.json "--query" Policy.Arn "| sed 's /" // g') エクスポートNODE_ROLE_NAME = eksctl-k8s-cluster-nodegroup-ng-a-NodeInstanceRole-MPUARSLLOYNO aws iam attach-role-policy --region = $ REGION --role-name = $ NODE_ROLE_NAME --policy-arn = $ ALB_POLICY_ARN |
NODE_ROLE_NAMEの箇所
再度デプロイ
1 2 3 |
kubectl delete pod alb-ingress-controller-5bfd896bd9-hctqk -n kube-system kubectl apply -f alb-ingress-controller.yaml |
ALBが無事作成された
動作確認
target1へのアクセス
1 2 3 4 5 6 |
〜/ D / ingress❯❯❯curl http://b0a25c21-testapp-ingress-1d16-1953215674 .us-east-2.elb.amazonaws.com/target1 / target1:test-app-deployment-target1-66498868db-tvfgx% 〜/ D / ingress❯❯❯curl http://b0a25c21-testapp-ingress-1d16-1953215674 .us-east-2.elb.amazonaws.com/target1 / target1:test-app-deployment-target1-66498868db-67zdw% |
target2へのアクセス
1 2 3 4 5 6 |
〜/ D / ingress❯❯❯curl http://b0a25c21-testapp-ingress-1d16-1953215674 .us-east-2.elb.amazonaws.com/target2 / target2:test-app-deployment-target2-646fd4978f-xjqw7% 〜/ D / ingress❯❯❯curl http://b0a25c21-testapp-ingress-1d16-1953215674 .us-east-2.elb.amazonaws.com/target2 / target2:test-app-deployment-target2-646fd4978f-282qj% |