zatsu na benkyou matome saito

勉強したことをまとめるだけのサイト、数学、プログラミング、機械学習とか

データ構造とアルゴリズム:Bubbleソート

一番左側から、配列の個数分forループを行い、limitまで到達したら再度左に戻ってきて同じ処理を行う。 その際にlimitの位置は1つ左に移動する。

スクリーンショット 2020-11-25 0.19.06.png (391.4 kB) スクリーンショット 2020-11-25 0.19.19.png (378.2 kB)

  • for j in range(len_numbers - 1)の部分でlimitの移動を再現している。
    • 一番大きい数字は1週目で一番右にくるようになっているのでlimitを設けて一番右端の数値は処理しなくても良いようにする
    • limitを設けることで、無駄なソート処理を行う必要がないので、コードのパフォーマンスが向上する
  • for文を2回行って2個目のfor分内で一つ前の配列要素(i)とその一つ後の配列要素を比較して左側(i)の値が小さければ右側の値と入れ替える。
  • numbers[j], numbers[j + 1] = numbers[j + 1], numbers[j]という処理で入れ替えを行える。
from typing import List

def bubble_sort(numbers: List[int]) -> List[int]:
    len_numbers = len(numbers)
    for i in range(len_numbers):
        for j in range(len_numbers - 1 - i):
            if numbers[j] > numbers[j + 1]:
                numbers[j], numbers[j + 1] = numbers[j + 1], numbers[j]
    return numbers


if __name__ == '__main__':
    nums = [2, 5, 1, 8, 7, 3]
    print(bubble_sort(nums))
    
[1, 2, 3, 5, 7, 8]

処理時間

bogoソートと比較すると圧倒的に早くなっている。

[1, 2, 4, 5, 6, 8]
0.0003845040009764489

# 配列をランダムに作成したとき
[64, 181, 228, 335, 360, 377, 500, 627, 883, 909]
0.00043242100036877673

ランダムな配列の作り方

これで、0 ~ 1000までのランダムな数字で要素が10個の配列を作ることができる。

import random
arry = [random.randint(0, 1000) for i in range(10)]

CH1:kubernetes基礎 - 基本的な構成と、各種機能について

kubernetes用語集

kubernetes チュートリアル

Docker & kubernetes tutorial YouTube

まずはDoker

#37: AI-人工知能/MLOps/docker/CH1: Docker imagesとVolumeについて

kubernetes

アプリケーションの運用のトレンドがMonolithからMicroservicesに移ってきているので、複数のコンテナを用意してそれらのコンテナをコンテナオーケストレーションツールで操作・運用することで様々な運用環境構築・対応している。

benefits

1. High Availability - アプリの動作が停止することを防止している 2. Scalability - アクセスを分散させて動作させることができるのでアプリの動作やパフォーマンスが高い 3. Disaster recovery - バックアップやリストアが容易にできる

kubernetesアーキテクチャ

スクリーンショット 2020-11-21 20.26.36.png (220.3 kB)

それぞれのworkerではkubeketというものが動いていて、それがそれぞれのworkerノードとデータをやりとりしたり、アクセスを行ったりを可能にしている

Pod, Service & Ingress

kubernetesの基本的な構成要素で、kubernetesを実用的に使うためにはこれらを知っておく必要がある。

スクリーンショット 2020-11-21 20.31.57.png (258.6 kB)

Pod

Podについての説明は公式HPに書いているが、実際に触ってみないとなんとも。。 密接に関連するアプリを起動しているコンテナをカプセル化させてまとめるコンテナのコンテナのようなもののよう。 https://kubernetes.io/ja/docs/concepts/workloads/pods/pod-overview/

スクリーンショット 2020-11-21 23.04.48.png (895.3 kB)

  • Pod内で各アプリケーションごとにIPアドレスが振られており、コンテナがkillされた時に、新しくアプリケーションコンテナが立ち上げられるが、IPアドレスが変更されてしまう。そうなると、今まで接続していたIPアドレスに接続されなくなってしまい困るのでIPアドレスの永続化を行うためにServiceが用いられる。

Service and Ingress

PodとServiceのプロセスは結合されていないので、Podのプロセスが止まってしまってもServiceのプロセスが止まることはないのでIPアドレスの永続化を行える。 各PodはServiceを介してコミュニケーションを行う

スクリーンショット 2020-11-21 23.09.15.png (490.6 kB)

Ingress

クラスター内のServiceに対する外部からのアクセス(主にHTTP)を管理するAPIオブジェクトです。 Ingressは負荷分散、SSL終端、名前ベースの仮想ホスティングの機能を提供します。 引用:公式:Ingress

Config Map and Secret

Config Map

コンテナのアプリケーション名などが変更されたた時に各コンテナの設定を変更してre-buildやre-pushを行う必要があるため、一度アプリを止めて再度構築し直しを行わなければいけない。そのような状況を改善するためにConfig Mapが使われる。

スクリーンショット 2020-11-21 23.15.39.png (569.7 kB)

・例えば、dbのアプリケーション名を変更した時に、Config Mapの名称を変更するだけで、Config Mapから、アプリのロケーションを読み取れるのでわざわざDockerfileなどのアプリ名を変更してre-buildしたりしなくても済む。

スクリーンショット 2020-11-21 23.18.16.png (504.4 kB)

しかし、DBのユーザー名やパスワードなどを変更する際にこのConfigMapに記載することはやめたほうが良い。ユーザー名やパスワードの変更を管理したい際に使われるのがSecretという機能である。

