Sonatype Nexus 自动化部署实践

一.部署思维导图如下:

Sonatype Nexus 自动化部署实践_第1张图片
2. 成功部署截图
Sonatype Nexus 自动化部署实践_第2张图片
前提条件:
1.操作系统 Centos7 /Mac OSX
Sonatype Nexus 自动化部署实践_第3张图片
2.操作系统安装了Docker
[root@localhost nexus]# docker --version
Docker version 18.09.0, build 4d60db4

3.安装了bash shell

源代码下载:
https://github.com/HappyFreeAngel/nexus-docker-starter.git

二.使用方法如下:

happy:nexus-docker-starter happy$ tree .
.
├── LICENSE
├── README.md
├── manual-config-nexus.conf
└── start-nexus-docker.sh

#配置文件 用户可以自定义。
more manual-config-nexus.conf

NEXUS_IMAGE_NAME="sonatype/nexus3:3.16.1"
NIC_NAME="ens160"
NEXUS_IP_ADDRESS="192.168.2.22"
NEXUS_DOMAIN=nexus.example.com

KEY_STORE_PASSWORD=your_password
KEY_PASSWORD=your_password
KEY_MANAGER_PASSWORD=your_password
TRUST_STORE_PASSWORD=your_password

NEXUS_VERSION=3.16.1
KEYSTORE_ALIAS="jetty"

#关于docker 配置
HTTP_PORT=8081
HTTPS_PORT=8443
DOCKER_PRIVATE_HTTP_PORT=1080
DOCKER_PRIVATE_HTTPS_PORT=1443
DOCKER_GROUP_HTTP_PORT=2080
DOCKER_GROUP_HTTPS_PORT=2443

#DOCKER_PROXY 里面必须选择 User Docker Hub

通用启动脚本如下:
more start-nexus-docker.sh

#!/bin/bash
#确保shell 切换到当前shell 脚本文件夹
current_file_path=$(cd "$(dirname "$0")"; pwd)
cd ${current_file_path}

#输入参数如下
export NIC_NAME="ens160"
export NEXUS_IP_ADDRESS=""
export NEXUS_DOMAIN=nexus.cityworks.cn

export KEY_STORE_PASSWORD=your_password
export KEY_PASSWORD=your_password
export KEY_MANAGER_PASSWORD=your_password
export TRUST_STORE_PASSWORD=your_password

export NEXUS_VERSION=3.16.1
export NEXUS_IMAGE_NAME="sonatype/nexus3:3.16.1"
export KEYSTORE_ALIAS="jetty"
export HTTP_PORT=8081
export HTTPS_PORT=8443
export DOCKER_PRIVATE_HTTP_PORT=1080
export DOCKER_PRIVATE_HTTPS_PORT=1443
export DOCKER_GROUP_HTTP_PORT=2080
export DOCKER_GROUP_HTTPS_PORT=2443

# docker-private  http:1080 https:1443
# docker-proxy
#docker-group:  http: 2080  https: 2443

#以上参数可以通过修改manual-config-nexus.conf覆盖.
source manual-config-nexus.conf


echo "https://hub.docker.com/r/sonatype/nexus3/"
echo "默认用户admin 默认密码:admin123"

docker stop nexus
docker rm   nexus

if [[ -z "$NEXUS_IP_ADDRESS" ]];
then
    if [[ -z "$NIC_NAME" ]];
    then
          echo "没有指定NIC网卡无法获取正确的IP地址. 程序退出."
          exit 1
    fi
    export currentHostIp=`ip -4 address show $NIC_NAME | grep 'inet' |  grep -v grep | awk '{print $2}' | cut -d '/' -f1`
    export NEXUS_IP_ADDRESS=$currentHostIp
fi

echo "NEXUS_IP_ADDRESS=$NEXUS_IP_ADDRESS"

NEXUS_DATA_DIR="$current_file_path/nexus-data"
NEXUS_CONF_DIR="$current_file_path/nexus-conf"

`mkdir ${NEXUS_DATA_DIR}`
sudo chown -R 200 ${NEXUS_DATA_DIR}

