LabHub

ブログ

CKA_9_Network

한국어English日本語

この記事は、Udemyの講座 https://www.udemy.com/course/certified-kubernetes-administrator-with-practice-tests および https://kodekloud.com/ の内容を学習しながらまとめたものです。

201 Switching Routing

Switchは同一ネットワーク内のデバイスを接続します。

Network

Routerは2つ以上の分離されたネットワークを接続します。あるネットワークから別のネットワークへパケットが移動する際にはGatewayを経由しますが、これはRouterに接続されたアドレスを意味します。

Network

カーネルのルーティングテーブルは以下のコマンドで確認できます。

root@latte01:~# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.219.1   0.0.0.0         UG    100    0        0 enp2s0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 enp2s0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.219.0   0.0.0.0         255.255.255.0   U     100    0        0 enp2s0

アクセスしたいすべてのIPアドレスを明示する代わりに、0.0.0.0 を入力してすべてのネットワークを表すことができます。

Network

外部へ出るルーターと内部ネットワークへ出るルーターが分離されている場合、ルーティングテーブルに別途指定できます。

Network

LinuxマシンをRouterとしてセットアップするにはどうすればよいでしょうか?以下のようにBに2つのネットワークインターフェースを付与した上で、AからBへpingを送っても、正常にpingは返ってきません。その理由は、Linuxではセキュリティ上の問題から、デフォルトでパケットの転送(forward)がブロックされているためです。

Network

Bのマシンで echo 1 > /proc/sys/net/ipv4/ip_forward を実行してforwardを有効にすると、正常にRouterとして動作するようになります。再起動後も同じ設定を維持するには、/etc/sysctl.confnet.ipv4.ip_forward =1 を設定します。

202 DNS

/etc/hosts にHost Bを「db」として登録すると、IPの代わりに文字列の名前を使用できるようになります。/etc/hosts はローカルのネームサーバー(DNS)と呼ばれます。ただし、実際に「db」と呼ばれるサーバーのホスト名が「db」ではない場合があります。また、サーバー数が増えたり、IPアドレスが変更される状況では管理がさらに困難になります。

Network

IPアドレスとホスト名のマッピングを管理するサーバーをDNSサーバーと呼びます。 すべてのサーバーは /etc/resolv.conf というファイルにネームサーバーを登録して使用します。

Network

ネームサーバーを利用するからといって、ローカルの /etc/hosts ファイルが使えなくなるわけではなく、同様に使用可能です。IP→ホスト名のマッピング情報を検索する際、DNSサーバーよりも /etc/hosts ファイルの内容が優先的に検索されます。この順序は /etc/nsswitch.conf のhostsに登録されています。デフォルトは files dns となっており、これは /etc/hosts を先に検索するという意味です。

8.8.8.8はGoogleが運営する有名なネームサーバーです。複数のネームサーバーをここに定義できます。

DNSサーバーでapps.google.comを検索する場合、以下のようにDNSツリーをたどってIPアドレスを取得します。一度取得したらローカルにキャッシュして再利用します。

Network

IPをホスト名に変換するのをAタイプレコードと呼びます。エイリアス(別名)を持たせるのをCNAMEと呼びます。

Network

nslookup <domain_name> でネームサーバーとIPを調べることができますが、注意すべき点はnslookupは /etc/hosts を検索しないということです。このため、実際のローカルでのネットワーク動作と異なる場合があることを認識しておく必要があります。

digもネームサーバーを調べるのに優れたツールです。

nslookup www.google.com
dig www.google.com

204 Network Namespaces

コンテナには独自のRouting TableとARP Tableが存在します。独立したネットワーク名前空間が存在するのです。

Network

新規ネットワーク名前空間を作成するには ip netns add <namespace_name> を入力します。ip ns コマンドで作成された名前空間を確認できます。

名前空間内部でipコマンドを使用するには以下のようにします。link コマンド入力時、ホストとは異なりloopback link以外は確認できません。arproute コマンドも同様です。

Network

新しい名前空間は外部への接続が設定されていないため、他の名前空間との通信のためにはネットワーク接続を設定する必要があります。この接続プロセスは物理的なケーブルを接続すること(virtual cable)に似ています。

Network

