云原生-DevOps-环境搭建

1、生态环境介绍

1.1、生态环境

环境:Gitee,Jenkins,Java,Git,Maven,SonarQube,Docker,阿里云镜像仓库,K8s

云原生-DevOps-环境搭建_第1张图片

1.2、三种搭建方式

  • Jenkins拉取Gitee代码,使用Maven编译打包和代码分析,再使用Jenkins把打包好的Jar包发送给目标服务器(部署项目服务器),发送成功后在目标服务器执行java -jar xxx.jar
  • Jenkins拉取Gitee代码,使用Maven编译打包和代码分析,使用Docker把打包好的Jar包制作成一个自定义镜像,推送到阿里云镜像仓库(阿里云镜像仓库可选),再使用Jenkins通知目标服务器拉取阿里云镜像仓库,拉取镜像成功后再创建容器即可
  • Jenkins拉取Gitee代码,使用Maven编译打包和代码分析,使用Docker把打包好的Jar包制作成一个自定义镜像,推送到阿里云镜像仓库(阿里云镜像仓库可选),再运行K8s.yaml(k8s.yaml需要提前提供好)

2、准备工作

2.1、创建码云项目

这里就是准备一个自己的代码仓库,使用GitHubGitLabGitee等都可以,创建教程就不写了

2.2、创建阿里云镜像仓库

这里就是准备一个自己的Docker镜像仓库,使用registryHarbor阿里云镜像仓库等都可以,创建教程就不写了

2.3、服务器准备(可以使用虚拟机)

名称 配置 环境 描述
devops-jenkins 2核4GB java,maven,docker,sonarqube,jenkins 拉取代码,编译代码,代码监测,打包上传docker镜像
devops-k8s-master 2核4GB docker,k8s k8s-master节点,拉取docker镜像,部署
devops-k8s-node1 2核4GB docker,k8s k8s-node节点
devops-k8s-node2 2核4GB docker,k8s k8s-node节点

3、Jenkins服务器环境配置,并且部署项目

3.1、关闭防火墙

启动防火墙 systemctl start firewalld
禁用防火墙 systemctl stop firewalld
设置开机启动 systemctl enable firewalld
停止并禁用开机启动 systemctl disable firewalld
重启防火墙 firewall-cmd --reload

3.2、Docker安装

3.2.1、下载Docker依赖组件
yum -y install yum-utils device-mapper-persistent-data lvm2
3.2.2、设置下载Docker的镜像源为阿里云
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
3.2.3、安装Docker服务
yum -y install docker-ce
3.2.4、安装成功后,启动Docker并设置开机自启
# 启动Docker服务
systemctl start docker
# 设置开机自动启动
systemctl enable docker
3.2.5、测试安装成功
docker version

云原生-DevOps-环境搭建_第2张图片

3.2.6、配置Docker阿里云镜像加速

因为docker下载镜像是从docker hub中下载,是国外的,所以下载比较慢,跟我们使用的maven一样

  • 去到阿里云官方网址,找到容器镜像服务:https://www.aliyun.com/product/acr?spm=5176.19720258.J_3207526240.30.3cb876f4HGkuU9
  • 进入管理控制台(这里没有开通服务的需要开通一下容器服务)
  • 点击镜像加速器,选择CentOS

云原生-DevOps-环境搭建_第3张图片

  • 在Linux中执行以下命令
# 1、创建目录
sudo mkdir -p /etc/docker
# 2、配置镜像加速器地址
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://rrnv06ig.mirror.aliyuncs.com"]
}
EOF
# 3、启动docker后台线程
sudo systemctl daemon-reload
# 4、重启docker服务
sudo systemctl daemon-reload

3.3、Docker-Compose安装

3.3.1、下载命令
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
3.3.2、下载完 执行此命令 给dokcer-compose权限
sudo chmod +x /usr/local/bin/docker-compose

3.4、JDK8和Maven安装

需要提前准备好JDK8和Maven的安装包

