EKSWorkshopを途中までやってみた3

前回までの進捗はこちら

今回はApp Meshを使用したService Meshまで

Step24

Elasticsearch, Fluentd, Kibana(EFK)を使用したロギング

ELKスタックの経験はあるけど時代はEFKなのかって感じ
とりあえずやってみる

  • インスタンスのロールにPolicyをputする(CWLogs周り)
  • ElasticsearchをElasticsearchServiceで作成する
  • fluentdをデプロイする(ap-northeastでやってるならRegion書き換え)
    中身はsaとclusterroleとそれのbind、cm及びds
  • 動いたことを確認する(例によってnodeは2つなので2でOK)
workshop:~/environment/fluentd $ kubectl get pods -w --namespace=kube-system
NAME                                   READY   STATUS    RESTARTS   AGE
aws-node-9dlvr                         1/1     Running   0          27m
aws-node-ltflc                         1/1     Running   0          27m
coredns-97bc697d6-7h87q                1/1     Running   0          33m
coredns-97bc697d6-vvhn8                1/1     Running   0          33m
fluentd-cloudwatch-nc26t               1/1     Running   0          2m39s
fluentd-cloudwatch-wq98x               1/1     Running   0          2m39s
kube-proxy-jhlxb                       1/1     Running   0          27m
kube-proxy-lwghz                       1/1     Running   0          27m
kubernetes-dashboard-57df4db6b-t9g56   1/1     Running   0          22m
tiller-deploy-5d6cc99fc-5h55h          1/1     Running   0          20m
  • CW -> ESのためのlambdaを作成する(ついでにRoleを作成してAWSLambdaBasicExecutionRoleをアタッチする)
  • AWSのUIでCWからESへ送るサブスクリプションフィルターを作成する
  • ESServiceからKibanaへアクセスして、インデックスを作成する
  • なんか思っていたよりいけてないログがでる(CWLogs側では期待しているログが出ていたのでそこまでの集約として考えるなら全然あり)

Step25

PrometheusとGrafanaを使用した監視

前々職でこの構成で監視基盤作ったときはdocker-composeで動かしてたのでk8sだとどう変わるのか

  • SSDはgp2を使用する(本番ではio1推奨らしいが、前々職ではIO周りで詰まった記憶はないので監視先のインスタンス/コンテナ数と使うexporter次第)
  • helmでprometheusをデプロイし確認する(namespaceも作成する)
workshop:~/environment $ kubectl get all -n prometheus
NAME                                                 READY   STATUS    RESTARTS   AGE
pod/prometheus-alertmanager-7fcbf759bd-rhr29         2/2     Running   0          3m23s
pod/prometheus-kube-state-metrics-7799d4bfbf-g6sq9   1/1     Running   0          3m23s
pod/prometheus-node-exporter-fvk9p                   1/1     Running   0          3m23s
pod/prometheus-node-exporter-k94qp                   1/1     Running   0          3m23s
pod/prometheus-pushgateway-5b8d9d5dcc-5ws4d          1/1     Running   0          3m23s
pod/prometheus-server-7648c9c478-cg4hv               2/2     Running   0          3m23s

NAME                                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/prometheus-alertmanager         ClusterIP   10.100.53.199   <none>        80/TCP     3m23s
service/prometheus-kube-state-metrics   ClusterIP   None            <none>        80/TCP     3m23s
service/prometheus-node-exporter        ClusterIP   None            <none>        9100/TCP   3m23s
service/prometheus-pushgateway          ClusterIP   10.100.88.172   <none>        9091/TCP   3m23s
service/prometheus-server               ClusterIP   10.100.19.184   <none>        80/TCP     3m23s

NAME                                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/prometheus-node-exporter   2         2         2       2            2           <none>          3m23s

NAME                                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/prometheus-alertmanager         1/1     1            1           3m23s
deployment.apps/prometheus-kube-state-metrics   1/1     1            1           3m23s
deployment.apps/prometheus-pushgateway          1/1     1            1           3m23s
deployment.apps/prometheus-server               1/1     1            1           3m23s

