/
カテゴリー

問題文  

概要  

あなたが働く株式会社ICTSCでは、WebサイトをホストするためにKubernetesクラスタを構築しました。しかし、担当者が何らかのミスをし、現在クラスタは正しく動いていない状態です。
また、残念なことに担当者は失踪し、あなたが後任となりました。
正しくWebサイトへリクエストが送れるように、Kubernetesクラスタを直してください。

ネットワークの構成とは以下のようになっています。f35-managerと呼ばれるノードが3つ、f35-workerと呼ばれるノードが3つあり、それぞれ192.168.7.1から192.168.7.6までIPアドレスが割り振られています。それぞれのマシンは同じLANに属しています。 また、f35-lbと呼ばれるロードバランサがあり、kube-apiのロードバランシングを行っています。

image

またKubernetes内部では、HTTPリクエストへ応答するために、Webサーバーのリソースが作成されています。

他に仕様書などはありません。

初期状態  

  • 参加者の踏み台サーバーから curl 192.168.7.1:30000 を実行しても応答がない (connection refused)

終了状態  

  • 参加者の踏み台サーバーから curl 192.168.7.1:30000 を実行するとHTTP応答が帰ってくる

解説  

この問題で発生しているしている具体的な問題は2点。

  • f35-worker-3のkubelet.serviceがdisable & stopされている点。
  • ホスト名が変更されており、かつ使用不可能な文字が含まれている。

ホスト名でアンダーバーが使用されていると、kube-apiserverが起動しません。さらに、ホスト名が初期のものと変更されているので、それも元に戻す必要があります。

まず、各managerノードの/etc/kubernetes/kubelet.yamletcd.yamlを見ると、当初のホスト名であるf35-manager-数字が判明するので、managerノードのホスト名を修正できます。

その後、kubectl get nodeコマンドが使えるようになるため、そこでworkerノードのノード名(当初のホスト名)が判明します。そのためworkerノードのホスト名も本来の名前であるf35-worker-数字へ修正できます。

2つ目については、f35-worker-3のkubelet.serviceをstart & enableするだけで構いません。 以上でk8sクラスタが起動するようになります。 また、aliceのdeploymentはnodeselector: f35-worker-3指定があるため、worker-3が起動しないと動かないような設定になっています。

これにについて、報告書に明記していないがおそらく暗黙的にsystemctl start kubeletなど行って居たためにworker-3が起動していたチームは、deployment自体は動いていても満点にしていません。

ただ、「原因の報告」の明記は問題文中で指定されていなかったため、結果worker-3でpodが動くような指示(systemctl startsystemctl restartsystemctl disable && reboot、nodeselectorの削除等)を報告書に明記したチームに関しては満点にしました。

最後に、kubectl get serviceを実行すると、Aliceという名前のdeploymentがNodePort 30000ポートでlistenしていることがわかる。 試しにcurlしてみるとリクエストが通るので問題が解決できたことになります。

所感  

f35-worker-3のkubelet.serviceがdisable & stopされている点。という問題が結構なチームが気づかれず、作問者としては残念でした。

採点のポイントとしては、 「問題解決の手順を報告書に書いているかどうか」 と 「初期状態のマシンで、報告書に書いてある作業を同じように実行すれば終了状態を満たした状態ができるかどうか」 「報告書に書いてあるコマンドや編集作業を問題サーバーでも同じように実行しているかどうか」 の3点で採点を行いました。 ちなみに、今回満点を取ったのは3チームです。

最後に今回の珍解答ですが、k8sクラスタを解体しゼロから作り直しているチームが複数見受けられました。 正直、内容を見る限りとても頑張っていて点数を上げたかったのはやまやまなのですが、解体前に内部で動いているリソースをエクスポートし、構築後applyができていなかった(終了状態を満たしていなかった)ため、0点とさせていただきました。

以上、ありがとうございました。

 /
カテゴリー

問題を解いていただきありがとうございました!