3.4.1、安装JDK8
#创建目录
mkdir -p /usr/lcoal/jdk
cd /usr/lcoal/jdk
#解压
tar -zxvf jdk-8u231-linux-x64.tar.gz
#配置环境变量
vi /etc/profile
#配置一下内容
export JAVA_HOME=/usr/local/jdk/jdk1.8.0_231
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
#重新载入配置文件
source /etc/profile
3.4.2、安装Maven
#创建目录
mkdir -p /usr/lcoal/maven
cd /usr/lcoal/maven
#解压
tar -zxvf apache-maven-3.6.3-bin.tar.gz
#配置环境变量
vi /etc/profile
#配置一下内容
export MAVEN_HOME=/usr/local/maven/apache-maven-3.6.3
export PATH=$PATH:$MAVEN_HOME/bin
#重新载入配置文件
source /etc/profile

配置maven的settings.xml



    alimaven
    aliyun maven
    http://maven.aliyun.com/nexus/content/groups/public/
    central



    jdk-1.8
    
        true
        1.8
    
    
        1.8
        1.8
        1.8
    

3.5、Jenkins安装

3.5.1、拉取Jenkins镜像
docker pull jenkins/jenkins:2.375.3-lts
3.5.2、创建目录
mkdir /opt/jenkins
cd /opt/jenkins

touch docker-compose.yml
mkdir jenkins_home
chmod -R a+w jenkins_home/

chown root:root /var/run/docker.sock
chmod o+rw /var/run/docker.sock
3.5.3、编写docker-compose.yml
version: "3.1"
services:
    jenkins:
        image: jenkins/jenkins:2.375.3-lts
        container_name: jenkins
        ports:
            - 8080:8080
            - 50000:50000
        volumes:
            - /opt/jenkins/jenkins_home:/var/jenkins_home/
            - /usr/local/jdk/jdk1.8.0_231:/usr/local/src/jdk/jdk1.8
            - /usr/local/maven/apache-maven-3.6.3:/usr/local/apache-maven-3.6.3
            - /usr/bin/docker:/usr/bin/docker
            - /var/run/docker.sock:/var/run/docker.sock
            - /etc/docker/daemon.json:/etc/docker/daemon.json
3.5.4、运行docker-compose.yml
docker-compose up -d
3.5.5、启动Jenkins容器后

由于Jenkins需要下载大量内容,但是由于默认下载地址下载速度较慢,需要重新设置下载地址为国内镜像站

# 修改数据卷中的hudson.model.UpdateCenter.xml文件


    
        default
        https://updates.jenkins.io/update-center.json
    

# 将下载地址替换为http://mirror.esuni.jp/jenkins/updates/update-center.json


    
        default
        http://mirror.esuni.jp/jenkins/updates/update-center.json
    

# 清华大学的插件源也可以https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
3.5.6、再次重启Jenkins容器,访问Jenkins(需要稍微等会)

云原生-DevOps-环境搭建_第4张图片

3.5.7、查看密码登录Jenkins,并登录下载插件
docker exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword
  • 安装:Git Parameter、Publish Over SSH、Gitee

云原生-DevOps-环境搭建_第5张图片

云原生-DevOps-环境搭建_第6张图片

云原生-DevOps-环境搭建_第7张图片

云原生-DevOps-环境搭建_第8张图片

云原生-DevOps-环境搭建_第9张图片

云原生-DevOps-环境搭建_第10张图片

云原生-DevOps-环境搭建_第11张图片

云原生-DevOps-环境搭建_第12张图片

3.6、Jenkins基础配置

3.6.1、系统功能 -> 全局工具配置(配置JDK和Maven地址)

云原生-DevOps-环境搭建_第13张图片

云原生-DevOps-环境搭建_第14张图片

云原生-DevOps-环境搭建_第15张图片

3.6.2、系统功能 -> 系统配置(配置Gitee、Publish Over SSH)

云原生-DevOps-环境搭建_第16张图片

  • 配置Gitee账号

云原生-DevOps-环境搭建_第17张图片

  • 配置Publish Over SSH连接测试、生产环境

云原生-DevOps-环境搭建_第18张图片

3.6.3、新建流水线任务

云原生-DevOps-环境搭建_第19张图片

云原生-DevOps-环境搭建_第20张图片

云原生-DevOps-环境搭建_第21张图片

云原生-DevOps-环境搭建_第22张图片

3.6.4、任务一般配置(General)

云原生-DevOps-环境搭建_第23张图片

  • 基础配置设置

云原生-DevOps-环境搭建_第24张图片

  • 设置项目参数化构建,Git参数和字符参数(可选操作)

