1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Kubernetes 入門1

1
Last updated at Posted at 2025-05-25

Kubernetesとは

Kubernetesはコンテナオーケストレーションプラットフォームです。Kubernetesはコンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するためのオープンソースシステムです。

Kubernetesの主な機能:

  • コンテナのオーケストレーション(配置、スケジューリング)
  • アプリケーションのスケーリング(自動水平/垂直スケーリング)
  • サービスディスカバリとロードバランシング
  • ストレージオーケストレーション
  • 自己修復機能(障害発生時の自動再起動や置き換え)
  • シークレットと構成管理
  • ローリングアップデートとロールバック

Kubernetesは「K8s」と略されることも多く、現代のクラウドネイティブアプリケーション開発とデプロイにおいて業界標準となっています。
なぜKubernetesを使うのかというと、自前で複数ホストと複数コンテナを管理するのが難しいから。

Docker RunやDocker Composeと比較したKubernetesの利点について

Docker Runは単一のコンテナを起動するための基本的なコマンドで、Docker Composeは複数コンテナで構成されるアプリケーションを単一ホスト上で管理するツールです。一方、Kubernetesはこれらと比較して以下の理由で使用されます:

スケーラビリティ

  • Docker Run/Compose: 主に単一ホスト向けで、マルチホスト環境での管理は複雑
  • Kubernetes: 複数ノードにわたる大規模クラスタを効率的に管理し、数千のコンテナまでスケール可能

高可用性

  • Docker Run/Compose: 高可用性機能が限定的
  • Kubernetes: ノード障害時の自動復旧、ポッドの再スケジューリング、自己修復機能を提供

デプロイ管理

  • Docker Run/Compose: 複雑なデプロイ戦略の実装が困難
  • Kubernetes: ローリングアップデート、カナリアデプロイ、ブルー/グリーンデプロイなどの高度な戦略をサポート

ロードバランシング

  • Docker Run/Compose: 基本的なロードバランシングのみ
  • Kubernetes: サービスディスカバリと内蔵ロードバランサーで複雑な通信をシームレスに管理

リソース管理

  • Docker Run/Compose: リソース制限はあるが、動的配分は限定的
  • Kubernetes: CPUやメモリの詳細な割り当て、QoS、オートスケーリング機能を提供

モニタリングと管理

  • Docker Run/Compose: 基本的なログとモニタリング
  • Kubernetes: 包括的なモニタリング、ロギング、アラート機能と豊富なエコシステム

Docker Run/Composeは小〜中規模の開発環境やシンプルなアプリケーションに適していますが、Kubernetesは本番環境での大規模デプロイ、高可用性要件、複雑なマイクロサービスアーキテクチャに適しています。

Minikubeを使用してローカル環境でKubernetesを動かす

Minikubeはローカル環境でKubernetesを簡単に実行するためのツールです。Kubernetesを試したり日々の開発への使用を検討するユーザー向けに、PC上のVM内でシングルノードのKubernetesクラスターを実行することができます。

brew install kubectl
brew install minikube

クラスターを起動

minikube start

image.png

ステータスを確認

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

クラスタのバージョンを確認

kubectl version

kubectlコマンドは、Kubernetesクラスターと対話するための公式コマンドラインツールです。

Client Version: v1.30.5
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.32.0
WARNING: version difference between client (1.30) and server (1.32) exceeds the supported minor version skew of +/-1

クラスタの正常性確認

kubectl cluster-info
kubectl get componentstatuses

クラスタのノード(物理/仮想マシン)一覧の表示
ノードとは、Kubernetesクラスター内の作業マシン(ワーカーマシン)のことです。

kubectl get nodes

クラスタのノード(物理/仮想マシン)詳細情報を表示

kubectl describe nodes

役立つツールとコマンド

  • watch''で囲んだコマンドを2秒ごとに実行してくれる

    brew install watch
    
    watch -t 'kubectl get pod'
    # 詳細な方
    watch 'kubectl get pod,svc -o wide'
    
  • batコマンド

    brew install bat
    
    bat pod.yaml
    bat Dockerfile
    

    image.png

