PR

Project CalicoをKubernetesで使ってみる:ネットワークポリシー編

2018年12月11日(火)
野口 礼生(のぐち・ひろふゆ)

はじめに

これまでの回で、Calicoのアーキテクチャや構築方法を説明してきました。実際に商用環境などで使うことを考えると、必ず検討しなくてはならないのがセキュリティです。Calicoではコンテナなどのワークロードに対するネットワークセキュリティへのアプローチとして、「Network Policy」(ネットワークポリシー)という機能を備えています。

今回はCalicoのNetwork Policyについて説明し、前回までに構築したKubernetes環境を用いて実際にNetwork Policyを使ってみたいと思います。

マイクロサービスにおけるセキュリティ

Calicoがセキュリティ機能を備えているのはなぜでしょうか。Webサービスを中心としたクラウドネイティブアプリケーションはマイクロサービスアーキテクチャで実装されることが増えてきています。マイクロサービスアーキテクチャとは、機能単位に分割されたマイクロサービスの集合体として1つのサービスを構築してしまう考え方です。例えば、あるWebサービスを提供するためにフロントエンドサービスとバックエンドサービスがある場合、マイクロサービスアーキテクチャになると、フロントエンドサービスも複数のマイクロサービスの集合体で構成されます。このように実装されたサービスは、さらに他のサービスと連携して新たなサービスを提供するようになります。

複数のサービスが相互に通信する環境においては、従来のようにネットワークドメインの境界にファイアーウォールを設置するようなセキュリティの設計では、さまざまな脅威に対する対策として不十分になってきます。そこで、マイクロサービス単位にファイアーウォールを設定し、アクセスを制限するという考え方が重要になってきます。

従来アーキテクチャとマイクロサービスアーキテクチャにおけるセキュリティ
従来アーキテクチャとマイクロサービスアーキテクチャにおけるセキュリティ

しかしながら、この考え方に基づいてファイアーウォールの設定を一つ一つのサービスおよびPodに対して手動で投入していくというのは、Podのライフサイクルの面から考えても現実的ではありません。Kubernetesではこの課題に対してNetwork Policyという機能を持っています。そして、CalicoはKubernetesのネットワークプラグインとしてこの機能の実装を担っています。

Kubernetes Network Policy

CalicoのNetwork Policyを理解するために、KubernetesのNetwork Policyを説明します。

Kubernetes Network Policyとは、Podレベルのファイアーウォールルールを提供するセキュリティ機能です。これを使用することにより、クラスタ内でどのPodやサービスが相互にアクセスできるかを制御できます。

Kubernetes Network Policyを使用するには、ネットワークプラグイン側がそれに対応した機能を持っている必要があります。現在対応しているネットワークプラグインは、Calico、Weave、Ciliumなどがあります。Kubernetesのネットワークプラグインとしてよく目にするFlannelは、Flannel単体ではNetwork Policyに対応していません。そこで、CalicoをNetwork Policy機能のみで動作させ、Flannelと統合した「Canal」というプラグインも開発されています。Kubernetesのドキュメントで、Network Policyに対応したプラグインとそれぞれの特徴が紹介されています。

Kubernetes Network Policyの書き方

それではKubernetesのNetwork Policyの書き方を解説します。

Kubernetesにおける設定ファイルはYAMLかJSONで記述できますが、よりユーザーフレンドリーであるYAMLでの記述が一般的なので、今回もYAMLで書いていきます。

Kubernetes Network Policyの特徴は、許可された通信以外を拒否するホワイトリスト方式であるということです。specのpolicyTypesで指定した方向の通信を全て拒否する動作となっており、specのingress/egressに記載した条件を許可する動作となっています。ルールの詳細な記述方法はKubernetesのドキュメントに記載されています。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
 name: ”ポリシー名”
 namespace: ”ポリシーのネームスペース名”
spec:
 podSelector: ”適用するPod”
 policyTypes:
 - Ingress ”Ingressトラフィックをすべて拒否する”
 - Egress ”Egressトラフィックをすべて拒否する”
 ingress: ”許可するIngressトラフィックの条件”
 egress: ”許可するEgressトラフィックの条件”