NAME                                                       DESIRED   CURRENT   READY   AGE
replicaset.apps/prometheus-alertmanager-7fcbf759bd         1         1         1       3m23s
replicaset.apps/prometheus-kube-state-metrics-7799d4bfbf   1         1         1       3m23s
replicaset.apps/prometheus-pushgateway-5b8d9d5dcc          1         1         1       3m23s
replicaset.apps/prometheus-server-7648c9c478               1         1         1       3m23s
  • port-forwardでprometheusにアクセスする(proxyでdashboardアクセスできるようにしてるとポート被るので気をつける)
  • helmでgrafanaをデプロイし確認する(namespaceも作成する)
workshop:~/environment $ kubectl get all -n grafana
NAME                          READY   STATUS    RESTARTS   AGE
pod/grafana-ffbdc8b97-t9hwx   1/1     Running   0          24s

NAME              TYPE           CLUSTER-IP       EXTERNAL-IP                                                                    PORT(S)        AGE
service/grafana   LoadBalancer   10.100.117.102   ################################-##########.ap-northeast-1.elb.amazonaws.com   80:32347/TCP   24s

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/grafana   1/1     1            1           24s

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/grafana-ffbdc8b97   1         1         1       24s
  • grafanaでprometheusからデータを取得して表示する(全体的にPromQLが古いので壊れてるから直す)
  • デプロイしたものを掃除する

Step26

Istioを使用したサービスメッシュ

  • Istio cliを落としてくる
  • Istio CRDをインストールする
  • Istioのコアコンポーネントをインストールする
workshop:~/environment/istio-1.3.1 $ kubectl get svc -n istio-system -w
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP        PORT(S)                                                                                                                                      AGE
grafana                ClusterIP      10.100.167.195   <none>             3000/TCP                                                      56s
istio-citadel          ClusterIP      10.100.195.15    <none>             8060/TCP,15014/TCP                                            56s
istio-galley           ClusterIP      10.100.205.166   <none>             443/TCP,15014/TCP,9901/TCP                                    56s
istio-ingressgateway   LoadBalancer   10.100.192.37    ##########         15020:31808/TCP,80:31380/TCP,443:31390/TCP,31400:31400/TCP,15029:32233/TCP,15030:32427/TCP,15031:31031/TCP,15032:30621/TCP,15443:32216/TCP   56s
istio-pilot            ClusterIP      10.100.226.51    <none>             15010/TCP,15011/TCP,8080/TCP,15014/TCP                        56s
istio-policy           ClusterIP      10.100.93.78     <none>             9091/TCP,15004/TCP,15014/TCP                                  56s
istio-telemetry        ClusterIP      10.100.253.149   <none>             9091/TCP,15004/TCP,15014/TCP,42422/TCP                        56s
prometheus             ClusterIP      10.100.143.199   <none>             9090/TCP                                                      56s
workshop:~/environment/istio-1.3.1 $ kubectl get pods -n istio-system
NAME                                    READY   STATUS      RESTARTS   AGE
grafana-575c7c4784-zwgn5                1/1     Running     0          3m21s
istio-citadel-59bff654d-9nzqr           1/1     Running     0          3m21s
istio-galley-568c49794c-rznn5           1/1     Running     0          3m21s
istio-ingressgateway-67c456dbbc-qwd72   1/1     Running     0          3m21s
istio-init-crd-10-1.3.1-lx8z6           0/1     Completed   0          4m19s
istio-init-crd-11-1.3.1-ftnnz           0/1     Completed   0          4m19s
istio-init-crd-12-1.3.1-j2tr2           0/1     Completed   0          4m19s
istio-pilot-779bc5cd44-84qgq            2/2     Running     0          3m21s
istio-policy-fb669db44-2vglz            2/2     Running     3          3m21s
istio-telemetry-768c56f5c7-9bxlv        2/2     Running     3          3m21s
prometheus-5679cb4dcd-gtjsq             1/1     Running     0          3m21s
  • サンプルアプリをデプロイする