云原生-DevOps-环境搭建_第25张图片

  • 构建触发器(根据自己需求去设置,这里就不设置了)

云原生-DevOps-环境搭建_第26张图片

3.6.5、在每台目标服务器上都准备上/opt/run.sh文件

到docker镜像仓库拉取指定版本的项目镜像,再过根据镜像创建容器并且运行容器

#! /bin/bash

bucket_url=$1
bucket_space_name=$2
project_name=$3
tag_version=$4
host_port=$5

image_name=$bucket_url/$bucket_space_name/$project_name:$tag_version

containerId=`docker ps -a | grep ${project_name} | awk '{print $1}'`
if [ "$containerId" != "" ] ; then
    docker stop $containerId
    docker rm $containerId
    echo "Delete Container Success"
fi

imageId=`docker images | grep ${project_name} | awk '{print $3}'`
if [ "$imageId" != "" ] ; then
    docker rmi -f $imageId
    echo "Delete Image Success"
fi

docker login --username=灬lin丶kai registry.cn-beijing.aliyuncs.com --password=kaige1230.

docker pull $image_name

docker run -d -p $host_port:$host_port --name $project_name $image_name

echo "Start Container Success"
3.6.6、Groovy脚本
  • Groovy脚本基础语法
// 所有脚本命令包含在pipeline{}中
pipeline {  
	// 指定任务在哪个节点执行(Jenkins支持分布式)
    agent any
    
    // 配置全局环境,指定变量名=变量值信息
    environment{
    	host = '192.168.11.11'
    }

    // 存放所有任务的合集
    stages {
    	// 单个任务
        stage('任务1') {
        	// 实现任务的具体流程
            steps {
                echo 'do something'
            }
        }
		// 单个任务
        stage('任务2') {
        	// 实现任务的具体流程
            steps {
                echo 'do something'
            }
        }
        // ……
    }
}

Ps:涉及到特定脚本,Jenkins给予了充足的提示,可以自动生成命令

云原生-DevOps-环境搭建_第27张图片

3.6.7、Jenkinsfile实现
  • 配置pipeline

云原生-DevOps-环境搭建_第28张图片

  • 准备Jenkinsfile
pipeline {
    agent any
	
	environment {
        bucketHost = '127.0.0.1'
        bucketRepo = 'xxx'
        bucketUser = 'root'
        bucketPasswd = '123456'
	}

    stages {
        stage('获取Git仓库代码') {
            steps {
                checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[credentialsId: '35edc56c-f10e-4a33-80a9-355fb68e8842', url: 'https://gitee.com/linkaiqq/test-project-cluster.git']])
            }
        }
		stage('通过Maven构建项目') {
            steps {
                sh '/usr/local/apache-maven-3.6.3/bin/mvn clean package -DskipTests'
            }
        }
		stage('通过Docker制作自定义镜像') {
            steps {
                sh '''cp ./target/*.jar ./docker/
                docker build -t ${JOB_NAME}:${tag} ./docker/ '''
            }
        }
		stage('将Docker自定义镜像推送到阿里云镜像仓库') {
            steps {
                sh '''docker login -u ${bucketUser} -p ${bucketPasswd} ${bucketHost}
                docker tag ${JOB_NAME}:${tag} ${bucketHost}/${bucketRepo}/${JOB_NAME}:${tag}
                docker push ${bucketHost}/${bucketRepo}/${JOB_NAME}:${tag}'''
            }
        }
		stage('通过Publish Over SSH通知目标服务器') {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/run.sh $bucketHost $bucketRepo $JOB_NAME $tag $port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }
    }
    
}

云原生-DevOps-环境搭建_第29张图片

4、集成SonarQube代码分析平台

4.1、SonarQube介绍

Sonar Qube是一个开源的代码分析平台,支持Java、Python、PHP、JavaScript、CSS等25种以上的语言,可以检测出重复代码、代码漏洞、代码规范和安全性漏洞的问题。

Sonar Qube可以与多种软件整合进行代码扫描,比如Maven,Gradle,Git,Jenkins等,并且会将代码检测结果推送回Sonar Qube并且在系统提供的UI界面上显示出来

img

4.2、SonarQube环境搭建

4.2.1、SonarQube安装

Sonar Qube在7.9版本中已经放弃了对MySQL的支持,并且建议在商业环境中采用PostgreSQL,那么安装Sonar Qube时需要依赖PostgreSQL。