if [[ ! -f "${NEXUS_DATA_DIR}/etc/nexus-default.properties" ]];
then
     `docker stop temp-nexus`
     `docker rm   temp-nexus`
     docker run --name temp-nexus -d ${NEXUS_IMAGE_NAME}
     sleep 5
     `rm -rf nexus-conf`
     `mkdir nexus-conf`
     docker cp temp-nexus:/opt/sonatype/nexus/etc nexus-conf/etc
     docker stop temp-nexus
     docker rm   temp-nexus
     echo "${NEXUS_IMAGE_NAME}缺省配置文件复制成功!"
     tree ${current_file_path}/nexus-conf

     #to do
     echo "替换/etc/jetty/jetty-https.xml里面的默认密码passowrd 为配置文件的密码"
     export KEY_STORE_PASSWORD=your_password
     export KEY_MANAGER_PASSWORD=your_password
     export TRUST_STORE_PASSWORD=your_password

     OLD_KEYSTORE_PASSWORD='KeyStorePassword\">password<'
     NEW_KEYSTORE_PASSWORD="KeyStorePassword\">${KEY_STORE_PASSWORD}<"

     OLD_KEY_MANAGER_PASSWORD='KeyManagerPassword\">password<'
     NEW_KEY_MANAGER_PASSWORD="KeyManagerPassword\">${KEY_MANAGER_PASSWORD}<"

     OLD_TRUST_STORE_PASSWORD='TrustStorePassword\">password<'
     NEW_TRUST_STORE_PASSWORD="TrustStorePassword\">${TRUST_STORE_PASSWORD}<"

     sed -i '' -e "s|$OLD_KEYSTORE_PASSWORD|$NEW_KEYSTORE_PASSWORD|g" $current_file_path/nexus-conf/etc/jetty/jetty-https.xml
     sed -i '' -e "s|$OLD_KEY_MANAGER_PASSWORD|$NEW_KEY_MANAGER_PASSWORD|g" $current_file_path/nexus-conf/etc/jetty/jetty-https.xml
     sed -i '' -e "s|$OLD_TRUST_STORE_PASSWORD|$NEW_TRUST_STORE_PASSWORD|g" $current_file_path/nexus-conf/etc/jetty/jetty-https.xml

    temp_jetty_path='${jetty.etc}'
    cat << EOF >$current_file_path/nexus-conf/etc/nexus-default.properties
# Jetty section
application-port=8081
application-host=0.0.0.0

application-port-ssl=8443

#下面代码有问题,to do ???? 无法写入文件.
nexus-args=${temp_jetty_path}/jetty.xml,${temp_jetty_path}/jetty-http.xml,${temp_jetty_path}/jetty-requestlog.xml,${temp_jetty_path}/jetty-https.xml,${temp_jetty_path}/jetty-http-redirect-to-https.xml

#nexus-args=${temp_jetty_path}/jetty.xml,${temp_jetty_path}/jetty-http.xml,${temp_jetty_path}/jetty-requestlog.xml

nexus-context-path=/${NEXUS_CONTEXT}

# Nexus section
nexus-edition=nexus-pro-edition
nexus-features=\
 nexus-pro-feature
nexus.clustered=false

EOF

#     echo "修改配置文件/etc/nexus-default.properties, 删除一行,增加2行."
#     sed -i '' -e '/nexus-args=*/d' $current_file_path/nexus-conf/etc/nexus-default.properties
#     echo "application-port-ssl=8443">> $current_file_path/nexus-conf/etc/nexus-default.properties
#     echo 'nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-requestlog.xml,${jetty.etc}/jetty-https.xml,${jetty.etc}/jetty-http-redirect-to-https.xml' >> $current_file_path/nexus-conf/etc/nexus-default.properties
fi
#生成https 相关证书
keytool -genkeypair -keystore keystore.jks -storepass ${KEY_STORE_PASSWORD}  -keypass ${KEY_PASSWORD} -alias ${KEYSTORE_ALIAS} -keyalg RSA -keysize 2048 -validity 5000 -dname "CN=*
.${NEXUS_DOMAIN}, OU=Example, O=Sonatype, L=Unspecified, ST=Unspecified, C=US" -ext "SAN=DNS:${NEXUS_DOMAIN},IP:${NEXUS_IP_ADDRESS}" -ext "BC=ca:true"

keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12 -alias ${KEYSTORE_ALIAS}  -srcstorepass  ${KEY_STORE_PASSWORD}  -srckeypass ${KEY_PASSWORD}

#配置keystore
`mkdir -p ${NEXUS_CONF_DIR}/etc/ssl/`
cp keystore.jks ${NEXUS_CONF_DIR}/etc/ssl/


firewall-cmd --permanent --zone=public --add-port=${HTTP_PORT}/tcp
firewall-cmd --permanent --zone=public --add-port=${HTTPS_PORT}/tcp
firewall-cmd --permanent --zone=public --add-port=${DOCKER_PRIVATE_HTTP_PORT}/tcp
firewall-cmd --permanent --zone=public --add-port=${DOCKER_PRIVATE_HTTPS_PORT}/tcp
firewall-cmd --permanent --zone=public --add-port=${DOCKER_GROUP_HTTP_PORT}/tcp
firewall-cmd --permanent --zone=public --add-port=${DOCKER_GROUP_HTTPS_PORT}/tcp

firewall-cmd --reload