CalicoのNetwork Policyについて

Kubernetesで定義されたNetwork Policyは、Calicoが解釈できるデータモデルでetcdに書き込まれ、最終的にはCalicoのNetwork Policyとしてワークロードエンドポイントに適用されます。CalicoのNetwork Policyが特徴的なのは、ワークロードエンドポイントだけではなくホストのインターフェースに適用できる点です。このCalicoの機能はHost Protection(ホストプロテクション)と呼ばれています。この機能を使用することで、ホストのインターフェースに対して、トラフィックの方向(Ingress/Egress)や制限方式(ホワイトリスト/ブラックリスト)、プロトコル(TCP/UDP/ICMP)、ポート番号など柔軟な制限をかけることが可能になります。

Calicoでの通信に制限をかける方法にはPolicyモデルとProfileモデルがあります。

Policyモデルでは、ルールの中でラベルを指定することで、ラベルに紐づいたエンドポイントに対してまとめて制限をかけることができます。Profileモデルでは、事前にルールを宣言し、エンドポイントの設定でProfileを指定することでエンドポイントに制限をかけることができます。どちらの方法を使用しても定義できるルールは同じですが、OpenStackやKubernetesなどのさまざまなオーケストレーターのプラグインとして使われることが想定されているため、オーケストレーター毎に適した定義方法を利用できるようになっています。

2つのネットワークポリシーモデル
2つのネットワークポリシーモデル

ちなみに、KubernetesやCalicoのNetwork PolicyはPod間の通信をTCP/IP(L3-4)で制限します。HTTPメソッド(GETやPOSTなど)といったアプリケーションレイヤー(L7)での制限や暗号化などには対応していません。アプリケーションレイヤーでルールを適用する、つまりマイクロサービスのセキュリティ対策としては、Istioやlinkerdなどを使用する必要が出てきます。

Kubernetes Network PolicyとCalicoのネットワークポリシーとの使い分け

CalicoのNetwork Policyが使用される場面は2つあります。

1つ目は、オーケストレーターのセキュリティ機能のプラグインとして暗黙的に使用される場合です。この場合、Network Policyの利用者はCalicoを直接操作することはありません。2つ目は、CalicoのNetwork Policyを直接使用する場合です。

  1. オーケストレーターからプラグインとして使用される場合
例を挙げると、Calicoプラグインを使用したKubernetesでネットワークポリシーを使用した場合などがこれに当たります。PodやDeploymentのルールを定義する際には、基本的にはKubernetesのネットワークポリシーを使用することが推奨されています。
  1. CalicoのNetwork Policyを直接使用する場合
Kubernetesのネットワークポリシーでは設定できない、Host ProtectionなどといったCalicoの機能を使用する場合のみ、Calicoのネットワークポリシーを使用する必要があります。

GKEとEKSの事例

これまで説明したように、CalicoのNetwork Policyの機能は、コンテナのセキュリティを考慮する上で非常に重要な役割を果たします。すでに商用環境にCalicoを使用している事業者もあります。ここでは、実際にCalicoのNetwork Policyが使用されている事例を2つ紹介します。

Google Kubernetes Engine(GKE)の事例(Google)

(「Introducing Network Policy support for Google Container Engine, with Project Calico and Tigera」Google Cloud Platform Blogより)

Google Cloud Platform Blogでは、「既存のFWはNorthSouthトラフィックに対して境界セキュリティを提供するが、コンテナ間のEastWestトラフィックのセキュリティには適していないという問題があり、Calicoが解決策となっている」と紹介されています。

Elastic Container Service(EKS)の事例(Amazon)

(「Exploring the Networking Foundation for EKS: amazon-vpc-cni-k8s + Calico」AWS Open Source Blogより)

AWS Open Source Blogでは、どのネットワークのアプローチを選択しても、Calicoのセキュリティ機能を使用できることが紹介されています。

実際にポリシーをかけてみる