workshop:~/environment/istio-1.3.1 $ kubectl get pod,svc
NAME                                 READY   STATUS    RESTARTS   AGE
pod/details-v1-6c7bc6569f-6qghz      2/2     Running   0          62s
pod/productpage-v1-d9cb4c69f-7c66z   2/2     Running   0          62s
pod/ratings-v1-684646657f-7556h      2/2     Running   0          62s
pod/reviews-v1-64d9894759-lxk4s      2/2     Running   0          62s // 評価サービスを呼び出さない(星なし)
pod/reviews-v2-74c48955f8-6zw8k      2/2     Running   0          62s // 評価サービスを呼び出す(星黒)
pod/reviews-v3-77cdbc686f-4lzd9      2/2     Running   0          62s // 評価サービスを呼び出す(星赤)

NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/details       ClusterIP   10.100.191.189   <none>        9080/TCP   62s
service/kubernetes    ClusterIP   10.100.0.1       <none>        443/TCP    127m
service/productpage   ClusterIP   10.100.148.57    <none>        9080/TCP   62s
service/ratings       ClusterIP   10.100.203.74    <none>        9080/TCP   62s
service/reviews       ClusterIP   10.100.241.119   <none>        9080/TCP   62s
  • 仮想のサービスとingress gatewayを定義する
  • ingress gatewayのdns名を取得し、アプリケーションへアクセスする(productpageへアクセスし、3バージョンにroutingされることを確認する)


  • Intelligent Routingを試すためにサブセットを定義する
  • 全てのトラフィックをreview:v1にルーティングする
  • いくらアクセスしてもv1へルーティングされることを確認する
  • jasonという名前のユーザからの全てのトラフィックをreview:v2にルーティングする
  • SIGN INした場合(jasonで)はv2に必ずルーティングされ、それ以外のuserもしくは匿名の場合はv1へルーティングされることを確認する


  • jasonだったら7秒遅延し、レビューの表示がエラーとして返ってくることを確認する
  • jasonだったら評価サービスの利用をできなくし、評価サービスが利用できない文言を確認する
  • 50%でv1、50%でv3へアクセスするように変更し確認する
  • GrafanaでIstioのMeshメトリクスを確認し、v1とv3で均等にリクエストが割り振られていることを確認する
  • Istioのdashboardが他にもあるので色々見てみる
  • デプロイしたものを掃除する

Step27

NodeへのPodの割り当て

  • Nodeにラベルを貼り付ける(今回はnumber=firstをつけた, 見づらいのでラベル毎に改行)
workshop:~/environment/istio-1.3.1 $ kubectl get nodes --show-labels
NAME                                               STATUS   ROLES    AGE   VERSION              LABELS
ip-192-168-16-30.ap-northeast-1.compute.internal   Ready    <none>   3h    v1.13.8-eks-cd3eb0   
alpha.eksctl.io/cluster-name=eksworkshop-eksctl,
alpha.eksctl.io/instance-id=i-0b477be0538f13d67,
alpha.eksctl.io/nodegroup-name=ng-646cd847,
beta.kubernetes.io/arch=amd64,
beta.kubernetes.io/instance-type=m5.large,
beta.kubernetes.io/os=linux,
failure-domain.beta.kubernetes.io/region=ap-northeast-1,
failure-domain.beta.kubernetes.io/zone=ap-northeast-1d,
kubernetes.io/hostname=ip-192-168-16-30.ap-northeast-1.compute.internal,
number=first

ip-192-168-85-95.ap-northeast-1.compute.internal   Ready    <none>   3h    v1.13.8-eks-cd3eb0   
alpha.eksctl.io/cluster-name=eksworkshop-eksctl,
alpha.eksctl.io/instance-id=i-014df24964d4e633a,
alpha.eksctl.io/nodegroup-name=ng-646cd847,
beta.kubernetes.io/arch=amd64,
beta.kubernetes.io/instance-type=m5.large,
beta.kubernetes.io/os=linux,
failure-domain.beta.kubernetes.io/region=ap-northeast-1,
failure-domain.beta.kubernetes.io/zone=ap-northeast-1a,
kubernetes.io/hostname=ip-192-168-85-95.ap-northeast-1.compute.internal
  • nodeSelectorを設定してデプロイする
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    number: first
  • ラベルを貼ったNodeと一致することを確認する
