Docker服务编排05-k8s持续集成(CICD)springcloud微服务

为君一笑 提交于 2019-12-04 16:36:41

DevOps简介

DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。
它是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
它的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运营工作必须紧密合作
详细解释

CICD简介

持续集成(continuous integration )指的是,频繁地(一天多次)将代码集成到主干。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
它的好处主要有两个。
(1)快速发现错误。每完成一点更新,就集成到主干,可以快速发现错误,定位错误也比较容易。
(2)防止分支大幅偏离主干。如果不是经常集成,主干又在不断更新,会导致以后集成的难度变大,甚至难以集成。
持续集成的目的,就是让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。
持续部署(continuous deployment)是通过自动化的构建、测试和部署循环来快速交付高质量的产品。
CICD持续集成设计
在这里插入图片描述
开发人员提交代码gitlab,gitlab通过hook触发事件,调用jenkins ,jenkins触发一系列动作,抓取代码,质量检查,maven构建,制作镜像,push到私服harbor,更新服务到k8s

环境准备

机器主备

机器ip 部署服务 描述
192.168.58.144 jenkins,k8smanager,maven,git 内存>=2G
192.168.58.145 k8sworker,gitlab 内存>=4G gitlab占用2G内存
192.168.58.147 k8sworker ,harbor 内存>=2G

微服务程序

微服务程序使用之前jwt代码
参考 https://blog.csdn.net/liaomin416100569/article/details/86615848

安装gitlab服务器中文版

gitlab私服容器最好有4G内存,否则很难部署成功
首先,Docker 容器数据应该存储于卷中,在这里我们使用最简单的本地命名卷:

  • gitlab-config 存储 GitLab 配置信息
  • gitlab-data 存储数据库
  • gitlab-logs 存储日志
    然后,我们需要创建自定义网络,从而让容器运行于独立的网络中,区别于默认网桥。
docker network create gitlab-net

准备好后,开始运行 Gitlab 容器:

docker run -d \
    --hostname 你的宿主机ip
    -p 8880:80 \
    -p 8443:443 \
    -p 2222:22 \
    --name gitlab \
    --restart unless-stopped \
    -v /root/gitlab-config:/etc/gitlab \
    -v /root/gitlab-logs:/var/log/gitlab \
    -v /root/gitlab-data:/var/opt/gitlab \
    --network gitlab-net \
    twang2218/gitlab-ce-zh:11.1.4

注意 --hostname 你的宿主机ip 不是容器ip啊 这个不加 一般访问首页 都是 响应时间太长的错误
修改 /root/gitlab-config/gitlab.rb
去掉下面这一行的#注释 将 22改成 2222

gitlab_rails['gitlab_shell_ssh_port'] = 2222

修改\root\gitlab-data\gitlab-rails\etc\gitlab.yml 将web端口改成8880

  gitlab:
    ## Web server settings (note: host is the FQDN, do not include http://)
    host: 192.168.58.145
    port: 8880
    https: false

将来创建项目的地址端口必须是宿主机的端口
在这里插入图片描述

重启 gitlab

docker restart gitlab

访问 http://宿主机:8880
在这里插入图片描述
gitlab默认的用户名是root 进入容器内设置密码

[root@swarm02 ~]# docker exec -it gitlab bash
root@192:/# gitlab-rails console production
-------------------------------------------------------------------------------------
 GitLab:       11.1.4 (63daf37)
 GitLab Shell: 7.1.4
 postgresql:   9.6.8
-------------------------------------------------------------------------------------
Loading production environment (Rails 4.2.10)
irb(main):001:0> user = User.where(id: 1).first
=> #<User id:1 @root>
irb(main):002:0> user.password=12345678
=> 12345678
irb(main):003:0> user.password_confirmation=12345678
=> 12345678
irb(main):004:0> user.save!
Enqueued ActionMailer::DeliveryJob (Job ID: 11333c17-1641-43cd-af4f-5fd1bf103d49) to Sidekiq(mailers) with arguments: "DeviseMailer", "password_change", "deliver_now", gid://gitlab/User/1
=> true
irb(main):005:0> quit
root@192:/# exit
exit

设置完成使用用户名root,密码123456登录,也可以自己注册一个账号
在这里插入图片描述

安装jenkins

使用war包安装参考 https://blog.csdn.net/liaomin416100569/article/details/78431720
使用docker安装

docker run -d -p 8880:8080 -p 50000:50000 -v /root/jenkins_home:/var/jenkins_home -u root --privileged --name jenkins jenkins

使用docker logs jenkins 查看生成的随机密码

INFO: 

*************************************************************
*************************************************************
*************************************************************

Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

e4addedcc5db483d910fa03794a3ff24