Secret

スクリーンショット 2020-11-21 23.21.28.png (805.0 kB)

Volumes

Dockerコンテナのvolumesと同じようなもので、データベースをローカルで管理できるようにしてPodが落ちた時でもデータの永続化ができるようにするもの

Deployments and Stateful Sets

Deployment

Deoploymentは、Podのコピーを作ることによって、もしnode1のPodが落ちたとしてもload balancerによってnode2のアプリケーションをIPにセットすることで運用ができなくなる状態を防ぐことが可能。

スクリーンショット 2020-11-22 0.23.19.png (1.1 MB)

Stateful Sets

StatefulSetsではDBなどのStatefulなアプリケーションの複製を行うために設定されるもので、データベースが落ちた時にもデータの永続化ができるようにするためのもの。

Minikube and Kubectl

minikubeとは?

実運用する際に動くかテストを行いたい時にローカル環境でミニマムなPod環境を作成してテストを行うことができるツール - ローカルPC上にVirtual Boxを構築することができる - そのVirtual Box上でnodeを走らせることができる - 1 node K8s cluster

スクリーンショット 2020-11-22 0.42.02.png (333.1 kB) スクリーンショット 2020-11-22 0.43.47.png (274.0 kB)

kubuctlとは?

APIを通して、kubernetesの設定をCUIで行えるアプリケーション ローカルマシンにインストールしてterminal上からkubernetesを操作/設定できる スクリーンショット 2020-11-22 0.49.12.png (242.3 kB)

docker/CH1: Docker imagesとVolumeについて

Docker

このページではdockerのimageとvolumeについて捜査を交えながら説明します。 local環境で行うのですが、ローカル環境でdockerを使えるようにしておく必要があります。 もしまだインストールしていなかったら、「docker インストール mac」とかぐぐると色々やり方が出てくるともいます。

(base) y.nakata@MacBook-Pro-4 website % docker -v
Docker version 19.03.13, build 4484c46d9d

### Docker vs VM スクリーンショット 2020-11-21 15.39.36.png (226.9 kB)

Docker benefits

  • コンテナの起動が早い
  • 少ない容量で構築できるので無駄にサーバーのスペースを占有しない
  • モリーの使用率が低い
  • OS全てを使わないので、複数の環境を構築可能

Images

コンテナ操作

nginxのimageをpullする

(base) y.nakata@MacBook-Pro-4 docker_tutorial % docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
852e50cd189d: Pull complete 
a29b129f4109: Pull complete 
b3ddf1fa5595: Pull complete 
c5df295936d3: Pull complete 
232bf38931fc: Pull complete 
Digest: sha256:c3a1592d2b6d275bef4087573355827b200b00ffc2d9849890a4f3aa2128c4ae
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

Dockerのコンテナを立てる前にどのようなコンテナの中身にするかの設計が書かれているimageをdcoker hubよりダウンロードしてくる。

Docker Hub 色々なアプリケーションのimageがあるので使いたいものをpullして、対象のアプリケーションコンテナを構築することでそのアプリケーションが使えるようになる。

pullしてきたimageを確認する

(base) y.nakata@MacBook-Pro-4 docker_tutorial % docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              daee903b4e43        2 days ago          133MB

コンテナを建てる

(base) y.nakata@MacBook-Pro-4 docker_tutorial % docker run nginx:latest
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Configuration complete; ready for start up

コンテナを確認

(base) y.nakata@MacBook-Pro-4 docker_tutorial % docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
db548a38af4d        nginx:latest        "/docker-entrypoint.…"   49 seconds ago      Up 48 seconds       80/tcp              silly_lewin

Portを開く

(base) y.nakata@MacBook-Pro-4 docker_tutorial % docker run -d -p 8080:80 nginx:latest
22cf87a188980192a7771371c1c174202dbd3b530d98580a534f705541c4a71e

というコマンドを打つことで、localhostの8080ポートとコンテナの80ポートを接続できるようにしている。

この後にウェブブラウザでlocalhost:8080に接続するとコンテナのnginxに接続することができる。 スクリーンショット 2020-11-21 17.09.27.png (760.0 kB)

もちろん、8080以外も接続できるので、

(base) y.nakata@MacBook-Pro-4 docker_tutorial % docker run -d -p 3000:80 nginx:latest
22cf87a188980192a7771371c1c174202dbd3b530d98580a534f705541c4a71e

というコマンドでもOK

Volumesについて

スクリーンショット 2020-11-21 17.19.28.png (133.6 kB)

コンテナとホスト(ローカルPC)間のデータの共有を可能にするために使用する スクリーンショット 2020-11-21 17.21.01.png (161.5 kB)

nginx (docker hub): https://hub.docker.com/_/nginx

共有しているvolumeでhtmlファイルを表示させる

スクリーンショット 2020-11-21 17.40.48.png (192.9 kB)

(base) y.nakata@MacBook-Pro-4 docker_tutorial % docker run --name website -d -p 8080:80 nginx    
b86b995e912390fda2885ef65c89316d3ec4d80fb1cc1642a195351e16c8f7eb

imageの時と同様にlocalhostの8080とdockerコンテナの80ポートを接続する.

その後、websitelocalhost:8080に接続できるかを確認する。 スクリーンショット 2020-11-21 17.43.38.png (759.9 kB)