設定が完了すると、ARPテーブルを照会した際に相手の情報が含まれています。ただし、ホストのARPテーブルにはこれに関連する情報は全くありません。

Network

2つではなくそれ以上の名前空間が存在する場合はどうすればよいでしょうか?この場合、仮想スイッチを作成する必要があります。Linux BridgeとOpen vSwitchが最も有名で、今回はLinux Bridgeについて説明します。

Network

Linux Bridgeを作成する前に、以前作成したredとblueのvirtual cableを削除します。ip -n red link del veth-red で削除できます。

以下の方法でLinux Bridgeに名前空間を接続すると、名前空間同士で通信ができるようになります。

Network

Network

BridgeとHost間の接続を設定するにはどうすればよいでしょうか?BridgeにIPを付与すれば完了です。

Network

このように作成した4つの名前空間はプライベートネットワークであるため、外部との通信はできません。

Network

以下のようにblueのルーティングテーブルにgatewayとしてBridge Networkを設定します。

Network

そして以下のコマンドで 192.168.15.0/24 から入ってくるパケットをホストのパケットとして設定すると、pingが可能になります。

Network

最後にデフォルトゲートウェイまで設定すれば完了です。

Network

外部からプライベートネットワークにアクセスするには2つの方法があります。NATを利用するか、ポートフォワーディングを利用する方法です。

Network

206 Docker Networking

Dockerは内部的に docker0 というBridgeを作成し、名前空間間およびホストマシンとの通信に使用します。これは docker network ls コマンドで確認できます。

Network

Network

Dockerでコンテナを起動すると、名前空間が1つ作成されると考えてください。そしてその名前空間とdocker0 Bridgeは、先ほど見たvirtual cableで接続されます。

Network

Network

ポートフォワーディングも先ほど見たのと同様に、iptablesにNATルールを追加して行います。

Network

ポートフォワーディングが設定された後、iptables -nvL -t nat コマンドでiptablesを確認すると、DNATが追加されていることが確認できます。

Network

207 CNI

以前、Network Namespaceを作成してネットワークを接続するプロセスと、Dockerでネットワークを接続するプロセスを一緒に見てきました。この2つは非常に似ています。rkt、Mesos、Kubernetesも同じ問題を解決する必要があります。CNI(Container Network Interface)は、Kubernetesでコンテナ間のネットワーク通信のために実装すべき事項を定義しています。そのため、CNIに準拠して実装されたプラグインは、どのランタイムでも正常に動作します。

Network

DockerはCNI標準に準拠しておらず、独自のCNM(Container Network Model)を持っているため、CNI(Flannel、Weaveworks)を使用できません。

Network

etcdプロセスが使用中のポートの確認方法:

$ netstat -anp | grep etcd
tcp        0      0 192.5.203.6:2379        0.0.0.0:*               LISTEN      3644/etcd
tcp        0      0 127.0.0.1:2379          0.0.0.0:*               LISTEN      3644/etcd
tcp        0      0 192.5.203.6:2380        0.0.0.0:*               LISTEN      3644/etcd
...

2379ポートはetcdがすべてのKubernetes Control Planeコンポーネントと通信する際に使用するポートで、2380はピア接続に使用するポートです。

212 Pod Networking

Kubernetesはすべてのpodに固有のIPアドレスを付与し、すべてのpod間でNATなしに通信可能なモデルを構築しました。このネットワークモデルを構築するために、Kubernetesはどのような問題を解決する必要があったのでしょうか?CNI標準に準拠して作られたさまざまなネットワークプラグインがこれらを解決しました(Flannel、Weave net、Cilium)。

Network

まず、すべてのノードにBridge Networkを作成し、Podが作成されるたびにネットワーク名前空間とBridgeに接続されるvethを生成します。これにより、1つのノード内にあるPod同士は通信可能な状態になります。しかし、別のノードにあるPodとの通信はまだできません。

Network

各ノードのルーティングテーブルに以下のようにgatewayを設定すれば、他のノードとのネットワーク通信も問題なく行えるようになります。

Network

概念的にはそれほど複雑ではありませんが、数百〜数千台のノードがある環境のKubernetesクラスターに適用するのは容易ではありません。しかし、CNIがこれを解決してくれるため、大きな心配は不要です。CNIは複雑なスクリプトを ADDDELETE にグループ化して管理・実行できるように提供しています。