并且这里会安装Sonar Qube的长期支持版本8.9

  • 拉取镜像
docker pull postgres
docker pull sonarqube:8.9.3-community
  • 编写docker-compose.yml
version: "3.1"
services:
  db:
    image: postgres
    container_name: db
    ports:
      - 5432:5432
    networks:
      - sonarnet
    environment:
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar
  sonarqube:
    image: sonarqube:8.9.3-community
    container_name: sonarqube
    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
  • 启动容器(启动报错)
docker-compose up -d
  • 需要设置sysctl.conf文件信息(设置vm.max_map_count)

img

云原生-DevOps-环境搭建_第30张图片

  • 并执行命令刷新
sysctl -p
  • 重新启动需要一定时间启动,可以可以查看容器日志,看到如下内容代表启动成功

云原生-DevOps-环境搭建_第31张图片

  • 访问Sonar Qube首页

云原生-DevOps-环境搭建_第32张图片

  • 还需要重新设置一次密码

云原生-DevOps-环境搭建_第33张图片

  • Sonar Qube首页

云原生-DevOps-环境搭建_第34张图片

4.2.2、安装中文插件

云原生-DevOps-环境搭建_第35张图片

安装成功后需要重启,安装失败重新点击install重装即可。

安装成功后,会查看到重启按钮,点击即可

云原生-DevOps-环境搭建_第36张图片

重启后查看效果

云原生-DevOps-环境搭建_第37张图片

4.3、SonarQube基本使用

SonarQube的使用方式很多,Maven可以整合,也可以采用SonarScanner的方式,再查看SonarQube的检测效果

4.3.1、Maven实现代码检测
  • 修改Maven的settings.xml文件配置SonarQube信息

    sonar
    
        true
    
    
        admin
        123456
        http://localhost:9000
    

  • 在代码位置执行命令:mvn sonar:sonar

云原生-DevOps-环境搭建_第38张图片

  • 查看Sonar Qube界面检测结果

云原生-DevOps-环境搭建_第39张图片

4.3.2、SonarScanner实现代码检测
  • 下载Sonar-scanner:https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/

下载4.6.x版本即可,要求Linux版本

  • 由于是zip压缩包,需要安装unzip解压插件
yum -y install unzip
  • 解压压缩包
unzip sonar-scanner-cli/sonar-scanner-cli-4.6.0.2311-linux.zip
  • 配置sonarQube服务端地址,修改conf下的sonar-scanner.properties

云原生-DevOps-环境搭建_第40张图片

  • 执行命令检测代码
# 在项目所在目录执行以下命令
~/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=demo -Dsonar.projectKey=java -Dsonar.java.binaries=target/

Ps:主要查看我的sonar-scanner执行命令的位置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-psRniIsN-1678445376314)(https://gitee.com/linkaiqq/lk-img-oss/raw/master/pictures/202303101701811.png)]

  • 查看SonarQube界面检测结果

云原生-DevOps-环境搭建_第41张图片

4.4、Jenkins集成SonarQube

Jenkins继承SonarQube实现代码扫描需要先下载整合插件

4.4.1、Jenkins安装插件

云原生-DevOps-环境搭建_第42张图片

云原生-DevOps-环境搭建_第43张图片

云原生-DevOps-环境搭建_第44张图片

4.4.2、Jenkins配置SonarQube
  • 开启Sonar Qube权限验证

云原生-DevOps-环境搭建_第45张图片

  • 获取Sonar Qube的令牌

云原生-DevOps-环境搭建_第46张图片

  • 配置Jenkins的Sonar Qube信息

云原生-DevOps-环境搭建_第47张图片

云原生-DevOps-环境搭建_第48张图片

云原生-DevOps-环境搭建_第49张图片

4.4.3、配置SonarScanner
  • 将Sonar-scaner添加到Jenkins数据卷中并配置全局配置

云原生-DevOps-环境搭建_第50张图片

  • 配置任务的SonarScanner
pipeline {
    agent any
	
	environment {
        bucketHost = '127.0.0.1'
        bucketRepo = 'xxx'
        bucketUser = 'root'
        bucketPasswd = '123456'
	}

    stages {
        stage('获取Git仓库代码') {
            steps {
                checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[credentialsId: '35edc56c-f10e-4a33-80a9-355fb68e8842', url: 'https://gitee.com/linkaiqq/test-project-cluster.git']])
            }
        }
		stage('通过Maven构建项目') {
            steps {
                sh '/usr/local/apache-maven-3.6.3/bin/mvn clean package -DskipTests'
            }
        }
        stage('通过SonarQube做代码质量检测') {
            steps {
                sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.source=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=40306ae8ea69a4792df2ceb4d9d25fe8a6ab1701'
            }
        }
		stage('通过Docker制作自定义镜像') {
            steps {
                sh '''cp ./target/*.jar ./docker/
                docker build -t ${JOB_NAME}:${tag} ./docker/ '''
            }
        }
		stage('将Docker自定义镜像推送到阿里云镜像仓库') {
            steps {
                sh '''docker login -u ${bucketUser} -p ${bucketPasswd} ${bucketHost}
                docker tag ${JOB_NAME}:${tag} ${bucketHost}/${bucketRepo}/${JOB_NAME}:${tag}
                docker push ${bucketHost}/${bucketRepo}/${JOB_NAME}:${tag}'''
            }
        }
		stage('通过Publish Over SSH通知目标服务器') {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'test-server', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/opt/run.sh $bucketHost $bucketRepo $JOB_NAME $tag $port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }
    }
    
}

