V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
klo424
V2EX  ›  Kubernetes

请教 k8s 国内网络访问不了镜像问题的解决方案

  •  
  •   klo424 · 2022-05-07 09:12:22 +08:00 · 7201 次点击
    这是一个创建于 932 天前的主题,其中的信息可能已经有所发展或是发生改变。

    由于国内网络问题,k8s 的官方镜像在腾讯云服务器上访问不到,导致一些错误。

    我是在安装 nginx-ingress 遇到的问题。

    在执行了 kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml 后,发现官方镜像访问超时。

    官方镜像访问超时

    我在我自己电脑(有代理)上试了下 docker 直接拉取,也是超时的。

    docker 直接拉取超时

    这么看,代理也是行不通的,我又尝试了修改 deploy.yaml 文件中的镜像源,如下:

    # 替换 k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
    
    docker.io/liangjw/kube-webhook-certgen:v1.1.1@sha256:23a03c9c381fba54043d0f6148efeaf4c1ca2ed176e43455178b5c5ebf15ad70
    
    
    # 替换 k8s.gcr.io/ingress-nginx/controller:v1.2.0@sha256:d8196e3bc1e72547c5dec66d6556c0ff92a23f6d0919b206be170bc90d5f9185
    
    docker.io/dyrnq/ingress-nginx-controller:v1.2.0@sha256:2746adf7d60c782b83f6fa6e1ceb938878b9f5b16c217e530ba8895f94221a04
    

    替完后重新 kubectl apply -f https://cdn.jsdelivr.net/gh/kade-code/k8s-mirror@master/deploy3.yaml 就会报错。

    kubectl apply 报错

    这个错误我 google 了,说是不让改里面的字段,我也试了把之前的 deployment 删掉,也是不行,就无解了,然后改镜像源的方案我就放弃了。

    其间,我查找了 github 的 issue ,https://github.com/kubernetes/ingress-nginx/issues/6335#issuecomment-1011850699,也没有一个能解决我的问题的。

    也尝试过 docker pull 镜像源,然后改成官方源的 tag ,也是不起作用。

    折腾了 2 天,实在没有办法,特来请教,希望大佬们支支招。

    第 1 条附言  ·  2022-05-07 11:44:44 +08:00

    解决方案:

    error when applying patch: field is immutable #5884

    先删除原来的部署

    kubectl delete -f <doployment_file_location>
    

    再应用新的部署

    kubectl apply -f <doployment_file_location>
    
    56 条回复    2023-06-07 16:04:16 +08:00
    Illusionary
        1
    Illusionary  
       2022-05-07 09:28:06 +08:00
    docker pull 走 http 代理
    hhshenhuaxx
        2
    hhshenhuaxx  
       2022-05-07 09:30:29 +08:00
    好好研究下你那个代理软件吧。要么开全局代理 保证命令行也能 curl google.com ,要么在 docker 上配置 Proxies ,指向自己本机代理暴露出来的地址。
    hzfyjgw
        3
    hzfyjgw  
       2022-05-07 09:31:06 +08:00
    感觉这个 image 的 tag 不太合规,照理应该不能存在 2 个:的,尝试换个短 tag 的试试
    wd
        4
    wd  
       2022-05-07 09:31:18 +08:00 via iPhone
    不太明白你替换了 image 之后为啥 apply 的还是那个 url 。你不应该 apply 本地你替换之后的吗?那个字段不允许改是正常的,你这样的情况可以删除之后在使用你修改的文件 apply
    tomqin
        5
    tomqin  
       2022-05-07 09:31:32 +08:00
    最不济就是本地 docker pull `k8s.gcr.io` 的镜像然后 `docker save` ,scp 到服务器再 `docker load`
    wd
        6
    wd  
       2022-05-07 09:31:56 +08:00 via iPhone
    另外本地改 image tag 应该也是可行的
    owlbatex
        7
    owlbatex  
       2022-05-07 09:39:53 +08:00
    如果是自己家的话,搞个路由器吧,走路由器代理,或者开个 op 虚拟机,旁网关代理机器流量
    owlbatex
        8
    owlbatex  
       2022-05-07 09:43:20 +08:00
    其实代理软件也是可以设置代理局域网其他设备的流量的,你在自己电脑上拉取失败可以试试全局
    ckxZzz
        9
    ckxZzz  
       2022-05-07 09:43:45 +08:00
    可以去 hub.docker 拉镜像后改 tag
    hzfyjgw
        10
    hzfyjgw  
       2022-05-07 09:46:05 +08:00
    root@xxxx:~# docker pull k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
    k8s.gcr.io/ingress-nginx/kube-webhook-certgen@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660: Pulling from ingress-nginx/kube-webhook-certgen
    ec52731e9273: Pull complete
    b90aa28117d4: Pull complete
    Digest: sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
    Status: Downloaded newer image for k8s.gcr.io/ingress-nginx/kube-webhook-certgen@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
    k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
    root@xxxx:~# docker images
    REPOSITORY TAG IMAGE ID CREATED SIZE
    k8s.gcr.io/ingress-nginx/kube-webhook-certgen <none> c41e9fcadf5a 6 months ago 47.7MB


    带 2 个: 的长 tag 拉取下来的之后 tag 是<none>
    只要 tag 换成 v1.1.1 就可以了
    ration
        11
    ration  
       2022-05-07 09:46:33 +08:00 via Android
    试过改 deploy.yaml 里的地址可行
    konakona
        12
    konakona  
       2022-05-07 09:51:49 +08:00
    1. google 生态的开发要准备科学上网(必备)
    2. docker 环境设置代理
    3. 命令行的配置设置代理,比如:export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890

    就可以了
    klo424
        13
    klo424  
    OP
       2022-05-07 09:56:01 +08:00
    @Illusionary @hhshenhuaxx #1 #2 我开了全局代理,访问 google 没有问题。

    ![全局代理访问 google]( https://s3.bmp.ovh/imgs/2022/05/07/9f2807cedcdea9c0.png)
    klo424
        14
    klo424  
    OP
       2022-05-07 09:58:07 +08:00
    @hzfyjgw #3 短的我也试过,一样的错误,就是不生效。
    mysalt
        15
    mysalt  
       2022-05-07 09:58:36 +08:00
    # 首先确保国外有 Trojan 服务端

    # 在腾讯云服务器上安装 Trojan 客户端
    $ tar -xvf trojan-1.16.0-linux-amd64.tar.xz
    $ mv trojan/trojan /usr/local/bin

    # 配置 Trojan 客户端配置文件
    $ mkdir /etc/trojan
    $ cat > /etc/trojan/config.json <<-EOF
    {
    "run_type": "client",
    "local_addr": "0.0.0.0",
    "local_port": 1080,
    "remote_addr": "xxxx",
    "remote_port": 443,
    "password": [
    "xxxxx"
    ],
    "log_level": 1,
    "ssl": {
    "verify": false,
    "verify_hostname": false,
    "cert": ""
    }
    }
    EOF

    # 配置 Systemd 的 Trojan 客户端服务
    $ cat > /etc/systemd/system/trojan.service <<-EOF
    [Unit]
    Description=trojan
    After=network.target

    [Service]
    Type=simple
    User=nobody
    Restart=on-failure
    RestartSec=5s
    ExecStart=/usr/local/bin/trojan -c /etc/trojan/config.json -l /var/log/trojan.log
    ExecReload=/bin/kill -HUP $MAINPID
    LimitNOFILE=1048576

    [Install]
    WantedBy=multi-user.target
    EOF

    # 创建日志文件
    $ touch /var/log/trojan.log
    $ chown nobody:nogroup /var/log/trojan.log

    # 启动 Trojan
    $ systemctl enable trojan
    $ systemctl start trojan

    # 验证代理是否成功
    $ curl ip.sb --socks5 127.0.0.1:1080

    # 在 Systemd 中配置 Docker Daemon 使用 SOCKS5 代理,其中代理 IP 改为自己的 Trojan 客户端 IP
    $ mkdir -p /etc/systemd/system/docker.service.d
    $ tee /etc/systemd/system/docker.service.d/socks5-proxy.conf <<-'EOF'
    [Service]
    Environment="HTTP_PROXY=socks5://172.27.111.113:1080/" "HTTPS_PROXY=socks5://172.27.111.113:1080/" "NO_PROXY=localhost,127.0.0.1,docker.io,yanzhe919.mirror.aliyuncs.com,99nkhzdo.mirror.aliyuncs.com,*.aliyuncs.com,*.mirror.aliyuncs.com,registry.docker-cn.com,hub.c.163.com,hub-auth.c.163.com,"
    EOF

    # 重启 Docker Daemon 服务
    $ systemctl daemon-reload
    $ systemctl restart docker
    $ systemctl show --property=Environment docker # 查看环境变量是否生效

    # 测试能否下载 Google 镜像
    $ docker pull k8s.gcr.io/kube-proxy:v1.22.0
    hzfyjgw
        16
    hzfyjgw  
       2022-05-07 10:01:24 +08:00
    @klo424 #14 只要 image 的 tag 不要带 2 个: 照理没问题了,你 yaml 文件里的 image 的 tag 不需要这么长的
    mysalt
        17
    mysalt  
       2022-05-07 10:06:15 +08:00
    @mysalt 以上的步骤是我在国内云环境验证过可以成功的。如果是本地,直接搞个软路由吧,也不用折腾什么 HTTP ,SOCK5 这种代理。
    klo424
        18
    klo424  
    OP
       2022-05-07 10:08:18 +08:00
    @wd #4 apply 的 url 我换了,原来是 https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.0/deploy/static/provider/cloud/deploy.yaml ,换的 https://cdn.jsdelivr.net/gh/kade-code/k8s-mirror@master/deploy3.yaml ,我刚才又传到服务器本地试了下,还是一样的错误。
    那个字段不允许改的话,具体是哪个字段呢?我只修改了 image 字段的值,别的都没改,所以我理解是这个文件就不能改。
    #5 这个我也试了,改 tag ,但 apply 后,k8s 还是会 pull error 。
    XiLingHost
        19
    XiLingHost  
       2022-05-07 10:10:02 +08:00
    我的解决方案是在内网搭一个 nexus 做 k8s.gcr.io 的 docker 镜像,然后把 yml 里的 repo 改成内网的 repo
    stille
        20
    stille  
       2022-05-07 10:15:59 +08:00
    dockerproxy.com

    这个可以临时解决问题么?
    klo424
        21
    klo424  
    OP
       2022-05-07 10:16:07 +08:00
    klo424
        22
    klo424  
    OP
       2022-05-07 10:20:03 +08:00
    @tomqin #5
    @wd #6
    @ckxZzz #9
    @hzfyjgw #10
    试过改 tag 了,不起作用。
    ![改 tag]( https://s3.bmp.ovh/imgs/2022/05/07/7937e44bb7d44be0.png)
    klo424
        23
    klo424  
    OP
       2022-05-07 10:21:57 +08:00
    @ration #11
    @XiLingHost #19
    我现在改了 yml 文件,但问题是报错,无法生效。
    klo424
        24
    klo424  
    OP
       2022-05-07 10:23:42 +08:00
    @stille #20 这个我也试过😂,我 docker 加了这个镜像,也是拉不了。
    klo424
        25
    klo424  
    OP
       2022-05-07 10:24:56 +08:00
    @mysalt #15 Trojan 服务端没有呢😂
    etby
        26
    etby  
       2022-05-07 10:31:22 +08:00
    自建仓库是最好的,还可以用阿里云等免费的,实在不行上传到 DockerHub 使用国内 mirrors 试试
    ncepuzs
        27
    ncepuzs  
       2022-05-07 10:31:59 +08:00
    Trojan 服务端没有,你不会临时开台按时计费的非大陆地区 VPS 装一下吗?
    上面将镜像下载到本地然后改 tag 之类的很明显是有用的,不知道到你这儿怎么就没用了
    另外,Windows 上 SS(R) 之类的全局代理又不是所有软件都会读取和使用……
    hhshenhuaxx
        28
    hhshenhuaxx  
       2022-05-07 10:32:27 +08:00
    @klo424 要在命令行通过 curl 或者 wget 也能访问才行,因为你 docker pull 命令是在命令行执行的。
    mysalt
        29
    mysalt  
       2022-05-07 10:32:52 +08:00
    @klo424 DigitalOcean 开台机器配置下吧,k8s 安装完再关闭。另外不建议用各种替代镜像或者什么仓库,我原来折腾过很久,大概率要么不维护,要么要改一大串东西,不值当。
    stille
        30
    stille  
       2022-05-07 10:36:53 +08:00
    @klo424 能具体点? 因为我没搞过 k8s,不知道你具体的场景,如果是改 daemon.json 应该是 k8s.dockerproxy.com
    liuhan907
        31
    liuhan907  
       2022-05-07 10:40:48 +08:00 via Android
    不是,你直接把 yaml 里面的 image 换成云的镜像不就可以了,为什么会这么折腾?
    julyclyde
        32
    julyclyde  
       2022-05-07 10:50:40 +08:00
    kubelet 有个参数
    pod-infra-container-image
    klo424
        33
    klo424  
    OP
       2022-05-07 10:53:10 +08:00
    @ncepuzs #27 Trojan 服务端我没有搞过,不知道怎么弄,如果别的方法都不行,我就去试试看。但按理说改 tag 和改镜像都应该可以,我也不知道为什么到了我这不行,可能被我设置来设置去的搞坏了吧😂
    @hhshenhuaxx #28 另外我又试了下 curl google.com ,是可以的。
    https://imgur.com/g4tscwV
    klo424
        34
    klo424  
    OP
       2022-05-07 11:00:00 +08:00
    @stille #30 直接 docker pull k8s.dockerproxy.com/ingress-nginx/kube-webhook-certgen:v1.1.1 是好使的,改 daemon.json 不行呢?
    https://imgur.com/undefined
    klo424
        35
    klo424  
    OP
       2022-05-07 11:00:46 +08:00
    @liuhan907 #31 这个前面说过很多次了,报错,不生效。
    hzfyjgw
        36
    hzfyjgw  
       2022-05-07 11:12:02 +08:00
    @klo424 #22 现在已经不是你的镜像拉取有问题了,是 error when apply patch ,现在是你 yaml 文件其他的地方的配置错了
    klo424
        37
    klo424  
    OP
       2022-05-07 11:14:34 +08:00
    @hzfyjgw #36 应该是这样的,不过我是拷贝的官方文件,只修改了三个 image 的值,不知道有什么问题。
    klo424
        38
    klo424  
    OP
       2022-05-07 11:16:57 +08:00
    @julyclyde #32 我看了我的配置文件,没有用到这个参数,应该是正常的吧?
    stille
        39
    stille  
       2022-05-07 11:21:43 +08:00
    @klo424 我测试 daemon.json 没问题.
    无论是 docker pull ingress-nginx/kube-webhook-certgen:v1.1.1 还是 docker pull k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1 都没问题

    https://i.ioiox.com/2022/05/07/20220507112005PQUbAP.jpg
    https://i.ioiox.com/2022/05/07/202205071120066iJ6pJ.jpg
    julyclyde
        40
    julyclyde  
       2022-05-07 11:21:57 +08:00
    @klo424 把这个参数改掉,就可以不访问 gcr.io
    stille
        41
    stille  
       2022-05-07 11:22:41 +08:00
    你这个需求还是得搞定 daemon.json,需要 reload daemon 和重启 docker.

    这样不会再你本身项目中来修改一些配置.
    stille
        42
    stille  
       2022-05-07 11:25:34 +08:00
    @stille 接 39 楼

    不过值得注意的是,daemon 加的是 k8s 的代理.拉取确实是不需要加 k8s.gcr.io 前缀,但是 docker 默认最后还是加 docker.io,所以还是用原始的镜像地址拉取 k8s.gcr.io/xxx/xxx
    klo424
        43
    klo424  
    OP
       2022-05-07 11:37:07 +08:00
    @liuhan907 解决了,哈哈哈哈哈哈哈哈哈哈!!!
    多谢提醒!感谢!感谢!~

    之前搜 field is immutable 搜到的是 kubectl delete deployment ,这个只删除了 deployment 。
    刚刚搜 error when apply patch ,搜到了 https://github.com/kubernetes/ingress-nginx/issues/5884#issuecomment-946298539 ,试了先 kubectl delete -f <doployment_file_location> 再 kubectl apply -f <doployment_file_location>,就可以了,不报错了。
    见图,https://s3.bmp.ovh/imgs/2022/05/07/3f4724878bbd85d2.png
    kubectl delete 不止删除了 deployment ,还删除了其他的一些,之前都没有删掉,所以 apply 时还是之前的 ingress-nginx-admission-create ,就报那个 field is immutable 的错误了。

    结帖!
    klo424
        44
    klo424  
    OP
       2022-05-07 11:37:49 +08:00
    @stille @julyclyde 谢了,已经解决了。
    klo424
        45
    klo424  
    OP
       2022-05-07 11:41:11 +08:00
    @hzfyjgw #43 刚才过于兴奋,@错人了😂
    多谢提醒!感谢!感谢!~
    sujin190
        46
    sujin190  
       2022-05-07 13:51:12 +08:00
    这个问题确实烦人,全新安装的时候依赖镜像又很多,除了 k8s.gcr.io ,还有 gcr.ioproduction.cloudflare.docker.comingresses.meta.k8s.io 都访问有问题,production.cloudflare.docker.com 这个好多不是从这地方发拉取的镜像中间也会走到这个去,后来没办法了去每个节点上都用 iptables 把这几个域名的访问都重定向都代理去了才顺顺利利的装完了
    Frankcox
        47
    Frankcox  
       2022-05-07 16:10:13 +08:00
    想起不知道在哪看见有人说的,每次安装 kubernetes 集群,都会发自内心感恩强大的祖国
    oceanxie
        48
    oceanxie  
       2022-05-07 18:13:40 +08:00
    我本地的话就走的 docker 先拉镜像的,可以试试 https://oceanxie.cn/2021/09/14/docker%E9%80%9A%E8%BF%87ssr%E4%BB%A3%E7%90%86/
    jxxz
        49
    jxxz  
       2022-05-07 18:21:38 +08:00
    kubesphere 的 kubekey 工具支持从国内镜像下载安装 k8s 集群的,也提供了离线部署方式
    对国内网络比较友好
    zxbutton
        50
    zxbutton  
       2022-05-07 23:07:25 +08:00
    旁路由吧,这个一劳永逸
    uncat
        51
    uncat  
       2022-05-08 06:57:45 +08:00
    Add your proxy settings and restart docker daemon

    [Imgur]( https://imgur.com/7kL1a5i)
    uncat
        52
    uncat  
       2022-05-08 06:59:08 +08:00
    Add your proxy settings and restart docker daemon
    ![howto setup docker behind a http proxy]( https://i.imgur.com/7kL1a5i)
    SakataToushirou
        53
    SakataToushirou  
       2022-05-09 08:06:56 +08:00 via Android
    你可能需要一个支持 TUN 模式的代理
    xin053
        54
    xin053  
       2022-05-09 09:11:44 +08:00
    可以利用 github action 帮你下载国外镜像,并推送到 docker hub ,或者你自己的私仓,参考:
    https://github.com/xin053/mirror_docker_image
    yyttrr
        55
    yyttrr  
       2022-05-15 11:28:43 +08:00
    生产环境一定要用自建镜像仓库,出现过官方镜像小版本变更引起的 bug ,镜像 tag 没变实际上里面变动了一个小版本
    LanLiang
        56
    LanLiang  
       2023-06-07 16:04:16 +08:00
    太简单了,只需要为 gcr.ioregistry.k8s.io 配置镜像源为 gcr.lank8s.cnregistry.lank8s.cn 就可以愉快了拉取镜像了!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2517 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 02:32 · PVG 10:32 · LAX 18:32 · JFK 21:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.