** 開發(fā)者將代碼提交(push)到GitLab后,GitLab通過Hook通知jenkins,jenkins自動(dòng)從GitLab中獲取項(xiàng)目最新的源碼進(jìn)行集成和發(fā)布。 1. 構(gòu)建私有的GitLab容器
>```javascriptversion: '2'services: redis: restart: always image: sameersbn/redis:latest command: - --loglevel warning volumes: - /srv/docker/gitlab/redis:/var/lib/redis:Z #文件的掛載點(diǎn) postgresql: restart: always image: sameersbn/postgresql:9.6-2 volumes: - /srv/docker/gitlab/postgresql:/var/lib/postgresql:Z #文件的掛載點(diǎn) environment: - DB_USER=gitlab - DB_PASS=password - DB_NAME=gitlabhq_production - DB_EXTENSION=pg_trgm gitlab: restart: always image: sameersbn/gitlab:9.1.4 depends_on: - redis - postgresql ports: - '10080:80' - '10022:22' volumes: - /srv/docker/gitlab/gitlab:/home/git/data:Z #文件的掛載點(diǎn) environment: - DEBUG=false - DB_ADAPTER=postgresql - DB_HOST=postgresql - DB_PORT=5432 - DB_USER=gitlab - DB_PASS=password - DB_NAME=gitlabhq_production - REDIS_HOST=redis - REDIS_PORT=6379 - TZ=Asia/Kolkata - GITLAB_TIMEZONE=Kolkata - GITLAB_HTTPS=false - SSL_SELF_SIGNED=false - GITLAB_HOST=localhost - GITLAB_PORT=10080 - GITLAB_SSH_PORT=10022 - GITLAB_RELATIVE_URL_ROOT= - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string - GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alphanumeric-string - GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alphanumeric-string - GITLAB_ROOT_PASSWORD= - GITLAB_ROOT_EMAIL= - GITLAB_NOTIFY_ON_BROKEN_BUILDS=true - GITLAB_NOTIFY_PUSHER=false - GITLAB_EMAIL=notifications@example.com - GITLAB_EMAIL_REPLY_TO=noreply@example.com - GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com - GITLAB_BACKUP_SCHEDULE=daily - GITLAB_BACKUP_TIME=01:00 - SMTP_ENABLED=false - SMTP_DOMAIN=www.example.com - SMTP_HOST=smtp.gmail.com - SMTP_PORT=587 - SMTP_USER=mailer@example.com - SMTP_PASS=password - SMTP_STARTTLS=true - SMTP_AUTHENTICATION=login - IMAP_ENABLED=false - IMAP_HOST=imap.gmail.com - IMAP_PORT=993 - IMAP_USER=mailer@example.com - IMAP_PASS=password - IMAP_SSL=true - IMAP_STARTTLS=false - OAUTH_ENABLED=false - OAUTH_AUTO_SIGN_IN_WITH_PROVIDER= - OAUTH_ALLOW_SSO= - OAUTH_BLOCK_AUTO_CREATED_USERS=true - OAUTH_AUTO_LINK_LDAP_USER=false - OAUTH_AUTO_LINK_SAML_USER=false - OAUTH_EXTERNAL_PROVIDERS= - OAUTH_CAS3_LABEL=cas3 - OAUTH_CAS3_SERVER= - OAUTH_CAS3_DISABLE_SSL_VERIFICATION=false - OAUTH_CAS3_LOGIN_URL=/cas/login - OAUTH_CAS3_VALIDATE_URL=/cas/p3/serviceValidate - OAUTH_CAS3_LOGOUT_URL=/cas/logout - OAUTH_GOOGLE_API_KEY= - OAUTH_GOOGLE_APP_SECRET= - OAUTH_GOOGLE_RESTRICT_DOMAIN= - OAUTH_FACEBOOK_API_KEY= - OAUTH_FACEBOOK_APP_SECRET= - OAUTH_TWITTER_API_KEY= - OAUTH_TWITTER_APP_SECRET= - OAUTH_GITHUB_API_KEY= - OAUTH_GITHUB_APP_SECRET= - OAUTH_GITHUB_URL= - OAUTH_GITHUB_VERIFY_SSL= - OAUTH_GITLAB_API_KEY= - OAUTH_GITLAB_APP_SECRET= - OAUTH_BITBUCKET_API_KEY= - OAUTH_BITBUCKET_APP_SECRET= - OAUTH_SAML_ASSERTION_CONSUMER_SERVICE_URL= - OAUTH_SAML_IDP_CERT_FINGERPRINT= - OAUTH_SAML_IDP_SSO_TARGET_URL= - OAUTH_SAML_ISSUER= - OAUTH_SAML_LABEL='Our SAML Provider' - OAUTH_SAML_NAME_IDENTIFIER_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:transient - OAUTH_SAML_GROUPS_ATTRIBUTE= - OAUTH_SAML_EXTERNAL_GROUPS= - OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL= - OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME= - OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME= - OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME= - OAUTH_CROWD_SERVER_URL= - OAUTH_CROWD_APP_NAME= - OAUTH_CROWD_APP_PASSWORD= - OAUTH_AUTH0_CLIENT_ID= - OAUTH_AUTH0_CLIENT_SECRET= - OAUTH_AUTH0_DOMAIN= - OAUTH_AZURE_API_KEY= - OAUTH_AZURE_API_SECRET= - OAUTH_AZURE_TENANT_ID= 在docker-compose.yml文件所在目錄下,執(zhí)行docker-compose up命令(docker-compose命令需要安裝),如果之前沒有下載過GitLab的鏡像會(huì)自動(dòng)下載,如果下載過就直接啟動(dòng)已有的容器。
執(zhí)行完成之后,gitlab容器的80端口綁定在了宿主機(jī)的10080端口,同時(shí)gitlab容器的22端口(ssh)綁定在宿主機(jī)10022端口。可以通過訪問localhost:10080來訪問私有倉(cāng)庫(kù)2. 構(gòu)建Jenkins容器
a.通過Dockerfile構(gòu)建一個(gè)jenkins容器,基于centos7的鏡像。 這里不推薦將一個(gè)基礎(chǔ)鏡像一次性打包成完整的應(yīng)用鏡像,建議構(gòu)建三層鏡像模型。所謂三層鏡像就是,基礎(chǔ)鏡像,中間件鏡像,應(yīng)用鏡像。例如我要構(gòu)建一個(gè)Jenkins 的鏡像,打包一個(gè)基于Centos7 和一些常用工具的鏡像就是基礎(chǔ)鏡像,例如叫Centos7-base。然后這里Jenkins依賴Java和Maven,所以在基于Centos7-base的基礎(chǔ)上安裝配置java及maven后,再打包的鏡像為中間件鏡像,例如叫Centos7-jdk8-mvn3,這層中間件的鏡像我們?yōu)閬淼膹?fù)用會(huì)很高,以后只要有基于java1.8和maven3的,就可以直接使用這個(gè)鏡像進(jìn)行構(gòu)建。最后我們?cè)僭贑entos7-jdk8-mvn3的基礎(chǔ)上安裝配置jenkins,最后打包運(yùn)用在生產(chǎn)環(huán)境。 b.構(gòu)建基礎(chǔ)鏡像,整合jdk及mvn。配置PATH ,安裝所需要的工具,Dockerfile如下: #base on centos 7 imageFROM daocloud.io/centos:7MAINTAINER hoewonLABEL JDK \ 1.8COPY jdk1.8 /usr/local/jdk1.8/ \ maven /usr/local/maven/RUN yum install -y openssh-server openssh-clients git RUN yum install -y iproute net-toolsENV JAVA_HOME /usr/local/jdk1.8ENV PATH $JAVA_HOME/bin:$PATHEXPOSE 8080ENTRYPOINT /bin/bash 將要復(fù)制進(jìn)鏡像里的jdk和maven文件放到與Dockerfile相同的目錄下 執(zhí)行命令打包鏡像 #最后 . 是當(dāng)前目錄的意思,不可省略,或自定義Dockerfile所在目錄docker build -t repo/name:tag . #成功后查看本地鏡像docker images c.通過基礎(chǔ)鏡像安裝jenkins,也是通過Dockerfile #A jenkins 2.7.4 on centos 7 image#基于剛才做好的基礎(chǔ)鏡像FROM 127.0.0.1:5000/env/centos7-jdk8-mvn:1.3MAINTAINER hoewonLABEL JDK1.8 \ Jenkins-2.7.4#復(fù)制jenkins rpm至鏡像COPY jenkins.rpm /usr/local/#創(chuàng)建jenkins用戶,并更改密碼RUN useradd jenkins && echo 'jenkins password' > passwd jenkins --stdin#安裝jenkinsRUN rpm -ivh /usr/local/jenkins.rpm#更改jenkins安裝文件的所有者RUN rpm -ql jenkins | xargs chown -R jenkins:jenkins#創(chuàng)建jenkins日志文件RUN touch /usr/lib/jenkins/jenkins-logs #更改日志文件所有者RUN chown jenkins:jenkins /usr/lib/jenkins/jenkins-logs#曝光8080端口EXPOSE 8080#啟動(dòng)容器時(shí)使用jenkins用戶USER jenkins#定義用戶空間為工作空間WORKDIR /home/jenkins#啟動(dòng)容器時(shí)啟動(dòng)jenkinsENTRYPOINT java -jar /usr/lib/jenkins/jenkins.war &> /usr/lib/jenkins/jenkins-logs d.運(yùn)行jenkins容器,這里需要將container的網(wǎng)絡(luò)設(shè)置跟GtiLab同網(wǎng)絡(luò)的環(huán)境下,同時(shí)我們希望jenkins容器在用maven打包之后,在調(diào)用docker驚醒封裝鏡像,然后推送鏡像至私有的鏡像倉(cāng)庫(kù),所以我們把宿主機(jī)的/usr/bin/docker 和/run/docker.sock 和所依賴的共享庫(kù)文件,在啟動(dòng)容器時(shí)一并掛載至容器內(nèi)部。 # --net 指定docker的網(wǎng)橋 docker run -idt --net mygitlab_default --name jenkins_c -p 8888:8080 -v /usr/lib64/libltdl.so.7:/usr/lib64/libltdl.so.7 -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker 127.0.0.1:5000/myjenkins:1.0 /bin/bash e.容器啟動(dòng)后,8080端口被綁定到了宿主機(jī)的8888端口,訪問localhost:8888來訪問jenkins 3.構(gòu)建私有的Docker 鏡像倉(cāng)庫(kù) docker run \ -e SETTINGS_FLAVOR=s3 \ -e AWS_BUCKET=acme-docker \ -e STORAGE_PATH=/registry \ -e AWS_KEY=AKIAHSHB43HS3J92MXZ \ -e AWS_SECRET=xdDowwlK7TJajV1Y7EoOZrmuPEJlHYcNP2k4j49T \ -e SEARCH_BACKEND=sqlalchemy \ -p 5000:5000 \ daocloud.io/registry 運(yùn)行成功后,可以訪問http://localhost:5000/v2/_catalog 來查看本地倉(cāng)庫(kù)信息 4.構(gòu)建持續(xù)集成環(huán)境 a.在gitlab中創(chuàng)建一個(gè)項(xiàng)目,項(xiàng)目類為public,創(chuàng)建后會(huì)有如下提示,這些提示用來告訴你如何通過客戶端下載項(xiàng)目,并提交項(xiàng)目 #Command line instructions #Git global setupgit config --global user.name 'jenkins'git config --global user.email '15561581025@163.com'#Create a new repositorygit clone ssh://git@localhost:10022/jenkins/demo.gitcd demotouch README.mdgit add README.mdgit commit -m 'add README'git push -u origin master#Existing foldercd existing_foldergit initgit remote add origin ssh://git@localhost:10022/jenkins/demo.gitgit add .git commitgit push -u origin master#Existing Git repositorycd existing_repogit remote add origin ssh://git@localhost:10022/jenkins/demo.gitgit push -u origin --allgit push -u origin --tags b.進(jìn)入jenkins容器,然后通過git客戶端,拉取項(xiàng)目。在拉取之前,需要用使用ssh-keygen來生成當(dāng)前jenkins用戶在jenkins容器的公鑰密鑰,ssh-keygen需要安裝openssh。 ssh-keygen – t rsa 可以一路回車,默認(rèn)生成在jenkins用戶的家目錄下的一個(gè).ssh的文件夾,將.ssh/id_rsa.pub的內(nèi)容全部復(fù)制 c.登錄gitlab,右上角下拉列表下選擇setting,然后在主頁面有一個(gè)SSH Keys的tab頁,將你剛才復(fù)制的公鑰內(nèi)容添加至Key這個(gè)文本框,然后點(diǎn)擊Add key。這個(gè)步驟的意思是,如果你想讓jenkins通過ssh協(xié)議從gitlab拉取項(xiàng)目,需要認(rèn)證,配置的公鑰就是允許jenkins容器的jenkins用戶所運(yùn)行的jenkins從gitlab通過ssh協(xié)議拉取項(xiàng)目(有點(diǎn)別扭,但是需要注意的是jenkins這個(gè)容器主機(jī)和jenkins用戶,jenkins程序是jenkins用戶啟動(dòng)的)。 在配置好key之后,我們回到j(luò)enkins容器,當(dāng)前用戶為jenkins。我們想通過git客戶端拉取項(xiàng)目的第二個(gè)準(zhǔn)備工作,需要配置git的全局配置。 git config --global user.name=”yourName” 我的gitlab 和jenkins的用戶都是jenkins,這里應(yīng)該填寫的是git用戶名git config –global user.email=”your email” 這兩個(gè)配置完成后,我們可以就可以拉取項(xiàng)目到本地了,以我自己demo為例 git clone ssh://git@localhost:10022/jenkins/eurka.git d.現(xiàn)在拉取到當(dāng)前目錄的eurka是個(gè)空項(xiàng)目,我們把我們要上傳的項(xiàng)目源碼和Dockerfile(用來jenkins調(diào)用docker打包鏡像用的)添加至這個(gè)目錄,然后git add ,git commit ,git push 命令將本地文件添加提交并推送整合至gitlab這個(gè)項(xiàng)目的某個(gè)分支下,默認(rèn)是master e.提交完成后,我們開始配置jenkins,以jenkins用戶登錄jenkins,新建,選擇 --構(gòu)建一個(gè)自由風(fēng)格的軟件項(xiàng)目然后確定 f.然后進(jìn)入到這個(gè)項(xiàng)目的配置下,在源碼管理選擇Git,然后在Repository URL下,填入項(xiàng)目的ssh地址,注意這里不可一世用localhost,你可以填寫主機(jī)的ip加上10022端口,也可以配置gitlab容器的ip地址加上22端口,我這里配置的是我的容器地址,例如ssh://git@172.18.0.4:22/jenkins/eurka.git,這里不要寫10022端口?。。。∫?yàn)槭莗ublic項(xiàng)目,所以不需要添加認(rèn)證 h.回到j(luò)enkins的設(shè)置,在構(gòu)建中下Execute shell下,編寫shell腳本,這里就是gitlab被push后,通過webhook的方式讓jenkins自動(dòng)從gitlab下拉取項(xiàng)目之后,要執(zhí)行的代碼 #先打印當(dāng)前位置pwd#進(jìn)入到我的maven項(xiàng)目cd spring-cloud-02-service#maven打包mvn clean compile package -Dmaven.test.skip=true#回到上一級(jí),因?yàn)樯弦患?jí)有Dockerfile文件cd ../#這里我先移除掉了我之前的鏡像,然后再重新構(gòu)建一個(gè)鏡像,如果當(dāng)前有#這個(gè)鏡像運(yùn)行的容器,需要先停止容器,移除容器,最后移除鏡像docker rmi 127.0.0.1:5000/auto/eurka:1.0 . || docker build -t 127.0.0.1:5000/auto/eurka:1.0 .#將打包的鏡像推送到本地的docker倉(cāng)庫(kù)docker push 127.0.0.1:5000/auto/eurka:1.0#查看本地是否打包成功docker images#最后可以執(zhí)行docker run -itd –name container_name -p xxxx:xxxx repo/im#g:tag /bin/bash讓jenkins調(diào)用宿主機(jī)的docker,運(yùn)行剛才打包好的鏡像,不#出意外,應(yīng)該在我們指定的端口上可以訪問這個(gè)項(xiàng)目了。 最初我們?cè)趓un jenkins容器的時(shí)候,將宿主機(jī)的docker文件掛載進(jìn)了容器內(nèi)部,這個(gè)操作很重要,但我也很迷糊,但可以肯定的是,jenkins容器所運(yùn)行的docker及操作是針對(duì)宿主機(jī)的docker的 后續(xù)的持續(xù)集成,要基于kubernetes,kubernetes會(huì)自動(dòng)的找其節(jié)點(diǎn)自動(dòng)拉取剛push的鏡像,并自動(dòng)部署。未完待續(xù) |
|