5、K8S服务器环境配置

5.1、准备工作

名称 CPU 内存 磁盘 IP
k8s-master 2核 4GB 20GB 10.1.20.8
k8s-node1 2核 4GB 20GB 10.1.20.2
k8s-node2 2核 4GB 20GB 10.1.20.14

5.2、基础环境配置(所有节点全部执行)

5.2.1、关闭防火墙
systemctl stop firewalld
5.2.2、关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config
5.2.3、关闭swap
  • 方式一
echo "vm.swappiness = 0">> /etc/sysctl.conf 
swapoff -a && swapon -a
sysctl -p
  • 方式二(可选)
#关掉swapoff
swapoff -a

#注释掉配置(注释掉最后一行)
vi /etc/fstab

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SeZ3lsUv-1678445378254)(null)]

重启虚拟机

reboot now
5.2.4、设置主机名称
5.2.4.1、master节点
hostnamectl set-hostname k8s-master
5.2.4.2、node1节点
hostnamectl set-hostname k8s-node1
5.2.4.3、node2节点
hostnamectl set-hostname k8s-node2
5.2.5、修改hosts(注意:修改自己的内网ip)
vim /etc/hosts

在最下方添加内网ip映射

10.0.20.8 k8s-master
10.0.20.2 k8s-node1
10.0.24.14 k8s-node2
5.2.6、将桥接的 IPv4 流量传递到 iptables 的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1
EOF
 
sysctl --system # 刷新生效
5.2.7、时间同步
yum install ntpdate -y
 
ntpdate time.windows.com
5.2.8、配置完成以上操作最好是重启一下服务器
reboot now

5.3、安装Docker(所有节点全部执行)

这里就不介绍了,安装docker并且要设置阿里云镜像加速

5.4、安装kubeadm、kubelet 、 kubectl(所有节点全部执行)

5.4.1、添加 Kubernetes yum 源
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
5.4.2、安装 kubeadm, kubelet 和 kubectl
yum install -y kubelet-1.17.3 kubectl-1.17.3 kubeadm-1.17.3
systemctl enable kubelet

5.5、启动k8s(master节点执行)

5.5.1、初始化master节点(注意:10.0.20.8修改为自己的master节点ip,其他忽动)
kubeadm init \
--apiserver-advertise-address=10.0.20.8 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.17.3 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16

初始化完成后会生成一段代码,这段代码在子节点加入的时候需要执行,如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-puQmfX3K-1678445377703)(null)]

5.5.2、使用 kubectl 工具
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
5.5.3、检查master节点
kubectl get nodes

如下图则代表master节点已启动

云原生-DevOps-环境搭建_第51张图片

5.5.4、安装pod网络插件
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
  • 上面下载速度慢,可以直接下面的方法
kubectl apply -f kube-flannel.yml
  • 将下方内容复制到kube-flannel.yml文件中,执行上方命令即可
---
kind: Namespace
apiVersion: v1
metadata:
  name: kube-flannel
  labels:
    pod-security.kubernetes.io/enforce: privileged
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes/status
  verbs:
  - patch
