Red Hat Training

A Red Hat training course is available for OpenShift Container Platform

第6章 ネットワークの管理

6.1. 概要

This topic describes the management of the overall cluster network, including project isolation and outbound traffic control.

Pod ごとの帯域幅の制限などの Pod レベルのネットワーク機能については、Pod の管理で説明されています。

6.2. Pod ネットワークの管理

When your cluster is configured to use the ovs-multitenant SDN plugin, you can manage the separate pod overlay networks for projects using the administrator CLI. See the Configuring the SDN section for plug-in configuration steps, if necessary.

6.2.1. プロジェクトネットワークへの参加

プロジェクトを既存のプロジェクトネットワークに参加させるには、以下を実行します。

$ oc adm pod-network join-projects --to=<project1> <project2> <project3>

In the above example, all the pods and services in <project2> and <project3> can now access any pods and services in <project1> and vice versa. Services can be accessed either by IP or fully-qualified DNS name (<service>.<pod_namespace>.svc.cluster.local). For example, to access a service named db in a project myproject, use db.myproject.svc.cluster.local.

または、特定のプロジェクト名を指定する代わりに --selector=<project_selector> オプションを使用することもできます。

6.3. プロジェクトネットワークの分離

プロジェクトネットワークをクラスターから分離したり、その逆を実行するには、以下を実行します。

$ oc adm pod-network isolate-projects <project1> <project2>

上記の例では、<project1> および <project2> のすべての Pod およびサービスは、クラスター内のグローバル以外のプロジェクトの Pod およびサービスにアクセスできず、その逆も実行できません。

または、特定のプロジェクト名を指定する代わりに --selector=<project_selector> オプションを使用することもできます。

6.3.1. プロジェクトネットワークのグローバル化

プロジェクトからクラスター内のすべての Pod およびサービスにアクセスできるようにするか、その逆を可能にするには、以下を実行します。

$ oc adm pod-network make-projects-global <project1> <project2>

上記の例では、<project1> および <project2> のすべての Pod およびサービスはクラスター内のすべての Pod およびサービスにアクセスでき、その逆の場合も可能になります。

または、特定のプロジェクト名を指定する代わりに --selector=<project_selector> オプションを使用することもできます。

6.4. ルートおよび Ingress オブジェクトにおけるホスト名の競合防止の無効化

OpenShift Container Platform では、ルートおよび ingress オブジェクトのホスト名の競合防止はデフォルトで有効にされています。これは、cluster-admin ロールのないユーザーは、作成時にのみルーターまたは ingress オブジェクトのホスト名を設定でき、その後は変更できなくなることを意味しています。ただし、ルートおよび ingress オブジェクトのこの制限は、一部またはすべてのユーザーに対して緩和することができます。

警告

OpenShift Container Platform はオブジェクト作成のタイムスタンプを使用して特定のホスト名の最も古いルートや ingress オブジェクトを判別するため、ルートまたは ingress オブジェクトは、古いルートがそのホスト名を変更したり、ingress オブジェクトが導入される場合に新規ルートのホスト名をハイジャックする可能性があります。

OpenShift Container Platform クラスター管理者は、作成後でもルートのホスト名を編集できます。また、特定のユーザーがこれを実行できるようにロールを作成することもできます。

$ oc create clusterrole route-editor --verb=update --resource=routes.route.openshift.io/custom-host

次に、新規ロールをユーザーにバインドできます。

$ oc adm policy add-cluster-role-to-user route-editor user

ingress オブジェクトのホスト名の競合防止を無効にすることもできます。これを実行することで、cluster-admin ロールを持たないユーザーが作成後も ingress オブジェクトのホスト名を編集できるようになります。これは、ingress オブジェクトのホスト名の編集を許可する場合などに Kubernetes の動作に依存する OpenShift Container Platform のインストールで役に立ちます。

  1. 以下を master.yaml ファイルに追加します。

    admissionConfig:
      pluginConfig:
        openshift.io/IngressAdmission:
          configuration:
            apiVersion: v1
            allowHostnameChanges: true
            kind: IngressAdmissionConfig
          location: ""
  2. 変更を有効にするために、マスターサービスを再起動します。

    $ systemctl restart atomic-openshift-master-api atomic-openshift-master-controllers

6.5. Egress トラフィックの制御

クラスター管理者は、ホストレベルで数多くの静的 IP アドレスを特定ノードに割り当てることができます。アプリケーション開発者がそれぞれのアプリケーションサービスに専用 IP アドレスを必要とする場合、ファイアウォールアクセスを要求するプロセスでこのアドレスを要求することができます。その後、開発者はデプロイメント設定の nodeSelector を使用して、開発者のプロジェクトから egress ルーターをデプロイし、静的 IP アドレスが事前に割り当てられたホストに Pod が到達することを確認できます。

The egress pod’s deployment declares one of the source IPs, the destination IP of the protected service, and a gateway IP to reach the destination. After the pod is deployed, you can create a service to access the egress router pod, then add that source IP to the corporate firewall. The developer then has access information to the egress router service that was created in their project, for example, service.project.cluster.domainname.com.

開発者が外部の firewalled サービスにアクセスする必要がある場合、実際の保護されたサービス URL ではなくアプリケーション (例: JDBC 接続情報) で、egress ルーター Pod のサービス (service.project.cluster.domainname.com) に対して呼び出し実行することができます。

