国内环境拉取gcr和k8s镜像

Posted by 梁远鹏 on 2023-02-22 | 阅读 |,阅读约 4 分钟

TOC

前言

本文接下来所有配置都是基于 lank8s服务来做的.

在习惯了 kind 创建 kubernetes 集群后再次尝试了另外的搭建 kubernetes 集群工具: Talos 和 K0s,深深的感受到 Kind 将常用组件镜像都打包到 kindest/node 这个镜像内是多么明智的选择。 尝试 Talos 和 K0s 的首个问题就是镜像无法访问,其次是需要学习新的配置内容,而 Kind 是基于 Kubeadm 的,因此没有带来太多的学习成本,但 Talos 和 K0s 都有一个很实用的特性是支持部署好 kubernetes 集群后 apply 一些用户自定义的 manifests.

Kind 是一个基于 Docker 来实现在容器内跑 kubernetes 的方案,其原理是在容器内使用 kubeadm 部署 kubernetes,我发布了一个同样是长期更新的专门记录 Kind 内容的博客,因此在这里的一些配置问题很可能已经出现在了用kind搭建k8s集群环境这篇文章,如果在本文没有找到你想要的内容可以去那篇文章试试运气,对信息碎片化感到抱歉 (:

Harbor 和 Minikube 以及 Containerd 部分的坑还没填上,热烈欢迎感兴趣的同学提交 PR 更新这部分内容!

相关文章推荐阅读

Talos

这个项目是我觉得非常有意思的一个项目,一个专注于 kubernetes 的容器化 Linux 操作系统,甚至连 SSH 功能都去掉了,一切都通过 API 的方式来操作。

目前来看 Talos 启动 kubernetes 集群的速度比 Kind 慢,测试了多次基本上 Talos 基于 Docker 来启动一个 1 master 和 1 node 的 kubernetes 集群需要 2m18s,而 Kind 启动一个 1 master 和 1 node 的 kubernetes 集群只需要 48s,这个测试结果的前提是已经将需要的镜像全部都缓存在本地了。

因此日常测试需要使用 kubernetes 集群还是推荐 Kind,不过 Talos 的目标是大规模情况下管理容器化 Linux 上的 kubernetes,所以也能够理解速度上比 Kind 慢,而且速度也已经足够快了。

talosctl cluster create --provisioner docker \
    --registry-mirror registry.k8s.io=http://172.17.0.1:5001 \
    --registry-mirror gcr.io=http://172.17.0.1:5003 \
    --image ghcr.io/siderolabs/talos:v1.4.5 --install-image ghcr.io/siderolabs/installer:v1.4.5

Kind

由于 Kind 使用的 CRI 是 Containerd,因此如果你熟悉 Containerd 的配置方式的话,那么为 Kind 配置镜像仓库会显得很容易,关键配置如下:

containerdConfigPatches:
- |-
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."gcr.io"]
    endpoint = ["https://gcr.lank8s.cn"]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
    endpoint = ["https://registry.lank8s.cn"]  

具体可以看看用kind搭建k8s集群环境

k0s

目前 k0s 正在考虑将项目捐赠给 CNCF,可以关注:Future of k0s, a CNCF project?

k3s 将 kubernetes 基本的组件都打包成一个二进制,然而依然需要 kubelet 和 CRI CNI 等运行时,而 K0s 这个项目将所有内容都打包成一个单一的二进制,也是挺有意思的。