当連載の第3回ではdefaultのネームスペースに対してNginxのコンテナをデプロイし、同じネームスペースにデプロイした、cURLがインストールされているPodからのアクセスを確認しました。今回はKubernetsのNetwork PolicyとCalicoのNetwork Policyをそれぞれ設定していきます。

用語解説
用語解説

Kubernetes Network Policyをかけてみる

Kubernetesのデフォルトでは、全てのPodが相互に通信できるようになっているため、アクセス制限をかけたい場合には明示的に設定する必要があります。

まずはじめに、「test」というネームスペースにデプロイしたPodからNginxにアクセスできることを確認します。その後に、KubernetesのNetwork PolicyでdefaultネームスペースのPodに対して、全てのアクセスを制限するルールと、同じネームスペースからのアクセスは許可するルールを設定します。そうすることにより、defaultネームスペースのPodからはcurlで(HTTP)アクセス可能ですが、testネームスペースのPodからはcURLで(HTTP)アクセスできなくなることを確認していきます。

Network Policy構成
Network Policy構成

まず、第3回の環境の確認として、NginxのPodがデプロイされていることを確認します。

k8s-master:~$ kubectl get pods -n default -o wide
NAME                       READY     STATUS    RESTARTS   AGE       IP                NODE
my-nginx-9d5677d94-48pmz   1/1       Running   0          3d        192.168.154.193   k8s-node-01
my-nginx-9d5677d94-z655m   1/1       Running   0          3d        192.168.44.193    k8s-node-02

Nginxのコンテナが「k8s-node-01」と「k8s-node-02」にデプロイされているのがわかります。それではまず、「test」ネームスペースを作成します。

k8s-master:~$ kubectl create namespace test
namespace "test" created

ネームスペースが作成できたか確認します。

k8s-master:~$ kubectl get namespaces
NAME          STATUS    AGE
default       Active    3d
kube-public   Active    3d
kube-system   Active    3d
test          Active    1m

「test」ネームスペースを作成できていることが確認できます。次に、作成したネームスペースに対してラベルを設定します。今回はtestネームスペースに対して、「test-label=default」というラベルを設定します。

k8s-master:~$ kubectl label namespace/default test-label=default
namespace "default" labeled

ラベルが設定できたか確認します。

k8s-master:~$ kubectl get namespaces --show-labels
NAME          STATUS    AGE       LABELS
default       Active    4d        test-label=default
kube-public   Active    4d        <none>
kube-system   Active    4d        <none>
test          Active    2h        <none>

defaultネームスペースに対して「test-label=default」というラベルを設定できていることが確認できます。次にtestネームスペースにcURLがインストールされているPodを立ち上げます。

k8s-master:~$ kubectl run curl --image=radial/busyboxplus:curl -i --tty --rm -n test
If you don't see a command prompt, try pressing enter.
[ root@curl-545bbf5f9c-gdww6:/ ]$

Podを立ち上げた状態で、別の画面から下記のコマンドを実行することで、testネームスペースにcURLがインストールされているPodが立ち上がっていることを確認できます。

k8s-master:~$ kubectl get pods --all-namespaces
NAMESPACE     NAME                                       READY     STATUS    RESTARTS   AGE
default       my-nginx-9d5677d94-48pmz                   1/1       Running   0          3d
default       my-nginx-9d5677d94-z655m                   1/1       Running   0          3d
kube-system   calico-etcd-dxb8s                          1/1       Running   0          4d
kube-system   calico-kube-controllers-559b575f97-29m7j   1/1       Running   0          4d
kube-system   calico-node-2mttf                          2/2       Running   0          3d
kube-system   calico-node-6snck                          2/2       Running   1          3d
kube-system   calico-node-bggsx                          2/2       Running   0          4d
kube-system   etcd-k8s-master                            1/1       Running   0          4d
kube-system   kube-apiserver-k8s-master                  1/1       Running   0          4d
kube-system   kube-controller-manager-k8s-master         1/1       Running   0          4d
kube-system   kube-dns-6f4fd4bdf-8xwwz                   3/3       Running   0          4d
kube-system   kube-proxy-22gs4                           1/1       Running   0          3d
kube-system   kube-proxy-f5mpg                           1/1       Running   0          4d
kube-system   kube-proxy-tc24n                           1/1       Running   0          3d
kube-system   kube-scheduler-k8s-master                  1/1       Running   0          4d
test          curl-545bbf5f9c-gdww6                      1/1       Running   0          43s