docker run -d \
--name nexus \
-p ${HTTP_PORT}:${HTTP_PORT} \
-p ${HTTPS_PORT}:${HTTPS_PORT} \
-p ${DOCKER_PRIVATE_HTTP_PORT}:${DOCKER_PRIVATE_HTTP_PORT} \
-p ${DOCKER_PRIVATE_HTTPS_PORT}:${DOCKER_PRIVATE_HTTPS_PORT} \
-p ${DOCKER_GROUP_HTTP_PORT}:${DOCKER_GROUP_HTTP_PORT} \
-p ${DOCKER_GROUP_HTTPS_PORT}:${DOCKER_GROUP_HTTPS_PORT} \
-v `pwd`/nexus-data:/nexus-data \
-v `pwd`/nexus-conf/etc:/opt/sonatype/nexus/etc \
-v /etc/localtime:/etc/localtime:ro \
-e INSTALL4J_ADD_VM_PARAMS="-Xms2g -Xmx2g -XX:MaxDirectMemorySize=3g  -Djava.util.prefs.userRoot=/some-other-dir" \
-e "TZ=Asia/Shanghai" \
${NEXUS_IMAGE_NAME}

echo "等待服务器启动..."
echo "准备导出自签名证书,给Nexus docker客户端服务器使用(如mesos-agent),请您耐心等待服务器启动,大概30秒左右"

max_wait_time_in_seconds=240 #最多等待240秒
while [ $max_wait_time_in_seconds -gt 0 ]
do
    result=$(docker logs nexus | grep 'Start RESTORE')
    if [[ -z $result ]];
    then
          sleep 5
          max_wait_time_in_seconds=$((max_wait_time_in_seconds-5))
    else
          echo "nexus启动成功"
          keytool -printcert -sslserver ${NEXUS_DOMAIN}:${HTTPS_PORT} -rfc > ${NEXUS_DOMAIN}.crt
          more ${NEXUS_DOMAIN}.crt

          ##下面这行代码有问题.
          ##keytool -export -alias ${KEYSTORE_ALIAS} -keystore keystore.jks -storepass ${STORE_PASS} -file ${NEXUS_DOMAIN}.crt  ##??

          cp $NEXUS_DOMAIN.crt   /etc/pki/ca-trust/source/anchors/${NEXUS_DOMAIN}.crt
          update-ca-trust

          echo " 请将证书文件${NEXUS_DOMAIN}.crt拷贝到所有需要推送拉取镜像的机器上,位置是:/etc/docker/certs.d/${NEXUS_DOMAIN}\:${DOCKER_PRIVATE_HTTPS_PORT}/${NEXUS_DOMAIN}.crt"
          echo " 请将证书文件${NEXUS_DOMAIN}.crt拷贝到所有需要推送拉取镜像的机器上,位置是:/etc/docker/certs.d/${NEXUS_DOMAIN}\:${DOCKER_GROUP_HTTPS_PORT}/${NEXUS_DOMAIN}.crt"
          echo " 然后就可以在远程机器上使用 1: docker login ${NEXUS_DOMAIN}:${DOCKER_GROUP_HTTPS_PORT} 拉取镜像了。"
          echo " 然后就可以在远程机器上使用 1: docker login ${NEXUS_DOMAIN}:${DOCKER_PRIVATE_HTTPS_PORT} 推送镜像了。"

          break
    fi
done

./start-nexus-docker.sh 执行就可以了。

下面讲配置docker 仓库的过程.

  1. 创建3个blob store 如下图
  2. Sonatype Nexus 自动化部署实践_第4张图片
  3. 在这里插入图片描述
    Sonatype Nexus 自动化部署实践_第5张图片

Sonatype Nexus 自动化部署实践_第6张图片
Sonatype Nexus 自动化部署实践_第7张图片

设置docker repo
Sonatype Nexus 自动化部署实践_第8张图片
点击create Repositories
Sonatype Nexus 自动化部署实践_第9张图片
分别选择 docker(hosted) docker(proxy) docker(group)
3个,
具体配置如下图
Sonatype Nexus 自动化部署实践_第10张图片
Sonatype Nexus 自动化部署实践_第11张图片
点击 create repository 创建

Sonatype Nexus 自动化部署实践_第12张图片
Sonatype Nexus 自动化部署实践_第13张图片
Sonatype Nexus 自动化部署实践_第14张图片
点击create repository 创建

Sonatype Nexus 自动化部署实践_第15张图片
Sonatype Nexus 自动化部署实践_第16张图片
点击create repository 创建 docker-group

点击左侧Security->Realms 添加Docker Bearer Token Realm 然后 点击 save 保存.

Sonatype Nexus 自动化部署实践_第17张图片

验证测试:
[root@localhost nexus]# docker login nexus.example.com:2443
Username: admin
Password:
Error response from daemon: Get https://nexus.example.com:2443/v2/: x509: certificate signed by unknown authority

报错了,
这个需要添加证书到/etc/docker/certs.d 目录下。

