From 4a98bfd107a8cb0b49c8b0d824a19d2325cc1aee Mon Sep 17 00:00:00 2001 From: Alastair Pitts Date: Mon, 27 Nov 2023 21:38:42 +1100 Subject: [PATCH 1/5] Add kubernetes tentacle docker build --- docker-compose.build.yml | 9 + docker/kubernetes-tentacle/Dockerfile | 60 +++++ .../scripts/configure-tentacle.sh | 211 ++++++++++++++++++ .../scripts/run-tentacle.sh | 4 + 4 files changed, 284 insertions(+) create mode 100644 docker/kubernetes-tentacle/Dockerfile create mode 100644 docker/kubernetes-tentacle/scripts/configure-tentacle.sh create mode 100644 docker/kubernetes-tentacle/scripts/run-tentacle.sh diff --git a/docker-compose.build.yml b/docker-compose.build.yml index 80cb7e777..56ee7318f 100644 --- a/docker-compose.build.yml +++ b/docker-compose.build.yml @@ -10,6 +10,15 @@ services: BUILD_NUMBER: ${BUILD_NUMBER:?err} image: docker.packages.octopushq.com/octopusdeploy/tentacle:${BUILD_NUMBER?err}-linux + octopusdeploy-kubernetes-tentacle-linux: + build: + context: . + dockerfile: ./docker/kubernetes-tentacle/Dockerfile + args: + BUILD_DATE: ${BUILD_DATE:?err} + BUILD_NUMBER: ${BUILD_NUMBER:?err} + image: docker.packages.octopushq.com/octopusdeploy/kubernetes-tentacle:${BUILD_NUMBER?err}-linux + octopusdeploy-tentacle-windows-2019: build: context: . diff --git a/docker/kubernetes-tentacle/Dockerfile b/docker/kubernetes-tentacle/Dockerfile new file mode 100644 index 000000000..637ae066a --- /dev/null +++ b/docker/kubernetes-tentacle/Dockerfile @@ -0,0 +1,60 @@ +FROM mcr.microsoft.com/dotnet/runtime-deps:6.0 + +ARG BUILD_NUMBER +ARG BUILD_DATE + +EXPOSE 10933 + +WORKDIR /tmp + +COPY docker/kubernetes-tentacle/scripts/* /scripts/ +RUN chmod +x /scripts/*.sh + +# Install Tentacle +COPY _artifacts/deb/tentacle_${BUILD_NUMBER}_amd64.deb /tmp/ +RUN apt-get update && \ + apt install ./tentacle_${BUILD_NUMBER}_amd64.deb && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +WORKDIR / + +# We know this won't reduce the image size at all. It's just to make the filesystem a little tidier. +RUN rm -rf /tmp/* + +ENV OCTOPUS_RUNNING_IN_CONTAINER=Y +ENV ACCEPT_EULA=N +ENV CustomPublicHostName="" +ENV ListeningPort="" +ENV MachinePolicy="Default Machine Policy" +ENV PublicHostNameConfiguration="ComputerName" +ENV ServerApiKey="" +ENV ServerPassword="" +ENV ServerCommsAddress="" +ENV ServerPort="" +ENV ServerUrl="" +ENV ServerUsername="" +ENV Space="Default" +ENV TargetEnvironment="" +ENV TargetName="" +ENV TargetRole="" +ENV TargetTenant="" +ENV TargetTenantTag="" +ENV TargetTenantedDeploymentParticipation="" +ENV OCTOPUS__TENTACLE__K8SNAMESPACE="octopus-tentacle" +ENV OCTOPUS__TENTACLE__K8SUSEJOBS="True" +ENV OCTOPUS__TENTACLE__K8SSERVICEACCOUNTNAME="octopus-tentacle-job" +ENV OCTOPUS__TENTACLE__K8SJOBVOLUMEYAML="" + +CMD /scripts/configure-tentacle.sh && /scripts/run-tentacle.sh + +LABEL \ + org.label-schema.schema-version="1.0" \ + org.label-schema.name="Octopus Deploy Kubernetes Tentacle" \ + org.label-schema.vendor="Octopus Deploy" \ + org.label-schema.url="https://octopus.com" \ + org.label-schema.vcs-url="https://github.com/OctopusDeploy/OctopusTentacle" \ + org.label-schema.license="Apache" \ + org.label-schema.description="Octopus Kubernetes Tentacle instance with auto-registration to Octopus Server" \ + org.label-schema.version=${BUILD_NUMBER} \ + org.label-schema.build-date=${BUILD_DATE} diff --git a/docker/kubernetes-tentacle/scripts/configure-tentacle.sh b/docker/kubernetes-tentacle/scripts/configure-tentacle.sh new file mode 100644 index 000000000..1acfaf727 --- /dev/null +++ b/docker/kubernetes-tentacle/scripts/configure-tentacle.sh @@ -0,0 +1,211 @@ +#!/bin/bash +set -e + +if [[ "$ACCEPT_EULA" != "Y" ]]; then + echo "ERROR: You must accept the EULA at https://octopus.com/company/legal by passing an environment variable 'ACCEPT_EULA=Y'" + exit 1 +fi + +# Tentacle Docker images only support once instance per container. Running multiple instances can be achieved by running multiple containers. +instanceName=Tentacle +configurationDirectory=/etc/octopus +applicationsDirectory=/home/Octopus/Applications +internalListeningPort=10933 + +mkdir -p $configurationDirectory +mkdir -p $applicationsDirectory + +if [ ! -f /usr/bin/tentacle ]; then + ln -s /opt/octopus/tentacle/Tentacle /usr/bin/tentacle +fi + +function getPublicHostName() { + if [[ "$PublicHostNameConfiguration" == "PublicIp" ]]; then + curl https://api.ipify.org/ + elif [[ "$PublicHostNameConfiguration" == "FQDN" ]]; then + hostname --fqdn + elif [[ "$PublicHostNameConfiguration" == "ComputerName" ]]; then + hostname + else + echo $CustomPublicHostName + fi +} + +function validateVariables() { + if [[ -z "$ServerApiKey" && -z "$BearerToken" ]]; then + if [[ -z "$ServerPassword" || -z "$ServerUsername" ]]; then + echo "Please specify either an API key, a Bearer Token or a username/password with the 'ServerApiKey' or 'ServerUsername'/'ServerPassword' environment variables" >&2 + exit 1 + fi + fi + + if [[ -z "$ServerUrl" ]]; then + echo "Please specify an Octopus Server with the 'ServerUrl' environment variable" >&2 + exit 1 + fi + + if [[ -z "$TargetEnvironment" ]]; then + echo "Please specify an environment name with the 'TargetEnvironment' environment variable" >&2 + exit 1 + fi + + if [[ -z "$TargetRole" ]]; then + echo "Please specify a role name with the 'TargetRole' environment variable" >&2 + exit 1 + fi + + echo " - server endpoint '$ServerUrl'" + echo " - api key '##########'" + + if [[ ! -z "$ServerCommsAddress" || ! -z "$ServerPort" ]]; then + echo " - communication mode 'Kubernetes' (Polling)" + + if [[ ! -z "$ServerCommsAddress" ]]; then + echo " - server comms address $ServerCommsAddress" + fi + if [[ ! -z "$ServerPort" ]]; then + echo " - server port $ServerPort" + fi + else + echo " - communication mode 'Kubernetes' (Listening)" + echo " - registered port $ListeningPort" + fi + + echo " - environment '$TargetEnvironment'" + echo " - role '$TargetRole'" + echo " - host '$PublicHostNameConfiguration'" + + if [[ ! -z "$TargetName" ]]; then + echo " - name '$TargetName'" + fi + if [[ ! -z "$TargetTenant" ]]; then + echo " - tenant '$TargetTenant'" + fi + if [[ ! -z "$TargetTenantTag" ]]; then + echo " - tenant tag '$TargetTenantTag'" + fi + if [[ ! -z "$TargetTenantedDeploymentParticipation" ]]; then + echo " - tenanted deployment participation '$TargetTenantedDeploymentParticipation'" + fi + if [[ ! -z "$Space" ]]; then + echo " - space '$Space'" + fi +} + +function configureTentacle() { + tentacle create-instance --instance "$instanceName" --config "$configurationDirectory/tentacle.config" + + echo "Setting directory paths ..." + tentacle configure --instance "$instanceName" --app "$applicationsDirectory" + + echo "Configuring communication type ..." + if [[ ! -z "$ServerCommsAddress" || ! -z "$ServerPort" ]]; then + tentacle configure --instance "$instanceName" --noListen "True" + else + tentacle configure --instance "$instanceName" --port $internalListeningPort --noListen "False" + fi + + echo "Updating trust ..." + tentacle configure --instance "$instanceName" --reset-trust + + echo "Creating certificate ..." + tentacle new-certificate --instance "$instanceName" --if-blank +} + +function registerTentacle() { + echo "Registering with server ..." + + local ARGS=() + + ARGS+=('register-k8s-cluster') + + if [[ ! -z "$TargetEnvironment" ]]; then + IFS=',' read -ra ENVIRONMENTS <<<"$TargetEnvironment" + for i in "${ENVIRONMENTS[@]}"; do + ARGS+=('--environment' "$i") + done + fi + + if [[ ! -z "$TargetRole" ]]; then + IFS=',' read -ra ROLES <<<"$TargetRole" + for i in "${ROLES[@]}"; do + ARGS+=('--role' "$i") + done + fi + + if [[ ! -z "$TargetTenant" ]]; then + IFS=',' read -ra TENANTS <<<"$TargetTenant" + for i in "${TENANTS[@]}"; do + ARGS+=('--tenant' "$i") + done + fi + + if [[ ! -z "$TargetTenantTag" ]]; then + IFS=',' read -ra TENANTTAGS <<<"$TargetTenantTag" + for i in "${TENANTTAGS[@]}"; do + ARGS+=('--tenanttag' "$i") + done + fi + + ARGS+=( + '--instance' "$instanceName" + '--server' "$ServerUrl" + '--space' "$Space" + '--policy' "$MachinePolicy") + + if [[ ! -z "$ServerCommsAddress" || ! -z "$ServerPort" ]]; then + ARGS+=('--comms-style' 'TentacleActive') + + if [[ ! -z "$ServerCommsAddress" ]]; then + ARGS+=('--server-comms-address' $ServerCommsAddress) + fi + + if [[ ! -z "$ServerPort" ]]; then + ARGS+=('--server-comms-port' $ServerPort) + fi + else + ARGS+=( + '--comms-style' 'TentaclePassive' + '--publicHostName' $(getPublicHostName)) + + if [[ ! -z "$ListeningPort" && "$ListeningPort" != "$internalListeningPort" ]]; then + ARGS+=('--tentacle-comms-port' $ListeningPort) + fi + fi + + if [[ ! -z "$ServerApiKey" ]]; then + echo "Registering Tentacle with API key" + ARGS+=('--apiKey' $ServerApiKey) + elif [[ ! -z "$BearerToken" ]]; then + echo "Registering Tentacle with Bearer Token" + ARGS+=('--bearerToken' "$BearerToken") + else + echo "Registering Tentacle with username/password" + ARGS+=( + '--username' "$ServerUsername" + '--password' "$ServerPassword") + fi + + if [[ ! -z "$TargetName" ]]; then + ARGS+=('--name' "$TargetName") + fi + + if [[ ! -z "$TargetTenantedDeploymentParticipation" ]]; then + ARGS+=('--tenanted-deployment-participation' "$TargetTenantedDeploymentParticipation") + fi + + tentacle "${ARGS[@]}" +} + +echo "===============================================" +echo "Configuring Octopus Deploy Kubernetes Tentacle" + +validateVariables + +echo "===============================================" + +configureTentacle +registerTentacle + +echo "Configuration successful." +echo "" \ No newline at end of file diff --git a/docker/kubernetes-tentacle/scripts/run-tentacle.sh b/docker/kubernetes-tentacle/scripts/run-tentacle.sh new file mode 100644 index 000000000..b011d17fe --- /dev/null +++ b/docker/kubernetes-tentacle/scripts/run-tentacle.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -eux + +tentacle agent --instance Tentacle --noninteractive From ea2155ad691693525cbd7dc4646eda15c37b8700 Mon Sep 17 00:00:00 2001 From: Alastair Pitts Date: Tue, 28 Nov 2023 14:00:04 +1100 Subject: [PATCH 2/5] Update environment variables --- docker/kubernetes-tentacle/Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docker/kubernetes-tentacle/Dockerfile b/docker/kubernetes-tentacle/Dockerfile index 637ae066a..7686047ad 100644 --- a/docker/kubernetes-tentacle/Dockerfile +++ b/docker/kubernetes-tentacle/Dockerfile @@ -30,10 +30,10 @@ ENV MachinePolicy="Default Machine Policy" ENV PublicHostNameConfiguration="ComputerName" ENV ServerApiKey="" ENV ServerPassword="" +ENV ServerUsername="" ENV ServerCommsAddress="" ENV ServerPort="" ENV ServerUrl="" -ENV ServerUsername="" ENV Space="Default" ENV TargetEnvironment="" ENV TargetName="" @@ -41,10 +41,10 @@ ENV TargetRole="" ENV TargetTenant="" ENV TargetTenantTag="" ENV TargetTenantedDeploymentParticipation="" -ENV OCTOPUS__TENTACLE__K8SNAMESPACE="octopus-tentacle" -ENV OCTOPUS__TENTACLE__K8SUSEJOBS="True" -ENV OCTOPUS__TENTACLE__K8SSERVICEACCOUNTNAME="octopus-tentacle-job" -ENV OCTOPUS__TENTACLE__K8SJOBVOLUMEYAML="" +ENV OCTOPUS__K8STENTACLE__NAMESPACE="" +ENV OCTOPUS__K8STENTACLE__USEJOBS="True" +ENV OCTOPUS__K8STENTACLE__JOBSERVICEACCOUNTNAME="" +ENV OCTOPUS__K8STENTACLE__JOBVOLUMEYAML="" CMD /scripts/configure-tentacle.sh && /scripts/run-tentacle.sh From ea91da408c4b7a67e342c424512f7f8334963d99 Mon Sep 17 00:00:00 2001 From: Alastair Pitts Date: Tue, 28 Nov 2023 15:22:48 +1100 Subject: [PATCH 3/5] Support multiple architectures --- docker-compose.build.yml | 3 ++- docker/linux/Dockerfile | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/docker-compose.build.yml b/docker-compose.build.yml index 56ee7318f..946e241fc 100644 --- a/docker-compose.build.yml +++ b/docker-compose.build.yml @@ -11,13 +11,14 @@ services: image: docker.packages.octopushq.com/octopusdeploy/tentacle:${BUILD_NUMBER?err}-linux octopusdeploy-kubernetes-tentacle-linux: + platform: "linux/${BUILD_ARCH:?err}" build: context: . dockerfile: ./docker/kubernetes-tentacle/Dockerfile args: BUILD_DATE: ${BUILD_DATE:?err} BUILD_NUMBER: ${BUILD_NUMBER:?err} - image: docker.packages.octopushq.com/octopusdeploy/kubernetes-tentacle:${BUILD_NUMBER?err}-linux + image: docker.packages.octopushq.com/octopusdeploy/kubernetes-tentacle:${BUILD_NUMBER?err}-linux-${BUILD_ARCH:?err} octopusdeploy-tentacle-windows-2019: build: diff --git a/docker/linux/Dockerfile b/docker/linux/Dockerfile index 89394c77d..f34eb3085 100644 --- a/docker/linux/Dockerfile +++ b/docker/linux/Dockerfile @@ -2,6 +2,7 @@ FROM mcr.microsoft.com/dotnet/runtime-deps:6.0 ARG BUILD_NUMBER ARG BUILD_DATE +ARG BUILD_ARCH RUN apt-get update && \ apt-get install -y \ @@ -28,11 +29,11 @@ COPY docker/linux/scripts/dockerd-entrypoint.sh /usr/local/bin/ RUN /install-scripts/install-docker.sh # Install Tentacle -COPY _artifacts/deb/tentacle_${BUILD_NUMBER}_amd64.deb /tmp/ -RUN apt-get update && \ - apt install ./tentacle_${BUILD_NUMBER}_amd64.deb && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* +COPY _artifacts/deb/tentacle_${BUILD_NUMBER}_${BUILD_ARCH}.deb /tmp/ +RUN apt-get update +RUN apt install ./tentacle_${BUILD_NUMBER}_${BUILD_ARCH}.deb -y +RUN apt-get clean +RUN rm -rf /var/lib/apt/lists/* WORKDIR / From 857210071933259d8b4eb844d8c83e5a1c2e4d62 Mon Sep 17 00:00:00 2001 From: Alastair Pitts Date: Tue, 28 Nov 2023 16:05:29 +1100 Subject: [PATCH 4/5] Multi-arch k8s only --- docker-compose.build.yml | 1 + docker/kubernetes-tentacle/Dockerfile | 11 ++++++----- docker/linux/Dockerfile | 11 +++++------ 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/docker-compose.build.yml b/docker-compose.build.yml index 946e241fc..2fccf2a29 100644 --- a/docker-compose.build.yml +++ b/docker-compose.build.yml @@ -18,6 +18,7 @@ services: args: BUILD_DATE: ${BUILD_DATE:?err} BUILD_NUMBER: ${BUILD_NUMBER:?err} + BUILD_ARCH: ${BUILD_ARCH:?err} image: docker.packages.octopushq.com/octopusdeploy/kubernetes-tentacle:${BUILD_NUMBER?err}-linux-${BUILD_ARCH:?err} octopusdeploy-tentacle-windows-2019: diff --git a/docker/kubernetes-tentacle/Dockerfile b/docker/kubernetes-tentacle/Dockerfile index 7686047ad..b0695d346 100644 --- a/docker/kubernetes-tentacle/Dockerfile +++ b/docker/kubernetes-tentacle/Dockerfile @@ -2,6 +2,7 @@ FROM mcr.microsoft.com/dotnet/runtime-deps:6.0 ARG BUILD_NUMBER ARG BUILD_DATE +ARG BUILD_ARCH EXPOSE 10933 @@ -11,11 +12,11 @@ COPY docker/kubernetes-tentacle/scripts/* /scripts/ RUN chmod +x /scripts/*.sh # Install Tentacle -COPY _artifacts/deb/tentacle_${BUILD_NUMBER}_amd64.deb /tmp/ -RUN apt-get update && \ - apt install ./tentacle_${BUILD_NUMBER}_amd64.deb && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* +COPY _artifacts/deb/tentacle_${BUILD_NUMBER}_${BUILD_ARCH}.deb /tmp/ +RUN apt-get update +RUN apt install ./tentacle_${BUILD_NUMBER}_${BUILD_ARCH}.deb -y +RUN apt-get clean +RUN rm -rf /var/lib/apt/lists/* WORKDIR / diff --git a/docker/linux/Dockerfile b/docker/linux/Dockerfile index f34eb3085..89394c77d 100644 --- a/docker/linux/Dockerfile +++ b/docker/linux/Dockerfile @@ -2,7 +2,6 @@ FROM mcr.microsoft.com/dotnet/runtime-deps:6.0 ARG BUILD_NUMBER ARG BUILD_DATE -ARG BUILD_ARCH RUN apt-get update && \ apt-get install -y \ @@ -29,11 +28,11 @@ COPY docker/linux/scripts/dockerd-entrypoint.sh /usr/local/bin/ RUN /install-scripts/install-docker.sh # Install Tentacle -COPY _artifacts/deb/tentacle_${BUILD_NUMBER}_${BUILD_ARCH}.deb /tmp/ -RUN apt-get update -RUN apt install ./tentacle_${BUILD_NUMBER}_${BUILD_ARCH}.deb -y -RUN apt-get clean -RUN rm -rf /var/lib/apt/lists/* +COPY _artifacts/deb/tentacle_${BUILD_NUMBER}_amd64.deb /tmp/ +RUN apt-get update && \ + apt install ./tentacle_${BUILD_NUMBER}_amd64.deb && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* WORKDIR / From fa0079a23e5aedc83e8a8d7a39ba6ab0d86022ab Mon Sep 17 00:00:00 2001 From: Alastair Pitts Date: Wed, 29 Nov 2023 17:33:14 +1100 Subject: [PATCH 5/5] Minor error message changes --- docker/kubernetes-tentacle/scripts/configure-tentacle.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/kubernetes-tentacle/scripts/configure-tentacle.sh b/docker/kubernetes-tentacle/scripts/configure-tentacle.sh index 1acfaf727..851f0d9b0 100644 --- a/docker/kubernetes-tentacle/scripts/configure-tentacle.sh +++ b/docker/kubernetes-tentacle/scripts/configure-tentacle.sh @@ -45,12 +45,12 @@ function validateVariables() { fi if [[ -z "$TargetEnvironment" ]]; then - echo "Please specify an environment name with the 'TargetEnvironment' environment variable" >&2 + echo "Please specify one or more environment names (comma delimited) with the 'TargetEnvironment' environment variable" >&2 exit 1 fi if [[ -z "$TargetRole" ]]; then - echo "Please specify a role name with the 'TargetRole' environment variable" >&2 + echo "Please specify one or more role names (comma delimited) with the 'TargetRole' environment variable" >&2 exit 1 fi