当前位置: 首页 > news >正文

Kubernetes 离线部署 Spinnaker

离线部署 Spinnaker

离线部署 spinnaker 需要提前准备以下依赖项

  • halyard 安装工具:该hal命令的apt源地址https://us-apt.pkg.dev/projects/spinnaker-community位于国外
  • halyard boms物料清单:Spinnaker 将其halyard boms配置存储在公共谷歌云存储 ( gs://halconfig ) 存储桶中。该位置无法访问,并且导致 hal 命令超时。
  • Spinnaker 微服务docker镜像:微服务的镜像存储在 us-docker.pkg.dev/spinnaker-community/docker/ 镜像仓库中,从国内访问该存储库同样很困难。

在这里插入图片描述

相关参数:

SPINNAKER_REPOSITORY_URL="https://us-apt.pkg.dev/projects/spinnaker-community"
SPINNAKER_DOCKER_REGISTRY="us-docker.pkg.dev/spinnaker-community/docker"
SPINNAKER_BOMS="gs://haconfig"

解决方法:

  • halyard 安装工具:hal命令使用docker方式安装
  • halyard boms物料清单:从google对象存储桶下载到本地,修改halyard配置从本地目录读取boms文件
  • Spinnaker 微服务docker镜像:将镜像同步到阿里云ACR镜像仓库(个人版免费),修改halyard配置从阿里云镜像仓库拉取镜像

在下载依赖阶段依然需要能够访问外网,可以使用外网的免费CICD工具,例如githubAction、gitlabCI或circleCI。

或者免费的临时虚拟机例如 google cloudshell、github codespace 或者购买一台阿里云香港云主机。

准备kubernetes集群

查看节点信息,kubernetes版本为v1.27.7,容器运行时为containerd.

root@node40:~# kubectl get nodes -o wide
NAME     STATUS   ROLES           AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
node40   Ready    control-plane   11d   v1.27.7   192.168.72.40   <none>        Ubuntu 22.04.2 LTS   5.15.0-76-generic   containerd://1.6.24

已通过 helm 方式安装 openebs,用于通过 storageclass 为minio 动态提供存储卷

root@node40:~# kubectl -n openebs get pods
NAME                                           READY   STATUS    RESTARTS      AGE
openebs-localpv-provisioner-658c87d4bb-rtsc7   1/1     Running   2 (22m ago)   11d
root@node40:~# 
root@node40:~# kubectl get sc
NAME                         PROVISIONER        RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
openebs-hostpath (default)   openebs.io/local   Delete          WaitForFirstConsumer   false                  11d

已通过 helm 方式安装 minio,spinnaker依赖S3存储保存数据

root@node40:~# kubectl -n minio get pods
NAME                    READY   STATUS    RESTARTS   AGE
minio-8976fd4b7-42vkt   1/1     Running   0          103mroot@node40:~# kubectl -n minio get svc
NAME            TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
minio           NodePort   10.96.2.159   <none>        9000:32000/TCP   103m
minio-console   NodePort   10.96.1.5     <none>        9001:32001/TCP   103m

备注:记录minio service连接地址及凭证,后续spinnaker指定存储时需要使用,以上示例在集群内连接地址为http://minio.minio:9000

已通过 helm 方式安装 metallb,为ingress-nginx提供LoadBalancer类型IP地址

root@node40:~# kubectl -n metallb-system get pods
NAME                                  READY   STATUS    RESTARTS   AGE
metallb-controller-5cd9b4944b-jwjbm   1/1     Running   0          104m
metallb-speaker-mqdh9                 4/4     Running   0          104m

已通过 helm 方式安装 ingress-nginx 网关,后续通过创建ingress规则,连接spinnaker UI.

root@node40:~# kubectl -n ingress-nginx get pods
NAME                                      READY   STATUS    RESTARTS   AGE
ingress-nginx-controller-8db7bbbc-mdpsv   1/1     Running   0          107m
root@node40:~# kubectl -n ingress-nginx get svc
NAME                                 TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.96.3.108   192.168.72.191   80:31306/TCP,443:32253/TCP   107m
ingress-nginx-controller-admission   ClusterIP      10.96.2.255   <none>           443/TCP                      107m

备注:记录metallb为 ingress-nginx 分配的EXTERNAL-IP: 192.168.72.191,后续访问spinnaker解析ingress域名时需要使用。

下载spinnaker boms 依赖

halyard 配置存储在google gcs 存储桶中。所有标准安装都将引用此位置的元数据,例如可用版本列表、各个微服务每个版本的物料清单 (bom) 等。

可以使用以下命令查看存储桶中的文件,注意,执行该命令需要能够访问外网或配置代理。

docker run -it --rm --name gloud-cli docker.io/google/cloud-sdk:alpine \gcloud storage ls gs://halconfig

示例输出如下:

$ docker run -it --rm --name gloud-cli docker.io/google/cloud-sdk:alpine \gcloud storage ls gs://halconfig
gs://halconfig/versions.yml
gs://halconfig/bom/
gs://halconfig/clouddriver/
gs://halconfig/deck/
gs://halconfig/echo/
gs://halconfig/fiat/
gs://halconfig/front50/
gs://halconfig/gate/
gs://halconfig/igor/
gs://halconfig/kayenta/
gs://halconfig/monitoring-daemon/
gs://halconfig/orca/
gs://halconfig/rosco/

创建 google-cloud-sdk 容器

docker run -d --name gloud-cli -v /workspace:/workspace -w /workspace \--env HTTP_PROXY=http://192.168.72.1:7890 \--env HTTPS_PROXY=http://192.168.72.1:7890 \docker.io/google/cloud-sdk:alpine sleep infinity

下载整个halconfig文件

可以下载整个halconfig存储桶到本地,请注意, gsutil cp 命令可能需要相当长的时间,虽然大小仅有150M左右,但它有超过 55k 个文件需要拉取。

$ docker exec -it gloud-cli bash
gsutil cp -R -n gs://halconfig .
# gcloud storage cp -R -n gs://halconfig .
tar -zcvf halconfig.tar.gz halconfig

下载指定halconfig文件

实际我们只需要对应版本的boms文件,需要下载的文件列表如下:

gs://halconfig/versions.yml
gs://halconfig/bom/${spinnaker_version}.yml
gs://halconfig/clouddriver/${clouddriver_version}/
gs://halconfig/deck/${deck_version}/
gs://halconfig/echo/${echo_version}/
gs://halconfig/fiat/${fiat_version}/
gs://halconfig/front50/${front50_version}/
gs://halconfig/gate/${gate_version}/
gs://halconfig/igor/${igor_version}/
gs://halconfig/kayenta/${kayenta_version}/
gs://halconfig/monitoring-daemon/${monitoring-daemon_version}/
gs://halconfig/orca/${orca_version}/
gs://halconfig/rosco/${rosco_version}/

下面创建一个boms下载脚本

$ cat /workspace/download_boms.sh
#!/bin/bash
spinnaker_version=1.32.2
halconfig_path=./halconfig
spinnaker_bom_path=${halconfig_path}/bom
spinnaker_bom_file=${spinnaker_version}.ymlcurl -sL -o /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.40.2/yq_linux_amd64
chmod a+x /usr/local/bin/yqmkdir -p ${spinnaker_bom_path}
gsutil -m cp -R gs://halconfig/versions.yml ./halconfig
gsutil -m cp -R gs://halconfig/bom/${spinnaker_bom_file} ${spinnaker_bom_path}
services=$(yq e '.services | keys | .[]' ${spinnaker_bom_path}/${spinnaker_bom_file})for service in ${services}; domkdir -p ${halconfig_path}/${service}spinnaker_service_path=${halconfig_path}/${service}version=$(service=${service} yq e '.services.[env(service)].version' ${spinnaker_bom_path}/${spinnaker_bom_file})gsutil -m cp -R gs://halconfig/${service}/${version} ${spinnaker_service_path}
done
yq e -i '.services.*.version |= "local:" + .' ${spinnaker_bom}
tar -zcvf halconfig.tar.gz ./halconfig

进入容器执行脚本下载boms

docker exec -it gloud-cli bash /workspace/download_boms.sh

查看下载并打包好的boms文件

root@ubuntu:~# ls /workspace/
download_boms.sh  halconfig  halconfig.tar.gz

下载docker镜像

创建 skopeo 容器,使用skopeo工具在两个远程仓库之间同步镜像,将spinnaker镜像转存到国内阿里云acr镜像仓库。

docker run -d --name skopeo -v /workspace:/workspace -w /workspace --entrypoint="" \--env HTTP_PROXY=http://192.168.72.1:7890 \--env HTTPS_PROXY=http://192.168.72.1:7890 \quay.io/skopeo/stable:latest sleep infinity

创建镜像下载脚本

$ cat /workspace/download_images.sh
#!/bin/bash
export spinnaker_version=1.32.2
export spinnaker_dockerRegistry="us-docker.pkg.dev/spinnaker-community/docker/"
export dockerhub_dockerRegistry="docker.io/library/"
export spinnaker_bom="./halconfig/bom/${spinnaker_version}.yml"export dest_registry=registry.cn-shenzhen.aliyuncs.com/cnmirror
export registry_username=xxxxxx
export registry_password=xxxxxxcurl -sL -o /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/v4.40.2/yq_linux_amd64
chmod a+x /usr/local/bin/yqyq -r '.services | to_entries | .[] | env(spinnaker_dockerRegistry) + .key + ":" + .value.version' ${spinnaker_bom} > spinnaker_images.txt
yq -r '.dependencies | to_entries | .[] | env(dockerhub_dockerRegistry) + .key + ":" + .value.version' ${spinnaker_bom} >> spinnaker_images.txt
echo "us-docker.pkg.dev/spinnaker-community/docker/halyard:stable" >> spinnaker_images.txtsed -i "s#docker.io/library/redis:.*#docker.io/library/redis:6.2#g" spinnaker_images.txt
sed -i '/monitoring-third-party/d' spinnaker_images.txtfor image in $(cat spinnaker_images.txt);doimage_name=$(echo $image | awk -F '/' '{print $NF}')skopeo sync --src docker --dest docker \--dest-username ${registry_username} --dest-password ${registry_password} \$image ${dest_registry}
done

进入容器执行脚本下载spinnaker镜像

docker exec -it skopeo bash /workspace/download_images.sh

查看生成的镜像清单,可能个别镜像并不需要,另外redis镜像tag需要从halyard源码仓库搜索获取。

root@ubuntu:~# cat /workspace/spinnaker_images.txt 
us-docker.pkg.dev/spinnaker-community/docker/clouddriver:5.82.0
us-docker.pkg.dev/spinnaker-community/docker/deck:3.15.1
us-docker.pkg.dev/spinnaker-community/docker/echo:2.39.0
us-docker.pkg.dev/spinnaker-community/docker/fiat:1.42.0
us-docker.pkg.dev/spinnaker-community/docker/front50:2.30.1
us-docker.pkg.dev/spinnaker-community/docker/gate:6.60.1
us-docker.pkg.dev/spinnaker-community/docker/igor:4.13.3
us-docker.pkg.dev/spinnaker-community/docker/kayenta:2.38.0
us-docker.pkg.dev/spinnaker-community/docker/monitoring-daemon:1.4.0
us-docker.pkg.dev/spinnaker-community/docker/orca:8.36.0
us-docker.pkg.dev/spinnaker-community/docker/rosco:1.18.0
docker.io/library/consul:0.7.5
docker.io/library/redis:6.2
docker.io/library/vault:0.7.0
us-docker.pkg.dev/spinnaker-community/docker/halyard:stable

docker安装halyard

以docker方式安装halyard

docker run -d --name halyard \-p 8084:8084 -p 9000:9000 \-w /home/spinnaker \-v /home/spinnaker/.hal:/home/spinnaker/.hal \-v /home/spinnaker/.kube:/home/spinnaker/.kube \-e KUBECONFIG=/home/spinnaker/.kube/config \registry.cn-shenzhen.aliyuncs.com/cnmirror/halyard:1.62.0

复制kubeconfig文件

使用scp命令复制kubernetes节点上的/root/.kube/config文件到halyard节点/home/spinnaker/.kube/目录下

cp config /home/spinnaker/.kube/config

修改主机目录权限,避免后续安装出现权限问题

uid=$(docker exec -it halyard id -u)
chown -R ${uid}:${uid} /home/spinnaker

进入halyard容器

docker exec -it halyard bash

验证与集群连接是否正常

kubectl get nodes

复制boms到halyard目录

解压halconfig.tar.gz到/home/spinnaker/.hal/.boms/目录下

mkdir -p /home/spinnaker/.hal/.boms/
tar -zxvf halconfig.tar.gz -C /home/spinnaker/.hal/.boms/ --strip=2
chown -R 1000:1000 /home/spinnaker/.hal/.boms/

boms目录结构如下:

root@ubuntu:~# tree /home/spinnaker/.hal/.boms/
/home/spinnaker/.hal/.boms/
├── bom
│   └── 1.32.2.yml
├── clouddriver
│   └── 5.82.0
│       ├── clouddriver-bootstrap.yml
│       ├── clouddriver-caching.yml
│       ├── clouddriver-ro-deck.yml
│       ├── clouddriver-ro.yml
│       ├── clouddriver-rw.yml
│       ├── clouddriver.yml
│       └── README.md
├── deck
│   └── 3.15.1
│       ├── README.md
│       └── settings.js
├── echo
│   └── 2.39.0
│       ├── echo-scheduler.yml
│       ├── echo-worker.yml
│       ├── echo.yml
│       └── README.md
├── fiat
│   └── 1.42.0
│       ├── fiat.yml
│       └── README.md
├── front50
│   └── 2.30.1
│       ├── front50.yml
│       └── README.md
├── gate
│   └── 6.60.1
│       ├── gate.yml
│       └── README.md
├── igor
│   └── 4.13.3
│       ├── igor.yml
│       └── README.md
├── kayenta
│   └── 2.38.0
│       ├── kayenta.yml
│       └── README.md
├── monitoring-daemon
│   └── 1.4.0
│       ├── README.md
│       └── spinnaker-monitoring.yml
├── monitoring-third-party
├── orca
│   └── 8.36.0
│       ├── orca-bootstrap.yml
│       ├── orca.yml
│       └── README.md
├── rosco
│   └── 1.18.0
│       ├── images.yml
│       ├── packer.tar.gz
│       ├── README.md
│       └── rosco.yml
└── versions.yml

修改/home/spinnaker/.hal/.boms/bom/<version>.yml文件,其中services.*.version版本字段前需要加local。配置完成之后,hal在deploy的时候不会去google拉取版本配置,而是从本地读取。

以下命令在download_boms.sh脚本中已执行,无需重复执行。

yq e -i '.services.*.version |= "local:" + .' /home/spinnaker/.hal/.boms/bom/1.32.2.yml

查看修改后的配置文件

root@ubuntu:~# cat /home/spinnaker/.hal/.boms/bom/1.32.2.yml
artifactSources:debianRepository: https://us-apt.pkg.dev/projects/spinnaker-communitydockerRegistry: registry.cn-shenzhen.aliyuncs.com/cnmirrorgitPrefix: https://github.com/spinnakergoogleImageProject: marketplace-spinnaker-release
dependencies:consul:version: 0.7.5redis:version: 2:2.8.4-2vault:version: 0.7.0
services:clouddriver:commit: 98204860175e00f8b1e01b43f8fa06670cc4cd2eversion: local:5.82.0deck:commit: 4bc0ae68f578f94fb5473a90d2db18d4c580944aversion: local:3.15.1echo:commit: c24b570673fc0f441a65fb69f6936027905c686dversion: local:2.39.0fiat:commit: 37a686b46d1bfe5569fff487151d6b8e84295169version: local:1.42.0front50:commit: f8d4d344e3858d9c3d45534d34a10e51181ece8eversion: local:2.30.1gate:commit: 431b73f62d5d2caec4619e64ca7084c0d61f7b9eversion: local:6.60.1igor:commit: 95c19bd7f49d5fd831104c8a0a92195a6eded154version: local:4.13.3kayenta:commit: 137036d870f9f4834eccd60d7895b212a42b9080version: local:2.38.0monitoring-daemon:commit: 96d510cb22f65dcf788324ed8b68447c31de255aversion: local:1.4.0monitoring-third-party:commit: 96d510cb22f65dcf788324ed8b68447c31de255aversion: local:1.4.0orca:commit: cb269b64cf2883317cd169cc7d82b75093ad6754version: local:8.36.0rosco:commit: a035e26d7fadeb258cb3c4206e386203c6ab1ac3version: local:1.18.0
timestamp: '2023-09-20 20:55:47'
version: 1.32.2

配置 halyard 以引用本地镜像

配置 halyard 从国内镜像仓库拉取 Spinnaker 微服务镜像。编辑 ~/.hal/.boms/bom 文件夹中的 <version>.yml 文件,修改dockerRegistry参数,例如:

$ vim /home/spinnaker/.hal/.boms/bom/1.32.2.yml
artifactSources:debianRepository: https://us-apt.pkg.dev/projects/spinnaker-communitydockerRegistry: registry.cn-shenzhen.aliyuncs.com/cnmirrorgitPrefix: https://github.com/spinnakergoogleImageProject: marketplace-spinnaker-release

本地 BOM 仅引用 Spinnaker 服务的私有注册表,而不引用 Redis 等依赖服务。如果想从自己的私有注册表中提取 Redis 映像,需要创建一个~/.hal/$DEPLOYMENT/service-settings/redis.yml文件,其中 $DEPLOYMENT 通常是默认值。

DEPLOYMENT=default
mkdir -p /home/spinnaker/.hal/$DEPLOYMENT/service-settings/
cat >/home/spinnaker/.hal/$DEPLOYMENT/service-settings/redis.yml<<EOF
artifactId: registry.cn-shenzhen.aliyuncs.com/cnmirror/redis:6.2
EOF
chown -R 1000:1000 /home/spinnaker

在单独的 shell 中,以root身份连接到 Halyard:

docker exec -it -u root halyard bash

禁用gcs,配置halyard使用本地boms文件,可以新建halyard-local.yml或修改halyard.yml

cat >/opt/halyard/config/halyard-local.yml<<EOF
spinnaker:config:input:gcs:enabled: false
EOF

重新启动halyard

docker restart halyard

halyard 配置 spinnaker

后续所有操作都在halyard容器中执行。

docker exec -it halyard bash

指定 Spinnaker 版本

列出当前halyard可用的spinnaker版本。

hal version list

选择一个要部署的 spinnaker 版本,这里以 spinnaker 最新版本为例,读取本地boms文件需要在版本号前加上local。

hal config version edit --version local:1.32.2

添加spinnaker账户

使用kubernetes cluster-admin作为spinnaker账户

hal config provider kubernetes account add spinnaker-admin \
--context $(kubectl config current-context)

为Spinnaker UI设置时区

hal config edit --timezone Asia/Shanghai

指定providers

配置提供程序,指定为kubernetes

hal config provider kubernetes enable

指定安装环境

分布式安装适用于资源占用量较大的开发组织,以及那些无法承受 Spinnaker 更新期间停机的情况。

使用您在配置提供程序时创建的$ACCOUNT名称运行以下命令:

hal config deploy edit --type distributed --account-name spinnaker-admin

指定外置存储

记录值如下:

export ENDPOINT="http://minio.minio:9000"
export MINIO_ACCESS_KEY=admin
export MINIO_SECRET_KEY=minio123

鉴于 Minio 不支持版本控制对象,需要在 Spinnaker 中禁用它。将以下行添加到 ~/.hal/$DEPLOYMENT/profiles/front50-local.yml

DEPLOYMENT=default
mkdir -p /home/spinnaker/.hal/$DEPLOYMENT/profiles
echo "spinnaker.s3.versioning: false" > /home/spinnaker/.hal/$DEPLOYMENT/profiles/front50-local.yml

$DEPLOYMENT 通常是 default 。在这里内容。如果该文件不存在,则可能需要创建它。

编辑存储设置,运行以下命令(请注意,我们选择 S3 作为存储类型,因为 Minio 实现了 S3 API):

echo $MINIO_SECRET_KEY | hal config storage s3 edit --path-style-access=true \--endpoint $ENDPOINT \--access-key-id $MINIO_ACCESS_KEY \--secret-access-key
hal config storage edit --type s3

配置spinnaker UI URL

修改Spinnaker Deck和Gate的域名配置,与后续创建的ingress规则域名一致。

hal config security ui edit --override-base-url http://spinnaker.example.com
hal config security api edit --override-base-url http://spinnaker.example.com/api/v1

修改gate组件配置,与override-base-url和ingress规则一致

mkdir -p /home/spinnaker/.hal/default/profiles
cat >/home/spinnaker/.hal/default/profiles/gate-local.yml<<EOF
server:servlet:context-path: /api/v1
EOFmkdir -p /home/spinnaker/.hal/default/service-settings
cat >/home/spinnaker/.hal/default/service-settings/gate.yml<<EOF
healthEndpoint: /api/v1/health
EOF

部署 Spinnaker

执行以下命令开始部署 Spinnaker 到 kubernetes 集群

hal deploy apply

命令输出结果如下:

spinnaker@ubuntu:~$ hal deploy apply
+ Get current deploymentSuccess
+ Prep deploymentSuccess
Validation in default.stats:
- INFO Stats are currently ENABLED. Usage statistics are beingcollected. Thank you! These stats inform improvements to the product, and thathelps the community. To disable, run `hal config stats disable`. To learn moreabout what and how stats data is used, please seehttps://spinnaker.io/docs/community/stay-informed/stats.+ Preparation complete... deploying Spinnaker
+ Get current deploymentSuccess
+ Apply deploymentSuccess
+ Deploy spin-redisSuccess
+ Deploy spin-clouddriverSuccess
+ Deploy spin-front50Success
+ Deploy spin-orcaSuccess
+ Deploy spin-deckSuccess
+ Deploy spin-echoSuccess
+ Deploy spin-gateSuccess
+ Deploy spin-roscoSuccess
+ Run `hal deploy connect` to connect to Spinnaker.

查看创建的pods,所有pod完全运行可能需要5~10m,需要耐心等待。

root@node40:~# kubectl -n spinnaker get pods
NAME                                READY   STATUS    RESTARTS   AGE
spin-clouddriver-77b9989787-962xc   1/1     Running   0          5m59s
spin-deck-7b6d795dcb-8pxfk          1/1     Running   0          6m
spin-echo-bbcd4f8f-nnnsf            1/1     Running   0          6m
spin-front50-58bf57cbcf-hd55d       1/1     Running   0          5m58s
spin-gate-5d4f6c9dd9-ks6m6          1/1     Running   0          6m
spin-orca-5cbf687487-bgbvx          1/1     Running   0          5m59s
spin-redis-6d475cc85c-mcv2v         1/1     Running   0          6m1s
spin-rosco-5df7654856-8pd7q         1/1     Running   0          5m58s

查看创建的service

root@node40:~# kubectl -n spinnaker get svc
NAME               TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
spin-clouddriver   ClusterIP   10.96.0.171   <none>        7002/TCP   6m7s
spin-deck          ClusterIP   10.96.3.245   <none>        9000/TCP   6m6s
spin-echo          ClusterIP   10.96.2.106   <none>        8089/TCP   6m6s
spin-front50       ClusterIP   10.96.1.59    <none>        8080/TCP   6m7s
spin-gate          ClusterIP   10.96.1.2     <none>        8084/TCP   6m6s
spin-orca          ClusterIP   10.96.0.69    <none>        8083/TCP   6m7s
spin-redis         ClusterIP   10.96.3.62    <none>        6379/TCP   6m7s
spin-rosco         ClusterIP   10.96.2.66    <none>        8087/TCP   6m6s

查看pods镜像,默认从阿里云镜像仓库拉取:

root@node40:~# kubectl -n spinnaker get pods  -o yaml  | grep image: | sort -uimage: registry.cn-shenzhen.aliyuncs.com/cnmirror/redis:6.2image: registry.cn-shenzhen.aliyuncs.com/cnmirror/clouddriver:5.82.0image: registry.cn-shenzhen.aliyuncs.com/cnmirror/deck:3.15.1- image: registry.cn-shenzhen.aliyuncs.com/cnmirror/deck:3.15.1image: registry.cn-shenzhen.aliyuncs.com/cnmirror/echo:2.39.0image: registry.cn-shenzhen.aliyuncs.com/cnmirror/front50:2.30.1image: registry.cn-shenzhen.aliyuncs.com/cnmirror/gate:6.60.1image: registry.cn-shenzhen.aliyuncs.com/cnmirror/orca:8.36.0image: registry.cn-shenzhen.aliyuncs.com/cnmirror/rosco:1.18.0

连接到 Spinnaker UI

这里使用ingress连接spinnaker UI,创建如下Ingress规则

cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: spin-ingressnamespace: spinnaker
spec:rules:- host: spinnaker.example.comhttp:paths:- path: /pathType: ImplementationSpecificbackend:service:name: spin-deckport:number: 9000- host: spinnaker.example.comhttp:paths:- path: /api/v1pathType: ImplementationSpecificbackend:service:name: spin-gateport:number: 8084
EOF

查看创建的ingress规则

root@node40:~# kubectl -n spinnaker get ingress
NAME           CLASS   HOSTS                                         ADDRESS          PORTS   AGE
spin-ingress   nginx   spinnaker.example.com,spinnaker.example.com   192.168.72.191   80      75s

本地配置hosts解析,其中 192.168.72.191 为ingress服务绑定的 EXTERNAL-IP

192.168.72.191 spinnaker.example.com

浏览器访问spinnaker

http://spinnaker.example.com

在这里插入图片描述

相关文章:

Kubernetes 离线部署 Spinnaker

离线部署 Spinnaker 离线部署 spinnaker 需要提前准备以下依赖项 halyard 安装工具&#xff1a;该hal命令的apt源地址https://us-apt.pkg.dev/projects/spinnaker-community位于国外halyard boms物料清单&#xff1a;Spinnaker 将其halyard boms配置存储在公共谷歌云存储 ( g…...

TypeScript 学习笔记 第三部分 贪吃蛇游戏

尚硅谷TypeScript教程&#xff08;李立超老师TS新课&#xff09; 1. 创建开发环境 创建工程&#xff0c;使用学习笔记的第二部分安装css部分 npm i -D less less-loader css-loader style-loader对css部分处理&#xff0c;能够运行在低版本浏览器 npm i -D postcss postcss…...

【spring(一)】核心容器总结

&#x1f308;键盘敲烂&#xff0c;年薪30万&#x1f308; 目录 IOC 配置bean对象&#xff1a; DI 注入bean对象 ①.setter方法注入 ②.构造器注入 Bean的实例化 1.setter方法注入(重点) 2.静态工厂&#xff08;了解&#xff09; 3.实例工厂&#xff08;了解&#xff0…...

易点易动固定资产管理系统:实现全面的固定资产采购管理

在现代企业中&#xff0c;固定资产采购管理是一项关键的任务。为了确保企业的正常运营和发展&#xff0c;有效管理和控制固定资产采购过程至关重要。易点易动固定资产管理系统为企业提供了一种全面的解决方案&#xff0c;整合了从采购需求、采购计划、询比价、采购合同到采购执…...

力扣:178. 分数排名(Python3)

题目&#xff1a; 表: Scores ---------------------- | Column Name | Type | ---------------------- | id | int | | score | decimal | ---------------------- 在 SQL 中&#xff0c;id 是该表的主键。 该表的每一行都包含了一场比赛的分数。Score …...

raid磁盘阵列

在单机时代&#xff0c;采用单块磁盘进行数据存储和读写的方式&#xff0c;由于寻址和读写的时间消耗&#xff0c;导致I/O性能非常低&#xff0c;且存储容量还会受到限制。另外&#xff0c;单块磁盘极其容易出现物理故障&#xff0c;经常导致数据的丢失。此时&#xff0c;RAID技…...

SpringBoot学习笔记-实现微服务:匹配系统(上)

笔记内容转载自 AcWing 的 SpringBoot 框架课讲义&#xff0c;课程链接&#xff1a;AcWing SpringBoot 框架课。 CONTENTS 1. 配置WebSocket2. 前后端WebSocket通信2.1 WS通信的建立2.2 加入JWT验证 3. 前后端匹配业务3.1 实现前端页面3.2 实现前后端交互逻辑3.3 同步游戏地图 …...

重磅!全球首个“绿色黑灯工厂”落户中国,竟然是这家企业……

作者&#xff1a;叶蓁 “52”、“白加黑”、“无人看守作业”&#xff0c;这是九牧“绿色黑灯工厂”的几大关键词。 九牧绿色黑灯工厂不仅是单体产量最大的工厂&#xff0c;也是全球首个入选的“绿色黑灯工厂”。 11月17日&#xff0c;中国节能协会授予九牧5G智能马桶工厂全球…...

go语言学习-异常处理

1、异常场景 网络故障硬件故障组件故障输入错误逻辑错误链路调度错误 2、异常处理方式 # python或者java异常处理 try 可能出现的错误 catch对错误进行处理 xxx,err : 代码 if err ! nil {代码出现错误&#xff0c;需要做处理 }3、自定义错误 有两种方法&#xff1a;1、通过…...

如何使用 JavaScript 实现图片上传并转换为 LaTeX 公式

在本教程中&#xff0c;我们将学习如何使用 JavaScript 创建一个上传图片的功能&#xff0c;并将所选图片转换为 LaTeX 公式。我们将使用 FileReader 对象来读取图片并将其转换为 Base64 格式&#xff0c;然后利用 img2latex API 将其转换为 LaTeX 公式。 1. HTML 结构 首先&…...

深刻理解MySQL8游标处理中not found

深刻理解MySQL8游标处理中not found 最近使用MySQL的游标&#xff0c;在fetch循环过程中&#xff0c;程序总是提前退出 &#xff0c;百思不得其解&#xff0c;经过测试&#xff0c;原来是对于游标处理中not found的定义理解有误&#xff0c;默认是视同Oracle的游标not found定…...

甄知燕千云与SAP、EBS、TC、NS等应用深度集成,智能提单一键畅通,效能一键提升

当今全球化时代下&#xff0c;全球商业环境面临前所未有的机遇和挑战&#xff0c;企业需要持续的业务变革、组织优化来进行降本增效&#xff0c;企业管理软件已成为中小企业、大型企业数字化转型不可或缺的管理工具&#xff0c;企业内管理软件系统也越来越多。 为了适应当前企业…...

第99步 深度学习图像目标检测:SSDlite建模

基于WIN10的64位系统演示 一、写在前面 本期&#xff0c;我们继续学习深度学习图像目标检测系列&#xff0c;SSD&#xff08;Single Shot MultiBox Detector&#xff09;模型的后续版本&#xff0c;SSDlite模型。 二、SSDlite简介 SSDLite 是 SSD 模型的一个变种&#xff0c…...

用EasyAVFilter将网络文件或者本地文件推送RTMP出去的时候发现CPU占用好高,用的也是vcodec copy呀,什么原因?

最近同事在用EasyAVFilter集成在EasyDarwin中做视频拉流转推RTMP流的功能的时候&#xff0c;发现怎么做CPU占用都会很高&#xff0c;但是视频没有调用转码&#xff0c;vcodec用的就是copy&#xff0c;这是什么原因呢&#xff1f; 我们用在线的RTSP流就不会出现这种情况&#x…...

Vatee万腾科技的独特力量:Vatee数字时代创新的新视野

在数字化时代的浪潮中&#xff0c;Vatee万腾科技以其独特而强大的创新力量&#xff0c;为整个行业描绘了一幅崭新的视野。这不仅是一场科技创新的冒险&#xff0c;更是对未来数字时代发展方向的领先探索。 Vatee万腾将创新视为数字时代发展的引擎&#xff0c;成为推动行业向前的…...

【JavaSE】基础笔记 - 异常(Exception)

目录 1、异常的概念和体系结构 1.1、异常的概念 1.2、 异常的体系结构 1.3 异常的分类 2、异常的处理 2.1、防御式编程 2.2、异常的抛出 2.3、异常的捕获 2.3.1、异常声明throws 2.3.2、try-catch捕获并处理 3、自定义异常类 1、异常的概念和体系结构 1.1、异常的…...

QTableWidget——编辑单元格

文章目录 前言熟悉QTableWiget&#xff0c;通过实现单元格的合并、拆分、通过编辑界面实现表格内容及属性的配置、实现表格的粘贴复制功能熟悉QTableWiget的属性 一、[单元格的合并、拆分](https://blog.csdn.net/qq_15672897/article/details/134476530?spm1001.2014.3001.55…...

编译QT Mysql库并集成使用

安装MSVC编译器与Windows 10 SDK 打开Visual Studio Installer&#xff0c;如果已经安装过内容了可能是如下页面&#xff0c;点击修改&#xff08;头一回打开的话不需要这一步&#xff09;&#xff1a; 然后在工作负荷中勾选使用C的桌面开发&#xff0c;它会帮我们勾选好一些…...

利用企业被执行人信息查询API保障商业交易安全

前言 在当今竞争激烈的商业环境中&#xff0c;企业为了保障商业交易的安全性不断寻求新的手段。随着技术的发展&#xff0c;利用企业被执行人信息查询API已经成为了一种强有力的工具&#xff0c;能够帮助企业在商业交易中降低风险&#xff0c;提高合作的信任度。 企业被执行人…...

【深度学习】P1 深度学习基础框架 - 张量 Tensor

深度学习基础框架 张量 Tensor 张量数据操作导入创建张量获取张量信息改变张量张量运算 张量与内存 张量 Pytorch 是一个深度学习框架&#xff0c;用于开发和训练神经网络模型。 而其核心数据结构&#xff0c;则是张量 Tensor&#xff0c;类似于 Numpy 数组&#xff0c;但是可…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

goreplay

1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具&#xff0c;可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长&#xff0c;测试它所需的工作量也会呈指数级增长。GoRepl…...

使用python进行图像处理—图像滤波(5)

图像滤波是图像处理中最基本和最重要的操作之一。它的目的是在空间域上修改图像的像素值&#xff0c;以达到平滑&#xff08;去噪&#xff09;、锐化、边缘检测等效果。滤波通常通过卷积操作实现。 5.1卷积(Convolution)原理 卷积是滤波的核心。它是一种数学运算&#xff0c;…...

深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀”

深入浅出JavaScript中的ArrayBuffer&#xff1a;二进制数据的“瑞士军刀” 在JavaScript中&#xff0c;我们经常需要处理文本、数组、对象等数据类型。但当我们需要处理文件上传、图像处理、网络通信等场景时&#xff0c;单纯依赖字符串或数组就显得力不从心了。这时&#xff…...