0%

容器仓库是容器化管理中非常重要的一环,相当于 SVN 在程序研发、运维发布中的地位。因此,一个稳定、可靠的容器仓库尤为重要。

目前我知道的的数据仓库有

  • Docker 官方的 Registry 原生仓库

  • SuSE 团队推出的出的 Portus:https://github.com/SUSE/Portus

  • VMWare 中国团队推出的企业级仓库—Harbor

  • 大家熟知的 Maven 私服:Sonatype Nexus3

    本文主要介绍下 Sonatype Nexus 3 这个功能强大的产品,它不仅能够用于创建 Maven 私服,还可以用来创建 yum、pypi、npm、nuget、rubygems 等各种私有仓库。而且,Nexus 从 3.0 版本也开始支持创建 Docker 镜像仓库了!

因此,在上述几个产品里面我毫不犹豫的选择了 Nexus3 作为部门的公共数据仓库,一举多得。

部署

创建docker-compose.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
version: "3.7"

services:
nexus3:


container_name: nexus3
tty: true
image: sonatype/nexus3
volumes:
- "./data:/nexus-data"
- "/etc/localtime:/etc/localtime:ro"
- "/etc/timezone:/etc/timezone:ro"
ports:
- "8081:8081"
- "8082:8082"
- "8083:8083"
environment:
- TZ=Asia/Shanghai

user: root

deploy:
resources:
limits:
# 限制内存使用
memory: 4G

logging:
driver: "json-file"
options:
max-size: "100M"

然后一键部署

1
docker-compose --compatibility up -d

https://hub.docker.com/r/sonatype/nexus3/

大概 2 分钟左右可以完成启动,此时可以通过浏览器访问 http://IP 地址:8081 即可出现 nexus 的 web 界面:

配置

默认账户名admin, 密码参阅官方文档, 在./data/admin.password这个文件中

1
Default user is admin and the uniquely generated password can be found in the admin.password file inside the volume. See Persistent Data for information about the volume.

创建 Docker 仓库

回到前面的 repository 界面,点击 repositories 打开页面后点击【create repository】打开仓库类型选择界面

可以看到 Docker 有三种类型,分别是 docker(group),docker(hosted),docker(proxy)。其含义解释如下:

  • hosted : 本地存储,即同 docker 官方仓库一样提供本地私服功能

  • proxy : 提供代理其他仓库的类型,如 docker 中央仓库

  • group : 组类型,实质作用是组合多个仓库为一个地址

开始创建 Docker 仓库

首先,我们创建一个 docker 代理仓库,点击 docker(proxy),如图填写信息

往下翻页,勾上 “Allow clients to use the V1 API to interact with this Repository”,允许 Docker V1 API 请求。

至于代理的对象,我可以选择官方的镜像地址:https://registry-1.docker.io,但是官方的比较慢,所以这里我们可以填写国内的 Docker 镜像加速器地址,比如阿里云或DaoCloud的容器加速

我这里选择了 DaoCloud 的镜像加速,这里为了确保能够拉取 DockerHub 最新的镜像,我选择了 Use DockerHub 这个 Index

接着,再创建一个本地仓库,这里比较简单,只需要填写本地仓库的名称,比如 docker-hosted,然后填写 HTTP 端口即可,比如 8083

保存之后,最后创建一个聚合仓库(group),将代理仓库和本地仓库聚合到一起使用,这里我命名为 docker,然后端口选择 8082

这里成员仓库的顺序可以稍微规划下,一般来说将本地的放前面,代理第三方的放后面,好处就是优先使用本地或小众的镜像仓库。我这边是用了多个第三方仓库,所有有多个

至此,nexus 在 docker 这一块是部署已经完成了,但是这样并不能很好的使用。因为 group 仓库并不能推送镜像,因为你推送自己制作的镜像到仓库还得通过本地仓库的端口去推送,很不方便!

配置 Nginx

上面配置完了,但是不够完美。

Pull/Push 操作的端口并不相同,我们需要聚合到一个端口, 通过配置 Nginx 匹配请求方法,路径的匹配来分流到不同的端口

