cicd实战
cicd实验1:
图解

环境:
2个仓库,test,deploy
-
test仓库,go代码
-
deploy仓库,dockerfile文件(基于编译好的go代码构建镜像),部署文件
jenkins
kubernetes
gitee
harbor
实验流程
问题:test上有一个go代码,需要将其编译,推送到harbor仓库上,拉取这个harbor仓库镜像,部署到k8s节点上
-
不要小看这几句话,涉及到的操作非常的多
-
首先就是jenkins连接gitee,harbor,需要创建2个凭证,拉取代码,推送构建好的镜像到harbor
-
自己构建带有go环境的镜像,需要编译go代码为二进制文件
-
拉取deploy仓库,里面有dockerfile文件(将编译好的二进制文件构建成镜像),部署文件
-
自己构建一个docker环境的镜像,构建编译好的镜像,推送到harbor仓库
-
构建一个带有kubectl环境的镜像,部署文件
1、go代码文件
一个go编写的应用程序
package main
import (
"fmt"
"net/http"
)
// 处理函数:访问 / 时返回 hello world
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello world")
}
func main() {
// 绑定路由:访问 http://localhost:8080 就触发 helloHandler
http.HandleFunc("/", helloHandler)
fmt.Println("服务启动成功,监听端口 8080")
fmt.Println("访问地址:http://127.0.0.1:8080")
// 监听 0.0.0.0:8080
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Println("服务启动失败:", err)
}
}
2、构建go环境镜像
[root@master01 dockerimage]# ls
dockerfile openEuler.repo
[root@master01 dockerimage]# cat dockerfile
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/openeuler/openeuler:22.03-lts-sp4
COPY ./openEuler.repo /etc/yum.repos.d/
RUN set -ex; \
yum -y install tar curl ; \
curl https://mirrors.aliyun.com/golang/go1.16.9.linux-amd64.tar.gz -O ; \
tar -xf go1.16.9.linux-amd64.tar.gz -C /usr/local/
ENV GO_HOME=/usr/local/go
ENV PATH=$PATH:$GO_HOME/bin
RUN go version
# 推送到harbor仓库
3、编译go代码
pipeline {
agent {
kubernetes {
cloud "k8s"
showRawYaml true
yaml """
apiVersion: "v1"
kind: "Pod"
metadata:
name: "go"
namespace: "devops"
spec:
serviceAccount: jenkins-admin // 用户为jenkins-admin
securityContext:
runAsUser: 0 // 提权为root
volumes:
- name: localtime
hostPath:
path: /etc/localtime
containers:
- name: jnlp
image: jenkins/inbound-agent
args: ['\$(JENKINS_SECRET)', '\$(JENKINS_NAME)']
- command:
- "cat"
image: "192.168.50.21:5000/jichu/go:v1" // 拉取镜像
name: "go"
tty: true
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
"""
}
}
options { // 选项参数
timestamps()
skipDefaultCheckout()
disableConcurrentBuilds()
timeout(time: 1, unit: 'HOURS')
}
stages {
stage("获取代码") {
steps {
echo "git拉取go代码....." // 通过流水线语法,自动生成拉取gitee仓库代码
git changelog: false, credentialsId: '1', poll: false, url: 'https://gitee.com/qw_97/test.git'
}
}
stage("执行编译go代码") {
steps {
container("go") { // 编译go代码
sh '''
go mod init test
go mod tidy
/usr/local/go/bin/go build -o code .
ls -lh ./
'''
}
}
}
}
}
4、构建docker环境镜像
[root@master01 dockerimage]# ls
dockerfile openEuler.repo
[root@master01 dockerimage]# cat dockerfile
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/openeuler/openeuler:22.03-lts-sp4
COPY ./openEuler.repo /etc/yum.repos.d/
RUN set -ex; \
yum -y install docker; \
# 推送到harbor
- 容器还需要挂载docker.sock文件,因为是一个c/s架构,使用docker命令的时候需要去连接服务端
5、构建编译好的go文件为镜像
deploy仓库下有dockerfile文件
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/openeuler/openeuler:22.03-lts-sp4
RUN set -ex; \
mkdir -p /apps
COPY code /apps/code
EXPOSE 8080
CMD ["/apps/code"]
pipeline {
agent {
kubernetes {
cloud "k8s"
showRawYaml true
yaml """
apiVersion: "v1"
kind: "Pod"
metadata:
name: "go"
namespace: "devops"
spec:
serviceAccount: jenkins-admin
securityContext:
runAsUser: 0
volumes:
- name: localtime
hostPath:
path: /etc/localtime
- name: docker-sock
hostPath:
path: /var/run/docker.sock
containers:
- name: jnlp
image: jenkins/inbound-agent
args: ['\$(JENKINS_SECRET)', '\$(JENKINS_NAME)']
- command:
- "cat"
image: "192.168.50.21:5000/jichu/go:v1"
name: "go"
tty: true
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
- command:
- "cat"
image: "192.168.50.21:5000/jichu/docker:v1"
name: "docker"
tty: true
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
- name: docker-sock
mountPath: /var/run/docker.sock // docker.sock挂载
- command:
- "cat"
image: "192.168.50.21:5000/jichu/kubectl:v1.23.0"
name: "kubectl"
tty: true
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
"""
}
}
options {
timestamps()
skipDefaultCheckout()
disableConcurrentBuilds()
timeout(time: 1, unit: 'HOURS')
}
environment { // 定义环境变量,连接harbor仓库的
registry_account = credentials("2")
}
stages {
stage("获取代码") {
steps {
echo "git拉取go代码....."
git changelog: false, credentialsId: '1', poll: false, url: 'https://gitee.com/qw_97/test.git'
}
}
stage("执行编译go代码") {
steps {
container("go") {
sh '''
go mod init test
go mod tidy
/usr/local/go/bin/go build -o code .
ls -lh ./
'''
}
}
}
stage("构建镜像") {
steps {
git changelog: false, credentialsId: '1', poll: false, url: 'https://gitee.com/qw_97/deploy.git' // 拉取deploy仓库代码,里面有dockerfile文件,部署文件
container("docker") {
sh "docker login -u ${registry_account_USR} -p ${registry_account_PSW} 192.168.50.21:5000" // 登录harbor仓库
sh "docker -v"
sh "docker build -t webapp:v1 . -f dockerfile" // 构建镜像
sh "docker tag webapp:v1 192.168.50.21:5000/jichu/webapp:v1"
sh "docker push 192.168.50.21:5000/jichu/webapp:v1" // 推送镜像到harbor
}
}
}
}
}
6、构建带有kubectl环境镜像
-
kubectl 二进制文件,直接拷贝即可,需要使用config文件
-
其实这一步可以放在构建docker环境镜像里面,这样的话就不需要在启动一个容器部署
-
但是了linux就是一个任务就干一件事
[root@master01 kuebctl]# ls
dockerfile kubectl
[root@master01 kuebctl]# cat dockerfile
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/openeuler/openeuler:22.03-lts-sp4
COPY ./kubectl /usr/bin/kubectl # 需要这个授权文件,才能控制k8s集群
RUN set -ex; \
chmod +x /usr/bin/kubectl
# 推送到harbor仓库上
7、部署到k8s节点
pipeline {
agent {
kubernetes {
cloud "k8s"
showRawYaml true
yaml """
apiVersion: "v1"
kind: "Pod"
metadata:
name: "go"
namespace: "devops"
spec:
serviceAccount: jenkins-admin
securityContext:
runAsUser: 0
volumes:
- name: localtime
hostPath:
path: /etc/localtime
- name: docker-sock
hostPath:
path: /var/run/docker.sock
containers:
- name: jnlp
image: jenkins/inbound-agent
args: ['\$(JENKINS_SECRET)', '\$(JENKINS_NAME)']
- command:
- "cat"
image: "192.168.50.21:5000/jichu/go:v1"
name: "go"
tty: true
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
- command:
- "cat"
image: "192.168.50.21:5000/jichu/docker:v1"
name: "docker"
tty: true
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
- name: docker-sock
mountPath: /var/run/docker.sock
- command:
- "cat"
image: "192.168.50.21:5000/jichu/kubectl:v1.23.1"
name: "kubectl"
tty: true
volumeMounts:
- mountPath: "/etc/localtime"
name: "localtime"
"""
}
}
options {
timestamps()
skipDefaultCheckout()
disableConcurrentBuilds()
timeout(time: 1, unit: 'HOURS')
}
environment {
registry_account = credentials("2")
}
stages {
stage("获取代码") {
steps {
echo "git拉取go代码....."
git changelog: false, credentialsId: '1', poll: false, url: 'https://gitee.com/qw_97/test.git'
}
}
stage("执行编译go代码") {
steps {
container("go") {
sh '''
go mod init test
go mod tidy
/usr/local/go/bin/go build -o code .
ls -lh ./
'''
}
}
}
stage("构建镜像") {
steps {
git changelog: false, credentialsId: '1', poll: false, url: 'https://gitee.com/qw_97/deploy.git'
container("docker") {
sh "docker login -u ${registry_account_USR} -p ${registry_account_PSW} 192.168.50.21:5000"
sh "docker -v"
sh "docker build -t webapp:v1 . -f dockerfile"
sh "docker tag webapp:v1 192.168.50.21:5000/jichu/webapp:v1"
sh "docker push 192.168.50.21:5000/jichu/webapp:v1"
}
}
}
stage("部署应用"){
steps {
container("kubectl") {
sh "kubectl --kubeconfig config apply -f webapp.yml"
sh "kubectl --kubeconfig config apply -f webapp-svc.yml"
}
}
}
}
}
8、构建好的镜像推送到仓库上
- 可以自己运行一下,看是否构建正常
[root@master01 deploy]# docker ps -a| grep webapp
68137984f3fa 192.168.50.21:5000/jichu/webapp:v1 "/apps/code" 4 seconds ago Up 3 seconds 0.0.0.0:8080->8080/tcp webapp1
# 访问
[root@master01 deploy]# curl localhost:8080
hello world
# 构建的镜像是可以访问的,没有任何问题
容器实验环境
可以根据自己的需求构建各种不同的镜像环境
-
构建一个docker镜像容器环境
-
构建一个ssh免密登录镜像容器环境

浙公网安备 33010602011771号