[GCP LAB]Kubernetes in GCP(Googleクラウド上でKubernetesクラスタとリソースを作成)


Jumpstart your cloudのキャリアの一環として、Google Certified Corporationで行われたGoogle CloudJamを申請しました.申し込みは無料(早すぎる…)、Qwiklabアクセスアカウントは、約1ヶ月の購読クレジットを提供します.
行われた2つのQwiklab Questのうち、私がやったQuestテーマは[Kubernetesin GCP]ですが、実習内容を整理しておきます.

Introduction to Docker


GCPでDocker containerを実行、構築、デバッグする実践について.この実験では.
  • docker hub/Google Container Registryでdockerイメージ
  • を解放する方法
  • GCRドッキング画像
  • をプッシュする方法
    実習しました.
  • Dockerfileの作成
  • Dockerfileを作成する仕様は次のとおりです.
    cat > Dockerfile << EOF
    
    # base parent이미지를 명시한다 (이 경우에는 node version 6라고 명시함)
    FROM node:6
    # Set the working directory in the container to /app (container실행경로가 /app으로 하도록 작업경로 설정)
    WORKDIR /app 
    
    # Copy the current directory contents into the container at /app
    ADD . /app (현재 작업경로의 컨텐츠를 container에 add함)
    
    # Make the container's port 80 available to the outside world
    EXPOSE 80 (container 포트 노출)
    
    # Run app.js using node when the container launches
    CMD ["node", "app.js"]
    EOF
  • Nodeアプリケーション
  • の作成
    80番ポートでアクセスできるhello world出力の簡単なアプリケーションを作成します.
    cat > app.js <<EOF
    const http = require('http');
    const hostname = '0.0.0.0';
    const port = 80;
    const server = http.createServer((req, res) => {
        res.statusCode = 200;
          res.setHeader('Content-Type', 'text/plain');
            res.end('Hello World\n');
    });
    server.listen(port, hostname, () => {
        console.log('Server running at http://%s:%s/', hostname, port);
    });
    process.on('SIGINT', function() {
        console.log('Caught interrupt signal and will exit');
        process.exit();
    });
    EOF
    docker imagesコマンドで確認すると、0.1バージョンにdockerファイルが表記されています
    student_04_13d47ca1e9b3@cloudshell:~/test (qwiklabs-gcp-00-6a9fb388c3c3)$ docker images
    REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
    node-app      0.1       4da28894f75a   39 seconds ago   884MB
    hello-world   latest    d1165f221234   6 months ago     13.3kB
    node          6         ab290b853066   2 years ago      884MB
    別の端末を開きcurlを要求した場合の結果
    student_04_13d47ca1e9b3@cloudshell:~ (qwiklabs-gcp-00-6a9fb388c3c3)$ curl http://localhost:4000
    Hello World
    docker bashに近づきたい時?(さっき/appディレクトリでコンテナを実行すると指定したので、このパスに接続することができます)student_04_13d47ca1e9b3@cloudshell:~/test (qwiklabs-gcp-00-6a9fb388c3c3)$ docker exec -it e9c73fffe77f bash
  • このイメージをGoogle Contenter Registry(GCR):
  • に公開
    GCRが管理するprivate registryに画像をプッシュするには、画像registry nameとともにタグ付けする必要があります.The format is [hostname]/[project-id]/[image]:[tag].
    次にTagからgcrにpushを加えたcmdを以下に示す.
    student_04_13d47ca1e9b3@cloudshell:~/test (qwiklabs-gcp-00-6a9fb388c3c3)$ docker tag node-app:0.2 gcr.io/qwiklabs-gcp-00-6a9fb388c3c3/node-app:0.2
    
    student_04_13d47ca1e9b3@cloudshell:~/test (qwiklabs-gcp-00-6a9fb388c3c3)$ docker push gcr.io/qwiklabs-gcp-00-6a9fb388c3c3/node-app:0.2
    The push refers to repository [gcr.io/qwiklabs-gcp-00-6a9fb388c3c3/node-app]
    cf85c86000d0: Pushed
    8c8e6d8018ef: Pushed
    f39151891503: Pushed
    f1965d3c206f: Pushed
    a27518e43e49: Layer already exists
    910d7fd9e23e: Layer already exists
    4230ff7f2288: Layer already exists
    2c719774c1e1: Layer already exists
    ec62f19bb3aa: Layer already exists
    f94641f1fe1f: Layer already exists
    既存の埠頭労働者をすべて除去し、GCRから画像を引き出します.
    student_04_13d47ca1e9b3@cloudshell:~/test (qwiklabs-gcp-00-6a9fb388c3c3)$ docker pull gcr.io/qwiklabs-gcp-00-6a9fb388c3c3/node-app:0.2
    0.2: Pulling from qwiklabs-gcp-00-6a9fb388c3c3/node-app
    c5e155d5a1d1: Pull complete
    221d80d00ae9: Pull complete
    4250b3117dca: Pull complete
    3b7ca19181b2: Pull complete
    425d7b2a5bcc: Pull complete
    69df12c70287: Pull complete
    ea2f5386a42d: Pull complete
    d421d2b3c5eb: Pull complete
    3d3f5cc96fd9: Pull complete
    dfc21c45a13c: Pull complete
    Digest: sha256:928d65b1be2111de18666af5e150cdd94bf62d631f4b8881928cb768f96d59c1
    Status: Downloaded newer image for gcr.io/qwiklabs-gcp-00-6a9fb388c3c3/node-app:0.2
    gcr.io/qwiklabs-gcp-00-6a9fb388c3c3/node-app:0.2
    pullイメージを対応するポートとして実行します.
    student_04_13d47ca1e9b3@cloudshell:~ (qwiklabs-gcp-00-6a9fb388c3c3)$ curl http://localhost:4000
    Jiyoon
    やれやれ!GCRから画像をドラッグしてコンテナquestの実行を完了

    Kubernetes Engine:Qwik Start/GCPでKubernetes Engine Clusterを構築する


    次のタスクはGKEでKubernetes engineクラスタを構築してクラスタを編成することです.
    シェルを利用してGKEクラスタを構築する.
    クラスタを作成する前にdefault compute zoneを設定します.gcloud config set compute/zone us-central1-aはus-central/ZoneAに設定されています.
    student_00_6b130b2897a7@cloudshell:~ (qwiklabs-gcp-04-ba9754128013)$ gcloud container clusters create jiyoon-cluster
    
    WARNING: Your Pod address range (`--cluster-ipv4-cidr`) can accommodate at most 1008 node(s).
    WARNING: Starting with version 1.19, newly created clusters and node-pools will have COS_CONTAINERD as the default node image when no image type is specified.
    Creating cluster jiyoon-cluster in us-central1-a...done.     
    Created [https://container.googleapis.com/v1/projects/qwiklabs-gcp-01-500142021c34/zones/us-central1-a/clusters/jiyoon-cluster].
    To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/us-central1-a/jiyoon-cluster?project=qwiklabs-gcp-01-500142021c34
    kubeconfig entry generated for jiyoon-cluster.
    NAME: jiyoon-cluster
    LOCATION: us-central1-a
    MASTER_VERSION: 1.20.9-gke.701
    MASTER_IP: 104.154.182.127
    MACHINE_TYPE: e2-medium
    NODE_VERSION: 1.20.9-gke.701
    NUM_NODES: 3
    STATUS: RUNNING
  • クラスタアクセス認証
  • を取得
    gcloud container clusters get-credentials [CLUSTER-NAME]
    アプリケーションを
  • のクラスタ
  • に配備
    You can now deploy a containerized application to the cluster. For this lab, you'll run hello-app in your cluster.
    student_00_df37a4b73fa7@cloudshell:~ (qwiklabs-gcp-01-500142021c34)$ kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:1.0
    
    deployment.apps/hello-server created
    To create a Kubernetes Service, which is a Kubernetes resource that lets you expose your application to external traffic, run the following kubectl expose command:
    私のappを外部トラフィックに露出させるために、K 8 Sオブジェクトサービスを生成します.
    student_00_df37a4b73fa7@cloudshell:~ (qwiklabs-gcp-01-500142021c34)$ kubectl expose deployment hello-server --type=LoadBalancer --port 8080
    
    service/hello-server exposed
    kubectl cmdを使用してサービスに関する情報を取得します.
    student_00_df37a4b73fa7@cloudshell:~ (qwiklabs-gcp-01-500142021c34)$ kubectl get service
    NAME           TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)          AGE
    hello-server   LoadBalancer   10.7.254.122   34.133.67.214   8080:32531/TCP   53s
    kubernetes     ClusterIP      10.7.240.1     <none>          443/TCP          7m20s
    次に、示すexternal ipを介してクラスタ外部のブラウザにアクセスします.

    わあ!
    なんだ.なぜクラスタを削除するのかはわかりませんが...現実にはほとんど起こらないけど...でも実習から削除までは.
    student_00_df37a4b73fa7@cloudshell:~ (qwiklabs-gcp-01-500142021c34)$ gcloud container clusters delete jiyoon-cluster
    The following clusters will be deleted.
     - [jiyoon-cluster] in [us-central1-a]
    
    Do you want to continue (Y/n)?  y
    
    Deleting cluster jiyoon-cluster...working.
    クラスタを削除する練習が完了しました.
    注意)クラスタの作成と削除には、構成に時間がかかることがよくあります.5分以上かかったのではないでしょうか.

    クラウドをKubernetsで組織する(クラウド環境でクバーネスを編成する)


    この実験室では、Kubernetesengineを使用してKubernetesclusterを提供し、kubectlを使用してdocker containersを管理し、Kubernetesdeploymentとserviceを使用してappをMicroserviceに分割します.

  • Google K 8 S Engine defaultエリアの設定gcloud config set compute/zone us-central1-b次にioというクラスタを開始します.student_00_f2561c75d8fe@cloudshell:~ (qwiklabs-gcp-03-b5e575611d87)$ gcloud container clusters create io

  • Github repoでは、Gitrepoからクローン化されたこの実習に必要なプロファイルが公開されています.

  • Pod creation
    Podの内容についてkubernetesの核心として、1つ以上の容器の集合である.導入の一部として、ライフサイクル管理の一部として使用されます.
    コンテナ間に強い依存性がある場合は、パッケージ化して単一podに配置します.
    apiVersion: v1
    kind: Pod
    metadata:
      name: monolith
      labels:
        app: monolith
    spec:
      containers:
        - name: monolith
          image: kelseyhightower/monolith:1.0.0
          args:
            - "-http=0.0.0.0:80"
            - "-health=0.0.0.0:81"
            - "-secret=secret"
          ports:
            - name: http
              containerPort: 80
            - name: health
              containerPort: 81
          resources:
            limits:
              cpu: 0.2
              memory: "10Mi"
    このyamlファイルでは3つの事実を確認できます.

  • 全体と呼ばれる容器からなる

  • コンテナが起動するとargsがいくつか渡されます.

  • 80番ポートを開いてHTTPトラフィックを制御します.
    このyamlファイルをkuberクラスタのリソースとして使用して生成されるcmdは、次のようになります.kubectl create -f pods/monolith.yaml
    student_00_f2561c75d8fe@cloudshell:~/orchestrate-with-kubernetes/kubernetes (qwiklabs-gcp-03-b5e575611d87)$ kubectl get pods
    NAME                    READY   STATUS    RESTARTS   AGE
    monolith                1/1     Running   0          11s
    nginx-56cd7f6b6-w7rfx   1/1     Running   0          5m37s

  • Podとのインタラクション
    デフォルトではpodはprivate ip addressとして生成されるため、kubectl port-forwardコマンドを使用してローカルポートをクラスタ内部のポートと一致させる必要があります.
    student_00_f2561c75d8fe@cloudshell:~/orchestrate-with-kubernetes/kubernetes (qwiklabs-gcp-03-b5e575611d87)$ kubectl port-forward monolith 10080:80
    Forwarding from 127.0.0.1:10080 -> 80
    設定されていない予期せぬセキュリティエンドポイントにcurlをリクエストしてみました.
    student_00_f2561c75d8fe@cloudshell:~/orchestrate-with-kubernetes/kubernetes (qwiklabs-gcp-03-b5e575611d87)$ curl http://127.0.0.1:10080/secure
    authorization failed
    やっぱり権限失敗
    curl-u user http://127.0.0.1:10080/loginうん。でアクセスし、スーパー秘密パスワード「password」でログインしたことがあります.
    student_00_f2561c75d8fe@cloudshell:~/orchestrate-with-kubernetes/kubernetes (qwiklabs-gcp-03-b5e575611d87)$ curl -u user http://127.0.0.1:10080/login
    Enter host password for user 'user':
    {"token":"eyJh이하생략"}
    コインを発行し、
    これをENVにしましょうこの環境変数に格納されているトークンを持って、/secure urlに再アクセスします.
    student_00_f2561c75d8fe@cloudshell:~/orchestrate-with-kubernetes/kubernetes (qwiklabs-gcp-03-b5e575611d87)$ curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:10080/secure
    {"message":"Hello"}
    私もhello~

  • container bashに直接アクセスし、コンテナでpingをテストします.
    kubectl exec monolith --stdin --tty -c monolith /bin/sh
    
    tudent_00_f2561c75d8fe@cloudshell:~/orchestrate-with-kubernetes/kubernetes (qwiklabs-gcp-03-b5e575611d87)$ kubectl exec monolith --stdin --tty -c monolith /bin/sh
    kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
    /
    / # ping -c 3 google.com
    PING google.com (172.253.119.101): 56 data bytes
    64 bytes from 172.253.119.101: seq=0 ttl=114 time=0.924 ms
    64 bytes from 172.253.119.101: seq=1 ttl=114 time=0.860 ms
    64 bytes from 172.253.119.101: seq=2 ttl=114 time=0.972 ms

  • Service creation
    Podは永続的なリソースではありません.これはliveness/rednessチェックにより、構成に失敗したときにすぐに再作成されるステータスレスリソースです.
    したがって、podに一定のipアドレスでアクセスすることを保証するために、podに継続的に貼り付けるために、サービスというリソースを作成することができる.
    3つのタイプがあり、

  • クラスタIP:このサービスはクラスタでのみ表示されます

  • NodePort:クラスタ内の各ノードが外部からアクセスできるようにします.

  • LoadBalancer:CloudProviderが提供するLoad Balancerタイプで、LBでサービス→Nodeにトラフィックサービスを提供します.
    サービスを作成すると、露出したnodepotを介して通信できるようにファイアウォールルールが作成されます.
    student_00_f2561c75d8fe@cloudshell:~/orchestrate-with-kubernetes/kubernetes (qwiklabs-gcp-03-b5e575611d87)$ gcloud compute firewall-rules create allow-monolith-nodeport \
    >   --allow=tcp:31000
    
    Creating firewall...working..Created [https://www.googleapis.com/compute/v1/projects/qwiklabs-gcp-03-b5e575611d87/global/firewalls/allow-monolith-nodeport].
    Creating firewall...done.
    NAME: allow-monolith-nodeport
    NETWORK: default
    DIRECTION: INGRESS
    PRIORITY: 1000
    ALLOW: tcp:31000
    DENY:
    DISABLED: False
    サービスが露呈し、ファイアウォールのルールも制定された.
    student_00_f2561c75d8fe@cloudshell:~/orchestrate-with-kubernetes/kubernetes (qwiklabs-gcp-03-b5e575611d87)$ curl -k https://34.71.149.193:31000
    curl: (7) Failed to connect to 34.71.149.193 port 31000: Connection refused
    外部ipのポートにアクセスすると、接続障害が発生します.どうして.
    最初にこのサービスを作成するとapp=monolithisというlabelセレクタでpodを選択してpodのトラフィックを固定しますが、実際にはpodにはlabelはありません
    今podにラベルを貼って、サービスがpodを正しく認識できるようにします.
    student_00_f2561c75d8fe@cloudshell:~/orchestrate-with-kubernetes/kubernetes (qwiklabs-gcp-03-b5e575611d87)$ kubectl label pods secure-monolith 'secure=enabled'
    pod/secure-monolith labeled
    student_00_f2561c75d8fe@cloudshell:~/orchestrate-with-kubernetes/kubernetes (qwiklabs-gcp-03-b5e575611d87)$ curl -k https://34.71.149.193:31000
    {"message":"Hello"}
    うん、よかった、満足!
    Deployment
    導入の2種類
    Rolling Update
    新しいレプリカセットを作成し、新しいレプリカセットの数を徐々に増やし、古いレプリカセットの数を徐々に減らします.
    最小限のコスト、最小限のパフォーマンスの影響、および最小限のダウンタイムが有益です.

  • Canary Update
    完全に分離されたデプロイメントを作成し、ある瞬間にサービスのターゲットをnewデプロイメントに変更します.

    Blue-Green deployments
    クバーネディスはスクロール更新を実行します/oldにblue version、newにgreen versionタグを追加します.

    注記)Googleクラウドの未理解領域と領域(Googleクラウドの領域/領域概念)


    Certain Compute Engine resources live in regions or zones. A region is a specific geographical location where you can run your resources. Each region has one or more zones. For example, the us-central1 region denotes a region in the Central United States that has zones  us-central1-aus-central1-bus-central1-c , and  us-central1-f .

    Resources that live in a zone are referred to as zonal resources. Virtual machine Instances and persistent disks live in a zone. To attach a persistent disk to a virtual machine instance, both resources must be in the same zone. Similarly, if you want to assign a static IP address to an instance, the instance must be in the same region as the static IP.