【免费架构】Heroku 不免费了,何去何从之 Keycloak 的容器化部署之路
共 4467字,需浏览 9分钟
·
2023-03-08 02:34
前情提要
好几年前,我 fork 了一个项目(https://github.com/Jeff-Tian/keycloak-heroku)并做了一些修改,将 Keycloak 适配到了 Heroku 的免费 Dyno 上,并添加了一键部署按钮。但是,如《Free Arch: Bye-bye to Heroku》所述,Heroku 不再免费。现在这个仓库,仍然可以一键部署到 Heroku 上,但是,可能产生费用。做为免费架构的拥趸,我必须找一个替代方案。
如果你看过我前面的文章,没错,是熟悉的味道:《免费架构:Heroku 不免费了,何去何从之 eggjs 的容器化部署之路 》。
本文将参考上文,对 jeff-tian/keycloak-heroku 项目做一个改造,将它部署到 Okteto。
在线演示
原来的 Heroku 站点是: https://keycloak.jiwai.win ,本来这个站点可以一直访问,Heroku 取消免费之后,我就将 Free Dyno 改成了最便宜的共享 Dyno,一个月 5 美元,但是每月有访问限额。如今只在月初可以访问,这个额度一旦用完就访问不了了。
替代方案部署在 Okteto,域名是: https://keycloak-jeff-tian.cloud.okteto.net/。
容器化
要部署到 Okteto 以及任何一个 k8s 集群,第一步是需要将应用容器化。我看了一下,原来我已经将 keycloak-heroku 项目容器化了,只是一直没有部署到 k8s 环境里。
本地运行
之前容器化后,只在本地以 docker compose up
的方式运行,然后打开 http://localhost:8080 。
如今要部署到集群,正好可以重用。
Dockerfile
项目里已经写好了 Dockerfile,只是文件名叫 Dockerfile.test:
FROM quay.io/keycloak/keycloak:latest
COPY idps/wechat-mobile/keycloak-services-social-weixin.jar \
/opt/keycloak/providers/
COPY idps/wechat-mobile/templates/realm-identity-provider-weixin-ext.html \
/opt/keycloak/themes/base/admin/resources/partials
COPY idps/wechat-mobile/templates/realm-identity-provider-weixin.html \
/opt/keycloak/themes/base/admin/resources/partials
COPY idps/wecom/keycloak-services-social-wechat-work.jar \
/opt/keycloak/providers/
COPY idps/wecom/templates/realm-identity-provider-wechat-work.html \
/opt/keycloak/themes/base/admin/resources/partials
COPY idps/wecom/templates/realm-identity-provider-wechat-work-ext.html \
/opt/keycloak/themes/base/admin/resources/partials
CMD ["start-dev", "--hostname-strict=false"]
打包脚本
要容器化打包,可以写个脚本来完成:
docker build -f Dockerfile.test -t jefftian/keycloak:"$1" .
docker images
docker run --network host -e CI=true -d -p 127.0.0.1:8080:8080 --name keycloak:"$1" jefftian/keycloak
docker ps | grep -q keycloak
docker ps -aqf "name=keycloak$"
docker push jefftian/keycloak:"$1"
docker logs $(docker ps -aqf name=keycloak$)
curl localhost:8080 || docker logs $(docker ps -aqf name=keycloak$)
docker kill keycloak || echo "keycloak killed"
docker rm keycloak || echo "keycloak removed"
注意它接收一个参数,用来做容器的标记:
SOPS
由于要将项目跑起来,需要一些秘密数据,想将它们纳入代码管理,但又不想明文展示出来,那就可以利用 SOPS 了。详情可以参考上文《免费架构:Heroku 不免费了,何去何从之 eggjs 的容器化部署之路 》,以及《加密 Kubernetes 集群中的敏感信息》。
配置 GitHub Action Secrets
参考上文,在最终的 CICD 脚本中需要用到一些密码数据:
配置 CICD 流水线
先准备一些 k8s 声明文件
详见项目的 k8s 文件夹,有 secrets.yaml、deployments.yaml、service.yaml 以及 kustomization.yaml 文件。
准备 github workflow
这个文件内容如下:
# This workflow will do a clean installation of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: CICD
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
schedule:
- cron: '0 */12 * * *'
jobs:
build-docker-image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: echo "${{secrets.DOCKER_PASSWORD}}" | docker login -u "${{secrets.DOCKER_USERNAME}}" --password-stdin
- run: git_hash=$(git rev-parse ${{ github.sha }})
- run: sh .github/dockerize.sh ${{ github.sha }}
deploy-okteto:
runs-on: ubuntu-latest
needs: build-docker-image
steps:
- uses: actions/checkout@v3
- run: mkdir ${HOME}/.aws
- run: echo -e "[lambda-doc-rotary]\naws_access_key_id = ${{secrets.AWS_ACCESS_KEY}}\naws_secret_access_key = ${{secrets.AWS_SECRET_KEY}}\n" > ~/.aws/config
- run: wget https://github.com/mozilla/sops/releases/download/v3.7.3/sops-v3.7.3.linux.amd64
- run: sudo cp sops-v3.7.3.linux.amd64 /usr/local/bin/sops
- run: sudo chmod +x /usr/local/bin/sops
- run: curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
- run: chmod +x ./kubectl
- run: sudo mv ./kubectl /usr/local/bin/kubectl
- run: mkdir ${HOME}/.kube
- run: npm i -g k8ss
- run: echo -e "machine github.com\n login ${{secrets.GH_TOKEN}}" > ~/.netrc
- run: git clone https://github.com/Jeff-Tian/k8s-config.git ${HOME}/k8s-config
- run: k8ss switch --cluster=okteto --namespace=jeff-tian
- run: sops -d k8s/secrets.yaml --aws-profile lambda-doc-rotary | kubectl apply -f -
- run: kubectl apply -k k8s
- run: kubectl set image deployment keycloak keycloak=jefftian/keycloak:${{ github.sha }}
这个流水线的效果如下图:
完成: 部署到 Okteto
部署到 Okteto 后:
打开自动分配的网址:
总结
耶!我们又重新拥有了属于自己的免费的 Keycloak 实例!