docker stopで一旦コンテナを止める

(base) y.nakata@MacBook-Pro-4 docker_tutorial % docker stop website 
website

Desktopに~/Desktop/website/index.htmlというhtmlファイルを作成する 中身は適当。

<h1> hello docker html </h1>
(base) y.nakata@MacBook-Pro-4 website % docker run --name website -v $(pwd):/usr/share/nginx/html:ro -d -p 8080:80 nginx

というコマンドで、-vでvolumをどこにマウントするかを指定して、pwdwebsiteであることを教えてあげる。

多分これでも良い。

(base) y.nakata@MacBook-Pro-4 website % docker run --name website -v ~/Desktop/website/index.html:/usr/share/nginx/html:ro -d -p 8080:80 nginx

この、/usr/share/nginx/html:roというのはdocker hubのnginxの公式READMEに書いてある。 (https://hub.docker.com/_/nginx ここの、Hosting some simple static contentというタイトルのところ)

:roというのはread onlyでファイルを共有する(マウントする)というのを指定している。 ・そのため、コンテナ内でtouchコマンドを使うことができない。 ・:roを外すと、read onlyでない状態でコンテナを起動できる。

表示する

コンテナを起動

(base) y.nakata@MacBook-Pro-4 website % docker run --name website -v $(pwd):/usr/share/nginx/html:ro -d -p 8080:80 nginx
1f6aab1df9e5566a817629ee9b7da93f00b4231772b6ece5d65e2599a4b26c06

すると、このようにhtmlファイルが表示される

スクリーンショット 2020-11-21 17.50.44.png (707.2 kB)

dockerコンテナを起動したまま、変更を加えても変更が反映されるようになる。 スクリーンショット 2020-11-21 17.51.29.png (712.1 kB)

dockerのコンテナ中で作業する

(base) y.nakata@MacBook-Pro-4 website % docker exec -it website bash
root@1f6aab1df9e5:/# ls
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@1f6aab1df9e5:/# ls -al
total 88
drwxr-xr-x   1 root root 4096 Nov 21 08:50 .
drwxr-xr-x   1 root root 4096 Nov 21 08:50 ..
-rwxr-xr-x   1 root root    0 Nov 21 08:50 .dockerenv
drwxr-xr-x   2 root root 4096 Nov 17 00:00 bin
drwxr-xr-x   2 root root 4096 Sep 19 21:39 boot
drwxr-xr-x   5 root root  340 Nov 21 08:50 dev
drwxr-xr-x   1 root root 4096 Nov 18 07:48 docker-entrypoint.d
-rwxrwxr-x   1 root root 1202 Nov 18 07:47 docker-entrypoint.sh
drwxr-xr-x   1 root root 4096 Nov 21 08:50 etc
drwxr-xr-x   2 root root 4096 Sep 19 21:39 home
drwxr-xr-x   1 root root 4096 Nov 18 07:48 lib
drwxr-xr-x   2 root root 4096 Nov 17 00:00 lib64
drwxr-xr-x   2 root root 4096 Nov 17 00:00 media
drwxr-xr-x   2 root root 4096 Nov 17 00:00 mnt
drwxr-xr-x   2 root root 4096 Nov 17 00:00 opt
dr-xr-xr-x 130 root root    0 Nov 21 08:50 proc
drwx------   2 root root 4096 Nov 17 00:00 root
drwxr-xr-x   1 root root 4096 Nov 21 08:50 run
drwxr-xr-x   2 root root 4096 Nov 17 00:00 sbin
drwxr-xr-x   2 root root 4096 Nov 17 00:00 srv
dr-xr-xr-x  13 root root    0 Nov 21 08:50 sys
drwxrwxrwt   1 root root 4096 Nov 18 07:48 tmp
drwxr-xr-x   1 root root 4096 Nov 17 00:00 usr
drwxr-xr-x   1 root root 4096 Nov 17 00:00 var

bootstrap のページを表示する

Bootstrap One Page Templates https://bootstrapmade.com/bootstrap-one-page-templates/

このサイトから好きなものを選んで、ソースをダウンロードしてくる。 今回はこれ。 スクリーンショット 2020-11-21 19.17.15.png (826.7 kB)

ファイル: Lonely.zip (4.2 MB)

website配下に中身をコピーする。

(base) y.nakata@MacBook-Pro-4 website % ls
Readme.txt      assets          changelog.txt       forms           index.html      inner-page.html     portfolio-details.html
(base) y.nakata@MacBook-Pro-4 website % pwd
/Users/y.nakata/Desktop/website

すると、index.htmlを表示するはず。。。

(base) y.nakata@MacBook-Pro-4 website % docker run --name website -v $(pwd):/usr/share/nginx/html:ro -d -p 8080:80 nginx
63af065d9ce329df04a2fbc0df8f61de393bca7bfcea666a4a7bf36de268aeef

見事ページが表示されました! スクリーンショット 2020-11-21 19.21.43.png (5.1 MB)

#4: インフラについて簡単に理解する [RDS]DBサーバーを構築

  1. RDSについて
  2. プライベートサブネットの作成
  3. RDSを設置
  4. WebサーバーからRDSに接続する

RDS

今回構築するもの

スクリーンショット 2020-11-03 22.16.34.png (224.2 kB) - プライベートサブネットにDBを置くことで外部からのインターネットによる接続をできないようにして安全性を担保する。 - RDSは複数のアベイラビリティーゾーンに用意しておくことを推奨しているため、別のアベイラビリティーゾーンを用意しておく必要がある。そのため、2つ以上のプライベートサブネットを2つ以上の別のアべイラビリティゾーンにおく必要がある。

1. RDSについて

スクリーンショット 2020-11-03 22.19.39.png (369.8 kB)

マルチAZというRDSの可用性(DBが死んでも復活させやすいこと)を保つシステムがあるが、このシステムを使うのに複数のアベイラビリティゾーンに複数のプライベートサブネットが必要。マルチAZについてはググったら色々出てくるので割愛。

例えばリンク: AWSでマルチAZ構成にする?しない?

2. プライベートサブネットの作成

前回同様

3.RDSの作成

スクリーンショット 2020-11-03 22.55.09.png (254.0 kB)

DB用のセキュリティグループを作成

今回はMySQLを使ってDBを作るので、プライベートサブネットにはMySQLのポートのみ接続できる状態に設定する。

  • セキュリティグループはMySWL/Auroraというものを選択すると3306ポートが開く。
  • ソースにはどこから接続するかを選ぶのだが、個別に繋ぎたいサーバーのIPを選択しても良いが、複数台サーバがある時に全てを設定する必要があるため煩雑。それを避けるためソースにセキュリティグループを選択するとそのセキュリティグループ内にあるもの全てに対して接続を許可することができる。 スクリーンショット 2020-11-03 23.56.57.png (153.3 kB)

作成後

スクリーンショット 2020-11-03 23.57.36.png (94.2 kB)

RDS DBサブネットグループの作成

rdsインスタンスを起動する時にDBサブネットを選択するので、必要。 ※これがないと、RDSをサブネットに紐付けられないので必ず作成

RDS > サブネットグループから作成

前回作成した二つの別々のアベイラビリティゾーンにあるサブネットを追加してサブネットを作成する。 また、VPCも前回作成したものを選択。

スクリーンショット 2020-11-04 0.01.24.png (158.0 kB)

DBパラメータグループ設定

スクリーンショット 2020-11-04 0.05.04.png (75.0 kB)

スクリーンショット 2020-11-04 0.03.27.png (64.4 kB)

オプショングループの作成

何かDBにオプションを設定したい時に使う。 スクリーンショット 2020-11-04 0.05.40.png (71.2 kB)

RDS オプショングループ

RDSの作成

RDS > データベースからDBを作成する

4. WEBサーバーからRDSに接続する

スクリーンショット 2020-11-08 0.02.23.png (199.9 kB)

MySQLをwebサーバーにインストール

sshでサーバーに接続

インストール

$ sudo yum -y install mysql

データベース のエンドポイント

RDSからエンドポイントを確認する。

スクリーンショット 2020-11-08 0.23.10.png (181.4 kB)

mysqlコマンドでmysqlに接続する。

$ mysql -h tokyo-ecole-staging01.cxrffzyjnal4.ap-northeast-1.rds.amazonaws.com -u root -p

接続できると、ターミナルに以下のように表示される。

$ mysql -h aws-and-infra-web.cxrffzyjnal4.ap-northeast-1.rds.amazonaws.com -u root -p -P 3306
Enter password: 

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 1097
Server version: 8.0.15 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [(none)]> 

この設定を.envなどのDB設定のファイルに接続することで、railsなどからDBに接続可能。

#3: インフラについて簡単に理解する[Route53ドメイン登録]

  1. ドメインについて
  2. DNSについて
  3. ドメインの購入
  4. Route53について
  5. Route53でDNSを設定

Route53

1.ドメインについて

ドメインの構造

トップレベルドメイン ・第2レベルドメイン ・第3レベルドメイン ・第4レベルドメイン に分かれている。

スクリーンショット 2020-11-03 11.26.50.png (220.2 kB)

ICANNという団体が管理していて一意性を保つためにそれぞれのトップレベルドメインにつき、一つの団体に管理を任せている。その団体がそれぞれリセラーにドメインを卸てそこから各人への販売が行われる。 ex) .jpはJPRSという団体が管理している。