問題文  

概要  

あなたのクラスメイトのA君は、CiscoルーターであるRTとUbuntuサーバーであるServer間でIPIP over ipsecの検証をしていました。 しかし、設定を変更しているとRTServer間の疎通ができなくなってしまいました。
A君の代わりに、RTServerのIPIP over ipsecの設定を修正し疎通できるようにして下さい。

topology.png
  • RT
    • Cisco CSR 1000v
    • IPアドレス
      • gi1 192.168.14.10/24
      • tun0 10.50.0.1/30
  • Server
    • Ubuntu 18.04
    • ipsec: strongswan
    • IPアドレス
      • eth0 192.168.14.20/24
      • tun0 10.50.0.2/30

初期状態  

  • RT, Server間で通信が行えない
    • RTから ping 10.50.0.2 をしても応答がない
    • Serverから ping 10.50.0.1 をしても応答がない

終了状態  

  • RT, Server間で通信が行える
    • RTから ping 10.50.0.2 をして応答がある
    • Serverから ping 10.50.0.1をして応答がある
  • IPIP over ipsecでトンネリング及び暗号化がされている
  • 設定が永続化されており、再起動後も自動で疎通ができる状態になっている

採点基準  

  • RTとServer間の通信でき、暗号化されている (80%)
    • RT -> Server ping 10.50.0.2 (40%)
    • Server -> RT ping 10.50.0.1 (40%)
  • 上記を満たしており、トンネリングにはIPIPのみを用いている (20%)
    • ipsecでトンネリングやその他のトンネリングはNG

解説  

RTとServerのそれぞれの設定が間違っていることによるトラブルでした。 具体的には以下の3つの原因が上げられます。

  • strongswanの設定でauto=addになっている
  • ipsecの通信モードが異なっている
  • ikeのバージョンが異なっている

原因  

strongswanの設定でauto=addになっている  

auto=addを設定したとき、strongswanは起動時設定の読み込みのみを行います。そのため、手動で接続しなければトンネルを張ることができません。 そこで、startまたはrouteを設定することによって接続を自動で行うようにします。

startrouteは以下のように動作します。

  • start サービス起動時にトンネルを張る
  • route 通信時にトンネルを張る

ipsecの通信モードが異なっている  

strongswanではipsecの通信モードをtype=transportとtransportモードに設定していますが、RTではmode tunnel とtunnelモードになっていました。

今回の構成では、IPIP over ipsecを行っているのでトンネリングはIPIPが担当します。そのため、ipsecではトンネリングする必要が無いのでRTの設定をmode transportに設定します。

ikeのバージョンが異なっている  

上記の問題を解決したあと、RTからServerへpingを送ってみると、接続が確立され疎通が取れていることが確認できます。

RT#ping 10.50.0.2
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.50.0.2, timeout is 2 seconds:
.!!!!
Success rate is 80 percent (4/5), round-trip min/avg/max = 1/1/1 ms

しかし、接続を確立していない状態でServerからRTへpingを送ってみると接続が確立されず疎通が取れません。

user@Server:~$ sudo systemctl restart strongswan
user@Server:~$ ping -c 1 10.50.0.1
PING 10.50.0.1 (10.50.0.1) 56(84) bytes of data.

--- 10.50.0.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

RTは設定からikev1を利用していることがわかります。 strongswanの設定では、keyexchange=ikeというように指定されています。strongswanでは、ikeを指定した場合、接続の開始時にikev2を提案します。しかし、受信時にはいずれかのバージョンをacceptします。
そのため、RTからServerでは接続できでも、ServerからRTはできないという状態になっていました。 今回の構成ではikeのバージョンを指定されていないので、楽に修正ができるikev1に合わせます。 strongswanの設定を、keyexchange=ikev1に変更します。

修正後の設定  

RTの設定  

RTの設定は以下のようになります。(show run 一部抜粋)

