自建机房为了节省公网流量都会有内网的yum源,对于自动化程度比较高,软件标准化和准入做的比较好的情况下,常用软件会打成rpm包放进内网源里,很多基础软件和依懒也都会打包进系统模板中。其实多数情况下,需要从yum源里更新的包不多,不需要将整个centos源都同步进内网源里。可以通过nignx反向代理用偷懒的方式实现一个yum源。

我们先来看看yum的工作流程:

  1. 服务器请求根据自己的系统版本、架构、依次请求各启用的源中的repomd.xml文件
  2. repomd.xml中保存了软件仓库中的metadata,也就是“元数据”,这些数据包含了该软件仓库内所有软件包的包名及其所需的依赖环境、软件包里文件列表等信息
  3. yum或dnf下载了metadata后,将这些信息和本地环境对比,进而确认需要安装哪些rpm包,并在用户确认后开始安装或更新

一般Yum源里会有以下五种后缀的文件:

  1. repomd.xml 是repo+md(metadata)的意思,软件源的主配置文件,保存源里面几个主要文件的校验码、时间戳和大小等信息
  2. .xml.gz 后缀的文件,如软件源里包数据(primary.xml)、文件列表数据(filelists.xml.gz)、 其它信息(other.xml)
  3. .bz2后缀的文件,一般是sqlite的压缩档,一般都有primary.sqlite.bz2、filelists.xml.gz、other.sqlite.bz2
  4. .xml其它metadata文件
  5. .rpm具体的软件包

要想节省流量,最好做法是nginx在反向代理时,用proxy_store的方式缓存一份在本地。rpm包比较大肯定是要缓存的,.xml/.bz2/.xml.gz这些文件一般几兆,文件名除了repomd.xml都有校验码。属于更新频繁的文件,但是最好缓存在本地并设置一的较短的缓存时间。

看下yum源服务器的nginx缓存配置:

resolver 8.8.8.8 ipv6=off  valid=10s;

server {

    listen 8001;
    server_name $host;
    # 反带官方源
    location /centos/ {
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://mirror.centos.org/centos/;
    }
}

server {
    listen 8002;
    #备用源
    server_name $host;
    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass       http://mirror.pregi.net;
    }
}

server {
    listen 8003;
    #epel源
    server_name $host;
    location /epel/ {
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass https://dl.fedoraproject.org/pub/epel/;
    }
}

upstream base {
    #官方源
    server 127.0.0.1:8001 fail_timeout=5s max_fails=3;
    #备用源
    server 127.0.0.1:8002  fail_timeout=5s max_fails=3 backup;
}

upstream epel {
    #epel源
    server 127.0.0.1:8003 fail_timeout=5s max_fails=3;
}

server {
    listen       80 ;
    server_name $host;
    root /opt/repos/;
    index index.html ;
    access_log logs/yum.access.log main;

    location /centos/ {
        location ~ (.xml|.gz|.bz2)$ {
                proxy_store on;
                proxy_temp_path "/opt/repos/";
                proxy_set_header Accept-Encoding identity;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_next_upstream error http_502;
                if ( !-e $request_filename ) {
                        proxy_pass http://base;
                }
                if ( -e $request_filename ) {
                                 expires      1d; #保存1天
                }
        }

        location ~ .rpm$ {
                proxy_store on;
                proxy_temp_path "/opt/repos/";
                proxy_set_header Accept-Encoding identity;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_next_upstream error http_502;
                if ( !-e $request_filename ) {
                        proxy_pass http://base;
                }
                if ( -e $request_filename ) {
                                 expires      2000d;
                }
        }
    }
    #EPEL源同/centos/,这里忽略了
    
}

接下来需要配置客户端yum源,如果内网有dns服务器,可以直接改域名的解析,这样就可以不更改客户端配置。否则删除原有所有的源,添加如下内容:

cat /etc/yum.repos.d/all.repo

[Nixops-Base]
name=Nixops-Base
#指到nginx yum缓存服务器
baseurl=http://172.20.1.1/centos/$releasever/os/$basearch/
#关闭gpg检查
gpgcheck=0

[Nixops-Updates]
name=Nixops-Updates
baseurl=http://172.20.1.1/centos/$releasever/updates/$basearch/
gpgcheck=0

[Nixops-Extras]
name=Nixops-Extras
baseurl=http://172.20.1.1/centos/$releasever/extras/$basearch/
gpgcheck=0

#[Nixops-Epel]
#name=Nixops-Epel
#baseurl=http://172.20.1.1/epel/$releasever/$basearch/
#gpgcheck=0

客户端设置好后,就可以用yum安装个软件试试了:

yum clean all
yum install telnet -y 

配置正确就能看到是从Nixops-Updates获取telnet,同时在nginx服务器上能看到请求日志和代向低代理日志

上面主要以centos官方源为例,epel源的配置没有写全,如果有其它软件源也可以按以上配置进行反代缓存,如zabbix、saltstack、remi、percona等源,这是一种比较偷懒又投机的做法,实际使用虽然没有什么问题,但还是建议使用rsync的方式完整的同步yum源。