美文网首页
阿里云搭建docker私有镜像仓库与SpringBoot项目推送

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

作者: Scallion | 来源:发表于2021-12-18 22:13 被阅读0次

    1. 前言

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

    • 构建一个Docker的私有镜像仓库,用于存储Docker镜像,当需要启动容器服务时可以指定Docker去私有镜像仓库获取镜像;
    • SpringBoot在打包的时候,使用插件对镜像进行打包并推送到远程的Docker镜像仓库;
    • Docker启动容器时指定获取镜像的仓库。

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

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

    • 修改配置
      registry-mirrors: 配置的是阿里云镜像加速地址,此项配置不是搭建私有仓库必须的。
      insecure-registries: 此项配置是让Docker信任私有仓库地址,xx.96.194.xx为服务器的IP,2112为私有仓库的端口。
    # vim /etc/docker/daemon.json 
    {
      "registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"],
      "insecure-registries": ["xx.96.194.xx:2112"]
    }
    
    • 拉取私有仓库镜像
    docker pull registry
    
    • 重新加载配置信息,重启Docker服务
    # 重新加载某个服务的配置文件
    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
    
    • 生成鉴权密码文件
      htpasswd 是 apache http 的基本认证文件,使用 htpasswd 命令可以生成用户及密码文件:
    # 创建存储鉴权密码文件目录
    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工程

    • 创建一个Controller
    @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);
        }
    }
    
    • 启动SpringBoot工程保证Controller能够正常访问


      获取用户信息

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

    • pom文件引入jib-maven-plugin插件依赖
            <dependency>
                <groupId>com.google.cloud.tools</groupId>
                <artifactId>jib-maven-plugin</artifactId>
                <version>2.8.0</version>
            </dependency>
    
    • pom文件编写jib镜像打包plugin
            <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>
    
    • 打开Terminal执行打包命令
      jib:build命令会完成镜像打包,并推送到远程仓库。
     mvn install -Dmaven.test.skip=true
     mvn compile jib:build -Dmaven.test.skip=true
    

    7. 查看并启动镜像

    • 查看镜像
      查看镜像有两个方式,方式一,使用curl命令连接docker私有仓库查看。方式二,安装registry-web通过Web UI界面查看。
    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/

    仓库镜像列表
    • 启动镜像
      docker run -di --name actual-combat -p 7000:8080 xx.96.194.xxx:2112/actual-combat:latest
      --name指定镜像名称
      actual-combat:latest需要和私有镜像仓库中的镜像保持一致
    [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
    # 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
    
    • 停止镜像
      docker stop [CONTAINER ID]
    [root@iz2zeh3bjq6rgoli6ng5g9z ~]# docker stop 8de8c650c485
    8de8c650c485
    [root@iz2zeh3bjq6rgoli6ng5g9z ~]# 
    
    • 删除镜像
      docker rm [CONTAINER ID]
    [root@iz2zeh3bjq6rgoli6ng5g9z ~]# docker rm 8de8c650c485
    8de8c650c485
    [root@iz2zeh3bjq6rgoli6ng5g9z ~]#
    
    • 查看容器日志
      docker logs -f [CONTAINER ID]
    [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集成安全认证

    相关文章

      网友评论

          本文标题:阿里云搭建docker私有镜像仓库与SpringBoot项目推送

          本文链接:https://www.haomeiwen.com/subject/iuaufrtx.html