阿里云搭建docker私有镜像仓库与SpringBoot项目推送

2021-12-18  本文已影响0人  Scallion

1. 前言

随着项目上容器技术的广泛应用,我也加入了Docker容器技术的学习。首先初学Docker,我的想法很简单。创建一个SpringBoot项目,如何将SpringBoot项目打包成容器镜像,然后推送至远程的Docker服务上部署。带着这个目的查阅了一些资料后,整体的实现思路如下:

环境描述:
准备一台阿里云服务器,已经完成Docker服务安装,后续将会在该服务器上进行搭建Docker私有镜像仓库。本地准备一个SpringBoot项目,至少编写一个Controller,保证本地SpringBoot项目启动后能够正常访问到Contriller。

2. 搭建建Docker私有镜像仓库

# vim /etc/docker/daemon.json 
{
  "registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"],
  "insecure-registries": ["xx.96.194.xx:2112"]
}
docker pull registry
# 重新加载某个服务的配置文件
sudo systemctl daemon-reload
# 重新启动 docker
sudo systemctl restart docker

3. 创建私有仓库并配置认证

由于私有镜像仓库是部署在阿里云上,要确保私有仓库的安全性,需要一个安全认证证书,防止发生意想不到的事情。所有需要在搭建私有仓库的Docker主机上先生成自签名证书。

mkdir -p /usr/local/registry/certs
openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/registry/certs/domain.key -x509 -days 365 -out /usr/local/registry/certs/domain.crt
  1. openssl req:创建证书签名请求等功能;
  2. -newkey: 创建 CSR 证书签名文件和 RSA 私钥文件;
  3. rsa:2048:指定创建的 RSA 私钥长度为 2048;
  4. -nodes:对私钥不进行加密;
  5. -sha256:使用 SHA256 算法;
  6. -keyout:创建的私钥文件名称及位置;
  7. -x509:自签发证书格式;
  8. -days:证书有效期;
  9. -out:指定 CSR 输出文件名称及位置;

生成自签名证书:
通过openssl命令先生成自签名证书,运行命令后需要填写一些证书信息。其中Common Name填写的xx.96.104.xxx是最关键的信息,这里填写的是私有仓库的地址:
Country Name:国家
State or Province Name:州或省
Locality Name:城市
Organization Name :机构名称
Organizational Unit Name :组织单位名称
Common Name:hostname域名
Email Address:邮箱地址

