feat: add Linkding deployment
This commit is contained in:
22
README.md
22
README.md
@@ -1 +1,23 @@
|
||||
# GitOps
|
||||
A set of "best practices" where the entire code delivery process is controlled via Git, including infrastructure and application definition as code and automation to complete updates and rollbacks.
|
||||
|
||||
The key GitOps Principles:
|
||||
|
||||
- The entire system (infrastructure and applications) is described declaratively.
|
||||
- The canonical desired system state is versioned in Git.
|
||||
- Changes approved are automated and applied to the system.
|
||||
- Software agents ensure correctness and alert on divergence.
|
||||
https://opengitops.dev/
|
||||
|
||||
Key points for a Kubernetes cluster:
|
||||
|
||||
The state of the cluster is always described in Git. Git holds everything for the application and not just the source code.
|
||||
There is no external deployment system with full access to the cluster. The cluster itself is pulling changes and deployment information.
|
||||
The GitOps controller is running in a constant loop and always matches the Git state with the cluster state (reconciliation loop).
|
||||
flux vs ArgoCD
|
||||
Flux is more CLI Driven ArgoCD has a richer GUI
|
||||
|
||||
## Flux
|
||||
Prerequisites:
|
||||
- Kubernetes Cluster
|
||||
-Github (giea, etc) personal access token
|
||||
|
||||
24
apps/hydra/linkding/deployment.yaml
Normal file
24
apps/hydra/linkding/deployment.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: linking
|
||||
name: linking
|
||||
namespace: linkding
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: linking
|
||||
strategy: {}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: linking
|
||||
spec:
|
||||
containers:
|
||||
- image: sissbruecket/linkding:1.31.0
|
||||
name: linkding
|
||||
ports:
|
||||
- containerPort: 9090
|
||||
resources: {}
|
||||
status: {}
|
||||
6
apps/hydra/linkding/namespace.yaml
Normal file
6
apps/hydra/linkding/namespace.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: linkding
|
||||
spec: {}
|
||||
status: {}
|
||||
15
apps/hydra/linkding/srv.yaml
Normal file
15
apps/hydra/linkding/srv.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: linking
|
||||
name: linking
|
||||
namespace: linkding
|
||||
spec:
|
||||
ports:
|
||||
- port: 9090
|
||||
targetPort: 0
|
||||
selector:
|
||||
app: linking
|
||||
status:
|
||||
loadBalancer: {}
|
||||
15
clusters/hydra/apps.yaml
Normal file
15
clusters/hydra/apps.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: apps
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 10m0s
|
||||
path: ./apps/hydra
|
||||
prune: true
|
||||
retryInterval: 1m0s
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: flux-system
|
||||
timeout: 5m0s
|
||||
status: {}
|
||||
2
go.mod
2
go.mod
@@ -3,7 +3,7 @@ module danicos.dev/daniel/homelab
|
||||
go 1.26.2
|
||||
|
||||
require (
|
||||
danicos.dev/daniel/go-kube v1.2.0
|
||||
danicos.dev/daniel/go-kube v1.2.2
|
||||
github.com/fatih/color v1.19.0
|
||||
github.com/fluxcd/kustomize-controller/api v1.8.3
|
||||
github.com/magefile/mage v1.17.1
|
||||
|
||||
4
go.sum
4
go.sum
@@ -1,5 +1,5 @@
|
||||
danicos.dev/daniel/go-kube v1.2.0 h1:nLcpSOmszmkMnHd4Fb9V7R8qO7z2OwNgUFFWQNwQazs=
|
||||
danicos.dev/daniel/go-kube v1.2.0/go.mod h1:FLgPxaiDpLmIwWddx5x4jTfP/onTzkOLbhmpdt2uX6w=
|
||||
danicos.dev/daniel/go-kube v1.2.2 h1:RW/mzIMIyMCEftTyvRTeJmo44JaCDsxLMlZcEnZxN1g=
|
||||
danicos.dev/daniel/go-kube v1.2.2/go.mod h1:FLgPxaiDpLmIwWddx5x4jTfP/onTzkOLbhmpdt2uX6w=
|
||||
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
*/)
|
||||
|
||||
var r target.Runner
|
||||
var Default = Run
|
||||
var Default = Build
|
||||
var Aliases = map[string]any{
|
||||
"r": Run,
|
||||
"b": Build,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -28,7 +28,7 @@ func init() {
|
||||
r = target.NewRunner(Env, nil)
|
||||
}
|
||||
|
||||
func Run() error {
|
||||
func Build() error {
|
||||
t := target.NewA("go", "run", ".")
|
||||
return r.RunV("run", t)
|
||||
}
|
||||
|
||||
38
main.go
38
main.go
@@ -1,15 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"danicos.dev/daniel/go-kube/pkg/kube"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"danicos.dev/daniel/go-kube/pkg/stack"
|
||||
"danicos.dev/daniel/homelab/pkg/flux"
|
||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1"
|
||||
)
|
||||
"danicos.dev/daniel/homelab/pkg/linkding"
|
||||
"danicos.dev/daniel/homelab/pkg/root"
|
||||
/*
|
||||
apps "k8s.io/api/apps/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
net "k8s.io/api/networking/v1"
|
||||
*/)
|
||||
|
||||
func main() {
|
||||
meta := kube.NewMetadata("name", kube.Namespace("nae"))
|
||||
kuz := kube.NewKustomization(meta, kustomizev1.KustomizationSpec{})
|
||||
fluxStack := flux.Stack()
|
||||
fluxStack.Add("apps", kuz)
|
||||
fluxStack.MarshalYaml("")
|
||||
flux_stack := flux.Stack()
|
||||
err := flux_stack.MarshalYamlFlat(root.FLUX_CLUSTER_HYDRA_PATH)
|
||||
assertNoErr(err)
|
||||
|
||||
hydraApps := map[string]stack.Stack{
|
||||
"linkding": linkding.Stack(),
|
||||
}
|
||||
for name, s := range hydraApps {
|
||||
fmt.Printf("STACK: %s\n", name)
|
||||
err = s.MarshalYaml(root.FLUX_APPS_HYDRA_PATH)
|
||||
assertNoErr(err)
|
||||
}
|
||||
}
|
||||
|
||||
func assertNoErr(err error) {
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,46 @@
|
||||
package flux
|
||||
|
||||
import "danicos.dev/daniel/go-kube/pkg/stack"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"danicos.dev/daniel/go-kube/pkg/kube"
|
||||
"danicos.dev/daniel/go-kube/pkg/stack"
|
||||
"danicos.dev/daniel/homelab/pkg/root"
|
||||
kz "github.com/fluxcd/kustomize-controller/api/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
var flux_apps_meta kube.Metadata
|
||||
var Flux_namespace = kube.Namespace(root.FLUX_NAMESPACE)
|
||||
|
||||
func init() {
|
||||
flux_apps_meta = kube.NewMetadata("apps", Flux_namespace)
|
||||
}
|
||||
|
||||
func Stack() stack.Stack {
|
||||
s := stack.NewStack("", nil)
|
||||
s := stack.NewStack("flux", map[string]any{
|
||||
"apps": Apps(),
|
||||
})
|
||||
return s
|
||||
}
|
||||
|
||||
func Apps() kz.Kustomization {
|
||||
retryInteval := durMin(1)
|
||||
timeout := durMin(5)
|
||||
spec := kz.KustomizationSpec{
|
||||
Interval: durMin(10),
|
||||
RetryInterval: &retryInteval,
|
||||
Timeout: &timeout,
|
||||
SourceRef: kz.CrossNamespaceSourceReference{
|
||||
Kind: "GitRepository",
|
||||
Name: Flux_namespace.Name,
|
||||
},
|
||||
Path: root.FLUX_APPS_HYDRA_PATH,
|
||||
Prune: true,
|
||||
}
|
||||
return kube.NewKustomization(flux_apps_meta, spec)
|
||||
}
|
||||
|
||||
func durMin(d int64) meta.Duration {
|
||||
return meta.Duration{Duration: (time.Duration(d) * time.Minute)}
|
||||
}
|
||||
|
||||
42
pkg/linkding/linkding.go
Normal file
42
pkg/linkding/linkding.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package linkding
|
||||
|
||||
import (
|
||||
"danicos.dev/daniel/go-kube/pkg/kube"
|
||||
"danicos.dev/daniel/go-kube/pkg/stack"
|
||||
"danicos.dev/daniel/homelab/pkg/root"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
var meta kube.Metadata
|
||||
var Namespace = kube.Namespace("linkding")
|
||||
var srv core.Service
|
||||
|
||||
func init() {
|
||||
meta = kube.NewMetadata("linking", Namespace)
|
||||
srv = meta.Service(root.Linkding.Port)
|
||||
}
|
||||
|
||||
func Stack() stack.Stack {
|
||||
s := stack.NewStack("linkding", map[string]any{
|
||||
"namespace": Namespace,
|
||||
"srv": srv,
|
||||
"deployment": deployment(),
|
||||
})
|
||||
return s
|
||||
}
|
||||
|
||||
func deployment() apps.Deployment {
|
||||
pod_spec := core.PodSpec{
|
||||
Containers: []core.Container{
|
||||
{
|
||||
Name: root.Linkding.Name,
|
||||
Image: root.Linkding.Image,
|
||||
Ports: []core.ContainerPort{{
|
||||
ContainerPort: root.Linkding.Port,
|
||||
}},
|
||||
},
|
||||
},
|
||||
}
|
||||
return kube.NewDeployment(meta, pod_spec)
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
package root
|
||||
|
||||
var (
|
||||
const (
|
||||
HYDRA_CLUSTER = "hydra"
|
||||
HYDRA_HOSTNAME = "hydra-0" // VPN Host
|
||||
GITEA_HOST = "danicos.dev"
|
||||
)
|
||||
|
||||
const (
|
||||
FLUX_NAMESPACE = "flux-system"
|
||||
FLUX_APPS_HYDRA_PATH = "./apps/" + HYDRA_CLUSTER
|
||||
FLUX_CLUSTER_HYDRA_PATH = "./clusters/" + HYDRA_CLUSTER
|
||||
)
|
||||
|
||||
13
pkg/root/services.go
Normal file
13
pkg/root/services.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package root
|
||||
|
||||
type Service struct {
|
||||
Name string
|
||||
Image string
|
||||
Port int32
|
||||
}
|
||||
|
||||
var Linkding = Service{
|
||||
Name: "linkding",
|
||||
Image: "sissbruecket/linkding:1.31.0",
|
||||
Port: 9090,
|
||||
}
|
||||
@@ -13,4 +13,4 @@ flux --kubeconfig ~/.kube/$CLUSTER_NAME \
|
||||
--private=false \
|
||||
--branch=main \
|
||||
--personal=true \
|
||||
--path=./clusters/hydra
|
||||
--path=./clusters/$CLUSTER_NAME
|
||||
|
||||
Reference in New Issue
Block a user