目的
– Djangoのテスト用アプリを構築する
– DjangoアプリをGitlabリポジトリへpushすると、ArgoCDがGitlabと同期して、microk8sにDjangoアプリをデプロイする
環境
– ubuntu 22.04
– MicroK8s v1.27.8 revision 6239
– Python 3.9
– Django 3.2.12
– ArgoCD v2.10.1
参考
ArgoCD構築
– https://murci.net/archives/4876
Microk8sでDjangoアプリをデプロイ
– https://murci.net/archives/5782
ArgoCDとGitlab連携
– https://qiita.com/ohtsuka-shota/items/8ba212cf5007ffebafb4
イメージ図
事前準備
- GitlabにArgoCDマニフェスト用のProjectを作成する
- ArgoCDをmicrok8sに構築
- テスト用のDjangoアプリを作成する
- テスト用のDjangoアプリをDockerで構築する
- テスト用のDjangoアプリのDockerイメージをmicrok8sのregistryにPushする
GitlabにArgoCDマニフェスト用のProjectを作成する
– Gitlabログイン -> Projectを開き、「New project」 -> 「Create blank project」
– Project name:myapp-3
– Project URL(Groups):manifest
– Create projectで作成する
– 事前にローカル端末に作成したProjectをpushする
$ pwd
/home/admin/myapp_3
$ git init
$ git remote add origin http://192.168.9.5:2080/manifest/myapp-3.git
$ git add .
$ git commit -m "initial comiit"
$ git push -u origin master
– GUIでmanifest用のディレクトリを作成する
– 「+」ボタン -> 「New directory」-> 「dev」
$ git pull origin master
ArgoCDをmicrok8sに構築
– 下記の手順に則る
– https://murci.net/archives/4876
– argoCDのGUIコンソールにログインできること
– アプリケーションの設定/Gitlabへのアクセス設定の登録は下記手順に則る
– Gitlabでユーザアクセストークンを発行
– 事前にGitlabでユーザアクセストークンを発行しておく
– Gitlabログイン -> プロジェクトページ -> 左ペインのSettings -> AccessTokens
– ArgoCDのGUIコンソール「Settings」からGitlabリポジトリを登録
– Type:git
– project:myapp-3
– Repository URL:http://192.168.9.5:2080/manifest/myapp-3.git ※ suffix「.git」まで付けないとエラー
– Username:argocd
– Password:gitlabのprojectで作成したAccessTokenを指定
– CONNECTを押すと同期が始まる。Successfulとなること
テスト用のDjangoアプリをDockerで構築し、Dockerイメージをmicrok8sのregistryにPushする
– 下記の手順に則る
– https://murci.net/archives/5782
プロジェクトフォルダ構成
– プロジェクトルート配下のdevディレクトリ内にmanifestを配置する
$ pwd
/home/admin
$ tree myapp_3
myapp_3
├── dev
│ ├── Application.yaml
│ ├── deployment.yaml
├── Dockerfile
├── manage.py
├── myapp_3
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── requirements.txt
ArgoCD用マニフェスト作成
– 下記のArgoCD用マニフェストを作成する
マニフェスト概要
– クライアントからNordPortを介して、Djangoアプリが稼働するPodへアクセスする
– 作成が必要なマニフェストは、それぞれApplication、deployment、serviceの3つ。deploymentとserviceは1つのyamlにまとめる
マニフェストの中身について
– namespaceは全て共通の「argocd」を使用(namespaceを分けると、Pod内のDjangoコンテナから、ClusterIPへ疎通できずに、外部からアクセスできなかったりする)
– Djangoアプリ名は「myapp-3」。dockerイメージ名のみ「myapp_3」を使用
Application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: argo-application ### Application名
namespace: argocd
spec: ### ここからPodの定義
project: default
source: ### デプロイの元となるソースコードはGitlabリポジトリを指定
repoURL: http://192.168.9.5:2080/manifest/myapp-3.git
targetRevision: HEAD
path: dev
destination: ### デプロイ先にkube-apiserverを指定
server: 'https://kubernetes.default.svc' ### namespace「default」にあるservice「kubernetes」。つまりControl Planeのkube-apiserverのこと。myapp-3のことでは無いので注意
namespace: argocd
syncPolicy: ### Gitlabリポジトリ同期ポリシー
syncOptions:
- CreateNamespace=true
automated:
selfHeal: true
prune: true
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-3-deployment
namespace: argocd
spec:
replicas: 1
selector:
matchLabels:
app: myapp-3
template:
metadata: ### label名はServiceのselector名と一致させる。一致しないとエラー「selector does not match template labels」発生
labels:
app: myapp-3
spec:
containers:
- name: myapp-3
image: localhost:32000/myapp_3 ### imageは事前準備でmicrok8sのregistryにPushしたimageを使用
ports:
- containerPort: 8000 ### コンテナのPort。ServiceのtargetPortと一致させる
-----
apiVersion: v1
kind: Service
metadata:
name: myapp-3-service
spec:
selector:
app: myapp-3
ports:
- protocol: TCP
port: 8002 ### ClusterIPが使用するPort
targetPort: 8000 ### コンテナのPort
nodePort: 32082 ### クライアントからのアクセスを受け付ける外部用Port
type: NodePort
ArgoCDのためのyamlをdeployする
– 下記を実行すると、ArgoCDのApplication画面でアプリが表示される
$ kubectl apply -f Application.yaml
正常性確認
– マニフェストを更新したら、GitlabリポジトリへPushする
– ArgoCDのApplication画面で、Syncをクリックして、同期が成功することを確認
– Djangoアプリが動作するURL「192.168.9.1:32080」へアクセスして、Djangoロケットが表示されればOK
検証中のエラーについて
同期失敗エラー
– 原因
– deployment.yamlにSelectorを書いてなかった
– selectorやlabelを後から編集して同期できないパターン。この場合一度deploymentを削除してから、再同期する必要がある
CLIでgitlabリポジトリ登録時の認証エラー
– NG時
$ argocd repo add ${GITLAB_MANIFESTS_REPO} –name myapp-3 –username ${GITLAB_USER} –password ${GITLAB_TOKEN} –server 192.168.9.1:30001 –insecureFATA[0000] rpc error: code = Unauthenticated desc = no session information
– 前述のArgoCDのGUIコンソールでGitlabリポジトリを登録して解消した
クライアントからNordPortにアクセスできない
– NG時
From 192.168.9.2(worker)
To myapp-3のPodのIP
$ nc -z -v 10.1.210.74 8000
Connection to 10.1.210.74 8000 port [tcp/*] succeeded!
To myapp-3のClusterIP
$ nc -z -v 10.152.183.48 8002
nc: connect to 10.152.183.48 port 8002 (tcp) failed: Connection refused
To myapp-3のNordPort(master)
$ nc -z -v 192.168.9.1 32082
nc: connect to 192.168.9.1 port 32082 (tcp) failed: Connection refused
※ ブラウザアクセス(http://192.168.9.1:32082)もNG
To myapp-3のNordPort(worker)
$ nc -z -v 192.168.9.2 32082
nc: connect to 192.168.9.2 port 32082 (tcp) failed: Connection refused
※ ブラウザアクセス(http://192.168.9.2:32082)もNG
– 解消時(namespace修正後)
From 192.168.9.2(worker)
To myapp-3のPodのIP
$ nc -z -v 10.1.210.74 8000
Connection to 10.1.210.74 8000 port [tcp/*] succeeded!
To myapp-3のClusterIP
$ nc -z -v 10.152.183.72 8002
Connection to 10.152.183.72 8002 port [tcp/*] succeeded!
To myapp-3のNordPort(master)
$ nc -z -v 192.168.9.1 32082
Connection to 192.168.9.1 32082 port [tcp/*] succeeded!
To myapp-3のNordPort(worker)
$ nc -z -v 192.168.9.2 32082
Connection to 192.168.9.2 32082 port [tcp/*] succeeded!
– 原因
– serviceのClusterIPが使用するnamespaceが、deploymentのPodが使うnamespaceとは異なっていた。Applicationのdestinationに別のnamespaceを定義していたが、そのnamespaceがなぜかserviceに使用されていた