部署一套新环境,实践用jenkins实现CD

前提,已经有开发环境,但是因为开发环境更新很频繁,会影响到测试,于是准备新建一个sit环境。
前置条件:
已经有一台jenkins服务器,有新建jenkins用户,ip为172.31.17.89.
新开一台linux虚拟机,安装好docker,ip为172.31.17.55.

1、在55上新建一个普通用户,开通sudo权限
新建用户 useradd ttop.sit ,再使用passwd 修改密码。可参考之前的文章
开通sudo权限,编辑/etc/sudoers,加入NOPASSWD:ALL。Linux给普通用户sudo权限

2、登录到89这台机,切换到jenkins用户,能使用刚新建的用户 免密登录到55那台机
使用ssh-keygen 生成一个密钥对
再使用ssh-copy-id [USER_NAME]@IP将公钥发到55那台机器上,再使用ssh ttop.sit@172.31.17.55发现不再需要输入密码。

#确认89机器的jenkins用户ssh免密登录至55那台机,且能使用sudo命令
bash-4.2$ ssh ttop.sit@172.31.17.55
Last failed login: Tue Jun 16 16:06:03 CST 2020 from 172.31.17.89 on ssh:notty
There were 4 failed login attempts since the last successful login.
Last login: Tue Jun 16 14:46:33 2020
[ttop.sit@sit-jm-vcsms ~]$ sudo docker ps
CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS              PORTS                                                                NAMES
7e1400f61dda        repo.ttooc.xyz/jm/ms_file:036745cf   "sh -c 'chmod +x /en…"   3 hours ago         Up 21 seconds       5701/udp, 8080/tcp                                                   jm_file_1
01790ca91b0f        nginx                                "/docker-entrypoint.…"   3 hours ago         Up 3 hours          0.0.0.0:80->80/tcp, 0.0.0.0:8080->8080/tcp, 0.0.0.0:8761->8761/tcp   nginx

3、运行registry容器

docker run \
-e SPRING_PROFILES_ACTIVE=dev,composite,swagger,peer1,zipkin,no-liquibase \
-e SPRING_CLOUD_CONFIG_SERVER_COMPOSITE_0_TYPE=git \
-e SPRING_CLOUD_CONFIG_SERVER_COMPOSITE_0_URI="https://devops.ttotox.net/XXXXXXXX/_git/profile-sit(存放配置文件的git库地址)" \
-e SPRING_CLOUD_CONFIG_SERVER_COMPOSITE_0_SEARCH-PATHS="/"  \
-e SPRING_CLOUD_CONFIG_SERVER_COMPOSITE_0_USERNAME=cicd.xxxx (能查看git库的用户) \
-e SPRING_CLOUD_CONFIG_SERVER_COMPOSITE_0_PASSWORD=xxxxxxx (密码) \
-e JHIPSTER_CORS_ALLOWED-ORIGINS="*" \
-e JHIPSTER_CORS_ALLOWED-METHODS="*" \
-e JHIPSTER_CORS_ALLOWED-HEADERS="*" \
-e JHIPSTER_CORS_EXPOSED-HEADERS="Authorization,Link,X-Total-Count" \
-e JHIPSTER_CORS_ALLOWED-CREDENTIALS=true \
-e JHIPSTER_CORS_MAX-AGE=1800 \
-e ENCRYPT_KEY=jmvcsmscryptkeysit \
-e EUREKA_CLIENT_SERVICE-URL_DEFAULTZONE=http://admin:admin@eureka-peer-2:8762/eureka/  \
-v /etc/localtime:/etc/localtime \
--network jm \
--ip 172.20.0.100 \
--add-host eureka-peer-1:172.20.0.100 \
--add-host eureka-peer-2:172.20.0.101 \
--add-host localhost:127.0.0.1 \
--restart=always \
-itd --name jm_registry_sit_peer1 \
jhipster/jhipster-registry:v6.2.0

