From 07d700d6519a4519fcae0f0766308ad7ac2b6c10 Mon Sep 17 00:00:00 2001 From: Bertrand THOMAS Date: Sun, 29 Mar 2026 15:11:25 +0200 Subject: [PATCH 1/7] Add web icon --- docs/fundamentals/standards/glossary.md | 2 +- docs/organizations/companies/armis/armis.md | 4 ++-- docs/organizations/companies/armorcode/armorcode.md | 4 ++-- docs/organizations/companies/checkpoint/checkpoint.md | 4 ++-- docs/organizations/companies/crowdstrike/crowdstrike.md | 4 ++-- docs/organizations/companies/cyscale/cyscale.md | 2 +- docs/organizations/companies/data-theorem/data-theorem.md | 2 +- .../companies/enalean/{teleap.md => tuleap.md} | 0 docs/organizations/companies/fortinet/fortinet.md | 4 ++-- docs/organizations/companies/ibm/ibm.md | 2 +- docs/organizations/companies/infomaniak/infomaniak.md | 0 docs/organizations/companies/octopus-deploy/codefresh.md | 4 ++-- .../companies/octopus-deploy/octopus-deploy.md | 1 + docs/organizations/companies/orca-security/orca-security.md | 4 ++-- .../companies/paloaltonetworks/paloaltonetworks.md | 4 ++-- docs/organizations/companies/qualys/qualys.md | 2 +- docs/organizations/companies/rapid7/rapid7.md | 4 ++-- docs/organizations/companies/rapidfort/kimia.md | 4 ++-- docs/organizations/companies/sentinelone/sentinelone.md | 4 ++-- docs/organizations/companies/snyk/snyk.md | 4 ++-- docs/organizations/companies/wiz/glossary.md | 3 --- docs/organizations/companies/wiz/wiz.md | 6 +++--- 22 files changed, 33 insertions(+), 35 deletions(-) rename docs/organizations/companies/enalean/{teleap.md => tuleap.md} (100%) create mode 100644 docs/organizations/companies/infomaniak/infomaniak.md delete mode 100644 docs/organizations/companies/wiz/glossary.md diff --git a/docs/fundamentals/standards/glossary.md b/docs/fundamentals/standards/glossary.md index 7266601..800ff7d 100644 --- a/docs/fundamentals/standards/glossary.md +++ b/docs/fundamentals/standards/glossary.md @@ -1,4 +1,4 @@ -# Glossary +# Glossary ## IT diff --git a/docs/organizations/companies/armis/armis.md b/docs/organizations/companies/armis/armis.md index b74e8a1..11263d1 100644 --- a/docs/organizations/companies/armis/armis.md +++ b/docs/organizations/companies/armis/armis.md @@ -1,3 +1,3 @@ -# Armis +# Armis -[armis.com](https://www.armis.com/) +🌐 [armis.com](https://www.armis.com/) diff --git a/docs/organizations/companies/armorcode/armorcode.md b/docs/organizations/companies/armorcode/armorcode.md index fa45461..63a74cd 100644 --- a/docs/organizations/companies/armorcode/armorcode.md +++ b/docs/organizations/companies/armorcode/armorcode.md @@ -1,3 +1,3 @@ -# ArmorCode +# ArmorCode -[armorcode.com](https://www.armorcode.com/) +🌐 [armorcode.com](https://www.armorcode.com/) diff --git a/docs/organizations/companies/checkpoint/checkpoint.md b/docs/organizations/companies/checkpoint/checkpoint.md index 4d9228b..3614fb9 100644 --- a/docs/organizations/companies/checkpoint/checkpoint.md +++ b/docs/organizations/companies/checkpoint/checkpoint.md @@ -1,6 +1,6 @@ -# Check Point +# Check Point -[checkpoint.com](https://www.checkpoint.com/) +🌐 [checkpoint.com](https://www.checkpoint.com/) ## Check Point CloudGuard diff --git a/docs/organizations/companies/crowdstrike/crowdstrike.md b/docs/organizations/companies/crowdstrike/crowdstrike.md index 1a7b5b7..3979f38 100644 --- a/docs/organizations/companies/crowdstrike/crowdstrike.md +++ b/docs/organizations/companies/crowdstrike/crowdstrike.md @@ -1,3 +1,3 @@ -# CrowdStrike +# CrowdStrike -[crowdstrike.com](https://www.crowdstrike.com/) +🌐 [crowdstrike.com](https://www.crowdstrike.com/) diff --git a/docs/organizations/companies/cyscale/cyscale.md b/docs/organizations/companies/cyscale/cyscale.md index c7386f6..cbd7ea6 100644 --- a/docs/organizations/companies/cyscale/cyscale.md +++ b/docs/organizations/companies/cyscale/cyscale.md @@ -1,3 +1,3 @@ # Cyscale -[cyscale.com](https://cyscale.com/) +🌐 [cyscale.com](https://cyscale.com/) diff --git a/docs/organizations/companies/data-theorem/data-theorem.md b/docs/organizations/companies/data-theorem/data-theorem.md index 05116ec..2af6c5b 100644 --- a/docs/organizations/companies/data-theorem/data-theorem.md +++ b/docs/organizations/companies/data-theorem/data-theorem.md @@ -1,6 +1,6 @@ # Data Theorem -[datatheorem.com](https://www.datatheorem.com/) +🌐 [datatheorem.com](https://www.datatheorem.com/) ## Cloud Secure diff --git a/docs/organizations/companies/enalean/teleap.md b/docs/organizations/companies/enalean/tuleap.md similarity index 100% rename from docs/organizations/companies/enalean/teleap.md rename to docs/organizations/companies/enalean/tuleap.md diff --git a/docs/organizations/companies/fortinet/fortinet.md b/docs/organizations/companies/fortinet/fortinet.md index 12c0d5e..6664aae 100644 --- a/docs/organizations/companies/fortinet/fortinet.md +++ b/docs/organizations/companies/fortinet/fortinet.md @@ -1,6 +1,6 @@ -# Fortinet +# Fortinet -[fortinet.com](https://www.fortinet.com/) +🌐 [fortinet.com](https://www.fortinet.com/) ## Lacework FortiCNAPP diff --git a/docs/organizations/companies/ibm/ibm.md b/docs/organizations/companies/ibm/ibm.md index ef72396..8778add 100644 --- a/docs/organizations/companies/ibm/ibm.md +++ b/docs/organizations/companies/ibm/ibm.md @@ -1,6 +1,6 @@ # IBM -[ibm.com](https://ibm.com) +🌐 [ibm.com](https://ibm.com) ## IBM Cloud Security and Compliance Center diff --git a/docs/organizations/companies/infomaniak/infomaniak.md b/docs/organizations/companies/infomaniak/infomaniak.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/organizations/companies/octopus-deploy/codefresh.md b/docs/organizations/companies/octopus-deploy/codefresh.md index 16b9128..9aeddc3 100644 --- a/docs/organizations/companies/octopus-deploy/codefresh.md +++ b/docs/organizations/companies/octopus-deploy/codefresh.md @@ -1,5 +1,5 @@ -# Codefresh +# Codefresh -[codefresh.io](https://codefresh.io/) +🌐 [codefresh.io](https://codefresh.io/) [How we replaced the default K8s scheduler to optimize our Continuous Integration builds](https://codefresh.io/blog/custom-k8s-scheduler-continuous-integration/) - July 7, 2025 diff --git a/docs/organizations/companies/octopus-deploy/octopus-deploy.md b/docs/organizations/companies/octopus-deploy/octopus-deploy.md index e69de29..1f51dfc 100644 --- a/docs/organizations/companies/octopus-deploy/octopus-deploy.md +++ b/docs/organizations/companies/octopus-deploy/octopus-deploy.md @@ -0,0 +1 @@ +# Octopus Deploy diff --git a/docs/organizations/companies/orca-security/orca-security.md b/docs/organizations/companies/orca-security/orca-security.md index d82e566..0dd8c8b 100644 --- a/docs/organizations/companies/orca-security/orca-security.md +++ b/docs/organizations/companies/orca-security/orca-security.md @@ -1,3 +1,3 @@ -# Orca Security +# Orca Security -[orca.security](https://orca.security/) +🌐 [orca.security](https://orca.security/) diff --git a/docs/organizations/companies/paloaltonetworks/paloaltonetworks.md b/docs/organizations/companies/paloaltonetworks/paloaltonetworks.md index 73e27a2..f178238 100644 --- a/docs/organizations/companies/paloaltonetworks/paloaltonetworks.md +++ b/docs/organizations/companies/paloaltonetworks/paloaltonetworks.md @@ -1,6 +1,6 @@ -# Palo Alto Networks +# Palo Alto Networks -[paloaltonetworks.com](https://www.paloaltonetworks.com/) +🌐 [paloaltonetworks.com](https://www.paloaltonetworks.com/) ## Prisma Cloud diff --git a/docs/organizations/companies/qualys/qualys.md b/docs/organizations/companies/qualys/qualys.md index 6d0e247..0f92325 100644 --- a/docs/organizations/companies/qualys/qualys.md +++ b/docs/organizations/companies/qualys/qualys.md @@ -1,3 +1,3 @@ # Qualys -[qualys.com](https://www.qualys.com/) +🌐 [qualys.com](https://www.qualys.com/) diff --git a/docs/organizations/companies/rapid7/rapid7.md b/docs/organizations/companies/rapid7/rapid7.md index 6f4f5c0..5c0f96f 100644 --- a/docs/organizations/companies/rapid7/rapid7.md +++ b/docs/organizations/companies/rapid7/rapid7.md @@ -1,6 +1,6 @@ -# Rapid7 +# Rapid7 -[rapid7.com](https://www.rapid7.com/) +🌐 [rapid7.com](https://www.rapid7.com/) ## InsightCloudSec diff --git a/docs/organizations/companies/rapidfort/kimia.md b/docs/organizations/companies/rapidfort/kimia.md index b2bd892..70266a7 100644 --- a/docs/organizations/companies/rapidfort/kimia.md +++ b/docs/organizations/companies/rapidfort/kimia.md @@ -1,5 +1,5 @@ -# Kimia +# Kimia > Kimia is a Kubernetes-native, OCI-compliant container image builder designed for secure, daemonless builds in cloud environments. -[code](https://github.com/rapidfort/kimia) +🌐 [code](https://github.com/rapidfort/kimia) diff --git a/docs/organizations/companies/sentinelone/sentinelone.md b/docs/organizations/companies/sentinelone/sentinelone.md index e7c471d..6071781 100644 --- a/docs/organizations/companies/sentinelone/sentinelone.md +++ b/docs/organizations/companies/sentinelone/sentinelone.md @@ -1,6 +1,6 @@ -# SentinelOne +# SentinelOne -[sentinelone.com](https://www.sentinelone.com/) +🌐 [sentinelone.com](https://www.sentinelone.com/) ## Singularity Cloud Security diff --git a/docs/organizations/companies/snyk/snyk.md b/docs/organizations/companies/snyk/snyk.md index 17f3533..9fdbe00 100644 --- a/docs/organizations/companies/snyk/snyk.md +++ b/docs/organizations/companies/snyk/snyk.md @@ -1,3 +1,3 @@ -# Snyk +# Snyk -[snyk.io](https://snyk.io) +🌐 [snyk.io](https://snyk.io) diff --git a/docs/organizations/companies/wiz/glossary.md b/docs/organizations/companies/wiz/glossary.md deleted file mode 100644 index 4973780..0000000 --- a/docs/organizations/companies/wiz/glossary.md +++ /dev/null @@ -1,3 +0,0 @@ -# Glossary - -CNAPP (cloud-native application protection platform) diff --git a/docs/organizations/companies/wiz/wiz.md b/docs/organizations/companies/wiz/wiz.md index ec4a840..abc5ed1 100644 --- a/docs/organizations/companies/wiz/wiz.md +++ b/docs/organizations/companies/wiz/wiz.md @@ -1,8 +1,8 @@ -# Wiz +# Wiz -[wiz.io](https://www.wiz.io/) +🌐 [wiz.io](https://www.wiz.io/) -[YouTube channel](https://www.youtube.com/@wizsecurity) +[YouTube](https://www.youtube.com/@wizsecurity) ## History From cbbbb6af5b84e72f024f42175222df1840931b03 Mon Sep 17 00:00:00 2001 From: Bertrand THOMAS Date: Sun, 29 Mar 2026 15:14:34 +0200 Subject: [PATCH 2/7] Use markdownlint-cli2 in gitlab pipeline --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fa2c3ec..11e8da7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,4 @@ -workflow: +workflow: rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH @@ -11,8 +11,8 @@ lint-markdown: stage: build image: node:lts script: - - npm install -g markdownlint-cli - - markdownlint "**/*.md" + - npm install -g markdownlint-cli2 + - markdownlint-cli2 "**/*.md" lint-yaml: stage: build From a7187722276748dc2d39c487dbde1c9970738f18 Mon Sep 17 00:00:00 2001 From: Bertrand THOMAS Date: Sun, 29 Mar 2026 15:44:50 +0200 Subject: [PATCH 3/7] Add files from ci-pipeline-samples repo --- CONTRIBUTING.md | 8 -- .../learning-paths/code-pipelines/bamboo.md | 100 ++++++++++++++++++ .../code-pipelines/bitbucket-cloud.md | 44 ++++++++ .../code-pipelines/code-pieplines.md | 15 +++ .../code-pipelines/concourse.md | 62 +++++++++++ .../learning-paths/code-pipelines/teamcity.md | 57 ++++++++++ docs/guides/workstations/windows/windows.md | 11 +- .../companies/gitlab/runner-container.md | 14 ++- .../companies/jetbrains/rider.md | 3 + .../companies/jetbrains/webstorm.md | 3 + samples/concourse/compose.yml | 27 +++++ .../pipelines/basic/01_helloworld.yml | 13 +++ .../pipelines/dotnet/01_aspnetcore.yml | 30 ++++++ .../pipelines/dotnet/02_globaltool.yml | 46 ++++++++ samples/concourse/tasks/basic/helloworld.yml | 7 ++ 15 files changed, 423 insertions(+), 17 deletions(-) create mode 100644 docs/guides/learning-paths/code-pipelines/bamboo.md create mode 100644 docs/guides/learning-paths/code-pipelines/bitbucket-cloud.md create mode 100644 docs/guides/learning-paths/code-pipelines/code-pieplines.md create mode 100644 docs/guides/learning-paths/code-pipelines/concourse.md create mode 100644 docs/guides/learning-paths/code-pipelines/teamcity.md create mode 100644 docs/organizations/companies/jetbrains/rider.md create mode 100644 docs/organizations/companies/jetbrains/webstorm.md create mode 100644 samples/concourse/compose.yml create mode 100644 samples/concourse/pipelines/basic/01_helloworld.yml create mode 100644 samples/concourse/pipelines/dotnet/01_aspnetcore.yml create mode 100644 samples/concourse/pipelines/dotnet/02_globaltool.yml create mode 100644 samples/concourse/tasks/basic/helloworld.yml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dac8fe0..61f0979 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,11 +64,3 @@ Check Markdown files: ```bash docker run --rm -v "$(pwd)":/workdir davidanson/markdownlint-cli2 "**/*.md" ``` - -Reproduce locally GitLab jobs: - -```bash -mkdir -p .gitlab/runner/local -docker run --rm --name gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock -v $PWD/.gitlab/runner/local/config:/etc/gitlab-runner -v $PWD:$PWD --workdir $PWD gitlab/gitlab-runner exec docker lint-markdown -docker run --rm --name gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock -v $PWD/.gitlab/runner/local/config:/etc/gitlab-runner -v $PWD:$PWD --workdir $PWD gitlab/gitlab-runner exec docker lint-yaml -``` diff --git a/docs/guides/learning-paths/code-pipelines/bamboo.md b/docs/guides/learning-paths/code-pipelines/bamboo.md new file mode 100644 index 0000000..b8082d1 --- /dev/null +++ b/docs/guides/learning-paths/code-pipelines/bamboo.md @@ -0,0 +1,100 @@ +# Bamboo Data Center + +## Introduction + +> Bamboo Data Center is a continuous delivery pipeline that offers resilience, reliability, and scalibility for teams of any size. + +[atlassian.com/software/bamboo](https://www.atlassian.com/software/bamboo) + +## Setup + +### Build the custom image + +Create `.bamboo/server/Dockerfile` file: + +```Dockerfile +# starts from the base image provided by Atlassian: https://hub.docker.com/r/atlassian/bamboo-server (7.2.2 based on Ubuntu 20.04.1 LTS, codename focal) +FROM atlassian/bamboo-server:7.2.2 + +# switches to root user for admin commands +USER root + +# installs system requirements +RUN apt-get update +RUN apt-get install -y apt-transport-https \ + ca-certificates \ + wget \ + curl \ + gnupg-agent \ + software-properties-common +RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - +RUN add-apt-repository \ + "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) \ + stable" +RUN wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \ + && dpkg -i packages-microsoft-prod.deb +RUN apt-get update + +# installs Docker: https://docs.docker.com/engine/install/ubuntu/ +RUN apt-get install -y docker-ce \ + docker-ce-cli \ + containerd.io +RUN usermod -a -G docker bamboo + +# installs .NET SDK LTS: https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu +RUN apt-get install -y dotnet-sdk-3.1 +RUN apt-get install -y dotnet-sdk-5.0 + +# switches back to bamboo user +USER bamboo + +# updates image entrypoint with commands that can only be ran when the container starts +RUN echo "chown root:docker /var/run/docker.sock" >> /entrypoint.sh +``` + +```bash +# creates a new image +docker build . -t devprofr/bamboo-server -f .bamboo/server/Dockerfile --no-cache +``` + +### Run the custom image + +```bash +docker volume create --name bambooVolume + +# for Linux +docker run -v /var/run/docker.sock:/var/run/docker.sock -v bambooVolume:/var/atlassian/application-data/bamboo --name="bamboo" --init -d -p 54663:54663 -p 8085:8085 devprofr/bamboo-server + +# for Windows +docker run -v //var/run/docker.sock:/var/run/docker.sock -v bambooVolume:/var/atlassian/application-data/bamboo --name="bamboo" --init -d -p 54663:54663 -p 8085:8085 devprofr/bamboo-server +``` + +### Configuration + +Open [localhost:8085](http://localhost:8085/) + +#### Set server capabilities + +_Limitation 2021-02-28_: Unfortunately it is not possible to automate it through an API call + +You have to manually go to this page ["Bamboo administration > Server capabilities"](http://localhost:8085/admin/agent/configureSharedLocalCapabilities.action) and set the server capabilities (if not present), it must be done only once/ + +Category | Executable / Label | Path | Bamboo key +-----------|--------------------|-------------------|-------------------------------- +Executable | dotnet | `/usr/bin/dotnet` | `system.builder.command.dotnet` +Docker | Docker | `/usr/bin/docker` | `system.docker.executable` + +### Troubleshooting + +```bash +docker exec -it bamboo sh +docker exec -u 0 -it bamboo bash +``` + +### Clean-up + +```bash +docker stop bamboo +docker rm bamboo +``` diff --git a/docs/guides/learning-paths/code-pipelines/bitbucket-cloud.md b/docs/guides/learning-paths/code-pipelines/bitbucket-cloud.md new file mode 100644 index 0000000..aeda487 --- /dev/null +++ b/docs/guides/learning-paths/code-pipelines/bitbucket-cloud.md @@ -0,0 +1,44 @@ +# Bitbucket (Cloud) + +## Introduction + +> Bitbucket is more than just Git code management. +> Bitbucket gives teams one place to plan projects, collaborate on code, test, and deploy. + +[bitbucket.org/product](https://bitbucket.org/product/) + +## Setup + +Create a file `bitbucket-pipelines.yml`: + +```yml +image: mcr.microsoft.com/dotnet/sdk:5.0 + +pipelines: + default: + - parallel: + - step: + name: Build and Test + caches: + - dotnetcore + script: + - REPORTS_PATH=./test-reports/build_${BITBUCKET_BUILD_NUMBER} + - cd samples/dotnet + - dotnet restore + - dotnet build --no-restore --configuration Release + - dotnet test --no-build --configuration Release --test-adapter-path:. --logger:"junit;LogFilePath=$REPORTS_PATH/junit.xml" + - step: + name: Lint the code + caches: + - dotnetcore + script: + - export SOLUTION_NAME=Devpro.CIToolsDemo + - export REPORTS_PATH=linter-reports + - cd samples/dotnet + - dotnet new tool-manifest + - dotnet tool install JetBrains.ReSharper.GlobalTools --version 2021.1.0-eap02 + - dotnet tool restore + - dotnet jb inspectcode ${SOLUTION_NAME}.sln --output="${REPORTS_PATH}/jb-${BITBUCKET_BUILD_NUMBER}.xml" + artifacts: + - linter-reports/** +``` diff --git a/docs/guides/learning-paths/code-pipelines/code-pieplines.md b/docs/guides/learning-paths/code-pipelines/code-pieplines.md new file mode 100644 index 0000000..6bf27fa --- /dev/null +++ b/docs/guides/learning-paths/code-pipelines/code-pieplines.md @@ -0,0 +1,15 @@ +# Code pipelines + +Let's explore different tools to implement CI pipelines! + +## Platforms + +Platform | Typology +--------------------------------------|------------------------ +Azure DevOps | Cloud +[Bamboo Data Center](bamboo.md) | Self-hosted (container) +[Bitbucket Cloud](bitbucket-cloud.md) | Cloud +[Concourse](concourse.md) | Self-hosted (container) +GitHub | Cloud +GitLab | Cloud +[TeamCity Professional](teamcity.md) | Self-hosted (container) diff --git a/docs/guides/learning-paths/code-pipelines/concourse.md b/docs/guides/learning-paths/code-pipelines/concourse.md new file mode 100644 index 0000000..c9bfb39 --- /dev/null +++ b/docs/guides/learning-paths/code-pipelines/concourse.md @@ -0,0 +1,62 @@ +# Concourse samples + +Comprehensive samples to quickly get up to speed with [Concourse](../../../organizations/communities/concourse/concourse.md). + +## Requirements + +* Have an account to a running Concourse instance + * For the first time, you can use the local containers with `docker compose -f samples/concourse/compose.yml up -d` + * You can also deploy it in a Kubernetes cluster with [Helm chart](https://github.com/devpro/helm-charts/tree/feature/concourse/charts/concourse) + * Ultimately, you can run it on a [VM](https://github.com/devpro/information-technology-guide/blob/main/docs/communities/concourse/ubuntu-install.md) + +* Have `fly` executable on the machine running the command lines (careful with the version that needs to match the one from Concourse instance) + * Grab it from the [releases GitHub page](https://github.com/concourse/concourse/releases) or from the running Concourse web page + +## Samples + +### Login + +```bash +fly --target localhost login --concourse-url http://localhost:8080/ +``` + +### Pipelines + +* Hello world + +Login on localhost: + +```bash +fly --target localhost set-pipeline --pipeline helloworld --config samples/concourse/tasks/basic/01_helloworld.yml + +# enables the pipeline and run it (can also be done from http://localhost:8080/teams/main/pipelines/helloworld, click on play symbol then on + symbol) +fly -t localhost unpause-pipeline -p helloworld +fly -t localhost trigger-job -j helloworld/job +``` + +* .NET + +```bash +fly --target localhost set-pipeline --pipeline aspnetcore --config samples/concourse/tasks/dotnet/01_aspnetcore.yml + +fly -t localhost unpause-pipeline -p aspnetcore + +fly -t localhost trigger-job -j aspnetcore/build-webapp + +fly --target localhost set-pipeline --pipeline dotnetglobaltool --config pipelines/dotnetcore/02_globaltool.yml --var mdbatlas-publickey=xxxx --var mdbatlas-publickey=yyyy -var almops-token=zzz --var almops-org=xxxx -var almops-user=yyyy -var almops-token=zzz + +fly -t localhost unpause-pipeline -p dotnetglobaltool + +fly -t localhost trigger-job -j dotnetglobaltool/mongodb-atlas -w +fly -t localhost trigger-job -j dotnetglobaltool/azure-devops -w +``` + +### Tasks + +* Hello world + +```bash +fly --target localhost login --concourse-url http://localhost:8080/ + +fly -t localhost execute --config samples/concourse/tasks/basic/helloworld.yml +``` diff --git a/docs/guides/learning-paths/code-pipelines/teamcity.md b/docs/guides/learning-paths/code-pipelines/teamcity.md new file mode 100644 index 0000000..e58b29c --- /dev/null +++ b/docs/guides/learning-paths/code-pipelines/teamcity.md @@ -0,0 +1,57 @@ +# TeamCity + +In this tutorial we'll setup an instance of TeamCity, running on Docker, and configure a CI pipeline on the code samples available in this repository. + +## Setup + +### Create local folders + +```bash +# creates local folders to store TeamCity run files +md data logs agent +md agent/conf +``` + +### Run TeamCity server in a container + +```bash +# starts the container +docker run -it --name teamcity-server -v $PWD/data:/data/teamcity_server/datadir -v $PWD/logs:/opt/teamcity/logs -p 8111:8111 jetbrains/teamcity-server + +# if stopped, starts again the container +docker start teamcity-server +``` + +### Run TeamCity agent in a container + +#### Use the Docker image + +```bash +docker run -it --name teamcity-agent -e SERVER_URL="http://teamcity-server:8111" -v $PWD/agent/conf:/data/teamcity_agent/conf --link teamcity-server jetbrains/teamcity-agent +``` + +→ [hub.docker.com](https://hub.docker.com/r/jetbrains/teamcity-agent/) + +#### Use a custom image + +The default image may not contain all the needed tools for the pipeline to run. + +TODO + +### Clean-up + +```bash +docker rm teamcity-server teamcity-agent +``` + +## Configuration + +### First TeamCity configuration + +* Open [localhost:8111](http://localhost:8111) +* Log-in with empty username and the token shown in the container log file +* Go to the "Administration" section and click on "Users" to create a new user account (make sure to give the super administrative privilege) +* Authorize the agent [localhost:8111/agents](http://localhost:8111/agents.html?tab=unauthorizedAgents) +* Go to the "Projects" section and create a new project (use `https://github.com/devpro/ci-pipeline-samples` as repository URL) +* Use "Auto-detected Build Steps" to have TeamCity review what is needed (you can select everything except the NuGet and msbuild step) +* Review steps and step names and start a new build diff --git a/docs/guides/workstations/windows/windows.md b/docs/guides/workstations/windows/windows.md index f2ddc56..bb78d5e 100644 --- a/docs/guides/workstations/windows/windows.md +++ b/docs/guides/workstations/windows/windows.md @@ -1,4 +1,4 @@ -# Windows +# Windows The following instructions target **Windows 11**. For previous versions: [Windows 10](archive/windows-10.md). @@ -29,8 +29,7 @@ For previous versions: [Windows 10](archive/windows-10.md). ### Utilities -- KeePass - - Plugins: [KeeTheme](https://github.com/xatupal/KeeTheme) (dark theme) +- Password manager: 1Password, or KeePass (with [KeeTheme](https://github.com/xatupal/KeeTheme)) for example - WinDirStat ```batch @@ -48,9 +47,9 @@ For previous versions: [Windows 10](archive/windows-10.md). 1. [Visual Studio Code](../../../organizations/companies/microsoft/vscode.md) 2. Git 3. Notepad++ -4. [MongoDB Compass](https://www.mongodb.com/try/download/compass) -5. [Visual Studio 2022](../../../organizations/companies/microsoft/vs2022.md) or [Rider](https://www.jetbrains.com/rider/) -6. [WebStorm](https://www.jetbrains.com/webstorm/) +4. [MongoDB Compass](../../../organizations/companies/mongodb/compass.md) +5. [Rider](../../../organizations/companies/jetbrains/rider.md) or [Visual Studio 2026](../../../organizations/companies/microsoft/vs2026.md) +6. [WebStorm](../../../organizations/companies/jetbrains/webstorm.md) ### Office diff --git a/docs/organizations/companies/gitlab/runner-container.md b/docs/organizations/companies/gitlab/runner-container.md index e6a727f..7c168fb 100644 --- a/docs/organizations/companies/gitlab/runner-container.md +++ b/docs/organizations/companies/gitlab/runner-container.md @@ -1,4 +1,4 @@ -# GitLab Runner executed in a container +# GitLab Runner executed in a container ## Use cases @@ -13,10 +13,18 @@ Use Docker image: mkdir -p .gitlab/runner/local # displays help on a command -docker run --rm --name gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock -v $PWD/.gitlab/runner/local/config:/etc/gitlab-runner -v $PWD:$PWD --workdir $PWD gitlab/gitlab-runner exec help +docker run --rm --name gitlab-runner \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v $PWD/.gitlab/runner/local/config:/etc/gitlab-runner \ + -v $PWD:$PWD --workdir $PWD \ + gitlab/gitlab-runner exec help # executes shell on "build" job -docker run --rm --name gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock -v $PWD/.gitlab/runner/local/config:/etc/gitlab-runner -v $PWD:$PWD --workdir $PWD gitlab/gitlab-runner exec shell build +docker run --rm --name gitlab-runner \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v $PWD/.gitlab/runner/local/config:/etc/gitlab-runner \ + -v $PWD:$PWD --workdir $PWD \ + gitlab/gitlab-runner exec shell build ``` Warning: Includes are not supported unfortunately ([Issue #2797](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/2797), alternative with [firecow/gitlab-ci-local](https://github.com/firecow/gitlab-ci-local)) diff --git a/docs/organizations/companies/jetbrains/rider.md b/docs/organizations/companies/jetbrains/rider.md new file mode 100644 index 0000000..654fff8 --- /dev/null +++ b/docs/organizations/companies/jetbrains/rider.md @@ -0,0 +1,3 @@ +# Rider + +[jetbrains.com/rider](https://www.jetbrains.com/rider/) diff --git a/docs/organizations/companies/jetbrains/webstorm.md b/docs/organizations/companies/jetbrains/webstorm.md new file mode 100644 index 0000000..6d4dca2 --- /dev/null +++ b/docs/organizations/companies/jetbrains/webstorm.md @@ -0,0 +1,3 @@ +# WebStorm + +[jetbrains.com/webstorm](https://www.jetbrains.com/webstorm/) diff --git a/samples/concourse/compose.yml b/samples/concourse/compose.yml new file mode 100644 index 0000000..8e3beed --- /dev/null +++ b/samples/concourse/compose.yml @@ -0,0 +1,27 @@ +# ref. https://concourse-ci.org/docker-compose.yml +version: '3' + +services: + concourse-db: + image: postgres + environment: + POSTGRES_DB: concourse + POSTGRES_PASSWORD: concourse_pass + POSTGRES_USER: concourse_user + PGDATA: /database + + concourse: + image: concourse/concourse + command: quickstart + privileged: true + depends_on: [concourse-db] + ports: ["8080:8080"] + environment: + CONCOURSE_POSTGRES_HOST: concourse-db + CONCOURSE_POSTGRES_USER: concourse_user + CONCOURSE_POSTGRES_PASSWORD: concourse_pass + CONCOURSE_POSTGRES_DATABASE: concourse + CONCOURSE_EXTERNAL_URL: http://localhost:8080 + CONCOURSE_ADD_LOCAL_USER: test:test + CONCOURSE_MAIN_TEAM_LOCAL_USER: test + CONCOURSE_WORKER_BAGGAGECLAIM_DRIVER: overlay diff --git a/samples/concourse/pipelines/basic/01_helloworld.yml b/samples/concourse/pipelines/basic/01_helloworld.yml new file mode 100644 index 0000000..a0c6892 --- /dev/null +++ b/samples/concourse/pipelines/basic/01_helloworld.yml @@ -0,0 +1,13 @@ +jobs: + - name: job + public: true + plan: + - task: simple-task + config: + platform: linux + image_resource: + type: registry-image + source: {repository: busybox} + run: + path: echo + args: ["Hello, world!"] diff --git a/samples/concourse/pipelines/dotnet/01_aspnetcore.yml b/samples/concourse/pipelines/dotnet/01_aspnetcore.yml new file mode 100644 index 0000000..16bd339 --- /dev/null +++ b/samples/concourse/pipelines/dotnet/01_aspnetcore.yml @@ -0,0 +1,30 @@ +resources: + - name: git-repository + type: git + source: + uri: https://github.com/devpro/cf-dotnet-samples.git + branch: master +jobs: + - name: build-webapp + plan: + - get: git-repository + trigger: true + - task: run-tests + privileged: true + config: + platform: linux + inputs: + - name: git-repository + image_resource: + type: docker-image + source: + repository: microsoft/dotnet + tag: 2.2-sdk + run: + path: sh + args: + - -exc + - | + ls -alrt + cd ./git-repository/dotnetcore/2.2/webapp/ + dotnet build diff --git a/samples/concourse/pipelines/dotnet/02_globaltool.yml b/samples/concourse/pipelines/dotnet/02_globaltool.yml new file mode 100644 index 0000000..5f6103d --- /dev/null +++ b/samples/concourse/pipelines/dotnet/02_globaltool.yml @@ -0,0 +1,46 @@ +jobs: + - name: mongodb-atlas + plan: + - task: run-mdbatlas + privileged: true + config: + platform: linux + image_resource: + type: docker-image + source: + repository: mcr.microsoft.com/dotnet/core/sdk + tag: 3.1 + run: + path: sh + args: + - -exc + - | + export PATH="$PATH:/root/.dotnet/tools" + dotnet tool install --global mdbatlas + mdbatlas list orgs + params: + mdbatlas__PublicKey: ((mdbatlas-publickey)) + mdbatlas__PrivateKey: ((mdbatlas-privatekey)) + - name: azure-devops + plan: + - task: run-almops + privileged: true + config: + platform: linux + image_resource: + type: docker-image + source: + repository: mcr.microsoft.com/dotnet/core/sdk + tag: 3.1 + run: + path: sh + args: + - -exc + - | + export PATH="$PATH:/root/.dotnet/tools" + dotnet tool install --global almops + almops list projects + params: + almops__BaseUrl: ((almops-org)) + almops__Username: ((almops-user)) + almops__Token: ((almops-token)) diff --git a/samples/concourse/tasks/basic/helloworld.yml b/samples/concourse/tasks/basic/helloworld.yml new file mode 100644 index 0000000..50a85dc --- /dev/null +++ b/samples/concourse/tasks/basic/helloworld.yml @@ -0,0 +1,7 @@ +platform: linux +image_resource: + type: registry-image + source: {repository: busybox} +run: + path: echo + args: ["Hello, world!"] From d8db8f4f32af111dc71edd246253fec8bcf0d136 Mon Sep 17 00:00:00 2001 From: Bertrand THOMAS Date: Sun, 29 Mar 2026 15:57:31 +0200 Subject: [PATCH 4/7] Add content from epinio-samples repo --- .../{code-pieplines.md => code-pipelines.md} | 0 .../companies/suse/epinio-samples.md | 48 +++++++++++++++++++ 2 files changed, 48 insertions(+) rename docs/guides/learning-paths/code-pipelines/{code-pieplines.md => code-pipelines.md} (100%) create mode 100644 docs/organizations/companies/suse/epinio-samples.md diff --git a/docs/guides/learning-paths/code-pipelines/code-pieplines.md b/docs/guides/learning-paths/code-pipelines/code-pipelines.md similarity index 100% rename from docs/guides/learning-paths/code-pipelines/code-pieplines.md rename to docs/guides/learning-paths/code-pipelines/code-pipelines.md diff --git a/docs/organizations/companies/suse/epinio-samples.md b/docs/organizations/companies/suse/epinio-samples.md new file mode 100644 index 0000000..3245e2d --- /dev/null +++ b/docs/organizations/companies/suse/epinio-samples.md @@ -0,0 +1,48 @@ +# Epinio samples + +Samples of usage of [Epinio](epinio.md) to deploy workload with a command. + +## Angular + +Run the following command to deploy the Angular application: + +```bash +epinio push --name ngsample --path ngsample --env BP_WEB_SERVER=nginx --env BP_WEB_SERVER_ROOT=dist/ngsample --env BP_NODE_RUN_SCRIPTS=build --env BP_WEB_SERVER_ENABLE_PUSH_STATE=true +# NODE_ENV=development +``` + +References: + +- [paketo-buildpacks/samples/web-servers/angular-nginx-sample](https://github.com/paketo-buildpacks/samples/tree/main/web-servers/angular-nginx-sample) +- [Paketo Buildpacks > Build and Serve a Frontend Framework App](https://paketo.io/docs/howto/web-servers/#build-and-serve-a-frontend-framework-app) + +## .NET + +Run the following command to deploy an ASP.NET application: + +```bash +epinio push --name aspnetapisample --path src/WebApi --env ASPNETCORE_ENVIRONMENT=Development +``` + +For Paketo Buildpacks to be able to create artifacts that run, the file `Procfile` must be added (see [Override the Start Process Set by the Buildpack](https://paketo.io/docs/howto/dotnet-core/#override-the-start-process-set-by-the-buildpack)). + +For example `samples/dotnet/src/WebApi/Procfile`: + +```Procfile +web: dotnet EpinioDotnetSamples.WebApi.dll +``` + +## React + +Run the following command to deploy the application: + +```bash +epinio push --name reactsample --path sample-app --env BP_WEB_SERVER=nginx --env BP_WEB_SERVER_ROOT=build --env BP_NODE_RUN_SCRIPTS=build --env BP_WEB_SERVER_ENABLE_PUSH_STATE=true +``` + +References: + +- [paketo-buildpacks/samples/web-servers/react-frontend-sample](https://github.com/paketo-buildpacks/samples/tree/main/web-servers/react-frontend-sample) +- [Paketo Buildpacks > Build and Serve a Frontend Framework App](https://paketo.io/docs/howto/web-servers/#build-and-serve-a-frontend-framework-app) +- [react.dev](https://react.dev/) +- [create-react-app.dev](https://create-react-app.dev/) From 0c8a4b3d8da7954b35c16aae55f9dcac2029a41e Mon Sep 17 00:00:00 2001 From: Bertrand THOMAS Date: Sun, 29 Mar 2026 17:54:23 +0200 Subject: [PATCH 5/7] Add files from rancher-ecosystem repo --- docs/guides/workstations/ubuntu/ubuntu.md | 3 +- .../google/google-cloud/google-cloud.md | 37 +++- .../companies/google/google-cloud/skaffold.md | 5 + docs/organizations/companies/suse/alp.md | 3 - .../companies/suse/archive/hobbyfarm.md | 45 +++++ .../companies/suse/archive/hypper.md | 5 + .../companies/suse/archive/s3gw.md | 5 + docs/organizations/companies/suse/edge.md | 18 ++ .../organizations/companies/suse/elemental.md | 13 ++ docs/organizations/companies/suse/epinio.md | 94 +++++++++ docs/organizations/companies/suse/fleet.md | 113 +++++++++++ .../organizations/companies/suse/harvester.md | 9 + docs/organizations/companies/suse/k3s.md | 40 ++-- .../companies/suse/kubewarden.md | 9 + docs/organizations/companies/suse/longhorn.md | 13 +- .../organizations/companies/suse/neuvector.md | 34 ---- .../suse/neuvector/architecture-overview.png | Bin 0 -> 118081 bytes .../companies/suse/neuvector/architecture.md | 22 +++ .../companies/suse/neuvector/neuvector.md | 183 ++++++++++++++++++ docs/organizations/companies/suse/opensuse.md | 7 +- docs/organizations/companies/suse/products.md | 49 +++++ .../companies/suse/rancher-desktop.md | 4 +- docs/organizations/companies/suse/rancher.md | 40 ---- .../companies/suse/rancher/3ds-outscale.md | 180 +++++++++++++++++ .../companies/suse/rancher/applications.md | 35 ++++ .../companies/suse/rancher/architecture.md | 1 + .../companies/suse/rancher/authentication.md | 49 +++++ .../companies/suse/rancher/automation.md | 20 ++ .../rancher/cluster-provisioning-logic.svg | 1 + .../companies/suse/rancher/extensions.md | 35 ++++ .../companies/suse/rancher/gettingstarted.md | 46 +++++ .../companies/suse/rancher/installation.md | 22 +++ .../companies/suse/rancher/microsoft-azure.md | 97 ++++++++++ .../companies/suse/rancher/migrations.md | 7 + .../companies/suse/rancher/nutanix.md | 28 +++ .../companies/suse/rancher/observability.md | 13 ++ .../companies/suse/rancher/operations.md | 8 + .../companies/suse/rancher/prime.md | 3 + .../companies/suse/rancher/provisioning.md | 74 +++++++ .../suse/{ => rancher}/rancher-api.md | 0 .../{ => rancher}/rancher-docker-howto.md | 0 .../companies/suse/rancher/rancher.md | 80 ++++++++ .../companies/suse/rancher/training.md | 5 + .../companies/suse/rancher/versions.md | 114 +++++++++++ .../companies/suse/rancher/wmware-vsphere.md | 29 +++ docs/organizations/companies/suse/rke.md | 25 ++- docs/organizations/companies/suse/rke2.md | 100 +++++++++- docs/organizations/companies/suse/sles.md | 97 +++++++++- .../companies/suse/suse-glossary.md | 5 + docs/organizations/companies/suse/suse.md | 17 +- samples/azure-cli/aks-rancher-installation.sh | 108 +++++++++++ samples/azure-cli/az-rke2.sh | 49 +++++ samples/azure-cli/az-vm.sh | 50 +++++ .../aks-helloworld-applications.yaml | 136 +++++++++++++ .../manifests/gitrepo-guestbook-sample.yaml | 8 + 55 files changed, 2082 insertions(+), 111 deletions(-) create mode 100644 docs/organizations/companies/google/google-cloud/skaffold.md delete mode 100644 docs/organizations/companies/suse/alp.md create mode 100644 docs/organizations/companies/suse/archive/hobbyfarm.md create mode 100644 docs/organizations/companies/suse/archive/hypper.md create mode 100644 docs/organizations/companies/suse/archive/s3gw.md create mode 100644 docs/organizations/companies/suse/edge.md create mode 100644 docs/organizations/companies/suse/elemental.md create mode 100644 docs/organizations/companies/suse/epinio.md create mode 100644 docs/organizations/companies/suse/fleet.md create mode 100644 docs/organizations/companies/suse/harvester.md create mode 100644 docs/organizations/companies/suse/kubewarden.md delete mode 100644 docs/organizations/companies/suse/neuvector.md create mode 100644 docs/organizations/companies/suse/neuvector/architecture-overview.png create mode 100644 docs/organizations/companies/suse/neuvector/architecture.md create mode 100644 docs/organizations/companies/suse/neuvector/neuvector.md create mode 100644 docs/organizations/companies/suse/products.md delete mode 100644 docs/organizations/companies/suse/rancher.md create mode 100644 docs/organizations/companies/suse/rancher/3ds-outscale.md create mode 100644 docs/organizations/companies/suse/rancher/applications.md create mode 100644 docs/organizations/companies/suse/rancher/architecture.md create mode 100644 docs/organizations/companies/suse/rancher/authentication.md create mode 100644 docs/organizations/companies/suse/rancher/automation.md create mode 100644 docs/organizations/companies/suse/rancher/cluster-provisioning-logic.svg create mode 100644 docs/organizations/companies/suse/rancher/extensions.md create mode 100644 docs/organizations/companies/suse/rancher/gettingstarted.md create mode 100644 docs/organizations/companies/suse/rancher/installation.md create mode 100644 docs/organizations/companies/suse/rancher/microsoft-azure.md create mode 100644 docs/organizations/companies/suse/rancher/migrations.md create mode 100644 docs/organizations/companies/suse/rancher/nutanix.md create mode 100644 docs/organizations/companies/suse/rancher/observability.md create mode 100644 docs/organizations/companies/suse/rancher/operations.md create mode 100644 docs/organizations/companies/suse/rancher/prime.md create mode 100644 docs/organizations/companies/suse/rancher/provisioning.md rename docs/organizations/companies/suse/{ => rancher}/rancher-api.md (100%) rename docs/organizations/companies/suse/{ => rancher}/rancher-docker-howto.md (100%) create mode 100644 docs/organizations/companies/suse/rancher/rancher.md create mode 100644 docs/organizations/companies/suse/rancher/training.md create mode 100644 docs/organizations/companies/suse/rancher/versions.md create mode 100644 docs/organizations/companies/suse/rancher/wmware-vsphere.md create mode 100644 docs/organizations/companies/suse/suse-glossary.md create mode 100644 samples/azure-cli/aks-rancher-installation.sh create mode 100644 samples/azure-cli/az-rke2.sh create mode 100644 samples/azure-cli/az-vm.sh create mode 100644 samples/kubernetes/manifests/aks-helloworld-applications.yaml create mode 100644 samples/kubernetes/manifests/gitrepo-guestbook-sample.yaml diff --git a/docs/guides/workstations/ubuntu/ubuntu.md b/docs/guides/workstations/ubuntu/ubuntu.md index aa7b2ee..f7370c9 100644 --- a/docs/guides/workstations/ubuntu/ubuntu.md +++ b/docs/guides/workstations/ubuntu/ubuntu.md @@ -1,4 +1,4 @@ -# Ubuntu +# Ubuntu The following instructions target **Ubuntu 24.04**. For previous instructions: [Ubuntu 20.04](archive/ubuntu-20_04.md). @@ -10,6 +10,7 @@ For previous instructions: [Ubuntu 20.04](archive/ubuntu-20_04.md). ```bash sudo apt update sudo apt -y upgrade +sudo apt autoremove ``` ## Packages diff --git a/docs/organizations/companies/google/google-cloud/google-cloud.md b/docs/organizations/companies/google/google-cloud/google-cloud.md index 881f0bc..d53b05c 100644 --- a/docs/organizations/companies/google/google-cloud/google-cloud.md +++ b/docs/organizations/companies/google/google-cloud/google-cloud.md @@ -2,8 +2,43 @@ > Google Cloud offers over 150 products and services for cloud computing, data analytics, AI and machine learning, security, and more. -🌐 [cloud.google.com](https://cloud.google.com/), [console](https://console.cloud.google.com/) +🌐 [cloud.google.com](https://cloud.google.com/) + +Launched in April, 2008. ## Content * [CLI](gcloud-cli.md) + +### Quick start + +Go to [console.cloud.google.com](https://console.cloud.google.com/) to reach the web console (portal) and start your experience with GCP. + +Build your learning path from official resources: + +* [Cloud Architecture Center](https://cloud.google.com/architecture) +* [Google Cloud Skills Boost](https://www.cloudskillsboost.google/) + +Keep up-to-date with [Google Cloud Podcast](https://cloud.google.com/podcasts/gcp-podcast) + +### Concepts + +* [Marketplace](https://console.cloud.google.com/marketplace) lets you quickly deploy software on Google Cloud +* [Virtual Private Cloud (VPC)](https://cloud.google.com/vpc) is a global virtual network that spans all regions. Single VPC for an entire organization, isolated within projects. Increase IP space with no downtime. + +## Products + +Navigate the product offering with [interactive cheat sheet](https://googlecloudcheatsheet.withgoogle.com/) and [Google Cloud solutions page](https://cloud.google.com/solutions). + +### Application Life Management (ALM) + +* [Artifact Registry](https://cloud.google.com/artifact-registry) + * [Artifact Analysis](https://cloud.google.com/artifact-analysis/docs) +* [Cloud Deploy](https://cloud.google.com/deploy) + * [Skaffold](skaffold.md) + +## Google Kubernetes Engine (GKE) + +> The most scalable and fully automated Kubernetes service. + +[cloud.google.com](https://cloud.google.com/kubernetes-engine), [docs](https://cloud.google.com/kubernetes-engine/docs) diff --git a/docs/organizations/companies/google/google-cloud/skaffold.md b/docs/organizations/companies/google/google-cloud/skaffold.md new file mode 100644 index 0000000..66c3f53 --- /dev/null +++ b/docs/organizations/companies/google/google-cloud/skaffold.md @@ -0,0 +1,5 @@ +# Skaffold + +> Skaffold handles the workflow for building, pushing and deploying your application, allowing you to focus on what matters most: writing code. + +[skaffold.dev](https://skaffold.dev/), [code](https://github.com/GoogleContainerTools/skaffold), [docs](https://skaffold.dev/docs/), [cloud.google.com](https://cloud.google.com/skaffold) diff --git a/docs/organizations/companies/suse/alp.md b/docs/organizations/companies/suse/alp.md deleted file mode 100644 index c0a41b4..0000000 --- a/docs/organizations/companies/suse/alp.md +++ /dev/null @@ -1,3 +0,0 @@ -# SUSE’s Adaptable Linux Platform (ALP) - -🌐 [docs](https://documentation.suse.com/#alp) diff --git a/docs/organizations/companies/suse/archive/hobbyfarm.md b/docs/organizations/companies/suse/archive/hobbyfarm.md new file mode 100644 index 0000000..f6fa6ad --- /dev/null +++ b/docs/organizations/companies/suse/archive/hobbyfarm.md @@ -0,0 +1,45 @@ +# HobbyFarm + +> Hobbyfarm is an interactive coding platform that runs in the browser + +🌐 [hobbyfarm.github.io](https://hobbyfarm.github.io/hobbyfarm/), +[docs](https://hobbyfarm.github.io/), +[organization](https://github.com/hobbyfarm), +[issues](https://github.com/hobbyfarm/hobbyfarm/issues) + +## Software design + +### Technologies + +* Front-end: Angular +* Back-end: Go +* Documentation: Markdown +* Website: Hugo + +### Code repositories + +Name | Content +------------------------------------------------------------------------|----------------------------------------------------------------- +[admin-ui](https://github.com/hobbyfarm/admin-ui) | HobbyFarm administration UI (web application) +[ec2-operator](https://github.com/hobbyfarm/ec2-operator) | Amazon EC2 operator for HobbyFarm +[gargantua](https://github.com/hobbyfarm/gargantua) | HobbyFarm back-end (monolith application) +[hfcli](https://github.com/hobbyfarm/hfcli) | HobbyFarm Command Line Interface (CLI) +[hobbyfarm](https://github.com/hobbyfarm/hobbyfarm) | HobbyFarm Helm chart +[hobbyfarm.github.io](https://github.com/hobbyfarm/hobbyfarm.github.io) | HobbyFarm documentation/website +[ui](https://github.com/hobbyfarm/ui) | HobbyFarm UI + +### Local setup + +* Start [Gargantua](https://github.com/hobbyfarm/gargantua/blob/master/CONTRIBUTING.md) +* Start Admin UI +* TODO + +## Operations + +### Installation + +* [Documentation](https://hobbyfarm.github.io/docs/setup/installation/) + +## References + +* [Amazon EC2](https://aws.amazon.com/ec2/) diff --git a/docs/organizations/companies/suse/archive/hypper.md b/docs/organizations/companies/suse/archive/hypper.md new file mode 100644 index 0000000..d1868af --- /dev/null +++ b/docs/organizations/companies/suse/archive/hypper.md @@ -0,0 +1,5 @@ +# Hypper + +> Hypper makes it easy to install and manage cluster level applications while leveraging Helm and charts + +[hypper.io](https://hypper.io/), [code](https://github.com/rancher-sandbox/hypper) diff --git a/docs/organizations/companies/suse/archive/s3gw.md b/docs/organizations/companies/suse/archive/s3gw.md new file mode 100644 index 0000000..0259e1f --- /dev/null +++ b/docs/organizations/companies/suse/archive/s3gw.md @@ -0,0 +1,5 @@ +# s3gw + +> The s3gw project is a lightweight, open source S3 service for small deployments, and easy to deploy in a cloud native environment such as Kubernetes + +[s3gw.tech](https://s3gw.tech/), [code](https://github.com/s3gw-tech/s3gw) diff --git a/docs/organizations/companies/suse/edge.md b/docs/organizations/companies/suse/edge.md new file mode 100644 index 0000000..3c775b4 --- /dev/null +++ b/docs/organizations/companies/suse/edge.md @@ -0,0 +1,18 @@ +# SUSE Edge Computing Solutions + +> SUSE Edge solutions deliver consistency, performance, reliability, security and the highest standards of support – all of which are vitally important elements in edge computing environments. + +[suse.com/solutions/edge-computing](https://www.suse.com/solutions/edge-computing/) + +## Components + +* [Elemental](elemental.md) +* [k3s](k3s.md) +* [LongHorn](longhorn.md) +* [NeuVector](neuvector/index.md) +* [Rancher](rancher/index.md) +* [SLE micro](https://github.com/devpro/information-technology-guide/blob/main/docs/companies/suse/sle-micro.md) + +## Ecosystem + +* [Kairos](https://github.com/kairos-io/kairos) is an immutable Linux meta-distribution for edge Kubernetes diff --git a/docs/organizations/companies/suse/elemental.md b/docs/organizations/companies/suse/elemental.md new file mode 100644 index 0000000..df6f941 --- /dev/null +++ b/docs/organizations/companies/suse/elemental.md @@ -0,0 +1,13 @@ +# Elemental + +> Elemental is a software stack enabling a centralized, full cloud-native OS management with Kubernetes. + +[docs](https://elemental.docs.rancher.com/), [code](https://github.com/rancher/elemental) + +## Design + +* [Architecture](https://elemental.docs.rancher.com/architecture/) + +## Presentations + +* [Global Online Meetup: Elemental](https://www.youtube.com/watch?v=-uenjgsxI5U) - July 19, 2023 diff --git a/docs/organizations/companies/suse/epinio.md b/docs/organizations/companies/suse/epinio.md new file mode 100644 index 0000000..866f8ce --- /dev/null +++ b/docs/organizations/companies/suse/epinio.md @@ -0,0 +1,94 @@ +# Epinio + +> Tame your developer workflow to go from Code to URL in one push. + +[epinio.io](https://epinio.io/), [docs](https://docs.epinio.io/), [code](https://github.com/epinio/epinio) + +## Getting started + +### Introduction + +Epinio addresses the wish to hide all the complexity of building and deploying code. This subject was adressed before by Cloud Foundry, which got depecrated with the rise of Kubernetes. + +Epinio is Cloud Native, free, open-source, simple solution that runs in a Kubernetes cluster. Its development is lead by SUSE. + +### Quick start + +!!! tip + + Use short name for the application name (less than 22) and do not use `-` to avoid Ingress issue (see [application name restrictions](#application-name-restrictions)). + +* Make sure you have a Kubernetes cluster to work on and you are connected (by executing `kubectl config current-context` in a terminal for example) +* Follow [Epinio official quickstart](https://docs.epinio.io/tutorials/quickstart) + +### Presentations + +* Youtube videos + * [SUSECON - Customize your Developer Experience with Epinio](https://www.youtube.com/watch?v=cr4vWO9J7tk) - October 8, 2022 + * [SUSE Projects - Epinio demo: Wordpress on Digital Ocean](https://www.youtube.com/watch?v=OdPF0qH5Pf8&t=296s) - July 6, 2021 + * [Kubesimplify - Let's Learn Epinio](https://www.youtube.com/watch?v=ietNQSQXhAc) - June 23, 2021 + * [SUSECON - Epinio Demo: Building a PaaS on Kubernetes using off-the-shelf components](https://www.youtube.com/watch?v=HKXtAgh3ILw) - November 10, 2021 + +## Going further + +### Application examples + +!!! tip + + Delete local files before pushing the application if done from a developer workstation (see [local files restriction](#local-files-restriction)). + +Language/Framework | Path | Details +---------------------|-------------------------------------------------------------------------------------------------|------------------------------------------------------ +Angular (TypeScript) | [devpro/epinio-samples](https://github.com/devpro/epinio-samples/tree/main/samples/angular) | Angular Web App (Single Page Application) +.NET (C#) | [devpro/epinio-samples](https://github.com/devpro/epinio-samples/tree/main/samples/dotnet) | ASP.NET 7 Web API (REST), ASP.NET Web App (Razor) +Go | [epinio/golang-sample-app](https://github.com/epinio/epinio/tree/main/assets/golang-sample-app) | +Java | [spring-projects/spring-petclinic](https://github.com/spring-projects/spring-petclinic) | Spring +JavaScript | [ellisonleao/clumsy-bird](https://github.com/ellisonleao/clumsy-bird) | melonJS game engine +PHP | [epinio/sample-app](https://github.com/epinio/epinio/tree/main/assets/sample-app) | phpinfo +Python | [mageran/minio-epinio](https://github.com/mageran/minio-epinio/tree/main/samples/photo-album) | Flask and Boto3 for the backend and Svelte for the UI +React | [devpro/epinio-samples](https://github.com/devpro/epinio-samples/tree/main/samples/react) | React Web App (Single Page Application) +Ruby on Rails | [epinio/example-rails](https://github.com/epinio/example-rails) | +Wordpress | [epinio/example-wordpress](https://github.com/epinio/example-wordpress) | CMS written in PHP and using a MySQL database + +### CLI + +#### CLI cheat sheet + +Command | Action +-----------------------------------------------|---------------------------------------------------- +`epinio app delete sample` | Delete an application +`epinio login -u admin 'https://'` | Log in Epinio server +`epinio push --name sample --path sample-app` | Create or update an application from a local folder +`epinio settings show` | Display Epinio server information + +#### CLI examples + +```bash +# creates an application from a remote git repository on a branch +epinio push --name dotnetapisample --git-provider github --git https://github.com/devpro/epinio-samples,feature/init-solution + +# creates an application from a remote git repository +epinio push --name clumsybird --git-provider github --git https://github.com/ellisonleao/clumsy-bird +``` + +### Helm chart + +* [devpro/helm-charts](https://github.com/devpro/helm-charts/blob/main/charts/epinio/README.md) encapsulates Epinio Helm chart and provides concrete example of installation and use + +### Local cluster with K3D + +* [mesquitamv/epinio-deploy](https://github.com/mesquitamv/epinio-deploy) + +### Limitations + +#### Application name restrictions + +* **Max length**: There is an issue with Ingress if the application name is too long +(reproduced with raspnetwebrazorsample which generated a service name like raspnetwebrazorsample-40251af7269c59d923bfa391bc241c7a320d332c, of 63 characters). +* **Special characters**: Avoid special character like `-` + +### Local files restriction + +Currently, there is no way to ignore local folders and files when pushing an application. This is a serious issue while working on a codebase using NPM packages because node_modules can easily be heavy. + +This limitation is tracked by [Issue #2589](https://github.com/epinio/epinio/issues/2589). diff --git a/docs/organizations/companies/suse/fleet.md b/docs/organizations/companies/suse/fleet.md new file mode 100644 index 0000000..456f4b1 --- /dev/null +++ b/docs/organizations/companies/suse/fleet.md @@ -0,0 +1,113 @@ +# Fleet + +> Fleet is a container management and deployment engine designed to offer users more control on the local cluster and constant monitoring through GitOps + +[fleet.rancher.io](https://fleet.rancher.io/), [code](https://github.com/rancher/fleet) + +## Quick start + +### Getting to know Fleet + +* Youtube videos + * [GitOps The Planet (E4) - GitOps at Edge](https://www.youtube.com/watch?v=OPbgvBSAO9U) - January 4, 2023 + * [Using Fleet to Manage Clusters at Scale](https://www.youtube.com/watch?v=8gXbxt3AjdE&t=723s) - November 21, 2020 + +### Install Fleet objects in your Kubernetes cluster + +```bash +# sets version +FLEET_VERSION=0.3.9 + +# (optional) views objects that will be created +helm template fleet-crd https://github.com/rancher/fleet/releases/download/v${FLEET_VERSION}/fleet-crd-${FLEET_VERSION}.tgz > temp/fleet-crd.yaml +helm template -n cattle-fleet-system fleet https://github.com/rancher/fleet/releases/download/v${FLEET_VERSION}/fleet-${FLEET_VERSION}.tgz > temp/fleet.yaml + +# installs +helm -n cattle-fleet-system install --create-namespace --wait fleet-crd https://github.com/rancher/fleet/releases/download/v${FLEET_VERSION}/fleet-crd-${FLEET_VERSION}.tgz +helm -n cattle-fleet-system install --create-namespace --wait fleet https://github.com/rancher/fleet/releases/download/v${FLEET_VERSION}/fleet-${FLEET_VERSION}.tgz + +# makes sure all containers are running fine +kubectl get all -n cattle-fleet-system +``` + +### Use examples repo (or your own) to deploy your first applications + +```bash +# creates sample namespace +kubectl create namespace fleet-sample +# creates or updates the sample gitrepo +kubectl apply -f samples/gitrepo-guestbook-sample.yaml -n fleet-sample +# views fleet action +kubectl get fleet -n fleet-sample +``` + +## Configuration + +* [Git Repository Contents](https://fleet.rancher.io/gitrepo-content) + * [`fleet.yaml`](https://fleet.rancher.io/ref-fleet-yaml) + +## Samples + +* [Fleet examples](https://github.com/rancher/fleet-examples) +* [Martin Weiss](https://github.com/Martin-Weiss/rancher-fleet) +* [SUSE Exchange Paris 2023](https://github.com/devpro/helm-charts/tree/main/samples/suse-exchange-paris-2023) + +## Alternatives + +Name | Model +-----------|------ +**ArgoCD** | Push +**Fleet** | Pull +**Flux** | Pull + +## Limitations + +### Helm chart dependencies + +* tgz files in charts folder (coming from `helm dependency update`) must be added to git to be picked up by Fleet (see [issue #250](https://github.com/rancher/fleet/issues/250)) + +### Helm chart with objects on multiple namespaces + +* You may encounter the issue `Error while running post render on files: invalid cluster scoped object [name=* kind=PodSecurityPolicy apiVersion=policy/v1beta1] found, consider using "defaultNamespace", not "namespace" in fleet.yaml` + +### Modified GitRepos + +* [Generating Diffs to Ignore Modified GitRepos](https://fleet.rancher.io/bundle-diffs) + +## Troubleshoot + +### Fleet Kubernetes objects + +Kind | Name +------------------------------------------|------------------------- +bundles.fleet.cattle.io | CustomResourceDefinition +bundledeployments.fleet.cattle.io | CustomResourceDefinition +bundlenamespacemappings.fleet.cattle.io | CustomResourceDefinition +clustergroups.fleet.cattle.io | CustomResourceDefinition +clusters.fleet.cattle.io | CustomResourceDefinition +clusterregistrationtokens.fleet.cattle.io | CustomResourceDefinition +gitrepos.fleet.cattle.io | CustomResourceDefinition +clusterregistrations.fleet.cattle.io | CustomResourceDefinition +gitreporestrictions.fleet.cattle.io | CustomResourceDefinition +contents.fleet.cattle.io | CustomResourceDefinition +imagescans.fleet.cattle.io | CustomResourceDefinition +gitjobs.gitjob.cattle.io | CustomResourceDefinition +gitjob | ServiceAccount +fleet-controller | ServiceAccount +fleet-controller-bootstrap | ServiceAccount +fleet-controller | ConfigMap +gitjob | ClusterRole +fleet-controller | ClusterRole +fleet-controller-bootstrap | ClusterRole +gitjob-binding | ClusterRoleBinding +fleet-controller | ClusterRoleBinding +fleet-controller-bootstrap | ClusterRoleBinding +fleet-controller | Role +fleet-controller | RoleBinding +gitjob | Service +gitjob | Deployment +fleet-controller | Deployment + +### Git token expired + +* If you manage the GitRepo from Rancher UI and create new git credential, save twice the UI diff --git a/docs/organizations/companies/suse/harvester.md b/docs/organizations/companies/suse/harvester.md new file mode 100644 index 0000000..79de491 --- /dev/null +++ b/docs/organizations/companies/suse/harvester.md @@ -0,0 +1,9 @@ +# Harvester + +> The open source hyperconverged infrastructure (HCI) solution for a cloud native world + +[harvesterhci.io](https://harvesterhci.io/), [docs](https://docs.harvesterhci.io/), [docs](https://github.com/harvester/harvester) + +## Commercial offer + +* [Support Matrix](https://www.suse.com/suse-harvester/support-matrix/all-supported-versions/harvester-v1-7-x/) diff --git a/docs/organizations/companies/suse/k3s.md b/docs/organizations/companies/suse/k3s.md index 2ca9299..a6f6d35 100644 --- a/docs/organizations/companies/suse/k3s.md +++ b/docs/organizations/companies/suse/k3s.md @@ -1,25 +1,28 @@ -# K3s +# K3s -> K3s is a CNCF sandbox project that delivers a lightweight yet powerful certified Kubernetes distribution. When used with SUSE Rancher, K3s is ideal for running production workloads across resource-restrained, remote locations or on IoT devices. +> K3s is a CNCF sandbox project that delivers a lightweight yet powerful certified Kubernetes distribution -→ [k3s.io](https://k3s.io/), [docs](https://rancher.com/docs/k3s/latest/en/), [GitHub](https://github.com/k3s-io/k3s), +[k3s.io](https://k3s.io/), [docs](https://rancher.com/docs/k3s/latest/en/), [code](https://github.com/k3s-io/k3s), [suse.com/products/k3s](https://www.suse.com/products/k3s/) -## General idea +## Architecture ![How K3s works](https://k3s.io/img/how-it-works-k3s-revised.svg) -## Quick start - -### Install +Single binary: -### Run in a container with k3d +* [containerd](https://containerd.io/) +* [flannel](https://github.com/flannel-io/flannel) +* [CoreDNS](https://coredns.io/) +* iptables +* [SQLite](https://www.sqlite.org/) +* [klipper-lb](https://github.com/k3s-io/klipper-lb) +* [Helm](https://helm.sh/) +* [traefik](https://traefik.io/) Ingress Controller -> k3d is a lightweight wrapper to run K3s (Rancher Lab's minimal Kubernetes distribution) in Docker. - -→ [k3d.io](https://k3d.io/) ([GitHub](https://github.com/k3d-io/k3d)) +## Quick start -#### Create a cluster with k3d +[Quick-Start Guide](https://rancher.com/docs/k3s/latest/en/quick-start/) ```bash # runs installation script @@ -35,6 +38,15 @@ kubectl get nodes k3d cluster delete firstcluster ``` -### Run in a Linux system +## Knowledge + +* [Advanced Options and Configuration](https://rancher.com/docs/k3s/latest/en/advanced/) + * Auto-deploying manifests + +## Cluster API + +* [zawachte/cluster-api-k3s](https://github.com/zawachte/cluster-api-k3s) + +## Infrastructure automation (IaC) -* [Quick-Start Guide](https://rancher.com/docs/k3s/latest/en/quick-start/) +* [rlex/ansible-role-k3s](https://github.com/rlex/ansible-role-k3s) diff --git a/docs/organizations/companies/suse/kubewarden.md b/docs/organizations/companies/suse/kubewarden.md new file mode 100644 index 0000000..b5e8d5d --- /dev/null +++ b/docs/organizations/companies/suse/kubewarden.md @@ -0,0 +1,9 @@ +# Kubewarden + +> Kubewarden is a policy engine for Kubernetes. Its mission is to simplify the adoption of policy-as-code. + +[kubewarden.io](https://www.kubewarden.io/), [code](https://github.com/kubewarden) + +## Presentations + +* [Global Online Meetup](https://www.crowdcast.io/e/gomu_rancher_kubewarden_01182023/1) - February 15th, 2023 diff --git a/docs/organizations/companies/suse/longhorn.md b/docs/organizations/companies/suse/longhorn.md index 1653664..3f75cbb 100644 --- a/docs/organizations/companies/suse/longhorn.md +++ b/docs/organizations/companies/suse/longhorn.md @@ -1,4 +1,4 @@ -# Longhorn +# Longhorn > Cloud native distributed block storage for Kubernetes @@ -9,3 +9,14 @@ ### 1.6.0 [Blog annoucement](https://www.suse.com/c/rancher_blog/announcing-longhorn-1-6-0/) - February 8, 2024 + +## Features + +### Backup & restore + +* [CSI Snapshot Support](https://longhorn.io/docs/1.5.1/snapshots-and-backups/csi-snapshot-support/) + * [Container Storage Interface (CSI)](https://github.com/container-storage-interface/spec) + +## General litterature + +* [Self Hosted Kubernetes - Solving the Storage Problem](https://refaktory.net/blog/posts/self-hosted-kubernetes-solving-the-storage-problem) by Refaktory - 2022-08-09 diff --git a/docs/organizations/companies/suse/neuvector.md b/docs/organizations/companies/suse/neuvector.md deleted file mode 100644 index 2d2f8e7..0000000 --- a/docs/organizations/companies/suse/neuvector.md +++ /dev/null @@ -1,34 +0,0 @@ -# NeuVector - -## Scanner in CI pipelines - -### GitLab - -Updates from [plugin](https://gitlab.com/neuvector/gitlab-plugin) (MR are not looked at...): - -* Scan a private registry - -```yaml -# GitLab Project > Settings > CI/CD > Variables > CONTAINER_REGISTRY_USER & IMAGE_REGISTRY_PASSWORD - -include: - - remote: 'https://gitlab.com/neuvector/gitlab-plugin/-/raw/master/scan.yml' - -stages: - - scan - -neuvector_scan: - stage: scan - variables: - image_registry_url: "https://registry-1.docker.io" - image_registry_user: $CONTAINER_REGISTRY_USER - image_registry_password: $IMAGE_REGISTRY_PASSWORD - image_repo: "library/alpine" - image_tag: "3.6" - nv_registry_user: $CONTAINER_REGISTRY_USER - nv_registry_password: $IMAGE_REGISTRY_PASSWORD - scan_layers: "false" - high_vul_to_fail: 5 - medium_vul_to_fail: 9 - vul_names_to_fail: "CVE-2020-1971, CVE-2020-1972" -``` diff --git a/docs/organizations/companies/suse/neuvector/architecture-overview.png b/docs/organizations/companies/suse/neuvector/architecture-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..b02f811c8238066d63c3283a13b11011d474ea8a GIT binary patch literal 118081 zcmcG$g4XM0XK2~d&!sM?w#TP z_a*p4k8CSUj`aG!ub|Zb-@ayMip8<3q&M;2!nWv3Bgz{LFK#@iv#;9ar_INR{^ zJZ+;kX$@ue#VsC=jEW-cP7$N{_3PKCPoKWt?UM}bNfudg88&*wsQX#pKOg|h(DkRz zNR6v)>hApf{N6yZVfEv@#_jK1E7^VDzFF%Y@9yqe8GIpZyf~LI7}HN1xU{j%U^KK&_GWDfhI`}c8K+1Om? zQXIr~roSGg2IFlASgiivtq>yv5Hz`$c3 z!_6wO*k-In=cEq%g$~zl*J`PS4xf239?Xud-Gq{$?F8=mg&?vGm1=3ZonhJ^eP@=l!< zT1;-nYNO({Y)LgETr5YaZ<%W3a*S`7F82t*V4^+qh6x>=yRB+-GU<(Kef|zfE97=v zk{nF~I17C*ljqJ?oN&L$oG%Bi(RX|dIU-Hticro*?VcaqB^n%L%~OeG5Sr$JKYK;zReKT+Nv1EEYr|V%f&Xr&mh=B zO2RD7K*6D|sHPTW+-@aG7~I_{8$>1H(oW}o>Lo##e!7rsKf6{rMOAPcx));B+{;db zSwC7SZY*(IL!@|be-o#R!DBn^P7)^Qlev)WmAUX9ckEyk?)rFsI2WtZ5yRMD?QEIa zQQE;22?|g@l3UNjN7(mlPmd?$_rijW)!H3K@p7_H@2w z+u9w}u+@6~*2disrd)NlHdeU;ml2t8q3D&|QRCT8aT~SvlnOCeSYeF~Kk3@+R~uyV z?s_qben5cW=K6mQ%&3%$q^d1x2;u%>JH7o6Di#>MxXY5JikjGBiu0TI?*sW74&@`s zL6Z|Ns+z^;Hfb<4@ELdRld75tq31_7Uw<+7@mUJvy+1k9X+EQ?C7>gYV+Rk;s>KK2xr(j0(zLRam)BO;5@&L;!M!#yFJHNHS;e&>v)8hY41JI0;hdaX zJ;E6`9oH&`Gr>MIh*f9?nR;q};$OUd`?huH7c?)*y?GwZjijcFDR*ozYr|jLyvNI{ z-gh?`&#f9Itmxt*6hcIwo8Xvoq$!KqyKiB^Zqb|am)|wiPdscEVwk#>l$m<+#1kf; zT`itB48Dgmo_-JHyKyDGxo^YkCnHjiXd6dgu3<0`d#$C=_|4b z5!i#JmR1-Nj>a7OPxw?3W7FdE1X+vr?iuk?AMY*)9!z>^T�HfBxJvJ(QRcF(=U$ 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 Tnpt-MJXCIJC>AK(d-i_-6Xv@o literal 0 HcmV?d00001 diff --git a/docs/organizations/companies/suse/neuvector/architecture.md b/docs/organizations/companies/suse/neuvector/architecture.md new file mode 100644 index 0000000..f92b6ea --- /dev/null +++ b/docs/organizations/companies/suse/neuvector/architecture.md @@ -0,0 +1,22 @@ +# NeuVector Architecture + +## Overview + +![archivecture overview](neuvector-architecture-overview.png) + +Ref. [Basics > Overview](https://docs.neuvector.com/basics/overview) + +## Kubernetes objects + +* Controller + * Manage policies REST API + +* Scanner + +* Web UI + * Manager User Interface + * CLI tool + +* Enforcer (DaemonSet) + * Enforce Securities Policies + * Inspect Network Traffic diff --git a/docs/organizations/companies/suse/neuvector/neuvector.md b/docs/organizations/companies/suse/neuvector/neuvector.md new file mode 100644 index 0000000..a7f34bb --- /dev/null +++ b/docs/organizations/companies/suse/neuvector/neuvector.md @@ -0,0 +1,183 @@ +# NeuVector + +> NeuVector delivers Full Lifecycle Container Security with the only cloud-native, Kubernetes security platform providing end-to-end vulnerability management, automated CI/CD pipeline security, +> and complete run-time security including the industry’s only container firewall to protect your infrastructure from zero days and insider threats. + +[neuvector.com](https://neuvector.com/), [docs](https://docs.neuvector.com/), [code](https://github.com/neuvector/neuvector) + +## Content + +* [Architecture](architecture.md) + +## Features + +* Automated _Behavioral-Based_ Zero-Trust modes + * Discover + * Monitor + * Protect + +* Continuously watches every packet + * Layer 3 + * Layer 4 + * Layer 7 + +* Network traffic to the source of truth + +* Security-as-Code for replicating Zero-Trust Segmentation + * [neuvector.com/videos](https://neuvector.com/videos/the-neuvector-minute-security-policy-as-code/) + +* Protect data with Data Loss Prevention (DLP) + * [How to Protect Sensitive Data in Containers with Container DLP](https://blog.neuvector.com/article/protect-sensitive-data-with-container-dlp) + +* Service Mesh integration + * [How to Secure Containers in a Service Mesh such as Istio and Linkerd2](https://neuvector.com/videos/secure-containers-in-service-mesh-istio/) + +* Automation + * [REST API and Automation](https://open-docs.neuvector.com/automation/automation) + +## Trainings + +* NeuVector Rodeo + +* [NeuVector Youtube channel](https://www.youtube.com/channel/UCpAoVOdUS0i7T92cszeRVoQ) + * [NeuVector - 101 (Fall 2021)](https://www.youtube.com/watch?v=9ihaBr_QGzQ) + * [NeuVector Minute - Installing NeuVector on Rancher](https://www.youtube.com/watch?v=cc8nA7nxuDc) - Nov 12, 2020 + * [Zero-Trust Security for Kubernetes and Container Workloads](https://www.youtube.com/watch?v=SzNbJ7W3Mik) - March 29, 2022 + +## Versions + +### v5.3.0 + +* [Enhancing Network Security and Automation](https://www.suse.com/c/neuvector-releases-v-5-3-0-enhancing-network-security-and-automation/) + +### v5 + +* New scanning targets +* Zero-drift process and file protection +* Split policy mode +* Web app firewall rule detection +* CRD updates +* Enhanced Rancher Integration +* Automated promotion of group nodes + +## Installation + +### Rancher App + +* In Rancher, from your cluster, go to Apps > Charts and look for NeuVector and click on Install +* In Step 2 > Edit Options + * In Container Runtime, make sure you select the right runtime (containerd for instance with AKS) + * In Ingress Configuration, check the Manager Ingress Status box, fill Manager Ingress Host (neuvector.demo for example) +* In Step 2 > Edit YAML, edit the content to add ingressClassName + + ```bash + manager: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: HTTPS + enabled: true + host: neuvector.demo + ingressClassName: nginx + path: / + secretName: null + tls: false + ``` + +* Click on Install and review the overall installation process +* Once installed correctly (all pods running fine), go to Service Discovery > Ingresses + * In `cattle-neuvector-system` namespace, click on the target link + * Log in with admin/admin and update immediatly the password + +## Q&A + +Q: It is possible to export reports and scans in pdf and automate the creation sending them via email for example? + +A: Yes, this could be done by leveraging the API + +Q: Is it possible to customize login UI? + +A: The name can be changed but no other customization for the moment (a feature request has been created to cover this part) + +Q: Must NeuVector be installed into each working cluster or is it possible to have one central NeuVector cluster and route to it from each downstream cluster? + +A: The components such as the scanner, enforcer, etc. must be installed in each cluster but you can federate clusters together so there's a single UI to manage multiple clusters + +Q: Can we "ignore/silence" a vulnerability so it doesn't show in the reporting? + +A: You can "accept" vulnerabilities that negate them coming up in reports/alerts, reports can also filter out vulnerabilities with (for example) a low CVE score, No fix, etc. +So you could generate a list of all known CVE's in your environment, filter by no fix and then bulk accept those + +Q: How much of a performance overhead is the enforcer? + +A: This is documented in the [FAQ](https://neuvector.com/wp-content/uploads/2019/05/NeuVector-Customer-FAQ.pdf) at point 2 + +## Known issues + +* Timeout while on the web interface + * Refresh the page and authenticate again + +## Articles + +* [Enhancing Kubernetes Application Security with NeuVector](https://www.infracloud.io/blogs/secure-container-images-using-neuvector/) - September 15th, 2023 +* [FAQ](https://neuvector.com/wp-content/uploads/2019/05/NeuVector-Customer-FAQ.pdf) + +## Alternatives + +* [tetragon](https://tetragon.io/) ([playground](https://labs.iximiuz.com/playgrounds/tetragon)) + +## Recipes + +### How to scan control plane nodes + +By default, only worker nodes are scanned. You can change this by adapting the tolerations of the enforcer when installing NeuVector. +The default can be seen in [values.yaml](https://github.com/neuvector/neuvector-helm/blob/master/charts/core/values.yaml) (enforcer / tolerations). +Depending on the Kubernetes distribution, the taints may be different on non-worker nodes. + +To tolerate all possible taints, a config would be: + +```yaml +enforcer: + tolerations: + - operator: "Exists" +``` + +## Integrations + +### Harbor + +* [Installing and Configuring NeuVector Harbor Registry Adapter](https://github.com/rancher/barn/blob/main/Walkthroughs/NeuVector/Harbor%20Adapter%20Configuration/README.md) + +## Scanning + +### GitLab + +[Scan for Vulnerabilities during Gitlab Build Pipeline](https://docs.neuvector.com/scanning/build/gitlab) + +Updates from [plugin](https://gitlab.com/neuvector/gitlab-plugin) (MR are not looked at...): + +* Scan a private registry + +```yaml +# GitLab Project > Settings > CI/CD > Variables > CONTAINER_REGISTRY_USER & IMAGE_REGISTRY_PASSWORD + +include: + - remote: 'https://gitlab.com/neuvector/gitlab-plugin/-/raw/master/scan.yml' + +stages: + - scan + +neuvector_scan: + stage: scan + variables: + image_registry_url: "https://registry-1.docker.io" + image_registry_user: $CONTAINER_REGISTRY_USER + image_registry_password: $IMAGE_REGISTRY_PASSWORD + image_repo: "library/alpine" + image_tag: "3.6" + nv_registry_user: $CONTAINER_REGISTRY_USER + nv_registry_password: $IMAGE_REGISTRY_PASSWORD + scan_layers: "false" + high_vul_to_fail: 5 + medium_vul_to_fail: 9 + vul_names_to_fail: "CVE-2020-1971, CVE-2020-1972" +``` diff --git a/docs/organizations/companies/suse/opensuse.md b/docs/organizations/companies/suse/opensuse.md index cc62b28..df8844b 100644 --- a/docs/organizations/companies/suse/opensuse.md +++ b/docs/organizations/companies/suse/opensuse.md @@ -1,5 +1,8 @@ -# openSUSE +# openSUSE -[opensuse.org](https://www.opensuse.org/) +> The openSUSE distribution is a stable, easy to use and complete multi-purpose distribution. It is aimed towards users and developers working on the desktop or server. +(...) It comes with more than 1,000 open source applications. openSUSE Tumbleweed is the rolling release, providing the latest upstream software releases, yet only those packages that pass testing. + +→ [opensuse.org](https://www.opensuse.org/), [wiki](https://en.opensuse.org/Main_Page) [build.opensuse.org/project](https://build.opensuse.org/project) diff --git a/docs/organizations/companies/suse/products.md b/docs/organizations/companies/suse/products.md new file mode 100644 index 0000000..fa63676 --- /dev/null +++ b/docs/organizations/companies/suse/products.md @@ -0,0 +1,49 @@ +# Products + +All this projects are open-source and managed by SUSE. + +## Cloud Native components + +### GitOps + +- [Fleet](fleet.md) + +### Kubernetes cluster management + +- [Rancher](rancher/rancher.md) + +### Kubernetes distributions + +- [K3s](k3s.md) +- [RKE1](rke.md) +- [RKE2](rke2.md) + +### Operating system management + +- [Elemental](elemental.md) + +### Policies + +- [Kubewarden](kubewarden.md) + +### Security + +- [NeuVector](neuvector/neuvector.md) + +### Storage + +- [Longhorn](longhorn.md) + +### Virtualization + +- [Harvester](harvester.md) + +### Workstation + +- [Rancher Desktop](rancher-desktop.md) + +## Linux distributions + +- [openSUSE](opensuse.md) +- [SLE Micro](sle-micro.md) +- [SLES](sles.md) diff --git a/docs/organizations/companies/suse/rancher-desktop.md b/docs/organizations/companies/suse/rancher-desktop.md index 5379b01..3e6900c 100644 --- a/docs/organizations/companies/suse/rancher-desktop.md +++ b/docs/organizations/companies/suse/rancher-desktop.md @@ -1,4 +1,4 @@ -# Rancher Desktop +# Rancher Desktop > An open-source desktop application for Mac, Windows and Linux. Rancher Desktop runs Kubernetes and container management on your desktop. @@ -6,4 +6,4 @@ You can choose the version of Kubernetes you want to run. You can build, push, pull, and run container images using either containerd or Moby (dockerd). The container images you build can be run by Kubernetes immediately without the need for a registry. -→ [rancherdesktop.io](https://rancherdesktop.io/), [code](https://github.com/rancher-sandbox/rancher-desktop) +[rancherdesktop.io](https://rancherdesktop.io/), [code](https://github.com/rancher-sandbox/rancher-desktop) diff --git a/docs/organizations/companies/suse/rancher.md b/docs/organizations/companies/suse/rancher.md deleted file mode 100644 index d700df5..0000000 --- a/docs/organizations/companies/suse/rancher.md +++ /dev/null @@ -1,40 +0,0 @@ -# Rancher - -> Rancher is a container management platform built for organizations that deploy containers in production. Rancher makes it easy to run Kubernetes everywhere, meet IT requirements, and empower DevOps teams. - -→ [rancher.com](https://rancher.com/), [docs](https://rancher.com/docs/rancher/v2.6/en/) - -## Presentation - -![Rancher platform](https://rancher.com/docs/img/rancher/platform.png) - -## Quick start - -* [Get Started with SUSE Rancher in 2 Easy Steps](https://www.suse.com/products/suse-rancher/get-started/) -(see also [Installing Rancher on a Single Node Using Docker](https://rancher.com/docs/rancher/v2.6/en/installation/other-installation-methods/single-node-docker/)) - -```bash -# creates Rancher container -sudo docker run --privileged -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher - -# manual: open http://localhost and follow instructions to login, at the end download the kubeconfig file - -# sets kubectl to the Kubernetes cluster and displays the single node -export KUBECONFIG=local.yaml -kubectl get nodes -``` - -## Operations - -* [Rancher Upgrade Checklist](https://www.suse.com/support/kb/doc/?id=000020061) - -## Learning - -* [Rancher Manager 2.8 for Rancher Prime Operations](https://www.suse.com/training/course/ran201v2.8) -* [Rancher Manager 2.7 for Rancher Prime Deployment](https://www.suse.com/training/course/ran211v2.7) - -## Tips - -Q. Is it possible to change the rancher/shell to another image? - -A. Yes, it’s a setting in global settings. It can also be set with the environment variable on rancher CATTLE_SHELL_IMAGE=my/customshell:tag diff --git a/docs/organizations/companies/suse/rancher/3ds-outscale.md b/docs/organizations/companies/suse/rancher/3ds-outscale.md new file mode 100644 index 0000000..3b29c72 --- /dev/null +++ b/docs/organizations/companies/suse/rancher/3ds-outscale.md @@ -0,0 +1,180 @@ +# 3DS OUTSCALE + +> Founded in 2010 and a strategic partner of Dassault Systèmes, 3DS OUTSCALE is at the forefront of Cloud Computing infrastructure services (IaaS). + +:octicons-cross-reference-24: **Links:** [:material-web: outscale.com](https://outscale.com/), [:simple-github: organization](https://github.com/outscale) + +## Getting started + +A good starting point is the [User Guide](https://docs.outscale.com/userguide). + +### Account + +An _Account Key_ and a _Secret Key_ are needed to authenticate and manage the resources on OUTSCALE Cloud. + +### Management + +* [API](https://docs.outscale.com/api) ([reference](https://docs.outscale.com/en/userguide/OUTSCALE-APIs-Reference.html), [code](https://github.com/outscale/osc-api)) +* [OSC CLI](https://docs.outscale.com/en/userguide/Installing-and-Configuring-OSC-CLI.html) ([code](https://github.com/outscale/osc-cli)) +* [AWS CLI](https://docs.outscale.com/en/userguide/Installing-and-Configuring-AWS-CLI.html) +* [Cockpit (web UI)](https://cockpit.outscale.com/) ([v2 (beta)](https://new.cockpit.outscale.com/), [docs](https://docs.outscale.com/en/userguide/About-Cockpit.html)) +* [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=outscale.osc-viewer) ([code](https://github.com/outscale/vscode-osc-viewer)) + +## Recipes + +### Create a Kubernetes cluster from OSC VMs and install Rancher on it + +* Terraform: use [Rancher Quickstart](https://github.com/rancher/quickstart/blob/master/rancher/outscale/README.md) + +### Connect to a OSC VM + +* From OUTSCALE Web UI + * In "Compute" > "VMs" (Instances in cockpit V1), click on "Create" + * In "Security", add a rule to authorize SSH (port 22) from "My IP" + * Copy the public IP address, download the rsa file and log in with `ssh -i ~/.ssh/outscale_xxx.rsa -l outscale` + +### Create a Kubernetes Rancher on OCS VMs from Rancher + +* From Rancher UI + * In "Cluster Management" > "Drivers" > "Node Drivers" + * Select "Outscale" ([definition](https://github.com/rancher/rancher/blob/release/v2.7/pkg/data/management/machinedriver_data.go#L140)) and click on "Activate" + * In "Cluster Management" > "Clusters" + * In "Create" form, select "RKE2/K3s", click on "outscale" + +### RKE2 creation from Rancher UI + +* Open Rancher + * In "Cluster Management", "Drivers", "Node Drivers", enable "Outscale" + * In "Cluster Management", "Cloud Credentials", click on "Create", select "Outscale", submit and fill the informations + * In "Cluster Management", "Clusters", click on "Create", select "outscale" + * Specify the "supportOmi" (check [Official OMIs Reference](https://docs.outscale.com/en/userguide/Official-OMIs-Reference.html)) + * Set "tinav5.c3r4p1" as "instanceType" (check [Instance Types](https://docs.outscale.com/en/userguide/Instance-Types.html)) + +### RKE2 troubleshooting + +* Open Rancher + * In "Cluster Management", "Clusters", click on the cluster, in the Machine Pool line click on the menu and select "Download SSH Key" + +* Open [new.cockpit.outscale.com](https://new.cockpit.outscale.com/) + * In "Compute", "VMs", in the VM line, copy the "Public IP" value + +* Open a terminal + +```bash +# makes sure ssh files have the right permission +chmod 600 /path/to/ssh +# connects to the VM +ssh -i /path/to/ssh/id_rsa -l outscale +# example: ssh -i /mnt/c/Users/SomeUser/workspace/temp/osc-dummy01-pool1-xxxxxx-yyyy/id_rsa 1.2.3.4 -l outscale +``` + +* Investigate potential issues + +```bash +journalctl -xefu rke2-server +systemctl status rke2-server +journalctl -u rancher-system-agent.service -f + +# installs kubectl +curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" +sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl + +sudo cp /etc/rancher/rke2/rke2.yaml . +sudo chown outscale:outscale rke2.yaml +export KUBECONFIG=/home/outscale/rke2.yaml +kubectl get pods --all-namespaces +``` + +## Ressources + +### Network + +* Virtual Private Clouds +* External IPs +* Flexible Network Interfaces +* Load Balancing Unit +* VPN Connections +* DirectLink +* OUTSCALE Public IPs +* OUTSCALE NTP Servers + +Ref. [docs](https://docs.outscale.com/en/userguide/Network-and-Security.html) + +### Storage + +* [Block Storage Unit](https://docs.outscale.com/en/userguide/Block-Storage-Unit-BSU.html) +* [OUTSCALE Object Storage](https://docs.outscale.com/en/userguide/OUTSCALE-Object-Storage-OOS.html) + +### Compute + +* [Flexible Compute Unit](https://docs.outscale.com/en/userguide/Flexible-Compute-Unit-FCU.html) +* [OUTSCALE Machine Images](https://docs.outscale.com/en/userguide/OUTSCALE-Machine-Images-OMIs.html) +* [Flexible GPUs](https://docs.outscale.com/en/userguide/Flexible-GPUs-fGPUs.html) + +## Open-source projects + +### Kubernetes + +Name | Links +------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------- +[BSU CSI driver](https://github.com/outscale/osc-bsu-csi-driver) | +[Cloud Controller Manager](https://github.com/outscale/cloud-provider-osc) | +[Cluster API Provider](https://github.com/outscale/cluster-api-provider-outscale) | [Book](https://cluster-api-outscale.oos-website.eu-west-2.outscale.com/) +[Docker machine plugin](https://github.com/outscale/docker-machine-driver-outscale) | [Technical guide](https://docs.outscale.com/en/userguide/Using-DockerMachine-with-3DS-OUTSCALE.html) +[RKE provisioning example](https://github.com/outscale/osc-k8s-rke-cluster) | +[Terraform provider](https://github.com/outscale/terraform-provider-outscale) | [Docs](https://registry.terraform.io/providers/outscale/outscale/latest/docs) +[Rancher Driver UI](https://github.com/outscale/rancher-ui-driver-outscale) | + +#### Cloud Controller Manager + +* Install from Helm ([code](https://github.com/outscale/cloud-provider-osc/tree/OSC-MIGRATION/deploy/k8s-osc-ccm), [ArtifactHub](https://artifacthub.io/packages/helm/osc-cloud-controller-manager/osc-cloud-controller-manager)) + +```bash +helm install my-osc-cloud-controller-manager oci://registry-1.docker.io/outscalehelm/osc-cloud-controller-manager +``` + +* Use annotations ([examples](https://github.com/outscale/cloud-provider-osc/tree/OSC-MIGRATION/examples)) + +```yaml +# Service example +apiVersion: v1 +metadata: + annotations: + service.beta.kubernetes.io/osc-load-balancer-name-length: "20" + service.beta.kubernetes.io/osc-load-balancer-name: "simple-lb-test" +``` + +#### Container Storage Interface + +TODO + +### Cloud + +* [Frieza](https://github.com/outscale/frieza) + +## Closed-source software + +### Tina OS + +* [TINA OS Cloud Orchestrator](https://en.outscale.com/pourquoi-outscale/tina-os-cloud-orchestrator/) + +## Glossary + +Name | Meaning +-----|---------------------------- +AK | Account Key +BSU | Block Storage Unit +CAPI | Cluster API +CCM | Cloud Controller Manager +CSI | Container Storage Interface +EIP | External IP +FCU | Flexible Compute Unit +fGPU | Flexible GPU +FNI | Flexible Network Interface +GPU | Graphics Processing Units +LBU | Load Balancing Unit +OMI | OUTSCALE Machine Image +OOS | OUTSCALE Object Storage +OSC | OUTSCALE Cloud +SK | Secret Key +VPC | Virtual Private Clouds diff --git a/docs/organizations/companies/suse/rancher/applications.md b/docs/organizations/companies/suse/rancher/applications.md new file mode 100644 index 0000000..4f91f39 --- /dev/null +++ b/docs/organizations/companies/suse/rancher/applications.md @@ -0,0 +1,35 @@ +# Rancher Applications + +Available in Rancher, in the menu for a Cluster, with the "Apps" link. + +## Chart repositories + +### Indexes + +TODO: check & update with Rancher 2.8 + +```txt +https://charts.rancher.io/index.yaml +https://partner-charts.rancher.io/index.yaml +https://rke2-charts.rancher.io/index.yaml +https://rancher.github.io/elemental-operator/index.yaml +https://raw.githubusercontent.com/rancher/ui-plugin-charts/main/index.yaml +https://raw.githubusercontent.com/rancher/partner-extensions/gh-pages/index.yaml +``` + +### Official charts + +* Helm chart codebase for Rancher 2.8: [rancher/charts](https://github.com/rancher/charts/tree/release-v2.8/charts) + +* Helm chart repository for Rancher Prime: [charts.rancher.com/server-charts/prime](https://charts.rancher.com/server-charts/prime) + +* Helm CLI + +```bash +helm repo add rancher-charts https://charts.rancher.io +helm upgrade --install --namespace xxxx yyyy rancher-charts/yyyy --create-namespace +``` + +### Partner charts + +* Repository for Partner charts: [rancher/partner-charts](https://github.com/rancher/partner-charts/tree/main-source/charts) diff --git a/docs/organizations/companies/suse/rancher/architecture.md b/docs/organizations/companies/suse/rancher/architecture.md new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/docs/organizations/companies/suse/rancher/architecture.md @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/organizations/companies/suse/rancher/authentication.md b/docs/organizations/companies/suse/rancher/authentication.md new file mode 100644 index 0000000..5b4e2e4 --- /dev/null +++ b/docs/organizations/companies/suse/rancher/authentication.md @@ -0,0 +1,49 @@ +# Authentication + +## Key features + +* [Users and Groups](https://docs.ranchermanager.rancher.io/how-to-guides/new-user-guides/authentication-permissions-and-global-configuration/authentication-config/manage-users-and-groups) +* [Role-Based Access Control (RBAC)](https://docs.ranchermanager.rancher.io/pages-for-subheaders/manage-role-based-access-control-rbac) +* [Cluster and Project Roles](https://docs.ranchermanager.rancher.io/how-to-guides/new-user-guides/authentication-permissions-and-global-configuration/manage-role-based-access-control-rbac/cluster-and-project-roles) + +## Providers + +### Keycloak + +See [Get started with Keycloak on Kubernetes started](https://www.keycloak.org/getting-started/getting-started-kube) +and [Configure Keycloak (OIDC)](https://docs.ranchermanager.rancher.io/how-to-guides/new-user-guides/authentication-permissions-and-global-configuration/authentication-config/configure-keycloak-oidc) + +* Open the Keycloak admin console + * Create a Realm + + > A realm in Keycloak is the equivalent of a tenant. It allows creating isolated groups of applications and users. By default there is a single realm in Keycloak called master. This is dedicated to manage Keycloak and should not be used for your own applications. + + * Create a User and set Credentials (password) + * (Optional) Validate login on Account Console with the newly created User ("https://mydomain/realms/demo/account/#/") + + * Create a Client + * **Add Client**, Client ID to "rancher", Client Protocol to "openid-connect" + * In **Client details > Settings**, set Base URL to "https://rancherurl/", Valid Redirect URIs to "https://rancherurl/verify-auth", Access Type to confidential, activate Authorization Enabled and click on Save (so Credentials tab can be displayed) + * In **Client details > Mappers**, create the 3 Mappers (Groups Mapper, Client Audience, Group Path) + * In **Client details > Credentials**, copy client secret + + * Realm Settings > General tab, click OpenID Endpoint Configuration and copy from the JSON output will display values for issuer and authorization_endpoint + + ```json + { + "issuer":"https://keycloak.mydomain/realms/demo", + "authorization_endpoint":"https://keycloak.mydomain/realms/demo/protocol/openid-connect/auth" + // ... + } + ``` + +* Open Rancher + * Configure a Keycloak OIDC account form, change Endpoints to Specify (advanced) and override the Issuer and Auth Endpoint values + +## Integrations + +### NeuVector + +* [horantj/rancher-nv-rbac](https://github.com/horantj/rancher-nv-rbac) + * [Roles](https://vimeo.com/790515566) + * [membership](https://vimeo.com/790248342) diff --git a/docs/organizations/companies/suse/rancher/automation.md b/docs/organizations/companies/suse/rancher/automation.md new file mode 100644 index 0000000..a529f99 --- /dev/null +++ b/docs/organizations/companies/suse/rancher/automation.md @@ -0,0 +1,20 @@ +# Automation with Rancher + +## Terraform + +* [Rancher2 Provider](https://registry.terraform.io/providers/rancher/rancher2/latest/docs) ([code](https://github.com/rancher/terraform-provider-rancher2)) + +## Usecases + +### Kubernetes management cluster with Rancher + +![Cluster creation diagram](../assets/images/Provisioning_logic-Rancher_cluster_creation.svg) + +### RKE1 cluster from Rancher + +* [RKE Templates and Infrastructure > Terraform](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/authentication-permissions-and-global-configuration/about-rke1-templates/infrastructure#terraform) + +## Code examples + +* [Devpro Terraform projects](https://github.com/devpro/terraform-projects) +* [Rancher quickstarts](https://github.com/rancher/quickstart) diff --git a/docs/organizations/companies/suse/rancher/cluster-provisioning-logic.svg b/docs/organizations/companies/suse/rancher/cluster-provisioning-logic.svg new file mode 100644 index 0000000..3d0bafe --- /dev/null +++ b/docs/organizations/companies/suse/rancher/cluster-provisioning-logic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/organizations/companies/suse/rancher/extensions.md b/docs/organizations/companies/suse/rancher/extensions.md new file mode 100644 index 0000000..8f7c984 --- /dev/null +++ b/docs/organizations/companies/suse/rancher/extensions.md @@ -0,0 +1,35 @@ +# Rancher extensions + +💡 Introduced in Rancher 2.7.0 + +> Extensions allow users, developers, partners, and customers to extend and enhance the Rancher UI. In addition, users can make changes and create enhancements to their UI functionality independent of Rancher releases. +Extensions will enable users to build on top of Rancher to better tailor it to their respective environments. + +→ [ranchermanager.docs.rancher.com](https://ranchermanager.docs.rancher.com/integrations-in-rancher/rancher-extensions), [rancher.github.io/dashboard](https://rancher.github.io/dashboard/extensions/home) + +## Quick start + +* Enable Extensions in Rancher + * From the Rancher UI, from the left menu, under Configuration, click on "Extensions" + * If "Extension support is not enabled" is displayed, then click on "Enable" + * If no extensions is displayed in "Available" you may have to refresh the page + * By default, two extensions will be available: "Elemental" and "Kubewarden" + +## Available extensions + +* [Rancher UI plugins](https://github.com/rancher/ui-plugin-charts) + * [Elemental](https://github.com/rancher/elemental-ui) ([Helm chart](https://github.com/rancher/elemental-ui/tree/main/charts/elemental)) + * [Kubewarden](https://github.com/kubewarden/ui) ([Helm chart](https://github.com/kubewarden/ui/tree/main/charts/kubewarden)) +* [Rancher Partner Extensions](https://github.com/rancher/partner-extensions) (installation simplified in Rancher UI, see [PR #9260](https://github.com/rancher/dashboard/pull/9260)) + +## Samples + +* [Rancher UI Plugin examples](https://github.com/rancher/ui-plugin-examples) +* [Devpro samples](https://github.com/devpro/rancher-extensions-samples) + +## Creating an extension + +* [Getting Started](https://rancher.github.io/dashboard/extensions/extensions-getting-started) +* Node driver extension + * [example](https://github.com/rancher/ui-plugin-examples/tree/main/pkg/node-driver) + * [docs](https://rancher.github.io/dashboard/extensions/usecases/node-driver/machine-config) diff --git a/docs/organizations/companies/suse/rancher/gettingstarted.md b/docs/organizations/companies/suse/rancher/gettingstarted.md new file mode 100644 index 0000000..ce630a2 --- /dev/null +++ b/docs/organizations/companies/suse/rancher/gettingstarted.md @@ -0,0 +1,46 @@ +# Getting started with Rancher + +## Quick start + +### Run Rancher with Docker + +To have a quick look at Rancher UI, follow the procedure given at [rancher.com/quick-start](https://www.rancher.com/quick-start#getstarted-1). +More details on [Installing Rancher on a Single Node Using Docker](https://ranchermanager.docs.rancher.com/pages-for-subheaders/rancher-on-a-single-node-with-docker) documentation. + +* Open a terminal and use Docker CLI to run Rancher container + +```bash +# starts Rancher container +docker run --name local_rancher --privileged -d --restart=unless-stopped -p 3001:443 rancher/rancher +# waits few seconds to make sure Rancher is running +curl -k -L https://localhost:3001/dashboard +# gets the generated password +docker logs local_rancher 2>&1 | grep "Bootstrap Password:" +# prints the processes running in Rancher container (k3d, containerd, coredns, rancher in particular) +docker exec -it local_rancher ps -ef +``` + +* Open local [Rancher dashboard](https://localhost:3001/dashboard) + * Ignore the invalid certificate warning + * Login the password copied in the previous steps + * Set the password that you want, agree with terms and conditions and click on Continue + * You are now on Rancher home page! Here you see the list of Kubernetes clusters managed by Rancher + * Click on the `local`, which is the one running Rancher + * Explore the UI with on the left the menu to access all Kubernetes resources, on the top specific actions and the user menu + * Open a Kubectl shell and inspect the running containers + + ```bash + # inspects the running container + kubectl get pods -A + # displays the applications installed by Helm (fleet and webhooks) + helm list --all-namespaces + ``` + +* Use the terminal to clean resources + +```bash +# stops Rancher container +docker stop local_rancher +# delete Rancher container +docker rm local_rancher +``` diff --git a/docs/organizations/companies/suse/rancher/installation.md b/docs/organizations/companies/suse/rancher/installation.md new file mode 100644 index 0000000..32b94bb --- /dev/null +++ b/docs/organizations/companies/suse/rancher/installation.md @@ -0,0 +1,22 @@ +# Installation of Rancher + +## General procedures + +* [Install/Upgrade Rancher on a Kubernetes Cluster](https://docs.ranchermanager.rancher.io/pages-for-subheaders/install-upgrade-on-a-kubernetes-cluster) +* [Rancher Upgrade Checklist](https://www.suse.com/support/kb/doc/?id=000020061) +* [Rancher Upgrade FAQ](https://www.suse.com/support/kb/doc/?id=000020727) + +## Providers + +* [AKS](../providers/microsoft-azure.md#install-rancher-on-aks) +* [Outscale](../providers/3ds-outscale.md#create-a-rke2-cluster-and-install-rancher-on-it) +* [Nutanix](../providers/nutanix.md#rancher--rke-on-nutanix) +* [vSphere](../providers/wmware-vsphere.md#install-rancher-in-vsphere) + +## Known issues + +* If `cert-manager` is used, make sure `cert-manager` CRDs are applied before installing it with Helm (see [Install CustomResourceDefinitions](https://cert-manager.io/docs/installation/helm/#3-install-customresourcedefinitions)) + +## Tutorials + +* [pitch7900/Rancher-3-nodes-install](https://github.com/pitch7900/Rancher-3-nodes-install) (in French) diff --git a/docs/organizations/companies/suse/rancher/microsoft-azure.md b/docs/organizations/companies/suse/rancher/microsoft-azure.md new file mode 100644 index 0000000..879c09c --- /dev/null +++ b/docs/organizations/companies/suse/rancher/microsoft-azure.md @@ -0,0 +1,97 @@ +# Microsoft Azure + +## Getting started + +### Ressources + +Name | Type +-----------------------------------|------------------------------ +**AKS** (Azure Kubernetes Service) | Kubernetes cluster management + +### Best practices + +* [Azure resource naming convention](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming) + +![Diagram of the components of an Azure resource name](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/_images/ready/resource-naming.png) + +### Tips + +* When creating an Azure VM from Azure, the default Linux Admin username is `azureuser` + +## Usecases + +### Install Rancher on AKS + +* [Installing Rancher on AKS](https://docs.ranchermanager.rancher.io/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-aks) + * `samples/scripts/aks-rancher-installation.sh` + +### Provision AKS from Rancher + +#### Cloud credentials + +In order to authenticate and authorize actions against Azure, you need to create an Azure Active Directory (AD) application. It can be done through the web UI (portal) or the command line. + +* [Use the portal](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal). + * In `Azure Active Directory` > `App registrations`, register a new application and save the value of Tenant ID, client ID, client secret + * In `Subscription` > `IAM`, assign a Contributor role to the application and save the Subscription ID value + +Then, in Rancher add the newly created credentials. + +* Create a new Azure Cloud Credential in Rancher + +#### AKS Kubernetes cluster creation from Rancher + +* In `Cluster Management`, click on `Create` (it will the provider selection page) + * Under `Provision new nodes and create a cluster using RKE2/K3s` (make sure `RKE2/K3s` is checked), click on `Azure` (it will open the `Cluster: Create Azure` form) + * Under `Machine Pools`, click on `Show Advanced` and make sure to override all Azure ressource names + * Under `Cluster Configuration` > `Basics`, select "Azure" in `Cloud Provider` list and fill `Cloud Provider Config` field (see [Setting up the Azure Cloud Provider](https://rancher.com/docs/rancher/v2.6/en/cluster-provisioning/rke-clusters/cloud-providers/azure/)) + + ```json + { + "cloud":"AzurePublicCloud", + "tenantId": "", + "aadClientId": "", + "aadClientSecret": "", + "subscriptionId": "", + "resourceGroup": "", + "location": "", + "subnetName": "", + "securityGroupName": "", + "securityGroupResourceGroup": "", + "vnetName": "", + "vnetResourceGroup": "", + "primaryAvailabilitySetName": "", + "routeTableResourceGroup": "", + "cloudProviderBackoff": false, + "useManagedIdentityExtension": false, + "useInstanceMetadata": true + } + ``` + + * Under `Cluster Configuration` > `Advanced` > `Additional Controller Manager Args`, click `Add` and add the flag `--configure-cloud-routes=false` (see [Rancher issue #34367](https://github.com/rancher/rancher/issues/34367)) + +### Use Azure VM as Kubernetes nodes + +#### Ingress Controller in a Kubernetes cluster with Azure VM nodes + +```bash +# installs with helm (see https://kubernetes.github.io/ingress-nginx/deploy/) +helm upgrade --install ingress-nginx ingress-nginx \ + --repo https://kubernetes.github.io/ingress-nginx \ + --namespace ingress-nginx --create-namespace + +# checks NGINX Ingress Controller service (if EXTERNAL-IP gets stuck at then you need to look at the Cloud Provider configuration) +kubectl --namespace ingress-nginx get services -o wide ingress-nginx-controller +``` + +## Known issues + +### AKS cluster on a service princical with a new secret + +Once the secret used by the Cloud Credentials is revoked, we have to create another one and may prevent the AKS cluster from starting. In this case run the following command: + +```bash +az aks update-credentials --resource-group rg-xxxx --name aks-xxxx --reset-service-principal --service-principal "xxxx" --client-secret "xxxx" +``` + +See [AKS startup error “Token refresh failed with invalid client secret error”](https://blog-bertrand-thomas.devpro.fr/2023/08/22/aks-startup-error-token-refresh-failed-with-invalid-client-secret-error/) for more information. diff --git a/docs/organizations/companies/suse/rancher/migrations.md b/docs/organizations/companies/suse/rancher/migrations.md new file mode 100644 index 0000000..8537e4c --- /dev/null +++ b/docs/organizations/companies/suse/rancher/migrations.md @@ -0,0 +1,7 @@ +# Rancher migrations + +## Swarm to Kubernetes clusters managed by Rancher + +* Design Kubernetes solution + * Migrate docker-compose files to Kubernetes files + * Use tools like [Kompose](https://kompose.io/) ([code](https://github.com/kubernetes/kompose)) or [Move2Kube](https://move2kube.konveyor.io/) ([code](https://github.com/konveyor/move2kube), [tutorial](https://move2kube.konveyor.io/tutorials/migrating-from-docker-compose-to-kubernetes)) diff --git a/docs/organizations/companies/suse/rancher/nutanix.md b/docs/organizations/companies/suse/rancher/nutanix.md new file mode 100644 index 0000000..ab1e29c --- /dev/null +++ b/docs/organizations/companies/suse/rancher/nutanix.md @@ -0,0 +1,28 @@ +# Nutanix + +## Getting started + +### Rancher & RKE on Nutanix + +* [How to deploy RKE1 clusters from Rancher on Nutanix](https://www.nutanix.dev/2023/06/09/how-to-deploy-a-fleet-of-rancher-rke1-clusters-on-nutanix-the-complete-guide-part-1/) - June 9, 2023 + +## Open-Source Software + +### Kubernetes + +Name | Installation | Documentation +--------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|----------------------------------------------------------------------------- +[Cloud Controller Manager](https://github.com/nutanix-cloud-native/cloud-provider-nutanix) | | +[Custer API Provider](https://github.com/nutanix-cloud-native/cluster-api-provider-nutanix) | | [Getting Started](https://opendocs.nutanix.com/capx/latest/getting_started/) +CSI Snapshot Controller | [Helm chart](https://github.com/nutanix/helm/tree/master/charts/nutanix-csi-snapshot) | +CSI Storage Driver | [Helm chart](https://github.com/nutanix/helm/tree/master/charts/nutanix-csi-storage) | +[Docker machine](https://github.com/nutanix/docker-machine) | | +[NDB Service Operator](https://github.com/nutanix-cloud-native/ndb-operator) | [Helm chart](https://github.com/nutanix/helm/tree/master/charts/ndb-operator) | +[Rancher UI Driver](https://github.com/nutanix/rancher-ui-driver) | | + +## Glossary + +Abbreviation | Meaning +-------------|----------------------------------------------------------------------------------- +**CSI** | [Container Storage Interface](https://github.com/container-storage-interface/spec) +**NDB** | Nutanix Database diff --git a/docs/organizations/companies/suse/rancher/observability.md b/docs/organizations/companies/suse/rancher/observability.md new file mode 100644 index 0000000..37246fb --- /dev/null +++ b/docs/organizations/companies/suse/rancher/observability.md @@ -0,0 +1,13 @@ +# Observability + +## guides + +* [Monitoring](https://ranchermanager.docs.rancher.com/pages-for-subheaders/monitoring-alerting-guides) +* [Monitoring V2](https://ranchermanager.docs.rancher.com/pages-for-subheaders/monitoring-v2-configuration-guides) +* [Monitoring and Alerting](https://ranchermanager.docs.rancher.com/pages-for-subheaders/monitoring-and-alerting) +* [Logging](https://ranchermanager.docs.rancher.com/pages-for-subheaders/logging) + * [Logging Operator](https://kube-logging.dev/) ([github/kube-logging](https://github.com/kube-logging)) + +## Prometheus exporters + +* [David-VTUK/prometheus-rancher-exporter](https://github.com/David-VTUK/prometheus-rancher-exporter) diff --git a/docs/organizations/companies/suse/rancher/operations.md b/docs/organizations/companies/suse/rancher/operations.md new file mode 100644 index 0000000..47507ad --- /dev/null +++ b/docs/organizations/companies/suse/rancher/operations.md @@ -0,0 +1,8 @@ +# Rancher operations + +## Backup strategy + +* Rancher data + * [Backups and Disaster Recovery](https://ranchermanager.docs.rancher.com/pages-for-subheaders/backup-restore-and-disaster-recovery) +* Downstream clusters data + * [Kasten K10 by Veeam](https://www.suse.com/c/kasten-k10-by-veeam-and-suse-rancher-enterprise-k8s-data-protection/) diff --git a/docs/organizations/companies/suse/rancher/prime.md b/docs/organizations/companies/suse/rancher/prime.md new file mode 100644 index 0000000..1a9fa30 --- /dev/null +++ b/docs/organizations/companies/suse/rancher/prime.md @@ -0,0 +1,3 @@ +# Prime + +[Migrating to the Prime Registry](https://scc.suse.com/rancher-docs/rancherprime/latest/en/suse-rancher-prime/migrating-to-the-prime-registry.html) diff --git a/docs/organizations/companies/suse/rancher/provisioning.md b/docs/organizations/companies/suse/rancher/provisioning.md new file mode 100644 index 0000000..ec9b60d --- /dev/null +++ b/docs/organizations/companies/suse/rancher/provisioning.md @@ -0,0 +1,74 @@ +# Resource provisioning + +## General features + +* [Launching Kubernetes with Rancher](https://docs.ranchermanager.rancher.io/pages-for-subheaders/launch-kubernetes-with-rancher) +* [Cluster Management Resources](https://rancher.github.io/dashboard/code-base-works/cluster-management-resources) + +## Provisioning logic + +💡 Rancher v2.6.0 introduces V2 cluster provisioning that leverages [CAPI](https://cluster-api.sigs.k8s.io/) resources including Clusters and MachineDeployments to define and manage the desired state of downstream RKE2 and K3s clusters + +### Drivers + +From Rancher UI, drivers can be viewed and managed from **Cluster Management > Drivers page**. + +#### Cluster drivers + +Operators are used for built-in cluster drivers, for example [AKS operator](https://github.com/rancher/aks-operator), [EKS operator](https://github.com/rancher/eks-operator), [GKE operator](https://github.com/rancher/gke-operator). + +See also: [Kontainer Engine Example Driver](https://github.com/rancher-plugins/kontainer-engine-driver-example) + +#### Node drivers + +Drivers are [docker-machine](https://github.com/docker/machine) implementations for each provider, whether for RKE or RKE2/K3s. It is an API to create and delete VMs. + +Built-in node drivers are defined in [rancher/machine](https://github.com/rancher/machine/tree/master/drivers). + +Additional node drivers are added in [rancher/rancher](https://github.com/rancher/rancher/blob/release/v2.7/pkg/data/management/machinedriver_data.go#L74). + +See also: [UI DevKit > Machine Drivers](https://rancher.github.io/dashboard/code-base-works/machine-drivers) + +### Templates (V1 provisioning) + +In V1 provisioning, clusters have nodes, nodePools, and nodeTemplates. + +#### Node Templates + +Node templates make it possible to reuse machine configs for RKE1 provisioning. + +### Templates (V2 provisioning) + +In V2 provisioning, clusters have [Machines](https://cluster-api.sigs.k8s.io/user/concepts.html#machine) which are instances of MachineTemplates and have a specific configuration for each infrastructure provider. + +#### MachineTemplates + +#### Cluster templates + +> Cluster templates encompass both Kubernetes configuration and node pool configuration, allowing a single template to contain all the information Rancher needs to provision new nodes in a cloud provider +> and install Kubernetes on those nodes. (ref. [How-to Guides > New User Guides > Manage Clusters](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/manage-clusters/manage-cluster-templates)) + +Currently (August 2023) examples are only provided for RKE2. + +See also: [devpro/helm-charts](https://github.com/devpro/helm-charts/tree/main/charts/rancher-cluster-templates), [Kubernetes Master Class: Creating RKE2 Cluster Templates](https://youtu.be/xXtOP7CHbSA)). + +### Kubernetes distribution specifics + +#### RKE + +Rancher uses custom CRDs to create clusters and custom controllers that will be used with docker-machine drivers. + +Node templates are used to ease cluster creation. + +RKE1 cluster template exist but doesn't allow node pool configuration or RBAC. + +#### RKE2/K3s + +RKE2/K3s cluster creation uses [Povisioning V2](https://github.com/rancher/rancher/tree/release/v2.7/pkg/controllers/provisioningv2) + +Rancher uses the Cluster API controllers and CRDs internally. But it wraps its own Cluster and other CRDs around it to make it "easier to use" and maybe add additional features necessary for Rancher. +Rancher then bundles its own RKE2 Cluster API provider, which uses the same docker machine drivers to create and delete VMs. + +When a Cluster (provisioning.cattle.io/v1) is created, various CAPI objects are generated: RKECluster, RKEControlPlane, Cluster, RKEBootstrapTemplate, MachineDeployment and infra specific kinds like Amazonec2MachineTemplate. + +Currently (January 2023) it is not easily possible to use other Cluster API providers with Rancher. diff --git a/docs/organizations/companies/suse/rancher-api.md b/docs/organizations/companies/suse/rancher/rancher-api.md similarity index 100% rename from docs/organizations/companies/suse/rancher-api.md rename to docs/organizations/companies/suse/rancher/rancher-api.md diff --git a/docs/organizations/companies/suse/rancher-docker-howto.md b/docs/organizations/companies/suse/rancher/rancher-docker-howto.md similarity index 100% rename from docs/organizations/companies/suse/rancher-docker-howto.md rename to docs/organizations/companies/suse/rancher/rancher-docker-howto.md diff --git a/docs/organizations/companies/suse/rancher/rancher.md b/docs/organizations/companies/suse/rancher/rancher.md new file mode 100644 index 0000000..cc779f8 --- /dev/null +++ b/docs/organizations/companies/suse/rancher/rancher.md @@ -0,0 +1,80 @@ +# Rancher + +> Rancher is a container management platform built for organizations that deploy containers in production. +> Rancher makes it easy to run Kubernetes everywhere, meet IT requirements, and empower DevOps teams. + +[rancher.com](https://rancher.com/), [code](https://github.com/rancher/rancher), [docs](https://ranchermanager.docs.rancher.com) + +## Presentation + +![Rancher platform](https://rancher.com/docs/img/rancher/platform.png) + +[ranchermanager.docs.rancher.com](https://ranchermanager.docs.rancher.com/reference-guides/rancher-manager-architecture) + +## Content + +* [Applications](applications.md) +* [Architecture](architecture.md) +* [Authentication](authentication.md) +* [Automation](automation.md) +* [Extensions](extensions.md) +* [Getting started](gettingstarted.md) +* [Installation](installation.md) +* [Migrations](migrations.md) +* [Operations](operations.md) +* [Provisioning](provisioning.md) +* [Training](training.md) + +## Releases + +Version | Date | Links +--------------------------------------------------------------------|------------|-------------------------------------------------------------------- +[**2.7.5**](https://github.com/rancher/rancher/releases/tag/v2.7.6) | 2023-07-31 | [Annoucement](https://forums.rancher.com/t/rancher-release-v2-7-6/41410) +[**2.7.0**](https://github.com/rancher/rancher/releases/tag/v2.7.0) | 2022-11-16 | [Annoucement](https://forums.rancher.com/t/rancher-release-v2-7-0/39478) +[**2.6.0**](https://github.com/rancher/rancher/releases/tag/v2.6.0) | 2021-08-31 | [Annoucement](https://forums.rancher.com/t/rancher-release-v2-6-0/21048) + +[See more](versions.md) + +## Goodies + +* [Rancher Best Practices](https://www.suse.com/support/kb/doc/?id=000020105) +* [Rancher Brand Guidelines & Resources](https://www.rancher.com/brand-guidelines) +* [Rancher Forums](https://forums.rancher.com/) +* [Rancher UI DevKit](https://rancher.github.io/dashboard/) +* [Support Matrix for Rancher](https://www.suse.com/suse-rancher/support-matrix/all-supported-versions/rancher-v2-7-5/) +* Non-official: [Rancher Barn](https://github.com/rancher/barn) (recipes) + +## Alternatives + +* [Kubermatic](https://github.com/kubermatic/kubermatic) + +## Quick start + +* [Get Started with SUSE Rancher in 2 Easy Steps](https://www.suse.com/products/suse-rancher/get-started/) +(see also [Installing Rancher on a Single Node Using Docker](https://rancher.com/docs/rancher/v2.6/en/installation/other-installation-methods/single-node-docker/)) + +```bash +# creates Rancher container +sudo docker run --privileged -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher + +# manual: open http://localhost and follow instructions to login, at the end download the kubeconfig file + +# sets kubectl to the Kubernetes cluster and displays the single node +export KUBECONFIG=local.yaml +kubectl get nodes +``` + +## Operations + +* [Rancher Upgrade Checklist](https://www.suse.com/support/kb/doc/?id=000020061) + +## Learning + +* [Rancher Manager 2.8 for Rancher Prime Operations](https://www.suse.com/training/course/ran201v2.8) +* [Rancher Manager 2.7 for Rancher Prime Deployment](https://www.suse.com/training/course/ran211v2.7) + +## Tips + +Q. Is it possible to change the rancher/shell to another image? + +A. Yes, it’s a setting in global settings. It can also be set with the environment variable on rancher CATTLE_SHELL_IMAGE=my/customshell:tag diff --git a/docs/organizations/companies/suse/rancher/training.md b/docs/organizations/companies/suse/rancher/training.md new file mode 100644 index 0000000..aafc54e --- /dev/null +++ b/docs/organizations/companies/suse/rancher/training.md @@ -0,0 +1,5 @@ +# Rancher training + +## Online self-learning + +* [A Cloud Guru - Introduction to Rancher](https://learn.acloud.guru/course/introduction-to-rancher/dashboard) diff --git a/docs/organizations/companies/suse/rancher/versions.md b/docs/organizations/companies/suse/rancher/versions.md new file mode 100644 index 0000000..ed6c40a --- /dev/null +++ b/docs/organizations/companies/suse/rancher/versions.md @@ -0,0 +1,114 @@ +# Rancher versions + +## 2.8 + +### 2.8.1 + +Release date | 2024-12-31 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.8.1) +Annoucement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-8-1/42468) + +### 2.8.0 + +Release date | 2023-12-06 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.8.0) +Annoucement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-8-0/42098) + +Articles: + +* [Building a Custom Read-only Global Role with the Rancher Kubernetes API](https://www.suse.com/c/rancher_blog/building-a-custom-read-only-global-role-with-the-rancher-kubernetes-api/) - January 9, 2024 + +## 2.7 + +### 2.7.9 + +Release date | 2023-11-02 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.7.9) +Annoucement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-7-9/41872) + +### 2.7.6 + +Release date | 2023-07-31 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.7.6) +Annoucement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-7-6/41410) + +### 2.7.5 + +!!! warning + + Skip upgrading to 2.7.5 and immediately upgrade to 2.7.6. + +Release date | 2023-06-29 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.7.5) +Announcement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-7-5/40993) +Enhancements | Kubernetes v1.26 support + +### 2.7.4 (security release) + +Release date | 2023-06-01 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.7.4) +Announcement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-7-4/40836) + +### 2.7.3 (security release) + +Release date | 2023-04-24 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.7.3) +Announcement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-7-3/40521) + +### 2.7.2 + +Release date | 2023-04-12 +-------------|---------------------------------------------------------------------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.7.2) +Announcement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-7-2/40445) +New features | Rancher webhook installed in downstream clusters, Pod Security Admissions and Pod Security Standards as replacement for Pod Security Policies +Enhancements | Kubernetes v1.25 Support, RBAC for Fleet users ([Issue](https://github.com/rancher/dashboard/issues/7315) + +### 2.7.1 (security release) + +Release date | 2023-01-25 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.7.1) +Announcement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-7-1/39886) + +### 2.7.0 + +Release date | 2022-11-16 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.7.0) +Announcement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-7-0/39478) +New features | Rancher Extensions + +## 2.6 + +### 2.6.9 (bug fixes) + +Release date | 2022-10-18 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.6.9) +Announcement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-6-9/39243) + +### 2.6.0 + +Release date | 2021-08-31 +-------------|--------------------------------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.6.0) +Announcement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-6-0/21048) +New features | Support for Keycloak with OIDC +Enhancements | Redesigned Rancher User Experience (UI), Improvements for Hosted Kubernetes Clusters (AKS, EKS, and GKE) + +### 2.5 + +## 2.5.0 + +Release date | 2020-10-06 +-------------|-------------------------------------------------------------------------------- +Release note | [github.com](https://github.com/rancher/rancher/releases/tag/v2.5.0) +Announcement | [forums.rancher.com](https://forums.rancher.com/t/rancher-release-v2-5-0/18510) diff --git a/docs/organizations/companies/suse/rancher/wmware-vsphere.md b/docs/organizations/companies/suse/rancher/wmware-vsphere.md new file mode 100644 index 0000000..cd918e3 --- /dev/null +++ b/docs/organizations/companies/suse/rancher/wmware-vsphere.md @@ -0,0 +1,29 @@ +# VMware vSphere + +:octicons-light-bulb-16: **Info:** [vSphere](https://www.vmware.com/products/vsphere.html) is VMware's "Enterprise Workload Platform". +It is a virtualization platform, that includes vCenter Configuration Manager, vCenter Application Discovery Manager and vMotion. + +## Usecases + +### Install Rancher in vSphere + +* [Installing Rancher in a vSphere Environment](https://rancher.com/docs/rancher/v2.6/en/best-practices/rancher-server/rancher-in-vsphere/) + +#### Create VM template in vSphere + +* [Create a VMware vSphere template for Ubuntu Server 18.04](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/manage/hybrid/server/best-practices/vmware-ubuntu-template) +* Download Ubuntu ova from [cloud-images.ubuntu.com](https://cloud-images.ubuntu.com/focal/current/) +* Download Ubunu iso from [releases.ubuntu.com](https://releases.ubuntu.com/focal/) + +### Provision Kubernetes cluster on vSphere VMs from Rancher + +* [Creating a vSphere Cluster](https://rancher.com/docs/rancher/v2.6/en/cluster-provisioning/rke-clusters/node-pools/vsphere/) +* [Rancher, vSphere Network Protocol Profiles and static IP addresses for k8s nodes](https://www.virtualthoughts.co.uk/2020/03/29/rancher-vsphere-network-protocol-profiles-and-static-ip-addresses-for-k8s-nodes/) - March 29, 2020 +* [Using cloud-init for VM templating on vSphere](https://blah.cloud/infrastructure/using-cloud-init-for-vm-templating-on-vsphere/) - June 9, 2019 +* [frank-at-suse/vsphere_HA_autoscale_cluster](https://github.com/frank-at-suse/vsphere_HA_autoscale_cluster) + +## References + +### Storage + +* [Compatibility Matrices for vSphere Container Storage Plug-in](https://docs.vmware.com/en/VMware-vSphere-Container-Storage-Plug-in/2.0/vmware-vsphere-csp-getting-started/GUID-D4AAD99E-9128-40CE-B89C-AD451DA8379D.html) diff --git a/docs/organizations/companies/suse/rke.md b/docs/organizations/companies/suse/rke.md index f75ce56..8e6f319 100644 --- a/docs/organizations/companies/suse/rke.md +++ b/docs/organizations/companies/suse/rke.md @@ -1,9 +1,16 @@ -# Rancher Kubernetes Engine (RKE) - -> RKE is a CNCF-certified Kubernetes distribution that solves common installation complexities of Kubernetes by removing most host dependencies, presenting a stable path for deployment, upgrades & rollbacks. - -→ [suse.com/products/rancher-kubernetes-engine](https://www.suse.com/products/rancher-kubernetes-engine/), [docs](https://rancher.com/docs/rke/latest/en/) - -## Quick start - -* [RKE Kubernetes Installation](https://rancher.com/docs/rke/latest/en/installation/) +# Rancher Kubernetes Engine (RKE) + +> RKE is a CNCF-certified Kubernetes distribution that solves common installation complexities of Kubernetes by removing most host dependencies, presenting a stable path for deployment, upgrades & rollbacks. + +[suse.com/products](https://www.suse.com/products/rancher-kubernetes-engine/), [docs](https://rke.docs.rancher.com/) + +## Quick start + +* [RKE Kubernetes Installation](https://rancher.com/docs/rke/latest/en/installation/) + +## Components + +* cri-dockerd +* etcd +* NGINX Ingress Controller +* Canal diff --git a/docs/organizations/companies/suse/rke2.md b/docs/organizations/companies/suse/rke2.md index f73d889..647095e 100644 --- a/docs/organizations/companies/suse/rke2.md +++ b/docs/organizations/companies/suse/rke2.md @@ -1,6 +1,29 @@ -# RKE2 +# RKE2 -Disable CoreDNS autoscaler +> RKE2 (Rancher Kubernetes Engine v2), also known as RKE Government, is Rancher's next-generation Kubernetes distribution. It is a fully conformant Kubernetes distribution that focuses on security and compliance within the U.S. Federal Government sector. + +[docs](https://docs.rke2.io/) + +## Architecture + +![Architecture Overview](https://docs.rke2.io/assets/images/overview-06f8a098e271952bfe5db78b3a0e9b25.png) + +[ADRs](https://github.com/rancher/rke2/blob/master/docs/adrs/README.md) + +## Components + +- containerd +- etcd +- NGINX Ingress Controller +- Canal + +## Features + +- [Cluster Autoscaler for Rancher with RKE2](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler/cloudprovider/rancher) + +## Recipes + +### Disable CoreDNS autoscaler ```yaml apiVersion: helm.cattle.io/v1 @@ -13,3 +36,76 @@ spec: autoscaler: enabled: false ``` + +### Migration from RKE1 to RKE2 + +- [Issue #562](https://github.com/rancher/rke2/issues/562) +- [rancher/migration-agent](https://github.com/rancher/migration-agent) + +### Windows Clusters support + +- [Launching Kubernetes on Windows Clusters](https://docs.ranchermanager.rancher.io/pages-for-subheaders/use-windows-clusters) +- [Create a Windows HostProcess Pod](https://kubernetes.io/docs/tasks/configure-pod-container/create-hostprocess-pod/) + +## Installation + +### Ansible + +- [rancherfederal/rke2-ansible](https://github.com/rancherfederal/rke2-ansible) + +### Azure VM + +- Review VM specifications (example) + - Size: Standard_D2s_v3 (2 vcpus, 8 GiB memory) + - Operating System: Linux (Ubuntu 20.04) + - Location: West Europe + +- Create the VMs + - From the web UI + - With Azure CLI: [quick start](https://docs.microsoft.com/en-us/azure/virtual-machines/windows/quick-create-cli), [tutorial](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/tutorial-manage-vm), `samples/scripts/az-vm.sh` + - With an IaC tool, such as Azure Resource Manager or Terraform + +### RKE2 quickstart + +- Connect with SSH: `ssh @` + +- Follow the [Quick Start](https://docs.rke2.io/install/quickstart/), see the `samples/scripts/az-rke2.sh` + +- Once created and running fine, import the cluster in Rancher, execute the command line to register the cluster and make sure the agent is running fine and the cluster can be seen in Rancher + +### Cluster API + +- [Cluster API Provider RKE2](https://github.com/rancher-sandbox/cluster-api-provider-rke2) + +### Helm chart installed + +NAME | NAMESPACE | CHART | APP VERSION +--------------------|-------------|----------------------------------------------|------------ +rke2-canal | kube-system | rke2-canal-v3.22.2-build2022050902 | v3.22.2 +rke2-coredns | kube-system | rke2-coredns-1.19.400 | 1.9.3 +rke2-ingress-nginx | kube-system | rke2-ingress-nginx-4.1.004 | 1.2.0 +rke2-metrics-server | kube-system | rke2-metrics-server-2.11.100-build2021111904 | 0.5.0 + +### Processes running on a server node + +- /usr/local/bin/rke2 server +- containerd -c /var/lib/rancher/rke2/agent/etc/containerd/config.toml -a /run/k3s/containerd/containerd.sock --state /run/k3s/containerd --root /var/lib/rancher/rke2/agent/containerd +- kubelet +- /var/lib/rancher/rke2/data/v1.23.9-rke2r1-eef53a0d1ec2/bin/containerd-shim-runc-v2 -namespace k8s.io -id -address /run/k3s/containerd/containerd.sock +- kube-proxy --cluster-cidr=10.42.0.0/16 --conntrack-max-per-core=0 --conntrack-tcp-timeout-close-wait=0s --conntrack-tcp-timeout-established=0s --healthz-bind-address=127.0.0.1 --hostname-override=vm-bthomas-rke2server --kubeconfig=/var/lib/rancher/rke2/agent/kubeproxy.kubeconfig --proxy-mode=iptables +- kube-scheduler --permit-port-sharing=true --authentication-kubeconfig=/var/lib/rancher/rke2/server/cred/scheduler.kubeconfig --authorization-kubeconfig=/var/lib/rancher/rke2/server/cred/scheduler.kubeconfig --bind-address=127.0.0.1 --kubeconfig=/var/lib/rancher/rke2/server/cred/scheduler.kubeconfig --profiling=false --secure-port=10259 +- kube-apiserver +- etcd --config-file=/var/lib/rancher/rke2/server/db/etcd/config +- cloud-controller-manager +- kube-controller-manager +- /cluster-proportional-autoscaler +- /nginx-ingress-controller + +### Processes running on a worker node + +- /usr/local/bin/rke2 agent +- containerd -c /var/lib/rancher/rke2/agent/etc/containerd/config.toml -a /run/k3s/containerd/containerd.sock --state /run/k3s/containerd --root /var/lib/rancher/rke2/agent/containerd +- kubelet +- /var/lib/rancher/rke2/data/v1.23.9-rke2r1-eef53a0d1ec2/bin/containerd-shim-runc-v2 -namespace k8s.io -id -address /run/k3s/containerd/containerd.sock +- kube-proxy --cluster-cidr=10.42.0.0/16 --conntrack-max-per-core=0 --conntrack-tcp-timeout-close-wait=0s --conntrack-tcp-timeout-established=0s --healthz-bind-address=127.0.0.1 --hostname-override=vm-bthomas-rke2worker1 --kubeconfig=/var/lib/rancher/rke2/agent/kubeproxy.kubeconfig --proxy-mode=iptables +- /nginx-ingress-controller --election-id=ingress-controller-leader --controller-class=k8s.io/ingress-nginx --ingress-class=nginx --configmap=kube-system/rke2-ingress-nginx-controller --validating-webhook=:8443 --validating-webhook-certificate=/usr/local/certificates/cert --validating-webhook-key=/usr/local/certificates/key --watch-ingress-without-class=true diff --git a/docs/organizations/companies/suse/sles.md b/docs/organizations/companies/suse/sles.md index 8a4c3df..4bcc737 100644 --- a/docs/organizations/companies/suse/sles.md +++ b/docs/organizations/companies/suse/sles.md @@ -1,4 +1,4 @@ -# SUSE Linux Enterprise Server (SLES) +# SUSE Linux Enterprise Server (SLES) ## SUSE Linux Enterprise Desktop @@ -17,3 +17,98 @@ > SUSE Linux Enterprise Server (SLES) is an adaptable and easy-to-manage linux server platform that allows developers and administrators to deploy business-critical workloads on-premises, in the cloud and at the edge. → [suse.com/products/server](https://www.suse.com/products/server/) + +## Cheat sheet + +### Quickstart + +* Basic commands + +```bash +# displays system version +cat /etc/os-release + +# gets network information +ip a + +# displays date +date + +# updates date +su -c 'date -s "11 DEC 2022 21:30:00"' + +# shuts down the system +su -c 'shutdown now' +``` + +* Text editors + +```bash +# installs vi +zypper install vi +``` + +* Time Synchronization with NTP (Network Time Protocol) ([docs](https://documentation.suse.com/sles/15-SP3/html/SLES-all/cha-ntp.html)) + +```bash +# installs chrony +zypper install chrony + +# edits configuration +vi /etc/chrony.conf + +# starts and enables chrony service +systemctl start chronyd.service +systemctl enable chronyd.service +``` + +* Hostname + +```bash +# updates hostname +hostnamectl set-hostname + +# displays hostname (after logout/login) +hostname +``` + +* Static IP Address + +```bash +# edits network interface configuration +vi /etc/sysconfig/network/ifcfg-eth0 + +# restarts network service +systemctl restart network + +# displays routes configuration +more /etc/sysconfig/network/routes + +# displays name resolution configuration +more /etc/resolv.conf +``` + +* Enable SSH + +```bash +# switches to root account +su + +# installs OpenSSH +zypper install openssh + +# starts sshd service and checks status +systemctl start sshd + +# checks sshd service status +systemctl status sshd + +# enables sshd service +systemctl enable sshd + +# adds sshd service in firewall +firewall-cmd --permanent --add-service=ssh + +# reloads firewall +firewall-cmd --reload +``` diff --git a/docs/organizations/companies/suse/suse-glossary.md b/docs/organizations/companies/suse/suse-glossary.md new file mode 100644 index 0000000..d7516fd --- /dev/null +++ b/docs/organizations/companies/suse/suse-glossary.md @@ -0,0 +1,5 @@ +# Glossary + +Acronym | Meaning +--------|------------------------- +ALP | Adaptable Linux Platform diff --git a/docs/organizations/companies/suse/suse.md b/docs/organizations/companies/suse/suse.md index b5f435b..5875b36 100644 --- a/docs/organizations/companies/suse/suse.md +++ b/docs/organizations/companies/suse/suse.md @@ -1,4 +1,4 @@ -# SUSE +# SUSE 🌐 [suse.com](https://www.suse.com/) @@ -21,6 +21,16 @@ 📝 [The History of S.u.S.E. - The other enterprise Linux company](https://www.abortretry.fail/p/the-history-of-suse) - January 13, 2025 +## Areas + +* [Edge](edge.md) +* [GPUs](gpu.md) +* [Kubernetes](kubernetes/distributions.md) +* [Networking](networking.md) +* [Observability](observability.md) +* [Security](security.md) +* [Storage](storage.md) + ## Offering ### Open source @@ -52,3 +62,8 @@ ## Resources * [PINT (The Public Cloud Information Tracker)](https://pint.suse.com/) + +## Goodies + +* [Rancher Academy](https://www.rancher.academy/) +* [SUSE Technical Reference Documentation](https://documentation.suse.com/trd-supported.html) diff --git a/samples/azure-cli/aks-rancher-installation.sh b/samples/azure-cli/aks-rancher-installation.sh new file mode 100644 index 0000000..0377afb --- /dev/null +++ b/samples/azure-cli/aks-rancher-installation.sh @@ -0,0 +1,108 @@ +#!/bin/bash + +# sets parameters +AZURE_LOCATION=westeurope +CERT_MANAGER_VERSION=v1.10.0 +KUBERNETES_VERSION=v1.23.12 +NODE_COUNT=2 +RESOURCE_PREFIX=bthomas-kubemgmt01 +SUBSCRIPTION_ID=*********** +VM_SIZE=Standard_D2s_v3 + +# MANUAL: authenticates and sets account +az login +az account set --subscription $SUBSCRIPTION_ID + +# creates resource group +az group create --name rg-${RESOURCE_PREFIX} --location ${AZURE_LOCATION} + +# create AKS resource (Kubernetes cluster managed by Azure) +az aks create \ + --resource-group rg-${RESOURCE_PREFIX} \ + --name aks-${RESOURCE_PREFIX} \ + --kubernetes-version ${KUBERNETES_VERSION} \ + --node-count ${NODE_COUNT} \ + --node-vm-size ${VM_SIZE} + +# adds cluster credentials to local kubectl config +az aks get-credentials --resource-group rg-${RESOURCE_PREFIX} --name aks-${RESOURCE_PREFIX} +chmod 600 ~/.kube/config + +# makes sure Helm repo chart has been added (https://github.com/devpro/helm-charts/blob/main/README.md) +helm repo add devpro https://devpro.github.io/helm-charts +helm repo update + +# installs NGINX Ingress Controller +helm upgrade --install ingress-nginx devpro/ingress-nginx --namespace ingress-nginx --create-namespace +# MANUAL: waits until External IP is set +kubectl get service ingress-nginx-controller --namespace=ingress-nginx +# saves NGINX Ingress service public IP +NGINX_PUBLIC_IP=`kubectl get service -n ingress-nginx ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}'` + +# installs cert-manager +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.crds.yaml +helm upgrade --install cert-manager devpro/cert-manager --namespace cert-manager --create-namespace +# MANUAL: makes sure all 3 pods are running fine (cert-manager, cert-manager-cainjector, cert-manager-webhook) +kubectl get pods,clusterissuer --namespace cert-manager + +# installs Let's Encrypt cluster issuers +helm upgrade --install letsencrypt devpro/letsencrypt \ + --set registration.emailAddress=mypersonal@email.address \ + --namespace cert-manager +# MANUAL: makes sure there are 3 cluster issuers (letsencrypt-prod, letsencrypt-staging, selfsigned-cluster-issuer) +kubectl get clusterissuer + +# installs Rancher with Helm +kubectl create namespace cattle-system +helm upgrade --install rancher devpro/rancher \ + --set rancher.hostname=rancher.${NGINX_PUBLIC_IP}.sslip.io \ + --namespace cattle-system +# MANUAL: with Rancher < 2.6.7, edit the rancher ingress object to add "ingressClassName: nginx" under "spec" +# checks everything is ok +kubectl get svc,deploy,pod,ingress,pv,certificate -n cattle-system +# MANUAL: retrieves generated password +kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{ .data.bootstrapPassword|base64decode}}{{ "\n" }}' +# makes sure Rancher UI is available +curl https://rancher.${NGINX_PUBLIC_IP}.sslip.io +# MANUAL: edits Public IP address Azure resource (Configuration) to set a DNS name label, for example rancher-demo(.westeurope.cloudapp.azure.com), update the server-url in Rancher > Global Settings +kubectl edit ingress rancher -n cattle-system +# apiVersion: networking.k8s.io/v1 +# kind: Ingress +# metadata: +# spec: +# ingressClassName: nginx +# rules: +# - host: rancher-demo.westeurope.cloudapp.azure.com +# http: +# paths: +# - backend: +# service: +# name: rancher +# port: +# number: 80 +# pathType: ImplementationSpecific +# tls: +# - hosts: +# - rancher-demo.westeurope.cloudapp.azure.com +# secretName: tls-rancher-ingress +# MANUAL: opens https://rancher.${NGINX_PUBLIC_IP}.sslip.io + +# MANUAL: adds GitRepo +# apiVersion: fleet.cattle.io/v1alpha1 +# kind: GitRepo +# spec: +# branch: release/demo +# clientSecretName: gitrepo-auth-rrxgw +# insecureSkipTLSVerify: false +# paths: +# - fleet/ingress-nginx +# - fleet/cert-manager +# - fleet/sealed-secrets +# repo: https://github.com/devpro/kubernetes-demo-definitions +# targets: [] + +# OPTIONAL: removes Rancher +helm uninstall rancher --namespace cattle-system + +# cleans up +az group delete --name rg-${RESOURCE_PREFIX} --yes --no-wait diff --git a/samples/azure-cli/az-rke2.sh b/samples/azure-cli/az-rke2.sh new file mode 100644 index 0000000..2fc67c9 --- /dev/null +++ b/samples/azure-cli/az-rke2.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# checks if NetworkManager is enabled (if it is follow https://docs.rke2.io/known_issues/#networkmanager) +sudo systemctl status NetworkManager +# checks if networkd is enabled +sudo systemctl status systemd-networkd.service +# makes sure firewalld is disabled +sudo systemctl status firewalld +# makes sure AppArmor is loaded +sudo aa-status + +# installs RKE2 on the server node +curl -sfL https://get.rke2.io | sudo sh - +# enables the rke2-server service +sudo systemctl enable rke2-server.service +# starts the service +sudo systemctl start rke2-server.service +# OPTIONAL: follows the logs +sudo journalctl -u rke2-server -f +# OPTIONAL: checks Kubernetes locally +sudo cp /etc/rancher/rke2/rke2.yaml . +chown bthomas:bthomas rke2.yaml +/var/lib/rancher/rke2/bin/kubectl get nodes --kubeconfig rke2.yaml +# retrieves the node token +sudo cat /var/lib/rancher/rke2/server/node-token +# OPTIONAL: cleanup +/usr/local/bin/rke2/rke2-killall.sh +/usr/local/bin/rke2/rke2-uninstall.sh + +# installs RKE2 on the worker node +curl -sfL https://get.rke2.io | INSTALL_RKE2_TYPE="agent" sudo sh - +# enables the rke2-agent service +sudo systemctl enable rke2-agent.service +# configures the rke2-agent service +sudo mkdir -p /etc/rancher/rke2/ +sudo cat << \EOF | sudo tee /etc/rancher/rke2/config.yaml +server: https://:9345 +token: +EOF +# starts the service +sudo systemctl start rke2-agent.service +# OPTIONAL: follows the logs +sudo journalctl -u rke2-agent -f + +# the cluster is now operational and can be accessed from a remote site (just edit the local ~/.kube/config file) +kubectl get nodes + +# for self-signed certificates add insecure flag or edit kube/config file to comment certificate-authority-data line and add "insecure-skip-tls-verify: true" line under clusters/cluster +kubectl --insecure-skip-tls-verify get nodes diff --git a/samples/azure-cli/az-vm.sh b/samples/azure-cli/az-vm.sh new file mode 100644 index 0000000..7adebf5 --- /dev/null +++ b/samples/azure-cli/az-vm.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# sets parameters +AZ_LOCATION=westeurope +RG_NAME=rg-bthomas-rke2220825 +VM_NAME=vm-bthomas-rke2worker1 +VM_IMAGE="Canonical:UbuntuServer:20.04-LTS:latest" +VM_SIZE=Standard_D2_v2 +VM_ADMINUSER=azureuser +VNET_NAME=vnet-bthomas-rke220220825 + +# MANUAL: authenticates or double check account +az login +az account show + +# OPTIONAL: creates a resource group +az group create --name ${RG_NAME} --location ${AZURE_LOCATION} + +# OPTIONAL: creates a virtual network +az network vnet create \ + --resource-group ${RG_NAME} \ + --name ${VNET_NAME} \ + --address-prefix 10.0.0.0/16 + +# OPTIONAL: views an incomplete list of VM images +az vm image list + +# creates a new virtual machine (see https://docs.microsoft.com/en-us/cli/azure/vm?view=azure-cli-latest#az-vm-create) +az vm create --resource-group ${RG_NAME} --name ${VM_NAME} \ + --image ${VM_IMAGE} --size ${VM_SIZE} \ + --vnet-name ${VNET_NAME} --subnet default \ + --storage-sku StandardSSD_LRS --data-disk-delete-option Delete \ + --public-ip-sku Standard --admin-username ${VM_ADMINUSER} + +# MANUAL: copy the public IP (output as publicIpAddress) + +# OPTIONAL: views the created VM +az vm show --name ${VM_NAME} --resource-group ${RG_NAME} + +# updates the network interface +az vm update -n ${VM_NAME} -g ${RG_NAME} --set networkProfile.networkInterfaces[0].deleteOption=Delete + +# OPTIONAL: enables auto-shutdown +az vm auto-shutdown -g ${RG_NAME} -n ${VM_NAME} --time 2030 --email "bertrand.thomas@suse.com" + +# OPTIONAL: open ports +az vm open-port -g ${RG_NAME} -n ${VM_NAME} --name RKE2_ports --port 6443,9345 --priority 100 + +# OPTIONAL: connects to the VM +ssh ${VM_ADMINUSER}@${VM_PUBLICIPADDRESS} diff --git a/samples/kubernetes/manifests/aks-helloworld-applications.yaml b/samples/kubernetes/manifests/aks-helloworld-applications.yaml new file mode 100644 index 0000000..e4a9a13 --- /dev/null +++ b/samples/kubernetes/manifests/aks-helloworld-applications.yaml @@ -0,0 +1,136 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: aks-helloworld-one +spec: + replicas: 1 + selector: + matchLabels: + app: aks-helloworld-one + template: + metadata: + labels: + app: aks-helloworld-one + spec: + containers: + - name: aks-helloworld-one + image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 + ports: + - containerPort: 80 + resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "128Mi" + cpu: "500m" + env: + - name: TITLE + value: "Welcome to Azure Kubernetes Service (AKS)" +--- +apiVersion: v1 +kind: Service +metadata: + name: aks-helloworld-one +spec: + type: ClusterIP + ports: + - port: 80 + selector: + app: aks-helloworld-one +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: aks-helloworld-two +spec: + replicas: 1 + selector: + matchLabels: + app: aks-helloworld-two + template: + metadata: + labels: + app: aks-helloworld-two + spec: + containers: + - name: aks-helloworld-two + image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 + ports: + - containerPort: 80 + resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "128Mi" + cpu: "500m" + env: + - name: TITLE + value: "AKS Ingress Demo" +--- +apiVersion: v1 +kind: Service +metadata: + name: aks-helloworld-two +spec: + type: ClusterIP + ports: + - port: 80 + selector: + app: aks-helloworld-two +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: hello-world-ingress + annotations: + nginx.ingress.kubernetes.io/ssl-redirect: "false" + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + ingressClassName: nginx + rules: + - http: + paths: + - path: /hello-world-one(/|$)(.*) + pathType: Prefix + backend: + service: + name: aks-helloworld-one + port: + number: 80 + - path: /hello-world-two(/|$)(.*) + pathType: Prefix + backend: + service: + name: aks-helloworld-two + port: + number: 80 + - path: /(.*) + pathType: Prefix + backend: + service: + name: aks-helloworld-one + port: + number: 80 +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: hello-world-ingress-static + annotations: + nginx.ingress.kubernetes.io/ssl-redirect: "false" + nginx.ingress.kubernetes.io/rewrite-target: /static/$2 +spec: + ingressClassName: nginx + rules: + - http: + paths: + - path: /static(/|$)(.*) + pathType: Prefix + backend: + service: + name: aks-helloworld-one + port: + number: 80 diff --git a/samples/kubernetes/manifests/gitrepo-guestbook-sample.yaml b/samples/kubernetes/manifests/gitrepo-guestbook-sample.yaml new file mode 100644 index 0000000..44be453 --- /dev/null +++ b/samples/kubernetes/manifests/gitrepo-guestbook-sample.yaml @@ -0,0 +1,8 @@ +apiVersion: fleet.cattle.io/v1alpha1 +kind: GitRepo +metadata: + name: guestbook-sample +spec: + repo: "https://github.com/rancher/fleet-examples" + paths: + - simple From 6222e8d47d04579d0a45245f4e093a8f4af0770e Mon Sep 17 00:00:00 2001 From: Bertrand THOMAS Date: Sun, 29 Mar 2026 17:59:10 +0200 Subject: [PATCH 6/7] Fix markdown issues --- .../suse/{ => archive}/epinio-samples.md | 0 .../companies/suse/{ => archive}/epinio.md | 4 +- .../companies/suse/rancher/3ds-outscale.md | 38 ++++++------ .../companies/suse/rancher/authentication.md | 42 ++++++------- .../companies/suse/rancher/extensions.md | 18 +++--- .../companies/suse/rancher/gettingstarted.md | 30 ++++----- .../companies/suse/rancher/microsoft-azure.md | 62 +++++++++---------- .../companies/suse/rancher/migrations.md | 6 +- .../companies/suse/rancher/nutanix.md | 14 ++--- .../companies/suse/rancher/operations.md | 6 +- 10 files changed, 110 insertions(+), 110 deletions(-) rename docs/organizations/companies/suse/{ => archive}/epinio-samples.md (100%) rename docs/organizations/companies/suse/{ => archive}/epinio.md (97%) diff --git a/docs/organizations/companies/suse/epinio-samples.md b/docs/organizations/companies/suse/archive/epinio-samples.md similarity index 100% rename from docs/organizations/companies/suse/epinio-samples.md rename to docs/organizations/companies/suse/archive/epinio-samples.md diff --git a/docs/organizations/companies/suse/epinio.md b/docs/organizations/companies/suse/archive/epinio.md similarity index 97% rename from docs/organizations/companies/suse/epinio.md rename to docs/organizations/companies/suse/archive/epinio.md index 866f8ce..8d576e4 100644 --- a/docs/organizations/companies/suse/epinio.md +++ b/docs/organizations/companies/suse/archive/epinio.md @@ -41,13 +41,13 @@ Language/Framework | Path ---------------------|-------------------------------------------------------------------------------------------------|------------------------------------------------------ Angular (TypeScript) | [devpro/epinio-samples](https://github.com/devpro/epinio-samples/tree/main/samples/angular) | Angular Web App (Single Page Application) .NET (C#) | [devpro/epinio-samples](https://github.com/devpro/epinio-samples/tree/main/samples/dotnet) | ASP.NET 7 Web API (REST), ASP.NET Web App (Razor) -Go | [epinio/golang-sample-app](https://github.com/epinio/epinio/tree/main/assets/golang-sample-app) | +Go | [epinio/golang-sample-app](https://github.com/epinio/epinio/tree/main/assets/golang-sample-app) | - Java | [spring-projects/spring-petclinic](https://github.com/spring-projects/spring-petclinic) | Spring JavaScript | [ellisonleao/clumsy-bird](https://github.com/ellisonleao/clumsy-bird) | melonJS game engine PHP | [epinio/sample-app](https://github.com/epinio/epinio/tree/main/assets/sample-app) | phpinfo Python | [mageran/minio-epinio](https://github.com/mageran/minio-epinio/tree/main/samples/photo-album) | Flask and Boto3 for the backend and Svelte for the UI React | [devpro/epinio-samples](https://github.com/devpro/epinio-samples/tree/main/samples/react) | React Web App (Single Page Application) -Ruby on Rails | [epinio/example-rails](https://github.com/epinio/example-rails) | +Ruby on Rails | [epinio/example-rails](https://github.com/epinio/example-rails) | - Wordpress | [epinio/example-wordpress](https://github.com/epinio/example-wordpress) | CMS written in PHP and using a MySQL database ### CLI diff --git a/docs/organizations/companies/suse/rancher/3ds-outscale.md b/docs/organizations/companies/suse/rancher/3ds-outscale.md index 3b29c72..f4a6826 100644 --- a/docs/organizations/companies/suse/rancher/3ds-outscale.md +++ b/docs/organizations/companies/suse/rancher/3ds-outscale.md @@ -1,4 +1,4 @@ -# 3DS OUTSCALE +# 3DS OUTSCALE > Founded in 2010 and a strategic partner of Dassault Systèmes, 3DS OUTSCALE is at the forefront of Cloud Computing infrastructure services (IaaS). @@ -29,34 +29,34 @@ An _Account Key_ and a _Secret Key_ are needed to authenticate and manage the re ### Connect to a OSC VM * From OUTSCALE Web UI - * In "Compute" > "VMs" (Instances in cockpit V1), click on "Create" - * In "Security", add a rule to authorize SSH (port 22) from "My IP" - * Copy the public IP address, download the rsa file and log in with `ssh -i ~/.ssh/outscale_xxx.rsa -l outscale` + * In "Compute" > "VMs" (Instances in cockpit V1), click on "Create" + * In "Security", add a rule to authorize SSH (port 22) from "My IP" + * Copy the public IP address, download the rsa file and log in with `ssh -i ~/.ssh/outscale_xxx.rsa -l outscale` ### Create a Kubernetes Rancher on OCS VMs from Rancher * From Rancher UI - * In "Cluster Management" > "Drivers" > "Node Drivers" - * Select "Outscale" ([definition](https://github.com/rancher/rancher/blob/release/v2.7/pkg/data/management/machinedriver_data.go#L140)) and click on "Activate" - * In "Cluster Management" > "Clusters" - * In "Create" form, select "RKE2/K3s", click on "outscale" + * In "Cluster Management" > "Drivers" > "Node Drivers" + * Select "Outscale" ([definition](https://github.com/rancher/rancher/blob/release/v2.7/pkg/data/management/machinedriver_data.go#L140)) and click on "Activate" + * In "Cluster Management" > "Clusters" + * In "Create" form, select "RKE2/K3s", click on "outscale" ### RKE2 creation from Rancher UI * Open Rancher - * In "Cluster Management", "Drivers", "Node Drivers", enable "Outscale" - * In "Cluster Management", "Cloud Credentials", click on "Create", select "Outscale", submit and fill the informations - * In "Cluster Management", "Clusters", click on "Create", select "outscale" - * Specify the "supportOmi" (check [Official OMIs Reference](https://docs.outscale.com/en/userguide/Official-OMIs-Reference.html)) - * Set "tinav5.c3r4p1" as "instanceType" (check [Instance Types](https://docs.outscale.com/en/userguide/Instance-Types.html)) + * In "Cluster Management", "Drivers", "Node Drivers", enable "Outscale" + * In "Cluster Management", "Cloud Credentials", click on "Create", select "Outscale", submit and fill the informations + * In "Cluster Management", "Clusters", click on "Create", select "outscale" + * Specify the "supportOmi" (check [Official OMIs Reference](https://docs.outscale.com/en/userguide/Official-OMIs-Reference.html)) + * Set "tinav5.c3r4p1" as "instanceType" (check [Instance Types](https://docs.outscale.com/en/userguide/Instance-Types.html)) ### RKE2 troubleshooting * Open Rancher - * In "Cluster Management", "Clusters", click on the cluster, in the Machine Pool line click on the menu and select "Download SSH Key" + * In "Cluster Management", "Clusters", click on the cluster, in the Machine Pool line click on the menu and select "Download SSH Key" * Open [new.cockpit.outscale.com](https://new.cockpit.outscale.com/) - * In "Compute", "VMs", in the VM line, copy the "Public IP" value + * In "Compute", "VMs", in the VM line, copy the "Public IP" value * Open a terminal @@ -117,13 +117,13 @@ Ref. [docs](https://docs.outscale.com/en/userguide/Network-and-Security.html) Name | Links ------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------- -[BSU CSI driver](https://github.com/outscale/osc-bsu-csi-driver) | -[Cloud Controller Manager](https://github.com/outscale/cloud-provider-osc) | +[BSU CSI driver](https://github.com/outscale/osc-bsu-csi-driver) | - +[Cloud Controller Manager](https://github.com/outscale/cloud-provider-osc) | - [Cluster API Provider](https://github.com/outscale/cluster-api-provider-outscale) | [Book](https://cluster-api-outscale.oos-website.eu-west-2.outscale.com/) [Docker machine plugin](https://github.com/outscale/docker-machine-driver-outscale) | [Technical guide](https://docs.outscale.com/en/userguide/Using-DockerMachine-with-3DS-OUTSCALE.html) -[RKE provisioning example](https://github.com/outscale/osc-k8s-rke-cluster) | +[RKE provisioning example](https://github.com/outscale/osc-k8s-rke-cluster) | - [Terraform provider](https://github.com/outscale/terraform-provider-outscale) | [Docs](https://registry.terraform.io/providers/outscale/outscale/latest/docs) -[Rancher Driver UI](https://github.com/outscale/rancher-ui-driver-outscale) | +[Rancher Driver UI](https://github.com/outscale/rancher-ui-driver-outscale) | - #### Cloud Controller Manager diff --git a/docs/organizations/companies/suse/rancher/authentication.md b/docs/organizations/companies/suse/rancher/authentication.md index 5b4e2e4..a6e6fd5 100644 --- a/docs/organizations/companies/suse/rancher/authentication.md +++ b/docs/organizations/companies/suse/rancher/authentication.md @@ -1,4 +1,4 @@ -# Authentication +# Authentication ## Key features @@ -14,36 +14,36 @@ See [Get started with Keycloak on Kubernetes started](https://www.keycloak.org/g and [Configure Keycloak (OIDC)](https://docs.ranchermanager.rancher.io/how-to-guides/new-user-guides/authentication-permissions-and-global-configuration/authentication-config/configure-keycloak-oidc) * Open the Keycloak admin console - * Create a Realm + * Create a Realm - > A realm in Keycloak is the equivalent of a tenant. It allows creating isolated groups of applications and users. By default there is a single realm in Keycloak called master. This is dedicated to manage Keycloak and should not be used for your own applications. + > A realm in Keycloak is the equivalent of a tenant. It allows creating isolated groups of applications and users. By default there is a single realm in Keycloak called master. This is dedicated to manage Keycloak and should not be used for your own applications. - * Create a User and set Credentials (password) - * (Optional) Validate login on Account Console with the newly created User ("https://mydomain/realms/demo/account/#/") + * Create a User and set Credentials (password) + * (Optional) Validate login on Account Console with the newly created User (`https://mydomain/realms/demo/account/#/`) - * Create a Client - * **Add Client**, Client ID to "rancher", Client Protocol to "openid-connect" - * In **Client details > Settings**, set Base URL to "https://rancherurl/", Valid Redirect URIs to "https://rancherurl/verify-auth", Access Type to confidential, activate Authorization Enabled and click on Save (so Credentials tab can be displayed) - * In **Client details > Mappers**, create the 3 Mappers (Groups Mapper, Client Audience, Group Path) - * In **Client details > Credentials**, copy client secret + * Create a Client + * **Add Client**, Client ID to "rancher", Client Protocol to "openid-connect" + * In **Client details > Settings**, set Base URL to `https://rancherurl/`, Valid Redirect URIs to `https://rancherurl/verify-auth`, Access Type to confidential, activate Authorization Enabled and click on Save (so Credentials tab can be displayed) + * In **Client details > Mappers**, create the 3 Mappers (Groups Mapper, Client Audience, Group Path) + * In **Client details > Credentials**, copy client secret - * Realm Settings > General tab, click OpenID Endpoint Configuration and copy from the JSON output will display values for issuer and authorization_endpoint + * Realm Settings > General tab, click OpenID Endpoint Configuration and copy from the JSON output will display values for issuer and authorization_endpoint - ```json - { - "issuer":"https://keycloak.mydomain/realms/demo", - "authorization_endpoint":"https://keycloak.mydomain/realms/demo/protocol/openid-connect/auth" - // ... - } - ``` + ```json + { + "issuer":"https://keycloak.mydomain/realms/demo", + "authorization_endpoint":"https://keycloak.mydomain/realms/demo/protocol/openid-connect/auth" + // ... + } + ``` * Open Rancher - * Configure a Keycloak OIDC account form, change Endpoints to Specify (advanced) and override the Issuer and Auth Endpoint values + * Configure a Keycloak OIDC account form, change Endpoints to Specify (advanced) and override the Issuer and Auth Endpoint values ## Integrations ### NeuVector * [horantj/rancher-nv-rbac](https://github.com/horantj/rancher-nv-rbac) - * [Roles](https://vimeo.com/790515566) - * [membership](https://vimeo.com/790248342) + * [Roles](https://vimeo.com/790515566) + * [membership](https://vimeo.com/790248342) diff --git a/docs/organizations/companies/suse/rancher/extensions.md b/docs/organizations/companies/suse/rancher/extensions.md index 8f7c984..edfc96a 100644 --- a/docs/organizations/companies/suse/rancher/extensions.md +++ b/docs/organizations/companies/suse/rancher/extensions.md @@ -1,4 +1,4 @@ -# Rancher extensions +# Rancher extensions 💡 Introduced in Rancher 2.7.0 @@ -10,16 +10,16 @@ Extensions will enable users to build on top of Rancher to better tailor it to t ## Quick start * Enable Extensions in Rancher - * From the Rancher UI, from the left menu, under Configuration, click on "Extensions" - * If "Extension support is not enabled" is displayed, then click on "Enable" - * If no extensions is displayed in "Available" you may have to refresh the page - * By default, two extensions will be available: "Elemental" and "Kubewarden" + * From the Rancher UI, from the left menu, under Configuration, click on "Extensions" + * If "Extension support is not enabled" is displayed, then click on "Enable" + * If no extensions is displayed in "Available" you may have to refresh the page + * By default, two extensions will be available: "Elemental" and "Kubewarden" ## Available extensions * [Rancher UI plugins](https://github.com/rancher/ui-plugin-charts) - * [Elemental](https://github.com/rancher/elemental-ui) ([Helm chart](https://github.com/rancher/elemental-ui/tree/main/charts/elemental)) - * [Kubewarden](https://github.com/kubewarden/ui) ([Helm chart](https://github.com/kubewarden/ui/tree/main/charts/kubewarden)) + * [Elemental](https://github.com/rancher/elemental-ui) ([Helm chart](https://github.com/rancher/elemental-ui/tree/main/charts/elemental)) + * [Kubewarden](https://github.com/kubewarden/ui) ([Helm chart](https://github.com/kubewarden/ui/tree/main/charts/kubewarden)) * [Rancher Partner Extensions](https://github.com/rancher/partner-extensions) (installation simplified in Rancher UI, see [PR #9260](https://github.com/rancher/dashboard/pull/9260)) ## Samples @@ -31,5 +31,5 @@ Extensions will enable users to build on top of Rancher to better tailor it to t * [Getting Started](https://rancher.github.io/dashboard/extensions/extensions-getting-started) * Node driver extension - * [example](https://github.com/rancher/ui-plugin-examples/tree/main/pkg/node-driver) - * [docs](https://rancher.github.io/dashboard/extensions/usecases/node-driver/machine-config) + * [example](https://github.com/rancher/ui-plugin-examples/tree/main/pkg/node-driver) + * [docs](https://rancher.github.io/dashboard/extensions/usecases/node-driver/machine-config) diff --git a/docs/organizations/companies/suse/rancher/gettingstarted.md b/docs/organizations/companies/suse/rancher/gettingstarted.md index ce630a2..96b5d69 100644 --- a/docs/organizations/companies/suse/rancher/gettingstarted.md +++ b/docs/organizations/companies/suse/rancher/gettingstarted.md @@ -1,4 +1,4 @@ -# Getting started with Rancher +# Getting started with Rancher ## Quick start @@ -21,20 +21,20 @@ docker exec -it local_rancher ps -ef ``` * Open local [Rancher dashboard](https://localhost:3001/dashboard) - * Ignore the invalid certificate warning - * Login the password copied in the previous steps - * Set the password that you want, agree with terms and conditions and click on Continue - * You are now on Rancher home page! Here you see the list of Kubernetes clusters managed by Rancher - * Click on the `local`, which is the one running Rancher - * Explore the UI with on the left the menu to access all Kubernetes resources, on the top specific actions and the user menu - * Open a Kubectl shell and inspect the running containers - - ```bash - # inspects the running container - kubectl get pods -A - # displays the applications installed by Helm (fleet and webhooks) - helm list --all-namespaces - ``` + * Ignore the invalid certificate warning + * Login the password copied in the previous steps + * Set the password that you want, agree with terms and conditions and click on Continue + * You are now on Rancher home page! Here you see the list of Kubernetes clusters managed by Rancher + * Click on the `local`, which is the one running Rancher + * Explore the UI with on the left the menu to access all Kubernetes resources, on the top specific actions and the user menu + * Open a Kubectl shell and inspect the running containers + + ```bash + # inspects the running container + kubectl get pods -A + # displays the applications installed by Helm (fleet and webhooks) + helm list --all-namespaces + ``` * Use the terminal to clean resources diff --git a/docs/organizations/companies/suse/rancher/microsoft-azure.md b/docs/organizations/companies/suse/rancher/microsoft-azure.md index 879c09c..7ce42aa 100644 --- a/docs/organizations/companies/suse/rancher/microsoft-azure.md +++ b/docs/organizations/companies/suse/rancher/microsoft-azure.md @@ -1,4 +1,4 @@ -# Microsoft Azure +# Microsoft Azure ## Getting started @@ -23,7 +23,7 @@ Name | Type ### Install Rancher on AKS * [Installing Rancher on AKS](https://docs.ranchermanager.rancher.io/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster/rancher-on-aks) - * `samples/scripts/aks-rancher-installation.sh` + * `samples/scripts/aks-rancher-installation.sh` ### Provision AKS from Rancher @@ -32,8 +32,8 @@ Name | Type In order to authenticate and authorize actions against Azure, you need to create an Azure Active Directory (AD) application. It can be done through the web UI (portal) or the command line. * [Use the portal](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal). - * In `Azure Active Directory` > `App registrations`, register a new application and save the value of Tenant ID, client ID, client secret - * In `Subscription` > `IAM`, assign a Contributor role to the application and save the Subscription ID value + * In `Azure Active Directory` > `App registrations`, register a new application and save the value of Tenant ID, client ID, client secret + * In `Subscription` > `IAM`, assign a Contributor role to the application and save the Subscription ID value Then, in Rancher add the newly created credentials. @@ -42,33 +42,33 @@ Then, in Rancher add the newly created credentials. #### AKS Kubernetes cluster creation from Rancher * In `Cluster Management`, click on `Create` (it will the provider selection page) - * Under `Provision new nodes and create a cluster using RKE2/K3s` (make sure `RKE2/K3s` is checked), click on `Azure` (it will open the `Cluster: Create Azure` form) - * Under `Machine Pools`, click on `Show Advanced` and make sure to override all Azure ressource names - * Under `Cluster Configuration` > `Basics`, select "Azure" in `Cloud Provider` list and fill `Cloud Provider Config` field (see [Setting up the Azure Cloud Provider](https://rancher.com/docs/rancher/v2.6/en/cluster-provisioning/rke-clusters/cloud-providers/azure/)) - - ```json - { - "cloud":"AzurePublicCloud", - "tenantId": "", - "aadClientId": "", - "aadClientSecret": "", - "subscriptionId": "", - "resourceGroup": "", - "location": "", - "subnetName": "", - "securityGroupName": "", - "securityGroupResourceGroup": "", - "vnetName": "", - "vnetResourceGroup": "", - "primaryAvailabilitySetName": "", - "routeTableResourceGroup": "", - "cloudProviderBackoff": false, - "useManagedIdentityExtension": false, - "useInstanceMetadata": true - } - ``` - - * Under `Cluster Configuration` > `Advanced` > `Additional Controller Manager Args`, click `Add` and add the flag `--configure-cloud-routes=false` (see [Rancher issue #34367](https://github.com/rancher/rancher/issues/34367)) + * Under `Provision new nodes and create a cluster using RKE2/K3s` (make sure `RKE2/K3s` is checked), click on `Azure` (it will open the `Cluster: Create Azure` form) + * Under `Machine Pools`, click on `Show Advanced` and make sure to override all Azure ressource names + * Under `Cluster Configuration` > `Basics`, select "Azure" in `Cloud Provider` list and fill `Cloud Provider Config` field (see [Setting up the Azure Cloud Provider](https://rancher.com/docs/rancher/v2.6/en/cluster-provisioning/rke-clusters/cloud-providers/azure/)) + + ```json + { + "cloud":"AzurePublicCloud", + "tenantId": "", + "aadClientId": "", + "aadClientSecret": "", + "subscriptionId": "", + "resourceGroup": "", + "location": "", + "subnetName": "", + "securityGroupName": "", + "securityGroupResourceGroup": "", + "vnetName": "", + "vnetResourceGroup": "", + "primaryAvailabilitySetName": "", + "routeTableResourceGroup": "", + "cloudProviderBackoff": false, + "useManagedIdentityExtension": false, + "useInstanceMetadata": true + } + ``` + + * Under `Cluster Configuration` > `Advanced` > `Additional Controller Manager Args`, click `Add` and add the flag `--configure-cloud-routes=false` (see [Rancher issue #34367](https://github.com/rancher/rancher/issues/34367)) ### Use Azure VM as Kubernetes nodes diff --git a/docs/organizations/companies/suse/rancher/migrations.md b/docs/organizations/companies/suse/rancher/migrations.md index 8537e4c..3e3240b 100644 --- a/docs/organizations/companies/suse/rancher/migrations.md +++ b/docs/organizations/companies/suse/rancher/migrations.md @@ -1,7 +1,7 @@ -# Rancher migrations +# Rancher migrations ## Swarm to Kubernetes clusters managed by Rancher * Design Kubernetes solution - * Migrate docker-compose files to Kubernetes files - * Use tools like [Kompose](https://kompose.io/) ([code](https://github.com/kubernetes/kompose)) or [Move2Kube](https://move2kube.konveyor.io/) ([code](https://github.com/konveyor/move2kube), [tutorial](https://move2kube.konveyor.io/tutorials/migrating-from-docker-compose-to-kubernetes)) + * Migrate docker-compose files to Kubernetes files + * Use tools like [Kompose](https://kompose.io/) ([code](https://github.com/kubernetes/kompose)) or [Move2Kube](https://move2kube.konveyor.io/) ([code](https://github.com/konveyor/move2kube), [tutorial](https://move2kube.konveyor.io/tutorials/migrating-from-docker-compose-to-kubernetes)) diff --git a/docs/organizations/companies/suse/rancher/nutanix.md b/docs/organizations/companies/suse/rancher/nutanix.md index ab1e29c..ea5e8c5 100644 --- a/docs/organizations/companies/suse/rancher/nutanix.md +++ b/docs/organizations/companies/suse/rancher/nutanix.md @@ -1,4 +1,4 @@ -# Nutanix +# Nutanix ## Getting started @@ -12,13 +12,13 @@ Name | Installation | Documentation --------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|----------------------------------------------------------------------------- -[Cloud Controller Manager](https://github.com/nutanix-cloud-native/cloud-provider-nutanix) | | +[Cloud Controller Manager](https://github.com/nutanix-cloud-native/cloud-provider-nutanix) | | - [Custer API Provider](https://github.com/nutanix-cloud-native/cluster-api-provider-nutanix) | | [Getting Started](https://opendocs.nutanix.com/capx/latest/getting_started/) -CSI Snapshot Controller | [Helm chart](https://github.com/nutanix/helm/tree/master/charts/nutanix-csi-snapshot) | -CSI Storage Driver | [Helm chart](https://github.com/nutanix/helm/tree/master/charts/nutanix-csi-storage) | -[Docker machine](https://github.com/nutanix/docker-machine) | | -[NDB Service Operator](https://github.com/nutanix-cloud-native/ndb-operator) | [Helm chart](https://github.com/nutanix/helm/tree/master/charts/ndb-operator) | -[Rancher UI Driver](https://github.com/nutanix/rancher-ui-driver) | | +CSI Snapshot Controller | [Helm chart](https://github.com/nutanix/helm/tree/master/charts/nutanix-csi-snapshot) | - +CSI Storage Driver | [Helm chart](https://github.com/nutanix/helm/tree/master/charts/nutanix-csi-storage) | - +[Docker machine](https://github.com/nutanix/docker-machine) | | - +[NDB Service Operator](https://github.com/nutanix-cloud-native/ndb-operator) | [Helm chart](https://github.com/nutanix/helm/tree/master/charts/ndb-operator) | - +[Rancher UI Driver](https://github.com/nutanix/rancher-ui-driver) | | - ## Glossary diff --git a/docs/organizations/companies/suse/rancher/operations.md b/docs/organizations/companies/suse/rancher/operations.md index 47507ad..8a2f1f1 100644 --- a/docs/organizations/companies/suse/rancher/operations.md +++ b/docs/organizations/companies/suse/rancher/operations.md @@ -1,8 +1,8 @@ -# Rancher operations +# Rancher operations ## Backup strategy * Rancher data - * [Backups and Disaster Recovery](https://ranchermanager.docs.rancher.com/pages-for-subheaders/backup-restore-and-disaster-recovery) + * [Backups and Disaster Recovery](https://ranchermanager.docs.rancher.com/pages-for-subheaders/backup-restore-and-disaster-recovery) * Downstream clusters data - * [Kasten K10 by Veeam](https://www.suse.com/c/kasten-k10-by-veeam-and-suse-rancher-enterprise-k8s-data-protection/) + * [Kasten K10 by Veeam](https://www.suse.com/c/kasten-k10-by-veeam-and-suse-rancher-enterprise-k8s-data-protection/) From 18a79c08c2382bab4622a01861101832e7b65131 Mon Sep 17 00:00:00 2001 From: Bertrand THOMAS Date: Sun, 29 Mar 2026 19:52:15 +0200 Subject: [PATCH 7/7] Fix site build issues --- docs/organizations/companies/suse/edge.md | 18 --------- .../companies/suse/neuvector/architecture.md | 2 +- .../companies/suse/rancher/automation.md | 40 +++++++++---------- .../companies/suse/rancher/installation.md | 10 ++--- docs/organizations/companies/suse/rke2.md | 4 +- docs/organizations/companies/suse/suse.md | 14 +------ 6 files changed, 30 insertions(+), 58 deletions(-) delete mode 100644 docs/organizations/companies/suse/edge.md diff --git a/docs/organizations/companies/suse/edge.md b/docs/organizations/companies/suse/edge.md deleted file mode 100644 index 3c775b4..0000000 --- a/docs/organizations/companies/suse/edge.md +++ /dev/null @@ -1,18 +0,0 @@ -# SUSE Edge Computing Solutions - -> SUSE Edge solutions deliver consistency, performance, reliability, security and the highest standards of support – all of which are vitally important elements in edge computing environments. - -[suse.com/solutions/edge-computing](https://www.suse.com/solutions/edge-computing/) - -## Components - -* [Elemental](elemental.md) -* [k3s](k3s.md) -* [LongHorn](longhorn.md) -* [NeuVector](neuvector/index.md) -* [Rancher](rancher/index.md) -* [SLE micro](https://github.com/devpro/information-technology-guide/blob/main/docs/companies/suse/sle-micro.md) - -## Ecosystem - -* [Kairos](https://github.com/kairos-io/kairos) is an immutable Linux meta-distribution for edge Kubernetes diff --git a/docs/organizations/companies/suse/neuvector/architecture.md b/docs/organizations/companies/suse/neuvector/architecture.md index f92b6ea..eac92f5 100644 --- a/docs/organizations/companies/suse/neuvector/architecture.md +++ b/docs/organizations/companies/suse/neuvector/architecture.md @@ -2,7 +2,7 @@ ## Overview -![archivecture overview](neuvector-architecture-overview.png) +![archivecture overview](architecture-overview.png) Ref. [Basics > Overview](https://docs.neuvector.com/basics/overview) diff --git a/docs/organizations/companies/suse/rancher/automation.md b/docs/organizations/companies/suse/rancher/automation.md index a529f99..fec6f66 100644 --- a/docs/organizations/companies/suse/rancher/automation.md +++ b/docs/organizations/companies/suse/rancher/automation.md @@ -1,20 +1,20 @@ -# Automation with Rancher - -## Terraform - -* [Rancher2 Provider](https://registry.terraform.io/providers/rancher/rancher2/latest/docs) ([code](https://github.com/rancher/terraform-provider-rancher2)) - -## Usecases - -### Kubernetes management cluster with Rancher - -![Cluster creation diagram](../assets/images/Provisioning_logic-Rancher_cluster_creation.svg) - -### RKE1 cluster from Rancher - -* [RKE Templates and Infrastructure > Terraform](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/authentication-permissions-and-global-configuration/about-rke1-templates/infrastructure#terraform) - -## Code examples - -* [Devpro Terraform projects](https://github.com/devpro/terraform-projects) -* [Rancher quickstarts](https://github.com/rancher/quickstart) +# Automation with Rancher + +## Terraform + +* [Rancher2 Provider](https://registry.terraform.io/providers/rancher/rancher2/latest/docs) ([code](https://github.com/rancher/terraform-provider-rancher2)) + +## Usecases + +### Kubernetes management cluster with Rancher + +![Cluster creation diagram](cluster-provisioning-logic.svg) + +### RKE1 cluster from Rancher + +* [RKE Templates and Infrastructure > Terraform](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/authentication-permissions-and-global-configuration/about-rke1-templates/infrastructure#terraform) + +## Code examples + +* [Devpro Terraform projects](https://github.com/devpro/terraform-projects) +* [Rancher quickstarts](https://github.com/rancher/quickstart) diff --git a/docs/organizations/companies/suse/rancher/installation.md b/docs/organizations/companies/suse/rancher/installation.md index 32b94bb..758b92a 100644 --- a/docs/organizations/companies/suse/rancher/installation.md +++ b/docs/organizations/companies/suse/rancher/installation.md @@ -1,4 +1,4 @@ -# Installation of Rancher +# Installation of Rancher ## General procedures @@ -8,10 +8,10 @@ ## Providers -* [AKS](../providers/microsoft-azure.md#install-rancher-on-aks) -* [Outscale](../providers/3ds-outscale.md#create-a-rke2-cluster-and-install-rancher-on-it) -* [Nutanix](../providers/nutanix.md#rancher--rke-on-nutanix) -* [vSphere](../providers/wmware-vsphere.md#install-rancher-in-vsphere) +* [AKS](microsoft-azure.md) +* [Outscale](3ds-outscale.md) +* [Nutanix](nutanix.md) +* [vSphere](wmware-vsphere.md) ## Known issues diff --git a/docs/organizations/companies/suse/rke2.md b/docs/organizations/companies/suse/rke2.md index 647095e..f913065 100644 --- a/docs/organizations/companies/suse/rke2.md +++ b/docs/organizations/companies/suse/rke2.md @@ -91,7 +91,7 @@ rke2-metrics-server | kube-system | rke2-metrics-server-2.11.100-build2021111904 - /usr/local/bin/rke2 server - containerd -c /var/lib/rancher/rke2/agent/etc/containerd/config.toml -a /run/k3s/containerd/containerd.sock --state /run/k3s/containerd --root /var/lib/rancher/rke2/agent/containerd - kubelet -- /var/lib/rancher/rke2/data/v1.23.9-rke2r1-eef53a0d1ec2/bin/containerd-shim-runc-v2 -namespace k8s.io -id -address /run/k3s/containerd/containerd.sock +- /var/lib/rancher/rke2/data/v1.23.9-rke2r1-eef53a0d1ec2/bin/containerd-shim-runc-v2 -namespace k8s.io -id container_id -address /run/k3s/containerd/containerd.sock - kube-proxy --cluster-cidr=10.42.0.0/16 --conntrack-max-per-core=0 --conntrack-tcp-timeout-close-wait=0s --conntrack-tcp-timeout-established=0s --healthz-bind-address=127.0.0.1 --hostname-override=vm-bthomas-rke2server --kubeconfig=/var/lib/rancher/rke2/agent/kubeproxy.kubeconfig --proxy-mode=iptables - kube-scheduler --permit-port-sharing=true --authentication-kubeconfig=/var/lib/rancher/rke2/server/cred/scheduler.kubeconfig --authorization-kubeconfig=/var/lib/rancher/rke2/server/cred/scheduler.kubeconfig --bind-address=127.0.0.1 --kubeconfig=/var/lib/rancher/rke2/server/cred/scheduler.kubeconfig --profiling=false --secure-port=10259 - kube-apiserver @@ -106,6 +106,6 @@ rke2-metrics-server | kube-system | rke2-metrics-server-2.11.100-build2021111904 - /usr/local/bin/rke2 agent - containerd -c /var/lib/rancher/rke2/agent/etc/containerd/config.toml -a /run/k3s/containerd/containerd.sock --state /run/k3s/containerd --root /var/lib/rancher/rke2/agent/containerd - kubelet -- /var/lib/rancher/rke2/data/v1.23.9-rke2r1-eef53a0d1ec2/bin/containerd-shim-runc-v2 -namespace k8s.io -id -address /run/k3s/containerd/containerd.sock +- /var/lib/rancher/rke2/data/v1.23.9-rke2r1-eef53a0d1ec2/bin/containerd-shim-runc-v2 -namespace k8s.io -id container_id -address /run/k3s/containerd/containerd.sock - kube-proxy --cluster-cidr=10.42.0.0/16 --conntrack-max-per-core=0 --conntrack-tcp-timeout-close-wait=0s --conntrack-tcp-timeout-established=0s --healthz-bind-address=127.0.0.1 --hostname-override=vm-bthomas-rke2worker1 --kubeconfig=/var/lib/rancher/rke2/agent/kubeproxy.kubeconfig --proxy-mode=iptables - /nginx-ingress-controller --election-id=ingress-controller-leader --controller-class=k8s.io/ingress-nginx --ingress-class=nginx --configmap=kube-system/rke2-ingress-nginx-controller --validating-webhook=:8443 --validating-webhook-certificate=/usr/local/certificates/cert --validating-webhook-key=/usr/local/certificates/key --watch-ingress-without-class=true diff --git a/docs/organizations/companies/suse/suse.md b/docs/organizations/companies/suse/suse.md index 5875b36..6fef8de 100644 --- a/docs/organizations/companies/suse/suse.md +++ b/docs/organizations/companies/suse/suse.md @@ -21,16 +21,6 @@ 📝 [The History of S.u.S.E. - The other enterprise Linux company](https://www.abortretry.fail/p/the-history-of-suse) - January 13, 2025 -## Areas - -* [Edge](edge.md) -* [GPUs](gpu.md) -* [Kubernetes](kubernetes/distributions.md) -* [Networking](networking.md) -* [Observability](observability.md) -* [Security](security.md) -* [Storage](storage.md) - ## Offering ### Open source @@ -39,9 +29,9 @@ * Harvester * [K3s](k3s.md) * [Longhorn](longhorn.md) -* [NeuVector](neuvector.md) +* [NeuVector](neuvector/neuvector.md) * [openSUSE](opensuse.md) -* [Rancher](rancher.md) +* [Rancher](rancher/rancher.md) * [Rancher Desktop](rancher-desktop.md) * [RKE](rke.md)