You can also assign static IP addresses to projects, ensuring that all outgoing external connections from the specified project have recognizable origins. This is different from the default egress router, which is used to send traffic to specific destinations. See the Enabling Fixed IPs for External Project Traffic section for more information.

注記

The egress router is not available for OpenShift Dedicated.

OpenShift Container Platform クラスター管理者は、以下を使用して egress トラフィックを制御できます。

ファイアウォール
egress ファイアウォールを使用すると、受け入れ可能な発信トラフィックポリシーを実施し、特定のエンドポイントまたは IP 範囲 (サブネット) のみを動的エンドポイント (OpenShift Container Platform 内の Pod) が通信できる受け入れ可能なターゲットとすることができます。
ルーター
egress ルーターを使用することで、識別可能なサービスを作成し、トラフィックを特定の宛先に送信できます。これにより、それらの外部の宛先はトラフィックを既知のソースから送られるものとして処理します。これにより namespace の特定の Pod のみがトラフィックをデータベースにプロキシー送信するサービス (egress ルーター) と通信できるよう外部データベースが保護されるため、セキュリティー対策として役立ちます。
iptables
上記の OpenShift Container Platform 内のソリューションのほかにも、発信トラフィックに適用される iptables ルールを作成することができます。これらのルールは、egress ファイアウォールよりも多くのオプションを許可しますが、特定のプロジェクトに制限することはできません。

6.5.1. 外部リソースへのアクセスを制限するための Egress ファイアウォールの使用

As an OpenShift Container Platform cluster administrator, you can use egress firewall policy to limit the external addresses that some or all pods can access from within the cluster, so that:

  • Pod の対話を内部ホストに制限し、パブリックインターネットへの接続を開始できないようにする。

    または

  • Pod の対話をパブリックインターネットに制限し、(クラスター外の) 内部ホストへの接続を開始できないようにする。

    または

  • Pod が接続する理由のない指定された内部サブネット/ホストに到達できないようにする。

You can configure projects to have different egress policies. For example, allowing <project A> access to a specified IP range, but denying the same access to <project B>. Or restrict application developers from updating from (Python) pip mirrors, and forcing updates to only come from desired sources.

注意

You must have the ovs-multitenant or ovs-networkpolicy plug-in enabled in order to limit pod access via egress policy.

プロジェクト管理者は、EgressNetworkPolicy オブジェクトを作成することも、プロジェクトで作成するオブジェクトを編集することもできません。また、EgressNetworkPolicy の作成に関連して他のいくつかの制限があります。

  • デフォルトプロジェクト (および oc adm pod-network make-projects-global でグローバルにされたその他のプロジェクト) には egress ポリシーを設定することができません。
  • (oc adm pod-network join-projects を使用して) 2 つのプロジェクトをマージする場合、マージしたプロジェクトのいずれでも egress ポリシーを使用することはできません。
  • いずれのプロジェクトも複数の egress ポリシーオブジェクトを持つことができません。

上記の制限のいずれかに違反すると、プロジェクトの egress ポリシーに障害が発生し、すべての外部ネットワークトラフィックがドロップされる可能性があります。

oc コマンドまたは REST API を使用して egress ポリシーを設定します。oc [create|replace|delete] を使用して EgressNetworkPolicy オブジェクトを操作できます。api/swagger-spec/oapi-v1.json ファイルには、オブジェクトを実際に機能させる方法についての API レベルの詳細情報が含まれます。

egress ポリシーを設定するには、以下を実行します。

  1. 対象とするプロジェクトに移動します。
  2. Create a JSON file with the desired policy details. For example:

    {
        "kind": "EgressNetworkPolicy",
        "apiVersion": "v1",
        "metadata": {
            "name": "default"
        },
        "spec": {
            "egress": [
                {
                    "type": "Allow",
                    "to": {
                        "cidrSelector": "1.2.3.0/24"
                    }
                },
                {
                    "type": "Allow",
                    "to": {
                        "dnsName": "www.foo.com"
                    }
                },
                {
                    "type": "Deny",
                    "to": {
                        "cidrSelector": "0.0.0.0/0"
                    }
                }
            ]
        }
    }

    上記のサンプルがプロジェクトに追加されると、IP 範囲 1.2.3.0/24 およびドメイン名 www.foo.com へのトラフィックが許可されますが、その他のすべての外部 IP アドレスへのアクセスは拒否されます。このポリシーは外部トラフィックにのみ適用されるため、その他すべての Pod へのトラフィックは影響を受けません。

    EgressNetworkPolicy のルールは順番にチェックされ、一致する最初のルールが実施されます。上記の例の 3 つの例を逆順に定義した場合、0.0.0.0/0 ルールが最初にチェックされ、すべてのトラフィックに一致し、それらすべてを拒否するため、1.2.3.0/24 および www.foo.com へのトラフィックは許可されません。

    Domain name updates are polled based on the TTL (time to live) value of the domain of the local non-authoritative server, or 30 minutes if the TTL is unable to be fetched. The pod should also resolve the domain from the same local non-authoritative server when necessary, otherwise the IP addresses for the domain perceived by the egress network policy controller and the pod will be different, and the egress network policy may not be enforced as expected. In the above example, suppose www.foo.com resolved to 10.11.12.13 and has a DNS TTL of one minute, but was later changed to 20.21.22.23. OpenShift Container Platform will then take up to one minute to adapt to these changes.

注記