Podとは?

Podとは、Kubernetesにおける最小のデプロイ単位であり、1つ以上のコンテナをグループ化して管理するための概念です。

  1. コンテナのグループ

    通常は単一のアプリケーションを表す1つのメインコンテナと、オプションの補助的なコンテナ(サイドカー)で構成
    同一Podの複数コンテナは常に同一ノード上でスケジュールされる

  2. 共有リソース

    Pod内のコンテナは同じネットワーク名前空間を共有(localhost経由で通信可能)
    同じIPアドレスとポート空間を共有
    共有ストレージボリュームにアクセス可能

Podは「論理的なホスト」と考えることができ、密接に関連するコンテナをまとめ、従来のVMに似た環境を提供します。ただし、Podは永続的な存在ではなく、再作成される可能性があるため、ステートレスな設計が推奨されます。

Podを使ってHello WorldをK8sにDeployしよう

  1. Hello WorldのPodを起動

    kubectl run --image gcr.io/google-samples/hello-app:1.0 --restart Never helloworld
    
  2. Podの表示

    kubectl get pods
    
    NAME         READY   STATUS    RESTARTS   AGE
    helloworld   1/1     Running   0          28s
    
  3. Podないのコンテナのログを表示

    kubectl logs helloworld
    
  4. Podのメタデータを表示

    kubectl describe pod helloworld
    
    # Pod の基本識別情報
    Name:             helloworld                    # Pod の名前(この Pod を識別するための名前)
    Namespace:        default                       # Pod が属するネームスペース(リソースをグループ分けする仕組み)
    Priority:         0                            # Pod の優先度(0が最低、数値が高いほど優先される)
    Service Account:  default                      # Pod が使用するサービスアカウント(権限管理用)
    
    # Pod が動作している物理的な場所
    Node:             minikube/192.168.49.2        # Pod が配置されているノード(サーバー)の名前とIPアドレス
    Start Time:       Sun, 25 May 2025 17:31:07 +0900  # Pod が開始された日時
    
    # Pod の分類・管理用ラベル
    Labels:           run=helloworld               # Pod に付けられたラベル(検索や管理に使用)
    Annotations:      <none>                       # Pod に付けられた注釈情報(現在は未設定)
    
    # Pod の現在の状態
    Status:           Running                      # Pod の実行状態(Running = 正常に動作中)
    
    # ネットワーク関連の設定
    IP:               10.244.0.6                  # Pod に割り当てられた内部IPアドレス
    IPs:                                          # Pod が持つIPアドレスの一覧
     IP:  10.244.0.6                           # 同上(複数IP対応のため配列形式)
    
    # Pod 内のコンテナ情報
    Containers:                                   # Pod に含まれるコンテナの一覧
     helloworld:                                # コンテナの名前
       Container ID:   docker://bceef2d5e09710e621489bba7fdcda458ca29d66da27474bedefbabe09b14c06  # コンテナの一意識別子
       Image:          gcr.io/google-samples/hello-app:1.0  # 使用しているDockerイメージ
       Image ID:       docker-pullable://gcr.io/google-samples/hello-app@sha256:173d532964a8cfd250b01878a46c18ccb303bcf21855b0fb9ac445bc486d1dbc  # イメージの詳細識別子
       Port:           <none>                    # コンテナが公開するポート(未設定)
       Host Port:      <none>                   # ホスト側のポート(未設定)
       State:          Running                  # コンテナの実行状態
         Started:      Sun, 25 May 2025 17:31:07 +0900  # コンテナが開始された日時
       Ready:          True                     # コンテナがリクエストを受け付ける準備ができているか
       Restart Count:  0                        # コンテナが再起動された回数(0 = 安定している)
       Environment:    <none>                   # 環境変数の設定(現在は未設定)
       Mounts:                                  # コンテナにマウントされたボリューム
         /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-zxqt6 (ro)  # Kubernetes API へのアクセス用トークン(読み取り専用)
    
    # Pod の健全性チェック結果
    Conditions:                                  # Pod の各種状態チェック結果
     Type                        Status         # チェック項目とその結果
     PodReadyToStartContainers   True          # コンテナ開始準備完了
     Initialized                 True          # 初期化完了
     Ready                       True          # サービス提供準備完了
     ContainersReady             True          # 全コンテナが準備完了
     PodScheduled                True          # ノードへの配置完了
    
    # ストレージ関連の設定
    Volumes:                                     # Pod が使用するボリューム
     kube-api-access-zxqt6:                    # ボリューム名
       Type:                    Projected (a volume that contains injected data from multiple sources)  # 複数のデータソースを統合したボリューム
       TokenExpirationSeconds:  3607           # APIアクセス用トークンの有効期限(秒)
       ConfigMapName:           kube-root-ca.crt  # 使用するConfigMap名
       ConfigMapOptional:       <nil>          # ConfigMapが必須かどうか
       DownwardAPI:             true           # Pod情報をファイルとして公開するか
    
    # リソース使用に関する設定
    QoS Class:                   BestEffort     # サービス品質クラス(BestEffort = 最低限の保証)
    
    # Pod配置に関する設定
    Node-Selectors:              <none>         # 特定ノードを選択する条件(未設定)
    Tolerations:                               # ノードの問題を許容する設定
     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s      # ノードが準備未完了でも300秒間は実行継続
     node.kubernetes.io/unreachable:NoExecute op=Exists for 300s    # ノードが到達不能でも300秒間は実行継続
    
    # Pod に関するイベント履歴
    Events:                                    # Pod で発生したイベントの履歴
     Type    Reason     Age   From               Message
     ----    ------     ----  ----               -------
     Normal  Scheduled  85s   default-scheduler  Successfully assigned default/helloworld to minikube  # Pod がノードに正常に配置された
     Normal  Pulled     85s   kubelet            Container image "gcr.io/google-samples/hello-app:1.0" already present on machine  # イメージが既にローカルに存在
     Normal  Created    85s   kubelet            Created container: helloworld  # コンテナが正常に作成された
     Normal  Started    85s   kubelet            Started container helloworld  # コンテナが正常に開始された 
    
  5. Pod内のコンテナの環境変数を定義

    kubectl run --env TEST_ENV=hellow_world \
        --image gcr.io/google-samples/hello-app:1.0 \
        --restart Never helloworld
    

    以下のコマンドで設定したENVを確認できる。

    kubectl describe pod helloworld
    

    image.png

  6. Podを削除

    kubectl delete pod helloworld
    
  7. ubuntuのイメージで作られたubuntuという名前のPodを作成し、起動し続ける。そしてコンテナに入る。

    kubectl run ubuntu --image=ubuntu --restart Never -- sleep infinity
    
    # コンテナの中に入る
    kubectl exec -it ubuntu -- bash
    

    各パラメータの回詳細説明

    kubectl run
    # 意味:新しいPodを作成して実行する基本コマンド
    # 類似:docker run(Dockerでコンテナを実行するのと似ている)
    
    ubuntu
    # 意味:作成するPodの名前
    # 結果:Pod名が「ubuntu」になる
    # 確認:kubectl get pods で「ubuntu」という名前で表示される
    
    --image=ubuntu
    # 意味:使用するDockerイメージを指定
    # ubuntu:Ubuntu Linux の公式イメージ
    # 取得元:Docker Hub から自動でダウンロード
    # 類似:docker run ubuntu と同じイメージを使用
    
    --restart Never
    # 意味:Podが終了しても再起動しない設定
    # Never:一度だけ実行(ジョブのような動作)
    # 対比:Always(常に再起動)、OnFailure(失敗時のみ再起動)
    
    -- sleep infinity
    # コンテナが終了せずに起動し続ける
    