crypto ipsec transform-set TS_IPSEC esp-aes esp-sha256-hmac 
 mode transport

Server(strongswan)の設定  

Serverのstrongswanの設定(/etc/ipsec.conf)は以下のようになります。

# ipsec.conf - strongSwan IPsec configuration file

# basic configuration

config setup
	
conn RT
	authby=secret
	left=192.168.14.20
	leftid=192.168.14.20
	right=192.168.14.10
	rightid=192.168.14.10
	auto=start
	type=transport
	keyexchange=ikev1
	ike=aes-sha256-modp3072
	esp=aes-sha256

参考文献  

 /
カテゴリー

問題文  

概要  

あなたは企業のICT専門の職員として働いている。
人事部から “2019年1月1日から2019年12月31日までの営業部売り上げランキングを調べたい” とのメール依頼を受け作業している。WebサーバにMySQLを運用している。
MySQLのデータベースからcsvファイル(re.csv)を出力するSQL文(SQL.txt)を作成し実行しなさい。

初期状態  

  • MySQLが起動しroot権限にて正常動作することを確認している
  • 使用するデータベースはBusinessである
  • データベースBusinessのテーブルには以下がある
    • Department(部署)
    • Payment(給与)
    • Sales(売り上げ)
    • Worker(従業員)

終了状態  

  • 提出されたCSVデータは売り上げ(Moneyカラム)の順位にソートされている
  • 提出時に付随するカラムは以下の通り
    • Worker ID
    • Name f
    • Name p
    • DepartmentID
    • Date
    • Money

提出方法  

  • CSV形式で出力されたデータ(re.csv)と使用したSQL文(SQL.txt)で提出する
    • ファイルを解答フォームにてドラッグアンドドロップを行いアップロードを行う

採点基準  

  • 上記のカラムが表示できるSQL文を作成できている。[40%]
  • 正しく出力できている。[40%]
  • 売り上げ1位から順表示ができている。[20%]

解説  

  1. 内部結合とは DBテーブルの概要図を元に解説します。

    今回使用するテーブルは wokersalesのテーブル利用します。
    内部結合(Inner Join)を利用するための共通部分が必要になります。今回はwokerテーブルidsalesテーブルのwokerIDが同一の値であり結合条件として内部結合を行います。内部結合の例select ○○○ from テーブル1 INNER JOIN テーブル名2 ON 結合条件
  2. SQLの抽出条件 SQLでのある特定のデータを抽出する際にはいくつか方法があります。今回はwhereを利用した抽出について解説します。
    基本的な使い方select ○○○ from ○○○ where 条件 条件の指定方法については
    カラム名 演算子 数値などの条件 となっています。
    また、andorを組み合わせることで複数の条件を指定することが可能です。
  3. SQLの実行 1・2よりSQL文を作成するとselect Worker.ID,Name_f,Name_p,DepartmentID,Date,Money from Worker inner join Sales on Worker.ID=Sales.WorkerID where DepartmentID=1 and Date>='2019-1-1' and Date<='2019-12-31' order by Money DESC となります。
  4. CSVファイルへの出力 Bashにてsudo mysql -u root -p -D Business -e "3.SQL文"> 〇〇.csv

注意点  

今回の場合、2つのミスが多かったです。1つは期間をしているが、営業部 の指定を正しく行っていない、その場合は20%となります。もう一つはWorker.IDSales.WorkerIDを見つけ結合条件とすることができるのかという点になります。こちらをWorker.IDSales.IDとした場合は正しく結合できていない、つまり問題文と成り立たなくなるため0%となります。

 /
カテゴリー

問題文  

概要  