version: "3.9"
services:
  k0s:
    container_name: k0s
    image: docker.io/k0sproject/k0s:latest
    command: k0s controller --config=/etc/k0s/config.yaml --enable-worker
    hostname: k0s
    privileged: true
    volumes:
      - "/var/lib/k0s"
    tmpfs:
      - /run
      - /var/run
    ports:
      - "5443:5443"
      - 9443:9443
    network_mode: "bridge"
    environment:
      K0S_CONFIG: |-
        apiVersion: k0s.k0sproject.io/v1beta1
        kind: ClusterConfig
        metadata:
          creationTimestamp: null
          name: k0s
        spec:
          images:
            konnectivity:
              image: registry.lank8s.cn/kas-network-proxy/proxy-agent
            metricsserver:
              image: registry.lank8s.cn/metrics-server/metrics-server
            kubeproxy:
              image: registry.lank8s.cn/kube-proxy
            coredns:
              image: registry.lank8s.cn/coredns/coredns
            pause:
              image: registry.lank8s.cn/pause
          api:
            k0sApiPort: 9443
            port: 5443
            sans:
              - 192.168.1.77
              - 172.17.0.1
              - 172.18.0.1
              - 10.5.0.1
              - fe80::cf76:3e83:d99c:2819
              - fe80::42:3eff:feb3:ace1
              - fc00:f853:ccd:e793::1
              - fe80::1
              - fe80::42:65ff:fe15:bab6
              - fe80::f0da:a2ff:fe07:c45c
              - fe80::b038:81ff:fe28:7eac
            tunneledNetworkingMode: false
          controllerManager: {}
          extensions:
            helm:
              charts: null
              repositories: null
            storage:
              create_default_storage_class: false
              type: external_storage
          installConfig:
            users:
              etcdUser: etcd
              kineUser: kube-apiserver
              konnectivityUser: konnectivity-server
              kubeAPIserverUser: kube-apiserver
              kubeSchedulerUser: kube-scheduler
          konnectivity:
            adminPort: 8133
            agentPort: 8132
          network:
            calico: null
            clusterDomain: cluster.local
            dualStack: {}
            kubeProxy:
              iptables:
                minSyncPeriod: 0s
                syncPeriod: 0s
              ipvs:
                minSyncPeriod: 0s
                syncPeriod: 0s
                tcpFinTimeout: 0s
                tcpTimeout: 0s
                udpTimeout: 0s
              metricsBindAddress: 0.0.0.0:10249
              mode: iptables
            kuberouter:
              autoMTU: true
              hairpin: Enabled
              ipMasq: false
              metricsPort: 8080
              mtu: 0
              peerRouterASNs: ""
              peerRouterIPs: ""
            nodeLocalLoadBalancing:
              envoyProxy:
                apiServerBindPort: 7443
                image:
                  image: quay.io/k0sproject/envoy-distroless
                  version: v1.24.1
                konnectivityServerBindPort: 7132
              type: EnvoyProxy
            podCIDR: 10.244.0.0/16
            provider: kuberouter
            serviceCIDR: 10.96.0.0/12
          scheduler: {}
          storage:
            type: etcd
          telemetry:
            enabled: true
        status: {}

containerd

基本上就是上面 Kind 提供的配置,但暂时没有单独整理.

Kata Containers

TODO

K3s

/etc/rancher/k3s/registries.yaml 中配置 registry.k8s.io 和 gcr.io 的镜像加速,如下所示:(如果已经有这个文件了可以更新,添加 对应的配置)

cat >> /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
  "registry.k8s.io":
    endpoint:
      - "https://registry.lank8s.cn"
  "gcr.k8s.io":
    endpoint:
      - "https://gcr.lank8s.cn"
EOF
systemctl restart k3s

crio

关键配置如下:

[[registry]]
location = "gcr.io"

[[registry.mirror]]
location = "gcr.lank8s.cn"


[[registry]]
location = "registry.k8s.io"

[[registry.mirror]]
location = "registry.lank8s.cn"

官方文档: https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md

distribution registry (docker registry)

distribution 配置镜像代理非常简单,只需要传递一个环境变量就可以了,下面是一个 docker-compose 的配置示例:

version: "3.8"
services:
    registry:
      image: registry:2
      restart: always
      ports:
        - 5000:5000
      environment:
        - REGISTRY_PROXY_REMOTEURL=https://registry.lank8s.cn