2. DNSについて

スクリーンショット 2020-11-03 11.32.29.png (471.1 kB)

ドメインを購入したあとはIPアドレスドメイン名を紐づけることで名前解決が行われてどのドメイン名でどのIPアドレスなのかというのがわかる。

スクリーンショット 2020-11-03 11.34.29.png (952.6 kB)

①
ブラウザでhttp://www.example.comなどのURLを打ち込む

②、③、④
フルリゾルバにアクセスされて、フルリゾルバがトップレベル階層のルートを管理している「ルートネームサーバー」にcomで終わるドメインを管理しているサーバーのIPアドレスを教える。

⑤、⑥
comで終わるルートの管理をしているネームサーバー「comネームサーバー」の場所がわかったのでそちらに問い合わせる。今回はexample.comがつぎの階層なのでcomネームサーバーはexample.comネームサーバーのIPをフルリゾルバに伝える。

⑦、⑧
www.example.comのIPを知りたいので「example.comネームサーバー」に「www.example.comのIPアドレスは何?」と問い合わせる。そうすると、「93.184.216.34がwww.example.comのIPアドレスだよ」と帰ってくるので

⑨、⑩
フルリゾルバはスマホに対してもらったIPアドレスを教える。その後、スマホのブラウザからIPアドレス93.184.216.34に接続することでホームページが表示される。

3.ドメインの購入

