サイドカーパターンは、メインのコンテナに加えて、補助的な機能を追加するコンテナを内包したパターン。
多くの場合はデータや設定にまつわるパターンである。
例
アンバサダーパターンは、メインのコンテナが外部のシステムと接続する際に代理で中継を行うコンテナを内包したパターン。
メインコンテナと外部のシステムが疎結合になることで、アプリケーションから見ると環境差を考慮する必要がなくなる。
例
アダプターパターンは、外部からのリクエストに対して差分を吸収するコンテナを内包したパターン。
BFF のようなもの。
例
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
spec:
dnsPolicy: ClusterFirst
containers:
- name: nginx-container
image: nginx:1.16
workingDir: /tmp
DNS サーバに関する設定は「spec.dnsPolicy」に記述。
クラスタ内の DNS サーバを使って名前解決を行い、解決できない場合アップストリームの DNS サーバに問い合わせを行う。
クラスタ外の DNS サーバを参照させたい場合、「spec.dnsConfig」に設定したい値を記述する。
しかし、クラスタ内 DNS を利用したサービスディスカバリができなくなる。
Kubernetes Node の DNS 設定をそのまま引き継ぐ場合には、「spec.dnsPolicy: Default」に設定。
$ kubectl exec -it sample-pod -- cat /etc/resolv.conf
DNS による名前解決の前に/etc/hosts ファイルによる静的な名前解決を行う。
「spec.hostAliases」で/etc/hosts を書き換えることが可能。
Pod のレプリカを作成し、指定した数の Pod を維持し続けるリソース。
同じラベルをもつ Pod を ReplicaSet 外で作成した場合は、RS が Pod を増やしすぎた勘違いし、既存の Pod を削除してしまうため、ラベルはユニークにつける必要がある。
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: sample-rs
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.6
複数の ReplicaSet を管理することで、ローリングアップデートやロールバックなどを実現するリソース。
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.6
Deployment に変更があると ReplicaSet が作成されるが、この「変更」とは作成される Pod の内容の変更で「spec.template」に変更がある場合である。(Pod の構造体のハッシュ値をラベル付で管理しているため、Pod の内容に変更がない場合既存の ReplicaSet を利用するようになっている。)
安全のために、Deployment に対する変更を行なっても適用は待ってほしい場合がある。
即時適用を一時停止したい場合は、「kubectl rollout pause」を実行し、再開するには「kubectl rollout resume」を実行。
Recreate は、一度全ての Pod を削除してから再度 Pod を作成するためダウンタイムが発生する。
Kubernetes クラスタを構築するとノードごとに Pod のための内部ネットワークを自動的に構成する。この内部ネットワークが自動構成されているため、Pod は Service を利用せずとも Pod 間通信を行うことが可能。
しかし、Service を利用することには以下のメリットがある。
Deployment を使用して Pod を複数起動できるが、Pod は起動するごとにそれぞれ異なる IP アドレスが割り当てられる。自前でロードバランシングを実装するとすると、毎回 Pod の IP を調べて設定しなければならない。
Pod のポート定義に名前を付与しておくことで、名前を用いた参照を行うことが可能。この機能を利用することで、異なる宛先のポート番号を扱うことが可能。
apiVersion: v1
kind: Pod
metadata:
name: simple-named-pord-pod-80
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: amsy810/echo-nginx:v2.0
ports:
- name: http
containerPort: 80
---
apiVersion: v1
kind: Pod
metadata:
name: simple-named-pord-pod-81
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: amsy810/echo-nginx:v2.0
ports:
- name: http
containerPort: 81
---
apiVersion: v1
kind: Service
metadata:
name: sample-named-port-service
spec:
type: ClusterIP
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: http
selector:
app: sample-app
サービスディスカバリとは、特定の条件の対象となるメンバを列挙したり、名前からエンドポイントを判別する機能。
Pod 内からは、環境変数でも同じ Namespace のサービスが確認できるようになっている。
$ kubectl exec -it [pod名] -- env | grep -i sample_clsuterip
SAMPLE_CLUSTERIP_SERVICE_HOST=[ServiceのPodのホスト]
SAMPLE_CLUSTERIP_SERVICE_PORT=8080
Service リソースの IP アドレスを接続元コンテナの設定ファイルなどで明示的に指定してしまうと、Service 作成のたびに設定ファイルなどの変更が必要になる。
DNS 名を利用すれば、Service の再作成による IP アドレスの変更も気にする必要がありませんし、設定ファイルの変更を行う必要もありません。
正式な FQDN は、[Service 名].[Namespace 名].svc.cluster.local となっている。
コンテナ内の/etc/resolv.conf に下記のような記述があるため、[Service 名].default や[Service 名]だけでも名前解決できるようになる。
$ kubectl run --image=amsy810/tools:v2.0 --restart=Never --rm -i testpod --command -- cat /etc/resolv.conf
nameserver 10.11.240.10
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
...
また、逆引きもできるようになっている。
$ kubectl run --image=amsy810/tools:v2.0 --restart=Never --rm -i testpod --command -- dig -x 10.11.253.80
:: ANSWER SECTION::
80.253.11.10.in-addr.arpa. 30 IN PTR sample-clusterip.default.svc.cluster.local.
SRV レコードとは、DNS で定義されるそのドメインについての情報の種類の一つで、そのドメインで提供されているサービスの詳細な情報を記述するためのもの。
SRV レコードを使って Service のエンドポイント(宛先のホスト名と Port 番号)も確認できる。SRV レコードは、Port めいと Protocol を利用することで、サービスを提供している Port 番号を含めたエンドポイントを DNS で解決する仕組み。
レコードの形式は、[_Service の Port 名].[_Protocol].[Service 名].[Namespace 名].svc.cluster.local である。
$ kubectl run --image=amsy810/tools:v2.0 --restart=Never --rm -i testpod \
--command -- dig _http-port._tcp.sample-clusterip.default.svc.cluster.local SRV
:: ANSWER SECTION::
_http-port._tcp.sample-clusterip.default.svc.cluster.local. 30 IN SRV 10 100 8080
sample-clusterip.default.svc.cluster.local.
大規模なクラスタでのパフォーマンスを向上させるために各ノードのローカル上に DNS キャッシュサーバを用意する仕組みがある。
ClusterIP 宛の通信は、各ノード上で実行しているシステムコンポーネントの kube-proxy が Pod 向けに転送を行う。