毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。
0. はじめに
0-1. GitLab Agent for Kubernetes(GitLab Kubernetes Agent改め)ってなに?
簡単に言うとGitLabとKubernetesを連携させる方法です。
0-2. 何で連携させるの?
GitLab CI/CDの時にKubernetesクラスターを取り扱うために連携させます。
CI/CDのジョブ内でkubectlを実行すると連携されたKubernetesクラスターにkubectlの実行を反映させることができます。
0-3. 今までもできたよね?
はい、いままでもできました。
下記記事参照:
GitLab Kubernetes接続(オンプレ) - Qiita
しかし、kubeconfigファイルをGitLabサーバー側に保存する必要があり、それがセキュリティーリスクとなっていました。また、GitLabサーバー側からKubernetesクラスターへ接続する必要があり、KubernetesクラスターにグローバルIPが必要でインターネットに出ている必要がありました。
注: GitLab RunnerとKubernetesクラスターが同じプライベートネットワークにある場合は、インターネットに出ている必要はありません。しかし、GitLabサーバーにkubeconfigが必要なのは同じです。
0-4. どうなった?
GitLabへ接続するエージェントが開発されて、Kubernetesクラスターへインストールする方式に変わりました。
GitLab Runnerと同じ方法です。GitLabサーバーとagentkはWebSocketで接続します。
これならば、
- Kubernetesクラスターがインターネットに出ている必要はなく、グローバルIPも不要です。
- kubeconfigをGitLabサーバー側に保存する必要がなくkubectlを実行する為のkubeconfigを変数に保存する必要がありません。
- これによりセキュリティーリスクが下がります。
というメリットがあります。
GitLabRunnerとKubernetesクラスターが別々の場所にあっても問題ありません。
GitLabサーバーにだけ接続できるようにしておけば大丈夫です。
例えば、以下のような構成も可能です。
1. やってみる
1-1. GitLabプロジェクトを作成
普通にプロジェクトを作成するので割愛します。
CI/CDを有効にしてください。
GitLab Runnerはどこにあっても問題ありません。
1-2. GitLabプロジェクトのGitリポジトリにファイルを作成
GitLab Agent for Kubernetesのエージェント用のファイルを作ります。
作るファイル名は、config.yaml
ですが、ファイルを作るパスに特徴があります。
.gitlab/agents/
ディレクトリを作り、その下にGitLab Agentの名前
のディレクトリを作り、
その下にconfig.yamlファイルを作ります。config.yamlの中身は空で構いません。
GitLab Agentの名前
は何でもOKです。aaa-bbb-ccc
とか好きな名前を付けましょう。
.gitlab/agents/<GitLab Agentの名前>/config.yaml
この時のGitLab Agent
の名前はDNS label standard from RFC 1123に準拠してください。
- プロジェクトでユニークであること。
- 最大63文字まで。
- 小文字の英数字または-のみを使用。
- 英数字で始めます。
- 英数字で終了します。
1-3. GitLab Agentをプロジェクトから登録します。
「GitLabメニュー」>「インフラ」>「Kubernetes Clusters」を開いて、「Connect a cluster」をクリックします。
「Select an agent....」をクリックすると1-2で作ったディレクトリのGitLab Agentの名前
が表示されるので選択して「Register」をクリックします。
以下のような画面が表示されるので、helm
のコマンドをコピっておきましょう。
2. Kubernetesクラスターを立てる
インターネットに出ていける環境で仮想マシンを動かしてシングルのK3Sをインストールしましょう。
2-1. 仮想マシンの用意
簡単にmultipassで用意します。
multipass launch 20.04 --name test.gitlabagentk
test.gitlabagentkにログインします。
multipass shell test.gitlabagentk
2-2. k3supを使ってK3Sをインストール
シングルサーバーなので、k3supをダウンロードして、K3Sをインストールします。
詳細はこちらを参考にしてください。
k3supを使ってk3sをインストールする - Qiita
https://qiita.com/ynott/items/25df249040ceb7430c3f
curl -sLS https://get.k3sup.dev | sh
sudo install k3sup /usr/local/bin/
K3Sをインストールします。
k3sup install --local --k3s-extra-args="--write-kubeconfig-mode 644"
K3Sの挙動を確認します。
export KUBECONFIG=./kubeconfig
kubectl config set-context default
kubectl get node -o wide
2-3. helmコマンドをインストール
helmコマンドもインストールしておきます。
sudo snap install helm --classic
helm 3.7.0 from Snapcrafters installed
3. GitLab Agent for Kubernetesをインストール
3-1. GitLab Agentを helmでインストール
1.3で出てきたhelmコマンドのコピーを貼り付けます。
helm repo add gitlab https://charts.gitlab.io
helm repo update
helm upgrade --install teXXXXXXXXXXXXXXXXXXXXXXXXer gitlab/gitlab-agent \
--namespace gitlab-agent \
--create-namespace \
--set image.tag=v15.1.0 \
--set config.token=AyamK7XXXXXXXXXXXXXXXXXXXXXPg \
--set config.kasAddress=wss://kas.gitlab.com
3-2. GitLab UIを確認
「GitLabメニュー」>「インフラ」>「Kubernetes Clusters」に接続したGitLab Agentが表示されます。
3-3. kubectlでgitlab-agentの実行状態を確認
以下のコマンドでgitlab-agentが実行されているか確認します。
kubectl get all -n gitlab-agent
問題なさそうです。
4. Kubernetesをテストしてみる
.gitlab-ci.yamlのジョブからKubernetesクラスターへ接続できるか試してみます。
4-1. .gitlab-ci.ymlファイルを作成
以下のような内容で.gitlab-ci.ymlファイルをGitリポジトリ直下に作成します。
重要なポイントは、kubectl config use-context
です。
kubeconfig内のcontextsを指定しますが、このkubeconfigはKubernetesクラスターを作ったときに出てくるkubeconfigではなくて、GitLab Agent用にCI/CDジョブ実行時に自動的に生成されるものです。
<グループ名>/<プロジェクト名>:<GitLab Agent名>
の指定方法が分からない場合は、kubectl config get-contexts
で出てきたName部分を指定すれば問題ありません。kubectl config use-contextがないと動きませんでした(defaultじゃないので)
deploy:
stage: deploy
image:
name: bitnami/kubectl:latest
entrypoint: ['']
script:
- kubectl config get-contexts
- kubectl config use-context <グループ名>/<プロジェクト名>:<GitLab Agent名>
- kubectl get pods -A
4-2. ジョブ実行状態を確認
5. なぜこんなことができるの?
ジョブ実行時にkubeconfigが自動的に生成されて、Runnerのジョブ上で読み取れるようになるからkubectlを実行してKubernetesクラスターを操作できるのですが、RunnerはKubernetesクラスターの場所を知らないのにkubectlが実行できるのは不思議です。
5-1. kubeconfigを見てみる
先ほどの.gitlab-ci.ymlファイルに以下を1行追加してみます。
- kubectl config view --raw
以下のようになります。
deploy:
stage: deploy
image:
name: bitnami/kubectl:latest
entrypoint: ['']
script:
- kubectl config get-contexts
- kubectl config use-context <グループ名>/<プロジェクト名>:<GitLab Agent名>
- kubectl get pods -A
- kubectl config view --raw
追加で出力された結果
clusters.cluster.serverは通常KubernetesクラスターのAPI接続Endpointですが、gitlabサーバーを指しています。
GitLabサーバーがProxyになっていて、Kubernetesクラスターへ接続しています。
以下の図は、Ultimate GitOps: Deploy Secure Microservices to AWS EKS with the GitLab Agent :: GitLab for EKSからの引用ですが、一番左の緑のRunnerの枠から真ん中のオレンジのGitLabを経由して右側の水色のKubernetesクラスターへ接続しているのが分かります。
GitLab Agent Connections and Flows より引用
GitLab CI/CD内のジョブがRunnerで実行されているときに自動的にkubeconfigが設定されて、接続先はGitLabのKASです。
KASはGitLab AgentをインストールしたKubernetesクラスターへトンネリングを提供して、kubectlコマンドを実行してくれます。
7. どう使う?
ジョブ内でkubectlを実行できるので、KubernetesのマニフェストファイルをGitリポジトリ内に置いておいて、kubectl apply -f ./manifest.yamlすればいいでしょう。
deploy:
stage: deploy
image:
name: bitnami/kubectl:latest
entrypoint: ['']
script:
- kubectl config use-context <グループ名>/<プロジェクト名>:<GitLab Agent名>
- kubectl apply -f ./manifest.yaml
imageにkustomizeを入れたり、helmを入れれば同様にKubernetesクラスターに適用できます。
6. まとめ
- GitLab Agent for Kubernetesは、Kubernetesクラスターへ安全に接続するための方法です。
- GitLab Runnerから安全にKubernetesクラスターへ接続することができます。
7. 参考資料
Installing the agent for Kubernetes | GitLab
https://docs.gitlab.com/ee/user/clusters/agent/install/index.html
Ultimate GitOps: Deploy Secure Microservices to AWS EKS with the GitLab Agent :: GitLab for EKS
https://gitlab-for-eks.awsworkshop.io/
How to use ‘GitLab Kubernetes Agent Working Examples for Training and Demos’ 2022-06-01
https://youtu.be/RGs65Zi-Tno