前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >nginx反向代理+http user 认证访问 私有registry

nginx反向代理+http user 认证访问 私有registry

作者头像
qsjs
发布2020-06-09 10:38:53
2.6K0
发布2020-06-09 10:38:53
举报
文章被收录于专栏:MyPanda的学习笔记

利用nginx做反向代理,从而实现对registry的访问;而nginx作为反向代理来使用在实际情况中非常多见,并且还支持基本的用户权限认证。 本节讲述如何用nginx 的反向代理实现对registry的访问(https访问),同时用nginx提供基本的用户认证功能:

  1. 首先下载nginx image, 然后run nginx 容器. 我们需要这个容器run起来,然后把配置文件从容器中copy到宿主机中. 在随后会将 localhost下的 /root/docker_study/nginx/ , mapping到容器的/etc/nginx; 理解这一点很重要. 因为nginx的配置文件中不能用localhost的路径,而要用在container中的路径;
代码语言:javascript
复制
#docker pull nginx的过程忽略. 以下的nginx是官方的nginx image.
[root@localhost ~]# docker image ls nginx
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/nginx     latest              f949e7d76d63        8 days ago          126 MB
[root@localhost ~]#
#把nginx 容器运行起来;
[root@localhost ~]# docker run -d -p 8080:80 --rm --name official_nginx nginx
03b95be10b94d47e5f92dd9b139c230633cce5db3c7c4863582d2f9cf35d2127
[root@localhost ~]# curl -I http://192.168.0.110:8080/
HTTP/1.1 200 OK
Server: nginx/1.17.4
...
[root@localhost ~]#
#容器中nginx的配置文件在 /etc/nginx , copy配置文件到localhost的当前目录下
[root@localhost docker_study]# docker cp official_nginx:/etc/nginx  . 
[root@localhost docker_study]# ls
nginx  
[root@localhost docker_study]#
  1. 编辑nginx的配置文件: A. 因为要配置ssl支持,所以需要在配置文件中打开ssl支持,并指定证书以及key的路径; B. 因为做反向代理,所以需要指定后端registry的IP以及端口信息;
代码语言:javascript
复制
#这里依然使用之前的证书,一共用到的是如下的2个文件;
#首先copy证书到nginx的cert.d目录下
[root@localhost nginx]# pwd
/root/docker_study/nginx
[root@localhost nginx]# mkdir cert.d
[root@localhost nginx]# cp /root/cert_test/{my.crt,myprivate.key}  ./cert.d
[root@localhost nginx]# ls cert.d/
my.crt  myprivate.key

我们有了证书 (nginx/cert.d/目录下)后,就可以修改nginx的配置了,这里主要分为两步来完成: A. 添加ssl相关的配置: 参照docker官方文档的说明 https://docs.docker.com/registry/recipes/nginx/ ,在nginx的conf.d/default.conf中的server 配置节中添加如下内容:

代码语言:javascript
复制
    listen       443 ssl;      #修改原来的80端口为443端口,并指出用ssl连接;        
    server_name  www.my.com;  #修改server name 为 www.my.com ,需要和证书my.crt中的设定相一致,这个名字就是nginx对外提供服务器名字;
    #添加ssl相关的配置,指定cert以及key的路径,此处的路径为在container中的路径;
    ssl_certificate /etc/nginx/cert.d/my.crt;
    ssl_certificate_key /etc/nginx/cert.d/myprivate.key;
    #ssl安全相关的其他配置,直接copy官方的参数:
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;

B. 进行nginx 反向代理的配置: 配置反向代理之前,我们需要考虑nginx 和 registry容器的通信问题, 因为nginx和registry容器的ip在每次退出重启后都会变化,所以nginx 如何知道后端registry的ip呢? 这里采用的方法是:让两个容器使用同一个网络栈,从而对另一个容器的访问就变成了对localhost的访问,这样就避免了ip变化带来的通信上的困扰;理解了这一点,我们在配置nginx反向代理的时候,后端的registry 就是localhost了 在nginx的主配置文件nginx.conf中的http节,添加内容如下:

代码语言:javascript
复制
#添加proxy相关的配置,
  upstream my_registry {         #定义uptream的名称,后面server 节的proxy_pass参数会使用这个名称;
    server localhost:5000;          #后端的registry服务器就是localhost, 因为nginx 和registry 会使用同一个网络栈,所以指定localhost就可以了;
  }

在default.conf中已经存在的server节中添加如下内容, 并注释掉原有的local / {...} 部分:

代码语言:javascript
复制
      location /v2/ {
       #如下的配置是nginx proxy相关的配置;
      proxy_pass                          http://my_registry; #这个名称要和上面指定的upstream的名称一致;
#这里的proxy不能够写为: http://my_registry/, 如果后面有字符“/”, 那么匹配部分的v2 在pass到后端的registry就丢失了;
      proxy_set_header  Host              $http_host;   # required for docker client's sake
      proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
      proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
      proxy_set_header  X-Forwarded-Proto $scheme;
      proxy_read_timeout                  900;
      }
  1. 启动nginx, my_registry容器,进行初步的验证: 在启动nginx的时候,用--network="container:<CONTAINER-ID>"的模式,从而确保nginx和registry使用的是同一个网络栈;