zot registry

下面是一个配置示例, zot 支持对同一个镜像源配置多个上游,这一点非常实用.

{
	"distspecversion":"1.1.0-dev",
	"storage": {
		"rootDirectory": "/tmp/zot_to_sync",
		"dedupe": false,
		"gc": false
	},
	"http": {
		"address": "127.0.0.1",
		"port": "8081"
	},
	"log": {
		"level": "debug"
	},
	"extensions": {
		"sync": {
			"registries": [
				{
					"urls": [
						"https://registry.lank8s.cn"
					],
					"onDemand": false,
					"tlsVerify": false,
					"PollInterval": "30s",
					"content": [
						{
							"prefix": "/**"
						}
					]
				}
			]
		},
		"scrub": {
			"interval": "24h"
		}
	}
}

harbor

kubeadm

image-repository 参数指向 registry.lank8s.cn 即可.

kubeadm init  --image-repository=registry.lank8s.cn

这里需要注意的一点是 coredns 也需要配置镜像地址,例如 registry.lank8s.cn/coredns, 因此目前不能用一条命令来进行 kubeadm 初始化了,需要指定配置文件,具体原因看: https://liangyuanpeng.com/post/kubeadm-config-note-long-term

后续考虑在 registry.lank8s.cn 服务层做一层适配,做到和原有的 registry.k8s.io 相同的体验.

minikube

TODO

docker

dockerhub 只支持配置 dockerhub 的镜像加速源,因此如果你希望直接用 docker 拉取 registry.k8s.io 的容器镜像,只需要将 registry.k8s.io 改为 registry.lank8s.cn 就可以了.

docker pull registry.lank8s.cn/kube-apiserver:v1.26.0

如果希望机器上的 docker 可以直接拉取到 registry.k8s.io,也有一个曲线救国的方法,需要做以下几件事:

  1. 将 registry.k8s.io 配置为 insecure 类型的注册中心,这会让docker 拉取 registry.k8s.io 镜像时通过 http 请求而不是 https 请求
  2. 部署一个 nginx,将流量反向代理到 registry.lank8s.cn
  3. 配置 hosts,将 registry.k8s.io 映射为本地IP,例如 192.168.3.160 (你的机器IP).

/etc/docker/daemon.json

{
    "insecure-registries": ["registry.k8s.io"]
}

nginx 配置如下:

server {
    listen   80;
    listen [::]:80;

    access_log  /var/log/nginx/host.access.log  main;

    location / {
        proxy_pass https://registry.lank8s.cn/;
        proxy_set_header Host registry.lank8s.cn;
        proxy_ssl_name registry.lank8s.cn;
        proxy_ssl_server_name on;
        proxy_set_header X-Real-IP $remote_addr;
        add_header Access-Control-Allow-Headers Authorization;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

总体流量走向如下:

docker pull —http—> nginx —-> registry.lank8s.cn

通过这样的方式可以让你在机器上使用 docker pull 拉取 registry.k8s.io 镜像时通过nginx反向代理去请求 registry.lank8s.cn,这可以省去一些重新给容器镜像打 tag 的过程,但这不是银弹,无法适用所有场景.

iSula

util_test.go:101: Exist is not expact! key:etcd-servers want args:[--etcd-servers=http://192.168.66.2:2379 --etcd-prefix=/registry], got args:[--etcd-servers=http://192.168.66.2:3379 --etcd-prefix=/registry]

目前还没用过这个容器引擎(好奇除了项目研发公司,还有谁用?),有了解的朋友欢迎提交 PR 更新这一块,感谢!:)

Podman

目前来说我基本上没怎么用 podman,因此这部分非常欢迎提供参考或 PR 更新.

微信公众号

扫描下面的二维码关注我们的微信公众号,第一时间查看最新内容。同时也可以关注我的Github,看看我都在了解什么技术,在页面底部可以找到我的Github。

wechat-qrcode