- apiGroups:
  - "networking.k8s.io"
  resources:
  - clustercidrs
  verbs:
  - list
  - watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: flannel
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: flannel
subjects:
- kind: ServiceAccount
  name: flannel
  namespace: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: flannel
  namespace: kube-flannel
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube-flannel-ds
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
spec:
  selector:
    matchLabels:
      app: flannel
  template:
    metadata:
      labels:
        tier: node
        app: flannel
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      hostNetwork: true
      priorityClassName: system-node-critical
      tolerations:
      - operator: Exists
        effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni-plugin
        image: docker.io/flannel/flannel-cni-plugin:v1.1.2
       #image: docker.io/rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.2
        command:
        - cp
        args:
        - -f
        - /flannel
        - /opt/cni/bin/flannel
        volumeMounts:
        - name: cni-plugin
          mountPath: /opt/cni/bin
      - name: install-cni
        image: docker.io/flannel/flannel:v0.21.2
       #image: docker.io/rancher/mirrored-flannelcni-flannel:v0.21.2
        command:
        - cp
        args:
        - -f
        - /etc/kube-flannel/cni-conf.json
        - /etc/cni/net.d/10-flannel.conflist
        volumeMounts:
        - name: cni
          mountPath: /etc/cni/net.d
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
        image: docker.io/flannel/flannel:v0.21.2
       #image: docker.io/rancher/mirrored-flannelcni-flannel:v0.21.2
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        resources:
          requests:
            cpu: "100m"
            memory: "50Mi"
        securityContext:
          privileged: false
          capabilities:
            add: ["NET_ADMIN", "NET_RAW"]
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: EVENT_QUEUE_DEPTH
          value: "5000"
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
        - name: xtables-lock
          mountPath: /run/xtables.lock
      volumes:
      - name: run
        hostPath:
          path: /run/flannel
      - name: cni-plugin
        hostPath:
          path: /opt/cni/bin
      - name: cni
        hostPath:
          path: /etc/cni/net.d
      - name: flannel-cfg
        configMap:
          name: kube-flannel-cfg
      - name: xtables-lock
        hostPath:
          path: /run/xtables.lock
          type: FileOrCreate
5.5.5、如果token过期重新获取token

执行命令生成token

kubeadm token generate

云原生-DevOps-环境搭建_第52张图片

根据token输出添加命令,create后面带刚才生成的token文件

kubeadm token create ins9ct.n3vpfy86dsjglmxy --print-join-command --ttl=0

如此便获得新的加入命令了,拿去子节点执行

img

5.6、集群配置

5.6.1、子节点加入集群(子节点执行)

这时候就用到1.4.1单元中生成的那段代码了,我的如下

kubeadm join 10.0.20.8:6443 --token 9z52d6.eq693qimjgc1znu4 \
    --discovery-token-ca-cert-hash sha256:ce4e0694eadb2c27255d225facdb04fc2da19fbbf432e779f0070f5b3a40a67b 

哪个子节点需要加入集群就在哪个子节点执行,然后如下图等待完成

云原生-DevOps-环境搭建_第53张图片

如果提示下图错误,有可能是token过期了,按照1.4.5单元的操作重新获取token然后执行加入命令即可

云原生-DevOps-环境搭建_第54张图片

如果重新生成token还不可以就检查是部署防火墙和开放端口的问题,检查master节点是否开启了6443

5.6.2、检查节点是否加入集群 (master节点执行)
kubectl get nodes

如下图,两个node节点都加入了集群即为成功

云原生-DevOps-环境搭建_第55张图片

5.6.3、最后

配置到了这里就结束了,需要安装 控制台 执行百度

6、Jenkins+K8S项目集群搭建

6.1、K8S配置文件

apiVersion: v1
kind: Namespace
metadata:
  name: test-dev
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: test-dev
  name: pipeline
  labels:
    app: pipeline
spec:
  replicas: 2
  selector:
    matchLabels:
      app: pipeline
  template:
    metadata:
      labels:
        app: pipeline
    spec:
      serviceAccountName: default
      imagePullSecrets:
      - name: aliyun-secret
      containers:
      - name: pipeline
        image: registry.cn-beijing.aliyuncs.com/linkaiing/test-project-cluster:v1.0.0
        imagePullPolicy: Always
        ports:
        - containerPort: 9999