This may also be found at: /var/jenkins_home/secrets/initialAdminPassword

*************************************************************
*************************************************************
*************************************************************

其中我的密码时:e4addedcc5db483d910fa03794a3ff24
也可以通过(挂载容器的volum是/root/jenkins_home)

[root@swarm01 ~]# more /root/jenkins_home/secrets/initialAdminPassword
e4addedcc5db483d910fa03794a3ff24

访问安装宿主机:8880
在这里插入图片描述
输入密码 其他操作可以参考https://blog.csdn.net/liaomin416100569/article/details/78431720在这里插入图片描述
安装插件选择
在这里插入图片描述
安装所有流水线插件
在这里插入图片描述
点击确认,之后就等待安装完成罗
一般流水线都会安装失败,安装失败没关系 继续完成 输入admin的用户名和密码 注意所有字段必填 ,不填会卡住
登录进入后 点击系统管理 很多错误 拉倒最下面 升级到 2.57.1 然后重启,流水线插件就会安装完成,重启再次登录就可以在新建任务列表看到流水线
在这里插入图片描述
安装完成后才发现个问题 maven和git都需要安装在容器中 麻烦 拷贝容器的jenkins.war还是在宿主机运行得了

docker cp jenkins:/usr/share/jenkins/jenkins.war /root/jenkins_home/

启动jenkins(要先停止容器)

nohup java -jar jenkins.war --httpPort=8880 &

修改 /root/.jenkins/hudson.model.UpdateCenter.xml
将其中
https://updates.jenkins.io/update-center.json
修改为
http://updates.jenkins.io/update-center.json
杀掉进程重启 如果不修改可能出现This Jenkins instance appears to be offline问题
安装完插件登录有可能卡在登陆卡在SetupWizard界面 重启下jenkins即可解决

安装harbor

私服安装参考https://blog.csdn.net/liaomin416100569/article/details/86599571
144可以先登录到harbor,因为制作镜像上传

docker login --username admin --password 123456 192.168.58.147

安装maven

将平时用到maven库和索引拷贝到jenkin同一台机器
修改本地仓库到你的本地仓库
比如我的maven安装在/root/apache-maven-3.0.4_localtest 本地仓库在/root/apache-maven-3.0.4_localtest/resp
修改 conf/settings.xml

<localRepository>/root/apache-maven-3.0.4_localtest/resp</localRepository>

设置环境变量到path

sed -e `grep -n PATH= /root/.bash_profile | cut -d: -f1`'a\PATH=$PATH:/root/apache-maven-3.0.4_localtest/bin\' /root/.bash_profile &&  chmod +x /root/apache-maven-3.0.4_localtest/bin/* && source /root/.bash_profile

查看mvn版本

[root@swarm01 conf]# mvn -v
Apache Maven 3.0.4 (r1232337; 2012-01-17 16:44:56+0800)
Maven home: /root/apache-maven-3.0.4_localtest
Java version: 1.7.0_79, vendor: Oracle Corporation
Java home: /usr/java/jdk1.7.0_79/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-327.el7.x86_64", arch: "amd64", family: "unix"

安装git客户端

所有机器安装git,执行命令

yum -y install git
[root@swarm02 ~]# git --version
git version 1.8.3.1

安装k8s集群

直接使用上篇文章的环境 https://blog.csdn.net/liaomin416100569/article/details/86711655

部署微服务

部署微服务

上传代码

一般开发时程序需要更新代码到gitlab私服中,假设项目名称是springcloud
在这里插入图片描述
具体你可以使用 idea使用git提交
提交过后可以使用CICD(流水线)安装gitlab-runner后进行代码质量检查等

添加构建服务

登录jenkins
创建一个自由风格的项目
源代码管理选择git 路径输入 http://192.168.58.145:8880/root/springcloud.git 项目公共 无需配置密码
Build Triggers 选择Trigger builds remotely (e.g., from scripts) 输入秘钥springcloud
触发构建只需要访问:http://192.168.58.144:8880/job/springcloud/build?token=springcloud
在这里插入图片描述
接下来添加构建步骤 选择类型 执行shell
我最终配置的shell是

chmod +x ${WORKSPACE}/cicd.sh
${WORKSPACE}/cicd.sh

${WORKSPACE}表示git拉去的源代码目录
将来构建就会自动运行源代码目录的cicd.sh脚本
接下里看我的源代码的结构 三个项目
在这里插入图片描述
编写springcloud_userclient的Dockerfile 用于制作镜像,直接访问子项目springcloud_userclient目录下

