おうちでGitOps (GitLab + Kubernetes + Flux) - シリーズ投稿1/6
以前、おうちのラボでDockerを使ってサービスを
いろいろ走らせてみようという記事をシリーズで書きましたが、
今度はGitOps環境をおうちのラボに用意して遊ぼうという記事を書きます。
GitLab + Kubernetes + Fluxといった組み合わせです。
Previous Series on Docker: Dockerで作るおうちLAN遊び場 シリーズ1/7
出来上がるもの
今回のシリーズで最初に紹介したいのは次の3つです。
- Kubernetesクラスタ
- Kubernetesクラスタを操るGitレポジトリ
- そのGitレポジトリを読み取りKubernetesクラスタに変更を加えるGitOpsツールであるFlux
Kubernetes用の設定ファイルをGitレポジトリに上げると、そのファイル通りにFluxがKubernetesクラスタを更新します。つまり動かしたいものを書いてGitレポジトリにプッシュすると、あとは自動でそれがKubernetes上に実装されるようになります。
例えばJupyter Notebookを動かすmanifestファイルを書いてGitレポジトリにpushすれば、Jupyter NotebookがKubernetesクラスタ上に自動的に作られるようになります。
更にこのシリーズでは、走らせるサービスへのアクセスもDNSサーバやウェブサーバへの変更を通じて出来るようにする工夫も紹介します。簡単に言えば、Kubernetesクラスタ上で、クラスタ外からアクセスできるようになっているサービスの確認、そしてその名前やIPアドレスをDNSやリバースプロキシが処理できるよう設定を投げ込むといったことをするスクリプトを用意します。
ここまでできれば、マニフェストを書く、すると自動でKubernetesクラスタ上でサービスが立ち上がる、更にブラウザでアクセスする準備も勝手に整うということになります。
ToC
このシリーズの目次は次のとおりです。
- おうちでGitOps シリーズイントロ (本ポストでカバー)
- 最終的に何ができるのかの紹介
- GitLab + Nginx + Unbound DNS用意 (本ポストでカバー)
- 私はすでにこれらが揃っている環境でk8sクラスタ構築へと進んだのでまずはそこまで...
- Kubernetesクラスタ構築 (実際のクラスタ構築は次のポストで!)
- ラズパイやファンレスミニPCでの必要な事前設定あれこれ
- k8s v1.27.1 + containerd as CRI + flannel as network plugin
- Flux導入とMetalLB実装
- GitLabにGitOps用レポジトリ用意
- Fluxで対象レポジトリへbootstrap
- MetalLBのmanifestをレポジトリに配置してKubernetesクラスタへ実装
- Weave GitOps Dashboard導入
- 手動でDNSやRPを設定するという手間を経てLAN上の他の端末からもアクセスできるように
- おうちラボでKubernetesサービスへのウェブアクセス自動実装
- 前のポストで触れた手間を自動化
- Kubernetesでのcsi-driver-nfsを用いたNFS利用
本シリーズのお約束
-
Kubernetes
Cluster on 3 nodes (2 raspberry pi4 - arm64, and 1 amd64 fanless mini PC)-
flannel
for networking -
flux
as a GitOps tool - metallb for
LoadBalancer
service type implementation
-
- 1 or more machine running
Docker
- serving
GitLab
(Used for GitOps central repository) - serving
Nginx
(Reverse proxy to provide access to GitLab and other web services to be created on Kubernetes Cluster) - serving
Unbound
(DNS resolver for machines on LAN)
- serving
- public DNS domain + SSL/TLS certification (for example, Let's Encrypt) recommended
- they are all
mydomain.net
in the series - replace
mydomain.net
with your own DNS domain to follow through
- they are all
More on Docker - Series Top: Dockerで作るおうちLAN遊び場 シリーズ1/7
Interested in getting your own DNS domain?
GitLab, Nginx, and Unbound on Docker
まず私のおうちラボ環境には元々DockerコンテナとしてGitLab、Nginx、Unboundが稼働しています。Kubernetesクラスタを作って遊ぼうと思ったとき、設定はgitレポジトリに載せておきたい、Kubernetesクラスタ上で稼働させるサービスはUnboundとNginxを利用してアクセスできるようにしたいと考えていました。そういうわけで全てを繋げて先のような目次になったのですが、このポストの残りでこれら既存サービスのセットアップについて触れておきます。
基本的に別シリーズで紹介した通りのセットアップであり、一番異なる部分はパブリックで通用するドメインおよびlet's encrypt証明書を使用しているところです。
ドメインはシリーズ通してmydomain.net
としていきますが、ご自身でドメインと*.mydomain.net
のようなワイルドカード証明書を用意すればスムーズに進められると思います。
Unbound
まずDNSサービスですが、docker-compose.yml
と、DNSレコードを載せるファイルconfig/a-records.conf
を用意し、docker compose up -d
で走らせるだけとなります。
❯ tree
.
|-config
| |-a-records.conf
|-docker-compose.yml
# ❯ which tree
# tree: aliased to find . -not -path "*/\.git/*" -not -path "*/venv/*" | sed -e "s/[^-][^\/]*\// |/g" -e "s/|\([^ ]\)/|-\1/"
docker-compose.yml
まずはdocker-compose.yml
です。イメージはmvance/unbound
を利用させて頂きます。Docker hubでタグ・バージョンを確認して好きなものを利用しましょう。
version: '3'
services:
unbound:
image: mvance/unbound:1.16.2
restart: unless-stopped
container_name: landns
hostname: 'landns'
ports:
- '53:53/udp'
- '53:53'
volumes:
- './config/a-records.conf:/opt/unbound/etc/unbound/a-records.conf:ro'
unbound config files
Unbound用の設定ファイルですが、a-records.conf
には好きなレコードを書いておけばこのコンテナがその通りに名前解決してくれます。ここではgitlab.mydomain.net.
を追加していますが、IPアドレスはNginx、リバースプロキシサーバのコンテナを走らせるノードのIPアドレスとしておきましょう。
例えば192.168.1.55のノードでUnboundとNginxを走らせ、192.168.1.56でGitLabを走らせる場合、gitlab.mydomain.net.
というGitLabへのアクセスリクエストはまずリバースプロキシに到達してほしいので以下のようになります。
local-data: "gitlab.mydomain.net. IN A 192.168.1.55"
Nginx
次にNginxです。こちらも私の本当の環境では、別シリーズで紹介した通りAutheliaという2FAサービスを載せたりしてかなりの行数のリストになってしまうのですが、必要最低限をここでは紹介したいと思います。
httpsアクセスを処理するリバースプロキシサーバを用意するのですが、ブラウザでアクセスするときに何も問題が出ないよう、すべてパブリックで通用するドメインおよびTLS証明書でやってほしいです。
ではまずはファイルのリストが次の通りです。
❯ tree
.
|-docker-compose.yml
|-conf
| |-nginx
| | |-gitlab.conf
| |-cert
| | |-fullchain.pem
| | |-privkey.pem
| | |-ssl-base.conf
| | |-ssl-dhparams.pem
| | |-ssl-wild.conf
| |-nginx.conf
docker-compose.yml
docker-compose.yml
ファイルはこんな感じです。
services:
nginx:
image: nginx:1.24.0
container_name: nginx
ports:
- "443:443"
volumes:
- ./conf/nginx/:/etc/nginx/conf.d
- type: bind
source: ./conf/cert
target: /etc/nginx/cert
read_only: true
- type: bind
source: ./conf/nginx.conf
target: /etc/nginx/nginx.conf
read_only: true
nginx config files
conf/nginx/*.conf
ファイルとしてリバースプロキシ処理させる名前、パス、プロキシとして通信を流す先を設定したファイルを配置し、その時利用するTLS関連の設定や証明書などはconf/cert
に入れておきます。そしてNginxの基本設定ファイルとしてconf/nginx.conf
も用意しておきます。
順番に設定ファイルなども紹介していきます。
nginx gitlab.conf
最初はconf/nginx/gitlab.conf
です。
サーバ名はgitlab.mydomain.net
で443ポートで受け付けるようにしてあります。
更にTLS関連の設定としては別ファイルであるconf/cert/ssl-base.conf
とconf/cert/ssl-wild.conf
を読み込むようにしてあります。
プロキシ先はGitLabサービスを立ち上げるノードのIPアドレスなりDNSなりで指定するのですが、ここでは192.168.1.56としています。
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl http2;
server_name gitlab.mydomain.net;
# docker resolver
resolver 127.0.0.11 valid=30s;
# upload size
client_max_body_size 10000M;
# ssl
include /etc/nginx/cert/ssl-base.conf;
include /etc/nginx/cert/ssl-wild.conf;
location / {
proxy_http_version 1.1;
set $upstream_gitlab 192.168.1.56:80;
proxy_pass http://$upstream_gitlab;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
nginx tls files
TLS関連設定を別ファイルとして設けているconf/cert/ssl-base.conf
とconf/cert/ssl-wild.conf
についてです。
1つ目のssl-base.conf
ではプロトコル、サイファー、使用するDHパラメータキーファイルなどを記載しています。DHパラメータ自体はopenssl dhparam -out ssh-dhparams.pem 4096
といったコマンドで生成すればよいかと思います。
# dhparam
ssl_dhparam /etc/nginx/cert/ssl-dhparams.pem;
# options
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
2つ目のssl-wild.conf
では単純に使用する証明書とキーを指定しています。ワイルドカードでやっていくつもりなのでいっそ2つのファイルを一つにまとめても良いかもしれません。証明書とキーは自身のドメインのワイルドカード証明書として用意しておきましょう。
# cert/key for *.mydomain.net
ssl_certificate /etc/nginx/cert/fullchain.pem;
ssl_certificate_key /etc/nginx/cert/privkey.pem;
最後にconf/nginx.conf
という一般設定ファルですが、私は次のようにしています。Elastic Searchで遊んだときの名残で吐き出すログの種類だけ少し足されているデフォルト設定だったかと思います。つまり変更する設定はないということですが、シリーズの後の方で変更を加える予定がありますので、最初からこういう構成で用意しておきましょう。
後々の変更でデフォルト設定だとサーバ名の文字数に関連してエラーを吐いて起動しなくなる可能性が出てきます。server_names_hash_bucket_size
設定を追加しておきましょう。
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_connect_time $upstream_header_time $upstream_response_time $server_name';
access_log /var/log/nginx/access.log main;
server_names_hash_bucket_size 128;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
すべて準備ができたらdocker compose up -d
で立ち上げておきましょう。
GitLab
そしてGitLabの準備です。別途設定ファイルと用意する必要がないのでシンプルです。
docker-compose.yml
以下のようなdocker-compose.yml
ファイルで、イメージのバージョン・タグ、ホスト名やexternal_url
などを適当な名前に変えたら、docker compose up -d
で立ち上げて完成です。
80番ポートでプレインなhttpでアクセスできるようセットアップし、実際のユーザアクセスはリバースプロキシへのhttps、そしてプロキシとGitLabサーバ間はhttpといったことになります。
services:
gitlab:
image: 'gitlab/gitlab-ee:15.10.2-ee.0'
restart: always
hostname: 'gitlab.mydomain.net'
container_name: k8s-gitlab
privileged: true
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://gitlab.mydomain.net'
ports:
- '80:80'
volumes:
- type: volume
source: v_config
target: /etc/gitlab
- type: volume
source: v_data
target: /var/opt/gitlab
- type: volume
source: v_logs
target: /var/log/gitlab
volumes:
v_data: {}
v_logs: {}
v_config: {}
完成!!
後はLAN上の普段遣いのスマホなりラップトップなりでDNS設定をDocker上で動かしているUnbound DNSを使うよう設定し、ブラウザでhttps://gitlab.mydomain.net
へアクセスできます。
次回 - Kubernetesクラスタのセットアップ
このシリーズの次のポストでは、Raspberry Pi 4やファンレスミニPCでKubernetesクラスタを構築します。
Discussion