---
apiVersion: v1
kind: Service
metadata:
  namespace: test-dev
  name: pipeline
  labels:
    app: pipeline
spec:
  selector:
    app: pipeline
  ports:
  - port: 9999
    targetPort: 9999
  type: NodePort

6.2、K8S使用阿里云镜像仓库

  • Node使用docker login阿里云的私有仓库,保证调度过来pod时可以及时拉取到镜像
docker login [email protected] registry.cn-hangzhou.aliyuncs.com
  • 需要在master上生成secret秘钥
kubectl create secret docker-registry alidockerregistryssecret --docker-server=registry.cn-hangzhou.aliyuncs.com --docker-username=xxx --docker-password=xxx [email protected]
  • 说明:

    • alidockerregistryssecret :指定秘钥的键名称,可自行定义
    • –docker-server :指定docker仓库的地址
    • –docker-username :指定docker仓库账号
    • –docker-password :指定docker仓库密码
    • –docker-email: 指定docker邮件地址(选填)
    • alidockerregistryssecret 只能在默认namespace下使用,其他要使用则在创建时指定namespace(-n xxx)
  • 将ImagePullSecrets添加到default

kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "alidockerregistryssecret"}]}'
  • 上方是介绍,我们执行
kubectl create secret docker-registry aliyun_secret --docker-server=xxx --docker-username=xxx --docker-password=xxx -n test-dev

6.3、修改Jenkins的Jenkinsfile文件

pipeline {
    agent any
	
	environment {
        bucketHost = '127.0.0.1'
        bucketRepo = 'xxx'
        bucketUser = 'root'
        bucketPasswd = '123456'
	}

    stages {
        stage('获取Git仓库代码') {
            steps {
                checkout scmGit(branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[credentialsId: '35edc56c-f10e-4a33-80a9-355fb68e8842', url: 'https://gitee.com/linkaiqq/test-project-cluster.git']])
            }
        }
		stage('通过Maven构建项目') {
            steps {
                sh '/usr/local/apache-maven-3.6.3/bin/mvn clean package -DskipTests'
            }
        }
        stage('通过SonarQube做代码质量检测') {
            steps {
                sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.source=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=./target/ -Dsonar.login=40306ae8ea69a4792df2ceb4d9d25fe8a6ab1701'
            }
        }
        stage('通过Docker制作自定义镜像') {
            steps {
                sh '''cp ./target/*.jar ./docker/
                docker build -t ${JOB_NAME}:${tag} ./docker/ '''
            }
        }
		stage('将Docker自定义镜像推送到阿里云镜像仓库') {
            steps {
                sh '''docker login -u ${bucketUser} -p ${bucketPasswd} ${bucketHost}
                docker tag ${JOB_NAME}:${tag} ${bucketHost}/${bucketRepo}/${JOB_NAME}:${tag}
                docker push ${bucketHost}/${bucketRepo}/${JOB_NAME}:${tag}'''
            }
        }
		stage('目标服务器使用K8S部署项目') {
            steps {
                sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s-master', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'kubectl apply -f /opt/k8s_yaml_list/pipeline.yaml', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'pipeline.yaml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }
    }
    
}

云原生-DevOps-环境搭建_第56张图片

6.4、K8S常用命令

# namespace=命名空间	默认:default
kubectl get namespace
kubectl create ns xxx
kubectl delete us xxx


# pod=一个环境
kubectl get pods
kubectl get pods -A
kubectl get pod -n test
kubectl run xxx --image=xxx:latest -n test
kubectl describe pod xxx
kubectl delete pod xxx -n test
kubectl logs -f xxx -n test
kubectl exec -it xxx -n test -- bash


# deployment=管理多个pod环境
kubectl get deploy -n test
kubectl create deploy xxx -n test --image=xxx:latest
kubectl delete deploy xxx -n test


# service
kubectl expose deploy xxx --port=8080 --target-port=80 -n test
kubectl expose deploy xxx --port=8080 --target-port=80 -n test --type=NodePort
kubectl get service -n test
kubectl delete xxx -n test


# yml方式运行
kubectl apply -f xxx.yml
kubectl delete -f xxx.yml

你可能感兴趣的:(Docker,DevOps,云原生,devops,docker)