diadia

興味があることをやってみる。自分のメモを残しておきます。

EC2インスタンスに複数のアパッチコンテナを起動して接続を試みる

今まで一つのサーバーにwebサーバーなどのソフトウェアが一つずつ入っている状況が自然なことだと考えてきたので、同じソフトウェアが同時に動く環境を用意し、いわゆるコンテナという概念を体感してみた。

方法としてはec2インスタンスにcontainerを3つ追加する。で一つは単純に既存のbridgeにコンテナを起動する。 残りの2つは、新しく作ったbridgeにコンテナをつなげる。

以下はec2インスタンス起動用のterraform設定ファイルである。

vpc.tf

# VPC

resource "aws_vpc" "example" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true # DNS解決を有効化
  enable_dns_hostnames = true # DNSホスト名を有効化

  tags = {
    Name = "example"
  }
}


# Subnet

resource "aws_subnet" "example" {
  cidr_block        = "10.0.1.0/24"
  availability_zone = "us-west-2a"
  vpc_id            = aws_vpc.example.id

  # trueにするとインスタンスにパブリックIPアドレスを自動的に割り当ててくれる
  map_public_ip_on_launch = true

  tags = {
    Name = "example"
  }
}


# Internet Gateway

resource "aws_internet_gateway" "example" {
  vpc_id = aws_vpc.example.id

  tags = {
    Name = "example"
  }
}


# Route Table

resource "aws_route_table" "example" {
  vpc_id = aws_vpc.example.id

  tags = {
    Name = "example"
  }
}

resource "aws_route" "example" {
  gateway_id             = aws_internet_gateway.example.id
  route_table_id         = aws_route_table.example.id
  destination_cidr_block = "0.0.0.0/0"
}

resource "aws_route_table_association" "example" {
  subnet_id      = aws_subnet.example.id
  route_table_id = aws_route_table.example.id
}


# Security Group

resource "aws_security_group" "example" {
  vpc_id = aws_vpc.example.id
  name   = "example"

  tags = {
    Name = "example"
  }
}

# インバウンドルール(ssh接続用)
resource "aws_security_group_rule" "in_ssh" {
  security_group_id = aws_security_group.example.id
  type              = "ingress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
}

# インバウンドルール(http接続用)
resource "aws_security_group_rule" "in_http" {
  security_group_id = aws_security_group.example.id
  type              = "ingress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = 80
  to_port           = 80
  protocol          = "tcp"
}


# インバウンドルール(pingコマンド用)
resource "aws_security_group_rule" "in_icmp" {
  security_group_id = aws_security_group.example.id
  type              = "ingress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = -1
  to_port           = -1
  protocol          = "icmp"
}

# アウトバウンドルール(全開放)
resource "aws_security_group_rule" "out_all" {
  security_group_id = aws_security_group.example.id
  type              = "egress"
  cidr_blocks       = ["0.0.0.0/0"]
  from_port         = 0
  to_port           = 0
  protocol          = "-1"
}
ec2.tf


# EC2 Instance

resource "aws_instance" "example" {
  ami                    = "ami-0873b46c45c11058d"
  vpc_security_group_ids = [aws_security_group.example.id]
  subnet_id              = aws_subnet.example.id
  key_name               = "id_rsa_ec2"
  instance_type          = "t2.micro"

  tags = {
    Name = "example"
  }

  user_data = <<EOF
#!/bin/bash
sudo yum update -y
sudo amazon-linux-extras install docker
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -a -G docker ec2-user
EOF
}


# Key Pair

resource "aws_key_pair" "example" {
  key_name   = "id_rsa_ec2"
  public_key = file("../id_rsa_ec2.pub")
}

手順

terraform apply

ec2インスタンスができたらマネジメントコンソールでセキュリティグループを追加する。 TCPで8000 - 9000 を開けておく。

ec2に接続する。

ssh -i id_rsa_ec2 ec2-user@パブリックIP

dockerfileを準備する。

mkdir ~/docker_practice
touch ~/docker_practice/Dockerfile
cd docker_practice
vi Dockerfile
#Dockerfileの内容

FROM centos:latest

RUN yum install -y httpd

#COPY ./index.html /var/www/html/index.html

EXPOSE 80 
RUN echo "Hello Apache." > /var/www/html/index.html

ENTRYPOINT ["/usr/sbin/httpd","-DFOREGROUND"]

次にImageをビルドした後にコンテナを起動していく

docker image build -t docker_practice

docker run -d -p 8000:80 docker_practice

ブラウザにパブリックIP:8000で接続できるか確認してみる。

dockerのbridgeとコンテナの情報を調べる。

docker network ls

docker network inspect bridge 

結果としてbridgeが属するサブネット及びgatewayがわかる。gatewayはbridge のアドレスみたいなものだと現段階では理解している。

次にdockerのコンテナの情報を調べる

docker container ls

docker network inspect (container_id)

この情報からbridgeと同じサブネット内にコンテナが作成されたことがわかった。

次に新しいブリッジを作り、そのブリッジにアタッチしたコンテナを2つ起動させる。

docker network create --attachable -d bridge --subnet=10.99.0.0/16 new_bridge
docker network ls

一覧でnew_bridgeが追加されていればオッケイ.また、docker network inspect new_bridgeでブリッジのサブネットが10.99.0.0/16であるかも確認する。

次にnew_bridgeにコンテナを2つ起動する。

docker run -d -p 8030:80 --net new_bridge docker_practice
docker run -d -p 8090:80 --net new_bridge docker_practice

このコンテナにそれぞれ接続できるかパブリックIP:8030 またはパブリックIP:8090で接続してみる。 できたらそれぞれのコンテナ情報を確認する。

docker container inspect (container_id)

そして内容にnew_bridgeという文言があったり、new_bridgeが属するサブネットが表示されれば、別のブリッジのコンテナが起動していることになる。

これらの確認は黒川さんのyoutubeのやり方をそのまま真似しただけだけど、とても勉強になった。 興味があればこちらを。
https://www.youtube.com/watch?v=h6uw5c5GB_U&list=PLtpYHR4V8Mg-jbuk4yoXhXwJtreodnvzg&index=2