好几年前,我 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:latestCOPY 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/partialsCOPY idps/wechat-mobile/templates/realm-identity-provider-weixin.html \/opt/keycloak/themes/base/admin/resources/partialsCOPY 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/partialsCOPY idps/wecom/templates/realm-identity-provider-wechat-work-ext.html \/opt/keycloak/themes/base/admin/resources/partialsCMD ["start-dev", "--hostname-strict=false"]打包脚本
要容器化打包,可以写个脚本来完成:
docker build -f Dockerfile.test -t jefftian/keycloak:"$1" .docker imagesdocker run --network host -e CI=true -d -p 127.0.0.1:8080:8080 --name keycloak:"$1" jefftian/keycloakdocker ps | grep -q keycloakdocker 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-actionsname: CICDon:push:branches: [ master ]pull_request:branches: [ master ]schedule:- cron: "0 */12 * * *"jobs:build-docker-image:runs-on: ubuntu-lateststeps:- 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-latestneeds: build-docker-imagesteps:- 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 实例!