お名前ドットコムで実際にドメインを購入する(安いもの) https://www.onamae.com/

・1年目はキャンペーンで安いけど2年目以降は高くなるといった場合があるのでそこに気をつけて購入する

スクリーンショット 2020-11-03 11.56.32.png (161.9 kB)

検索するとこのように値段が表示されるので、今回は1円の.workで取得する

料金一覧ページ スクリーンショット 2020-11-03 11.58.07.png (236.3 kB)

実際に購入

購入画面: スクリーンショット 2020-11-03 12.00.31.png (183.8 kB)

Whois情報とはWhoisとは、ドメインの保持者の氏名、住所、電話番号などの登録者情報を誰でも閲覧できる情報提供サービスです。登録者情報はICANN(※)より一般公開することが義務づけられています。

Whois情報公開代行サービスをご利用いただくことで、ドメイン保持者の登録情報から「お名前.com」の情報に代えたうえで一般公開することができます。これによりドメイン保持者のプライバシーが保護されます。

なので、個人情報を登録したくない場合に代理で個人情報登録を行ってくれる

ドメインプロテクションとは: お名前.comで管理されているドメインの各種設定手続きの操作を制限することができるサービスです。

設定・変更する場合は、ドメイン登録者の承認が必要となり、承認を得ることで操作制限されている手続きを進めることができるため、誤操作や第三者不正アクセスによる意図しない操作を遮断することができ、さらなるセキュリティ対策強化に期待することができます。

SSL証明とは: ・httpsにするやつ。

メールアドレスとパスワードを入力して次へ

名前などの登録

スクリーンショット 2020-11-03 12.07.01.png (113.1 kB)

支払い方法入力画面

スクリーンショット 2020-11-03 12.11.48.png (164.7 kB)

サーバー申し込みませんか?という画面が出てくるが今回はEC2を使うので無視

申し込み完了画面

スクリーンショット 2020-11-03 12.14.18.png (209.3 kB)

ドメインの自動更新の設定をOF Fにする

さっきの画面のここから設定できる スクリーンショット 2020-11-03 12.15.28.png (217.2 kB)

ドメイン機能一覧から、ドメインの自動更新を選択 スクリーンショット 2020-11-03 12.20.16.png (182.1 kB)

自動更新がONになっているので、OFFにする スクリーンショット 2020-11-03 12.21.40.png (298.0 kB) ・変更したいドメインにチェックを入れて確認画面へ進むを押下

スクリーンショット 2020-11-03 12.23.06.png (314.8 kB) ・規約に同意して上記内容を申し込むを押下

スクリーンショット 2020-11-03 12.24.03.png (298.6 kB) ・こういった画面が出てくるが無視

スクリーンショット 2020-11-03 12.24.49.png (288.1 kB) ・自動更新が解除される

これでドメインの登録完了

Route53について

スクリーンショット 2020-11-03 14.07.10.png (403.4 kB)

今回はシンプルルーティングを設定する

Route53で DNSを設定する

Route53はネームサーバーの役割を担っており、Route53に問合せを投げることで特定ドメインIPアドレスが返される。 現状ではお名前ドットコムのネームサーバーがIPアドレスを返すようになっているので、そこをRoute53に向き先を変更する必要がある。

スクリーンショット 2020-11-03 14.16.32.png (254.4 kB)

AWSでRoute53のページを開き、ホストゾーンを作成していく

スクリーンショット 2020-11-03 14.20.38.png (1.1 MB)

実際にホストゾーンを作成するとこんな感じ、 それぞれ ns-766.awsdns-31.net. ns-1052.awsdns-03.org. ns-1560.awsdns-03.co.uk. ns-297.awsdns-37.com. というネームサーバーがこのアドレスのネームサーバーとなっているよ。という表記。 (この時点ではまだネームサーバーは変更されていない)

スクリーンショット 2020-11-03 14.26.03.png (164.7 kB)

digコマンドでネームサーバーについての情報をみる

$ dig aws-infra-yuks.work NS + short

[ec2-user@ip-10-0-10-10 ~]$ dig aws-infra-yuks.work NS +short
dns1.onamae.com.
dns2.onamae.com.

お名前ドットコムのネームサーバーが表示されるのでまだRoute53のものは設定されていない。 お名前ドットコムでドメインを購入した時点dねお名前ドットコムのホストゾーンがお名前ドットコムのNSを使ってください。と指定されているからで、ROute53のものを指定するにはお名前ドットコムのページで設定する必要がある。

お名前ドットコムのログイン画面を開いて、Route53をホストゾーンとして設定する

お名前ドットコムの「ドメイン一覧」に移動する 手順書: https://www.onamae.com/guide/p/67

AWSのRoute53を見た時に表示される、この4つの値を入れていく

スクリーンショット 2020-11-03 14.40.39.png (117.5 kB)

こういった画面があるので、1, 2, 3, 4の順に貼り付ける(順番は特に関係ない) スクリーンショット 2020-11-03 14.41.51.png (170.5 kB)

反映までは時間がかかる

反映されたらdigコマンドで再度確認 スクリーンショット 2020-11-03 14.43.32.png (176.2 kB)

AWSには最後に ns-1052.awsdns-03.org. のようにドットがついているがそれは省く。

ドメイン名にEC2インスタンスIPアドレスを紐付ける

スクリーンショット 2020-11-03 14.45.38.png (82.7 kB)

