Kubernetesは強力なコンテナオーケストレーションプラットフォームですが、その全ての機能を活用するためには、ポッドとサービスが基盤となる役割を果たしていることを理解することが重要です。この記事では、それらが何であり、どのように連携してKubernetesクラスター内で実行されているアプリケーションへのアクセスを公開および管理するかについて詳しく見ていきます。
ポッドとは何ですか?
ポッドは、Kubernetesで作成および管理できる最小のデプロイ可能なコンピューティングユニットです。
ポッドを作成する前に、Kubernetesクラスターで利用可能なAPIリソースを確認しましょう。これには、kubectl api-resources
コマンドを使用できます。このコマンドは、Kubernetes APIサーバーでサポートされているAPIリソースをリストアップし、それらの短い名前、APIグループ、および名前空間の有無を含めます。これは、カスタムリソースを使用したり新しいKubernetesの機能を探求する際に、クラスターの機能を理解するのに役立ちます。kubectl explain
コマンドは、個々のリソースに関する詳細情報を提供することでこれを補完します。
簡単なNginxコンテナを実行するポッドの基本的なポッド構成ファイルを作成してみましょう。
nginx-pod.yaml
という名前のファイルを作成してください。
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
使用されている用語の簡単な説明は以下の通りです:
- apiVersion: v1:APIバージョンを指定します。
- kind: Pod:この構成がポッド用であることを示します。
- metadata:name:ポッドの名前。
- メタデータ: ラベル: ポッドを整理し選択するために使用できるキーと値のペア。
- 仕様:コンテナ: ポッド内で実行されるコンテナのリスト。
- 仕様:コンテナ:名前: コンテナの名前。
- 仕様:コンテナ:イメージ: 使用するコンテナイメージ(この場合、最新のNginxイメージ)。
- 仕様:コンテナ:ポート: コンテナから公開するポート。
設定ファイルを適用してポッドを作成するには、kubectl
を使用します:
kubectl apply -f nginx-pod.yaml
ポッドのステータスを確認して、作成されて実行されていることを確認してください:
kubectl get pods
次のような出力が表示されるはずです:
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 10s
次に、ポッドを削除します:
kubectl delete pod nginx-pod
出力は次のようになります:
kubectl get pod
No resources found in default namespace.
サービスとは何ですか?
Kubernetes内のNginxポッドのためのサービスを作成することで、Nginxアプリケーションを公開し、クラスター内外からアクセスできるようにします。以下は、Nginxポッドのためのサービスを作成する手順です。
Nginxポッドが実行されていることを確認するために、まだ持っていない場合は、nginx-pod.yaml
という名前のYAMLファイルを作成します:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
ポッドの設定を適用します:
kubectl apply -f nginx-pod.yaml
`nginx-service.yaml` という名前の YAML ファイルを作成して、Service を定義します:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
いくつかの注意点:
- selector: Nginx Pod に一致するラベルセレクターです。
- app: nginx: これは Nginx Pod のラベルに一致する必要があります。
- type: ClusterIP: Service のタイプです。ClusterIP は Service をクラスター内のみでアクセス可能にします。NodePort または LoadBalancer を使用して Service を外部に公開することもできます。
Service 設定を kubectl
を使用して適用します:
kubectl apply -f nginx-service.yaml
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-service ClusterIP 10.96.0.1 <none> 80/TCP 10s
Service が ClusterIP タイプであるため、クラスター内でのみアクセス可能です。クラスターの外からアクセスするには、Service タイプを NodePort または LoadBalancer に変更できます。
Service を外部に公開するために NodePort
を使用するには、nginx-service.yaml
ファイルを修正します:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30007 # Specify a node port in the range 30000-32767 (optional)
type: NodePort
更新された Service 設定を適用します:
kubectl apply -f nginx-service.yaml
これで、ノードの IP アドレスとノードポートを使用して Nginx アプリケーションにアクセスできるようになります(例: http://<node-ip>:30007)。
マルチコンテナポッド
1つのポッドごとに1つのコンテナを使用すると、最大の細かい粒度と切り離しが提供されます。ただし、1つのポッド内に複数のコンテナ(時にはコンポジットコンテナとも呼ばれる)を展開すると有益なシナリオもあります。これらの副次的コンテナはさまざまな役割を果たすことができます:ログの処理や主要コンテナの拡張(サイドカーの概念)、外部システムへのプロキシとして機能する(アンバサダーの概念)、またはデータを外部形式に合わせる(アダプターの概念)。これらの副次的コンテナは、主要コンテナが処理しないタスクを実行することで主要コンテナを補完します。
以下は、Nginxサーバーを実行する主要コンテナとログの処理のためのサイドカーとして機能する副次的コンテナを含むKubernetesポッド構成の例です。サイドカーのコンテナは、NginxのアクセスログをテイルできるようにするためにBusyBoxのようなシンプルなログコンテナを使用しています。
apiVersion: v1
kind: Pod
metadata:
name: nginx-with-logging-sidecar
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
- name: log-sidecar
image: busybox:latest
command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
volumes:
- name: shared-logs
emptyDir: {}
その後、以下の手順を実行します:
- YAML構成をファイルに保存します。たとえば、
nginx-with-logging-sidecar.yaml
とします。 kubectl apply -f nginx-with-logging-sidecar.yaml
を使用して構成を適用します。- ポッドが実行されていることを確認します:
kubectl get pods
。 - サイドカーのコンテナのログをチェックして、Nginxのアクセスログを確認します:
kubectl logs -f <pod-name> -c log-sidecar
。
これらの手順に従うことで、既存のPodを削除し、新しい構成を適用して、Nginxコンテナとログ用のサイドカーコンテナを持つPodをセットアップします。これにより、新しい構成がKubernetesクラスター内でアクティブかつ稼働していることが保証されます。
Kubernetesのマルチコンテナポッドは、より柔軟で効率的なアプリケーションの展開と管理を可能にするいくつかの利点を提供します。
マルチコンテナポッドパターン
サイドカーパターン
サイドカーコンテナは、ログ記録、構成管理、またはプロキシなどの補助機能を提供することで、主要なアプリケーションを強化できます。このパターンは、主要なコンテナを変更することなく機能を拡張するのに役立ちます。サイドカーコンテナは、メインアプリケーションコンテナからのログを収集して転送することでログ処理を行うことができます。
アンバサダーパターン
アンバサダーコンテナは、プロキシとして機能し、主要なアプリケーションと外部サービス間の通信を管理します。これにより、統合と構成が簡素化されることがあります。アンバサダーコンテナは、SSL終端処理やAPIゲートウェイ機能を扱うことがあります。
アンバサダーパターンは、サイドカーコンテナを使用して主要なアプリケーションと外部サービス間の通信を管理することを含みます。このパターンは、プロキシ処理、負荷分散、または安全な接続の管理などのタスクを扱うことができ、主要なアプリケーションコンテナから複雑さを抽象化します。
- 主要アプリケーションコンテナ: HTTPリクエストを行うシンプルなウェブサーバー
- アンバサダーコンテナ: 外部APIへのリクエストを管理するように設定されたEnvoyプロキシ
apiVersion: v1
kind: Pod
metadata:
name: app-with-ambassador
spec:
containers:
- name: web-app
image: python:3.8-slim
command: ["python", "-m", "http.server", "8000"]
volumeMounts:
- name: config-volume
mountPath: /etc/envoy
- name: envoy-proxy
image: envoyproxy/envoy:v1.18.3
args: ["-c", "/etc/envoy/envoy.yaml"]
ports:
- containerPort: 8080
volumeMounts:
- name: config-volume
mountPath: /etc/envoy
volumes:
- name: config-volume
configMap:
name: envoy-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: envoy-config
data:
envoy.yaml: |
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: external_service
http_filters:
- name: envoy.filters.http.router
clusters:
- name: external_service
connect_timeout: 0.25s
type: LOGICAL_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: external_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: api.example.com
port_value: 80
この例は、Kubernetesにおけるアンバサダーパターンを示しており、Envoyプロキシが主要なアプリケーションコンテナの外部通信を管理する中間者として機能します。このパターンは、通信の複雑さを抽象化し、モジュラリティと保守性を向上させます。
アダプターパターン
アダプターコンテナは、主要なアプリケーションと外部システム間のデータを変更または変換し、互換性と統合を確保します。例えば、アダプターコンテナはログデータを外部のロギングサービスの要件を満たすように再フォーマットすることができます。
Kubernetesにおけるアダプターパターンは、サイドカーコンテナを使用して主要なアプリケーションコンテナと外部システム間のデータを変換することを含みます。これは、主要なアプリケーションが外部システムによって提供された形式と異なる特定の形式でデータを必要とする場合に便利です。
例えば、カスタム形式でログを生成する主要なアプリケーションコンテナがあるとします。これらのログを特定の標準化された形式で要求される外部ロギングサービスに送信する必要があります。ログデータを外部サービスに送信する前に、アダプターコンテナを使用してログデータを必要な形式に変換することができます。
- 主要なアプリケーションコンテナ: カスタム形式でログを記述するシンプルなアプリケーションです。
- アダプターコンテナ: カスタムログを読み取り、それらをJSON形式に変換して外部ロギングサービスに送信するコンテナです。
apiVersion: v1
kind: Pod
metadata:
name: app-with-adapter
spec:
containers:
- name: log-writer
image: busybox
command: ["sh", "-c", "while true; do echo \"$(date) - Custom log entry\" >> /var/log/custom/app.log; sleep 5; done"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/custom
- name: log-adapter
image: busybox
command: ["sh", "-c", "tail -f /var/log/custom/app.log | while read line; do echo \"$(echo $line | sed 's/ - / - {\"timestamp\": \"/;s/$/\"}/')\" >> /var/log/json/app.json; done"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/custom
- name: json-logs
mountPath: /var/log/json
- name: log-sender
image: busybox
command: ["sh", "-c", "while true; do cat /var/log/json/app.json | grep -v '^$' | while read line; do echo \"Sending log to external service: $line\"; done; sleep 10; done"]
volumeMounts:
- name: json-logs
mountPath: /var/log/json
volumes:
- name: shared-logs
emptyDir: {}
- name: json-logs
emptyDir: {}
この例は、Kubernetesにおけるアダプターパターンを示しており、アダプターコンテナがプライマリアプリケーションコンテナからデータを必要な形式に変換して外部システムに送信する前に変換する役割を果たしています。このパターンは、サイドカーコンテナ内でデータ形式の変換を処理することで、アプリケーションと外部サービスを統合するのに役立ちます。
概要
要約すると、pods:
- Kubernetesにおける最小のデプロイ可能な単位です。
- 実行中のプロセスの単一のインスタンスを表します。
- 1つ以上のコンテナを含めることができます。
Services:
- ポッドにアクセスするための安定したIPアドレスとDNS名を提供します。
- 一連のポッド間で負荷分散を可能にします。
- クラスタ内でのサービスの検出を容易にします。
Source:
https://dzone.com/articles/the-ultimate-guide-to-kubernetes-pods-and-services