データ構造とアルゴリズム:Bubbleソート
一番左側から、配列の個数分forループを行い、limitまで到達したら再度左に戻ってきて同じ処理を行う。 その際にlimitの位置は1つ左に移動する。
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 チュートリアル
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アーキテクチャ
それぞれのworkerではkubeketというものが動いていて、それがそれぞれのworkerノードとデータをやりとりしたり、アクセスを行ったりを可能にしている
Pod, Service & Ingress
kubernetesの基本的な構成要素で、kubernetesを実用的に使うためにはこれらを知っておく必要がある。
Pod
Podについての説明は公式HPに書いているが、実際に触ってみないとなんとも。。 密接に関連するアプリを起動しているコンテナをカプセル化させてまとめるコンテナのコンテナのようなもののよう。 https://kubernetes.io/ja/docs/concepts/workloads/pods/pod-overview/
- Pod内で各アプリケーションごとにIPアドレスが振られており、コンテナがkillされた時に、新しくアプリケーションコンテナが立ち上げられるが、IPアドレスが変更されてしまう。そうなると、今まで接続していたIPアドレスに接続されなくなってしまい困るのでIPアドレスの永続化を行うためにServiceが用いられる。
Service and Ingress
PodとServiceのプロセスは結合されていないので、Podのプロセスが止まってしまってもServiceのプロセスが止まることはないのでIPアドレスの永続化を行える。 各PodはServiceを介してコミュニケーションを行う
クラスター内のServiceに対する外部からのアクセス(主にHTTP)を管理するAPIオブジェクトです。 Ingressは負荷分散、SSL終端、名前ベースの仮想ホスティングの機能を提供します。 引用:公式:Ingress
Config Map and Secret
Config Map
コンテナのアプリケーション名などが変更されたた時に各コンテナの設定を変更してre-buildやre-pushを行う必要があるため、一度アプリを止めて再度構築し直しを行わなければいけない。そのような状況を改善するためにConfig Mapが使われる。
・例えば、dbのアプリケーション名を変更した時に、Config Mapの名称を変更するだけで、Config Mapから、アプリのロケーションを読み取れるのでわざわざDockerfileなどのアプリ名を変更してre-buildしたりしなくても済む。
しかし、DBのユーザー名やパスワードなどを変更する際にこのConfigMapに記載することはやめたほうが良い。ユーザー名やパスワードの変更を管理したい際に使われるのがSecretという機能である。
Secret
Volumes
Dockerコンテナのvolumesと同じようなもので、データベースをローカルで管理できるようにしてPodが落ちた時でもデータの永続化ができるようにするもの
Deployments and Stateful Sets
Deployment
Deoploymentは、Podのコピーを作ることによって、もしnode1のPodが落ちたとしてもload balancerによってnode2のアプリケーションをIPにセットすることで運用ができなくなる状態を防ぐことが可能。
Stateful Sets
StatefulSetsではDBなどのStatefulなアプリケーションの複製を行うために設定されるもので、データベースが落ちた時にもデータの永続化ができるようにするためのもの。
Minikube and Kubectl
minikubeとは?
実運用する際に動くかテストを行いたい時にローカル環境でミニマムなPod環境を作成してテストを行うことができるツール - ローカルPC上にVirtual Boxを構築することができる - そのVirtual Box上でnodeを走らせることができる - 1 node K8s cluster
kubuctlとは?
APIを通して、kubernetesの設定をCUIで行えるアプリケーション ローカルマシンにインストールしてterminal上からkubernetesを操作/設定できる
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
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に接続することができる。
もちろん、8080以外も接続できるので、
(base) y.nakata@MacBook-Pro-4 docker_tutorial % docker run -d -p 3000:80 nginx:latest 22cf87a188980192a7771371c1c174202dbd3b530d98580a534f705541c4a71e
というコマンドでもOK
Volumesについて
コンテナとホスト(ローカルPC)間のデータの共有を可能にするために使用する
nginx (docker hub): https://hub.docker.com/_/nginx
共有しているvolumeでhtmlファイルを表示させる
(base) y.nakata@MacBook-Pro-4 docker_tutorial % docker run --name website -d -p 8080:80 nginx b86b995e912390fda2885ef65c89316d3ec4d80fb1cc1642a195351e16c8f7eb
imageの時と同様にlocalhostの8080とdockerコンテナの80ポートを接続する.
その後、websiteでlocalhost:8080
に接続できるかを確認する。
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をどこにマウントするかを指定して、pwdでwebsiteであることを教えてあげる。
多分これでも良い。
(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ファイルが表示される
dockerコンテナを起動したまま、変更を加えても変更が反映されるようになる。
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/
このサイトから好きなものを選んで、ソースをダウンロードしてくる。 今回はこれ。
ファイル: 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
見事ページが表示されました!
#4: インフラについて簡単に理解する [RDS]DBサーバーを構築
- RDSについて
- プライベートサブネットの作成
- RDSを設置
- WebサーバーからRDSに接続する
RDS
今回構築するもの
- プライベートサブネットにDBを置くことで外部からのインターネットによる接続をできないようにして安全性を担保する。 - RDSは複数のアベイラビリティーゾーンに用意しておくことを推奨しているため、別のアベイラビリティーゾーンを用意しておく必要がある。そのため、2つ以上のプライベートサブネットを2つ以上の別のアべイラビリティゾーンにおく必要がある。
1. RDSについて
マルチAZというRDSの可用性(DBが死んでも復活させやすいこと)を保つシステムがあるが、このシステムを使うのに複数のアベイラビリティゾーンに複数のプライベートサブネットが必要。マルチAZについてはググったら色々出てくるので割愛。
例えばリンク: AWSでマルチAZ構成にする?しない?
2. プライベートサブネットの作成
前回同様
3.RDSの作成
DB用のセキュリティグループを作成
今回はMySQLを使ってDBを作るので、プライベートサブネットにはMySQLのポートのみ接続できる状態に設定する。
- セキュリティグループはMySWL/Auroraというものを選択すると3306ポートが開く。
- ソースにはどこから接続するかを選ぶのだが、個別に繋ぎたいサーバーのIPを選択しても良いが、複数台サーバがある時に全てを設定する必要があるため煩雑。それを避けるためソースにセキュリティグループを選択するとそのセキュリティグループ内にあるもの全てに対して接続を許可することができる。
作成後
RDS DBサブネットグループの作成
rdsインスタンスを起動する時にDBサブネットを選択するので、必要。 ※これがないと、RDSをサブネットに紐付けられないので必ず作成
RDS > サブネットグループから作成
前回作成した二つの別々のアベイラビリティゾーンにあるサブネットを追加してサブネットを作成する。 また、VPCも前回作成したものを選択。
DBパラメータグループ設定
オプショングループの作成
何かDBにオプションを設定したい時に使う。
RDSの作成
RDS > データベースからDBを作成する
4. WEBサーバーからRDSに接続する
MySQLをwebサーバーにインストール
sshでサーバーに接続
インストール
$ sudo yum -y install mysql
データベース のエンドポイント
RDSからエンドポイントを確認する。
$ 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ドメイン登録]
Route53
1.ドメインについて
ドメインの構造
・トップレベルドメイン ・第2レベルドメイン ・第3レベルドメイン ・第4レベルドメイン に分かれている。
ICANNという団体が管理していて一意性を保つためにそれぞれのトップレベルドメインにつき、一つの団体に管理を任せている。その団体がそれぞれリセラーにドメインを卸てそこから各人への販売が行われる。 ex) .jpはJPRSという団体が管理している。
2. DNSについて
ドメインを購入したあとはIPアドレスとドメイン名を紐づけることで名前解決が行われてどのドメイン名でどのIPアドレスなのかというのがわかる。
① ブラウザで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年目以降は高くなるといった場合があるのでそこに気をつけて購入する
検索するとこのように値段が表示されるので、今回は1円の.workで取得する
実際に購入
購入画面:
Whois情報とは: Whoisとは、ドメインの保持者の氏名、住所、電話番号などの登録者情報を誰でも閲覧できる情報提供サービスです。登録者情報はICANN(※)より一般公開することが義務づけられています。
Whois情報公開代行サービスをご利用いただくことで、ドメイン保持者の登録情報から「お名前.com」の情報に代えたうえで一般公開することができます。これによりドメイン保持者のプライバシーが保護されます。
なので、個人情報を登録したくない場合に代理で個人情報登録を行ってくれる
ドメインプロテクションとは: お名前.comで管理されているドメインの各種設定手続きの操作を制限することができるサービスです。
設定・変更する場合は、ドメイン登録者の承認が必要となり、承認を得ることで操作制限されている手続きを進めることができるため、誤操作や第三者の不正アクセスによる意図しない操作を遮断することができ、さらなるセキュリティ対策強化に期待することができます。
メールアドレスとパスワードを入力して次へ
名前などの登録
支払い方法入力画面
サーバー申し込みませんか?という画面が出てくるが今回はEC2を使うので無視
申し込み完了画面
ドメインの自動更新の設定をOF Fにする
さっきの画面のここから設定できる
自動更新がONになっているので、OFFにする ・変更したいドメインにチェックを入れて確認画面へ進むを押下
・規約に同意して上記内容を申し込むを押下
・こういった画面が出てくるが無視
・自動更新が解除される
これでドメインの登録完了
Route53について
今回はシンプルルーティングを設定する
Route53で DNSを設定する
Route53はネームサーバーの役割を担っており、Route53に問合せを投げることで特定ドメインのIPアドレスが返される。 現状ではお名前ドットコムのネームサーバーがIPアドレスを返すようになっているので、そこをRoute53に向き先を変更する必要がある。
AWSでRoute53のページを開き、ホストゾーンを作成していく
実際にホストゾーンを作成するとこんな感じ、 それぞれ ns-766.awsdns-31.net. ns-1052.awsdns-03.org. ns-1560.awsdns-03.co.uk. ns-297.awsdns-37.com. というネームサーバーがこのアドレスのネームサーバーとなっているよ。という表記。 (この時点ではまだネームサーバーは変更されていない)
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つの値を入れていく
こういった画面があるので、1, 2, 3, 4の順に貼り付ける(順番は特に関係ない)
反映までは時間がかかる
反映されたらdigコマンドで再度確認
AWSには最後に ns-1052.awsdns-03.org. のようにドットがついているがそれは省く。
ドメイン名にEC2インスタンスのIPアドレスを紐付ける
現状ではNSレコードトSOAレコードのみ登録されているのでAレコードを登録していく。 Aレコードとはここ(参照リンク)にあるようにホストのIPアドレスのことを指す。
Aレコード作成
まず、レコード作成をクリック
今回はシンプルルーティングで作成
名前のところには何も入力しない。 ・そのままの定義名でURLにアクセスしたいため
これで、しばらく時間が経ったら、ドメインのネームサーバーの変更が反映されたらドメイン名をブラウザに入力するとAレコードのIPが返されてブラウザから設定したサーバーを見れるようになる。
#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 |
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 インストールコマンド
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
ファイアーウォールの設定
- 現状ではファイアーウォールが通信をシャットダウンしてしまうのでサーバー上のアプリケーションを見ることができない。なので、ファイアーウォールの設定を変更して、アプリケーションを見れるようにする必要がある。
セキュリティグループを設定してファイアーウォールを調整する。
httpアクセスを許可するために80番ポートを開ける
HTTPを任意の場所から接続できるようにして、80番ポートを開ける設定。
そうすると、Apacheが起動しているサーバーに接続することが可能。
Gitリポジトリをメンテナンスして軽量化する
保存版
この方の記事が最高に欲しかった、かつまとまっていたので自分の保存用です。 ↓こっちをみてください。 qiita.com
これもいい
Gitリポジトリのメンテ?
Gitリポジトリにあるファイルは .git
がバージョン管理をしています。
今回はその .git
をメンテナンスする話です。
はじめに
こんな悩みを持ったことはないでしょうか。大型のプロジェクトでないと発生しないと思うので、個人プロジェクトではなかなか遭遇することはないでしょう。
今回は上記を解消するための リポジトリメンテナンス方法 をご紹介します。
!! 注意 !!
Gitリポジトリのメンテナンスは破壊的なため、Gitのコマンドを理解している方のみ行ってください。 この記事を読んで実行した結果、大切なリポジトリが壊れても当方は責任を負いかねます。
Gitオブジェクト(Git管理ファイル)の削減
Gitオブジェクトは .git/objects
の中身(00~FF)を指します。これが肥大化していると git clone
にかなりの時間がかかることになります。
リポジトリにあるファイルの差分や履歴を管理しているオブジェクトで、コミットが多くなればなるほど容量は膨れていきます。
このオブジェクトには知らず知らずにゴミをコミットしてしまっていることがあります。 :put_litter_in_its_place: そして、そのゴミが意図せずオブジェクトの容量を肥大化させている一因になることも多いです。
良くある一例で、npm install
を行い node_modules
以下に依存ファイルを取得・ビルドし、そのままコミットしたとします。
直後、.gitignore
に node_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は使えば使うほどしっくり来ますが、たまにはリポジトリのメンテナンスもしてあげてください。
複数リポジトリ統合の話しは別の機会に