Skip to content

Commit

Permalink
Merge pull request cmliu#32 from imdingtalk/main
Browse files Browse the repository at this point in the history
支持cri直接使用镜像仓库mirror的能力
  • Loading branch information
cmliu authored Aug 12, 2024
2 parents 0301111 + c788b2a commit 3f2f161
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 52 deletions.
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,79 @@ EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
```
### 3. 配置常见仓库的镜像加速
#### 3.1 配置
Containerd 较简单,它支持任意 `registry``mirror`,只需要修改配置文件 `/etc/containerd/config.toml`,添加如下的配置:
```yaml
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://xxxx.xx.com"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
endpoint = ["https://xxxx.xx.com"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."gcr.io"]
endpoint = ["https://xxxx.xx.com"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."ghcr.io"]
endpoint = ["https://xxxx.xx.com"]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."quay.io"]
endpoint = ["https://xxxx.xx.com"]
```
`Podman` 同样支持任意 `registry``mirror`,修改配置文件 `/etc/containers/registries.conf`,添加配置:
```yaml
unqualified-search-registries = ['docker.io', 'k8s.gcr.io', 'gcr.io', 'ghcr.io', 'quay.io']

[[registry]]
prefix = "docker.io"
insecure = true
location = "registry-1.docker.io"

[[registry.mirror]]
location = "https://xxxx.onrender.com"

[[registry]]
prefix = "k8s.gcr.io"
insecure = true
location = "k8s.gcr.io"

[[registry.mirror]]
location = "https://xxxx.onrender.com"

[[registry]]
prefix = "gcr.io"
insecure = true
location = "gcr.io"

[[registry.mirror]]
location = "https://xxxx.onrender.com"

[[registry]]
prefix = "ghcr.io"
insecure = true
location = "ghcr.io"

[[registry.mirror]]
location = "https://xxxx.onrender.com"

[[registry]]
prefix = "quay.io"
insecure = true
location = "quay.io"

[[registry.mirror]]
location = "https://xxxx.onrender.com"

```

#### 3.3 使用
对于以上配置,k8s在使用的时候,就可以直接`pull`外部无法pull的镜像了
手动可以直接`pull` 配置了`mirror`的仓库
`crictl pull registry.k8s.io/kube-proxy:v1.28.4`
`docker pull nginx:1.21`






## 变量说明
| 变量名 | 示例 | 必填 | 备注 |
Expand Down
117 changes: 65 additions & 52 deletions _worker.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
// _worker.js

// Docker镜像仓库主机地址
let hub_host = 'registry-1.docker.io'
let hub_host = 'registry-1.docker.io';
// Docker认证服务器地址
const auth_url = 'https://auth.docker.io'
const auth_url = 'https://auth.docker.io';
// 自定义的工作服务器地址
let workers_url = 'https://你的域名'
let workers_url = 'https://xxx/';

let 屏蔽爬虫UA = ['netcraft'];

// 根据主机名选择对应的上游地址
function routeByHosts(host) {
// 定义路由表
// 定义路由表
const routes = {
// 生产环境
"quay": "quay.io",
Expand Down Expand Up @@ -99,7 +99,7 @@ async function nginx() {
</body>
</html>
`
return text ;
return text;
}

