Skip to content

Commit

Permalink
Add files for ICTSC2024 preround
Browse files Browse the repository at this point in the history
  • Loading branch information
proelbtn committed Dec 13, 2024
1 parent 7cf67da commit 1a4f0e1
Show file tree
Hide file tree
Showing 16 changed files with 1,203 additions and 0 deletions.
Binary file added public/images/2024-pre-round-2nd/got-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/2024-pre-round-2nd/got-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/2024-pre-round-2nd/got-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/2024-pre-round-2nd/isi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/2024-pre-round-2nd/kob.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/2024-pre-round-2nd/mys.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/2024-pre-round-2nd/yfj.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions src/content/blog/2024-pre-round-2nd/2024pr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: "ICTSC2024 二次予選 問題解説まとめ"
description: "ICTSC2024 二次予選 問題解説まとめ"
tags: [ICTSC2024,問題解説まとめ]
pubDate: 2024-12-22T00:00:00
slug: "2024/12/14/ictsc2024pr"
draft: false
renderer: "md"
sticky: true
---

ICTSC2024に参加してくださった皆さん、お疲れ様でした!

ICTSC2024 二次予選で出題した問題の問題文、及び問題解説を公開します。
ぜひ今後の研鑽にご利用いただければと思います。


* [ICTSC2024 二次予選 問題解説: [NAO] ユーザが作成できない](./nao)
* [ICTSC2024 二次予選 問題解説: [GOT] 何もかもが繋がらない](./got)
* [ICTSC2024 二次予選 問題解説: [KOB] VyOS初めてです。](./kob)
* [ICTSC2024 二次予選 問題解説: [ISI] Welcome to Kubernetes](./isi)
* [ICTSC2024 二次予選 問題解説: [MYS] DNSって難しい。](./mys)
* [ICTSC2024 二次予選 問題解説: [YFJ] どちらのプロトコルも30年選手](./yfj)
* [ICTSC2024 二次予選 問題解説: [NGX] にゃーん](./ngx)
* [ICTSC2024 二次予選 問題解説: [MNG] MongoDBってなんですか?](./mng)

また、それぞれの配点, 平均点, 最高点は以下の通りです。

| 問題コード | 配点 | 回答チーム数 | 平均点 | 最高点 |
| ------------ | ---: | -----------: | -----: | -----: |
| NAO | 50 | 36 | 45.83 | 50 |
| GOT | 150 | 19 | 58.74 | 150 |
| KOB | 50 | 27 | 30 | 50 |
| ISI | 150 | 21 | 45.24 | 150 |
| MYS | 100 | 29 | 65.52 | 100 |
| YFJ | 100 | 28 | 72.14 | 100 |
| NGX | 100 | 31 | 94.84 | 100 |
| MNG | 100 | 27 | 38.3 | 99 |
| **(合計)** | 800 | --- | 450.6 | --- |
183 changes: 183 additions & 0 deletions src/content/blog/2024-pre-round-2nd/got.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
---
title: "ICTSC2024 二次予選 問題解説: [GOT] 何もかもが繋がらない"
description: "ICTSC2024 二次予選 問題解説: 何もかもが繋がらない"
tags: [ICTSC2024,問題解説]
pubDate: 2024-12-14T12:00:00
slug: "2024/12/14/ictsc2024pr/got"
draft: false
renderer: "md"
sticky: false
---

# 問題文

新卒で就職したあなたは、データセンターNWの構築するチームに配属されました。既存SWのEoSLに伴い、チームは新しいNWとしてVXLAN/EVPNを用いたL2透過なNWを構築して、クライアント - サーバ間のHTTP通信を通そうと日々励んでいました。しかし、同僚が全員突然退職してしまいました。残された環境を見ると、クライアント・サーバ間の通信がまだ上手くできていなさそうです。全ての問題を特定し、解決に導いて、会社のヒーローになりましょう。

## 前提条件

* アンダーレイのルーティングプロトコルはeBGPを使うこと
* オーバレイのEVPNはLoopbackアドレス同士でネイバーを貼ること
* Static Route含めその他のルーティングプロトコルは使用しないこと
* IPアドレス・AS番号などの設定は構成図に従い、変更しないこと
* RTのbridge/ethernetインタフェースの設定は変更しないこと
* 終了状態②においては、クライアントはsv-1の /home/user/client.pyが、サーバはsv-2で稼働するapacheがそれぞれの役割を担う
* sv-2の/etc/apache2配下のファイルの中身は変更しないこと
* sv-1の/home/user/client.pyはtry句の中身のみを変更すること
* 環境の制約を回避するためにサーバが互いのMACアドレスを静的に学習する設定を入れているので変更しないこと

## 構成図

![](/images/2024-pre-round-2nd/got-1.png)