それではcURLがインストールされたPodからNginxのPod IPに対して、curlでアクセスを行います。ここではk8s-node-01上のNginx(192.168.154.193)に対してのみ確認を行います。

[ root@curl-545bbf5f9c-6fj7w:/ ]$ curl 192.168.154.193
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

testネームスペースのPodからdefaultネームスペースのNginxへのアクセスが確認できました。KubernetesではデフォルトとしてPod間の通信は制限されておらず、別のネームスペースに存在するPod間でも通信が可能なことがわかります。

それではdefaultネームスペースに対して、他のネームスペースからのアクセスを制限するネットワークポリシーを設定していきます。「deny-all-allow-default.yaml」というファイルを作成し、下記の設定を記述します。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-allow-default
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector :
       matchLabels:
         test-label: default

今回の設定内容は、defaultネームスペースに「deny-all-allow-default」という名前のネームスペースからの入力トラフィックを許可するものです。「deny-all-allow-default」ネームスペースは全てのPodに対して入力トラフィックを拒否し、「test-label=default」にマッチするラベルを持っています。つまり、defaultネームスペースのPodへアクセスできるのはdefaultネームスペースのPodからのみで、他のネームスペースからのアクセスは拒否する設定になります。

それでは作成したネットワークポリシー(deny-all-allow-default.yaml)を適用していきましょう。

k8s-master:~$ kubectl apply -f deny-all-allow-default.yaml
networkpolicy "deny-all-allow-default" created

ネットワークポリシーが作成された確認を行います。

k8s-master:~$ kubectl get networkpolicy -o wide --all-namespaces
NAMESPACE   NAME                     POD-SELECTOR   AGE
default     deny-all-allow-default   <none>         46s

defaultというネームスペースに対して「deny-all-allow-default」というポリシーを作成できていることが確認できます。

それではdefaultネームスペースと、cURLがインストールされているtestネームスペースのPodからcurlでアクセスを行い、アクセスが制限されているかの確認を行います。まずはdefaultネームスペースから確認します。

k8s-master:~$ kubectl run curl --image=radial/busyboxplus:curl -i --tty --rm -n default
If you don't see a command prompt, try pressing enter.
[ root@curl-545bbf5f9c-fb7hs:/ ]$
[ root@curl-545bbf5f9c-fb7hs:/ ]$ curl 192.168.154.193
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

defaultネームスペースでは問題なくアクセスできていることがわかります。次にtestネームスペースも確認していきます。

k8s-master:~$ kubectl run curl --image=radial/busyboxplus:curl -i --tty --rm -n test
If you don't see a command prompt, try pressing enter.
[ root@curl-545bbf5f9c-wm5cg:/ ]$
[ root@curl-545bbf5f9c-wm5cg:/ ]$ curl 192.168.154.193
curl: (7) Failed to connect to 192.168.154.193 port 80: Connection timed out

testネームスペースのPodからは、defaultネームスペースのNginx Podに対してアクセスが制限されていることを確認できました。

calicoctlからworkloadのNetwork Policyを確認する

calicoctlコマンドを使用して、kubernetesでdefaultネームスペースに作成した「deny-all-allow-default」というネットワークポリシーがCalicoで設定されていることを確認していきます。

k8s-master:~$ ./calicoctl get networkpolicy
NAME
knp.default.deny-all-allow-default

Calicoに「knp.default.deny-all-allow-default」というネットワークポリシーが作成されていることがわかります。「knp.default.deny-all-allow-default」というCalicoのネットワークポリシーの設定を確認していきましょう。

/calicoctl get networkpolicy knp.default.deny-all-allow-default -o yaml
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
  creationTimestamp: 2018-03-19T02:26:46Z
  name: knp.default.deny-all-allow-default
  namespace: default
  resourceVersion: "4241"
  uid: f8af771d-2b1c-11e8-b6bd-525400073a83