workshop:~/environment/istio-1.3.1 $ kubectl get pods -o wide
NAME    READY   STATUS              RESTARTS   AGE   IP       NODE                                               NOMINATED NODE   READINESS GATES
nginx   0/1     ContainerCreating   0          4s    <none>   ip-192-168-16-30.ap-northeast-1.compute.internal   <none>           <none>
  • 再度別のラベルを貼る(azname=az1)
  • affinityを定義したPodをデプロイする(azname in az1, az2)
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: azname
            operator: In
            values:
            - az1
            - az2
  • affinityを満たしたNodeと一致することを確認する
workshop:~/environment $ kubectl get pods -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP               NODE                                               NOMINATED NODE   READINESS GATES
with-node-affinity   1/1     Running   0          8s    192.168.18.185   ip-192-168-16-30.ap-northeast-1.compute.internal   <none>           <none>
  • ラベルを剥がして別のNodeに貼り直す、再度デプロイしてラベルを貼ったNodeと一致することを確認する
workshop:~/environment $ kubectl get pods -o wide
NAME                 READY   STATUS    RESTARTS   AGE   IP               NODE                                               NOMINATED NODE   READINESS GATES
with-node-affinity   1/1     Running   0          9s    192.168.76.228   ip-192-168-85-95.ap-northeast-1.compute.internal   <none>           <none>
  • WEBのレプリカが期待通りにキャッシュと同じ場所にデプロイされることを確認する
  • デプロイしたものを掃除する

Step28

App Meshを使用したService Mesh

  • app-mesh-examplesをcloneする
  • インスタンスRoleにappmeshの権限を付与する
  • yamlのAWS_REGIONを書き換える
  • jobを実行する(ワーカーの権限の確認)
  • 名前空間を作成する(namespace: prod)
  • 各種マイクロサービスのデプロイ
  • 各種マイクロサービスのサービスのデプロイ
workshop:~/environment/aws-app-mesh-examples/examples/apps/djapp (master) $ kubectl get all -nprod
NAME                            READY   STATUS    RESTARTS   AGE
pod/dj-7fbb4d499c-784ct         1/1     Running   0          5m17s
pod/jazz-v1-6d5dd497f-wppcn     1/1     Running   0          5m17s
pod/metal-v1-746d77c67b-8lkmj   1/1     Running   0          5m17s

NAME               TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/dj         ClusterIP   10.100.250.189   <none>        9080/TCP   46s
service/jazz-v1    ClusterIP   10.100.109.71    <none>        9080/TCP   46s
service/metal-v1   ClusterIP   10.100.248.13    <none>        9080/TCP   46s

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/dj         1/1     1            1           5m18s
deployment.apps/jazz-v1    1/1     1            1           5m17s
deployment.apps/metal-v1   1/1     1            1           5m17s

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/dj-7fbb4d499c         1         1         1       5m17s
replicaset.apps/jazz-v1-6d5dd497f     1         1         1       5m17s
replicaset.apps/metal-v1-746d77c67b   1         1         1       5m17s
  • djコンテナのshellを起動してjazzとmetalのv1エンドポイントへcurlを実行する
root@dj-7fbb4d499c-784ct:/usr/src/app# curl jazz-v1.prod.svc.cluster.local:9080;echo
["Astrud Gilberto","Miles Davis"]
root@dj-7fbb4d499c-784ct:/usr/src/app# curl metal-v1.prod.svc.cluster.local:9080;echo
["Megadeth","Judas Priest"]
  • InjectorControllerを作成する
App Inject Pods and Services After Install:

NAME                  TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
aws-app-mesh-inject   ClusterIP   10.100.65.10   <none>        443/TCP   16s
NAME                                  READY   STATUS    RESTARTS   AGE
aws-app-mesh-inject-fcc965769-9ptc8   1/1     Running   0          17s
  • prodにappmesh.k8s.aws/sidecarInjectorWebhook=enabledのラベルを貼り付ける
  • InjectorControllerが実行されていることを確認する
workshop:~/environment/aws-app-mesh-examples/examples/apps/djapp (master) $ kubectl get pods -nappmesh-inject
NAME                                  READY   STATUS    RESTARTS   AGE
aws-app-mesh-inject-fcc965769-9ptc8   1/1     Running   0          2m1s
  • CRDの追加とコントローラーを作成し、実行されていることを確認する
