diff --git a/.github/workflows/pulumi.yml b/.github/workflows/pulumi.yml index 8c898f4..73935f8 100644 --- a/.github/workflows/pulumi.yml +++ b/.github/workflows/pulumi.yml @@ -11,11 +11,17 @@ on: - '*/README.md' jobs: kind-clustermesh: + strategy: + fail-fast: false + matrix: + dir: + - ./kind-clustermesh + - ./kind-clustermesh-optimization name: Cluster Mesh Kind runs-on: ubuntu-latest defaults: run: - working-directory: ./kind-clustermesh + working-directory: ${{ matrix.dir }} steps: - uses: actions/checkout@v4 - uses: cilium/cilium-cli@404d52692f62eebb7211fdacd114848995ada1b7 @@ -31,15 +37,13 @@ jobs: run: pip install -r requirements.txt - uses: pulumi/actions@v5 - with: - work-dir: ./kind-clustermesh - name: Create stack run: pulumi login --local && pulumi stack init dev && pulumi config set --stack dev clusterNumber $CLUSTER_NUMBER - uses: pulumi/actions@v5 with: - work-dir: ./kind-clustermesh + work-dir: ${{ matrix.dir }} command: up stack-name: dev cloud-url: file://~ @@ -57,7 +61,7 @@ jobs: - uses: pulumi/actions@v5 with: - work-dir: ./kind-clustermesh + work-dir: ${{ matrix.dir }} command: destroy stack-name: dev cloud-url: file://~ diff --git a/kind-clustermesh-optimization/Pulumi.yaml b/kind-clustermesh-optimization/Pulumi.yaml new file mode 100644 index 0000000..4d6245e --- /dev/null +++ b/kind-clustermesh-optimization/Pulumi.yaml @@ -0,0 +1,6 @@ +name: project +runtime: + name: python + options: + virtualenv: venv +description: install cilium using https://www.pulumi.com/registry/packages/cilium/ package diff --git a/kind-clustermesh-optimization/README.md b/kind-clustermesh-optimization/README.md new file mode 100644 index 0000000..099cb0b --- /dev/null +++ b/kind-clustermesh-optimization/README.md @@ -0,0 +1,28 @@ +# Install pulumi + +``` +curl -fsSL https://get.pulumi.com | sh +``` + +# Deploy cilium + +``` +pulumi up +``` + +## Number of clusters + +By default the number of clusters is 3. + +But if you want to only test with 2 clusters: + +``` +pulumi config set clusterNumber 2 +pulumi up +``` + +It should work with more than 200 but i never tested because it needs a good computer :) + +# Example + +![Example of deployment of cilium clustermesh on 3 clusters](img/clustermesh-3.gif) diff --git a/kind-clustermesh-optimization/__main__.py b/kind-clustermesh-optimization/__main__.py new file mode 100644 index 0000000..1617e92 --- /dev/null +++ b/kind-clustermesh-optimization/__main__.py @@ -0,0 +1,87 @@ +import pulumi +import littlejo_cilium as cilium +from pulumi_command import local +import itertools + +def cilium_clustermesh(i, kind): + cmesh_provider = cilium.Provider(f"cmesh{i}", context=f"kind-cmesh{i}", opts=pulumi.ResourceOptions(depends_on=kind[i-1], parent=kind[i-1])) + cmesh_cilium = cilium.Install(f"cmesh{i}Install", + sets=[ + f"cluster.name=cmesh{i}", + f"cluster.id={i}", + "ipam.mode=kubernetes", + ], + version="1.15.5", + opts=pulumi.ResourceOptions(depends_on=kind, providers=[cmesh_provider], parent=cmesh_provider), + ) + return { + "cmesh": cilium.Clustermesh(f"cmesh{i}Enable", service_type="NodePort", opts=pulumi.ResourceOptions(depends_on=[cmesh_cilium], providers=[cmesh_provider], parent=cmesh_cilium)), + "provider": cmesh_provider, + } + +def combinlist(seq): + return list(itertools.combinations(seq, 2)) + +def intersection(ll, la): + res = [] + flat_res = [] + for l in ll: + if list(set(l) & set(la)) == [] and list(set(flat_res) & set(l)) == []: + res += [l] + flat_res += [l[0], l[1]] + + return [la] + res + +def combi_optimization(connections_list): + intersect = [] + res = [] + flat_res = [] + + for conn in connections_list_cst: + if conn in connections_list: + intersect = intersection(connections_list, conn) + for i in intersect: + connections_list.remove(i) + res += [intersect] + flat_res += intersect + return (flat_res, res) + +config = pulumi.Config() +try: + cluster_number = int(config.require("clusterNumber")) +except: + cluster_number = 4 +kind_list = [] +c = [] +cmesh_connect = [] +depends_on = [] + +cluster_ids = list(range(1, cluster_number+1)) + +connections_list = combinlist(cluster_ids) +connections_list_cst = connections_list[:] + +flat_connections_list, connections_list = combi_optimization(connections_list) + +for i in cluster_ids: + kind_list += [local.Command(f"kindCluster-{i}", + create=f"sed 's/NUMBER/{i}/g' kind.yaml.template > kind-{i}.yaml && kind create cluster --config kind-{i}.yaml --name cmesh{i}", + delete=f"kind delete clusters cmesh{i} && rm kind-{i}.yaml", + )] + +for i in cluster_ids: + c += [cilium_clustermesh(i, kind_list)] + +k = 0 +l = 0 +null = [] + +for connections in connections_list: + null += [local.Command(f"null-{l}", create=f"echo ''", opts=pulumi.ResourceOptions(depends_on=[a['cmesh'] for a in c]))] + for conn in connections: + i = conn[0] + j = conn[1] + cmesh_connect += [cilium.ClustermeshConnection(f"cmeshConnect-{i}-{j}", destination_context=f"kind-cmesh{i}", opts=pulumi.ResourceOptions(parent=null[l], depends_on=depends_on, providers=[c[j-1]['provider']]))] + k += 1 + depends_on += cmesh_connect + null + l += 1 diff --git a/kind-clustermesh-optimization/kind.yaml.template b/kind-clustermesh-optimization/kind.yaml.template new file mode 100644 index 0000000..48d3a46 --- /dev/null +++ b/kind-clustermesh-optimization/kind.yaml.template @@ -0,0 +1,8 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane +networking: + disableDefaultCNI: true + podSubnet: "10.NUMBER.0.0/16" + serviceSubnet: "172.20.NUMBER.0/24" diff --git a/kind-clustermesh-optimization/requirements.txt b/kind-clustermesh-optimization/requirements.txt new file mode 100644 index 0000000..ee8c4fe --- /dev/null +++ b/kind-clustermesh-optimization/requirements.txt @@ -0,0 +1,3 @@ +pulumi>=3 +littlejo-cilium==0.1.2 +pulumi-command