AWS ECS on EC2 から OCI OKEへの移行検証をします。
AWS ECS Fargateをお使いの場合は、以下のQiitaをご参照ください。
ただ結論からお話しすると移行元の環境が違うだけで移行先の環境は同じの為、
OCIでの作業は双方のQiita記事でほぼ同じになります。
0. はじめに
0-1. 移行検証のイメージと流れ
何かAWSからOCIに移行するというよりは、AWSでも動いていたコンテナイメージをKubernetesベースのオーケストレーションツールOCI OKEでも問題なく動くことを確認していきます。
- ローカル環境でイメージを作成し、AWS環境のECRにpush
- ECS on EC2上でECRにあるイメージを基にデプロイし、ロードバランサーのDNS名をブラウザから叩いてHello World!がでることを確認
- 同じローカル環境にあるイメージを、今度はOCIRにpush
- OKE上でOCIRにあるイメージを基にデプロイし、ロードバランサーのIPアドレスをブラウザから叩いてHello World!がでることを確認
0-2. この記事の対象者
- AWS ECSからOCIに移行したい人
- AWSはわかるけど、OCIはほぼ触ったことない人
0-3. 前提
- ローカル環境既に構築済みで既に以下がインストールされているものとする
- Docker
- kubectl
- 今回のローカル環境はubuntu
1.事前準備
既に出来ている方もいると思うので、折りたたんで置きます。
適宜、折りたたみを開いてご確認下さい。
【AWS】AWS IAMユーザーの作成とアクセスキーの取得
1-1. IAMユーザー(Administrator)を作成
IAMのページより、画面左の [アクセス管理] > [ユーザー] からユーザーの作成
を押す。
ステップ1:ユーザー詳細の指定
- ユーザー名:Administrator
- AWS マネジメントコンソールへのユーザーアクセスを提供する - オプション:チェック入れる
- IAM ユーザーを作成します:チェックを入れる
- 自動生成されたパスワード:チェックを入れる
ステップ2:許可を設定
- 許可のオプション: ポリシーを直接アタッチする
- 許可ポリシー: AdministratorAccess
※今回は検証用途のみで簡単のために、AdministratorAccess ポリシーを選択します。
1-2. AWS IAM ユーザーのアクセスキーの取得
作成したIAMユーザーの詳細ページで、セキュリティ認証情報ページ
を選択します。
次に、アクセスキーで アクセスキーの作成
を選択します。
ステップ1:
- ユースケース
- コマンドインターフェイス(CLI):チェック入れる
ステップ2:
デフォルトの値のままアクセスキーを作成
を押す
ステップ3:
.csv ファイルをダウンロードを選択し、IAM ユーザーのアクセスキーとシークレットアクセスキーを含む .csv ファイルを保存します。※この情報は後のaws configureの設定で必要になります。
完了 を選択します。
【ローカル環境】AWS CLIのインストール
1-3. AWS CLIのインストール
ローカル環境にAWS CLIをインストールします
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html
1. 上記の公式ドキュメントを参考にインストールします。
2. インストールできたことを確認
ubuntu@public-instance-tokunaga-ubuntu2:~$ aws --version
aws-cli/2.19.1 Python/3.12.6 Linux/5.15.0-1069-oracle exe/x86_64.ubuntu.20
3. aws configureの設定
ubuntu@public-instance-tokunaga-ubuntu2:~$ aws configure
AWS Access Key ID [None]: XXXXXXXXXXXXXXX //先ほどダウンロードしたcsvファイルの内容を転記
AWS Secret Access Key [None]: XXXXXXXXXXXXXX //先ほどダウンロードしたcsvファイルの内容を転記
Default region name [None]: ap-northeast-1
Default output format [None]: json
4. 問題なくAWS CLIが設定できたか、試してS3一覧を出力してみる
ubuntu@public-instance-tokunaga-ubuntu2:~$ aws s3 ls
2024-08-26 10:43:21 bucket-es-repo-snapshot-0826
2024-08-29 13:00:36 bucket-es-repo-snapshot-0830
無事に一覧でました!
【ローカル環境】OCI CLIのインストール
1-4. OCI CLIのインストール
下記のドキュメントを参考にCLIをインストールしていきます。
手動およびオフライン・インストール
Oracle Linuxの場合はこちらのクイックスタートの方がわかりやすいので、適宜ご参考ください。
私はUbunt環境にCLIをインストールしていきます。
1. CLIをインストールする前に、新しいUbuntuイメージで次のコマンドを実行
sudo apt update
sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget libbz2-dev
sudo apt update && sudo apt install python3 python3-pip python3-venv
2. 仮想環境の作成
python3.8 -m venv oracle-cli
3. 仮想環境をアクティブ化
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ source oracle-cli/bin/activate
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$
4. CLIのインストール
こちらのステップ3を参考に、oci-cli.zipをダウンロードして、解答し、インストールします。
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ pip install oci_cli-*-py2.py3-none-any.whl
5. CLI構成ファイルの設定
oci setup config
を実施して、OCIの操作に必要な資格証明を構成ファイルに設定していきます。こちらのOCIのチュートリアル「3. CLIの設定」をご参考に設定をしてください。
6. CLI設定が正しくできたかの確認
試しにObjectStoregeのnamespaseが取得できるか確認します。
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ oci os ns get
{
"data": "xxxxxx" //ここにnamespaseが表示される
}
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$
2.今回移行する内容物(Hello World!)の作成
2-1. Dockerfileの作成
参考資料:
Amazon ECS で使用するコンテナイメージの作成
上記のドキュメントを参考にDockerfileを作成します。
1. Dockerfileの作成
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ touch Dockerfile
2. 作成したDockerfileの編集
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ vi Dockerfile
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ cat Dockerfile
FROM ubuntu:18.04
# Install dependencies
RUN apt-get update && \
apt-get -y install apache2
# Install apache and write hello world message
RUN echo 'Hello World!' > /var/www/html/index.html
# Configure apache
RUN echo '. /etc/apache2/envvars' > /root/run_apache.sh && \
echo 'mkdir -p /var/run/apache2' >> /root/run_apache.sh && \
echo 'mkdir -p /var/lock/apache2' >> /root/run_apache.sh && \
echo '/usr/sbin/apache2 -D FOREGROUND' >> /root/run_apache.sh && \
chmod 755 /root/run_apache.sh
EXPOSE 80
CMD /root/run_apache.sh
2-2. Dockerfileからイメージをビルド
1. Dockerfileからイメージをビルド
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ sudo docker build -t hello-world .
[+] Building 18.0s (8/8) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 590B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:18.04 0.3s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [1/4] FROM docker.io/library/ubuntu:18.04@sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98 1.5s
=> => resolve docker.io/library/ubuntu:18.04@sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98 0.0s
=> => sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98 1.33kB / 1.33kB 0.0s
=> => sha256:dca176c9663a7ba4c1f0e710986f5a25e672842963d95b960191e2d9f7185ebe 424B / 424B 0.0s
=> => sha256:f9a80a55f492e823bf5d51f1bd5f87ea3eed1cb31788686aa99a2fb61a27af6a 2.30kB / 2.30kB 0.0s
=> => sha256:7c457f213c7634afb95a0fb2410a74b7b5bc0ba527033362c240c7a11bef4331 25.69MB / 25.69MB 0.4s
=> => extracting sha256:7c457f213c7634afb95a0fb2410a74b7b5bc0ba527033362c240c7a11bef4331 1.0s
=> [2/4] RUN apt-get update && apt-get -y install apache2 15.1s
=> [3/4] RUN echo 'Hello World!' > /var/www/html/index.html 0.2s
=> [4/4] RUN echo '. /etc/apache2/envvars' > /root/run_apache.sh && echo 'mkdir -p /var/run/apache2' >> /root/run_ 0.4s
=> exporting to image 0.5s
=> => exporting layers 0.5s
=> => writing image sha256:3580a22bf44ebc94b66b311633bbfe5ab5248a58fd1da8b5e8937d22c1c88ed1 0.0s
=> => naming to docker.io/library/hello-world 0.0s
2. 作成したイメージファイルを確認
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 3580a22bf44e 24 hours ago 205MB
2-3. コンテナを起動&稼働確認
1. イメージを指定してコンテナを起動
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ sudo docker run -dp 8080:80 hello-world
46cce6e428b388caa3d3de8e38af62de3fc9ea208eac6f834795a5db4ef916ba
2. コンテナを一覧表示
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
46cce6e428b3 hello-world "/bin/sh -c /root/ru…" About a minute ago Up About a minute 0.0.0.0:8080->80/tcp, :::8080->80/tcp peaceful_yalow
3. 正しく「Hello World!」が出るか確認
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ curl localhost:8080
Hello World!
3.環境デプロイ@AWS
3-1. AWSCLIでECRを作成
1. CLIでECRを作成
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ aws ecr create-repository --repository-name hello-repository --region ap-northeast-1{
"repository": {
"repositoryArn": "arn:aws:ecr:ap-northeast-1:471112636311:repository/hello-repository",
"registryId": "471112636311",
"repositoryName": "hello-repository",
"repositoryUri": "471112636311.dkr.ecr.ap-northeast-1.amazonaws.com/hello-repository",
"createdAt": "2024-11-07T09:34:27.789000+00:00",
"imageTagMutability": "MUTABLE",
"imageScanningConfiguration": {
"scanOnPush": false
},
"encryptionConfiguration": {
"encryptionType": "AES256"
}
}
}
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$
3-2. ECS クラスタの作成
- インフラストラクチャー:Amazon EC2 インスタンス
残りの項目はデフォルト値で作成
3-3. ECS クラスタのタスク定義とサービスを作成
- タスク定義
ナビゲーションペインでタスク定義を選択します。
新しいタスク定義の作成、JSONを使用した新しいタスク定義の作成の順に選択します
以下のタスク定義の例をコピーしてボックスに貼り付け、作成を選択します。
{
"family": "hello-world-fargate",
"executionRoleArn": "ecsTaskExecutionRole",
"networkMode": "awsvpc",
"containerDefinitions": [
{
"name": "hello-world-app",
"image": "<aws_account_id>.dkr.ecr.<region>.amazonaws.com/hello-repository:latest",
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
],
"essential": true
}
],
"requiresCompatibilities": [
"FARGATE"
],
"cpu": "256",
"memory": "512"
}
- サービス作成
起動タイプでEC2を選択し、ロードバランサーでALBを指定します。
3-4. ECS タスク実行IAMロールの作成
IAMのページにて、画面左の[アクセス制御] > [ロール]よりロールの作成
をクリック
- 信頼されたエンティティタイプ:AWSのサービス
- ユースケース:
- サービスまたはユースケース:Elastic Container Service
- ユースケース:Elastic Container Service Task
- 許可ポリシー:AmazonECSTaskExecutionRolePolicy
ロール詳細で、ロール名に ecsTaskExecutionRole を入力し、ロールを作成
3-5. ECRにpush
1. ECRにpush用にtagを変更
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ sudo docker tag hello-world <aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/hello-repository
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
<aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/hello-repository latest 3580a22bf44e 39 minutes ago 205MB
hello-world latest 3580a22bf44e 39 minutes ago 205MB
2. aws ecr get-login-password コマンドを実行
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ aws ecr get-login-password --region ap-northeast-1 | sudo docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com
Login Succeeded
3. pushを実行
ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ sudo docker push <aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/hello-repository
Using default tag: latest
The push refers to repository [<aws_account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/hello-repository]
7e821cf0ddcb: Pushed
654c394d2294: Pushed
8e8c6a98d1e7: Pushed
548a79621a42: Pushed
latest: digest: sha256:9060dbc4c5acc0fbe94e089ad9e14fff7f1a4cbb5ce5068603afd97332d8eeb0 size: 1155
4. OCIコンソール上でもpushされたことを確認
3-6. 稼働確認
- 作成されたロードバランサーのDNS名を確認
- ブラウザにて、DNS名をいれ「Hello World!」が出力されることを確認
4.環境デプロイ@OCI
4-1. OKEの作成
- [開発者サービス] > [Kubernetesクラスタ(OKE)]をクリック
- [クラスタの作成]をクリック
- [クイック作成]を選択して送信をクリック
今回はOKEに必要なVCN等一緒に作成してくれるクイック作成を選択します。
逆に既存のVCN内でOKEを作成したい方はカスタム作成で大丈夫です。
- 名前:oke_cluster
- ノードタイプ:管理対象
- ノードシェイプ:VM.Standard.E5.Flex
※OCPUとメモリは検証の為デフォルトままですが、変更可能です。 - ノード数:1
※検証の為1台ですが、本番利用の場合は最小構成3ノードが推奨です。
- 基本的なクラスタを作成:チェックをいれる
- クラスタの作成を押す
- アクティブスステータスになったら、作成完了です。
4-2. OCIRにリポジトリの作成
- [開発者サービス] > [コンテナ・レジストリ]をクリック
- [リポジトリの作成]をクリック
- アクセス:パブリック
今回検証の為、パブリックにしてますが、プライベートの場合は以下のQiitaもご参考下さい。
- リポジトリ名:hello-repository/hello-world
4-3. OCIRにpush
1. OCIRへpushする用にtagを変更
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ sudo docker tag hello-world ap-seoul-1.ocir.io/orasejapan/hello-repository/hello-world
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ sudo docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
xxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/hello-repository latest 3580a22bf44e 19 hours ago 205MB
ap-seoul-1.ocir.io/orasejapan/hello-repository/hello-world latest 3580a22bf44e 19 hours ago 205MB
2. pushを実行
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ sudo docker image push ap-seoul-1.ocir.io/orasejapan/hello-repository/hello-world
Using default tag: latest
The push refers to repository [ap-seoul-1.ocir.io/orasejapan/hello-repository/hello-world]
7e821cf0ddcb: Pushed
654c394d2294: Pushed
8e8c6a98d1e7: Pushed
548a79621a42: Pushed
latest: digest: sha256:9060dbc4c5acc0fbe94e089ad9e14fff7f1a4cbb5ce5068603afd97332d8eeb0 size: 1155
3. OCIコンソール上でもpushされたことを確認
4-4. OKE上にデプロイ
- マニフェストの作成
Kubernetesのマニフェストとは、ECSのタスク定義のようなものです。
ECSではタスク定義を使って、どのコンテナイメージを使うか、CPUやメモリの割り当て、環境変数などを定義しますが、これに対してk8sのマニフェストはYAML形式のファイルで、同様にデプロイするコンテナやリソースを定義します。
imageの箇所だけ、皆さんの環境に合わせてに書き換えてく使ってください!!
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world-deployment
labels:
app: hello-world
spec:
replicas: 3 //コンテナが3つ立ち上がり冗長構成を組むという意味。
selector:
matchLabels:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: ap-seoul-1.ocir.io/orasejapan/hello-repository/hello-world:latest //皆さんの環境に合わせてpushしたイメージをしてしてください
ports:
- containerPort: 80
imagePullSecrets:
- name: ocisecret
hello-world-service.yaml
というマニフェストを作成します。
これでロードバランサーを定義してます。
apiVersion: v1
kind: Service
metadata:
name: hello-world-service
labels:
app: hello-world
annotations:
oci.oraclecloud.com/load-balancer-type: "lb"
service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "30"
spec:
type: LoadBalancer
selector:
app: hello-world
ports:
- port: 80
- namespaceの変更
クラスターを区画に分けて管理するための領域である、namespaceを作成します。
以下のコマンドで、namespace名は任意の文字列を指定できます。今回は”hello-world-demo”というnamespace名で作成します。
kubectl create namespace hello-world-demo
デフォルトのNamespaceを上記で作成したものに変更しておきます。これを行うと、以降、kubectlの実行の度にNamespaceを指定する必要がなくなります。
kubectl config set-context $(kubectl config current-context) --namespace=hello-world-demo
- Podをクラスター内に作成
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ kubectl apply -f hello-world.yaml
deployment.apps/hello-world-deployment created
- ロードバランサーをクラスター内に作成
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ kubectl apply -f hello-world-service.yaml
service/hello-world-service created
4-5. 稼働確認
作成されたロードバランサーのIPアドレスをkubectl getで確認します。
もちろんOCIコンソール上でもロードバランサーのIPアドレスは確認できます。
(oracle-cli) ubuntu@public-instance-tokunaga-ubuntu2:~/aws2oci$ kubectl get pod,service
NAME READY STATUS RESTARTS AGE
pod/hello-world-deployment-6777965556-jr7nr 1/1 Running 0 11m
pod/hello-world-deployment-6777965556-zhhx9 1/1 Running 0 78s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/hello-world-service LoadBalancer 10.96.79.59 217.142.145.58 80:32245/TCP 75m
ロードバランサーのEXTERNAL-IPをブラウザ上で叩くことで、OKE上でデプロイできることが確認できました。