Closed17

GitHub Actions self-hosted runnerとvclusterを使って、Kubernetesクラスタ上で隔離されたCI環境を構築する実験

zoetrozoetro

kindをセットアップ

$ kind create cluster

cert-managerをセットアップ

$ curl -fsL https://github.com/jetstack/cert-manager/releases/latest/download/cert-manager.yaml | kubectl apply -f -

actions-runner-controllerをセットアップ

$ kubectl apply -f https://github.com/actions-runner-controller/actions-runner-controller/releases/download/v0.20.3/actions-runner-controller.yaml
zoetrozoetro

認証はGitHub Appを使う方法とPATを使う方法があるらしい。
今回はPATを利用。repoのfull権限を付与する。

生成したPATでシークレットリソースを作成。

$ kubectl create secret generic controller-manager \
    -n actions-runner-system \
    --from-literal=github_token=${GITHUB_TOKEN}
zoetrozoetro

Runnerリソースを作成

apiVersion: actions.summerwind.dev/v1alpha1
kind: Runner
metadata:
  name: example-runner
  namespace: default
spec:
  repository: zoetrope/vcluster-runner-test
  env: []

runner podが動作していることを確認

$ kubectl get pod
NAME             READY   STATUS    RESTARTS   AGE
example-runner   2/2     Running   0          10m

GitHubのリポジトリを開いて、settings→actions→runnersをみるとexample-runnerが登録されていることが確認できる。

zoetrozoetro

GitHub ActionsのWorkflowを作成。
PRを作成してみると、Runner Podでチェックアウト処理が実行されました。

name: CI
on:
  pull_request:
  push:
    branches:
      - 'main'
jobs:
  test:
    name: test
    runs-on: [ self-hosted, linux ]
    steps:
      - name: Checkout
        uses: actions/checkout@v2

とりあえずこれで準備OK。

zoetrozoetro

Runnerの中でkubectlを叩きたいので、以下のようなRunnerのコンテナイメージを用意する。

FROM summerwind/actions-runner:latest

LABEL org.opencontainers.image.source https://github.com/zoetrope/vcluster-runner-test

RUN sudo curl -sfSL "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" -o /usr/local/bin/kubectl && \
    sudo chmod +x /usr/local/bin/kubectl

ghcr.ioに突っ込んでおく。

$ docker build -t ghcr.io/zoetrope/actions-runner:v0.1.0 .
$ docker push ghcr.io/zoetrope/actions-runner:v0.1.0
zoetrozoetro

vclusterで仮想クラスタを立てます。

$ vcluster --version
vcluster version 0.4.3
$ vcluster create test-cluster
zoetrozoetro

以前のスクラップを参考にしつつ
https://zenn.dev/zoetro/scraps/ab211300bae2db

values.yamlを用意する。

syncer:
  extraArgs:
  - --out-kube-config-server=https://test-cluster
  - --tls-san=test-cluster

仮想クラスタを作り直し

$ vcluster delete test-cluster
$ vcluster create test-cluster --extra-values=./values.yaml 

仮想clusterにアクセスするためのSecretリソースが生成されているので、それをRunnerから参照します。

apiVersion: actions.summerwind.dev/v1alpha1
kind: Runner
metadata:
  name: example-runner
  namespace: default
spec:
  repository: zoetrope/vcluster-runner-test
  image: ghcr.io/zoetrope/actions-runner:v0.1.0
  env: []
  volumeMounts:
  - mountPath: /etc/kubernetes
    name: kubeconfig
    readOnly: true
  volumes:
  - name: kubeconfig
    secret:
      defaultMode: 420
      secretName: vc-test-cluster

これで、Runner Podから仮想クラスタにアクセスできるはずです。

zoetrozoetro

ではこれを使って、CIから仮想クラスタ上にPodをデプロイしてみます。

適当なマニフェストを用意

apiVersion: v1
kind: Pod
metadata:
  name: sample
  namespace: default
spec:
  containers:
  - name: ubuntu
    image: ubuntu:20.04
    command: ["/usr/bin/sleep", "infinity"]

CIからkubectlを叩く処理を書いてみます。

name: CI
on:
  pull_request:
  push:
    branches:
      - 'main'
jobs:
  test:
    name: test
    runs-on: [ self-hosted, linux ]
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Deploy Pod
        run: |
          kubectl --kubeconfig=/etc/kubernetes/config apply -f ./pod.yaml
          kubectl --kubeconfig=/etc/kubernetes/config wait --for=condition=ready pod sample
zoetrozoetro

次は、仮想クラスタ上でArgo CDを入れてみます。

まずはRunner Podにargocdコマンドを追加。

FROM summerwind/actions-runner:latest

LABEL org.opencontainers.image.source https://github.com/zoetrope/vcluster-runner-test

RUN sudo curl -sfSL "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" -o /usr/local/bin/kubectl && \
    sudo chmod +x /usr/local/bin/kubectl && \
    sudo curl -sfSL https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64 -o /usr/local/bin/argocd && \
    sudo chmod +x /usr/local/bin/argocd
zoetrozoetro

次に仮想クラスタにArgo CDをデプロイ

$ kubectl exec -it example-runner bash

$ kubectl create namespace argocd
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
zoetrozoetro

そして、CIではこんな感じのテストを実行する。

name: CI
on:
  pull_request:
  push:
    branches:
      - 'main'
jobs:
  test:
    name: test
    runs-on: [ self-hosted, linux ]
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Deploy Application
        run: |
          ARGOCD_PASSWORD=$(kubectl get secrets -n argocd argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)
          argocd login argocd-server-x-argocd-x-test-cluster --insecure --username admin --password ${ARGOCD_PASSWORD}
          argocd app create test --repo https://github.com/zoetrope/vcluster-runner-test.git --path manifests --dest-namespace default --dest-server https://kubernetes.default.svc --directory-recurse
          argocd app sync test
zoetrozoetro

実用に向けての課題

  • テスト実行のたびにvclusterを作り直す仕組みが欲しい。
  • ホスト側のクラスタが提供している機能(カスタムリソース)を、仮想クラスタ内でも使いたい。
  • 仮想クラスタ上のPodから、ホストクラスタ上のサービスへのアクセスを制限するためのNetworkPolicyが必要。
このスクラップは2021/11/14にクローズされました