現状ではNSレコードトSOAレコードのみ登録されているのでAレコードを登録していく。 Aレコードとはここ(参照リンク)にあるようにホストのIPアドレスのことを指す。

Aレコード作成

まず、レコード作成をクリック スクリーンショット 2020-11-03 14.48.46.png (149.4 kB)

今回はシンプルルーティングで作成 スクリーンショット 2020-11-03 14.49.13.png (192.7 kB)

名前のところには何も入力しない。 ・そのままの定義名でURLにアクセスしたいため

スクリーンショット 2020-11-03 14.50.14.png (168.7 kB)

これで、しばらく時間が経ったら、ドメインのネームサーバーの変更が反映されたらドメイン名をブラウザに入力するとAレコードのIPが返されてブラウザから設定したサーバーを見れるようになる。

スクリーンショット 2020-11-03 14.54.20.png (100.6 kB)

#2: インフラについて簡単に理解する[EC2]

ウェルノウンポート(TCP)一覧(抜粋)

ポート番号 プロトコル
20 FTP(データ転送)
21 FTP(コントロール)
22 SSH
23 Telnet
25 SMTP
53 DNS
80 HTTP
110 POP3
443 HTTPS

ウェルノウンポート(UDP)一覧(抜粋)

ポート番号 プロトコル
53 DNS
67 DHCP(サーバ)
68 DHCP(クライアント)

登録済ポート番号(自分で使うもの抜粋)

ポート番号 アプリケーション名
3000 Ruby on Rails
3306 MySQL
5432 PostgreSQL
9000 PHP-FPM

スクリーンショット 2020-11-03 1.19.18.png (536.2 kB)

sudo lsof -i -n -P

どのポートでどのサービスが待っているかを表示するコマンド

[ec2-user@ip-10-0-10-10 ~]$ sudo lsof -i -n -P
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
rpcbind  2693      rpc    6u  IPv4  17079      0t0  UDP *:111 
rpcbind  2693      rpc    7u  IPv4  17082      0t0  UDP *:735 
rpcbind  2693      rpc    8u  IPv4  17083      0t0  TCP *:111 (LISTEN)
rpcbind  2693      rpc    9u  IPv6  17084      0t0  UDP *:111 
rpcbind  2693      rpc   10u  IPv6  17085      0t0  UDP *:735 
rpcbind  2693      rpc   11u  IPv6  17086      0t0  TCP *:111 (LISTEN)
chronyd  2706   chrony    1u  IPv4  17295      0t0  UDP 127.0.0.1:323 
chronyd  2706   chrony    2u  IPv6  17296      0t0  UDP [::1]:323 
dhclient 2920     root    6u  IPv4  17857      0t0  UDP *:68 
dhclient 3020     root    5u  IPv6  18151      0t0  UDP [fe80::484:59ff:fe7c:3fcc]:546 
master   3163     root   13u  IPv4  19137      0t0  TCP 127.0.0.1:25 (LISTEN)
sshd     3389     root    3u  IPv4  20940      0t0  TCP *:22 (LISTEN)
sshd     3389     root    4u  IPv6  20951      0t0  TCP *:22 (LISTEN)
sshd     4801     root    3u  IPv4 110006      0t0  TCP 10.0.10.10:22->126.140.213.190:58552 (ESTABLISHED)
sshd     4819 ec2-user    3u  IPv4 110006      0t0  TCP 10.0.10.10:22->126.140.213.190:58552 (ESTABLISHED)

(LISTEN)

(LISTEN)と書かれているものが、他のPCから接続を待ち受けているポート(サービス)

(ESTABLISHED)

(ESTABLISHED)と書かれているものは、現在通信を行っているポート

Apacheのインストール

yum update コマンド(最初)

sudo yum update -y

Apache インストールコマンド

sudo yum -y install httpd

Apache起動コマンド

sudo systemctl start httpd.service systemctlはサービスを動作させる時に使用するコマンドで、今回はhttpdというapacheサービスを起動するのに使用している。

Apache status確認コマンド

sudo systemctl status httpd.service

[ec2-user@ip-10-0-10-10 ~]$ sudo systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since 月 2020-11-02 16:31:30 UTC; 19s ago
     Docs: man:httpd.service(8)
 Main PID: 13864 (httpd)
   Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec:   0 B/sec"
   CGroup: /system.slice/httpd.service
           ├─13864 /usr/sbin/httpd -DFOREGROUND
           ├─13865 /usr/sbin/httpd -DFOREGROUND
           ├─13866 /usr/sbin/httpd -DFOREGROUND
           ├─13867 /usr/sbin/httpd -DFOREGROUND
           ├─13868 /usr/sbin/httpd -DFOREGROUND
           └─13869 /usr/sbin/httpd -DFOREGROUND
  • active(running)となっていれば起動している

ps -axu これでも確認できる。

ps = Linuxで起動しているサービスを表示する -ax = すべてのプロセスを表示 u = メモリの使用率などをともに表示

[ec2-user@ip-10-0-10-10 ~]$ ps -axu
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.5 125584  5480 ?        Ss   11月01   0:02 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root         2  0.0  0.0      0     0 ?        S    11月01   0:00 [kthreadd]
root         4  0.0  0.0      0     0 ?        I<   11月01   0:00 [kworker/0:0H]
root         6  0.0  0.0      0     0 ?        I<   11月01   0:00 [mm_percpu_wq]
root         7  0.0  0.0      0     0 ?        S    11月01   0:00 [ksoftirqd/0]
root         8  0.0  0.0      0     0 ?        I    11月01   0:00 [rcu_sched]
root         9  0.0  0.0      0     0 ?        I    11月01   0:00 [rcu_bh]
root        10  0.0  0.0      0     0 ?        S    11月01   0:00 [migration/0]

