ローカル環境でPipeCDのpipedをコンテナ下で動かしてみた
はじめに
本記事ではローカル環境でpiped(PipeCDのエージェント)をコンテナ下で動作させる方法について説明します。
デバッグなどでローカル環境でもpipedコンテナを動かしたい!という方がいらしたら参考になれば幸いです。
※ PipeCDで対応している、Kubernetes、AWS ECS、Lambda、Cloud Runについてローカルで動かすことができます。
Terraformは別途対応したら追記予定です。
作業全体像
pipedを動かすには主に3種類の情報が必要です。
- Control Planeへの接続情報: pipedがPipeCDのControl Planeと通信するための認証情報
- Gitリポジトリへの接続情報: マニフェストファイルが格納されているGitリポジトリへのアクセス情報
- デプロイ対象のPlatformへの接続情報: 実際にデプロイを行うプラットフォーム(Kubernetes、Cloud Run、ECS等)への認証情報
上記に加えてpiped.yamlというpipedの設定ファイルをコンテナにマウントすることで起動することができます。
本記事ではこれらの接続情報を作成し、dockerコンテナにアタッチしつつpipedを動かすことを目指します。
作業ディレクトリについて
本記事では、必要な情報を一つのディレクトリにまとめる形で進めます。事前に作業用のディレクトリを用意してください。
作成したディレクトリ(your-piped-directory)をコンテナ内の/etc/pipecd-devにマウントします。
これにより、以下のような構造になる想定です。
-
ホスト側:
/path/to/your-piped-directory/ -
コンテナ内:
/etc/pipecd-dev/
このため、piped.yamlファイル内のパスは、コンテナ内のパス(/etc/pipecd-dev/)を基準に記述します。
作業完了後、以下のようなディレクトリ構成になる想定です。
your-piped-directory/
├── piped.yaml # pipedのメイン設定ファイル
└── creds/
├── controlplane/
│ └── piped-key # Control Planeの認証キー
├── git/
│ ├── your-ssh-key # Git用のSSH秘密鍵
│ └── your-ssh-key.pub # Git用のSSH公開鍵
└── platform/
├── kubernetes/
│ └── kubeconfig # Kubernetes用の設定ファイル
├── googlecloud/
│ └── application_default_credentials.json # Google Cloud用の認証情報
└── aws/
├── credentials-lambda # AWS用の認証情報
└── credentials-ecs
0. 事前準備
作業ディレクトリの作成
あらかじめ必要なディレクトリを作っておきましょう。
mkdir your-piped-directory
mkdir -p your-piped-directory/creds/{controlplane,git,platform/{kubernetes,googlecloud,aws}}
touch your-piped-directory/piped.yaml
Control Planeの起動
本記事では、PipeCDのチュートリアルリポジトリのdocker-compose.yamlを使用してControl Planeを起動することを前提としています。
git clone https://github.com/pipe-cd/tutorial.git
cd tutorial/src/install/control-plane
docker-compose up -d
ブラウザで http://localhost:8080 にアクセスし、Control Planeが正常に起動していることを確認してください。
1. Control Planeへの接続情報の準備
1-1. Control Planeから情報を取得
起動したPipeCDのControl PlaneのWeb UI(http://localhost:8080)にアクセスし、新しいpipedを追加します。
この際に表示される以下の情報を控えておきましょう。
- piped ID: pipedの一意識別子
- piped key: Control Planeとの認証に使用するキー
1-2. 認証情報ファイルの作成
piped keyをファイルとして保存します。
echo YOUR_PIPED_KEY > creds/controlplane/piped-key
1-3. piped.yamlの基本設定
取得した情報をpiped.yamlファイルに設定します
apiVersion: pipecd.dev/v1beta1
kind: Piped
spec:
projectID: tutorial # tutorialのControl Planeですでに存在するProjectを利用しています
apiAddress: "host.docker.internal:9080"
pipedID: YOUR_PIPED_ID # FIXME
pipedKeyFile: /etc/pipecd-dev/creds/controlplane/piped-key
※ apiAddressについて
ホストマシンのローカルホスト上で動くControl Planeに接続するために、host.docker.internal を利用しています。
localhostを指定すると、pipedコンテナのローカルホストにアクセスしてしまうためです。
2. Gitリポジトリへの接続設定
SSHキーの生成
SSH経由でGitリポジトリにアクセスするため、SSHキーペアを作成します(ファイル名は任意です)
ssh-keygen -t ed25519 -f ./creds/git/your-ssh-key
GitHubでの設定
- GitHubのリポジトリページにアクセス
- Settings > Deploy keys に移動
- 生成した公開鍵(
your-ssh-key.pub)を登録
piped.yamlの更新
GitのSSHキーファイルのパスとリポジトリ情報を設定します
apiVersion: pipecd.dev/v1beta1
kind: Piped
spec:
projectID: tutorial
apiAddress: "host.docker.internal:9080"
pipedID: YOUR_PIPED_ID # FIXME
pipedKeyFile: /etc/pipecd-dev/creds/controlplane/piped-key
git:
sshKeyFile: /etc/pipecd-dev/creds/git/your-ssh-key # FIXME
repositories:
- repoId: ffjlabo-dev
remote: git@github.com:org/repo.git # FIXME
branch: main
3. デプロイ対象のPlatformへの接続情報
pipedでは、platformProvider と呼ばれるフィールド配下に、デプロイ対象のPlatformに接続するための情報を設定します。
これらはPlatformによって異なります。
以降では、使用するPlatformに応じて、以下のいずれかのセクションを参照してください。
apiVersion: pipecd.dev/v1beta1
kind: Piped
spec:
projectID: tutorial
apiAddress: "host.docker.internal:9080"
pipedID: YOUR_PIPED_ID # FIXME
pipedKeyFile: /etc/pipecd-dev/creds/controlplane/piped-key
git:
sshKeyFile: /etc/pipecd-dev/creds/git/your-ssh-key # FIXME
repositories:
- repoId: ffjlabo-dev
remote: git@github.com:org/repo.git # FIXME
branch: main
platformProviders: # ←
...
Kubernetes
今回はローカル環境にkindクラスタを立てた場合を想定しています。
1. kubectl proxyを起動
kubectl proxy --port 8081 --accept-hosts "^host.docker.internal$"
2. kindクラスタのkubeconfigをエクスポート
kind export kubeconfig --name your-cluster-name --kubeconfig ./creds/platform/kubernetes/kubeconfig
3. kubeconfigファイルを編集して、clusters[].cluster.serverのホスト名をhttp://host.docker.internal:8081に変更
exportしたkubeconfigは、api serverのホストが127.0.0.1になります。
pipedのコンテナ内でこのエンドポイントにアクセスすると、自身のコンテナのローカルアドレスを指すため、通常はkindクラスタに疎通できません。
そのため、ホストマシンのローカルアドレスにアクセスできる host.docker.internal を利用します。
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ...
server: http://host.docker.internal:8081
name: kind-pipecd
4. piped.yamlに設定を追加
platformProviders:
...
- name: kubernetes-dev
type: KUBERNETES
config:
masterURL: http://host.docker.internal:8081
kubeConfigPath: /etc/pipecd-dev/creds/platform/kubernetes/kubeconfig
kubectlVersion: 1.33.0
Cloud Run
1. サービスアカウントを作成し、roles/run.developerロールを付与
2. サービスアカウントの認証情報をダウンロード
gcloud auth application-default login --impersonate-service-account [サービスアカウントのメールアドレス]
3. 認証情報ファイルをコピー
cp /path/to/application_default_credentials.json ./creds/platform/googlecloud/
4. piped.yamlに設定を追加
platformProviders:
...
- name: cloudrun-dev
type: CLOUDRUN
config:
project: pipecd
region: asia-northeast1
credentialsFile: /etc/pipecd-dev/creds/platform/googlecloud/application_default_credentials.json
ECS
1. AWS IAMロールを作成(PipeCDのドキュメントを参考)
2. Assume Roleを実行
aws sts assume-role --role-arn arn:aws:iam::xxxx:role/ffjlabo-dev-piped --profile xxx --region ap-northeast-1 --role-session-name ffjlabo-dev-piped
3. 認証情報ファイルを作成
# 認証情報ファイルを作成
cat > ./creds/platform/aws/credentials-ecs << EOF
[dev]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
aws_session_token = YOUR_SESSION_TOKEN
EOF
4. piped.yamlに設定を追加
platformProviders:
...
- name: ecs-dev
type: ECS
config:
region: ap-northeast-1
profile: dev
credentialsFile: /etc/pipecd-dev/creds/platform/aws/credentials-ecs
Lambda
ECSと同様の手順で、Lambda用のIAMロールと認証情報を設定します。
1. AWS IAMロールを作成(PipeCDのドキュメントを参考)
2. Assume Roleを実行
aws sts assume-role --role-arn arn:aws:iam::xxxx:role/ffjlabo-dev-piped --profile xxx --region ap-northeast-1 --role-session-name ffjlabo-dev-piped
3. 認証情報ファイルを作成
# 認証情報ファイルを作成
cat > ./creds/platform/aws/credentials-lambda << EOF
[dev]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
aws_session_token = YOUR_SESSION_TOKEN
EOF
4. piped.yamlに設定を追加
platformProviders:
...
- name: lambda-dev
type: LAMBDA
config:
region: ap-northeast-1
profile: dev
credentialsFile: /etc/pipecd-dev/creds/platform/aws/credentials-lambda
4. pipedの起動
すべての設定が完了したら、pipedをコンテナ下で起動します。
以下のコマンドを実行してください。
docker run --rm -it \
-v /path/to/your-piped-directory:/etc/pipecd-dev \
ghcr.io/pipe-cd/piped:v0.52.1 \
piped --tools-dir=/tmp/piped-bin --config-file=/etc/pipecd-dev/piped.yaml --insecure=true
以下のようにpipedが終了せずに動いていれば問題ないです。
successfully configured ssh-config
successfully loaded the pre-installed tools {"tools": {}}
all 0 notifiers have been started
all 0 notifiers have been stopped
start running application store
start running deployment store
admin server is running on 9085
start running stats reporter
start running command store
start running event store
start running appsatestore
start running ecs app state store {"platform-provider": "ecs-dev"}
start running cloudrun app state store {"platform-provider": "cloudrun-dev"}
start running kubernetes app state store {"platform-provider": "kubernetes-dev"}
start running lambda app state store {"platform-provider": "lambda-dev"}
start running piped stop checker
starting app live state reporter for cloud provider: kubernetes-dev
start running app live state reporter {"platform-provider": "kubernetes-dev"}
waiting for livestatestore to be ready {"platform-provider": "kubernetes-dev"}
starting drift detector for cloud provider: kubernetes-dev
start running drift detector for kubernetes applications {"platform-provider": "kubernetes-dev"}
start running controller
workspace directory was configured to /tmp/workspace2989639729
start syncing planners and schedulers
start running deployment trigger
cloning ffjlabo-dev for the first time {"repo-id": "ffjlabo-dev", "remote": "git@github.com:ffjlabo/pipecd-manifests-v0.git", "repo-cache-path": "/tmp/gitcache1378603830/ffjlabo-dev"}
start running app-config-reporter
start running event watcher
start running planpreview handler
spawn 3 worker to handle commands
started a worker for handling plan-preview command
started a worker for handling plan-preview command
started a worker for handling plan-preview command
start running log persister
successfully preferred resources that contains for 0 groups {"platform-provider": "kubernetes-dev"}
filtered target resources {"platform-provider": "kubernetes-dev", "targetResources": [], "namespacedTargetResources": []}
start running 0 namespaced-resource informers {"platform-provider": "kubernetes-dev"}
start running 0 non-namespaced-resource informers {"platform-provider": "kubernetes-dev"}
all informer caches have been synced {"platform-provider": "kubernetes-dev"}
the reflector has done the first sync {"platform-provider": "kubernetes-dev"}
the store has done the initializing {"platform-provider": "kubernetes-dev"}
successfully the first synced all cloudrun services {"platform-provider": "cloudrun-dev"}
cloning a repo from cached one in local {"repo-id": "ffjlabo-dev", "remote": "git@github.com:ffjlabo/pipecd-manifests-v0.git", "repo-cache-path": "/tmp/gitcache1378603830/ffjlabo-dev", "src": "/tmp/gitcache1378603830/ffjlabo-dev", "dst": "/tmp/git430909190"}
setting gc.autoDetach {"repo-id": "ffjlabo-dev", "remote": "git@github.com:ffjlabo/pipecd-manifests-v0.git", "repo-cache-path": "/tmp/gitcache1378603830/ffjlabo-dev", "gc.autoDetach": false}
cloning a repo from cached one in local {"repo-id": "ffjlabo-dev", "remote": "git@github.com:ffjlabo/pipecd-manifests-v0.git", "repo-cache-path": "/tmp/gitcache1378603830/ffjlabo-dev", "src": "/tmp/gitcache1378603830/ffjlabo-dev", "dst": "/tmp/git4040909854"}
setting gc.autoDetach {"repo-id": "ffjlabo-dev", "remote": "git@github.com:ffjlabo/pipecd-manifests-v0.git", "repo-cache-path": "/tmp/gitcache1378603830/ffjlabo-dev", "gc.autoDetach": false}
cloning a repo from cached one in local {"repo-id": "ffjlabo-dev", "remote": "git@github.com:ffjlabo/pipecd-manifests-v0.git", "repo-cache-path": "/tmp/gitcache1378603830/ffjlabo-dev", "src": "/tmp/gitcache1378603830/ffjlabo-dev", "dst": "/tmp/event-watcher372884644/ffjlabo-dev2769298911"}
setting gc.autoDetach {"repo-id": "ffjlabo-dev", "remote": "git@github.com:ffjlabo/pipecd-manifests-v0.git", "repo-cache-path": "/tmp/gitcache1378603830/ffjlabo-dev", "gc.autoDetach": false}
start watching events {"repo": "ffjlabo-dev"}
successfully ran the first sync of all lambda resources {"platform-provider": "lambda-dev"}
successfully ran the first sync of all ecs resources {"platform-provider": "ecs-dev"}
found out 0 valid registered applications that config has been changed in repository "ffjlabo-dev"
found out 4 valid unregistered applications in repository "ffjlabo-dev"
starting drift detector for cloud provider: cloudrun-dev
starting app live state reporter for cloud provider: cloudrun-dev
start running app live state reporter {"platform-provider": "cloudrun-dev"}
waiting for livestatestore to be ready {"platform-provider": "cloudrun-dev"}
start running drift detector for cloudrun applications {"platform-provider": "cloudrun-dev"}
successfully synced all cloudrun services {"platform-provider": "cloudrun-dev"}
successfully synced all lambda resources {"platform-provider": "lambda-dev"}
successfully synced all ecs resources {"platform-provider": "ecs-dev"}
まとめ
この手順に従うことで、ローカル環境でpipedをコンテナ下で動作させることができます。
少し長くなってしまいました。ここまで読んでいただきありがとうございました。
Discussion