## 初期状態

* sv-1とsv-2でNWの疎通性が無い = pingが通らない
* sv-1とsv-2がそれぞれクライアント・サーバとして機能すべきだが、HTTP通信が通らない

![](/images/2024-pre-round-2nd/got-2.png)

## 終了状態

* ①sv-1とsv-2でpingを用いた同セグ通信が通る
* ②sv-1のclient.pyを用いてsv-2のapacheからの"Hello ICTSC!!!"というHTTPレスポンスがターミナル上に出力される

![](/images/2024-pre-round-2nd/got-3.png)


## 回答にあたって意識してほしいこと

* 問題を起こしている原因に対する解決策を提示するだけではなく、「そもそもの構成がどういうものか」「問題となっている設定が何をするための設定なのか」「どうして現状の設定だと問題を引き起こすのか」「提示した解決策が問題をどう解決しているのか」など全体像を含めて記述していただきたいです
* 冗長にする必要は無いですが、「こんなところも理解しているよ」というのを回答に盛り込んでいただけると、高得点に繋がります

# 解説

## 回答例

このNWが繋がらない事象は5つの問題によって引き起こされております。

1つ目は、eBGPネイバーを張れていない点です。\
`show ip bgp neighbors`の結果から、eBGPのネイバー確立が失敗していることが分かります。eBGP以外のルーティングプロトコルが使えないという前提条件から、前任者がやろうとしていたLoopbackアドレスをeBGPネイバーとして指定する方法は使わずに、直接接続されているIPアドレス同士でeBGPネイバーを張ることでアンダーレイのネイバーを確立します。また、この設定は、VXLANによってカプセル化されたパケットを転送するためのルーティング設定となります。\
以下が修正内容です。
```bash
rt-1
(誤)
set protocols bgp neighbor 2.2.2.2 address-family ipv4-unicast
(正)
set protocols bgp neighbor 192.168.20.34 address-family ipv4-unicast
set protocols bgp neighbor 192.168.20.34 remote-as '65102'

rt-2
(誤)
set protocols bgp neighbor 1.1.1.1 address-family ipv4-unicast
set protocols bgp neighbor 3.3.3.3 address-family ipv4-unicast

(正)
set protocols bgp neighbor 192.168.20.33 address-family ipv4-unicast
set protocols bgp neighbor 192.168.20.33 remote-as '65101'
set protocols bgp neighbor 192.168.20.66 address-family ipv4-unicast
set protocols bgp neighbor 192.168.20.66 remote-as '65103'

rt-3
(誤)
set protocols bgp neighbor 2.2.2.2 address-family ipv4-unicast
(正)
set protocols bgp neighbor 192.168.20.65 address-family ipv4-unicast
set protocols bgp neighbor 192.168.20.65 remote-as '65102'

```

2つ目は、EVPNのネイバーを貼れていない点です。\
前提条件を見るとLoopbackアドレスを使ってEVPNのネイバーを貼ることが要求されています。1つ目の問題点を解消した結果、eBGPによって、直接接続されているNWのうちLoopbackアドレスのNWが広報されており、各ルータのLoopbackアドレスに到達性を確保できている状態ではあります。ですが、パケットキャプチャをしてみるとEVPNのネイバーを貼るBGPメッセージの送信元IPが物理インタフェースのIPで送信されていることが分かります。従って、EVPNのネイバーを貼るBGPメッセージをLoopbackアドレスによって送付するためのコンフィグを設定する必要があります。\
以下が修正内容です。
```bash
rt-1
(誤)
empty
(正)
set protocols bgp neighbor 2.2.2.2 update-source 'lo'

rt-2
(誤)
empty
(正)
set protocols bgp neighbor 1.1.1.1 update-source 'lo'
set protocols bgp neighbor 3.3.3.3 update-source 'lo'

rt-3
(誤)
empty
(正)
set protocols bgp neighbor 2.2.2.2 update-source 'lo'
```

3つ目は、SV-RT間のタグ有無が異なっている点です。\
rt-1とsv-1が接続されているインタフェースを確認すると、rt-1側はタグ無しのポート、sv-1側はタグ有りのポートとして設定されていることが分かります。ルータのbridge/ethernetインタフェースの設定変更してはいけないという前提条件から、sv-1側をタグ無しのポートに変更することで問題を解消する必要があります。\
以下が修正内容です(sv-1の`/etc/netplan/02-ictsc.yaml`
)。修正をしたのち、`sudo netplan apply` によって変更を反映します。
```bash
(誤)
network:
version: 2
ethernets:
eth1:
macaddress: 00:00:5e:00:01:01
dhcp4: false
vlans:
vlan.100:
id: 100
link: eth1
addresses: [192.168.20.1/27]
optional: false

(正)
network:
version: 2
ethernets:
eth1:
macaddress: 00:00:5e:00:01:01
addresses: [192.168.20.1/27]
dhcp4: false
```

