GCP AnthosでAWS EKSを管理する

# はじめに
こんにちは@tetotetoと申します。

本記事は、GCPのAnthosに関する学習履歴になります。
Anthosを理解したい人に役立てばと思います。
今回の記事では**ハンズオンを試したのち、EKSのクラスタを接続するところまでやってみます**

今回初めてAnthosについて投稿するため、簡単にAnthosとは？をまとめた後に
実際にやったことを整理します。

# Anthosとは
Anthosは、Kubernetesをベースにアプリケーションのマルチクラウド対応を実現する新サービス
Google Cloud上ではGoogle Kubernetes Engine（GKE）上で稼働し、オンプレミスではGKEオンプレミス上で稼働
さらにAWS上でも稼働予定のため、Google以外のクラウドサポートが見込まれている

つまり、GCPの統合管理サービスです。
GCP以外のクラウドサービスやオンプレサーバの一括管理ができるサービスです

##### 個人的には統合管理できること＋サービスメッシュのマネージドサービスがあることが強いと思っています
AWSもAppMeshというものがあるのですが、これとの比較もやりたいなあ

# Anthos Service Mesh とは
複雑なマイクロサービス アーキテクチャ向けのフルマネージド サービス メッシュ。

マイクロサービス アーキテクチャには多くのメリットがありますが、複雑性が増す
さまざまなワークロードで断片化が起きる、といった課題もあります。
Anthos プラットフォームにより、トラフィック管理やメッシュ テレメトリ、
サービス間の通信保護に至るまで、全体的なサービス運用をシンプルにして、
運用チームや開発チームの負担を軽減します。

Anthos Service Mesh は、マイクロサービス アーキテクチャの
複雑な環境を簡単に管理し、マイクロサービスのあらゆるメリットを享受できるようにするための
Google のフルマネージド サービス メッシュです。

https://cloud.google.com/anthos/service-mesh


##### 補足：サービスメッシュとは
ビジネス機能に沿って複数小さい「マイクロサービス」に分割し、それらを連携してアプリケーションを構築する
細かくサービスを分けることで、障害個所の発見や複数技術で対応可能、スケール・冗長化が容易
開発チームを小さくできる、サービス一つ一つが小さいため把握が容易
サービスの再利用性が高くなる　などのメリットがあります。