我们需要两个域名,一个用作Nexus, 一个用作Docker

例如

  • nexus.abc.com

  • docker.abc.com

注意替换里面的IP地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
upstream nexus_web {
# Nexus 前台
server 192.168.1.100:8081;
}

upstream nexus_docker_get {
# docker push 请求
server 192.168.1.100:8082;
}

upstream nexus_docker_put {
# docker pull 请求
server 192.168.1.100:8083;
}

# Docker 的配置
server {
listen 80;
listen 443 ssl;
# 这个用于 docker, 注意域名的配置
server_name docker.abc.com;
access_log /data/wwwlogs/docker.abc.com.log access_log_json;

# 证书配置
# 如果使用宝塔面板或其他可以自动申请证书的面板来配置会方便很多
ssl_certificate /data/wwwroot/ssl/out/docker.abc.com/docker.abc.com.crt;
ssl_certificate_key /data/wwwroot/ssl/out/docker.abc.com/docker.abc.com.key.pem;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

# disable any limits to avoid HTTP 413 for large image uploads
client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/docker/docker/issues/1486)
chunked_transfer_encoding on;
# 设置默认使用推送代理
set $upstream "nexus_docker_put";
# 当请求是 GET,也就是拉取镜像的时候,这里改为拉取代理,如此便解决了拉取和推送的端口统一
if ( $request_method ~* 'GET') {
set $upstream "nexus_docker_get";
}
# 只有本地仓库才支持搜索,所以将搜索请求转发到本地仓库,否则出现 500 报错
if ($request_uri ~ '/search') {
set $upstream "nexus_docker_put";
}
index index.html index.htm index.php;
location / {
proxy_pass http://$upstream;
proxy_set_header Host $host;
proxy_connect_timeout 3600;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_set_header X-Real-IP $remote_addr;
proxy_buffering off;
proxy_request_buffering off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto http;
}
}

# Nexus 前台的配置
server {
listen 80;
listen 443 ssl;
# 这个用于 nexus 前台, 注意域名的配置
server_name nexus.abc.com;
index index.html index.htm index.php;
ssl_certificate /data/wwwroot/ssl/out/nexus.abc.com/nexus.abc.com.crt;
ssl_certificate_key /data/wwwroot/ssl/out/nexus.abc.com/nexus.abc.com.key.pem;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers '!aNULL:kECDH+AESGCM:ECDH+AESGCM:RSA+AESGCM:kECDH+AES:ECDH+AES:RSA+AES:';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
access_log /data/wwwlogs/nexus.abc.com.log access_log_json;
location /download {
root /data/wwwroot/nexus.abc.com;
}
location / {
proxy_pass http://nexus_web;
proxy_set_header Host $host;
client_max_body_size 512m;
proxy_connect_timeout 3600;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_buffering off;
proxy_request_buffering off;
}
}

然后再Push镜像的时候只需要把tag加上自己域名即可

例如把官方的nginx推送到自建的仓库

1
docker pull nginx

改标签

1
docker tag nginx docker.abc.com/nginx

登录 docker.abc.com

1
docker login docker.abc.com

推送

1
docker push docker.abc.com/nginx

https://zhangge.net/5139.html

1
2
3
4
5
6
7
class A(object):

def get(self) -> B:
...

class B:
...

上面的代码在IDE里会报错, 因为类B在声明前被引用了

这样我们就无法利用IDE来查看类B的成员变量, 方法等内容.

解决方法很简单

1
2
3
4
5
6
7
class A(object):

def get(self) -> "B":
...

class B:
...

加个引号"

https://docs.python.org/zh-cn/3/library/typing.html#constant

在 Python 中有很多特殊属性, 例如 __name__, __module__ 等有特殊的意义

__annotations__ 该函数返回对象的注解字典, 更多详情参见官方文档

https://docs.python.org/zh-cn/3/howto/annotations.html

1
2
3
4
class Human(object):

name: str
age: int