ここまでの3点を解消すると、VXLAN/EVPNを通した同セグ通信がSV間で可能になり、終了状態①を満たします。終了条件②を満たすために、HTTP通信の成功を阻んでいる残り2つの問題点を解消します。

4つ目は、GETリクエストのフォーマットが正しくない点です。\
クライアント通信に使われる`/home/user/client.py`の中身とsv-2の`/etc/apache2`配下の設定ファイルを確認すると、実現しようとしているHTTP通信は、Authorizationヘッダを用いて81番ポート向けに行われていることが分かります。さらに、`/home/user/client.py`を実行した結果を確認すると、Bad RequestでありHTTPリクエストのフォーマットが正しくないという状態です。そこで`/home/user/client.py`のGETリクエストの中身を見てみると、HTTP1.1が使われているにもかかわらず、Hostヘッダが存在していないことが分かります。HTTP1.1においてはHostヘッダは必須であり、Hostヘッダが存在していないことで、HTTPリクエストとして成立していないことが分かります。対処方法としては、Hostヘッダを追加するか、Hostヘッダが無くてもAuthorizationヘッダを使うことが出来るHTTP1.0を使う、等の方法が考えられます。\
以下は修正内容の一例です(`/home/user/client.py`)。

```bash
(誤)
http_request = (
f"GET {request_path} HTTP/1.1\r\n"
f"Authorization: Basic {auth_base64}\r\n"
f"\r\n"
)

(正)
http_request = (
f"GET {request_path} HTTP/1.0\r\n"
f"Authorization: Basic {auth_base64}\r\n"
f"\r\n"
)
```

5つ目は、レスポンス表示のバッファサイズが小さい点です。\
4つ目の問題点を解消したことで、HTTP通信自体が成立する状態になりました。しかし、レスポンスが上手く表示されていないのは、`/home/user/client.py`のレスポンス表示のバッファサイズが小さいことが原因です。\
以下は修正内容の一例です(`/home/user/client.py`)。

```bash
(誤)
response = s.recv(16)

(正)
response = s.recv(4096)
```

以上で、全ての問題が解消され、終了状態②を満たします。

## 作問者コメント
本問題はVXLAN/EVPNを題材としつつ、NWの基本的な理解度を試す問題となっております。一見とっつきにくい題材ですが、アンダーレイやオーバーレイといった概念に慣れている人や、BGPに対して抵抗が無い人には、比較的スムーズに解ける問題になっていました。\
VXLAN/EVPNの技術自体は目新しいものではありませんが、複数の技術要素が組み合わさっていることや、使い方によってその言葉が示す中身が大きく異なるため、作問者は理解するのにかなり時間がかかりました。\
初学者の方は、L2の基礎 -> BGP -> アンダーレイ・オーバーレイの概念 -> VXLAN単体 -> EVPNという順番で学習することをお勧めします。\
下記に記した回答例以外にも、BGP Unnumberedを使ってIPv6のリンクローカルアドレスを使用してアンダーレイのBGPを張るという解法や、既存コンフィグのRoute Mapのポリシーを削除して直接接続されたすべてのNWに関する経路を広報しアンダーレイのBGPもLoopbackアドレスで張れるようにする、といった解法も見られました。私にとっても「その手があったか!」という発見であり、とても勉強になりました。\
本問で網羅されていない範囲の概念もまだまだありますが、この問題が皆様の勉強のきっかけや理解の促進に繋がれば幸いです!
125 changes: 125 additions & 0 deletions src/content/blog/2024-pre-round-2nd/isi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
title: "ICTSC2024 二次予選 問題解説: [ISI] Welcome to Kubernetes"
description: "ICTSC2024 二次予選 問題解説: Welcome to Kubernetes"
tags: [ICTSC2024,問題解説]
pubDate: 2024-12-14T12:00:00
slug: "2024/12/14/ictsc2024pr/isi"
draft: false
renderer: "md"
sticky: false
---

# 問題文

あなたは、新卒でとあるプロジェクトに配属されてしまいました。
このプロジェクトでは、Kubernetesを導入を試みていますが苦戦している様です。
- 社員Aからは、Kubernetesクラスタはデプロイできたものの、社内レジストリからイメージをpullすることができないとのことです。
- 社員Bからは、KubernetesクラスタにPodをデプロイできたものの、podから社内サービス(docker-registry)に疎通ができないそうです。

このことを踏まえ、社内のDocker Registryに検証用のimageが作成されました。
状況を整理し、検証imageが正しく利用できるようなKubernetesクラスタを構成してください。