workshop:~/environment/aws-app-mesh-examples/examples/apps/djapp (master) $ kubectl get pods -nappmesh-system
NAME                                   READY   STATUS              RESTARTS   AGE
app-mesh-controller-5bb6cf64cd-kbdwn   0/1     ContainerCreating   0          11s
  • meshを作成し、確認する(meshはカスタムリソース)
workshop:~/environment/aws-app-mesh-examples/examples/apps/djapp (master) $ kubectl get meshes -nprod
NAME     AGE
dj-app   8s
  • aws cliでも確認できる(app mesh)
workshop:~/environment/aws-app-mesh-examples/examples/apps/djapp (master) $ aws appmesh list-meshes
{
    "meshes": [
        {
            "meshName": "dj-app", 
            "arn": "arn:aws:appmesh:ap-northeast-1:0123456789:mesh/dj-app"
        }
    ]
}
  • jazzとmetal用のVirtual Nodeを作成する
  • djとmetal-v1とjazz-v1のVirtual Nodeを作成する
  • jazzとmetalのVirtual Serviceを作成する
  • kubernetes側でVirtual Serviceのプレースホルダ名とIPを登録する
workshop:~/environment/aws-app-mesh-examples/examples/apps/djapp (master) $ kubectl create -nprod -f 4_create_initial_mesh_components/metal_and_jazz_placeholder_services.yaml
service/jazz created
service/metal created

workshop:~/environment/aws-app-mesh-examples/examples/apps/djapp (master) $ kubectl get -nprod virtualservices
NAME                           AGE
jazz.prod.svc.cluster.local    8m
metal.prod.svc.cluster.local   8m

workshop:~/environment/aws-app-mesh-examples/examples/apps/djapp (master) $ kubectl get svc -nprod
NAME       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
dj         ClusterIP   10.100.250.189   <none>        9080/TCP   27m
jazz       ClusterIP   10.100.141.177   <none>        9080/TCP   112s
jazz-v1    ClusterIP   10.100.109.71    <none>        9080/TCP   27m
metal      ClusterIP   10.100.194.46    <none>        9080/TCP   112s
metal-v1   ClusterIP   10.100.248.13    <none>        9080/TCP   27m
  • 各種マイクロサービスにpatchをあてて再作成する(Injector Controllerをデプロイする前にデプロイしたのでApp meshのサイドカーが含まれていない状態を避けるため)
  • djコンテナのshellを起動してjazzとmetalのVirtual Serviceのendpointへcurlを実行してレスポンスが正常に返ることを確認する
  • jazzとmetalのv2をデプロイする
  • jazz(v1:90%,v2:10%),metal(v1:50%,v2:50%)でルーティングされるように変更する
  • djコンテナのshellを起動してjazzとmetalのVirtual Serviceのendpointへcurlを実行してレスポンスの割合がおおよそ正しいことを確認する
root@dj-54db57b985-mx69b:/usr/src/app# while [ 1 ]; do curl http://metal.prod.svc.cluster.local:9080/;echo; done
["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"]
["Megadeth","Judas Priest"]
["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"]
["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"]
["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"]
["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"]
["Megadeth","Judas Priest"]
["Megadeth","Judas Priest"]
["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"]
["Megadeth (Los Angeles, California)","Judas Priest (West Bromwich, England)"]

root@dj-54db57b985-mx69b:/usr/src/app# while [ 1 ]; do curl http://jazz.prod.svc.cluster.local:9080/;echo; done
["Astrud Gilberto","Miles Davis"]
["Astrud Gilberto","Miles Davis"]
["Astrud Gilberto","Miles Davis"]
["Astrud Gilberto","Miles Davis"]
["Astrud Gilberto","Miles Davis"]
["Astrud Gilberto","Miles Davis"]
["Astrud Gilberto","Miles Davis"]
["Astrud Gilberto","Miles Davis"]
["Astrud Gilberto (Bahia, Brazil)","Miles Davis (Alton, Illinois)"]
["Astrud Gilberto (Bahia, Brazil)","Miles Davis (Alton, Illinois)"]
  • デプロイしたものを掃除する