spec:
  ingress:
  - action: Allow
    destination: {}
    source:
      namespaceSelector: test-label == 'default'
      selector: projectcalico.org/orchestrator == 'k8s'
  order: 1000
  selector: projectcalico.org/orchestrator == 'k8s'
  types:
  - Ingress

defaultネームスペースに対して、「test-label=default」のラベルを持ったネームスペースからの通信を許可する設定がされており、KubernetesのNetwork PolicyがCalicoのNetwork Policyで設定されていると確認できました。

iptablesを確認してみる

次に、CalicoのNetwork Policyがiptablesで実装されているかを確認していきます。

CalicoのNetwork Policyの設定は、iptablesとipsetを使用して行われます。ipsetとはIPアドレスやMACアドレスなどを集合として扱うiptablesの補助技術で、ipsetの情報を表示するにはipsetのパッケージをインストールする必要があります。Network PolicyはPodが存在するホストに設定されるため、今回はk8s-node-01で確認していきます。

先ほど設定したPolicyではdefaultネームスペースに対しての入力トラフィックを拒否する設定を行ったため、defaultネームスペースに存在するNginxPodのIPへの通信を拒否する設定がiptablesに設定されます。

ipsetコマンドを使用することで、NginxPodのIPを「cali4-s:Hcn0P2TmkHTJcBdhlFhs23C」という名前で集合として扱えるようにしていることがわかります。

k8s-node-01:~$ sudo ipset list cali4-s:Hcn0P2TmkHTJcBdhlFhs23C
Name: cali4-s:Hcn0P2TmkHTJcBdhlFhs23C
Type: hash:ip
Revision: 4
Header: family inet hashsize 1024 maxelem 1048576
Size in memory: 224
References: 3
Members:
192.168.154.193
192.168.44.193

以下は「sudo iptables -L」コマンドの抜粋になりますが、ipsetで設定した「cali4-s:Hcn0P2TmkHTJcBdhlFhs23C」を条件に処理していることがわかります。

Chain cali-pi-_2ZqniN3ecx1Jf94lHPG (1 references)
target     prot opt source               destination
MARK       all  --  anywhere             anywhere             /* cali:75z4Tuuv5eJR6QB2 */ match-set cali4-s:Hcn0P2TmkHTJcBdhlFhs23C src MARK or 0x1000000
RETURN     all  --  anywhere             anywhere             /* cali:ALJPOl24E6kB7wLn */ mark match 0x1000000/0x1000000

今回はCalicoでiptablesが設定されていることのみを確認し、iptablesの内容の詳細については割愛します。

ここまではKubernetesのNetwork Policyを使用しました。次はCalicoのNetwork Policyを使用しHostProtectionの設定を行います。

HostProtectionをかけてみる

KubernetesのNetwork Policyはワークロードエンドポイントに適用されますが、CalicoのNetwork Policyはホストのインターフェースにも適用できます。実際にHostProtectionを使用する例としては、Calicoノードへの不正アクセスを防ぐために、CalicoノードへSSH接続できるIPを制限したい場合などがあります。

ちなみにCalicoには、Calicoノードの管理に必要な通信を制限できないようにする「Failsafe rules」という機能があります。SSHのポートはFailsafe rulesに含まれているため、SSH接続を制限するにはFailsafe rulesを無効にする必要があります。Failsafe rulesに設定されている通信の内容はCalicoのドキュメントに記載されています。今回はマスターに対しHostProtectionを設定し、ノードからマスターへのICMPを制限していきます。

HostProtection構成
HostProtection構成

実際にICMPの制限をかける前に、ノードからマスターに対してICMPの疎通確認を行います。

