Ruby Kamal 的讨论与问题汇总

jicheng1014 · 2023年10月13日 · 最后由 qinsicheng 回复于 2023年12月13日 · 1606 次阅读

自己在技术上向随着年纪变大,变得越来越保守,只不过对 rails 的东西还算是比较感兴趣 最近就想试试刚出的部署工具 kamal (MRSK),利用 docker 和 ssh 技术 做所谓的 0 downtime 的部署,

我在自己的练习过程中遇到了很多问题,我感觉很多人也会都遇到,就集中下资源,解决,我会在后续中尽量的修改这个帖子

我先汇总下最烦躁的网络问题,并再次强调: “强者从不抱怨环境”

问题 1:docker register 拉不了镜像怎么解决?

遇到的第一个问题是,docker hub 镜像拉取慢

国内 docker hub 的连通性基本为 0,但是考虑到 docker 镜像通常都比较大,所以用代理也不是很快, 如果不嫌弃 aliyun 的话 可以在 aliyun 容器镜像服务 里,有个镜像加速器,之后将这个加速器,配置到 docker 的 config 里

我这使用的是 docker desktop,所以可以在设置理的 docker engine 编辑代理

问题 2:想要推私有镜像,但是 docker hub 连通性太差?

docker hub 免费版本提供一个 私有仓库,但是仍然还是这个问题:国内推实在是太慢了... 这里仍然是如果不嫌弃 aliyun 的话,aliyun 有个对应的私有服务,服务也是在“容器镜像服务”板块

个人版本可以拥有 3 个命名空间,300 个项目,目前免费。企业版 1000+ 个项目,费用是 7k+ 一年,

问题 3:Rails 7.1 给的 dockerfile 在构建的时候慢的吐血。。。

实际上是因为安装的时候,去找了 debian 的源,替换就好了,我使用的仍然是 aliyun 的源。。。。

我的解决方案是 创建一个 base_for_mainland_china,之后其他的都由 from base 改为 from base_for_mainland_china

ARG RUBY_VERSION=3.2.2
FROM registry.docker.com/library/ruby:$RUBY_VERSION-slim as base

# 创建 base_for_mainland_china
FROM base as base_for_mainland_china
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources && \
    sed -i 's/security.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources


# 其他...
# 将  FROM base as build 替换为下列语句
FROM base_for_mainland_china as build

# ...

# Final stage for app image
# 将最后的 from base 替换为下列语句
FROM base_for_mainland_china

#...

这样,就能避免拉去软件过慢的情况了。

后续慢慢继续更新

问题 4:由于 ssh 到服务器采用的是 非 22 端口,导致 accessories 在部署的时候,环境变量无法正确安装,导致部署失败

我用的机器的 ssh 不是标准 22 端口 所以配置 accessories 的时候如下所示

accessories:
  db:
    image: postgres:15
    host: 222.222.222.222:12345
    port: 5432
    env:
      clear:
        POSTGRES_USER: 'blog'
        POSTGRES_DB: 'blog_production'
      secret:
        - POSTGRES_PASSWORD
    directories:
      - data:/var/lib/postgresql/data

这里有个坑,port 并不是 ssh 的端口,而是最后 docker 暴露的端口,需要注意下

我在测试项目部署的时候出现了这个问题

说是没有找到 .kamal/env/accessories/blog-db.env

之后结合源码,发现应该是 accessories 的环境变量没同步,

kamal 同步是使用的 kamal env push 进行部署 环境变量,翻看代码,发现问题出在这里

# 在 kamal/lib/cli/env.rb 中

      on(KAMAL.accessory_hosts) do
        KAMAL.accessories_on(host).each do |accessory|
          accessory_config = KAMAL.config.accessory(accessory)
          execute *KAMAL.accessory(accessory).make_env_directory
          upload! StringIO.new(accessory_config.env_file), accessory_config.host_env_file_path, mode: 400
        end
      end

里面的 KAMAL.accessories_on(host) 返回的是 []

而 这个 accessories_on 的实现是

# kamal/lib/kamal/commander.rb 中
  def accessories_on(host)
    config.accessories.select { |accessory| accessory.hosts.include?(host.to_s) }.map(&:name)
  end

此时运行的时候,参数 host 是 SSHKit 提供的,host.to_s 是只有 ip 的,而 accessory.hosts 是包含了 自定义端口的数组,所以筛选代码类似

["222.222.222.222:1234"].include?("222.222.222.222") 此时注定没有返回

如何解决?

目前我是直接改 kamal 的源代码,将 accessories_on 这个代码换成

def accessories_on(host)
  # config.accessories.select { |accessory| accessory.hosts.include?(host.to_s) }.map(&:name)
  config.accessories.select { |accessory| accessory.hosts.any? {|raw_host|  raw_host.include?(host.to_s)} }.map(&:name)
end

问题 5:部署的时候程序报错,导致部署失败,再次部署的时候出现了“ERROR (Kamal::Cli::LockError): Deploy lock found”

kamal 在部署的时候使用了文件锁,所以这里需要将锁清除一下,运行 kamal lock release 即可清除

参考链接

如何在 aws 上使用 kamal 部署 https://jetrockets.com/blog/how-to-use-basecamp-s-kamal-with-aws-and-github

已更新 问题 4-5

我使用 Kamal 部署的时候遇到一个问题,不能推镜像到 docker registry

#25 [auth] user/ticket-box:pull,push token for registry-1.docker.io

#20 ERROR:  push access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed

你知不知道是为了什么?

hungle 回复

排除网络影响的情况下,检查 .env 的 KAMAL_REGISTRY_PASSWORD 是否设置正确了

其实推荐问题 1-2 的解决办法 换国内源算了

我目前遇到的困难是

rails 无法连接到 accessories 的 db,

我之前都是用 docker-compose 弄的,会自动建立一个 network 实现互联互通

但是 kamal 好像并不是这样的,官方视频中给的例子比较奇葩,是直接远程 ip 连接 db,感觉这种方法不太适合

jicheng1014 回复

我是这样搞的

servers:
  web:
    hosts:
      - 52.83.154.1

    options:
      "add-host": docker.internal:host-gateway

env:
  clear:
    REDIS_URL: "redis://docker.internal:6379/2"
hungle 回复

运行一下 kamal registry login

zhongsheng 回复

本质上变回了 docker 网络连接问题

jicheng1014 回复

kamal 部署就是跑的 docker, docker compose 的 network 一样用的

问题 4:由于 ssh 到服务器采用的是 非 22 端口,导致 accessories 在部署的时候,环境变量无法正确安装,导致部署失败

直接配置 .ssh/config

host 用 .ssh/config 中的名字,可以不用加端口,试试呢

lidashuang 回复

或者绑个域名

kamal 中的配置文件中:builder 里,怎么样可以指定 默认的 --platform linux/amd64,linux/arm64参数,改成 --platform linux/amd64 我如果指定

builder:
  multiarch: false

那么它调用是 docker build 而不是 docker buildx build,这样就会导到我这里 build 失败,因为我在 Dockerfile 里的 COPY 命令使用了--link 参数

我先暂时执行 bundle lock --add-platform aarch64-linux这个来解决一下吧。

构建加速的部分真是学到了,非常感谢您的分享。

感谢分享!!!

需要 登录 后方可回复, 如果你还没有账号请 注册新账号