docker run \
-e SPRING_PROFILES_ACTIVE=dev,composite,swagger,peer2,zipkin,no-liquibase  \
-e SPRING_CLOUD_CONFIG_SERVER_COMPOSITE_0_TYPE=git \
-e SPRING_CLOUD_CONFIG_SERVER_COMPOSITE_0_URI="https://devops.ttotox.net/XXXXXXXX/_git/profile-sit" \
-e SPRING_CLOUD_CONFIG_SERVER_COMPOSITE_0_SEARCH-PATHS="/"  \
-e SPRING_CLOUD_CONFIG_SERVER_COMPOSITE_0_USERNAME=cicd.xxx  \
-e SPRING_CLOUD_CONFIG_SERVER_COMPOSITE_0_PASSWORD=xxxxxx  \
-e JHIPSTER_CORS_ALLOWED-ORIGINS="*" \
-e JHIPSTER_CORS_ALLOWED-METHODS="*" \
-e JHIPSTER_CORS_ALLOWED-HEADERS="*" \
-e JHIPSTER_CORS_EXPOSED-HEADERS="Authorization,Link,X-Total-Count" \
-e JHIPSTER_CORS_ALLOWED-CREDENTIALS=true \
-e JHIPSTER_CORS_MAX-AGE=1800 \
-e ENCRYPT_KEY=jmvcsmscryptkeysit \
-e EUREKA_CLIENT_SERVICE-URL_DEFAULTZONE=http://admin:admin@eureka-peer-1:8761/eureka/  \
-v /etc/localtime:/etc/localtime \
--network jm \
--ip 172.20.0.101 \
--add-host eureka-peer-1:172.20.0.100 \
--add-host eureka-peer-2:172.20.0.101 \
--add-host localhost:127.0.0.1 \
--restart=always \
-itd --name jm_registry_sit_peer2 \
jhipster/jhipster-registry:v6.2.0


SPRING_PROFILES_ACTIVE 此变量prod,composite,swagger,peer1,zipkin,no-liquibase

prod或者dev是registry自带有两个配置文档,如果想自定义uat则在项目下新建uat的配置文档即可,使用prod则说明优先读prod的配置
composite,peer1此为组合使用,涉及到eureka注册地址
swagger,开启swagger查看api zipkin,监控相关
no-liquibase,不使用liquibase记录数据库表结构变更

上面起了两个registry后,接下来就是新建jenkins流水线,因为CI之前已经弄好了,这里只需要弄好CD即可。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
流水线新建完成,这里的git库用户凭据是之前就生成了的,若没有,可自己新建一个。jenkins->凭据->系统->全局凭据->新建凭据
在这里插入图片描述
再查看一下git库下的dev_cd_sit中的脚本。总的来说就是给个微服务的名称,然后给个镜像的版本号,就可以自动部署起来。里面还有一个参数sshId,这是一个远程的凭据,是从jenkins服务器连到要部署微服务的那台服务器,也就是89到55,再看下面的脚本用的是 sshUserPrivateKey,说明这是一个PrivateKey凭据,貌似之前的免密白搞了,于是再生成一个私钥凭证。

pipeline {
	agent any
	parameters {
        string(name: 'MS_NAME', defaultValue: '', description: '微服务名称')
		string(name: 'COMMIT_ID', defaultValue: '', description: 'COMMIT_ID')
    }
    environment {
        PATH = "$PATH"
		remote="172.31.17.55"
		serverName="${params.MS_NAME}"
		container="jm_${serverName}_1"
		dockerRegistryUser="impos"
		dockerRegistryPassword="impos"
		dockerRegistry="repo.ttoocx.xyz"
        dockerTag="${dockerRegistry}/jm/ms_${serverName}"
		sshId="301a3c42-657d-4a2c-a003-e220466xxxxx"
		dockerJavaOpts="-Xmx800M"
		dockerRunParams=""
    }	
    stages {
        stage("Initialization") {
            steps {
                // use name of the patchset as the build name
                buildName "#${BUILD_NUMBER}-${serverName}-${params.COMMIT_ID}"
                buildDescription "${serverName}"
            }
        }		
        stage('通过SSH发布到DEV') {
            steps {
				script{
					withCredentials([sshUserPrivateKey(credentialsId: "${sshId}", keyFileVariable: 'PRIVATEKEYFILE', passphraseVariable: '', usernameVariable: 'USERNAME')]) {			
						script{
							try {
								sh "ssh -o \"StrictHostKeyChecking no\" ${USERNAME}@${remote} -i ${PRIVATEKEYFILE} sudo docker rm -f ${container}"
								sh "ssh -o \"StrictHostKeyChecking no\" ${USERNAME}@${remote} -i ${PRIVATEKEYFILE} sudo docker system prune -a -f"
							}
							catch(error){
								echo "停止旧容器发生错误,可能是已经被删除,跳过"
							}
						}		
						sleep 5
						def dockerRunParams=""	
						if (params.MS_NAME == 'gateway') {
							dockerRunParams="--ip 172.20.0.102";
						}						
						if (params.MS_NAME == 'file') {
							dockerRunParams="-v /opt/jm/files:/files:Z";
						}
						if (params.MS_NAME == 'websocket') {
							dockerRunParams="-p 2222:8081";
						}		
						if(params.MS_NAME=='wechat'){
							dockerRunParams = "-v /opt/jm/wechat/apiclient_cert.p12:/wechat/cert.p12";
						}
						sh "ssh -o \"StrictHostKeyChecking no\" ${USERNAME}@${remote} -i ${PRIVATEKEYFILE} sudo docker login -p ${dockerRegistryUser} -u ${dockerRegistryPassword} ${dockerRegistry}"
						sh "ssh -o \"StrictHostKeyChecking no\" ${USERNAME}@${remote} -i ${PRIVATEKEYFILE} sudo docker run ${dockerRunParams} -e EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE=http://admin:admin@eureka-peer-1:8761/eureka,http://admin:admin@eureka-peer-2:8762/eureka -e SPRING_CLOUD_CONFIG_URI=http://admin:admin@eureka-peer-1:8761/config,http://admin:admin@eureka-peer-2:8762/config -e JHIPSTER_REGISTRY_PASSWORD=admin -e SPRING_PROFILES_ACTIVE=dev,composite,swagger,zipkin,no-liquibase -e JAVA_OPTS=\"${dockerJavaOpts}\" --network jm --add-host eureka-peer-1:172.20.0.100 --add-host eureka-peer-2:172.20.0.101 --restart=always --name ${container} -itd ${dockerTag}:${params.COMMIT_ID}"
						
					}	
				}			
            }
        }			
    }
}