代码语言:javascript
复制
[root@localhost nginx]# docker run -d  -p 443:443 -v /root/docker_study/nginx/:/etc/nginx  --rm --name nginx_for_registry nginx 
d1a492516aab9456813603430356606a7ddce8b821436439d468910c0cabb538
[root@localhost nginx]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                          NAMES
d1a492516aab        nginx               "nginx -g 'daemon ..."   5 seconds ago       Up 4 seconds        80/tcp, 0.0.0.0:443->443/tcp   nginx_for_registry
[root@localhost nginx]# docker run -d -v /var/my_registry/:/var/lib/registry --network="container:d1a492516aab" --rm my_registry
c5fe1c808c2a6a26ab419f080227ae3c98fd12ba7c3ca727195ad5b525b0080c
[root@localhost nginx]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                          NAMES
c5fe1c808c2a        my_registry         "/my_entry.sh /etc..."   5 seconds ago       Up 4 seconds                                       kind_albattani
d1a492516aab        nginx               "nginx -g 'daemon ..."   2 minutes ago       Up About a minute   80/tcp, 0.0.0.0:443->443/tcp   nginx_for_registry
[root@localhost nginx]# 
[root@localhost conf.d]# curl  -XGET https://www.my.com/v2/_catalog   #可以正常访问到数据;
{"repositories":["panda/my_baseimage","panda/my_registry"]}
[root@localhost conf.d]# 

至此,已经成功完成利用"nginx作为反向代理”实现对registry的访问; 下面,我们将进一步学习如何配置http user的访问认证.

  1. 添加http user 访问认证: 我们这里使用htpasswd这个工具来进行密码认证,htpasswd是apache的http 密码生成工具,用起来比较简单,可以做基本的认证功能; a). 首先是用htpasswd来生成密码文件nginxpwd,并放到目录nginx/auth/下:
代码语言:javascript
复制
[root@localhost nginx]# htpasswd -Bb -c  nginxpwd testuser1 testpwd1 #首次生成要加-c参数
Adding password for user testuser1
[root@localhost nginx]# htpasswd -Bb nginxpwd testuser2 testpwd2
Adding password for user testuser2
[root@localhost nginx]# cat nginxpwd    #一共生成了两ID以及对应密码
testuser1:$2y$05$pzs.lZ9KyaAbLnrnZYIMwO8ibZKsELkXG8bPRpu3fp6QK.fvOFPvC
testuser2:$2y$05$XMpbB2deNcQPjo.qRDSwsu9kU3k8RP.LGoMmbb.8L/q/./WycKy3a
[root@localhost nginx]# mkdir -p auth
[root@localhost nginx]# mv nginxpwd  auth/
[root@localhost nginx]# 

b). 更新nginx的配置,在conf.d/default.conf下的server节添加如下内容:

代码语言:javascript
复制
auth_basic "Restricted Access";           #指定认证方式;
auth_basic_user_file /etc/nginx/auth/nginxpwd;  #指定用于认证的文件路径

c). 重新按照上面步骤启动nginx和registry容器,然后进行访问: 报错了,报错了,报错了......什么原因呢?

代码语言:javascript
复制
[root@localhost nginx]# docker login www.my.com
Username: testuser1
Password: 
Error response from daemon: login attempt to https://www.my.com/v2/ failed with status: 500 Internal Server Error
[root@localhost nginx]# 

经过排查(用docker logs CONTAINER-ID ),看错误logs, 是因为加密问题;再进一步查找原因,是因为nginx的auth_basic认证并不支持bcrypt加密方式,而 htpasswd 的-B 是 bcrypt加密方式,所以导致问题,重新用默认加密方式生成密码,再次验证:

代码语言:javascript
复制
[root@localhost auth]# docker login www.my.com
Username: testuser1
Password: 
Login Succeeded
[root@localhost auth]# docker pull -a www.my.com/panda/my_registry
Trying to pull repository www.my.com/panda/my_registry ... 
v1: Pulling from www.my.com/panda/my_registry
Digest: sha256:7022fc0185a773a8b7a75f624ef91b8b6fb03fafd9bf667cb90af95691129d00
Status: Downloaded newer image for www.my.com/panda/my_registry
[root@localhost auth]# 

通过以上步骤,完成基本的nginx 反向代理配置,以及通过nginx实现简单的认证;从而提供对私有registry的认证访问; 还有一些参数是需要加入的,请参考 : https://docs.docker.com/registry/recipes/nginx/ 获取更多指南;

本文原创,转载注明出处

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档