生活札记
Docker+K8S+Devops零基础入门教程之Devops
DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。
它是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
window系统下go的跨平台编译: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main main.go
教程:https://www.bilibili.com/video/BV1Pt4y1H7Zq
文档: https://pan.baidu.com/s/1LzpsBDVzVK5fZZqMv-0C6Q?pwd=dgu6 提取码: dgu6
安装虚拟机:https://blog.csdn.net/zhiboqingyun/article/details/126555260
虚拟机网卡设置:https://blog.csdn.net/weixin_45193791/article/details/124646170
配置IP地址网关
vi /etc/sysconfig/network-scripts/ifcfg-ens33 //进入到network-scripts目录下
//修改以下内容
BOOTPROTO=static //启用静态IP地址
ONBOOT=yes //开启自动启用网络连接
//添加vmnet8的子网掩码和网关,ip要保证在192.168.126.x,还要保证唯一性
IPADDR=192.168.40.100 //设置IP地址
NETMASK=255.255.255.0 //子网掩码
GATEWAY=192.168.40.2 //设置网关
设置DNS地址
vi /etc/resolv.conf //编辑 resolv.conf文件
nameserver 114.114.114.114 //添加DNS地址
nameserver 8.8.8.8 //添加DNS地址
重启网卡
systemctl restart network
查看IP是否正常
ip addr
ping www.copylian.com
docker安装:https://www.copylian.com/life/503.html
注意:安装docker之后需要关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
一、概念:
DevOps,字面意思是Development &Operations的缩写,也就是开发&运维。
整体的软件开发流程包括:
PLAN:开发团队根据客户的目标制定开发计划
CODE:根据PLAN开始编码过程,需要将不同版本的代码存储在一个库中。
BUILD:编码完成后,需要将代码构建并且运行。
TEST:成功构建项目后,需要测试代码是否存在BUG或错误。
DEPLOY:代码经过手动测试和自动化测试后,认定代码已经准备好部署并且交给运维团队。
OPERATE:运维团队将代码部署到生产环境中。
MONITOR:项目部署上线后,需要持续的监控产品。
INTEGRATE:然后将监控阶段收到的反馈发送回PLAN阶段,整体反复的流程就是DevOps的核心,即持续集成、持续部署。
CI/CD可以理解为:
CI过程即是通过Jenkins将代码拉取、构建、制作镜像交给测试人员测试。
持续集成:让软件代码可以持续的集成到主干上,并自动构建和测试。
CD过程即是通过Jenkins将打好标签的发行版本代码拉取、构建、制作镜像交给运维人员部署。
持续交付:让经过持续集成的代码可以进行手动部署。
持续部署:让可以持续交付的代码随时随地的自动化部署。
二、Gitlab:GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务。为了本地测试需要在本地安装下Gitlab仓库。否则可以直接用线上的Gitee
# 拉去仓库镜像,使用docker-compose启动gitlab
docker pull gitlab/gitlab-ce:latest
mkdir /usr/local/docker/gitlab
cd /usr/local/docker/gitlab
vim docker-compose.yml
version: '3.1'
services:
gitlab:
image: 'gitlab/gitlab-ce:latest'
container_name: gitlab
restart: always
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://192.168.40.101:8929'
gitlab_rails['gitlab_shell_ssh_port'] = 2224
ports:
- '8929:8929'
- '2224:2224'
volumes:
- './config:/etc/gitlab'
- './logs:/var/log/gitlab'
- './data:/var/opt/gitlab'
# 启动容器
docker-compose up -d
# 查看初始密码:
cat /usr/local/docker/gitlab/config/initial_root_password
# 浏览器访问gitlab,默认账号是root
# 修改gitlab密码:
# 配置允许推送到本地的webhook:admin >> Network
三、Jenkins:https://www.jenkins.io/
Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,Jenkins应用广泛,大多数互联网公司都采用Jenkins配合GitLab、Docker、K8s作为实现DevOps的核心工具。Jenkins最强大的就在于插件,Jenkins官方提供了大量的插件库,来自动化CI/CD过程中的各种琐碎功能。Jenkins最主要的工作就是将GitLab上可以构建的工程代码拉取并且进行构建,再根据流程可以选择发布到测试环境或是生产环境。一般是GitLab上的代码经过大量的测试后,确定发行版本,再发布到生产环境。
1)、安装:使用docker安装,Jenkins目录在 /usr/local/docker/jenkins
拉去docker镜像:
docker pull jenkins/jenkins:2.375.3-lts 或者 docker pull jenkins/jenkins
2)、启动docker-compose:docker-compose up -d
docker-compose.yml:
version: "3.1"
services:
jenkins:
image: jenkins/jenkins
container_name: jenkins
restart: always
ports:
- 8080:8080
- 50000:50000
volumes:
- ./data/:/var/jenkins_home/
data作为数据目录映射数据目,需要设置 data 的可写权限:chmod -R 777 data/
3)、修改Jenkins的镜像,默认国外的下载太慢,配置完成后重启:docker-compose restart jenkins
cat data/hudson.model.UpdateCenter.xml
<?xml version='1.1' encoding='UTF-8'?>
<sites>
<site>
<id>default</id>
<url>https://updates.jenkins.io/update-center.json</url>
</site>
</sites>
# 将下载地址替换为http://mirror.esuni.jp/jenkins/updates/update-center.json
<?xml version='1.1' encoding='UTF-8'?>
<sites>
<site>
<id>default</id>
<url>http://mirror.esuni.jp/jenkins/updates/update-center.json</url>
</site>
</sites>
# 清华大学的插件源也可以:https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
4)、登录Jenkins:http://192.168.40.101:8080/ 安装插件,相对比较慢要等会。。。
查看密码:
docker logs jenkins -f
docker exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword
cat data/secrets/initialAdminPassword
5)、需要准备的插件或配置:
maven:可通过Jenkins的全局配置安装,也可以自定义下载安装:https://maven.apache.org/download.cgi,下载 apache-maven-4.0.0-alpha-4-bin.tar.gz,解压到Jenkins的jenkins_home下,命名为maven,maven主要是用于java代码打包,如果是其他代码则不需要用到
jdk8:可通过Jenkins的全局配置安装,也可以自定义下载安装:https://www.oracle.com/java/technologies/downloads/#java8,下载 jdk-8u361-linux-x64.tar.gz,解压到Jenkins的jenkins_home下,命名为jdk
配置maven镜像、jdk插件,参考:https://blog.csdn.net/m0_67402731/article/details/126435240
vim ./data/maven/conf/setting.xml
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
<profiles>
<profile>
<id>jdk8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>jdk8</activeProfile>
</activeProfiles>
在Jenkins的全局配置里配置:
Git Parameter:git拉去git仓库上的代码,配置参数
Publish Over SSH:ssh登录服务器
四、SonarQube Scanner:代码检测
Sonar Qube在7.9版本中已经放弃了对MySQL的支持,并且建议在商业环境中采用PostgreSQL,那么安装Sonar Qube时需要依赖PostgreSQL。Sonar Qube的使用方式很多,Maven可以整合,也可以采用sonar-scanner的方式,再查看Sonar Qube的检测效果,官网:https://www.sonarsource.com/
Maven方式:修改Maven的settings.xml文件配置Sonar Qube信息
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.login>admin</sonar.login>
<sonar.password>123456789</sonar.password>
<sonar.host.url>http://192.168.11.11:9000</sonar.host.url>
</properties>
</profile>
在代码位置执行命令:mvn sonar:sonar
1)、拉取镜像:https://www.sonarsource.com/products/sonarqube/deployment/
docker pull postgres # PostgreSQL镜像
docker pull sonarqube:9.9.0-community
2)、docker-compose.yml启动容器:docker-compose up -d
mkdir /usr/local/docker/sonarqube # docker-compose.yml 文件位置
version: '3.1'
services:
db:
image: postgres
container_name: db
restart: always
ports:
- 5432:5432
networks:
- sonarnet
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
sonarqube:
image: sonarqube:lts-community
container_name: sonarqube
restart: always
depends_on:
- db
ports:
- 9000:9000
networks:
- sonarnet
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
networks:
sonarnet:
driver: bridge
如果报内存不足则需要改配置:vim /etc/sysctl.conf,写入:vm.max_map_count = 262144,sysctl -p查看
3)、访问:http://192.168.40.101:9000/,默认账号、密码:admin、admin,安装中文插件、生成token并重启
4)、Jenkins安装SonarQube Scanner for Jenkins插件、系统配置SonarQube服务、下载SonarScanner配置到Jenkins目录、全局配置SonarScanner
SonarScanner下载:https://docs.sonarqube.org/latest/analyzing-source-code/scanners/sonarscanner/
cd /usr/local/docker/jenkins/data/ # 切到Jenkins目录
unzip sonar-scanner-cli-4.8.0.2856-linux.zip # 解压
mv sonar-scanner-cli-4.8.0.2856-linux/ sonar-scanner # 重命名
rm -rf sonar-scanner-cli-4.8.0.2856-linux.zip # 删除源文件
测试sonarqube scanner:
cd /usr/local/devops # 切到代码目录
/usr/local/docker/jenkins/data/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.login=sqa_26b6a9a4f4d860b9b4933da870fa4256c8c2f63d -Dsonar.projectKey=test # 测试
系统配置SonarQube服务:
全局配置SonarScanner:
代码重新构建之后:
五、Harbor:镜像仓库
Harbor是一个开源注册中心,它通过策略和基于角色的访问控制来保护工件,确保图像被扫描并没有漏洞,并将图像签名为可信的。Harbor是一个CNCF Graded项目,它提供了合规性、性能和互操作性,帮助您在Kubernetes和Docker等云原生计算平台上一致、安全地管理工件,官网:https://goharbor.io/
下载:wget https://github.com/goharbor/harbor/releases/download/v2.5.6/harbor-offline-installer-v2.5.6.tgz
解压:tar -zvxf harbor-offline-installer-v2.5.6.tgz -C /usr/local
编辑配置:
cd /usr/local/harbor/
mv harbor.yml.tmpl harbor.yml # 重命名
vim harbor.yml # 配置hostname、http的端口、如果没有https则关闭https配置、默认密码:harbor_admin_password
安装:./install.sh
配置docker的安全镜像:vim /etc/docker/daemon.json
"insecure-registries":["192.168.40.101:80"]
重启docker:systemctl restart docker
访问:http://192.168.40.101:80,账号密码:admin、Harbor12345,这个仓库一定要是公开的(访问等级是公开的),否则后续k8s或者其他服务器无法拉取镜像
镜像打标签,并推送到Harbor镜像仓库:
docker tag d44ef6af962c 192.168.40.101:80/test/devops:v1.0.0 # test是新建的仓库名称需要登录先创建
docker login -u admin -p Harbor123456 192.168.40.101:80
docker push 192.168.40.101:80/test/devops:v1.0.0
配置Jenkins调用外部的docker:
cd /var/run
chown root:root docker.sock # 更改docker.sock的用户组
chmod -R 777 docker.sock # 更改权限
vim /usr/local/docker/jenkins/docker-compose.yml # 编辑jenkins的docker-compose配置
version: "3.1"
services:
jenkins:
image: jenkins/jenkins
container_name: jenkins
restart: always
ports:
- 8080:8080
- 50000:50000
volumes:
- ./data/:/var/jenkins_home/
- /usr/bin/docker:/usr/bin/docker
- /var/run/docker.sock:/var/run/docker.sock
- /etc/docker/daemon.json:/etc/docker/daemon.json
进入Jenkins容器内部:docker exec -it jenkins --bash,执行:docker version,能输出docker版本信息则表示Jenkins内部可调用docker
配置Jenkins项目构建时运行docker build、docker push操作:
docker build -t devops:$tag .
docker tag devops:$tag 192.168.40.101:80/test/devops:$tag
docker login -u admin -p Harbor12345 192.168.40.101:80
docker push 192.168.40.101:80/test/devops:$tag
通过shell脚本直接构建镜像、push镜像、拉取镜像、启动容器:docker exec -it jenkins --bash
chmod -R 777 go-build.sh # 给可执行权限
./go-build.sh 192.168.40.101:80 ${JOB_NAME} devops $tag # 执行二级制脚本名,带参数
go-build.sh:
# 构建docker镜像、启动镜像
# 镜像仓库地址
repository=$1
# 镜像仓库项目名称
repositoryProjectName=$2
# 项目名称
projectName=$3
# tag名称
tagName=$4
# 镜像仓库名称
imageName=$repository/$repositoryProjectName/$projectName
echo $imageName
# 镜像仓库全称
imageTagName=$imageName:$tagName
echo $imageTagName
# 构建镜像
docker build -t $imageTagName .
# 登录仓库
docker login -u admin -p Harbor123456 $repository
# 推送仓库
docker push $imageTagName
# 查询容器是否在运行,如果存在容器则停止、删除容器
containerId=`docker ps -a | grep ${imageName} | awk '{print $1}'`
echo $containerId
if [ "$containerId" != "" ]; then
docker stop $containerId
docker rm $containerId
echo "删除容器成功"
fi
# 查询镜像是否存在,如果存在则删除镜像
imageId=`docker images | grep ${imageName} | awk '{print $3}'`
echo $imageId
if [ "$imageId" != "" ]; then
docker rmi -f $imageId
echo "删除镜像成功"
fi
# 拉取镜像
docker pull $imageTagName
# 启动容器
docker run -d --restart=always -p 8081:8081 --name $projectName $imageTagName
echo "启动容器成功"
echo $projectName
六、Jenkins流水线:pipeline
Jenkins的Pipeline可以让项目的发布整体流程可视化,明确执行的阶段,可以快速的定位问题。并且整个项目的生命周期可以通过一个Jenkinsfile文件管理,而且Jenkinsfile文件是可以放在项目中维护
Jenkinsfile语法:
// 所有脚本命令包含在pipeline{}中
pipeline {
// 指定任务在哪个节点执行(Jenkins支持分布式)
agent any
// 配置全局环境,指定变量名=变量值信息
environment {
host = "192.168.40.101"
}
// 存放所有任务的合集
stages {
// 单个任务1
stage ("任务1") {
// 实现任务的具体流程
steps {
echo "任务1"
}
}
// 单个任务2
stage ("任务2") {
// 实现任务的具体流程
steps {
echo "任务2"
}
}
}
}
新建Jenkinsfile的流水线任务:
配置流水线、配置tag:
项目目录创建Jenkinsfile:Jenkinsfile的流水线语法、Jenkinsfile文件、全局配置参数
// 所有脚本命令包含在pipeline{}中
pipeline {
// 指定任务在哪个节点执行(Jenkins支持分布式)
agent any
// 配置全局环境,指定变量名=变量值信息
environment {
// 镜像仓库地址
repository= "192.168.40.101:80"
// 仓库账号
repositoryUser = "admin"
// 仓库密码
repositoryPwd = "Harbor12345"
// 项目名称
projectName = "devops"
// 钉钉ID
dingRobotId = "Jenkins-Test"
}
// 存放所有任务的合集
stages {
// git版本库拉取代码
stage ("git版本库拉取代码") {
// 实现任务的具体流程
steps {
checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[credentialsId: '5a63a5bc-123e-4dde-aa30-48bbb6e9d2a6', url: 'https://gitee.com/copylian/devops.git']])
}
}
// sornar代码检测
stage ("代码检测") {
// 实现任务的具体流程
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.sources=./ -Dsonar.login=sqa_26b6a9a4f4d860b9b4933da870fa4256c8c2f63d'
}
}
// 制作自定义镜像
stage ("制作Docker自定义镜像") {
// 实现任务的具体流程
steps {
sh 'docker build -t ${repository}/${JOB_NAME}/${projectName}:${tag} .'
}
}
// 推送Docker自定义镜像到Harbor仓库
stage ("推送Docker自定义镜像到Harbor仓库") {
// 实现任务的具体流程
steps {
sh 'docker login -u ${repositoryUser} -p ${repositoryPwd} ${repository}'
sh 'docker push ${repository}/${JOB_NAME}/${projectName}:${tag}'
}
}
// 通过Publish Over SSH通知目标服务器拉取镜像,go-build.sh 拉取
stage ("通过sh拉取镜像") {
// 实现任务的具体流程
steps {
sh 'chmod -R 777 go-build.sh'
sh './go-build.sh ${repository} ${JOB_NAME} ${projectName} ${tag}'
}
}
}
// 钉钉消息推送
post {
success {
dingtalk(
robot: "${dingRobotId}",
type: "MARKDOWN",
title: "success:${JOB_NAME}",
text: ["- 成功构建:${JOB_NAME}!\n- 版本:${tag}\n 持续时间:${currentBuild.durationString}"]
)
}
failure {
dingtalk(
robot: "${dingRobotId}",
type: "MARKDOWN",
title: "success:${JOB_NAME}",
text: ["- 成功失败:${JOB_NAME}!\n- 版本:${tag}\n 持续时间:${currentBuild.durationString}"]
)
}
}
配置钉钉通知:下载DingTalk插件、新建钉钉群聊自定义机器人并全局配置钉钉插件webhook信息、项目选中钉钉、Jenkinsfile的钉钉通知代码、构建通知
Jenkinsfile的钉钉配置:
// 钉钉消息推送
post {
success {
dingtalk(
robot: "${dingRobotId}",
type: "MARKDOWN",
atAll: true,
title: "${JOB_NAME}构建成功",
text: [
"# ${JOB_NAME} ${tag}环境 - 发布成功",
"---",
"### 构建信息",
"",
"- 分支: ${tag}",
"- 提交: ${env.GIT_COMMIT.take(7)}",
"- 时间:${currentBuild.durationString}",
"- 日志:[查看详情](${env.BUILD_URL})",
"---",
"### 更新记录",
"",
"- 1: ${currentBuild.changeSets}",
"- 2: ${currentBuild.description}",
]
)
}
failure {
dingtalk(
robot: "${dingRobotId}",
type: "MARKDOWN",
atAll: true,
title: "${JOB_NAME}构建失败",
text: [
"# ${JOB_NAME} ${tag}环境 - 发布失败",
"---",
"### 构建信息",
"",
"- 分支: ${tag}",
"- 提交: ${env.GIT_COMMIT.take(7)}",
"- 时间:${currentBuild.durationString}",
"- 日志:[查看详情](${env.BUILD_URL})",
]
)
}
}
也可配置全局自定义流水线仓库(Global Pipeline Libraries),参考钉钉api
七、Kubernetes:也称为 K8s,是用于自动部署、扩缩和管理容器化应用程序的开源系统。它将组成应用程序的容器组合成逻辑单元,以便于管理和服务发现。Kubernetes 源自Google 15 年生产环境的运维经验,同时凝聚了社区的最佳创意和实践。官网:https://kubernetes.io/zh-cn/
具体教程参考:https://www.copylian.com/life/504.html
Kubernetes主要能帮助我们完成:
- 服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
- 存储编排
Kubernetes 允许你自动挂载你选择的存储系统,比如本地存储,类似Docker的数据卷。
- 自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。Kubernetes 会自动帮你根据情况部署创建新容器,并删除现有容器给新容器提供资源。
- 自动完成装箱计算
Kubernetes 允许你设置每个容器的资源,比如CPU和内存。
- 自我修复
Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的容器,并运行状况检查的容器。
- 秘钥与配置管理
Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
Kuboard - Kubernetes 多集群管理界面:https://kuboard.cn/
安装Kuboard:https://www.kuboard.cn/install/v3/install-in-k8s.html
kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml
1)、Namespace:命名空间:主要是为了对Kubernetes中运行的资源进行过隔离, 但是网络是互通的,类似Docker的容器,可以将多个资源配置到一个NameSpace中。而NameSpace可以对不同环境进行资源隔离,默认情况下Kubernetes提供了default命名空间,在构建资源时,如果不指定资源,默认采用default资源。
# 查看现有的全部命名空间
kubectl get ns
# 构建命名空间
kubectl create ns 命名空间名称
# 删除现有命名空间, 并且会删除空间下的全部资源
kubectl delete ns 命名空间名称
yaml文件方式:(构建资源时,设置命名空间)
apiVersion: v1
kind: Namespace
metadata:
name: test
2)、Pod:Kubernetes运行的一组容器,Pod是Kubernetes的最小单位,但是对于Docker而然,Pod中会运行多个Docker容器
# 查看所有运行的pod
kubectl get pods -A
# 查看指定Namespace下的Pod
kubectl get pod [-n 命名空间] #(默认default)
# 创建Pod
kubectl run pod名称 --image=镜像名称
# 查看Pod详细信息
kubectl describe pod pod名称
# 删除pod
kubectl delete pod pod名称 [-n 命名空间] #(默认default)
# 查看pod输出的日志
kubectl logs -f pod名称
# 进去pod容器内部
kubectl exec -it pod名称 -- bash
# 查看kubernetes给Pod分配的ip信息,并且通过ip和容器的端口,可以直接访问
kubectl get pod -owide
yaml方式(推荐)
apiVersion: v1
kind: Pod
metadata:
labels:
run: 运行的pod名称
name: pod名称
namespace: 命名空间
spec:
containers:
- image: 镜像名称
name: 容器名称
# 启动Pod:kubectl apply -f yaml文件名称
# 删除Pod:kubectl delete -f yaml文件名称
Pod中运行多个容器:
apiVersion: v1
kind: Pod
metadata:
labels:
run: 运行的pod名称
name: pod名称
namespace: 命名空间
spec:
containers:
- image: 镜像名称
name: 容器名称
- image: 镜像名称
name: 容器名称
3)、Deployment:部署时,可以通过Deployment管理和编排Pod
# 基于Deployment启动容器
kubectl create deployment deployment名称 --image=镜像名称
# 用deployment启动的容器会在被删除后自动再次创建,达到故障漂移的效果
# 需要使用deploy的方式删除deploy
# 查看现在的deployment
kubectl get deployment
# 删除deployment
kubectl delete deployment deployment名称
# 基于Deployment启动容器并设置Pod集群数
kubectl create deployment deployment名称 --image=镜像名称 --replicas 集群个数
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
正常使用kubectl运行yaml即可
# 基于scale实现弹性伸缩
kubectl scale deploy/Deployment名称 --replicas 集群个数
# 或者修改yaml文件
kubectl edit deploy Deployment名称
#灰度发布
#Deploy可以在部署新版本数据时,成功启动一个pod,才会下线一个老版本的Pod
kubectl set image deployment/Deployment名称 容器名=镜像:版本
4)、Service:可以将多个Pod对外暴露一个Service,让客户端可以通过Service访问到这一组Pod,并且可以实现负载均衡
ClusterIP方式:ClusterIP是集群内部Pod之间的访问方式
# 通过生成service映射一个Deployment下的所有pod中的某一个端口的容器
kubectl expose deployment Deployment名称 --port=Service端口号 --target-port=Pod内容器端口,通过`kubectl get service`查看Service提供的ip,即可访问
NodePort方式:ClusterIP的方式只能在Pod内部实现访问,但是一般需要对外暴露网关,所以需要NodePort的方式Pod外暴露访问
# 通过生成service映射一个Deployment下的所有pod中的某一个端口的容器
kubectl expose deployment Deployment名称 --port=Service端口号 --target-port=Pod内容器端口 --type=NodePort
kubectl expose deployment nginx-deployment --port=8888 --target-port=80 --type=NodePort -n test
容器内部可通过服务名称访问:curl tomcat-deployment:8088
Service也可以通过yaml文件实现:
apiVersion: v1
kind: Service
metadata:
labels
app: nginx
name: nginx
spec:
selector:
app: nginx
ports:
- port: 8888
protocol: TCP
targetPort: 80
通过apply启动就也可以创建Service
测试效果-Deployment部署,通过Service暴露
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-service
name: nginx-service
spec:
selector:
app: nginx-deployment
ports:
- port: 8888
protocol: TCP
targetPort: 80
type: NodePort
5)、Ingress:Kubernetes推荐将Ingress作为所有Service的入口,提供统一的入口,避免多个服务之间需要记录大量的IP或者域名,毕竟IP可能改变,服务太多域名记录不方便。Ingress底层其实就是一个Nginx, 可以在Kuboard上直接点击安装,因为副本数默认为1,但是k8s整体集群就2个节点,所以显示下面即为安装成功,可以将Ingress接收到的请求转发到不同的Service中。
推荐使用yaml文件方式
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
ingressClassName: ingress # 这个ingress需要安装
rules:
- host: te.abc.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 8888
配置本地hosts文件:1270.0.01test.abc.com
八、Jenkins集成Kubernetes:镜像构建成功之后推送到仓库之后,将k8s的yaml部署文件推送到k8s主机,远程执行k8s的配置文件(包括重新加载rollout)
1)、k8s的master节点、node节点需要docker拉去私服镜像的权限
k8s所有节点都得配置:
vim /etc/docker/daemon.json
添加私服仓库:这个仓库一定要是公开的(访问等级是公开的),否则一直报没有拉取镜像的权限,重要事情说一遍
"insecure-registries":["192.168.40.101:80"]
重启docker
systemctl daemon-reload
systemctl restart docker
测试拉取镜像:docker pull 192.168.40.101:80/test2/devops:v3.0.0
2)、配置Jenkins(容器内部)登录k8s主机,通过Publish over SSH传输对应的yaml文件
Jinkens主机:
docker exec -it jenkins bash
cd ~/.ssh # 如果没有.ssh则直接生成,参考:https://blog.csdn.net/qq_55624813/article/details/121385737
cat id_rsa.pub # 复制id_rsa.pub内容到k8s主机
k8s主机:
将内容写入k8s主机文件中:
vim ~/.ssh/authorized_keys
直接在Jenkins内部测试:ssh root@192.168.40.201
Jenkins系统配置中配置Publish over SSH:生成Jenkinsfile语法将文件传输过去
远程目录 /usr/local/k8s 需要先创建,否则会报权限问题。
配置Jenkinsfile文件:
// 通过Publish Over SSH将部k8smaster.yaml署到k8smaster机器
stage ("将部k8smaster.yaml署到k8smaster机器") {
// 实现任务的具体流程
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'k8smaster', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'k8smaster.yaml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
3)、远程执行yaml文件:重启k8s应用、部署应用
配置Jenkinsfile文件:
// 远程执行k8smaster.yaml文件
stage ("远程执行k8smaster.yaml文件") {
// 实现任务的具体流程
steps {
sh '''ssh root@192.168.40.201 kubectl apply -f /usr/local/k8s/k8smaster.yaml
ssh root@192.168.40.201 kubectl rollout restart deployment devops -n test'''
}
}
4)、为了本地测试开启gitlab的本地webhook,并配置webhook来实现推送就触发Jenkins流水进程
下载gitlab插件:
项目配置gitlab流水线信息:
配置gitlab的webhook:
项目构建:
访问项目:http://192.168.40.201:32270/test,环境问题无法配置ingress,所以暂时只能通过ip+端口访问,如果加了ingress方式那可以配置本机hosts文件来直接访问
九、Kuboard - Kubernetes 多集群管理界面:https://www.kuboard.cn/
安装:https://www.kuboard.cn/install/v3/install-in-k8s.html
选择华为云的镜像安装,推荐的镜像很慢,可能会一直安装不上,安装完成之后按照文档操作登录即可。
十、pipeline整体关键性文件:包含Dockerfile构建镜像文件、go-build.sh 脚本文件、Jenkinsfile 流水线文件、k8s的yaml配置文件
Dockfile:容器内部
FROM alpine:latest
WORKDIR /usr/local/devops
COPY ./main /usr/local/devops/main
RUN chmod -R 777 /usr/local/devops/main
EXPOSE 8081
CMD [ "./main" ]
go-build.sh:./go-build.sh 192.168.40.101 test devops latest
# 构建docker镜像、启动镜像
# 镜像仓库地址
repository=$1
# 镜像仓库项目名称
repositoryProjectName=$2
# 项目名称
projectName=$3
# tag名称
tagName=$4
# 镜像仓库名称
imageName=$repository/$repositoryProjectName/$projectName
echo $imageName
# 镜像仓库全称
imageTagName=$imageName:$tagName
echo $imageTagName
# 查询容器是否在运行,如果存在容器则停止、删除容器
containerId=`docker ps -a | grep ${imageName} | awk '{print $1}'`
echo $containerId
if [ "$containerId" != "" ]; then
docker stop $containerId
docker rm $containerId
echo "删除容器成功"
fi
# 查询镜像是否存在,如果存在则删除镜像
imageId=`docker images | grep ${imageName} | awk '{print $3}'`
echo $imageId
if [ "$imageId" != "" ]; then
docker rmi -f $imageId
echo "删除镜像成功"
fi
Jenkinsfile:用于pipeline
// 所有脚本命令包含在pipeline{}中
pipeline {
// 指定任务在哪个节点执行(Jenkins支持分布式)
agent any
// 配置全局环境,指定变量名=变量值信息
environment {
// 镜像仓库地址
repository= "192.168.40.101:80"
// 仓库账号
repositoryUser = "admin"
// 仓库密码
repositoryPwd = "Harbor12345"
// 项目名称
projectName = "devops"
// 钉钉ID
dingRobotId = "Jenkins-Test"
}
// 存放所有任务的合集
stages {
// git版本库拉取代码
stage ("git版本库拉取代码") {
// 实现任务的具体流程
steps {
checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'b8c8ed01-15d8-4bfd-afd2-8dddfd0623bb', url: 'http://192.168.40.101:8929/test/devops3.git']])
}
}
// 代码检测
stage ("代码检测") {
// 实现任务的具体流程
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.sources=./ -Dsonar.login=sqa_26b6a9a4f4d860b9b4933da870fa4256c8c2f63d'
}
}
// 删除不用的镜像
stage ("删除不用的镜像") {
// 实现任务的具体流程
steps {
sh 'chmod -R 777 go-build.sh'
sh './go-build.sh ${repository} ${JOB_NAME} ${projectName} latest'
}
}
// 制作自定义镜像
stage ("制作Docker自定义镜像") {
// 实现任务的具体流程
steps {
sh 'docker build -t ${repository}/${JOB_NAME}/${projectName}:latest .'
}
}
// 推送Docker自定义镜像到Harbor仓库
stage ("推送Docker自定义镜像到Harbor仓库") {
// 实现任务的具体流程
steps {
sh 'docker login -u ${repositoryUser} -p ${repositoryPwd} ${repository}'
sh 'docker push ${repository}/${JOB_NAME}/${projectName}:latest'
}
}
// 通过Publish Over SSH将部k8smaster.yaml署到k8smaster机器
stage ("将部k8smaster.yaml署到k8smaster机器") {
// 实现任务的具体流程
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'k8smaster', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'k8smaster.yaml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
// 远程执行k8smaster.yaml文件,重启应用
stage ("远程执行k8smaster.yaml文件,重启应用") {
// 实现任务的具体流程
steps {
sh '''ssh root@192.168.40.201 kubectl apply -f /usr/local/k8s/k8smaster.yaml
ssh root@192.168.40.201 kubectl rollout restart deployment devops -n test'''
}
}
}
// 钉钉消息推送
post {
success {
dingtalk(
robot: "${dingRobotId}",
type: "MARKDOWN",
atAll: true,
title: "${JOB_NAME}构建成功",
text: [
"# ${JOB_NAME} 环境 - 发布成功",
"---",
"### 构建信息",
"",
"- 分支: latest",
"- 提交: ${env.GIT_COMMIT.take(7)}",
"- 时间:${currentBuild.durationString}",
"- 日志:[查看详情](${env.BUILD_URL})",
"---",
"### 更新记录",
"",
"- 1: ${currentBuild.changeSets}",
"- 2: ${currentBuild.description}",
]
)
}
failure {
dingtalk(
robot: "${dingRobotId}",
type: "MARKDOWN",
atAll: true,
title: "${JOB_NAME}构建失败",
text: [
"# ${JOB_NAME} 环境 - 发布失败",
"---",
"### 构建信息",
"",
"- 分支: latest",
"- 提交: ${env.GIT_COMMIT.take(7)}",
"- 时间:${currentBuild.durationString}",
"- 日志:[查看详情](${env.BUILD_URL})",
]
)
}
}
}
k8s的yaml配置文件:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: devops
labels:
app: devops
spec:
replicas: 2
selector:
matchLabels:
app: devops
template:
metadata:
labels:
app: devops
spec:
containers:
- name: devops
image: 192.168.40.101:80/test2/devops:latest
imagePullPolicy: Always
ports:
- containerPort: 8081
---
apiVersion: v1
kind: Service
metadata:
namespace: test
labels:
app: devops
name: devops
spec:
selector:
app: devops
ports:
- port: 8082
targetPort: 8081
type: NodePort
---
# 如果环境支持ingress的话可以配置ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: devops
spec:
ingressClassName: ingress # 这个ingress需要安装
rules:
- host: test.devops..com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: devops
port:
number: 8082
配置host指向:C:\Windows\System32\drivers\etc\hosts
十一、腾讯CODING DevOps:https://console.cloud.tencent.com/coding/container-devops
CODING DevOps 面向容器业务场景,提供代码编译、容器镜像构建、镜像推送及应用部署等功能,与容器服务 TKE、容器镜像服务 TCR 紧密结合,共同提供强大的云原生 DevOps 服务。
文明上网理性发言!
已完结!!!