The egress firewall always allows pods access to the external interface of the node the pod is on for DNS resolution. If your DNS resolution is not handled by something on the local node, then you will need to add egress firewall rules allowing access to the DNS server’s IP addresses if you are using domain names in your pods. The default installer sets up a local dnsmasq, so if you are using that setup you will not need to add extra rules.

  1. JSON ファイルを使用して EgressNetworkPolicy オブジェクトを作成します。

    $ oc create -f <policy>.json
注意

Exposing services by creating routes will ignore EgressNetworkPolicy. Egress network policy service endpoint filtering is done at the node kubeproxy. When the router is involved, kubeproxy is bypassed and egress network policy enforcement is not applied. Administrators can prevent this bypass by limiting access to create routes.

6.5.2. 外部リソースから Pod トラフィックを認識可能にするための Egress ルーターの使用

OpenShift Container Platform egress ルーターは、他の用途で使用されていないプライベートソース IP アドレスを使用して、指定されたリモートサーバーにトラフィックをリダイレクトするサービスを実行します。このサービスにより、Pod はホワイトリスト IP アドレスからのアクセスのみを許可するように設定されたサーバーと通信できるようになります。

重要

egress ルーターはすべての発信接続のために使用されることが意図されていません。多数の egress ルーターを作成することで、ネットワークハードウェアの制限を引き上げる可能性があります。たとえば、すべてのプロジェクトまたはアプリケーションに egress ルーターを作成すると、ソフトウェアの MAC アドレスのフィルターにフォールバックする前にネットワークインターフェースが処理できるローカル MAC アドレス数の上限を超えてしまう可能性があります。

重要

Currently, the egress router is not compatible with Amazon AWS due to AWS not being compatible with macvlan traffic.

デプロイメントに関する考慮事項

Egressルーターは 2 つ目の IP アドレスおよび MAC アドレスをノードのプライマリーネットワークインターフェースに追加します。OpenShift Container Platform をベアメタルで実行していない場合は、ハイパーバイザーまたはクラウドプロバイダーが追加のアドレスを許可するように設定する必要があります。

Red Hat OpenStack Platform

OpenShift Container Platform を Red Hat OpenStack Platform を使ってデプロイしている場合、OpenStack 環境で IP および MAC アドレスのホワイトリストを作成する必要があります。これを行わないと、通信は失敗します

neutron port-update $neutron_port_uuid \
  --allowed_address_pairs list=true \
  type=dict mac_address=<mac_address>,ip_address=<ip_address>
Red Hat Enterprise Virtualization
Red Hat Enterprise Virtualization を使用している場合、 EnableMACAntiSpoofingFilterRulesfalse に設定している必要があります。
VMware vSphere
VMware vSphere を使用している場合は、vSphere 標準スイッチのセキュリティー保護についての VMWare ドキュメントを参照してください。vSphere Web クライアントからホストの仮想スイッチを選択して、VMWare vSphere デフォルト設定を表示し、変更します。

とくに、以下が有効にされていることを確認します。

Egress ルーターモード

The egress router can run in two different modes: redirect mode and HTTP proxy mode. Redirect mode works for all services except for HTTP and HTTPS. For HTTP and HTTPS services, use HTTP proxy mode.

6.5.2.1. リダイレクトモードでの Egress ルーター Pod のデプロイ

リダイレクトモードでは、egress ルーターは、トラフィックを独自の IP アドレスから 1 つ以上の宛先 IP アドレスにリダイレクトするために iptables ルールをセットアップします。予約されたソース IP アドレスを使用する必要のあるクライアント Pod は、宛先 IP に直接接続するのでなく、egress ルーターに接続するように変更される必要があります。

  1. 上記を使用して Pod 設定を作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: egress-1
      labels:
        name: egress-1
      annotations:
        pod.network.openshift.io/assign-macvlan: "true" 1
    spec:
      initContainers:
      - name: egress-router
        image: registry.access.redhat.com/openshift3/ose-egress-router
        securityContext:
          privileged: true
        env:
        - name: EGRESS_SOURCE 2
          value: 192.168.12.99
        - name: EGRESS_GATEWAY 3
          value: 192.168.12.1
        - name: EGRESS_DESTINATION 4
          value: 203.0.113.25
        - name: EGRESS_ROUTER_MODE 5
          value: init
      containers:
      - name: egress-router-wait
        image: registry.access.redhat.com/openshift3/ose-pod
      nodeSelector:
        site: springfield-1 6
    1
    プライマリーネットワークインターフェースで Macvlan ネットワークインターフェースを作成し、これを Pod のネットワークプロジェクトに移行してから egress-router コンテナーを起動します。"true" の周りの引用符はそのまま残します。これらを省略すると、エラーが発生します。プライマリーネットワークインターフェース以外のネットワークインターフェースで Macvlan インターフェースを作成するには、アノテーションの値を該当インターフェースの名前に設定します。たとえば、 eth1 を使用します。
    2
    IP address from the physical network that the node is on and is reserved by the cluster administrator for use by this pod.
    3
    ノードで使用されるデフォルトゲートウェイと同じ値です。
    4
    トラフィックの送信先となる外部サーバー。この例では、Pod の接続は 203.0.113.25 にリダイレクトされます。ソース IP アドレスは 192.168.12.99 です。
    5
    これは egress ルーターイメージに対して、これが「init コンテナー」としてデプロイされていることを示しています。以前のバージョンの OpenShift Container Platform (および egress ルーターイメージ) はこのモードをサポートしておらず、通常のコンテナーとして実行される必要がありました。
    6
    Pod はラベル site=springfield-1 の設定されたノードにのみデプロイされます。
  2. 上記の定義を使用して Pod を作成します。

    $ oc create -f <pod_name>.json

    Pod が作成されているかどうかを確認するには、以下を実行します。

    $ oc get pod <pod_name>
  3. egresss ルーターを参照するサービスを作成し、他の Pod が Pod の IP アドレスを見つけられるようにします。

    apiVersion: v1
    kind: Service
    metadata:
      name: egress-1
    spec:
      ports:
      - name: http
        port: 80
      - name: https
        port: 443
      type: ClusterIP
      selector:
        name: egress-1

    Pod がこのサービスに接続できるようになります。これらの接続は、予約された egress IP アドレスを使用して外部サーバーの対応するポートにリダイレクトされます。

