Red HatでOpenShiftのサポートをしているid:nekopです。OpenShift Advent Calendar 2019の2日目のエントリです。
OpenShift Service MeshはIstioの製品版ですが、通常のIstioをセットアップしたときと少し構成が異なり、Istio CNIというものが利用されています。
IstioはトラフィックをインターセプトしてSidecar proxyへ流すためにiptablesのルールを利用しています。このiptablesのルールをどのように適用するか、というところですが、通常のセットアップではInit containerがSidecar proxyと共にアプリケーションのPodへInjectされて利用されます。このInit containerはiptablesを利用するため、NET_ADMIN capabilityが許可されている特権コンテナ(privileged, 要はroot権限)として設定される必要があります。しかし、特権コンテナを許可してしまうと、アプリケーションのすぐ横にセキュリティレベルの弱いコンテナが配置されることになりますし、特権コンテナ起動が許可されているサービスアカウントを流用して他の悪意のある特権コンテナを起動していろいろできてしまったりするので回避したいところです。そこで利用されるのがIstio CNIというCNIプラグインです。Istio CNIでは特権Init contaienrではなくCNIの仕組み内からiptablesのルール適用を行っています。
これがOpenShift 4.2上でどのように構成されているか見ていきたいと思います。この例ではtest-istio
というプロジェクトを対象に見ていきます。
OpenShift Service MeshではServiceMeshMemberRollsというリソースにIstioを使うプロジェクトを記述するとセットアップが実行されます。
$ oc get -n istio-system servicemeshmemberrolls.maistra.io NAME MEMBERS default [knative-serving test-knative test-istio]
OpenShift 4ではmultus-cniというCNIプラグインを柔軟に選択できるCNIメタプラグインが標準となっており、上記設定を行うとMultusのNetworkAttachmentDefinitionというリソースがプロジェクトに作成され、istio-cniが有効化されます。NetworkAttachmentDefinitionの中身は利用するCNIの名前だけ指定されているものです。
$ oc get network-attachment-definitions.k8s.cni.cncf.io --all-namespaces NAMESPACE NAME AGE knative-serving istio-cni 23m test-istio istio-cni 23m test-knative istio-cni 32d $ oc get -n test-istio network-attachment-definitions.k8s.cni.cncf.io istio-cni -o yaml apiVersion: k8s.cni.cncf.io/v1 kind: NetworkAttachmentDefinition metadata: generation: 1 name: istio-cni namespace: test-istio
この設定はどこに紐づいているかというと、OpenShift Service Meshに含まれるDaemonSetが各ノードのmultus設定ディレクトリにCNI設定ファイルを配置していて、その名前を指定しています。
$ oc set volumes -n openshift-operators ds/istio-node daemonsets/istio-node host path /opt/multus/bin as cni-bin-dir mounted at /host/opt/cni/bin host path /etc/cni as etc-cni-dir mounted at /host/etc/cni/
このDaemonSetによって各ホストに以下のファイル群が配置されています。
/etc/cni/multus/net.d/istio-cni.conf /etc/cni/multus/net.d/istio-cni.kubeconfig /opt/cni/bin/istio-cni /opt/cni/bin/istio-iptables.sh
実際のCNI設定内容は以下のようになっています。
$ oc debug node/node01 # chroot /host # cat /etc/cni/multus/net.d/istio-cni.conf { "cniVersion": "0.3.0", "name": "istio-cni", "type": "istio-cni", "log_level": "info", "kubernetes": { "kubeconfig": "/etc/cni/multus/net.d/istio-cni.kubeconfig", "cni_bin_dir": "/opt/multus/bin", "iptables_script": "istio-iptables.sh", "exclude_namespaces": [ "openshift-operators" ] } }
OpenShift Service Meshでは、このようにDaemonSetでMultusにistio-cni設定を配置、MultusのNetworkAttachmentDefinitionで有効化するという仕組みを利用して特権コンテナを利用しない、より安全なIstioのセットアップを実現しています。