とあるゲーム会社に務めるA君は、以前運営していたオンラインゲームのシステムを再利用し、最近サービスが開始されたオンラインゲーム『TORACON QUEST』のデータベースのレプリカを作成をするよう頼まれました。
A君は、レプリカの作成をしたことが無かったのですが、インターネットの情報を元になんとかレプリケーション構成を組むことができました。
しかし、上司のBさんが確認したところMasterサーバのレプリカがSlaveサーバに正常に作成されていないことが判明しました。
A君の代わりに、MasterサーバとSlaveサーバ間でデータの差異が無いレプリケーション構成を組んであげてください!
ただし、Masterサーバのデータベースが正しいので、レプリケーション後のデータベースはMasterサーバのデータを元にしてください!

初期状態  

  • MasterサーバのDBに保存してある情報が正しい
  • SlaveサーバのDBは一部のデータが誤っている
  • 一部のクエリをMasterサーバに投げるとMasterサーバとSlaveサーバでデータの差異が生まれてしまう
  • replはA君がレプリケーションを組んだときに作成したMySQLのレプリケーション用ユーザーである

終了状態  

  • どのようなクエリをMaster側に投げてもSlave側とデータの差異が発生しないレプリケーション構成が組めている
  • 各データベースで初期状態のMasterサーバのデータベースを元に作成されたデータが保存されている

解説  

トラブルの原因  

今回、問題を解いてくださった皆さまありがとうございました! この問題では、MySQLのレプリケーションという技術を使用して、DB1の複製(レプリカ)をDB2に作成しようとしたところ問題が発生した、という内容でした。
このレプリケーションを行う際、Master側(今回はdb1)のMySQL binlogを元にSlave側(今回はdb2)にデータの複製を行います。
そのときに、binlogのフォーマットが複数存在し、そのうちのSTATEMENTを選択すると非決定的な関数(例えば、UUID()やユーザー定義関数)の値がMaster,Slave間のデータベース上で不一致が発生してしまうことがあります。(ちなみに、rand()はMySQLの仕様で暗黙的にseed値が揃えられているのでデータが一致していたはずです。)

今回の問題では、この不一致が発生した状況から開始となりました。
なので、復旧するにはMasterのバックアップをSlaveに上書きしてあげて、my.cnfにbinlog_format=rowを設定してあげなければいけません。

解決方法  

VM02の作業  

  • vm02のmysqlがstopしてることを確認する