以下のようにすると絞り込みができる。

[ec2-user@ip-10-0-10-10 ~]$ ps -axu | grep httpd
root     13864  0.0  0.9 257348  9540 ?        Ss   16:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache   13865  0.0  0.6 298456  6448 ?        Sl   16:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache   13866  0.0  0.6 298456  6448 ?        Sl   16:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache   13867  0.0  0.6 298456  6448 ?        Sl   16:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache   13868  0.0  0.6 495128  6448 ?        Sl   16:31   0:00 /usr/sbin/httpd -DFOREGROUND
apache   13869  0.0  0.6 298456  6448 ?        Sl   16:31   0:00 /usr/sbin/httpd -DFOREGROUND
ec2-user 13967  0.0  0.0 119436   952 pts/0    S+   16:34   0:00 grep --color=auto httpd

Apache自動起動コマンド

サーバーを停止や再起動した時にApacheが自動で起動するようにするコマンド

$ sudo systemctl enable httpd.service

[ec2-user@ip-10-0-10-10 ~]$ sudo systemctl enable httpd.service
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.

自動起動が設定されているか確認するコマンド

[ec2-user@ip-10-0-10-10 ~]$ sudo systemctl is-enabled httpd.service
enabled
  • enabledとなっていればOK

ファイアーウォールの設定

  • 現状ではファイアーウォールが通信をシャットダウンしてしまうのでサーバー上のアプリケーションを見ることができない。なので、ファイアーウォールの設定を変更して、アプリケーションを見れるようにする必要がある。 スクリーンショット 2020-11-03 1.40.45.png (278.8 kB)

セキュリティグループを設定してファイアーウォールを調整する。

スクリーンショット 2020-11-03 1.41.39.png (258.0 kB)

httpアクセスを許可するために80番ポートを開ける

HTTPを任意の場所から接続できるようにして、80番ポートを開ける設定。 スクリーンショット 2020-11-03 1.46.09.png (85.4 kB)

そうすると、Apacheが起動しているサーバーに接続することが可能。 スクリーンショット 2020-11-03 1.46.59.png (130.6 kB)

Gitリポジトリをメンテナンスして軽量化する

保存版

この方の記事が最高に欲しかった、かつまとまっていたので自分の保存用です。 ↓こっちをみてください。 qiita.com

これもいい

qiita.com

qiita.com

qiita.com

Gitリポジトリのメンテ?

Gitリポジトリにあるファイルは .git がバージョン管理をしています。 今回はその .git をメンテナンスする話です。

はじめに

  • リポジトリに容量の大きいファイルをコミットしてしまった
  • git clone がやたらと時間がかかる(知らない間に容量の大きいファイルがコミットされている可能性がある)
  • 複数あるリポジトリを統合したい

こんな悩みを持ったことはないでしょうか。大型のプロジェクトでないと発生しないと思うので、個人プロジェクトではなかなか遭遇することはないでしょう。

今回は上記を解消するための リポジトリメンテナンス方法 をご紹介します。

!! 注意 !!

Gitリポジトリのメンテナンスは破壊的なため、Gitのコマンドを理解している方のみ行ってください。 この記事を読んで実行した結果、大切なリポジトリが壊れても当方は責任を負いかねます。

Gitオブジェクト(Git管理ファイル)の削減

Gitオブジェクトは .git/objects の中身(00~FF)を指します。これが肥大化していると git clone にかなりの時間がかかることになります。 リポジトリにあるファイルの差分や履歴を管理しているオブジェクトで、コミットが多くなればなるほど容量は膨れていきます。

このオブジェクトには知らず知らずにゴミをコミットしてしまっていることがあります。 :put_litter_in_its_place: そして、そのゴミが意図せずオブジェクトの容量を肥大化させている一因になることも多いです。

良くある一例で、npm install を行い node_modules 以下に依存ファイルを取得・ビルドし、そのままコミットしたとします。 直後、.gitignorenode_modules を書き忘れていることに気づき、慌てて git rm -rf node_modules をしたとしてもダメです。 一度コミットしてしまったものは既に管理対象となって通常の方法では消しさることはできません。 (そう、消したい過去を消去することができないのと同じです。)

このようなリポジトリは最初の方は問題ないですが、ファイルが増えてくると git clone に時間がかかってくるので履歴を消去したほうが時間の節約になります。

◆ 調査方法

1. Gitリポジトリをclone

$ git clone git@github.com:kaneshin/dotfiles.git ~/dotfiles

既にリポジトリをcloneしている場合はガベコレをします。

$ git gc --auto

2. .git/objects のファイルサイズ

du コマンドを使用して、 .git/objects のファイルサイズを測ります。

$ du -sh .git/objects
295M    .git/objects 

3. git_find_big.sh スクリプト

Maintaining a Git Repositoryにある git_find_big.sh というスクリプトを使用します。

このスクリプトリポジトリにあるファイルの容量降順で一覧してくれます。 一覧はデフォルト10件表示となっていますが、件数を変更することも可能です。

objects=`git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr | head`

↑ を ↓ のように head コマンドにライン数を渡します。

