背景

本文简单记录下最近在内网服务器离线安装docker及配置nexus作为docker私服,踩的一些坑。docker和k8s这块技术我跟得不是很紧,18年的时候用过一阵docker,后来发现它并不能解决当时我们遇到的问题,后来就没用了,再一个就是,在宿主机上啥命令都有,也太爽了,反观docker里面啥命令都没有,痛苦,所以没啥必要的话,我一般比较少docker部署。

现在docker,k8s这块已经是事实上标准了,我们工作里也在筹备上云的事情,这块技术也得跟上了。最近工作正好需要选型一个内网搭建的文档中心,知识库那种,可以拿来存各种markdown的文档,看了下网上,各种技术太多了,这次干脆就用docker部署,快速试错。

只是,刚在内网搭个docker,都一堆问题。

网络环境

开发环境的服务器,全都没有外网,除非提申请给网工,比如,nexus maven私服服务器(ip:1.1.1.1),要访问阿里的maven私服(maven.aliyun.com),那么,提申请就是1.1.1.1访问maven.aliyun.com的80/443端口。

另外,开发环境服务器也是访问不了办公电脑的网段的。

这些网络管控其实也很正常,只是搞工作有点麻烦。

安装过程

yum

先是在开发服务器A上准备安装docker,但也没办法使用yum安装,需要配置docker官方的yum源:

