Upgrade to Pro — share decks privately, control downloads, hide ads and more …

kubernetes入門

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Cybozu Cybozu PRO
July 26, 2024
12k

 kubernetes入門

Avatar for Cybozu

Cybozu PRO

July 26, 2024
Tweet

More Decks by Cybozu

Transcript

  1. 目次 (前半) ▌ コンテナオーケストレーションの必要性 ▌ Kubernetesとは ▌ サイボウズとKubernetes ▌ Kubernetesの構造と動作

    ▌ Kubernetesの代表的なリソース ▌ Kubernetesクラスタへのアクセス (後半) ▌ 実際にKubernetesクラスタに触れてみる 2
  2. Kubernetesとは ▌ コンテナを複数のサーバー上で協調動作、管理するためのシステム(=コンテナオーケストレーション) ▌ Googleの社内で使用していた「borg」を元にして作られた 主要な機能 ⚫ 宣言的なリソースの管理 ⚫ 「あるべき状態」を定義する

    ⚫ スケジューリング ⚫ アプリケーションを複数のサーバーに適切にスケジュールする ⚫ サービスディスカバリーと負荷分散 ⚫ アプリケーション間の通信を容易にし、負荷分散を可能にする ⚫ セルフヒーリング ⚫ コンテナに障害が発生した際の自動回復 5
  3. Kubernetesが解決する問題 ▌ 運用の自動化 ⚫ デプロイのたびに煩雑なオペレーションを行わなくて済む ▌ 高可用性 ⚫ ローリングアップデート ⚫

    障害が発生したときの自動回復 ⚫ 負荷分散 ▌ サーバ群の抽象化 ⚫ ユーザはサーバ1個1個のことを考えずに、大量のサーバー上にアプリケーションをデ プロイできる 6
  4. Kubernetesの構造 9 control-plane クラスタを管理するためのコンポーネントの総称 • etcd • kube-apiserver • kube-scheduler

    • kube-controller-manager Node アプリケーションがデプロイされるサーバ(数台~数千台) • kubelet • kube-proxy CLIツールやプログ ラム等からの操作
  5. コントロールプレーンコンポーネント ▌ etcd • 分散KVS • リソースの情報が保存される ▌ kube-apiserver •

    リソースにアクセスするためのAPIサーバ • ユーザーや各コンポーネントからの操作はすべてkube-apiserverを経 由する • etcdに保存された情報を用いる ▌ kube-scheduler • 作成されたPod*をどのNodeに配置するかを決定する • *Pod:アプリケーションをデプロイする単位のこと(後で説明) • 配置には様々な条件式や設定が存在する ▌ kube-controller-manager • リソースの状態を管理するコンポーネント • リソースの状態を監視し、あるべき状態になるように操作する 10
  6. 宣言的な構成管理 ▌ Kubernetesはリソースの「あるべき状態」をmanifestで定義し、システムはそれを 満たすように動作する(=reconcile) 14 apiVersion: apps/v1 kind: Deployment metadata:

    name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 Deploymentリソースの定義 app:nginxのラベルがついたPodが3個必要 Podリソースの定義 Nginxのコンテナを動かし、80番ポート を使う ※PodやDeploymentの概念は後で説明します ※例 手続的 宣言的 シェルスクリプトで作った インストールスクリプト Kubernetesのmanifest
  7. Pod ▌ アプリケーションをデプロイするための最小単位 ⚫ 1個以上のコンテナをまとめたもの ▌ Pod毎にIPアドレスを持ち、各コンテナはnetwork namespaceを共有する ▌ PID

    namespaceはコンテナ毎に別々(共有することも 可能) ▌ ファイルシステムもコンテナ毎に別々 17 よくある使い方 • アプリケーションのコンテナ • Proxyなどのコンテナ • メトリクスやログを取るコンテナ をまとめてPodにする
  8. Podのmanifest ▌ .spec以下にPodの設定を書く ▌ .spec.containers[]の配列にコンテナの設定を 書いていく ▌ .spec.containers[].commandがDockerの ENTRYPOINTに相当する 18

    apiVersion: v1 # リソースが属するグループの名前 kind: Pod # リソースの種類 metadata: name: my-pod # Podの名前 spec: containers: # コンテナの設定 - name: container-1 # 1つめのコンテナの設定 image: ubuntu:latest command: ["sleep", "infinity"] - name: container-2 # 2つめのコンテナの設定 image: ubuntu:latest command: ["sleep", "infinity"]
  9. ReplicaSet & Deployment ▌ ReplicaSet ⚫ 負荷分散・可用性のために、複数のPodをまとめたもの ⚫ ※Replicaset単体で使う事はほぼない ▌

    Deployment ⚫ ReplicaSetを用いてローリングアップデートの機能などを提供 する ▌ ReplicaSetのセルフヒーリング ⚫ ReplicaSetは指定した数のPodが動作することを保証する ⚫ Node故障などでPodが消されると、新しく作り直す 21 Nodeの故障などでPodを作り直す例
  10. Deploymentのマニフェスト 23 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec:

    replicas: 3 # Podのレプリカ数 selector: matchLabels: # app:nginxのラベルを持つPodを配下にする app: nginx template: # 作成するPodのテンプレート metadata: labels: app: nginx # app:nginxのラベルをつける spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ▌ .spec以下にDeploymentの設定を書く ▌ .spec.replicsasがレプリカ数の設定 ▌ .spec.selectorで配下にするPodの指定をする ▌ .spec.templateにPodのテンプレートを書く
  11. Service ▌ Podとの通信を抽象化する ▌ 負荷分散の機能を持つ ▌ Podと通信をする時に、Podの名前やIPアドレスの直接指定は基本的にしない ⚫ Podのライフサイクルは短いので、IPアドレスはすぐに変わる ⚫

    特定のPodではなく、「ある機能を持つPodのどれか」で指定したい ▌ 4つのタイプがある ⚫ ClusterIP: クラスタ内のみでアクセスできる ⚫ NodePort: 各Nodeの指定したポートに来たトラフィックをPodに転送する ⚫ LoadBalancer: 外部のロードバランサーを利用してトラフィックを転送する ⚫ ExternalName:クラスタ外のドメインをServiceのCNAMEに登録する NodePort,LoadBalancerを使うことでクラスタ外からのアクセスを受け付けられる 24
  12. Serviceのmanifest 25 apiVersion: v1 kind: Service metadata: name: nginx-service spec:

    type:ClusterIP # Serviceのtypeを指定する selector: app: nginx # app:nginxのラベルを持つPodにトラフィックを流す ports: - protocol: TCP port: 80 # Serviceが公開するポート targetPort: 80 # トラフィックを流す先のPodのポート apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 # Podのレプリカ数 selector: matchLabels: # app:nginxのラベルを持つPodを配下にする app: nginx template: # 作成するPodのテンプレート metadata: labels: app: nginx # app:nginxのラベルをつける spec: containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ↓のDeploymentに対するService .spec.typeでServiceのtypeを ClusterIP, NodePort, LoadBalancer, ExternalName から選ぶ .spec.selectorで対象のPodを選択する .spec.portsでプロトコルやポートの設定を行う
  13. Serviceのmanifest 先ほどのmanifestの例を挙げると・・・ nginx-service.default.svc.cluster.local:80 にアクセスが来ると、配下のnginxのPodにトラフィックが振り分けられる ▌ Nodeの障害などでPodが減った場合、そのPodは振り分け先から 自動的に外される ▌ Deploymentのセルフヒーリングによって新たにPodが作られた場合、 振り分け先に自動的に追加される

    26 apiVersion: v1 kind: Service metadata: name: nginx-service spec: type:ClusterIP # Serviceのtypeを指定する selector: app: nginx # app:nginxのラベルを持つPodにトラフィックを流す ports: - protocol: TCP port: 80 # Serviceが公開するポート targetPort: 80 # トラフィックを流す先のPodのポート
  14. kubectl ▌ Kubernetesクラスタを操作するためのCLIツール よく使うコマンド ▌ リソースの状態の取得(一覧) ⚫ kubectl get <リソース名>

    kubectl get pod ▌ リソースの状態の取得(個別) ⚫ kubectl get <リソース名> <名前> ⚫ 例:kubectl get pod example-pod ▌ manifestの適用 ⚫ kubectl apply –f <ファイル名> ⚫ 例: kubectl apply –f example-pod.yaml 30
  15. 実際にKubernetesクラスタを作って操作してみる ▌ kindというソフトウェアで、ローカル環境にKubernetesクラスタを作ることができる ▌ DockerコンテナでKubernetesノードを動かし、その中でコンテナが動作する (Docker in Docker) 32 https://kind.sigs.k8s.io/

    この章では、以下の資料の一部をかいつまんで説明します。 https://cybozu.github.io/introduction-to- kubernetes/introduction-to-kubernetes.html 興味のある方はご自身の環境でも試してみてください
  16. クラスタの立ち上げ $ kind create cluster でシングルノードのクラスタが立ち上がる Configを書いて指定すると複数ノードも可能 33 ❯ kind

    create cluster Creating cluster "kind" ... ✓ Ensuring node image (kindest/node:v1.27.3) ✓ Preparing nodes ✓ Writing configuration ✓ Starting control-plane ✓ Installing CNI ✓ Installing StorageClass Set kubectl context to "kind-kind" You can now use your cluster with: kubectl cluster-info --context kind-kind Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community
  17. クラスタの確認 34 ❯ kubectl get node NAME STATUS ROLES AGE

    VERSION kind-control-plane Ready control-plane 2m31s v1.27.3 $ kubectl get node でノード一覧を取得 1ノード作られていることがわかる
  18. Podをデプロイしてみる 35 apiVersion: v1 kind: Pod metadata: name: my-first-pod labels:

    component: nginx spec: containers: - name: nginx image: nginx:latest $ kubectl apply –f nginx-pod.yaml でmanifestを適用する ❯ kubectl apply -f nginx-pod.yaml pod/my-first-pod created # Podの名前 # コンテナの名前 # Podにつけるラベル # コンテナイメージ nginx-pod.yaml
  19. デプロイしたPodの確認 36 ❯ kubectl get pod NAME READY STATUS RESTARTS

    AGE my-first-pod 1/1 Running 0 3m47s ❯ kubectl exec -it my-first-pod -- bash root@my-first-pod:/# curl -i localhost:80 HTTP/1.1 200 OK Server: nginx/1.25.4 … $ kubectl get pod でpod一覧を取得 $ kubectl execでPodの中に入りシェルを実行、curlでnginxの動作を確認 ← my-first-podが作られている
  20. Podとの通信① 37 apiVersion: v1 kind: Pod metadata: name: bastion spec:

    containers: - name: bastion image: debian:stable command: ["sleep", "infinity"] Pod間の通信を行う方法 ①PodのIPアドレスを使う ②ServiceのClusterIPを使う ←まずはこちらを試す bastion.yaml $ kubectl apply -f bastion.yaml でmanifst適用 Bastion Pod nginx Pod Kubernetesクラスタ HTTP
  21. Podとの通信① 38 ❯ kubectl get pod -o wide NAME READY

    STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES bastion 1/1 Running 0 116m 10.244.0.6 kind-control-plane <none> <none> my-first-pod 1/1 Running 0 136m 10.244.0.5 kind-control-plane <none> <none> ❯ kubectl exec -it bastion -- bash root@bastion:/# apt update && apt install -y curl root@bastion:/# curl -i http://10.244.0.5 HTTP/1.1 200 OK Server: nginx/1.25.4 NginxのPodのIPアドレスは10.244.0.5 $ kubectl get pod でpod一覧を取得 $ kubectl execでbastion Podの中に入りシェルを実行、curlでnginx PodのIPアドレスにリクエストしてみる Bastion Pod nginx Pod Kubernetesクラスタ curl 10.244.0.5 10.244.0.5 10.244.0.6
  22. Podとの通信② 40 apiVersion: v1 kind: Service metadata: name: my-first-service spec:

    selector: component: nginx ports: - protocol: TCP port: 80 targetPort: 80 nginx-service.yaml #ここで設定したラベルを持つPod にトラフィックが振り分けられる 同様にこのmanifestを適用して Serviceをデプロイする Bastion Pod nginx Pod Kubernetesクラスタ Service
  23. Podとの通信② 41 ❯ kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP

    PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 160m my-first-service ClusterIP 10.96.207.133 <none> 80/TCP 4s ❯ kubectl exec -it bastion -- bash root@bastion:/# curl -i http://my-first-service/ HTTP/1.1 200 OK Server: nginx/1.25.4 $ kubectl execでbastion Podの中に入りシェルを実行 今度はservice名でリクエストを行う ※Kubernetes内にServiceのIPアドレスと名前を解決するDNSがあるので、Serviceの名前でアクセスできる Serviceが作られている
  24. 同じ Pod をいくつも立てる ▌ 前の節のように、複数の同じPodで冗 長構成にするのが一般的 ▌ ReplicaSetを用いて同じPodを指定 しただけ作る この例では、

    「component: nginxのラベルを持つ Podを3個デプロイする」 ということになる 42 apiVersion: apps/v1 kind: ReplicaSet metadata: name: nginx-replicaset labels: component: nginx spec: replicas: 3 selector: matchLabels: component: nginx template: metadata: labels: component: nginx spec: containers: - name: nginx image: nginx:latest nginx-replicaset.yaml #Podの数 #ここに一致した条件のPodをReplicaSetが管理する # Podのテンプレート
  25. デプロイしたReplicaSetの確認 43 ❯ kubectl get replicaset NAME DESIRED CURRENT READY

    AGE nginx-replicaset 3 3 3 7s ❯ kubectl get pod NAME READY STATUS RESTARTS AGE bastion 1/1 Running 0 149m my-first-pod 1/1 Running 0 169m nginx-replicaset-29jmp 1/1 Running 0 10s nginx-replicaset-8ph49 1/1 Running 0 10s 「component: nginxのラベルを持つPod」はすでに1個あったので、追加で2個作成される その際、Podの定義はtemplateに書いた内容が使われる
  26. ReplicaSetの動作の確認 44 ❯ kubectl delete pod my-first-pod pod "my-first-pod" deleted

    ❯ kubectl get pod NAME READY STATUS RESTARTS AGE bastion 1/1 Running 0 152m nginx-replicaset-29jmp 1/1 Running 0 2m51s nginx-replicaset-8ph49 1/1 Running 0 2m51s nginx-replicaset-cvrv5 1/1 Running 0 4s 「component: nginxのラベルを持つPod」を1個消してみる(my-first-pod) 削除された分、新た1個のPodが作成される
  27. ReplicaSetの動作の確認 45 ❯ vim nginx-replicaset.yaml ❯ kubectl apply -f nginx-replicaset.yaml

    replicaset.apps/nginx-replicaset configured ❯ kubectl get pod NAME READY STATUS RESTARTS AGE bastion 1/1 Running 0 153m nginx-replicaset-29jmp 1/1 Running 0 3m43s nginx-replicaset-8ph49 1/1 Running 0 3m43s nginx-replicaset-btlk4 1/1 Running 0 3s nginx-replicaset-cvrv5 1/1 Running 0 56s nginx-replicaset.yamlのreplicasを4に変更する replicasが4になり1個足りないので、追加で1個Podがデプロイされる ReplicaSetは定義されたレプリカ数を維持するようにPodを増やしたり減らしたりする
  28. Deploymentの作成 47 前の章で作成したReplicaSetは消しておきます $kubectl delete replicaset nginx-replicaset apiVersion: apps/v1 kind:

    Deployment metadata: name: nginx-deployment labels: component: nginx spec: replicas: 3 selector: matchLabels: component: nginx template: metadata: labels: component: nginx spec: containers: - name: nginx image: nginx:1.20 nginx-deployment.yaml ManifestはReplicaSetとほぼ同じで、リソース名が Deploymentになっているだけ
  29. デプロイしたDeploymentの確認 48 ❯ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE

    AGE nginx-deployment 3/3 3 3 16s ❯ kubectl get pod -o 'custom- columns=NAME:.metadata.name,IMAGE:.spec.containers[*].image,PHASE:.status.phase' NAME IMAGE PHASE bastion debian:stable Running nginx-deployment-79b59fbc9b-k76vl nginx:1.20 Running nginx-deployment-79b59fbc9b-ppcbj nginx:1.20 Running nginx-deployment-79b59fbc9b-q5zgj nginx:1.20 Running ReplicaSetの時と同様、nginxのPodが3つデプロイされている ※実験のためコンテナイメージのバージョンを表示している
  30. ローリングアップデートしてみる 49 ❯ vim nginx-deployment.yaml ❯ kubectl apply -f nginx-deployment.yaml

    deployment.apps/nginx-deployment configured ❯ kubectl get pod -o 'custom-columns=NAME:.metadata.name,IMAGE:.spec.containers[*].image,PHASE:.status.phase' NAME IMAGE PHASE bastion debian:stable Running nginx-deployment-6566fcf8b5-bcl2s nginx:1.21 Pending nginx-deployment-79b59fbc9b-k76vl nginx:1.20 Running nginx-deployment-79b59fbc9b-ppcbj nginx:1.20 Running nginx-deployment-79b59fbc9b-q5zgj nginx:1.20 Running ❯ kubectl get replicaset NAME DESIRED CURRENT READY AGE nginx-deployment-6566fcf8b5 2 2 2 5m36s nginx-deployment-79b59fbc9b 2 2 1 6m52s コンテナイメージをnginx:1.20からnginx:1.21に書き換えて適用 新しいReplicaSetで1.21のPodが作られ、置き換えられていくことがわかる