k8s-node-01:~$ ping  -c 5 172.16.0.10
PING 172.16.0.10 (172.16.0.10) 56(84) bytes of data.
64 bytes from 172.16.0.10: icmp_seq=1 ttl=64 time=1.09 ms
64 bytes from 172.16.0.10: icmp_seq=2 ttl=64 time=5.28 ms
64 bytes from 172.16.0.10: icmp_seq=3 ttl=64 time=0.809 ms
64 bytes from 172.16.0.10: icmp_seq=4 ttl=64 time=1.08 ms
64 bytes from 172.16.0.10: icmp_seq=5 ttl=64 time=0.771 ms

--- 172.16.0.10 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4003ms
rtt min/avg/max/mdev = 0.771/1.810/5.286/1.743 ms

ノード1からマスターに対してICMP疎通できていると確認できました。それでは実際に設定を行っていきます。Profileでルールを宣言し、HostEndpointでProfileを紐付けることでHostProtectionをかけることができます。まずProfileの設定を「deny-icmp-profile.yaml」というファイルに記述します。

apiVersion: projectcalico.org/v3
kind: Profile
metadata:
  name: deny-icmp-profile
spec:
  egress:
  - action: Allow
  ingress:
  - action: Deny
    protocol: ICMP
  - action: Allow

ICMPの入力トラフィックを拒否し、他の入力トラフィックと出力トラフィックを許可するProfileの設定になります。Profileを作成するだけではどこにも紐づかないため、このProfileを有効にするためにはHostEndopointの設定でProfileを指定する必要があります。HostEndpointの設定を「master-hostendpoint.yaml」というファイルに記述します。

apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
  name: master-hostendpoint
spec:
  interfaceName: enp0s3
  node: k8s-master
  expectedIPs:
  - 172.16.0.10
  profiles:
  - deny-icmp-profile

マスターのipが172.16.0.10でインターフェース名がenp0s3であるインターフェースに「deny-icmp-profile」というprofileを紐付ける設定になります。まずProfileを適用します。

k8s-master:~$ ./calicoctl apply -f deny-icmp-profile.yaml
Successfully applied 1 'Profile' resource(s)

Profileが作成された確認を行います。

./calicoctl get profiles
NAME
deny-icmp-profile
kns.default
kns.kube-public
kns.kube-system
kns.test

「deny-icmp-profile」というProfileが作成されていることが確認できます。次に、HostEndpointを適用していきます。

k8s-master:~$ ./calicoctl apply -f master-hostendpoint.yaml
Successfully applied 1 'HostEndpoint' resource(s)

HostEndpontが作成された確認を行います。

k8s-master:~$ ./calicoctl get hostendpoint
NAME                  NODE
master-hostendpoint   k8s-master

「master-hostendpoint」というHostEndpointが作成されていることが確認できます。それでは実際にマスターに対してICMPの疎通を確認しましょう。

k8s-node-01:~$ ping -c 5 172.16.0.10
PING 172.16.0.10 (172.16.0.10) 56(84) bytes of data.

--- 172.16.0.10 ping statistics ---
5 packets transmitted, 0 received, 100% packet loss, time 4030ms

ホストエンドポイントへの通信が制限できていることが確認できました。

終わりに

今回はCalicoのNetwork Policyについて紹介しました。コンテナなどのワークロードに対するネットワークセキュリティへのアプローチとしてCalicoが重要な役割を担っていることがお分かりいただけたと思います。

本記事ではあまり触れていませんが、CalicoはIstioなどのサービスメッシュを実現するOSSなどとも連携して、より堅牢なセキュリティ機能を実現することを目指しています。コンテナネットワークにおけるセキュリティは今後ますます重要になってくるので、その取っ掛かりとしてCalicoを使ってみるのも良いかもしれません。

著者
野口 礼生(のぐち・ひろふゆ)
コムシス情報システム株式会社

1992年、千葉県生まれ。2014年の入社以来、ネットワークエンジニアとして主に携帯キャリアのネットワーク設計に従事。2017年6月より沖縄オープンラボラトリに所属し、Project CalicoやONOS、CORDなどのSDN/NFVを中心とした検証に携わる。

連載バックナンバー

Think IT会員サービス無料登録受付中

Think ITでは、より付加価値の高いコンテンツを会員サービスとして提供しています。会員登録を済ませてThink ITのWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

他にもこの記事が読まれています