[サービスメッシュとGoogle Cloudサービスメッシュの紹介](https://qiita.com/nagasada/items/02381dc6042fc869a22b)


# 私が思うAnthosの利点
上記のAnthos Service Mesh が特徴的だと思っています

##### フルマネージドでサービスメッシュが用意できる
##### コンソールで可視化できるので扱いやすい
##### 公式ドキュメントも多いので、学習コストがやや低い

こんな感じで表示されます。
左側の項目にサービスメッシュがあるようにGCP側も推しているのかなと
![Anthos.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585341/c3320d35-78c1-c11d-9937-63082ef83b6f.png)

![Anthos2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585341/80c3c502-dbce-29be-06c5-ba70e2af0039.png)



# ①Anthos ハンズオンをやってみる


以下の公式の**Anthosを試す**をやってみる

Cloud Marketplace を使用して Google Cloud で Anthos サンプル デプロイを起動するので
ブラックボックスにはなりますが、サービスメッシュがよくわからない状態でも、どんな感じのことが
Anthosでできるのかがわかります。(上記の画像は以下のサンプル実行の結果になります)

https://cloud.google.com/anthos/docs/tutorials/explore-anthos?_ga=2.238410240.1494422275.1592695936-1900483699.1589728994&_gac=1.91806056.1592697064.Cj0KCQjwoaz3BRDnARIsAF1RfLd1AG6iP5E0DlpdRVXB9SYvt2H_ML7e7Jg99akGivXs32s4NfgQge8aAmUxEALw_wcB

特にはまりどころはなかったです
結構いろいろデプロイされるみたいで、月々5000円弱の費用が発生するので
確認終わったらすぐに消すのがいいと思います。

Anthosのリソースを削除したいときはDeployManagerから削除できます。

# ②AWS EKSとのクラスタ接続

Anthosを使う目的でもありますが、ほかクラウドサービスのサーバリソースが使えます。
ここではAWSのEKSとの連携をやってみます。
以下の記事を参考にしています。

https://cloud.google.com/anthos/docs/setup/attached-clusters#console

### 作業1 : AWS EKSクラスタの作成

Anthosの実行のため、AWSに構築したEC2からEKSを構築しました。
(サーバの接続とかで悩まないようにしたく)

特に今回はEKSの設定もデフォルトでいいかなと思って、細かく設定を与えていません。
クラスタ作成時にインスタンスタイプや台数も決められるため、ちゃんと入れたほうがいいです
eksctlはインストール必要だと思うので以下を参考にインストールしておく

```
$ eksctl create cluster --name eks-anthos-2
2022-01-26 15:22:04 [ℹ]  eksctl version 0.80.0
2022-01-26 15:22:04 [ℹ]  using region ap-northeast-1
省略
$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   13m
```


参考：
[kubectl のインストール](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/install-kubectl.html)
[eksctlのインストール](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/eksctl.html)
[「eksctl」コマンドを使ったAmazon EKS構築入門](https://dev.classmethod.jp/articles/getting-started-amazon-eks-with-eksctl/)
[Amazon EKS API サーバーに接続するときに発生する「承認されていないサーバー」のエラーを解決する方法を教えてください](https://aws.amazon.com/jp/premiumsupport/knowledge-center/eks-api-server-unauthorized-error/)
[Amazon EKS クラスターに接続できないのはなぜですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/eks-cluster-connection/)

### 作業2 : gcp Cloud SDK のインストール
AWS　EC2でクラスタを立てたので、gcloudのコマンドが通るように設定する
どのぐらいの手間なのか知りたい気持ちもあって、この作業を実施
awsやazのインストールは結構簡単だったが、gcloudのCLIのインストールはちょっとめんどくさい印象を受けた

以下がとても丁寧な感じです。SDK の初期化などがひと手間多い印象。

[Ubuntu 18.04 (WSL) に、Google Cloud SDK をインストールする](https://laboradian.com/install-google-cloud-sdk-on-wsl-ubuntu/#4_Google_Cloud_SDK_etc)

### 作業3 : サービスアカウントの払い出し

GCPにはサービスアカウントという考え方があります。
アプリに属するアカウントで、AWSでいうロールに近いですかね。
それを用意しておきます。以下の権限を付与する必要があります。
(今回はお試しのためowner付与、実は最初編集者の権限付与していてはまりました、一番下に記載)
以下の手順でjsonファイルが発行でき、そのjsonをEC2サーバにSCPしておきます
このとき、jsonファイルの位置を覚えておく必要があります(この後の手順でパス指定する必要がある)

> Google Cloud Console の左上から、[IAM と管理] 次に [サービス アカウント] に移動します。
> サービス アカウントを選択します。
> [キー] で [鍵を追加] を選択し、新しい JSON キーを作成します。

詳しくは以下

https://cloud.google.com/anthos/multicluster-management/connect/prerequisites?authuser=1#fleet_workload_identity_requirements

### 作業4 : EKSをAnthosに接続

今回はコンソールで作業をしました。詳しくは以下参照。
EC2側でコマンド実行することでgke-connectのデプロイがされ、管理可能となります。

https://cloud.google.com/anthos/multicluster-management/connect/registering-a-cluster?authuser=1&_ga=2.141830326.-56655199.1631519808#install-gcloud-beta

![スクリーンショット 2022-01-27 003813.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585341/fd1692fd-85ed-a547-5492-ea887bd7e366.png)


実行結果

```
$ gcloud container hub memberships register eks-anthos-2 \
>             --context=省略(kubectl config current-contextの実行結果を記載) \
>             --service-account-key-file=省略(サービスアカウントで払い出されたjsonファイルのパスを記載) \
>             --kubeconfig=~/.kube/config \
>             --project=省略
Waiting for membership to be created...                                                                                                                                             
Waiting for membership to be created...done.                                                                                                                                        
Created a new membership [projects/ 省略 for the cluster [eks-anthos-2]
Generating the Connect Agent manifest...
Deploying the Connect Agent on cluster [eks-anthos-2] in namespace [gke-connect]...
Deployed the Connect Agent on cluster [eks-anthos-2] in namespace [gke-connect].
Finished registering the cluster [eks-anthos-2] with the Fleet.
```

実行後コンソールを確認すると、登録されていた

![スクリーンショット 2022-01-27 020005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585341/73b256ee-1a65-44ef-7812-fa5f42efc5a1.png)


### 作業5 : クラスタ認証情報を有効にするためにログインする

ログイン方法自体はいくつかあるが、今回はトークン認証でやってみる
(正確にはGoogle Cloud ID を使用したログインがうまくいかなかったため、、何か設定が足りていない？)

https://cloud.google.com/anthos/multicluster-management/console/logging-in?authuser=1

実行結果

```
$ cat <<EOF > cloud-console-reader.yaml
> kind: ClusterRole
> apiVersion: rbac.authorization.k8s.io/v1
> metadata:
>   name: cloud-console-reader
> rules:
> - apiGroups: [""]
>   resources: ["nodes", "persistentvolumes", "pods"]
>   verbs: ["get", "list", "watch"]
> - apiGroups: ["storage.k8s.io"]
>   resources: ["storageclasses"]
>   verbs: ["get", "list", "watch"]
> EOF
$ kubectl apply -f cloud-console-reader.yaml
clusterrole.rbac.authorization.k8s.io/cloud-console-reader created

$ KSA_NAME=test-anthos
$ kubectl create serviceaccount ${KSA_NAME}
serviceaccount/test-anthos created
$ kubectl create clusterrolebinding r-test-anthos \
> --clusterrole view --serviceaccount default:${KSA_NAME}
clusterrolebinding.rbac.authorization.k8s.io/r-test-anthos created
$ kubectl create clusterrolebinding c-test-anthos \
> --clusterrole cloud-console-reader --serviceaccount default:${KSA_NAME}
clusterrolebinding.rbac.authorization.k8s.io/c-test-anthos created

$ SECRET_NAME=$(kubectl get serviceaccount test-anthos -o jsonpath='{$.secrets[0].name}')
$ kubectl get secret ${SECRET_NAME} -o jsonpath='{$.data.token}' | base64 --decode
eyJhbGciOiJSUzI1NiIsImtpZCI6ImV4THR2Qjc5a・・・
(省略：ここで書かれるコードをコンソール側にコピーして貼り付けするとログインできる)
```

払い出されたトークンを使うことで、認証完了
以下のようにサーバリソースをAnthos側で認識するようになりました

![スクリーンショット 2022-01-27 021520.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585341/82785098-49a3-b752-c0a8-ecab40cfc368.png)


# まとめ：思ったよりも時間がかかったが、慣れればなんとか？

同じようなことをAzureの統合管理サービスであるAzureArcでも実施しましたが
ほぼほぼ同じか、それ以上には時間を使った印象です。
Anthosと外部リソースの連携手順は複数ページにまたがるので、理解のしにくさはあるのかなと思ったり
[【Azure】Amazon EKS をジャンプスタートを使って Azure Arc に追加してみた](https://qiita.com/sk_130/items/31e429a77475ac6c9483)

# おまけ：権限エラーではまった

なかなかロードが終わらないので、一度キャンセル

![スクリーンショット 2022-01-27 014013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585341/82cf6758-33b8-a2c0-62d4-4951a8348343.png)


左のクラスタのボタンをクリックすると登録自体はされていた
が、コンソール右側でエラー表示されていた。。

![スクリーンショット 2022-01-27 015145.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585341/94512d53-5671-9066-0021-9d45a4229874.png)


ちゃんと、トラブルシューティング(ログ分析)のサイトも用意されていました

https://cloud.google.com/anthos/multicluster-management/connect/troubleshooting

指示に従って実行

```
$ for ns in $(kubectl get ns -o jsonpath={.items..metadata.name} -l hub.gke.io/project); do
>   echo "======= Logs $ns ======="
>   kubectl logs -n $ns -l app=gke-connect-agent
> done
======= Logs gke-connect =======
2022/01/26 16:45:11.836796 dialer.go:264: dialer: dial: connecting to gkeconnect.googleapis.com:443...
2022/01/26 16:45:11.902945 dialer.go:275: dialer: dial: connected to gkeconnect.googleapis.com:443
2022/01/26 16:45:11.902964 tunnel.go:324: serve: opening egress stream...
2022/01/26 16:45:11.903016 tunnel.go:332: serve: registering project_number="省略", connection_id="eks-anthos-2" connection_class="DEFAULT" agent_version="20220121-01-00" ...
2022/01/26 16:45:11.903048 dialer.go:225: Dial successful, current connections: 1
2022/01/26 16:45:12.283225 tunnel.go:381: serve: recv error: rpc error: code = PermissionDenied desc = The caller does not have permission
2022/01/26 16:45:12.283345 dialer.go:277: dialer: dial: connection to gkeconnect.googleapis.com:443 failed after 446.538427ms: serve: receive request failed: rpc error: code = PermissionDenied desc = The caller does not have permission
2022/01/26 16:45:12.312498 dialer.go:207: dialer: connection done: serve: receive request failed: rpc error: code = PermissionDenied desc = The caller does not have permission
2022/01/26 16:45:12.312554 dialer.go:295: dialer: backoff: 1m2.4659913s
E0126 16:45:33.996364       1 reflector.go:131] third_party/golang/kubeclient/tools/cache/reflector.go:99: Failed to list *unstructured.Unstructured: the server could not find the requested resource
```

実行した結果、PermissionDenied エラーであることがわかりました。
サービスアカウントの権限を強くすることで解決しました。
結構親切でした。