egress ルーターのセットアップは、openshift3/ose-egress-router イメージで作成される「init コンテナー」で実行され、このコンテナーは Macvlan インターフェースを設定し、iptables ルールをセットアップできるように特権モード実行されます。iptables ルールのセットアップ終了後に、これは終了し、openshift3/ose-pod コンテナーが Pod が強制終了されるまで (特定のタスクを実行しない) 実行状態になります。

環境変数は egress-router イメージに対し、使用するアドレスを指示します。これは、EGRESS_SOURCE を IP アドレスとして、また EGRESS_GATEWAY をゲートウェイとして使用するよう Macvlan を設定します。

NAT ルールが設定され、Pod のクラスター IP アドレスの TCP または UDP ポートへの接続が EGRESS_DESTINATION の同じポートにリダイレクトされるようにします。

クラスター内の一部のノードのみが指定されたソース IP アドレスを要求でき、指定されたゲートウェイを使用できる場合、受け入れ可能なノードを示す nodeName または nodeSelector を指定することができます。

6.5.2.2. 複数の宛先へのリダイレクト

前の例では、任意のポートでの egress Pod (またはその対応するサービス) への接続は単一の宛先 IP にリダイレクトされます。ポートによっては複数の異なる宛先 IP を設定することもできます。

apiVersion: v1
kind: Pod
metadata:
  name: egress-multi
  labels:
    name: egress-multi
  annotations:
    pod.network.openshift.io/assign-macvlan: "true"
spec:
  initContainers:
  - name: egress-router
    image: registry.access.redhat.com/openshift3/ose-egress-router
    securityContext:
      privileged: true
    env:
    - name: EGRESS_SOURCE
      value: 192.168.12.99
    - name: EGRESS_GATEWAY
      value: 192.168.12.1
    - name: EGRESS_DESTINATION
      value: | 1
        80   tcp 203.0.113.25
        8080 tcp 203.0.113.26 80
        8443 tcp 203.0.113.26 443
        203.0.113.27
    - name: EGRESS_ROUTER_MODE
      value: init
  containers:
  - name: egress-router-wait
    image: registry.access.redhat.com/openshift3/ose-pod
1
This uses the YAML syntax for a multi-line string; see below for details.

EGRESS_DESTINATION の各行は以下の 3 つのタイプのいずれかになります。

  • <port> <protocol> <IP address> - This says that incoming connections to the given <port> should be redirected to the same port on the given <IP address>. <protocol> is either tcp or udp. In the example above, the first line redirects traffic from local port 80 to port 80 on 203.0.113.25.
  • <port> <protocol> <IP address> <remote port> - As above, except that the connection is redirected to a different <remote port> on <IP address>. In the example above, the second and third lines redirect local ports 8080 and 8443 to remote ports 80 and 443 on 203.0.113.26.
  • <fallback IP address> - If the last line of EGRESS_DESTINATION is a single IP address, then any connections on any other port will be redirected to the corresponding port on that IP address (eg, 203.0.113.27 in the example above). If there is no fallback IP address then connections on other ports would simply be rejected.)

6.5.2.3. ConfigMap の使用による EGRESS_DESTINATION の指定

宛先マッピングのセットのサイズが大きいか、またはこれが頻繁に変更される場合、ConfigMap を使用して一覧を外部で維持し、egress ルーター Pod がそこから一覧を読み取れるようにすることができます。これには、プロジェクト管理者が ConfigMap を編集できるという利点がありますが、これには特権付きコンテナーが含まれるため、管理者は Pod 定義を直接編集することはできません。

  1. EGRESS_DESTINATION データを含むファイルを作成します。

    $ cat my-egress-destination.txt
    # Egress routes for Project "Test", version 3
    
    80   tcp 203.0.113.25
    
    8080 tcp 203.0.113.26 80
    8443 tcp 203.0.113.26 443
    
    # Fallback
    203.0.113.27

    空の行とコメントをこのファイルに追加できることに注意してください。

  2. このファイルから ConfigMap オブジェクトを作成します。

    $ oc delete configmap egress-routes --ignore-not-found
    $ oc create configmap egress-routes \
      --from-file=destination=my-egress-destination.txt

    ここで、egress-routes は作成される ConfigMap オブジェクトの名前で、my-egress-destination.txt はデータの読み取り元のファイルの名前です。

  3. 前述のように egress ルーター Pod 定義を作成しますが、ConfigMap を環境セクションの EGRESS_DESTINATION に指定します。

        ...
        env:
        - name: EGRESS_SOURCE
          value: 192.168.12.99
        - name: EGRESS_GATEWAY
          value: 192.168.12.1
        - name: EGRESS_DESTINATION
          valueFrom:
            configMapKeyRef:
              name: egress-routes
              key: destination
        - name: EGRESS_ROUTER_MODE
          value: init
        ...