objects=`git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr | head -n 100`

4. git_find_big.sh スクリプト実行

コミット履歴があればあるほど処理に時間がかかります。

$ ./git_find_big.sh
All sizes are in kB's. The pack column is the size of the object, compressed, inside the pack file.
size   pack   SHA                                       location
34442  31741  AAAAAAb732e07f17cf71f1d8584a48aXXXXXXXXX  dotfiles/node_modules/protractor/selenium/selenium-server-standalone-2.45.0.jar
10784  3428   AAAAAAe5f77536e4b078fd5d1957f87XXXXXXXXX  dotfiles/node_modules/chromedriver/lib/chromedriver/chromedriver

上記のような一覧を得ることが出来ます。 普段、あまり気にせずにGitへコミットしていると思いますが、今一度無駄なファイルが入っていないかの確認も面白いので試してみるのもいいと思います。

◆ ファイルを歴史から抹消する方法

歴史の書き換えでgit filter-branchコマンドを使用します。これを使いこなすことが出来ればあなたもリポジトリクラッシャーメンテナーになることができます。

このfilter-branchの使い方は簡単ですが、とても強力で破壊的です。

例)

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

HEADを対象としてコマンドを実行することができます。--all とすれば全てのブランチに対して実行します。

さて、実際のメンテの流れです。

0. バックアップを取る

# clone
$ git clone git@github.com:foo/bar.git /tmp/bar
$ cd /tmp/bar

# リモートのブランチを全てチェックアウト
$ git branch -r | sed -e "s#origin/##" | xargs -I{} git checkout -b {} origin/{}

# バックアップとして全てのブランチを別リモート先へプッシュ
$ git remote add tmp git@github.com:foo/bar-tmp.git
$ git push --force tmp --all

1. 履歴抹消対象ファイル

# 配列で抹消ファイルをセットする
$ TARGETS=(
  "shared-local-instance.db"
  "dump.rds"
  "*.log"
  "node_modules/"
)

# 半角スペースでjoinする
$ target=$(printf " %s" "${TARGETS[@]}")
$ target=${target:1}

2. 履歴抹消する

全てのブランチを対象にするため -- --all で実施する recursiveで行いたくない場合は git rm -r-r を削除してください。

$ git filter-branch --index-filter "git rm -r --cached --ignore-unmatch ${target}" -- --all

実行すると、削除対象ファイルが存在した場合に下記のようなログが出力されます。

Rewrite 1a8b35d383ae6472ef7ab8591aca3540f0771744 (3806/29089)rm 'include/swift/ABI/Class.h'
rm 'include/swift/ABI/MetadataValues.h'
rm 'include/swift/AST/AST.h'
rm 'include/swift/AST/ASTContext.h'
rm 'include/swift/AST/ASTVisitor.h'
rm 'include/swift/AST/ASTWalker.h'
rm 'include/swift/AST/Attr.def'
rm 'include/swift/AST/Attr.h'
rm 'include/swift/AST/Builtins.def'
rm 'include/swift/AST/Builtins.h'
rm 'include/swift/AST/Component.h'
rm 'include/swift/AST/Decl.h'
rm 'include/swift/AST/DeclContext.h'
rm 'include/swift/AST/DeclNodes.def'
rm 'include/swift/AST/DiagnosticEngine.h'
rm 'include/swift/AST/Diagnostics.def'
...

3. 履歴改変後のものをプッシュする

$ git push origin --all --force

もしくは、新しくリポジトリを作成して新しい方へプッシュするのもアリです。

◆ 結果

これは実際に実行したときの結果ログです。

[kaneshin@ip-172-0-0-0] /tmp                                                    
$ git clone git@github.com:foo/bar.git                               
Cloning into 'bar'...                                                        
remote: Counting objects: 202026, done.                                               
remote: Compressing objects: 100% (2547/2547), done.                                  
remote: Total 202026 (delta 4158), reused 3859 (delta 3859), pack-reused 195620       
Receiving objects: 100% (202026/202026), 292.02 MiB | 9.04 MiB/s, done.               
Resolving deltas: 100% (116884/116884), done.                                         
Checking connectivity... done.                                                        

# ... リモートからバックアップを消去する

[kaneshin@ip-172-0-0-0] /tmp                                                    
$ git clone git@github.com:foo/bar.git                               
Cloning into 'bar'...                                                        
remote: Counting objects: 140976, done.                                               
remote: Compressing objects: 100% (3913/3913), done.                                  
remote: Total 140976 (delta 8047), reused 7926 (delta 7926), pack-reused 129137       
Receiving objects: 100% (140976/140976), 148.73 MiB | 3.59 MiB/s, done.               
Resolving deltas: 100% (90626/90626), done.                                           
Checking connectivity... done.      

ピックアップして見てみると

Receiving objects: 100% (202026/202026), 292.02 MiB | 9.04 MiB/s, done.               
↓
Receiving objects: 100% (140976/140976), 148.73 MiB | 3.59 MiB/s, done.               

削減した結果、292MB から 148MB になりました。 およそ半分にまで削減できたので、うれしい限りです。無駄なファイルをコミットしたまま放置はダメですね。

おわりに

今回の話はAtlassianが紹介している 「Maintaining a Git Repository」 の紹介でした。 Gitは使えば使うほどしっくり来ますが、たまにはリポジトリのメンテナンスもしてあげてください。

複数リポジトリ統合の話しは別の機会に