Serviceとは?

ServiceはPodをクラスター内外に公開する静的IPを持ったL4ロードバランサーです。
クラスター内外からPodへの安定的なアクセスを提供できる仮想のIPアドレスをServiceに割り当てます。
いつ消えるかわからないPodのIPを覚えておく必要がなくなる。

ClusterIP Service

ClusterIPのServiceを使う利点は、いつ消えるかわからないPodIPを抽象化し、StaticIPを持ったProxyを前に置くことで:

  • Podにアクセスする際に、Pod IPを知る必要がなくなる
  • Podにアクセスする際に、ロードバランスしてくれる
    ことです。

コマンド

  1. 'Helloworld'PodをClusterIPのServiceとしてクラスタ内部で公開

    kubectl expose pod helloworld --type ClusterIP --port 8080 --name hellowworld-clusterip
    
  2. Serviceをリストアップ

    kubectl get service
    
  3. クラスターないにCurlコンテナのPodを作成しシェル接続

    kubectl run --restart Never --image curlimages/curl:7.68.0 -it --rm curl sh
    
  4. helloworld-clusterip ClusterIP serviceへCurlでアクセステスト

    curl helloworld-clusterip:8080
    

    レスポンス

    Hello, world!
    Version: 1.0.0
    Hostname: helloworld
    