注記

egress ルーターは、ConfigMap が変更されても自動的に更新されません。更新を取得するには Pod を再起動します。

6.5.2.4. Egress ルーター HTTP プロキシー Pod のデプロイ

HTTP プロキシーモードでは、egress ルーターはポート 8080 で HTTP プロキシーとして実行されます。これは、HTTP または HTTPS ベースのサービスと通信するクライアントの場合にのみ機能しますが、通常それらを機能させるのにクライアント Pod への多くの変更は不要です。環境変数を設定することで、プログラムは HTTP プロキシーを使用するように指示されます。

  1. 例として以下を使用して Pod を作成します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: egress-http-proxy
      labels:
        name: egress-http-proxy
      annotations:
        pod.network.openshift.io/assign-macvlan: "true" 1
    spec:
      initContainers:
      - name: egress-router-setup
        image: registry.access.redhat.com/openshift3/ose-egress-router
        securityContext:
          privileged: true
        env:
        - name: EGRESS_SOURCE 2
          value: 192.168.12.99
        - name: EGRESS_GATEWAY 3
          value: 192.168.12.1
        - name: EGRESS_ROUTER_MODE 4
          value: http-proxy
      containers:
      - name: egress-router-proxy
        image: registry.access.redhat.com/openshift3/ose-egress-http-proxy
        env:
        - name: EGRESS_HTTP_PROXY_DESTINATION 5
          value: |
            !*.example.com
            !192.168.1.0/24
            *
    1
    プライマリーネットワークインターフェースで Macvlan ネットワークインターフェースを作成してから、これを Pod のネットワークプロジェクトに移行し、egress-router コンテナーを起動します。"true" の周りの引用符をそのまま残します。これらを省略すると、エラーが発生します。
    2
    An IP address from the physical network that the node itself is on and is reserved by the cluster administrator for use by this pod.
    3
    ノード自体で使用されるデフォルトゲートウェイと同じ値。
    4
    これは egress ルーターイメージに対し、これが HTTP プロキシーの一部としてデプロイされているため、iptables のリダイレクトルールを設定できないことを示します。
    5
    プロキシーの設定方法を指定する文字列または YAML の複数行文字列です。これは、init コンテナーの他の環境変数ではなく、HTTP プロキシーコンテナーの環境変数として指定されることに注意してください。

    EGRESS_HTTP_PROXY_DESTINATION 値に以下のいずれかを指定できます。また、* を使用することができます。これは「すべてのリモート宛先への接続を許可」することを意味します。設定の各行には、許可または拒否する接続の 1 つのグループを指定します。

    • IP アドレス (例: 192.168.1.1) は該当する IP アドレスへの接続を許可します。
    • CIDR 範囲 (例: 192.168.1.0/24) は CIDR 範囲への接続を許可します。
    • ホスト名 (例: www.example.com) は該当ホストへのプロキシーを許可します。
    • *. が先に付けられるドメイン名 (例: *.example.com) は該当ドメインおよびそのサブドメインのすべてへのプロキシーを許可します。
    • 上記のいずれかに ! を付けると、接続は許可されるのではなく、拒否されます。
    • 最後の行が * の場合、拒否されていないすべてのものが許可されます。または、許可されていないすべてのものが拒否されます。
  2. egresss ルーターを参照するサービスを作成し、他の Pod が Pod の IP アドレスを見つけられるようにします。

    apiVersion: v1
    kind: Service
    metadata:
      name: egress-1
    spec:
      ports:
      - name: http-proxy
        port: 8080 1
      type: ClusterIP
      selector:
        name: egress-1
    1
    http ポートが常に 8080 に設定されていることを確認します。
  3. http_proxy または https_proxy 変数を設定して、クライアント Pod (egress プロキシー Pod ではない) を HTTP プロキシーを使用するように設定します。

        ...
        env:
        - name: http_proxy
          value: http://egress-1:8080/ 1
        - name: https_proxy
          value: http://egress-1:8080/
        ...
    1
    手順 2 で作成されたサービス。
    注記

    すべてのセットアップに http_proxy および https_proxy 環境変数が必要になる訳ではありません。上記を実行しても作業用セットアップが作成されない場合は、Pod で実行しているツールまたはソフトウェアについてのドキュメントを参照してください。

リダイレクトする egress ルーターの上記の例と同様に、ConfigMap を使用して EGRESS_HTTP_PROXY_DESTINATION を指定することもできます。

6.5.2.5. Egress ルーター Pod のフェイルオーバーの有効化