export default {
Expand All @@ -112,23 +112,38 @@ export default {
if (env.UA) 屏蔽爬虫UA = 屏蔽爬虫UA.concat(await ADD(env.UA));
workers_url = `https://${url.hostname}`;
const pathname = url.pathname;
const hostname = url.searchParams.get('hubhost') || url.hostname;
const hostTop = hostname.split('.')[0];// 获取主机名的第一部分
const checkHost = routeByHosts(hostTop);
hub_host = checkHost[0]; // 获取上游地址
const fakePage = checkHost[1];

// 获取请求参数中的 ns
const ns = url.searchParams.get('ns');
const hostname = url.searchParams.get('hubhost') || url.hostname;
const hostTop = hostname.split('.')[0]; // 获取主机名的第一部分

let checkHost; // 在这里定义 checkHost 变量
// 如果存在 ns 参数,优先使用它来确定 hub_host
if (ns) {
if (ns === 'docker.io') {
hub_host = 'registry-1.docker.io'; // 设置上游地址为 registry-1.docker.io
} else {
hub_host = ns; // 直接使用 ns 作为 hub_host
}
} else {
checkHost = routeByHosts(hostTop);
hub_host = checkHost[0]; // 获取上游地址
}

const fakePage = checkHost ? checkHost[1] : false; // 确保 fakePage 不为 undefined
console.log(`域名头部: ${hostTop}\n反代地址: ${hub_host}\n伪装首页: ${fakePage}`);
const isUuid = isUUID(pathname.split('/')[1].split('/')[0]);
if (屏蔽爬虫UA.some(fxxk => userAgent.includes(fxxk)) && 屏蔽爬虫UA.length > 0){
//首页改成一个nginx伪装页

if (屏蔽爬虫UA.some(fxxk => userAgent.includes(fxxk)) && 屏蔽爬虫UA.length > 0) {
// 首页改成一个nginx伪装页
return new Response(await nginx(), {
headers: {
'Content-Type': 'text/html; charset=UTF-8',
},
});
}

const conditions = [
isUuid,
pathname.includes('/_'),
Expand All @@ -146,10 +161,10 @@ export default {
];

if (conditions.some(condition => condition) && (fakePage === true || hostTop == 'docker')) {
if (env.URL302){
if (env.URL302) {
return Response.redirect(env.URL302, 302);
} else if (env.URL){
if (env.URL.toLowerCase() == 'nginx'){
} else if (env.URL) {
if (env.URL.toLowerCase() == 'nginx') {
//首页改成一个nginx伪装页
return new Response(await nginx(), {
headers: {
Expand Down Expand Up @@ -181,7 +196,7 @@ export default {
if (!/%2F/.test(url.search) && /%3A/.test(url.toString())) {
let modifiedUrl = url.toString().replace(/%3A(?=.*?&)/, '%3Alibrary%2F');
url = new URL(modifiedUrl);
console.log(`handle_url: ${url}`)
console.log(`handle_url: ${url}`);
}

// 处理token请求
Expand All @@ -197,14 +212,14 @@ export default {
'Cache-Control': 'max-age=0'
}
};
let token_url = auth_url + url.pathname + url.search
return fetch(new Request(token_url, request), token_parameter)
let token_url = auth_url + url.pathname + url.search;
return fetch(new Request(token_url, request), token_parameter);
}

// 修改 /v2/ 请求路径
if (/^\/v2\/[^/]+\/[^/]+\/[^/]+$/.test(url.pathname) && !/^\/v2\/library/.test(url.pathname)) {
if (ns === 'docker.io' && /^\/v2\/[^/]+\/[^/]+\/[^/]+$/.test(url.pathname) && !/^\/v2\/library/.test(url.pathname)) {
url.pathname = url.pathname.replace(/\/v2\//, '/v2/library/');
console.log(`modified_url: ${url.pathname}`)
console.log(`modified_url: ${url.pathname}`);
}

// 更改请求的主机名
Expand All @@ -230,7 +245,7 @@ export default {
}

// 发起请求并处理响应
let original_response = await fetch(new Request(url, request), parameter)
let original_response = await fetch(new Request(url, request), parameter);
let original_response_clone = original_response.clone();
let original_text = original_response_clone.body;
let response_headers = original_response.headers;
Expand All @@ -246,14 +261,14 @@ export default {

// 处理重定向
if (new_response_headers.get("Location")) {
return httpHandler(request, new_response_headers.get("Location"))
return httpHandler(request, new_response_headers.get("Location"));
}

// 返回修改后的响应
let response = new Response(original_text, {
status,
headers: new_response_headers
})
});
return response;
}
};
Expand All @@ -264,33 +279,33 @@ export default {
* @param {string} pathname 请求路径
*/
function httpHandler(req, pathname) {
const reqHdrRaw = req.headers
const reqHdrRaw = req.headers;

// 处理预检请求
if (req.method === 'OPTIONS' &&
reqHdrRaw.has('access-control-request-headers')
) {
return new Response(null, PREFLIGHT_INIT)
return new Response(null, PREFLIGHT_INIT);
}

let rawLen = ''
let rawLen = '';

const reqHdrNew = new Headers(reqHdrRaw)
const reqHdrNew = new Headers(reqHdrRaw);

const refer = reqHdrNew.get('referer')
const refer = reqHdrNew.get('referer');

let urlStr = pathname
let urlStr = pathname;

const urlObj = newUrl(urlStr)
const urlObj = newUrl(urlStr);

/** @type {RequestInit} */
const reqInit = {
method: req.method,
headers: reqHdrNew,
redirect: 'follow',
body: req.body
}
return proxy(urlObj, reqInit, rawLen)
};
return proxy(urlObj, reqInit, rawLen);
}

/**
Expand All @@ -300,44 +315,42 @@ function httpHandler(req, pathname) {
* @param {string} rawLen 原始长度
*/
async function proxy(urlObj, reqInit, rawLen) {
const res = await fetch(urlObj.href, reqInit)
const resHdrOld = res.headers
const resHdrNew = new Headers(resHdrOld)
const res = await fetch(urlObj.href, reqInit);
const resHdrOld = res.headers;
const resHdrNew = new Headers(resHdrOld);

// 验证长度
if (rawLen) {
const newLen = resHdrOld.get('content-length') || ''
const badLen = (rawLen !== newLen)
const newLen = resHdrOld.get('content-length') || '';
const badLen = (rawLen !== newLen);

if (badLen) {
return makeRes(res.body, 400, {
'--error': `bad len: ${newLen}, except: ${rawLen}`,
'access-control-expose-headers': '--error',
})
});
}
}
const status = res.status
resHdrNew.set('access-control-expose-headers', '*')
resHdrNew.set('access-control-allow-origin', '*')
resHdrNew.set('Cache-Control', 'max-age=1500')
const status = res.status;
resHdrNew.set('access-control-expose-headers', '*');
resHdrNew.set('access-control-allow-origin', '*');
resHdrNew.set('Cache-Control', 'max-age=1500');

// 删除不必要的头
resHdrNew.delete('content-security-policy')
resHdrNew.delete('content-security-policy-report-only')
resHdrNew.delete('clear-site-data')
resHdrNew.delete('content-security-policy');
resHdrNew.delete('content-security-policy-report-only');
resHdrNew.delete('clear-site-data');

return new Response(res.body, {
status,
headers: resHdrNew
})
});
}

async function ADD(envadd) {
var addtext = envadd.replace(/[ |"'\r\n]+/g, ',').replace(/,+/g, ','); // 将空格、双引号、单引号和换行符替换为逗号
//console.log(addtext);
if (addtext.charAt(0) == ',') addtext = addtext.slice(1);
if (addtext.charAt(addtext.length -1) == ',') addtext = addtext.slice(0, addtext.length - 1);
if (addtext.charAt(addtext.length - 1) == ',') addtext = addtext.slice(0, addtext.length - 1);
const add = addtext.split(',');
//console.log(add);
return add ;
return add;
}

0 comments on commit 3f2f161

Please sign in to comment.