# docker-jenkins **Repository Path**: devin-hung/docker-jenkins ## Basic Information - **Project Name**: docker-jenkins - **Description**: 基于k8s实战docker快速搭建jenkins - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-12-13 - **Last Updated**: 2025-08-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 简介 > 基于docker与jenkins集成,[参考项目github](https://github.com/devin-huang/docker-jenkins),[参考文章](https://yuyanqing.cn/pages/b38f59/#%E5%AE%89%E8%A3%85-docker) - 主要在官方版本之上增加了一些常用的依赖生产可用(详情可见plugins/jenkins) - 初始化账号密码:jenkins/1235678 - [镜像地址](https://hub.docker.com/repository/docker/devinhuang/jenkins/tags) - 重装镜像必须要重启:`systemctl restart docker` ```bash # 添加提前安装好的plugins https://github.com/jenkinsci/docker/blob/master/README.md ADD --chown=jenkins:jenkins plugins/jenkins/2.387.3/ /usr/share/jenkins/ref/plugins/ # 添加初始化脚本,用户提前设置用户名和密码, 需注意:如果你设置了JENKINS_USER变量=admin时会自动修改密码为admin COPY --chown=jenkins:jenkins scripts/set_user_password.groovy /usr/share/jenkins/ref/init.groovy.d/set_user_password.groovy # 安装常用软件 RUN apt-get update && \ apt-get install -y --no-install-recommends make wget vim sshpass net-tools ansible inetutils-ping telnet git openssh-server openssh-client ``` ## 实战步骤 ![Image text](https://devin-huang.github.io/img/pubilc/github/docker-jenkins-steps.png) #### 依赖版本及方式 * Centos(CentOS Linux release 7.9.2009 (Core)) * Docker(docker-ce-24.0.6) * Git(1.8.3.1) * Docker-compose方式启动 * 备注:`docker logs -f --tail 100 【容器名】`:查看容器日志; 打印:`printEnv` #### 准备工作:清除旧jenkins:`rm -rf jenkins_ssh_project/ jenkins/*` #### 第一步:安装docker:`sudo yum install docker-ce-24.0.7 docker-ce-cli-24.0.7 containerd.io --allowerasing`、docker仓库下载镜像 `docker pull devinhuang/jenkins:2.426.2-lts-jdk11-slim` #### 第二步:安装docker-compose,查看是否安装:`docker-compose --version` 【远程服务器提示:docker-compose:not command,需重装】 > 1. 下载(必须github连接):`curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose` > 2. 权限设置:`chmod +x /usr/local/bin/docker-compose` > 3. 查看安装成功否:`docker-compose -v` #### 第三步:目录/opt下创建docker-compose.yml 【参考下面目录:启动方式 - docker-compose方式启动】 > `touch /opt/docker-compose.yml` // 创建docker-compose.yml > `vim /opt/docker-compose.yml` // 写入内容 > `cd /opt` 并执行启动 `docker-compose up -d` > `docker restart jenkins` 重启jenkins #### 第四步:使用`docker-compose`方式启动 > centos(任意目录)执行命令: `/opt docker-compose up -d` 初始化并启动jenkins #### 第五步:jenkins全局配置凭据拉取git项目 > jenkins ->「系统管理(Manage Jenkins)」-> [凭据(credentials)] -> [系统(system)] -> [全局凭据(global credentials)] -> [新增凭据] -> 账号、密码 #### 第六步(非必须步骤 - 跨服务器部署配置):创建跨服务访问的镜像仓库私库 > 前言:实现跨服务器构建项目除了SSH外,还需要依赖腾讯云服务 - 容器镜像仓库 - 新增镜像(docker.hub无法访问缘由),[镜像参考文献](https://cloud.tencent.com/document/product/1141/63910) > 1. 云服务器后台新建个人镜像仓库(免费),配置命名空间与账号密码 > 2. 暂不需腾讯云提供手动往容器里加镜像,而是通过pipeline方式添加,这里也是需要在jenkins加入凭证(参考第五步),参考文件: `pipeline-node-push-image-to-registry` -> `stage('Push Image To Registry')`部分 > 3. jenkins根据镜像登录账号密码全局配置凭据拉取镜像 > 4. 注意:**不使用K8S的话**,首次部署时可以的,但是**第二次重新部署时会报错**出现重复容器问题,主要是因为远程的【权限授权】,远程指令方式只能将远程的容器停止并删除再新建,但部署期间存在无法访问情况。**所以最优做法是远程服务开启两个容器使用nginx做负载均衡,但需注意是每次都需要部署2个容器**,参考文件: `pipeline-node-push-image-to-registry` -> `/docker-compose.yaml down`部分 #### 第七步:SSH 配置(服务器凭证配置,注意:在目标推送服务器中配置) > 1. 【获取秘钥】: 进入centos(任意目录)执行命令:`ssh-keygen -m PEM -t rsa -b 4096` 或 `ssh-keygen -t rsa -P '' -f '/root/.ssh/id_rsa'` (一直回车,如存在就重写) > 2. 【复制id_rsa.pub内容到当前目录authorized_keys文件】:centos(任意目录)执行命令:`cd /root/.ssh/ && cat id_rsa.pub >> authorized_keys` (需要注意的是root代表是jenkins用户名) > 3. 【jenkins依赖,默认已安装当前可忽略】:jenkins下载`jar:ssh-steps.hpi.2.0.0`, 源码地址:`https://github.com/jenkinsci/ssh-steps-plugin/tree/ssh-steps-2.0.0` > 4. 重启jenkins并把「系统管理」-> [凭据] -> [系统] -> [全局凭据] -> [新增凭据] > 凭据配置步骤: > - (1)「类型」- 选择 SSH private Key > - (2)「ID」- 填入 pipeline 配置的 SSH_CREDENTIALS_ID * (自定义ID,只需要ID与SSH_CREDENTIALS_ID对应) * > - (3)「Private Key」- 填入(第二步生成authorized_keys)在跟目录 `/root/.ssh/`中的id_rsa文件,内容(拷贝的始尾: `-----BEGIN RSA PRIVATE KEY-----****-----END RSA PRIVATE KEY-----`) > - (4)「描述」- 备注服务器IP > - (5)「用户」- root #### 第七步:区分环境项目:我的视图 -> 新建视图 -> 我的视图 -> 选择项目 -> sit、prod #### 第八步:使用流水线方式创建项目并写入pipeline script:具体参考: `/docker-jenkins/pipeline` 或 `/docker-jenkins/pipeline-node` #### 其他问题: ###### 解决 Cannot connect to the Docker daemon at unix:///var/run/docker.sock.` - `rm -rf /var/run/docker.sock/` 与 `systemctl restart docker` ###### 解决部署时:`sudo: docker-compose: command not found`,原因:受不同系统印象导致 - 1. pipeline使用决定路径:`sshCommand remote: remote, sudo: true, command: "/usr/local/bin/docker-compose -f ${NFS_PROJECT_DIR}/docker-compose.yaml up -d"` - 2. /etc/profile 目录下添加环境变量 ## 启动方式 ### 命令式快速开始 ```bash docker run -d --name devinhuang-jenkins -p 18080:8080 -p 15001:50000 devinhuang/jenkins:2.426.2-lts-jdk11-slim ``` ### docker-compose方式启动 **1. 创建挂载目录** ```bash sudo sudo mkdir -p /opt/jenkins && chmod 777 -R /opt/jenkins && cd /opt/jenkins # 目录设置为 777 权限,避免权限问题 ``` **2. 创建 docker-compose.yml 文件**【具体参考实际:pipeline-frontend-push-image-to-registry(前端) / pipeline-node-single-push-image-to-registry(后端)】 ```bash version: '3.1' services: jenkins: restart: always privileged: true user: root container_name: jenkins image: devinhuang/jenkins:2.426.2-lts-jdk11-slim healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080"] interval: 6s timeout: 5s retries: 10 volumes: - /root/.ssh:/root/.ssh - /opt/jenkins/:/var/jenkins_home - /opt/jenkins/workspace/:/root/.jenkins/workspace - /var/run/docker.sock:/var/run/docker.sock - /usr/bin/docker:/usr/bin/docker - /usr/bin/buildctl:/usr/local/bin/buildctl - /usr/local/go:/usr/local/go - /usr/lib/x86_64-linux-gnu/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7 - /usr/local/gradle-7.3.3:/usr/local/gradle-7.3.3 - /usr/local/gradle-7.6:/usr/local/gradle-7.6 - /usr/local/jdk11.0.1:/usr/local/jdk11.0.1 - /usr/local/jdk1.8.0_141:/usr/local/jdk1.8.0_141 - /usr/local/node-v16.19.1-linux-x64:/usr/local/node-v16.19.1-linux-x64 - /usr/local/python3:/usr/local/python3 - /usr/local/android-sdk-linux:/usr/local/android-sdk-linux ports: - 18080:8080 - 15001:50000 ``` **说明** ```bash 以下软件均需提前安装好(若不需要则可以去掉) - /usr/bin/buildctl:/usr/local/bin/buildctl - /usr/local/go:/usr/local/go - /usr/lib/x86_64-linux-gnu/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7 - /usr/local/gradle-7.3.3:/usr/local/gradle-7.3.3 - /usr/local/gradle-7.6:/usr/local/gradle-7.6 - /usr/local/jdk11.0.1:/usr/local/jdk11.0.1 - /usr/local/jdk1.8.0_141:/usr/local/jdk1.8.0_141 - /usr/local/node-v16.19.1-linux-x64:/usr/local/node-v16.19.1-linux-x64 - /usr/local/python3:/usr/local/python3 - /usr/local/android-sdk-linux:/usr/local/android-sdk-linux ``` **3. 启动 docker-compose** ```bash docker-compose up -d ``` **4. 访问** ```bash # 默认账号/密码:jenkins/1235678 localhost:18080/manage/pluginManager/installed # 查看pluginInstalled localhost:18080/manage/configureSecurity/ # (因默认开启了游客状态可访问)、需登录下(/login?from=%2F)重新设置安全组 ``` ## K8S #### K8S组件 * Pod 是 Kubernetes 中的基本部署单元,代表一个或多个容器的集合,这些容器共享存储和网络资源。 * Deployment 以声明方式描述所需的应用程序状态,用户定义所需的 Pod 数量、容器镜像、环境变量等。它提供了版本控制、回滚和扩缩容等功能。 * svc(Service) 提供了负载均衡和服务发现的功能,使得 Pod 可以通过固定的 IP 地址和 DNS 名称进行访问。Service 可以将流量分发到后端的多个 Pod 中。 * nc(Namespace) 将资源进行逻辑分组的机制。帮助在同一集群中隔离不同的环境(如开发、测试和生产),并提供资源的访问控制和配额管理。 * HPA(Horizontal Pod Autoscaler) 是一种自动扩缩容的机制,能够根据 CPU 使用率或其他指标动态调整 Pod 的副本数量。它可以根据负载的变化自动增加或减少 Pod 的数量,以确保应用程序的性能和可用性。 * cs(ConfigMap) 是一种用于存储非机密的配置数据的对象。它允许将配置信息分离到 Kubernetes 资源之外,使得应用程序可以在不重新构建容器的情况下读取配置数据。 * ReplicationController 用于确保 Pod 的指定数量在任何时候都在运行的对象。它监控 Pod 的状态,并在 Pod 失败时自动创建新的 Pod 实例。 * Secrets 用于存储敏感信息(如密码、OAuth 令牌和 SSH 密钥)的对象。Secrets 通过将敏感数据存储在 Kubernetes 中而不是直接在 Pod 中定义,提供了安全性和便捷性。 #### K8S封装部署(基于CentOS 7.6版本) **使用文档、安装包:https://github.com/kamalyes/tarzan** **夸克云盘(推荐)[K8S封装程序-离线版](https://pan.quark.cn/s/a50c164bc386?pwd=pWaN) 提取码:pWaN** **百度云盘:[K8S封装程序-离线版](https://pan.baidu.com/s/1y10t0MFzj_tfN6Dy8qIivA),提取码: 4tn5** ##### 在线安装(推荐): ``` # 基于 tarzan-online 包且跟离线版安装配置一样 # 携带参数说明: # 在线安装:--image-pull-policy Always # 网络配置:-addr 10.0.0.3 例子为内网IP,外网参考第二步:外网安装方式 sh install-kube.sh -v v1.23.3 -addr 10.0.0.3 --flannel --image-pull-policy Always --hostname k8s-master ``` ##### 离线安装 ###### 第一步 ``` # Master节点目录 /opt 解压tar.gz 后`cd /opt/tarzan-offline` 执行以下命令 # 基于 tarzan-offline-multiple 包 # 服务器追加HOST配置信息,内网IP bash -c 'cat << EOF >> /etc/hosts 10.0.0.3 k8s-master 10.0.0.8 k8s-node1 10.0.0.9 k8s-node2 EOF' ``` ###### 第二步 ``` ########## 内网安装方式 ########## # Master节点执行,10.0.0.3为内网IP sh install-kube.sh -v v1.23.3 -addr 10.0.0.3 --flannel --hostname k8s-master # 安装完Master之后会得到一个join指令【Kubeadm join command】 # 查看【Kubeadm join command】指令:kubeadm token create --print-join-command --ttl=0 # 将Slave节点加入到 Kubernetes 集群 # 命令说明: 10.0.0.3:6443 【10.0.0.3 是 Master 节点的 IP 地址,6443 是 Kubernetes API 服务器的默认端口】 --token 【这是用于身份验证的令牌】 --discovery-token-ca-cert-hash【这是用于验证集群的 CA 证书的哈希值】 kubeadm join 10.0.0.3:6443 --token 0dy3rl.33bugu3rax35r815 --discovery-token-ca-cert-hash sha256:0c7e8afb55c242c351bfb744cc4e64cf7221033f3dd7f4aaa995602cb6af3b9d ########## 外网安装方式 ########## # 假设Master节点对应的外网为115.132.233.15 则需追加参数: --virtualip 115.132.233.15,且追加HOST中将Master的内网IP改外网IP sh install-kube.sh -v v1.23.3 -addr 115.132.233.15 --virtualip 115.132.233.15 --flannel --hostname k8s-master ``` ###### 第三步 ``` # Slave节点执行,必须Slave的/etc/hosts中也添加跟Master的hosts配置一样的IP与hostname,使两者相互通信 # 如果是重装先执行删旧Slave节点:kubectl dekete node ${节点名} # 如果是外网则需先创建网卡 ##### 第一种方式:在目录/opt/tarzan-online 执行: sh common.sh add_virtual_ip ${node-node-ip} eth0:1,而${node-node-ip}表示外网IP,然后安装Node: sh install-kube.sh --hostname k8s-node1 && ${Kubeadm join command} sh install-kube.sh --hostname k8s-node2 && ${Kubeadm join command} ##### 第二种方式:安装时追加参数: -addr ${node-addr-ip} --create-virtualeth,而${node-addr-ip}表示外网IP,即: sh install-kube.sh --hostname k8s-node1 -addr 114.132.233.15 --create-virtualeth && ${Kubeadm join command} ``` ## 实际案例: * container常规用法是多个相同的容器放在一个pod内,不是pod内多个不同的容器 * 背景:pod中有4个container,而90%请求都打到container_1,其余10%打到另外3个container; * 分析:外部原因:CDN就近原则刚好90%请求就在 container_1 所在地区,内部原因:(1)svc设了权重打到container_1、(2)ingress-nginx 灰度部署导致都到container_1 ## k3s 安装与使用(建议K8S) * 基于 k3s version v1.29.5+k3s1 (4e53a323)、go version go1.21.9 * Server节点指的是运行 k3s server 命令的主机,control plane 和数据存储组件由 K3s 管理。 * Agent节点指的是运行 k3s agent 命令的主机,不具有任何数据存储或 control plane 组件。 * [K3S基础概念与讲解](https://kubernetes.io/zh-cn/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/) #### 1. 下载K3S并设置国内镜像源(默认也把 `kubectl` 插件下载) ``` // INSTALL_K3S_EXEC="--disable traefik" 禁用内置的traefik,默认会占用80/443端口 curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | K3S_NODE_NAME=master INSTALL_K3S_EXEC="--disable traefik" INSTALL_K3S_MIRROR=cn sh -s - --system-default-registry=registry.cn-hangzhou.aliyuncs.com ``` #### 2. 查看Server与Agent 数量与状态 * 节点查询:`kubectl get nodes -o wide` * 安装成功:`k3s --version ` #### 3. kube-flannel集群网络插件(管理集群节点之间的容器网络通信、暴露端口供外部访问)- Server节点配置 * 模版内镜像已替换为自己腾讯云镜像仓库 * 模版:[kube-flannel.yaml](https://pan.baidu.com/s/1y10t0MFzj_tfN6Dy8qIivA),提取码: 4tn5 * /opt目录执行:`kubectl apply -f /opt/k3s/kube-flannel.yaml` * 验证: * `kubectl get svc -A` 获取所以命名空间下的服务信息 * `curl :` liunx输入IP与端口查看是否成功 * 外部访问 `curl <服务器ID地址>:<代理端口:五位数>`(在Service中配置类型为:nodePort才有效) - **注意:无法连接时设置 kube-flannel.yml 中 net-conf.json 的Network是否与 `ifconfig` 查看IP地址 打印的flannel一致** - kube-flannel 无法访问外网时重新安装K3S并把对应文件删除,而且优于 **Ingress-nginx创建** 与 **添加Agent节点** #### 4. Ingress-nginx安装(替换内置traefik) - Server节点配置 * 模版内镜像已替换为自己腾讯云镜像仓库 * 模版:[Ingress-nginx.yaml](https://pan.baidu.com/s/1y10t0MFzj_tfN6Dy8qIivA),提取码: 4tn5 * /opt目录执行: * `kubectl create namespace ingress-nginx` // 命名空间固定ingress-nginx就行,不需要与deployment、Server一个命名空间 * `kubectl apply -f /opt/k3s/ingress-nginx.yaml` * 验证: * `kubectl get pods -o wide -n ingress-nginx` // ingress-nginx-controller的pod在正常运行 * `kubectl get svc -A` // 查看 ingress-nginx 网络服务 * `curl :<80>` (在Service中配置类型为:nodePort才有效)查看是否成功 * 不占用外网的80/443端口,使用其他端口代理到K3S的80/443端口 (查看代理端口:` kubectl get svc -n ingress-nginx`) * [详细流程参考文章](https://blog.csdn.net/justlpf/article/details/132227856) #### 5. Ingress-nginx 配置SSL证书并创建代理 - Server节点配置 * 下载SSL证书,执行:`kubectl create secret tls dev-k3s-secret --cert= --key= -n tfw-prod` * 验证证书:`kubectl get secrets -n tfw-prod` * 模版:[ingress-ssl.yaml](https://pan.baidu.com/s/1y10t0MFzj_tfN6Dy8qIivA),提取码: 4tn5 * /opt目录执行:`kubectl apply -f /opt/k3s/ingress-ssl.yaml` * 验证:`kubectl get ingress -n tfw-prod` #### 6. 负载均衡(kube-descheduler) - Server、Agent节点配置 * kube-descheduler.zip内镜像已替换为自己腾讯云镜像仓库 * 模版:[kube-descheduler.zip](https://pan.baidu.com/s/1y10t0MFzj_tfN6Dy8qIivA),提取码: 4tn5 * kube-descheduler.zip 导入liunx并解压到在 /opt/k3s/kube-descheduler * /opt/k3s/kube-descheduler目录执行:`kubectl apply -f ./` * 校验:`kubectl get pod -A` // descheduler 是否运行中 #### 7. 资源使用情况数据(Metrics Server) - Server节点配置 * 模版内镜像已替换为自己腾讯云镜像仓库 * 模版:[components.yaml](https://pan.baidu.com/s/1y10t0MFzj_tfN6Dy8qIivA),提取码: 4tn5 * /opt目录执行:`kubectl apply -f /opt/k3s/components.yaml` * [参考博客](https://www.cnblogs.com/mjxi/p/17309067.html) * 节点指标:`kubectl top nodes` 显示节点 CPU 使用率、内存使用率 * pods指标:`kubectl top pods` 显示pods CPU 使用率、内存使用率 #### 8. 添加Agent节点 * Master节点获取token `sudo cat /var/lib/rancher/k3s/server/node-token` * Agent节点执行 ``` curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh -o k3s-install.sh K3S_NODE_NAME=node INSTALL_K3S_MIRROR=cn K3S_URL=https://:6443 K3S_TOKEN= sh k3s-install.sh ``` #### 9. 添加污点(Taints) * 防止pod创建在Server节点上,因为Server主要任务是管理Node,执行下列命令: ``` // 注意:某 Pod 要在Serve节点创建,需要 deployment.yaml 文件 tolerations 匹配 设置值,参考 deployment.yaml 注释部分 // :Serve节点名称 // :mainNode // :true kubectl taint nodes =:NoSchedule ``` #### 10. Server节点创建或更新K3S实例对象(Kubernetes 会自动根据调度算法将 Pod 分配到可用的节点上) * 模版内镜像已替换为自己腾讯云镜像仓库 * 模版:[deployment.yaml](https://pan.baidu.com/s/1y10t0MFzj_tfN6Dy8qIivA),提取码: 4tn5 * /opt目录执行:`kubectl apply -f /opt/k3s/deployment.yaml` * 验证:`kubectl get pod -n tfw-prod` #### 常用指令 查看网络信息:` kubectl get svc -A` 查看pod状态:`kubectl get pods -o wide` 查看具体pod详情:`kubectl describe pod ` 查看50条最新具体类型日志:`kubectl logs -f --tail 50 -n ` 更新命名空间为tfw-prod的deployment中容器镜像:`kubectl set image deployment/ =new-image:version -n ` 更新命名空间为tfw-prod的pod中容器镜像:`kubectl set image pod/my-pod my-container=new-image:version -n `