レプリケーションコントローラーを使用し、ダウンタイムを防ぐために egress ルーター Pod の 1 つのコピーを常に確保できるようにします。

  1. 以下を使用してレプリケーションコントローラーの設定ファイルを作成します。

    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: egress-demo-controller
    spec:
      replicas: 1 1
      selector:
        name: egress-demo
      template:
        metadata:
          name: egress-demo
          labels:
            name: egress-demo
          annotations:
            pod.network.openshift.io/assign-macvlan: "true"
        spec:
          initContainers:
          - name: egress-demo-init
            image: registry.access.redhat.com/openshift3/ose-egress-router
            env:
            - name: EGRESS_SOURCE
              value: 192.168.12.99
            - name: EGRESS_GATEWAY
              value: 192.168.12.1
            - name: EGRESS_DESTINATION
              value: 203.0.113.25
            - name: EGRESS_ROUTER_MODE
              value: init
            securityContext:
              privileged: true
          containers:
          - name: egress-demo-wait
            image: registry.access.redhat.com/openshift3/ose-pod
          nodeSelector:
            site: springfield-1
    1
    replicas1 に設定されていることを確認します。1 つの Pod のみが指定される EGRESS_SOURCE 値を随時使用できるためです。これは、ルーターの単一コピーのみがラベル site=springfield-1 が設定されたノードで実行されることを意味します。
  2. この定義を使用して Pod を作成します。

    $ oc create -f <replication_controller>.json
  3. 検証するには、レプリケーションコントローラー Pod が作成されているかどうかを確認します。

    $ oc describe rc <replication_controller>

6.5.3. 外部リソースへのアクセスを制限するための iptables ルールの使用

クラスター管理者の中には、EgressNetworkPolicy のモデルや egress ルーターの対象外の発信トラフィックに対してアクションを実行する必要のある管理者がいる場合があります。この場合には、iptables ルールを直接作成してこれを実行することができます。

たとえば、特定の宛先へのトラフィックをログに記録するルールを作成したり、1 秒ごとに設定される特定数を超える発信接続を許可しないようにしたりできます。

OpenShift Container Platform はカスタム iptables ルールを自動的に追加する方法を提供していませんが、管理者がこのようなルールを手動で追加できる場所を提供します。各ノードは起動時に、filter テーブルに OPENSHIFT-ADMIN-OUTPUT-RULES という空のチェーンを作成します (チェーンがすでに存在していないと仮定します)。管理者がこのチェーンに追加するすべてのルールは、Pod からクラスター外にある宛先へのすべてのトラフィックに適用されます (それ以外のトラフィックには適用されません)。

この機能を使用する際には、注意すべきいくつかの点があります。

  1. 各ノードにルールが作成されていることを確認するのは管理者のタスクになります。OpenShift Container Platform はこれを自動的に確認する方法は提供しません。
  2. ルールは egress ルーターによってクラスターを退出するトラフィックには適用されず、ルールは EgressNetworkPolicy ルールが適用された後に実行されます (そのため、EgressNetworkPolicy で拒否されるトラフィックは表示されません)。
  3. ノードには「外部」IP アドレスと「内部」SDN IP アドレスの両方があるため、Pod からノードまたはノードからマスターへの接続の処理は複雑になります。そのため、一部の Pod とノード間/Pod とマスター間のトラフィックはこのチェーンを通過しますが、他の Pod とノード間/Pod とマスター間のトラフィックはこれをバイパスする場合があります。

6.6. 外部プロジェクトトラフィックの静的 IP の有効化

クラスター管理者は特定の静的 IP アドレスをプロジェクトに割り当て、トラフィックが外部から容易に識別できるようにできます。これは、トラフィックを特定の宛先に送信するために使用されるデフォルトの egress ルーターの場合とは異なります。

識別可能な IP トラフィックは起点を可視化することで、クラスターのセキュリティーを強化します。これが有効にされると、指定されたプロジェクトからのすべての発信外部接続は同じ固定ソース IP を共有します。つまり、すべての外部リソースがこのトラフィックを認識できるようになります。

egress ルーターの場合とは異なり、これは EgressNetworkPolicy ファイアウォールルールに基づいて実行されます。

静的 IP を有効にするには、以下を実行します。

  1. 必要な IP で NetNamespace を更新します。

    $ oc patch netnamespace <project_name> -p '{"egressIPs": ["<IP_address>"]}'

    たとえば、MyProject プロジェクトを IP アドレス 192.168.1.100 に割り当てるには、以下を実行します。

    $ oc patch netnamespace MyProject -p '{"egressIPs": ["192.168.1.100"]}'

    The egressIPs field is an array, but must be set to a single IP address. If setting multiple IPs, the other IPs will be ignored.

  2. egress IP を必要なノードホストに手動で割り当てます。ノードホストの HostSubnet オブジェクトの egressIPs フィールドを設定します。そのノードホストに割り当てる必要のある任意の数の IP を含めることができます。

    $ oc patch hostsubnet <node_name> -p \
      '{"egressIPs": ["<IP_address_1>", "<IP_address_2>"]}'

    たとえば node1 に egress IPs 192.168.1.100、192.168.1.101 および 192.168.1.102 が必要である場合が、以下のようになります。

    $ oc patch hostsubnet node1 -p \
      '{"egressIPs": ["192.168.1.100", "192.168.1.101", "192.168.1.102"]}'
    重要

    Egress IPs are implemented as additional IP addresses on the primary network interface, and must be in the same subnet as the node’s primary IP. Allowing additional IP addresses on the primary network interface might require extra configuration when using some cloud or VM solutions.

プロジェクトに対して上記が有効にされる場合、そのプロジェクトからのすべての egress トラフィックはその egress IP をホストするノードにルーティングされ、(NAT を使用して) その IP アドレスに接続されます。egressIPsNetNamespace で設定されているものの、その egress IP をホストするノードがない場合、namespace からの egress トラフィックはドロップされます。