[root@iZ2ze0r5hel5o6fik77a26Z ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/registry/certs/domain.key -x509 -days 365 -out /usr/local/registry/certs/domain.crt
Generating a 2048 bit RSA private key
..............+++
............................+++
writing new private key to '/usr/local/registry/certs/domain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:BJ
Locality Name (eg, city) [Default City]:BJ
Organization Name (eg, company) [Default Company Ltd]:docker
Organizational Unit Name (eg, section) []:docker
Common Name (eg, your name or your server's hostname) []:xx.96.104.xxx
Email Address []:xxxxx@163.com
# 创建存储鉴权密码文件目录
mkdir -p /usr/local/registry/auth
# 如果没有 htpasswd 功能需要安装 httpd
yum install -y httpd
# 创建用户和密码
htpasswd -Bbn root ***1234 > /usr/local/registry/auth/htpasswd
  1. -d:后台运行容器;
  2. --name:为创建的容器命名;
  3. -p:表示端口映射,前者是宿主机端口,后者是容器内的映射端口。可以使用多个 -p 做多个端口映射;
  4. -v:将容器内 /var/lib/registry 目录下的数据挂载至宿主机 /mydata/docker_registry 目录下;
docker run -di --name registry -p 2112:5000 \
   -v /mydata/docker_registry:/var/lib/registry \
   -v /usr/local/registry/certs:/certs \
   -v /usr/local/registry/auth:/auth \
   -e "REGISTRY_AUTH=htpasswd" \
   -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
   -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
   -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
   -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
   registry

4. 操作私有容器镜像仓库

  1. 首先通过 docker login 命令输入账号密码登录私有仓库
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# docker login xx.96.194.xx:2112
Username: root
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
  1. 推送镜像至私有仓库
    先给镜像设置标签 docker tag local-image:tagname new-repo:tagname
    再将镜像推送至私有仓库 docker push new-repo:tagname
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# docker tag hello-world:latest xx.96.194.xx:2112/test-hello-world:1.0.0
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# docker push xx.96.194.xx/test-hello-world:1.0.0
The push refers to repository [xx.96.194.xx/test-hello-world]
An image does not exist locally with the tag: xx.96.194.xx/test-hello-world
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# 
  1. 查看推送至私有仓库的镜像
    由于我们做了目录挂载,因此可以在宿主机 /mydata/docker_registry/docker/registry/v2/repositories 目录下查看。
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# ll /mydata/docker_registry/docker/registry/v2/repositories/
total 8
drwxr-xr-x 5 root root 4096 Dec 15 10:04 actual-combat
drwxr-xr-x 5 root root 4096 Dec 14 12:36 test-hello-world
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# 
  1. 退出docker账号
    所有的推送镜像操作完成后,可以使用docker logout 命令退出账号。
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# docker logout xx.96.194.xx
Removing login credentials for xx.96.194.xx
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# 

5.搭建SpringBoot工程

@Slf4j
@RestController
@RequestMapping(value = "user")
public class UserController {

    @RequestMapping(value = "/info")
    @ResponseBody
    public String getUser() {
        User user = new User();
        user.setUserName("张三");
        user.setPassword("qwertyuiop");
        return JSONObject.toJSONString(user);
    }
}

6. SpringBoot项目集成镜像打包插件

        <dependency>
            <groupId>com.google.cloud.tools</groupId>
            <artifactId>jib-maven-plugin</artifactId>
            <version>2.8.0</version>
        </dependency>
        <plugin>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>2.8.0</version>
                <configuration>
                    <!-- 拉取所需的基础镜像 -->
                    <from>
                        <!-- 默认从官方公共仓库拉取镜像,速度较慢 -->
                        <image>openjdk:alpine</image>
                        <!-- 从指定仓库拉取镜像提速(需提前将镜像 push 至仓库) -->
                        <!--<image>192.168.10.10:5000/openjdk:alpine</image>-->
                    </from>
                    <!-- push 到哪个镜像仓库(公共仓库、阿里云仓库、私有自建仓库等) -->
                    <to>
                        <!-- 使用 DockerHub 的官方公共仓库:仓库地址/用户名/镜像名 -->
                        <!--<image>registry.hub.docker.com/mrhelloworld/${project.name}</image>-->
                        <!-- 使用自建的私有仓库:仓库地址/镜像名 -->
                        <image>xx.96.194.xx:2112/${project.artifactId}</image>
                        <!-- 镜像版本号 -->
                        <tags>
                            <tag>${project.version}</tag>
                        </tags>
                        <!-- 连接仓库的账号密码 -->
                        <auth>
                            <username>root</username>
                            <password>xxxxxx</password>
                        </auth>
                    </to>
                    <!-- 使 jib 插件支持 http 协议连接镜像仓库(安全起见,默认是关闭的) -->
                    <allowInsecureRegistries>true</allowInsecureRegistries>
                    <container>
                        <!-- 启动类 -->
                        <mainClass>com.erxiao.actualCombat.ActualCombatApplication</mainClass>
                    </container>
                </configuration>
            </plugin>
 mvn install -Dmaven.test.skip=true
 mvn compile jib:build -Dmaven.test.skip=true

7. 查看并启动镜像

  1. 使用curl命令
    curl -kiv -H "Authorization: Basic $(echo -n "root:wangxxxx" | base64)" https://localhost:2112/v2/_catalog 其中root:wangxxxx为关键信息,对应着生成鉴权密码文件时,用htpasswd 命令生成的用户与密码,用户名与密码直接使用英文冒号分隔。返回的{"repositories":["actual-combat","test-hello-world"]}内容就是当前私有仓库中的镜像。
# curl -kiv -H "Authorization: Basic $(echo -n "root:wangxxxx" | base64)" https://localhost:2112/v2/_catalog
* About to connect() to localhost port 2112 (#0)
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 2112 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* skipping SSL peer certificate verification
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*       subject: E=xxxxxxxx_email@sina.com,CN=xx.96.194.xxx,OU=erxiao,O=erxiao,L=BJ,ST=BJ,C=CN
*       start date: Dec 14 04:42:52 2021 GMT
*       expire date: Dec 14 04:42:52 2022 GMT
*       common name: xx.96.194.xxx
*       issuer: E=xxxxxx_email@sina.com,CN=xx.96.194.xxx,OU=erxiao,O=erxiao,L=BJ,ST=BJ,C=CN
> GET /v2/_catalog HTTP/1.1
> User-Agent: curl/7.29.0
> Host: localhost:2112
> Accept: */*
> Authorization: Basic cm9vdDp3YW5nY29uZw==
> 
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
Content-Type: application/json; charset=utf-8
< Docker-Distribution-Api-Version: registry/2.0
Docker-Distribution-Api-Version: registry/2.0
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< Date: Sat, 18 Dec 2021 12:53:12 GMT
Date: Sat, 18 Dec 2021 12:53:12 GMT
< Content-Length: 54
Content-Length: 54

< 
{"repositories":["actual-combat","test-hello-world"]}
* Connection #0 to host localhost left intact
  1. 安装registry-web通过页面查看镜像
    参数解释:
    -p 7001:8080 host主机端口8080映射到container8080
    --name 起个名字,docker logs start stop时就可以用了
    --link 连接registry,可以不加,以为下面有registry的url访问方式(registry必须和与私有镜像仓库保持一致)
    -e REGISTRY_TRUST_ANY_SSL=true, 环境变量,相信所有的ssl,因为我们大部分的ssl都是自建的
    -e REGISTRY_BASEIC_AUTH 这个里面的值是账号以及密码的base64获取的,可以通过
    echo "ops:123123123" | base64
    b3BzOjEyMzEyMzEyMwo=
    获得。
    -e REGISTRY_NAME, 目前看起来这个是会在页面上的显示
docker run -itd -p 7001:8080 --name registry-web --link registry \
           -e REGISTRY_URL=https://xx.96.194.xxx:2112/v2 \
           -e REGISTRY_TRUST_ANY_SSL=true \
           -e REGISTRY_BASIC_AUTH="cm9vdDp3YW5nY29uZw==" \
           -e REGISTRY_NAME=docker_registry hyper/docker-registry-web

页面访问:
页面访问:http://xx.96.194.xxx:7001/

仓库镜像列表
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# docker run -di --name actual-combat -p 7000:8080 xx.96.194.xxx:2112/actual-combat:latest
12f8cf18723fed54e17702659929e538cf8a878802a0820eeb46996962543e61
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# 

页面访问Spring Boot项目

页面访问

8. 常用命令

# docker ps
CONTAINER ID   IMAGE                                     COMMAND                  CREATED             STATUS             PORTS                    NAMES
12f8cf18723f   xx.96.194.xxx:2112/actual-combat:latest   "java -cp /app/resou…"   17 minutes ago      Up 17 minutes      0.0.0.0:7000->8080/tcp   actual-combat
59d00326d2b7   hyper/docker-registry-web                 "start.sh"               About an hour ago   Up About an hour   0.0.0.0:7001->8080/tcp   registry-web
4c0fd415f702   registry                                  "/entrypoint.sh /etc…"   4 days ago          Up 4 days          0.0.0.0:2112->5000/tcp   registry
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# docker stop 8de8c650c485
8de8c650c485
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# 
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# docker rm 8de8c650c485
8de8c650c485
[root@iz2zeh3bjq6rgoli6ng5g9z ~]#
[root@iz2zeh3bjq6rgoli6ng5g9z ~]# docker logs -f 59d00326d2b7
CATALINA_OPTS: -Djava.security.egd=file:/dev/./urandom -Dcontext.path=
Using CATALINA_BASE:   /var/lib/tomcat7
Using CATALINA_HOME:   /usr/share/tomcat7
Using CATALINA_TMPDIR: /var/lib/tomcat7/temp
Using JRE_HOME:        /usr/lib/jvm/java-7-openjdk-amd64
Using CLASSPATH:       /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar
Dec 18, 2021 1:02:07 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]

参考:Docker 私有镜像仓库的搭建及认证
参考:Spring Boot 多样化构建 Docker 镜像
参考:registry-web集成安全认证

上一篇下一篇

猜你喜欢

热点阅读