これらのスクリプトは /etc/cni/net.d/net-script.conflist/opt/cni/bin/net-script.sh にあり、ユーザーが直接これらのスクリプトを使用することもできます。

Network

213 CNI in Kubernetes

network-pluginはkubelet.serviceで設定可能です。CNIの実行バイナリは /opt/cni/bin に位置し、設定ファイルは /etc/cni/net.d 配下にあります。

Network

実際にBridge Networkの構成に使用される設定ファイルは以下のようになっています。

Network

Bridge Networkの範囲を知りたい場合は、ip link でBridge Network名を見つけ、ip addr show で調査します。

master-node
$  ip addr show weave
4: weave: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue state UP group default qlen 1000
    link/ether be:b5:e6:4f:f0:c1 brd ff:ff:ff:ff:ff:ff
    inet 10.244.0.1/16 brd 10.244.255.255 scope global weave
       valid_lft forever preferred_lft forever
worker-node
$ ip addr show weave
4: weave: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1376 qdisc noqueue state UP group default qlen 1000
    link/ether aa:be:68:65:bf:37 brd ff:ff:ff:ff:ff:ff
    inet 10.244.192.0/16 brd 10.244.255.255 scope global weave
       valid_lft forever preferred_lft forever

223 Service Networking

Serviceがデプロイされると、どのノードにデプロイされていても他のサービスから利用できる必要があります。このために、KubernetesではServiceにCluster IPを作成します。これにより、実際のPodのIPが変わっても、Serviceを使用する側はCluster IPを使用するため、シームレスに運用できます。クラスター外部からIPにアクセスする必要がある場合、Cluster IPは使用できません。この場合、NodePortというServiceで外部にエンドポイントを提供できます。これを可能にするのはkube-proxyです。cluster-ipの範囲はkube-api-serverの起動時に引数として入力する値です。

Network

Network

実際にiptablesでサービス名を検索すると、Cluster IPと実際のPodのIPがDNATとして設定されていることが確認できます。

Network

ip addr でBridgeのネットワーク範囲を確認できます。

226 DNS in kubernetes

Kubernetes内部でもDNSを利用できます。Serviceを作成するとCluster IPが生成され、このCluster IPはKube DNSにサービス名で登録されます。他のPodからCluster IPではなくホスト名(web-service)でアクセスしても問題なくアクセスできます。もちろん、同じnamespaceにある場合の話で、別のnamespaceにあるPodからアクセスするには web-service.apps でアクセスする必要があります。

Network

Network

ServiceではないPodはDNSに自動的に登録されません。設定を通じて登録できますが、この場合ホスト名はIPアドレスの .- に置換したものが設定されます。

Network

227 Core DNS in kubernetes

CoreDNSはkube-system namespaceで実行されるReplicaSet(Deployment)です。 /etc/coredns/Corefile でCoreDNSに関する設定ができます。CoreDNSの設定値はConfigMapに保存され、この値も変更可能です。

Network

CoreDNSは kube-dns という名前でクラスター内部からアクセス可能なエンドポイントを作成し、すべてのPodの /etc/resolv.conf のnameserverにこのDNSサーバーのIPアドレスが自動的に記入されます。

Network

ホスト名だけを入力してもFQDN(Fully Qualified Domain Name)を取得できますが、その理由は先ほど見た /etc/resolv.conf 内部の search に設定された上位ドメインのためです。

Network

Pod内部でnslookupした結果をローカルにコピーする方法:

kubectl exec -it hr -- nslookup mysql.payroll > /root/CKA/nslookup.out

230 Ingress

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  namespace: critical-space
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  rules:
  - http:
      paths:
      - path: /pay
        pathType: Prefix
        backend:
          service:
           name: pay-service
           port:
            number: 8282

クイズ

Q1: 「CKA_9_Network」の主なトピックは何ですか? CKA_9_Network

Q2: この記事の重要なポイントは何ですか? CKA_9_Network

Q3: この記事の概念を実践にどう適用できますか? 記事全体で議論されている実践的な例やパターンを参考にしてください。

コメント

まだコメントはありません。

ログインするとコメントできます