6.7. マルチキャストの有効化

重要

現時点で、マルチキャストは低帯域幅の調整またはサービスの検出での使用に最も適しており、高帯域幅のソリューションとしては適していません。

Multicast traffic between OpenShift Container Platform pods is disabled by default. You can enable Multicast on a per-project basis by setting an annotation on the project’s corresponding netnamespace object:

$ oc annotate netnamespace <namespace> \
    netnamespace.network.openshift.io/multicast-enabled=true

アノテーションを削除してマルチキャストを無効にします。

$ oc annotate netnamespace <namespace> \
    netnamespace.network.openshift.io/multicast-enabled-

If you have joined networks together, you will need to enable Multicast in each projects' netnamespace in order for it to take effect in any of the projects. To enable Multicast in the default project, you must also enable it in the kube-service-catalog project and all other projects that have been made global.

注記

Multicast global projects are not "global", but instead communicate with only other global projects via Multicast, not with all projects in the cluster, as is the case with unicast.

6.8. NetworkPolicy の有効化

The ovs-subnet and ovs-multitenant plugins have their own legacy models of network isolation, and don’t support Kubernetes NetworkPolicy. However, NetworkPolicy support is available by using the ovs-networkpolicy plug-in.

In a cluster configured to use the ovs-networkpolicy plugin, network isolation is controlled entirely by NetworkPolicy objects. By default, all pods in a project are accessible from other pods and network endpoints. To isolate one or more pods in a project, you can create NetworkPolicy objects in that project to indicate the allowed incoming connections. Project administrators can create and delete NetworkPolicy objects within their own project.

Pod を参照する NetworkPolicy オブジェクトを持たない Pod は完全にアクセスできますが、Pod を参照する 1 つ以上の NetworkPolicy オブジェクトを持つ Pod は分離されます。これらの分離された Pod は 1 つ以上の NetworkPolicy オブジェクトで許可される接続のみを受け入れます。

Following are a few sample NetworkPolicy object definitions supporting different scenrios:

  • すべてのトラフィックを拒否

    プロジェクトに「deny by default (デフォルトで拒否)」を実行させるには、すべての Pod に一致するが、トラフィックを一切許可しない NetworkPolicy オブジェクトを追加します。

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: deny-by-default
    spec:
      podSelector:
      ingress: []
  • プロジェクト内の Pod からの接続のみを許可

    Pod が同じプロジェクト内の他の Pod からの接続を受け入れるが、他のプロジェクトの Pod からの接続を拒否するように設定するには、以下を実行します。

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-same-namespace
    spec:
      podSelector:
      ingress:
      - from:
        - podSelector: {}
  • Pod ラベルに基づいて HTTP および HTTPS トラフィックのみを許可

    特定のラベル (以下の例の role=frontend) の付いた Pod への HTTP および HTTPS アクセスのみを有効にするには、以下と同様の NetworkPolicy オブジェクトを追加します。

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-http-and-https
    spec:
      podSelector:
        matchLabels:
          role: frontend
      ingress:
      - ports:
        - protocol: TCP
          port: 80
        - protocol: TCP
          port: 443

NetworkPolicy オブジェクトは加算されるものです。つまり、複数の NetworkPolicy オブジェクトを組み合わせて複雑なネットワーク要件を満すことができます。

たとえば、先の例で定義された NetworkPolicy オブジェクトの場合、同じプロジェト内に allow-same-namespaceallow-http-and-https ポリシーの両方を定義することができます。これにより、ラベル role=frontend の付いた Pod は各ポリシーで許可されるすべての接続、つまり、同じ namespace の Pod からのすべての接続、および すべて の namespace の Pod からのポート 80 443 での接続を受け入れます。

6.8.1. NetworkPolicy およびルーター

When using the ovs-multitenant plugin, traffic from the routers is automatically allowed into all namespaces. This is because the routers are usually in the default namespace, and all namespaces allow connections from pods in that namespace. With the ovs-networkpolicy plugin, this does not happen automatically. Therefore, if you have a policy that isolates a namespace by default, you need to take additional steps to allow routers to access it.

1 つのオプションとして、すべてのソースからのアクセスを許可する各サービスのポリシーを作成できます。以下は例になります。

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-to-database-service
spec:
  podSelector:
    matchLabels:
      role: database
  ingress:
  - ports:
    - protocol: TCP
      port: 5432

これにより、ルーターはサービスにアクセスできますが、同時に他のユーザーの namespace にある Pod もこれにアクセスできます。これらの Pod は通常はパブリックルーターを使用してサービスにアクセスできるため、これによって問題が発生することはないはずです。

Alternatively, you can create a policy allowing full access from the default namespace, as in the ovs-multitenant plugin:

  1. ラベルをデフォルト namespace に追加します。

    重要

    You only need to do this once for the entire cluster. The cluster administrator role is required to add labels to namesapces.

    $ oc label namespace default name=default
  2. その namespace からの接続を許可するポリシーを作成します。

    注記

    Perform this step for each namespace you want to allow conntections into. Users with the Project Administrator role can create policies.

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-from-default-namespace
    spec:
      podSelector:
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              name: default

6.8.2. 新規プロジェクトのデフォルト NetworkPolicy の設定