在上面的例子中, 我们创建了一个 Human 类, 同时声明了两个类属性name, age

因为我们使用了类型注解, 所以我们可以通过__annotations__方法拿到声明的这两个属性名以及类型

1
2
h = Human()
print(h.__annotations__)

输出

1
{'name': <class 'str'>, 'age': <class 'int'>}

我们得到了一个属性名:类型的键值对

此时我们继续创建一个Human的子类Man

1
2
3
class Man(Human):

name = "Naonao"

注意这里我们的类变量name没有使用类型注解, 仅仅是一个赋值的类变量

1
2
m = Man()
print(m.__annotations__)
1
{'name': <class 'str'>, 'age': <class 'int'>}

查看一下子类的__annotations__注解字典, 我们发现子类继承了父类的注解

但是如果我们这样写

1
2
3
class Man(Human):

name: str

name使用了类型注解, 我们将得到

1
{'name': <class 'str'>}

子类重写了__annotations__

https://docs.python.org/zh-cn/3/howto/annotations.html

查看官方文档发现, 这个是3.9版本之前的一个设计缺陷.

特此记录, 因为本人在此坑里陷了甚久

Cookie 的域无效, 这个大概率是写 Requests 写习惯了, 直接带这 cookie 请求

解决方法也很简单, 先用Selenium打开一下网址, 然后在加上Cookie重新访问即可

具体表现为使用WIndows10自带的输入法输入中文时出现严重卡顿,比如在键盘上按下一个键,至少要反应几秒钟才能出现按的字符,注意,是字符!也就是说字符是一个一个蹦出来的,并不连贯!

解决方法

1
%AppData%\Microsoft\InputMethod\Chs

把上面这个目录删掉!完美解决!

这个目录下有很多小文件

推测是输入法缓存,因为删除了以后,之前输入法记住的常输的句子就木有了。

这个是在网上找的一键清除脚本,没试过不确定是不是有用

1
2
3
4
5
6
7
' Fix Win10 Chinese IME lag
Option Explicit
Dim WSHShell, FSO, Target
Set WSHShell = CreateObject("WScript.Shell")
Set FSO = CreateObject("Scripting.FileSystemObject")
Target = WshShell.ExpandEnvironmentStrings("%AppData%") & "\Microsoft\InputMethod\Chs\"
FSO.DeleteFile Target & "UDP*.tmp"

https://ibug.io/cn/2021/03/win10-microsoft-ime-lag/

事情源于我要给新装的Ubuntu安装Python3.10, 结果在官网居然没有发现安装包

找了半天反正没找到, 只有源码没有发行版

没辙, 从源码编译安装吧

安装依赖

1
2
apt update
apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev wget libbz2-dev

下载对应版本的Python, 例如这里是3.10.8

1
wget https://www.python.org/ftp/python/3.10.6/Python-3.10.8.tgz

解压

1
tar -xf Python-3.10.*.tgz

检查配置

1
2
cd Python-3.10.*/
./configure --enable-optimizations

编译

1
make -j $(nproc)

安装到/usr/bin/python

1
make altinstall

https://computingforgeeks.com/how-to-install-python-on-ubuntu-linux-system/

docker-compose 使用3.7版本,然后加入 deploy,例如:

1
2
3
4
5
6
7
8
9
10
version: "3.7"
services:
redis:
image: redis:alpine
container_name: testredis
deploy:
resources:
limits:
cpus: '0.50'
memory: 500M

限制 CPU 使用率 50%, 500MB 内存

需要注意的是,启动时需增加 –compatibility 选项

1
docker-compose --compatibility up -d

否则会报错

1
WARNING: Some services (mysql, rsnmp) use the 'deploy' key, which will be ignored. Compose does not support 'deploy' configuration - use `docker stack deploy` to deploy to a swarm.

注:

–compatibility是docker-compose 1.20.0加入,主要目的就是用来将deploy中的数据限制、replicas与重启策略直接转译为version 2的语法

https://www.cnblogs.com/yjt1993/p/12402394.htm
https://www.jianshu.com/p/ba5518476057