NodePort Serviceとは

NodePort Serviceを使う利点は、ClusterIPでは不可能だったクラスター街へのPodの公開を、NodeIPとNodePort経由で可能にすること。

  1. helloworld-nodeportという名前で NodePortのServiceを作成。

    kubectl expose pod helloworld --type NodePort --port 8080 --name helloworld-nodeport
    
  2. 外部からの接続確認

    minikube service helloworld-nodeport
    
        |-----------|---------------------|-------------|---------------------------|
    | NAMESPACE |        NAME         | TARGET PORT |            URL            |
    |-----------|---------------------|-------------|---------------------------|
    | default   | helloworld-nodeport |        8080 | http://192.168.49.2:30724 |
    |-----------|---------------------|-------------|---------------------------|
    🏃  helloworld-nodeport サービス用のトンネルを起動しています。
    |-----------|---------------------|-------------|------------------------|
    | NAMESPACE |        NAME         | TARGET PORT |          URL           |
    |-----------|---------------------|-------------|------------------------|
    | default   | helloworld-nodeport |             | http://127.0.0.1:52965 |
    |-----------|---------------------|-------------|------------------------|
    🎉  デフォルトブラウザーで default/helloworld-nodeport サービスを開いています...
    ❗  Docker ドライバーを darwin 上で使用しているため、実行するにはターミナルを開く必要があります。
    

    以下で動作確認できた。
    http://127.0.0.1:52965

NodePortのServiceでクラスター外にPodを公開できるが、NodeIPやNode Portを知らないといけないという問題がある。

LoadBalancer Serviceとは

クラウドプロバイダのL4ロードバランサーのDNSから、各ノードの特定のポートにRoutingしてPodにアクセスする。

  1. ロードバランサーのserviceを作成。
    kubectl expose pod helloworld --type LoadBalancer --port 8080 --name helloworld-lb
    

LoadBalanserサービスにも問題があるので実際はL7のIngressを使う。

LoadBalancer:

  • L4(TCP/UDP)レベル
  • シンプルだが高コスト
  • 1サービス = 1ロードバランサー

Ingress:

  • L7(HTTP/HTTPS)レベル
  • 複雑だが低コスト
  • 1つのロードバランサーで複数サービス

L4 vs L7 の違い

L4(トランスポート層)

  • TCP/UDP レベルの負荷分散
  • IPアドレス + ポート番号で判断
  • 中身を見ない(HTTPの内容は無視)

L7(アプリケーション層)

  • HTTP/HTTPS レベルの負荷分散
  • URL、ヘッダー、Cookieなどで判断
  • 中身を理解(リクエストの詳細を解析)

具体例

L4の判断基準

192.168.1.100:80 → サーバーA
192.168.1.100:443 → サーバーB
# IPとポートのみで振り分け

L7の判断基準

example.com/api → APIサーバー
example.com/web → Webサーバー  
example.com/admin → 管理サーバー
# URLパスで振り分け
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?