クラスター管理者は、新規プロジェクトの作成時に、デフォルトのプロジェクトテンプレートを変更してデフォルトの NetworkPolicy オブジェクト (1 つ以上) の自動作成を有効にできます。これを実行するには、以下を行います。

  1. Create a custom project template and configure the master to use it, as described in Modifying the Template for New Projects.
  2. 必要な NetworkPolicy オブジェクトを含むようにテンプレートを編集します。

    $ oc edit template project-request -n default
    注記

    NetworkPolicy オブジェクトを既存テンプレートに含めるには、oc edit コマンドを使用します。現時点では、oc patch を使用してオブジェクトを Template リソースに追加することはできません。

    1. それぞれのデフォルトポリシーを objects 配列の要素として追加します。

      objects:
      ...
      - apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        metadata:
          name: allow-from-same-namespace
        spec:
          podSelector:
          ingress:
          - from:
            - podSelector: {}
      - apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        metadata:
          name: allow-from-default-namespace
        spec:
          podSelector:
          ingress:
          - from:
            - namespaceSelector:
                matchLabels:
                  name: default
      ...

6.9. HTTP Strict Transport Security の有効化

HTTP Strict Transport Security (HSTS) ポリシーは、ホストで HTTPS トラフィックのみを許可するセキュリティーの拡張機能です。デフォルトで、すべての HTTP 要求はドロップされます。これは、web サイトとの対話の安全性を確保したり、ユーザーのためにセキュアなアプリケーションを提供するのに役立ちます。

HSTS が有効にされると、HSTS はサイトから Strict Transport Security ヘッダーを HTTPS 応答に追加します。リダイレクトするルートで insecureEdgeTerminationPolicy 値を使用し、HTTP を HTTPS に送信するようにします。ただし、HSTS が有効にされている場合は、要求の送信前にクライアントがすべての要求を HTTP URL から HTTPS に変更するためにリダイレクトの必要がなくなります。これはクライアントでサポートされる必要はなく、max-age=0 を設定することで無効にできます。

重要

HSTS はセキュアなルート (edge termination または re-encrypt) でのみ機能します。この設定は、HTTP またはパススルールートには適していません。

ルートに対して HSTS を有効にするには、haproxy.router.openshift.io/hsts_header 値を edge termination または re-encrypt ルートに追加します。

apiVersion: v1
kind: Route
metadata:
  annotations:
    haproxy.router.openshift.io/hsts_header: max-age=31536000;includeSubDomains;preload
重要

haproxy.router.openshift.io/hsts_header 値にパラメーターのスペースやその他の値が入っていないことを確認します。max-age のみが必要になります。

必須の max-age パラメーターは、HSTS ポリシーの有効期間 (秒単位) を示します。クライアントは、ホストから HSTS ヘッダーのある応答を受信する際には常に max-age を更新します。max-age がタイムアウトになると、クライアントはポリシーを破棄します。

オプションの includeSubDomains パラメーターは、クライアントに対し、ホストのすべてのサブドメインがホストど同様に処理されるように指示します。

max-age が 0 より大きい場合、オプションの preload パラメーターは外部サービスがこのサイトをそれぞれの HSTS プリロードのリストに含めることを許可します。たとえば、Google などのサイトは preload が設定されているサイトの一覧を作成します。ブラウザーはこれらのリストを使用し、サイトと対話する前でも HTTPS 経由でのみ通信するサイトを判別できます。preload 設定がない場合、ブラウザーはヘッダーを取得するために HTTPS 経由でサイトと通信している必要があります。

6.10. スループットの問題のトラブルシューティング

OpenShift Container Platform でデプロイされるアプリケーションでは、特定のサービス間で非常に長い待ち時間が発生するなど、ネットワークのスループットの問題が生じることがあります。

Pod のログが問題の原因を指摘しない場合は、以下の方法を使用してパフォーマンスの問題を分析します。

  • ping または tcpdump などのパケットアナライザーを使用して Pod とそのノード間のトラフィックを分析します。

    たとえば、問題を生じさせる動作を再現している間に各ノードで tcpdump ツールを実行します。両サイトでキャプチャーしたデータを確認し、送信および受信タイムスタンプを比較して Pod への/からのトラフィックの待ち時間を分析します。待ち時間は、ノードのインターフェースが他の Pod やストレージデバイス、またはデータプレーンからのトラフィックでオーバーロードする場合に OpenShift Container Platform で発生する可能性があります。

    $ tcpdump -s 0 -i any -w /tmp/dump.pcap host <podip 1> && host <podip 2> 1
    1
    podip は Pod の IP アドレスです。以下のコマンドを実行して Pod の IP アドレスを取得します。
    # oc get pod <podname> -o wide

    tcpdump は 2 つの Pod 間のすべてのトラフィックが含まれる /tmp/dump.pcap のファイルを生成します。理想的には、ファイルサイズを最小限に抑えるために問題を再現するすぐ前と問題を再現したすぐ後ににアナライザーを実行することが良いでしょう。以下のようにノード間でパケットアナライザーを実行することもできます (式から SDN を排除する)。

    # tcpdump -s 0 -i any -w /tmp/dump.pcap port 4789
  • ストリーミングのスループットおよび UDP スループットを測定するために iperf などの帯域幅測定ツールを使用します。ボトルネックの特定を試行するには、最初に Pod から、次にノードからツールを実行します。iperf3 ツールは RHEL 7 の一部として組み込まれています。

iperf3 のインストールおよび使用についての詳細は、こちらの Red Hat ソリューションを参照してください。