- **補足: 検証image(`docker-registry.hideichi.as.a.service.com/someapp:latest`**
- 社内サービス(docker-registry)に疎通が取れないとの問い合わせを元に作成された検証用イメージです。
- クラスタにデプロイされると、社内サービス(docker-registry)に疎通できるか、確認ための簡単な検証を実行します。
- クラスタ構成が正しく行われれば、正常に終了します。

### **社内のコンポーネント構成図**

社内は、このような環境になっています:

![](/images/2024-pre-round-2nd/isi.png)

| Name | IP | Domain |
| --------------- | ------------- | ----------------------------------------- |
| CoreDNS | 10.244.10.130 | coredns.hideichi.as.a.service.com |
| Docker Registry | 10.233.90.120 | docker-registry.hideichi.as.a.service.com |

- 各コンポーネントの説明
- Docker Registry: 社内で動作するプライベートなDocker Registryです。以下のコマンドで確認することができます。
```
curl -X GET http://docker-registry.hideichi.as.a.service.com/v2/_catalog
```
- CoreDNS: 社内のDNSサーバです。
- 検証用VM: 検証用VM == node1です。貴方のプロジェクト先で唯一自由に操作できる検証環境です。
### **検証VMについて**
- 検証用VMには、userユーザからKubesprayでクラスタがデプロイ済みです。
- userユーザに共通パスワードで入れます。
- `/home/user/kubespray/`にKubesprayが用意されています。
- `/home/user/kubespray/inventory/mycluster`が検証のクラスタ設定です。
- クラスタを作った先駆者のメモが用意されています
```
# めも
## kubesprayを使うために
cd /home/user/kubespray && \
python3 -m venv venv && \
source venv/bin/activate
## kubesprayを流す
ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root --ask-pass --ask-become-pass cluster.yml
たまーにこけるが一回やり直すとよき
## kubectlはこれを使うと良き
/home/user/kubespray/inventory/mycluster/artifacts/kubectl.sh
## 作成したクラスタがうまくいくか簡単なチェック
./kubectl.sh create deployment nginx --image=nginx:latest
これは普通にうごく
## 検証用image。これは動くようなクラスタに構成できれば解決する
./kubectl.sh create job someapp --image=docker-registry.hideichi.as.a.service.com/someapp:latest
こいつは動かない
## 一旦クラスタresetする?
ansible-playbook -i inventory/mycluster/hosts.yaml --become --become-user=root --ask-pass --ask-become-pass reset.yml
```
## 前提条件
- 検証用VM(node1)しか操作してはいけません。
- Kubernetesの構築には、[Kubespray](https://github.com/kubernetes-sigs/kubespray)を利用する必要があります。
- 最終成果物として`/home/user/kubespray/`のマニフェストのみを変更する必要があります。
## 初期状態
- docker-registry.hideichi.as.a.service.comからimageをpullする事ができない。
- `./kubectl.sh create job someapp --image=docker-registry.hideichi.as.a.service.com/someapp:latest`をした際にJobが完了しない
```
./kubectl.sh get jobs
NAME STATUS COMPLETIONS DURATION AGE
someapp Running 0/1 36s 36s
```
- Podが`ErrImagePull` or `ImagePullBackOff`である
```
./kubectl.sh get pods
NAME READY STATUS RESTARTS AGE
someapp-d79qq 0/1 ErrImagePull 0 62s
```
## 終了状態
- `docker-registry.hideichi.as.a.service.com/someapp:latest`をpullできて、正常に動作させる事ができる
- `./kubectl.sh create job someapp --image=docker-registry.hideichi.as.a.service.com/someapp:latest`をした際に、imageをpullしてPodが動作して、正常に完了する(exitCodeは0である)。
```
./kubectl.sh get job
NAME STATUS COMPLETIONS DURATION AGE
someapp Complete 1/1 4s 14s
```
```
./kubectl.sh get pods <someapp_pods_name> -oyaml | yq ".status.containerStatuses[].state.terminated.exitCode"
0
```
# 解説
この問題は三つの課題から成り立っています。
* KubernetesのPodが割り当てられているCIDRと社内サービスのIPが衝突していて、Podから疎通ができない。
* k8s-cluster.ymlの`kube_service_addresses`と`kube_pods_subnet`を設定し直す事で解決します。
* PodがImagePullBackOffになる。
* 社内DockerRegistryはhttpでしか対応していません。一方でkubesprayはデフォルトでcontainerdを使用していて、httpsを利用するので別途設定をする必要があります。containerd.ymlのcontainerd_registries_mirrorsに設定を追記する事で解消できます。
* Kubernetes上に構築したPodが社内のDNSを参照しません。
* Kubesprayのupstream_dns_serversを設定する事で解決します。
Loading

0 comments on commit 1a4f0e1

Please sign in to comment.