$ sudo systemctl status mysql
● mysql.service - LSB: Start and stop the mysql database server daemon
   Loaded: loaded (/etc/init.d/mysql; bad; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:systemd-sysv-generator(8)
$ sudo systemctl start mysql

各VMで操作  

  • vm01とvm02にsshし、/etc/mysql/conf.d/mysql.cnfの[mysqld]以下に次の設定を記述する。
binlog_format=row

vm01で作業  

  • vm01のmysqlを起動する。
$ sudo systemctl restart mysql

  • binlogの書き込みロックと状態の確認を行う。
    • ここでFileとPositionを確認して覚えておきます。(この値を後で使用します。)
mysql> flush tables with read lock;
mysql> show master status;

  • vm01にsshし、dumpを作成してscpでvm02に送信する。(dumpを送受信できればsftpなどでも問題ありません)
$ mysqldump --single-transaction -u root -p TORACON_QUEST > backup.dump
$ scp backup.dump user@192.168.18.2:~

  • 最後にテーブルのロックを解除します。
mysql> unlock table;

ここからVM02  

  • vm02のmysqlを起動
$ sudo systemctl restart mysqld.service

  • dumpデータを用いて正しいテーブルを作成
mysql> stop slave;
mysql> drop database TORACON_QUEST;
mysql> create database TORACON_QUEST;
mysql> use TORACON_QUEST;
mysql> source ~/backup.dump;

  • 一度レプリケーションが止まってしまっているので、リレーログ周りの設定を初期化する。
mysql> RESET SLAVE;

  • masterの情報を入れておく
mysql> change master to master_host='192.168.18.1', master_user='repl',master_password='PlzComeToICTSC2020',master_log_file='[さっきメモした値(File)]',master_log_pos=[さっきメモした値(Position)];

  • レプリケーションを再開
mysql> start slave;

ここまで行うと終了条件をすべて満たすことができる。

トラブルシュートできたかの検証方法  

  • MasterのTQ_ITEMに以下のようなクエリを用いてUUIDが同じ状態になっているかを確認する
mysql> INSERT INTO TQ_ITEM (ItemID,WeaponID,Attack,UUID,UserID) VALUES (2020,1,ROUND(RAND()*(99999-1)+1,0),UUID(),8);

採点基準  

  • 25%:元のMasterサーバのデータの移行が済んでいる
  • 25%:Mysqlのコンフィグファイル内でrowもしくはmixedベースのレプリケーションが組む内容が記入されている
  • 25%:systemctl start mysqlなど細かく内容について書かれている。
  • 25%:レプリケーションが組めている

【合計】

  • 100%: UUID()を含むクエリを投げてもMasterSlave間でデータに差異が発生しない
 /
カテゴリー

問題文 

A社の社内システム用に作成したdocker上のmariaDBコンテナが非常に不安定で、すぐに落ちてしまい、社内システムの可用性に影響が出ている。 このシステムはとある社員が一人で作成したが、完成した日に退職してしまって連絡が取れず、このシステムの仕様書なども存在しない。

現在コンテナに安定したアクセスができない原因を報告し、 コンテナをレコード情報を保持したまま動作が可能となるように復旧せよ。

初期状態  

  • VM上でdocker ps -aをするとmariaDBコンテナが1つ存在している
  • VM上でdocker start mariaDBdocker exec -it mariaDB bashをしても落ちて開けない

終了状態  

  • コンテナが継続して起動している状態である
  • docker exec -it mariaDB bashでコンテナに入ることができ、入った際にMariaDBのDBictsc_incusersテーブルを見たときに
+----+------------+-----------+------+-------+
| ID | First_Name | Last_Name | Age  | Sex   |
+----+------------+-----------+------+-------+
|  1 | Tarou      | Yamada    |   23 | MAN   |
|  2 | Emi        | Uchiyama  |   23 | WOMAN |
|  3 | Ryo        | Sato      |   25 | MAN   |
|  4 | Yuki       | Tayama    |   22 | WOMAN |
|  5 | Yuto       | Takahashi |   21 | MAN   |
+----+------------+-----------+------+-------+

が存在している。

  • 社内システムがDBを参照出来るよう、3306番ポートが開いている。

配点  

  • このコンテナが不安定になっている原因を明確な証拠をもとに正しく特定できている(60%)
  • コンテナが継続動作するように復旧できている(25%)
  • 当該コンテナ上で問題文通りのレコードを参照できる(15%)

解説  

こちらの問題では、社内システムのデータベースとして使用している DockerのMariaDBコンテナの動作が何らかの原因で不安定になっているがその原因を報告し解決する、 というものでした。

まずこの問題でのシステム構成図を説明したいと思います。  このMariaDBコンテナと社内システムは3306番ポートを用いて接続されており、社内システムは日々このコンテナのMariaDBに対しデータの読み書きを行っています。 また、このコンテナはコンテナ内部にデータを保持している訳ではなく、mariaVOLというDocker内部のボリュームにコンテナ内部のデータディレクトリ/var/lib/mysqlをマウントしています。よって、このコンテナが破損したとしてもデータベース内部のデータは保持され続ける仕組みとなっております。

トラブルの原因  

この問題でMariaDBコンテナが不安定であった原因はこのシステムを退職した社員が「サーバーのメモリが足りないので、メモリを食わないようにしたい」ということでこのMariaDBコンテナが使用できるメモリの量を4MBにしたことが原因でした。 以下が当該コマンドです。

docker run -m "4M" -v mariaVOL:/var/lib/mysql -d --name mariaDB -e MYSQL_ROOT_PASSWORD=MariaPass -p 3306:3306 -d mariadb:latest

-mオプションでこのコンテナが利用できるメモリを4MBまでに制限していることが分かります。 ここでは当時打たれたコマンドを出してメモリ制限がされていることが分かりましたが、今回はDockerの設定やログ等でしかトラブルの原因を知ることが出来ません。

この原因を知る例として、細かいものは他にもあるかとは思いますが、大きく2つ紹介します。

1.docker inspectコマンドを使用する  

docker inspectコマンドは、dockerコンテナの設定情報を参照することが出来るコマンドです。これを見ると、コンテナがどのような設定で動作しているのかが分かります。しかし、この設定データの量は膨大で、全てを見るには時間がかかってしまいます。 例えばですが、この問題の原因のメモリについて調べたい際、docker inspect mariaDB | grep Memoryなど、grepコマンドなどを使い検索すると、

 "Memory": 4194304,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": -1,
            "MemorySwappiness": null,

といった値が出てきます。ここに出た"Memory": 4194304という値はバイト表記でして、MBに換算すると約4MBということが分かります。設定されていた値と同じですね。

2.docker statsコマンドを使用する  

docker statsコマンドは、コンテナのリソース使用状況を表示するコマンドです。Linuxのtopコマンドに似たような機能を持っています。 ここで、コンテナのリソース使用状況を知ることが出来ます。

CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
eb99786557f7        mariaDB             8.44%               3.664MiB / 4MiB     91.60%              656B / 0B           1.89GB / 0B         3

こちらでもMEM USAGE / LIMITの欄で3.664MiB / 4MiBと見えており、メモリが4MB制限であること、そして使用中のメモリが逼迫している状態であることから不安定になる原因であることが推定出来ます。

解決策  

前項の方法でメモリ制限が原因であることを突き止めた場合、現在のトラブルをどのように解決するかについて例を載せます。

1.docker updateコマンドを使用しリソース設定を更新する  

docker updateコマンドはコンテナの設定を更新するためのコマンドです。 コンテナの設定をコンテナを作り直すことなく変更することが可能です。 例として、問題のコンテナのメモリ制限を4MBから1GBへと緩和します。例えば、 docker update --memory 1G mariaDBこのコマンドを実行する事により、メモリ上限を4MBから1GBに変更することが出来ます。 docker inspect mariaDB | grep Memoryで見てみると

            "Memory": 1073741824,
            "KernelMemory": 0,
            "MemoryReservation": 0,
            "MemorySwap": -1,
            "MemorySwappiness": null,

となり、Memory": 1073741824(byte)は約1GBですので、1GBへと緩和されたことが分かります。

2.同じ設定のコンテナを作り直す  

解法の一つとして、同じ設定のMariaDBコンテナを再作成する方法があります。 docker run -v mariaVOL:/var/lib/mysql -d --name mariaDB -e MYSQL_ROOT_PASSWORD=MariaPass -p 3306:3306 -d mariadb:latest などで、メモリ制限を緩和、およびメモリ制限を無くしたコンテナを作成します。 ただし、MariaDBのデータベースはボリュームmariaVOLにマウントされているという点に注意しなければなりません。mariaVOLへコンテナをマウントしないと、コンテナに入ってもデータベースを参照することが出来なくなってしまいます。

上記の2つの設定のどちらかを適用し、

docker exec -it mariaDB bash

mysql -u root -p ${MYSQL_ROOT_PASSWORD}

use ictsc_inc;

select * from users;

をするとこちらのテーブル

+----+------------+-----------+------+-------+
| ID | First_Name | Last_Name | Age  | Sex   |
+----+------------+-----------+------+-------+
|  1 | Tarou      | Yamada    |   23 | MAN   |
|  2 | Emi        | Uchiyama  |   23 | WOMAN |
|  3 | Ryo        | Sato      |   25 | MAN   |
|  4 | Yuki       | Tayama    |   22 | WOMAN |
|  5 | Yuto       | Takahashi |   21 | MAN   |
+----+------------+-----------+------+-------+

を見ることが可能で、復旧したことが分かります。