https://docs.docker.com/engine/install/centos/
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo [docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable
enabled=1

然后里面都是去https://download.docker.com下载,我又没网络,内网yum源的docker版本又比较旧,看来只能rpm安装了。

rpm安装

然后我就去找rpm,在下面这个网址,下了6,7个rpm:

https://download.docker.com/linux/centos/7/x86_64/stable/Packages/

然后安装:

[root@monitor upload]# rpm -ivh *.rpm
warning: docker-ce-24.0.6-1.el7.x86_64.rpm: Header V4 RSA/SHA512 Signature, key ID 621e9f35: NOKEY
error: Failed dependencies:
container-selinux >= 2:2.74 is needed by docker-ce-3:24.0.6-1.el7.x86_64
containerd.io >= 1.6.4 is needed by docker-ce-3:24.0.6-1.el7.x86_64
docker-ce-rootless-extras is needed by docker-ce-3:24.0.6-1.el7.x86_64
libcgroup is needed by docker-ce-3:24.0.6-1.el7.x86_64
libseccomp >= 2.3 is needed by docker-ce-3:24.0.6-1.el7.x86_64
docker-buildx-plugin is needed by docker-ce-cli-1:24.0.6-1.el7.x86_64
docker-compose-plugin is needed by docker-ce-cli-1:24.0.6-1.el7.x86_64

我服了,怎么还依赖这么多rpm,这些rpm,在上面网址里还没有,看来这条路太累了,换个方式。

找一台能任意上外网的机器(比如本地虚拟机、个人的云服务器等),用yum的方式,把所有rpm包都拿到手,再拷贝到这边来装。

云服务器获取全部rpm

yum remove方式卸载失败

我是采用如下方式(--downloadonly),以获取tcpdump的rpm为例:

yum install --downloadonly --downloaddir=/root/download tcpdump

执行完成后,就在/root/download拿到了tcpdump的依赖包:

[root@strategy-stg-app-2 download]# ll
total 564
-rw-r--r-- 1 root root 141376 Jun 21 15:45 libpcap-1.5.3-11.el7.x86_64.rpm
-rw-r--r-- 1 root root 431300 Jun 21 15:45 tcpdump-4.9.2-3.el7.x86_64.rpm

行吧,我就把docker那几个包给卸载了,然后继续用上面的方式:

yum remove docker-ce docker-ce-cli ...
然后再安装:
yum install --downloadonly --downloaddir=/root/mypackage/ docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

执行完了去看,发现下载目录下也只有docker相关的几个包,docker依赖的包的rpm是一个没有。

看来,是我卸载的时候,卸的不干净,没把docker那些依赖给卸载掉。

yum history方式完全卸载

yum history这个命令,可以将你过往的yum历史操作记录找出来:

我这边不知道为啥,只找到两年前的,我查了网上,好像说默认只能看到最近的20个历史事务。

https://users.fedoraproject.narkive.com/bkvqvTY0/how-to-make-yum-history-show-more-than-the-last-20-transactions

当然了,我们还可以查询某个包相关的事务:

[root@VM-0-6-centos ~]# yum history info docker-ce
Transaction ID : 46
Begin time : Mon Nov 23 10:01:31 2020
End time : 10:01:56 2020 (25 seconds)
User : root <root>
Return-Code : Success
Command Line : install -y docker-ce-19.03.9-3.el7 docker-ce-cli-19.03.9-3.el7 containerd.io
Transaction performed with:
Installed rpm-4.11.3-43.el7.x86_64 @os
Installed yum-3.4.3-167.el7.centos.noarch @os
Installed yum-plugin-fastestmirror-1.1.31-54.el7_8.noarch @updates
Packages Altered:
Dep-Install audit-libs-python-2.8.5-4.el7.x86_64 @os
Dep-Install checkpolicy-2.5-8.el7.x86_64 @os
Dep-Install container-selinux-2:2.119.2-1.911c772.el7_8.noarch @extras
Install containerd.io-1.3.7-3.1.el7.x86_64 @docker-ce-stable
Install docker-ce-3:19.03.9-3.el7.x86_64 @docker-ce-stable
Install docker-ce-cli-1:19.03.9-3.el7.x86_64 @docker-ce-stable
Dep-Install libcgroup-0.41-21.el7.x86_64 @os
Dep-Install libsemanage-python-2.5-14.el7.x86_64 @os
Dep-Install policycoreutils-python-2.5-34.el7.x86_64 @os
Dep-Install python-IPy-0.75-6.el7.noarch @os
Dep-Install setools-libs-3.3.8-4.el7.x86_64 @os
Scriptlet output:
1 setsebool: SELinux is disabled.

这里可以看到时间是2020年,确实就是那时候安装的了,然后可以看到,很多依赖也一起安装了。

此时,我们可以回退这整个事务:

从上面的Transaction ID : 46,拿到事务id,46,然后回退:
yum history undo 46

此时,可以卸载全部的依赖包。当然,这个undo操作执行完成后,也变成了一个事务,也可以回退的。

参考:

https://www.tecmint.com/view-yum-history-to-find-packages-info/

https://unix.stackexchange.com/questions/303754/how-to-remove-all-installed-dependent-packages-while-removing-a-package-in-cento

https://blog.csdn.net/mighty13/article/details/122412447

重新执行,获取全部rpm

yum install --downloadonly --downloaddir=/root/mypackage/  docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

此时,再把rpm拷贝到目标服务器上,rpm -ivh *.rpm就可以安装完成了。

私服问题

查看私服上docker仓库的connector地址

docker安装完成后,启动:

systemctl start docker
拉取:
docker run hello-world

没外网,自然是报错,所以还要配置私服。我们内网有一个之前其他组搭的nexus,里面好像有docker仓库,看看能不能用吧。

我们nexus上(10.0.218.28),一共2个docker 仓库(一个host类型,存放公司内部镜像,一个proxy类型,连接了https://hub-mirror.c.163.com作为镜像源),最后又搞了一个group类型,聚合了上面两个仓库,对外就用这个group类型就可以,其connector地址为:

所以,在docker这边,只需要修改为如下:

[root@monitor upload]# vim /etc/docker/daemon.json(如没有可新建)
{
"registry-mirrors": ["http://10.0.218.28:8083"],
"insecure-registries": ["http://10.0.218.28:8083"]
}

就算是可以使用该私服了。

想当然犯的错

接下来就是拉取,听说wordpress这个很多拿来做网站,模版很多,我就拉取试试:

[root@monitor upload]# docker pull wordpress
Using default tag: latest
latest: Pulling from library/wordpress
Get "https://registry-1.docker.io/v2/": dial tcp: lookup registry-1.docker.io on [::1]:53: dial udp [::1]:53: connect: no route to host

网上查了下,乱七八糟的,后面跟着其中一个,配了下dns:

[root@monitor upload]# vim /etc/resolv.conf

然后,这次换了个错误:

[root@monitor upload]# docker pull wordpress
Using default tag: latest
latest: Pulling from library/wordpress
Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

这个错我真是花了不少时间,因为我认为我私服都配好了,为啥还会报这种问题(看起来还是去docker官方拉取),肯定是哪里配置没搞对吧。

当时没有想到好办法,https的,抓包也不好抓;strace跟踪了docker daemon进程,也没看到啥东西。

上网看了会,说,要好像pull时候要单独指定私服仓库地址:

[root@monitor ~]# docker pull 10.0.218.28:8083/wordpress
Using default tag: latest
latest: Pulling from wordpress
manifest for 10.0.218.28:8083/wordpress:latest not found: manifest unknown: manifest unknown

嗯,这次的报错不一样了,什么manifest unknown

这次试着tcpdump抓了下和私服之间的网络包:

tcpdump -i any tcp port 8083 -w wordpress.pcap

简单分析了下,一共有几个http请求:

  • 请求根地址
GET /v2/ HTTP/1.1
Host: 10.0.218.28:8083 响应:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="http://10.0.218.28:8083/v2/token",service="http://10.0.218.28:8083/v2/token" {"errors":[{"code":"UNAUTHORIZED","message":"access to the requested resource is not authorized","detail":null}]}

意思是 需要认证。

  • 获取token

    GET /v2/token?account=admin&scope=repository%3Awordpress%3Apull&service=http%3A%2F%2F10.0.218.28%3A8083%2Fv2%2Ftoken HTTP/1.1
    Host: 10.0.218.28:8083 返回:
    HTTP/1.1 200 OK
    {"token":"DockerToken.c1a93413-7ade-389f-9231-4a153f644b74"}
  • 获取wordpress镜像的元数据标识

    HEAD /v2/wordpress/manifests/latest HTTP/1.1
    Host: 10.0.218.28:8083 HTTP/1.1 200 OK
    Docker-Content-Digest: sha256:a078d12a76827322cf95c1e3ae470d30bd518af6e0bdb42f4f49919b2b3ba74b

    我是第一次实际看到head类型的请求,返回的header里有一个sha256开头的字符串,下面要用

  • 获取元数据

    GET /v2/wordpress/manifests/sha256:a078d12a76827322cf95c1e3ae470d30bd518af6e0bdb42f4f49919b2b3ba74b HTTP/1.1
    Host: 10.0.218.28:8083 返回:
    HTTP/1.1 200 OK
    body为json,里面是元数据

  • 根据架构对应的digest串,获取具体镜像

    GET /v2/wordpress/manifests/sha256:b4aabd2efdd7cf033b1f3b883c404ce2a260a27d83294f3a76c8e14b201572e4 HTTP/1.1
    Host: 10.0.218.28:8083 HTTP/1.1 404 Not Found
    body:
    {
    "errors": [
    {
    "code": "MANIFEST_UNKNOWN",
    "message": "manifest unknown",
    "detail": [
    {
    "Name": "wordpress"
    },
    {
    "Revision": "sha256:b4aabd2efdd7cf033b1f3b883c404ce2a260a27d83294f3a76c8e14b201572e4"
    }
    ]
    }
    ]
    }

    最后报的这个错,我就真的不是理解了。

因为是通过nexus访问163那边,前面折腾了半天,后面想起来去nexus看下日志:

2023-09-29 16:34:36,211+0800 WARN  [qtp1782934700-19476]  admin org.sonatype.nexus.repository.docker.internal.V2Handlers - Is the remote url a valid docker endpoint? Remote host https://hub-mirror.c.163.com/ with path /v2/library/wordpress/manifests/sha256:b4aabd2efdd7cf033b1f3b883c404ce2a260a27d83294f3a76c8e14b201572e4 did not return the expected response. Error message: manifest unknown

意思是感觉163那边返回的有问题。

我就拿日志里这个地址去请求:

意思是被限流了,还说,要提升限额,请访问docker官网的xx网站。

docker login疯狂踩坑

因为上面那个报错信息,我怀疑是我这边请求太频繁了,网上查了下,说是docker从2020年开始限制匿名用户拉取频率为每6个小时分别限制为100,登录的用户为200个。

https://blog.csdn.net/llg___/article/details/127230106

方法嘛,看起来,要么是换个源,要么是docker login,提升到200个。

我就想着,内网nexus服务器只开了到163这个源的网络,开网又麻烦,还是先搞个登录吧,解决目前的问题。

登录就登录,我拿出了docker hub网站的用户名密码,然后docker login,发现他么登不进去啊。

又以为是nexus私服的啥问题。后面就下班了,下班路上看了会docker login这块,思路清晰了一点,决定回家后,先去看看163源官网,看看有没有接口文档,看看这个报错要怎么弄(毕竟是他们报的错)。

后面继续开整,网上找163镜像源的官网都找半天,最终发现是这个:

https://sf.163.com/help/documents/15587821142962176

https://sf.163.com/

最终注册了个用户。

后面在nexus服务器上,试着docker login登录网易私服,没想到还登上了,用的刚在网易注册的用户名和密码。

docker login hub-mirror.c.163.com:443

此时,我才反应过来,原来登录不是传docker hub的密码,而是传私服的密码,艹,我还以为它们只是个代理呢,帮忙转发密码过去(现在想想也确实不对,密码一般不会转发,但也说不准啊)

行吧,看来我登私服的话,得传私服的用户名密码了:

 docker login 10.0.218.28:8083 -u admin -p xxxxxx

还真是这样。

后来我就想,我现在是通过nexus服务器去163拉取,163说我们过于频繁,那我通过nexus登录163不就行了吗。

后面在网上找了半天nexus的文档,也没发现有这个功能。

哎,看来靠登录来解决163限流的办法,是走不下去了。

后面想着,不是限流吗,至少6小时内还是能拉取100次的,结果第二天去了,发现还是拉不下来镜像。

原来是163源挂了,我他么

后面就是在网上溜达,看看有没有类似情况的,发现一篇公众号里提到这些事。

Docker 镜像国内加速的几种方法,推荐收藏!

说有个仓库在实时监测这些国内源的情况:

https://github.com/docker-practice/docker-registry-cn-mirror-test/actions

检测脚本(https://github.com/docker-practice/docker-registry-cn-mirror-test/blob/master/.github/workflows/ci.yaml)

执行过程:

https://github.com/docker-practice/docker-registry-cn-mirror-test/actions/runs/6333166370

我看到检测结果是,163已经挂了,我看了执行日志,163这边的报错也是一模一样。

哎,原来是源头的问题。

另外,发现这个仓库里有些资料不错:

https://github.com/yeasy/docker_practice/blob/master/install/mirror.md

docker daemon打开debug日志

这些年习惯了抓包解决问题,有时候遇到https就没辙(手机端https还能靠代理来搞搞,服务器端这个暂时没研究)

手里有了锤子,看哪里都是钉子,后面反应过来,https的话看日志应该也不错。

方式1

将systemctl安装的docker停掉,用下面的方法启动:

/usr/bin/dockerd -l debug

这个是前台启动,仅限自己掌控的docker这么操作。

方式2

systemctl stop docker
vim /etc/docker/daemon.json
{
"registry-mirrors": ["http://10.0.218.28:8083"],
"insecure-registries": ["http://10.0.218.28:8083"],
"debug": true
} systemctl start docker

增加debug:true即可。

然后docker info |grep debug 可以查看是否生效。

日志位置

一般在tailf /var/log/messages或者 :

 journalctl -u docker

docker pull 10.0.218.28:8083/wordpress时,dockerd的日志大概如下:

Sep 29 16:33:13 monitor dockerd: time="2023-09-29T16:33:13.348868678+08:00" level=debug msg="Fetching manifest from remote" digest="sha256:a078d12a76827322cf95c1e3ae470d30bd518af6e0bdb42f4f49919b2b3ba74b" error="<nil>" remote="10.0.218.28:8083/wordpress:latest"
Sep 29 16:33:13 monitor dockerd: time="2023-09-29T16:33:13.359405144+08:00" level=error msg="Not continuing with pull after error: manifest unknown: manifest unknown"

虽然也不怎么详细,也能多点信息吧。

另外,也可以看下nexus的日志:

lsof -p 38134(nexus pid)|grep log

找到了日志位置:

/usr/local/nexus/sonatype-work/nexus3/log/nexus.log

nexus的日志在协助甩锅到163那边,也发挥了巨大作用。

总结

我不知道大家有没有遇到这么多问题,反正我这边感觉问题层出不穷的,don't know why.

参考资料

https://docs.docker.com/config/daemon/

https://platform9.com/kb/kubernetes/enable-debug-logging-for-docker-daemon

https://docs.docker.com/engine/release-notes/24.0/

https://www.cnblogs.com/xiongzaiqiren/p/16900429.html

内网离线安装docker并配置使用nexus为docker私服的更多相关文章

  1. Docker源码安装附内网镜像安装演示

    Docker源码安装附内网镜像安装演示 系统版本要求 当前系统版本:CentOS Linux release 7.9.2009 (Core) 内核版本:3.10.0-1160.el7.x86_64 注 ...

  2. Linux系统如何在离线环境或内网环境安装部署Docker服务和其他服务

    如何在离线环境或纯内网环境的Linux机器上安装部署Docker服务或其他服务.本次我们以Docker服务和Ansible服务为例. 获取指定服务的所有rpm包 保证要获取rpm包的机器能够上网. 本 ...

  3. Centos7.2内网环境安装MySQL5.7.24

    1.配置本地yum源 内网环境,首先需要配置本地yum源,以解决MySQL的依赖安装,具体参考该文:点击打开 2.查看服务器环境 uname -a 3.去官网下载MySQL安装包 MySQL官网网址: ...

  4. ftp服务器搭建(离线安装vsftpd),配置

    1.下载vsftp:http://rpmfind.net/linux/rpm2html/search.php?query=vsftpd(x86-64) 2.检查是否已经安装了vsftp rpm -qa ...

  5. Gradle AndroidStudio内网离线构建配置踩坑记录

    最近一家新公司,由于办公环境都是在内网机上,导致在Unity导出android工程后,gradle离线构建也是第一次搞,花了一天时间也踩了一些坑,最后也终于构建成功了,这里记录下,方便大家少走些弯路. ...

  6. Linux(Red hat)无网离线安装TensorFlow

    文件下载 首先,下载想要安装的版本,目前最新的是1.8.0 根据你的python版本下载对应的whl文件,下载连接:https://pypi.org/project/tensorflow/#files ...

  7. Microsonf visual c++ 14+ 离线内网安装

    内网离线安装方法:先下载官方的visualcppbuildtools: <br  href=http://go.microsoft.com/fwlink/?LinkId=691126 >& ...

  8. python使用pip 18以上版本离线安装package

    在内网办公环境,常常需要使用离线安装python的软件包. 一般都会先在互联网的电脑上下载,再拷贝到内网办公机器上进行离线安装. 一般来说,我是这样做的: 1.拷贝和外网电脑上版本一致,且32位或64 ...

  9. 本地yum源构建以及Docker离线安装

    Docker离线安装以及本地yum源构建 在docker的使用过程中有时候会遇到一些私有化部署的问题,就是在一些无法上网的机器上面安装使用dokcer,这就引出了docker的离线安装的问题,dock ...

  10. k8s内网安装部署(二)

    续上篇 https://www.cnblogs.com/wangql/p/13397034.html 一.kubeadm安装 1.kube-proxy开启ipvs的前置条件 modprobe br_n ...

随机推荐

  1. 在 Istio 服务网格内连接外部 MySQL 数据库

    为了方便理解,以 Istio 官方提供的 Bookinfo 应用示例为例,利用 ratings 服务外部 MySQL 数据库. Bookinfo应用的架构图如下: 其中,包含四个单独的微服务: pro ...

  2. pcie reset系列之 内核框架

    FLR是pci reset的一种. 关于FLR的寄存器操作比较简单, 相关的寄存器有: 配置空间里device cap里的FLR capability bit, 这个表示设备是否支持FLR. 配置空间 ...

  3. 基于ChatGPT上线《你说我猜》小游戏

    摘要 AIGC.GPT.休闲小游戏三者可以怎么结合? AIGC.GPT与小游戏的结合为游戏体验带来了新的可能性.AIGC(Artificial Intelligence Game Content)作为 ...

  4. JSGRID loaddata显示超级多空行

    这个逼问题困扰了我两天了 作为一个主后端的程序员 初体验前端技术栈真的麻之又麻 以防万一 请先确认 是不是和我一个情况 如果是 请往下看 首先 我们需要念一段咒语 json是json string是s ...

  5. [Spring+SpringMVC+Mybatis]框架学习笔记(八):Mybatis概述

    第8章 Mybatis概述 8.1 几个概念 ORM Object-Relationship Mapping 对象关系映射,它是一种思想,它的实质是将数据库中的数据用对象的形式表现出来. JPA Ja ...

  6. 【后端面经-Java】JVM垃圾回收机制

    目录 1. Where:回收哪里的东西?--JVM内存分配 2. Which:内存对象中谁会被回收?--GC分代思想 2.1 年轻代/老年代/永久代 2.2 内存细分 3. When:什么时候回收垃圾 ...

  7. 利用Redis实现向量相似度搜索:解决文本、图像和音频之间的相似度匹配问题

    在自然语言处理领域,有一个常见且重要的任务就是文本相似度搜索.文本相似度搜索是指根据用户输入的一段文本,从数据库中找出与之最相似或最相关的一段或多段文本.它可以应用在很多场景中,例如问答系统.推荐系统 ...

  8. 三万字盘点Spring 9大核心基础功能

    大家好,我是三友~~ 今天来跟大家聊一聊Spring的9大核心基础功能. 其实最近有小伙伴私信问我怎么不写文章了,催更来了 其实我不是不写,而是一直在写这篇文章,只不过令我没想到的是,从前期的选题.准 ...

  9. 【笔记】- 【美团1万台 Hadoop 集群 YARN 的调优之路】

    原文:美团1万台 Hadoop 集群 YARN 的调优之路 背景 架构 YARN架构 资源抽象 YARN调度架构 资源抽象 调度流程 作业的组织方式 核心调度流程 指标 业务指标:有效调度 系统性能指 ...

  10. 记一次 .NET某培训学校系统 内存碎片化分析

    一:背景 1. 讲故事 前些天有位朋友微信上找到我,说他们学校的Web系统内存一直下不去,让我看下到底是怎么回事,老规矩让朋友生成一个dump文件丢给我,看一下便知. 二:WinDbg 分析 1. 托 ...