FROM insideo/jre8:8u121
RUN mkdir /code
COPY ./target/springcloud_userclient-0.0.1-SNAPSHOT.jar /code
WORKDIR /code
CMD ["java","-jar","/code/springcloud_userclient-0.0.1-SNAPSHOT.jar"]

编写springcloud_userservice的Dockerfile文件

FROM insideo/jre8:8u121
RUN mkdir /code
COPY ./target/springcloud_userservice-0.0.1-SNAPSHOT.jar /code/
WORKDIR /code
CMD ["java","-jar","/code/springcloud_userservice-0.0.1-SNAPSHOT.jar"]

在thrift项目根目录下新建build-source.sh 用于构建项目打jar包

mvn clean compile package -Dmaven.test.skip=true

在thrift项目根目录下新建build-images.sh 用于构建镜像 上传到私服

curTime=$1
docker build -t userclient_$curTime ./springcloud_userclient
docker build -t userservice_$curTime ./springcloud_userservice
docker tag userclient_$curTime 192.168.58.147/mylib/userclient_$curTime
docker tag userservice_$curTime 192.168.58.147/mylib/userservice_$curTime
docker push 192.168.58.147/mylib/userclient_$curTime
docker push 192.168.58.147/mylib/userservice_$curTime

在thrift项目根目录下创建项目依赖的redis k8s yaml部署文件 redis-depoyment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:latest
        ports:
        - containerPort: 6379

---
apiVersion: v1
kind: Service
metadata:
  labels:
    run: redis
  name: redis
  namespace: default
spec:
  ports:
  - nodePort: 20001
    port: 6379
    protocol: TCP
    targetPort: 6379
  selector:
    app: redis
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

在thrift项目根目录下创建项目依赖的eurekak8s yaml部署文件 eureka-depoyment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: eureka-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: eureka
    spec:
      containers:
      - name: eureka
        image: springcloud/eureka:latest
        ports:
        - containerPort: 8761

---
apiVersion: v1
kind: Service
metadata:
  labels:
    run: eureka
  name: eureka
  namespace: default
spec:
  ports:
  - nodePort: 20002
    port: 8761
    protocol: TCP
    targetPort: 8761
  selector:
    app: eureka
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

接下来thrift项目根目录下创建创建最终的cicd.sh文件
这里注意 因为userclient和userservice是我们的项目 一旦需要重新制作镜像就需要产生一个新的
镜像名称 我这里是使用 项目名称_当前时间戳来作为镜像名称

curTime=`date +%s`
#1.编译源代码打包
source ./build-source.sh
#2.构建镜像 上传harbor
source ./build-images.sh $curTime
# 3.安装redis和eureka服务
kubectl apply -f redis-depoyment.yaml
kubectl apply -f eureka-depoyment.yaml
#安装 userclient
cat <<EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: userclient-deployment
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: userclient
    spec:
      containers:
      - name: userclient
        image: 192.168.58.147/mylib/userclient_$curTime
        ports:
        - containerPort: 8000

---
apiVersion: v1
kind: Service
metadata:
  labels:
    run: userclient
  name: userclient
  namespace: default
spec:
  ports:
  - nodePort: 20003
    port: 8000
    protocol: TCP
    targetPort: 8000
  selector:
    app: userclient
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}
EOF

#4. 安装 userservice
cat <<EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: userservice-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: userservice
    spec:
      containers:
      - name: userservice
        image: 192.168.58.147/mylib/userservice_$curTime
        ports:
        - containerPort: 8899
EOF

ok准备就绪 点击jenkins项目的开始构建
构建成功后查看harbor 是否多了两个个最近时间的镜像
在这里插入图片描述
查看所有pods

[root@swarm01 springcloud]# kubectl get svc -o wide    
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE       SELECTOR
eureka       NodePort    10.68.147.217   <none>        8761:20002/TCP   4h        app=eureka
kubernetes   ClusterIP   10.68.0.1       <none>        443/TCP          19d       <none>
redis        NodePort    10.68.83.252    <none>        6379:20001/TCP   4h        app=redis
userclient   NodePort    10.68.212.41    <none>        8000:20003/TCP   19m       app=userclient

可以看到 eureka暴露的宿主机的20002端口
userclient 暴露了宿主机的20003端口
访问eureka 查看是否注册了2个userservice 1个userclient
http://192.168.58.145:20003/
在这里插入图片描述
访问页面查看是否能互相调用
http://192.168.58.145:20003/login.html
接下里可以在gitlab中 设置
在这里插入图片描述
点击系统钩子 url输入jenkins触发的url
在这里插入图片描述
jenkins默认是不允许其他网页远程来访问 所以需要关闭权限和cors保护
点击设置-全局安全设置
在这里插入图片描述

修改登录页面的代码 提交 测试刷新界面 看是否正常部署

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!