more nexus.example.com.crt
查看是否正常. 正确的应该类似下面这样的.
注意点: 1.配置文件里IP地址必须有,否则证书无法正确生成.
2. nexus.example.com 和对应的IP地址 请添加到/etc/hosts 里
3. nexus 启动比较慢,需要耐心等待几分钟.

-----BEGIN CERTIFICATE-----
MIIDyzCCArOgAwIBAgIEElTq3TANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJV
UzEUMBIGA1UECBMLVW5zcGVjaWZpZWQxFDASBgNVBAcTC1Vuc3BlY2lmaWVkMREw
DwYDVQQKEwhTb25hdHlwZTEQMA4GA1UECxMHRXhhbXBsZTEdMBsGA1UEAwwUKgou
bmV4dXMuZXhhbXBsZS5jb20wHhcNMTkwNDIzMTI0NjA3WhcNMzIxMjMwMTI0NjA3
WjB9MQswCQYDVQQGEwJVUzEUMBIGA1UECBMLVW5zcGVjaWZpZWQxFDASBgNVBAcT
C1Vuc3BlY2lmaWVkMREwDwYDVQQKEwhTb25hdHlwZTEQMA4GA1UECxMHRXhhbXBs
ZTEdMBsGA1UEAwwUKgoubmV4dXMuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCb56y9L4XlOvUHeQyDb8E6gxC/uyx1p1STAvqL7aGn
Wb1YoHqQ+63NZsJ+cytLqo/ETlT8ufxYZJf7DkpDmvetERO5HbB9wthX4rmBNlSB
aw0M96qKZIiaZeIXNwuaArz8NhtuSs1qHB8TaUCy8BXh60XMkfscZccRnFHp66mi
5dAZVWIMB+RA0AGv3NfaXyle1MKie6nYavbqtgaiulpFAtgjeFy1FssSsywSHwOU
TcyKt4K3qk2RSF7vAtkNhYaXP7RuLot7LLs91fZO4+TDpVSXdbilYDRzGXuZ1Aa+
7GrGJF6MKFSthU5Ux4QfFgYa1prwtf2u9c4ZtPectT5nAgMBAAGjUzBRMAwGA1Ud
EwQFMAMBAf8wIgYDVR0RBBswGYIRbmV4dXMuZXhhbXBsZS5jb22HBMCoAhYwHQYD
VR0OBBYEFMvNkMTpW0zYpB84VRc4Akyl7ADJMA0GCSqGSIb3DQEBCwUAA4IBAQBj
BTHpIF1lT1eRaAERNPqszVku88IyTIgeMAVEySciHgJrBvHo26IezQ3CrbrkUta5
4+4+68UQ/lj81DZ1hAhlMZ8WJZr/KzODVA2SQ60mFQSaozSg8wW1xHbg6Z7FL9JF
kpTChhAx4jQniyro1x4XECYdIAh0UeX22O1cVrqlccNftyFiwF4AVs3EShlvGGvn
R0bUqiNq9OA3T2zIF/0K1U2xsYXiTAOgbxxwTsQu8r/RNzLDusJM6iiVdKZ6IE3y
Oj2dFDtUCV5KUTry287bn3DgbBloVM2cHZVevjqXgKodNFK1Z9qojGkeKJF1MVcs
knzmKAUpkvk1TMja1rV0
-----END CERTIFICATE-----

拷贝nexus.example.com.crt 到需要访问nexus.example.com 的计算机上,

mkdir -p /etc/docker/certs.d/nexus.example.com:1443
mkdir -p /etc/docker/certs.d/nexus.example.com:2443
cp nexus.example.com.crt /etc/docker/certs.d/nexus.example.com:1443
cp nexus.example.com.crt /etc/docker/certs.d/nexus.example.com:2443

Sonatype Nexus 自动化部署实践_第18张图片
docker login nexus.example.com:1443
#用户名:admin 密码:admin123
docker login nexus.example.com:2443
#用户名:admin 密码:admin123
Sonatype Nexus 自动化部署实践_第19张图片
Sonatype Nexus 自动化部署实践_第20张图片

下面演示删除 nginx:1.13-alpine 然后再从nexus.example.com 拉取

Sonatype Nexus 自动化部署实践_第21张图片

至此,实验成功。
希望以上文章对有需要的朋友有帮助。

坑:
[root@nexus nexus]# docker login nexus.linkaixin.com:1443
Authenticating with existing credentials…
Login did not succeed, error: Error response from daemon: login attempt to https://nexus.linkaixin.com:1443/v2/ failed with status: 401 Unauthorized

出现这个问题,是因为: 你没有添加, Docker Bearer token Realm 到右边,正确的应该如下:

Sonatype Nexus 自动化部署实践_第22张图片

你可能感兴趣的:(DevOps,自动化运维)