生成私钥凭证
在这里插入图片描述
在这里插入图片描述
仔细思考一下,如果89要连到55去操作,而之前免密的时候就已经把公钥发到了55这台服务器,那么jenkins(89)想要操作55,是不是只需要把与那个公钥配对的那个私钥配到这个凭证里,之后就可以登录55那台机操作了?

登录89,找到私钥,一开始进到jenkins用户,发现没有.ssh目录,于是再运行ssh-keygen看它保存的路径在哪里。在此路径下找到id_rsa文件,把里面的内容配到凭证 私钥位置。注意整个放进去,不要去掉开头和结尾的----
在这里插入图片描述
保存凭据,拿到id,配置到脚本的sshId处。

运行流水线,看是否能成功启动容器,以及容器是否注册进registry。
遇到的问题:
1、一开始凭据使用的是用户名密码,运行流水线后,报错ERROR: Credentials ‘f27ebc14-a76e-4d13-8990-701b7acda412’ is of type ‘Username with password’ where ‘com.cloudbees.jenkins.plugins.sshcredentials.SSHUserPrivateKey’ was expected
查看脚本后,发现使用的是SSHUserPrivateKey,而我使用的凭据是用户名密码的,于是更换凭据,得到解决。

2、私钥凭证,一开始有些换乱,不知道是要哪个私钥,后来仔细思考,这个凭证到底是干啥用的?
看脚本是要ssh连接到55那台机使用的,那如何才能ssh连接到服务器?之前学习的时候有了解到可以使用用户密码以及公钥私钥登录,但是具体的原理没有深入去理解,ssh-kengen这是生成一个密钥对,一个公钥一个私钥,ssh-copy-id其实是把公钥放到服务器,那为什么这样就可以远程?客户端拿着私钥去到服务器,服务器中的公钥可以与之配对,于是得以通过认证,连接到服务器。那么如果jenkins要连接到服务器,也就是只要拿着与之匹配的私钥过去即可,于是想到拿jenkins生成的那条私钥,配上,成功。

3、容器运行起来后,发现没有注册进registry,检查脚本后,发现是参数SPRING_PROFILES_ACTIVE ,启动registry与CD脚本中启动容器的值不一致,修改为一致的之后得到解决。

4、之前是直接暴露registry容器地址,以此访问registry后台,但是这次的脚本中发现没有暴露registry的端口,而开发环境中确实可以通过该端口访问registry的,查看之后发现加了一层,用了nginx来转发,把nginx运行起来,通过nginx来暴露registry的端口,给到外部访问,该问题得到解决。
启动nginx的命令及配置文件如下:

sudo docker run --privileged=true -v /opt/jm/nginx/:/etc/nginx/conf.d/:ro -p 80:80 -p 8761:8761 -p 8080:8080 --network jm --restart=always --name nginx -d nginx

查看挂载的/opt/jm/nginx文件目录下有两个文件,一个是default.conf和registry.conf
default.conf文件内容如下
upstream gateway {
    server 172.20.0.102:8080; #查看之前CD脚本,这是gateway的ip
}
server {
    listen       80;
    listen  8080;
    server_name  localhost;

    #charset koi8-r;
    access_log  /var/log/nginx/host.access.log  main;
    error_log   /var/log/nginx/error.default.log    error;
    location / {
        proxy_pass http://gateway;
        proxy_http_version 1.1;
        proxy_buffer_size  128k;
        proxy_buffers   32 256k;
        proxy_busy_buffers_size 256k;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    location /html {
        root   /usr/share/nginx;
        index  index.html index.htm;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}


registry.conf文件内容如下

upstream registry {
    server 172.20.0.100:8761;
    server 172.20.0.101:8762;
}

server {
    listen       8761;
    server_name  localhost;

    location / {
  
        proxy_pass http://registry;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值