小白成长之路-jenkins使用pipline部署
初始化远程仓库
拉取空仓库
生成代码
上传代码
Git的暂存区
Git的本地仓库
git的远程仓库
问题
原因是你尝试推送代码到远程仓库的主分支(master
),但此时远程仓库的主分支正处于被检出(checked out) 状态,也就是说远程仓库那边有人正在使用这个分支进行工作
解决
在远程仓库设置
允许直接向远程仓库当前正在检出(checked out)的分支推送代码,绕过 Git 默认的安全限制
or
推送新的内容
jenkinsl连接k8集群
Kubernetes 云配置
下载插件
创建新项目
- kubectl cluster-info
- ## 查看K8S集群信息
-
- crt=$(cat /etc/kubernetes/admin.conf | awk -F: '/certificate-authority-data/{print $2}' | tr -d ' ')
- ## 将证书赋给crt变量
-
- echo $crt | base64 -d
- ## 解密证书
AI优化运行代码
获取解密证书
创建连接账户
kubectl create sa jenkins
AI优化运行代码
创建role角色
- kind: Role
- apiVersion: rbac.authorization.k8s.io/v1
- metadata:
- namespace: default
- name: pod-reader-role
- rules:
- - apiGroups: [""]
- resources: ["pods"]
- verbs: ["get", "list", "watch","create","update","delete"]
AI优化运行代码
添加bindroling绑定
- kind: RoleBinding
- apiVersion: rbac.authorization.k8s.io/v1
- metadata:
- namespace: default
- name: pod-reader-role-binding
- subjects:
- - kind: ServiceAccount
- name: jenkins
- namespace: default
- roleRef:
- kind: Role
- name: pod-reader-role
- apiGroup: rbac.authorization.k8s.io
AI优化运行代码
- kubectl describe rolebinding pod-reader-role-binding -n default
- ##查看绑定关系是否建立
-
- kubectl auth can-i get pods -n default --as=system:serviceaccount:default:jenkins
- ##验证是否有读取 Pod 的权限
AI优化运行代码
生成token凭证
有效期为1h
kubectl -n default create token jenkins
AI优化运行代码
添加凭证
添加jenkins地址
部署discuz论坛
- cat /var/lib/jenkins/mysql-svc.yaml
-
- apiVersion: v1
- kind: Service
- metadata:
- name: mysql-svc
- namespace: default
- spec:
- selector:
- app: mysql
- ports:
- - port: 3306
- targetPort: 3306
- clusterIP: None # 无头服务,Pod 可直接通过服务名访问
AI优化运行代码
- cat /var/lib/jenkins/mysql-deploy.yaml
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: mysql
- namespace: default
- spec:
- replicas: 1
- selector:
- matchLabels:
- app: mysql
- template:
- metadata:
- labels:
- app: mysql
- spec:
- containers:
- - name: mysql
- image: mysql:5.7 # 官网镜像
- ports:
- - containerPort: 3306
- env:
- - name: MYSQL_ROOT_PASSWORD
- value: "123.com" # root 密码
- - name: MYSQL_DATABASE
- value: "discuz" # 预创建数据库
- - name: MYSQL_USER
- value: "discuz" # 专用用户
- - name: MYSQL_PASSWORD
- value: "123.com" # 用户密码
- volumeMounts:
- - name: mysql-data
- mountPath: /var/lib/mysql
- - name: init-script
- mountPath: /docker-entrypoint-initdb.d # MySQL 初始化脚本目录
- volumes:
- - name: mysql-data
- emptyDir: {} # 非持久化存储
- - name: init-script
- configMap:
- name: mysql-init-script # 引用初始化脚本的 ConfigMap
- ---
- # 创建 MySQL 初始化脚本的 ConfigMap
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: mysql-init-script
- namespace: default
- data:
- init.sql: |
- # 授权 discuz 用户访问 discuz 数据库(可选,增强权限控制)
- GRANT ALL PRIVILEGES ON discuz.* TO 'discuz'@'%' IDENTIFIED BY '123.com';
- FLUSH PRIVILEGES;
AI优化运行代码
- cat /var/lib/jenkins/discuz-deploy.yaml
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: discuz
- namespace: default
- spec:
- replicas: 1
- selector:
- matchLabels:
- app: discuz
- template:
- metadata:
- labels:
- app: discuz
- spec:
- containers:
- - name: discuz
- image: php:7.4-apache # 官网 PHP+Apache 镜像
- ports:
- - containerPort: 80
- volumeMounts:
- - name: discuz-data
- mountPath: /var/www/html # Apache 网站根目录
- # 安装 Discuz 依赖的 PHP 扩展
- command: ["/bin/sh", "-c"]
- args:
- - apt-get update && \
- apt-get install -y libmysqlclient-dev zip unzip && \
- docker-php-ext-install mysqli pdo pdo_mysql && \
- apache2-foreground
- volumes:
- - name: discuz-data
- emptyDir: {} # 非持久化存储
AI优化运行代码
安装kubectl命令
拷贝证书到 jenkins用户
检测
编写 pipeline
使用构建wezzer平台的镜像
pipeline {
agent any
environment {
// 定义Kubernetes相关环境变量
K8S_MASTER = "192.168.11.10"
POD_NAME = "lnmp-pod"
NAMESPACE = "wezzer"
CONTAINER_PORT = "80"
NODE_PORT = "30080"
IMAGE_NAME = "lnmp:1"
}
stages {
stage('部署到Kubernetes') {
steps {
script {
echo "部署 ${POD_NAME} 到Kubernetes集群..."
// 创建部署的YAML内容
def deploymentYaml = """
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${POD_NAME}
namespace: ${NAMESPACE}
spec:
replicas: 1
selector:
matchLabels:
app: ${POD_NAME}
template:
metadata:
labels:
app: ${POD_NAME}
spec:
containers:
- name: ${POD_NAME}
image: ${IMAGE_NAME}
imagePullPolicy: Never
ports:
- containerPort: ${CONTAINER_PORT}
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
"""
writeFile file: 'deployment.yaml', text: deploymentYaml
sh 'cat deployment.yaml'
sh "kubectl apply -f deployment.yaml -n ${NAMESPACE}"
// 创建Service
def serviceYaml = """
apiVersion: v1
kind: Service
metadata:
name: ${POD_NAME}-service
namespace: ${NAMESPACE}
spec:
selector:
app: ${POD_NAME}
type: NodePort
ports:
- port: ${CONTAINER_PORT}
targetPort: ${CONTAINER_PORT}
nodePort: ${NODE_PORT}
"""
writeFile file: 'service.yaml', text: serviceYaml
sh 'cat service.yaml'
sh "kubectl apply -f service.yaml -n ${NAMESPACE}"
}
}
}
stage('验证部署') {
steps {
script {
echo "验证部署状态..."
sh """
echo "等待Pod就绪..."
kubectl wait --for=condition=ready pod -l app=${POD_NAME} -n ${NAMESPACE} --timeout=300s
echo "部署状态:"
kubectl get deployments ${POD_NAME} -n ${NAMESPACE}
echo "Pod状态:"
kubectl get pods -l app=${POD_NAME} -n ${NAMESPACE}
echo "Service状态:"
kubectl get service ${POD_NAME}-service -n ${NAMESPACE}
echo "部署成功! 访问地址: http://${K8S_MASTER}:${NODE_PORT}"
"""
}
}
}
}
post {
failure {
echo "部署失败!"
}
success {
echo "部署成功! 服务已通过30080端口暴露"
}
}
}