k8s jenkins kubeSphere布置运用

参阅:Jenkins k8s完成主动化布置

这里的k8s有两层含义,第一层便是把jenkins的agent布置到k8s里边,以完成各种一次性的独立的构建环境,第二层含义是把项目代码布置到k8s里边

阐明:以下的操作是在win11专业版上进行的,装置wsl2,在win上面用linux,jenkins直接装置在linux里边

必备环境

  • 装置wsl2,选ubuntu, 后续操作都是在ubuntu中进行
  • 装置jenkins
  • 装置docker engine和docker-compose
  • 装置minikube
  • 装置kubectl
  • 装置harbor

wsl2装置ubuntu

如何运用 WSL 在 Windows 上装置 Linux

# 会主动装置ubuntu
wsl --install

装置jenkins

Jenkins Debian Packages
大概过程便是先下载个啥.asc文件,然后转换成jenkins.list,再然后更新库房列表,然后就能找到jenkins官方下载地址下载装置

装置docker engine

装置docker engine的ubuntu版别

装置好后用docker info,测验是否ok,第一次engine或许发动比较慢会导致docker info提示连不上,能够稍等会儿,后续每次docker engine会跟随体系主动发动

假如按上面的链接操作装置,则直接装置了docker compose plugin,就能够经过docker compose履行原先的docker-compose指令,或许单独装置一个docker-compose

独立装置docker-compose

ps: sudo docker run hello-world或许镜像会下载不了,需求魔法

如何设置非安全的Docker镜像库房

// 这一步是为了后续能以http的形式拜访本地harbor
// 修改下 /etc/docker/daemon.json
// 增加这么一段,文件假如不存在就新建一个
 {
   "insecure-registries":["你的ubuntu ip"]
 }

装置minikube

装置minikube

# 装置好后履行,这一步依靠docker,会下载相关镜像生成一个minikube container
minikube start --drvier=docker --insecure-registry=linux的ip地址

装置kubectl

在 Linux 体系中装置并设置 kubectl

装置harbor

harbor装置参阅

这个装置没有参阅官方,感觉官方的装置写的贼杂乱,harbor装置依靠docker和docker-compose

# 从github下载最新的装置包,包里边有相关docker镜像,几百M,下载估计比较慢
# 1. liunx下载指令,或许用win下载,然后拷贝到linux, 一切版别列表https://github.com/goharbor/harbor/releases
wget https://github.com/goharbor/harbor/releases/download/v2.7.4/harbor-offline-installer-v2.7.4.tgz

# 2. 解压,并修改装备文件
tar zxf harbor-offline-installer-v2.7.4.tgz

# 默许有个harbor.yml.tmpl,直接从这个文件仿制下,然后修改harbor.yml
cp harbor.yml.tmpl harbor.yml

harbor.yml的部分

# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: 172.22.109.126 # 地址就按上面提示的用ubuntu的ip,能够经过ifconfig,找到eth0最初的那一段,便是ubuntu的ip

# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 80

# https相关的都注释掉,这个搞起来麻烦,当然这一块简略了,后边docker和minikube都需求特别处理下这个问题
# https related config
# https:
#   # https port for harbor, default is 443
#   port: 443
#   # The path of cert and key files for nginx
#   certificate: /root/certs/reg.westos.org.crt
#   private_key: /your/private/key/path

# 3. 进入解压后的harbor目录
./prepare # 做一些准备工作

# 取出里边的镜像,创立container,这一步或许遇到permission denied,便是没权限,那能够加上 sudo ./install.sh
# 我用的便是 sudo ./install.sh,但又碰上找不到/root/.docker/docker-desktop/docker.sock的问题,或许是由于我先装过win版的docker desktop导致的
# 后边用了软衔接处理的 ln s /var/run/docker.sock /root/.docker/docker-desktop/docker.sock
./install.sh 

# 浏览器拜访
# 直接翻开localhost就行,默许是80端口

具体过程

  • 进入wsl2
  • 发动minikube
  • 发动harbor
  • 发动jenkins,拜访jenkins的web操控台,装置k8s的各种插件
  • 构建集成kubectl和运用root用户的jenkins agent镜像
  • 编写k8s的deployment.yml文件,编写Jenkinsfile,编写Dockerfile
  • 创立pipline项目,填写项目信息,流水线挑选pipline script from scm,填入信息,保存,履行构建,构建成功后用minikube service serviceName露出服务,用浏览器检查

进入wsl2

能够查找wsl,或许ubuntu就能够进入

发动minikube

# 装置好后履行,这一步依靠docker,会下载相关镜像生成一个minikube container
# insecure的意思是答应以http的形式拜访本地harbor,前面harbor不是图简略直接把https注释了吗
minikube start --driver=docker --insecure-registry=linux的ip地址

# 发动k8s 操控台,快捷操作deployment, pod的检查删去操作
nohup minikube dashboard &
tail nohup.out # 翻开日志,ctrl   点击对应链接可在浏览器翻开对应的dashboard

发动harbor

再履行一遍前面的harbor装置过程涉及的install.sh文件即可,就能发动了,现在没整明白为啥harbor没有在体系重启后随docker主动发动

拜访localhost,输入默许用户名 “admin” 默许暗码 “Harbor12345”,创立库房

发动jenkins并拜访jenkins的web操控台

# 发动
nohup jenkins &

# log中找到jenkins初始化需求的字符串
tail nohup.out

拜访localhost:8080, 进入后装置k8s相关插件

  • Kubernetes plugin:用于完成jenkins agent的k8s布置 参阅插件官网
  • Kubernetes :: Pipeline :: DevOps Steps 效果没搞懂
  • Kubernetes CLI Plugin:用于完成kubectl衔接远程k8s cluster,供给用户名暗码和远程k8s cluster给它,就能够装置kubectl,然后操作远程k8s cluster了

增加安全凭证,后续的Jenkinsfile编写需求用到这些凭证,体系管理 -> 凭证管理 -> 增加凭证

  • gitee: 用于git拉代码,选username with password,id填入gitee,能够任意起名字,后续编写Jenkinsfile指定这个名字即可
  • harbor:用于登录harbor,选username with password,id填入harbor
  • sa-secret: 用于拜访k8s cluster,挑选secret text,填入token,id设置为sa-secret,token按下面的过程获取
  1. 创立用于拜访k8s cluster的凭证
# 创立serviceAccount,这一步没怎样研究,就跟着网上的走
# 创立一个名为jenkins-robot的sa
kubectl create serviceaccount jenkins-sa

# 绑定角色啥的,没太懂
kubectl create rolebinding jenkins-sa-binding --clusterrole=cluster-admin --serviceaccount=default:jenkins-sa
  1. 创立secret绑定到对应的serviceAccount
apiVersion: v1
kind: Secret
metadata:
  name: sa-secret # 指定secret的名字
  annotations:
    kubernetes.io/service-account.name: "jenkins-sa" # 绑定到jenkins-sa这个serviceAccount上
type: kubernetes.io/service-account-token
  1. 检查找到secret对应的token并仿制token
kubectl describe secret sa-secret
# 得到一大堆字符串,相似下面这种,仿制其间token字段的值
#Name:         sa-secret
#Namespace:    default
#
#Type:  kubernetes.io/service-account-token
#
#Data
#====
#ca.crt:     1111 bytes
#extra:      4 bytes
#namespace:  7 bytes
#token:      eyJhbGciOiJSUzI1NiIsImtpZCI6InNFNTdsTTBMSnUyQWNLNU4tLXl2S1Q0aDdzYm1USnFZWGtlbTRTdWhrZ00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InNhLXNlY3JldCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZTUyMTAyMDAtMGFhMS00Mjc2LWE4N2QtMjVhNTdkNjdlOTRkIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6ZGVmYXVsdCJ9.TrL5U-3GeYW5DORcG6Rk7CC2pGa0AO_pZ8O1Ia7vIKxiZq1STvQyewtJiBSUcpKPUmsTe60uWLR6_1MY3-7EESGx3G-XUIRtF9Bt5HGEnhfZn6-BGP0brXYQXhfMcssQdePYroO9N9N3LQnyMroCHyCFhamU_-gIKNgotLiE8xO-kA5v6FFgK3rzohex-qQyOEJRDoaIESvo-FlxDu2Ai8KXsTvd0wKTG1s-C5XtgUPczJuHUW8bHepuwimUsvtB4vI_XoygaeicOT_uajd9Hh5tVeX4pzl_vwSolrH-dVwEGjUCoEVp6-wDjs5ox0GEz4tFvQzIcL8pFbjPHuOibw

创立cloud,即指定衔接哪个k8s集群

创立即可,后续的kubernetes plugin的podTemplate假如不指定cloud会主动运用这个(猜的)

体系管理 -> clouds -> new cloud,填入称号k8s,挑选kubernetes,假如没有这个选项或许你还没装置kubernetes plugin

# 1. Kubernetes 地址: 用下面的指令获取,取第一个
kubectl cluster-info
# 2. 勾选 “禁用 HTTPS 证书检查”
# 3. 凭证挑选前面创立的sa-secret然后衔接测验,经过了表示能够衔接到k8s cluster,即后续的jenkins agent能够布置到k8s上
# 4.Jenkins 地址: 不填就会用jenkins体系装备里边的地址,填的话不要用localhost或许127,要用本地真实ip
#   Jenkins 通道不用填
# 保存即可

构建集成kubectl和运用root用户的jenkins agent镜像

构建自己的agent镜像,由于用默许镜像的话是运用不了kubectl指令的,而尝试挂载host中的kubectl又失利了,所以自己打包一个装置了kubectl的版别

# 这个版别应该是随意的,我写这个是前面运用过程中发现我装置的kubernets plugins主动用的这个版别,也能够用最新版吧
FROM jenkins/inbound-agent:3192.v713e3b_039fb_e-1
# 修改为root用户发动,这一步很重要,默许jenkins agent用的是jenkins用户发动,会导致拜访不了主机的docker.sock
# 不过也能够装备 kubernets plugins的runAsUser参数, runAsUser: '0', 也表示用root用户发动
USER root
# 这一步kubectl的版别号,需求保持和host共同,能够经过 kubectl version检查版别
ARG KUBECTL_VERSION=1.28.4
# Install kubectl (same version of aws esk)
RUN curl -sLO https://storage.googleapis.com/kubernetes-release/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl && 
    mv kubectl /usr/bin/kubectl && 
    chmod  x /usr/bin/kubectl
ENTRYPOINT ["/usr/local/bin/jenkins-agent"]
# 构建镜像并推送
docker build -t localhost/my-rep/agent1:latest
docker push localhost/my-rep/agent1:latest

编写Dockerfile,Jenkinsfile,k8s装备文件

先在gitee上创立个项目,然后用vue-cli进行下初始化,在新建个deploy目录,在里边创立deployment.yml, Dockerfile和Jenkinsfile放在根目录

Dockerfile

# 从docker hub下载nginx镜像,然后仿制dist目录下的文件到/usr/share/nginx/html/,由于nginx发动后,主页默许在这个目录
FROM nginx:alpine
COPY dist/ /usr/share/nginx/html/

创立一个secret

kubectl create secret docker-registry my-docker-secret 
  --docker-username=admin 
  --docker-password=Harbor12345 
  --docker-server=你的ubuntu ip

k8s deployment.yml

# 创立deployment,称号为nginx,运用镜像为IMAGE_PATH,这是个占位字符,后续在pipline中会用正则把它替换成真正的镜像地址
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: IMAGE_PATH
          ports:
            - containerPort: 80
      imagePullSecrets:
        - name: my-docker-secret # 指定一个前面创立的docker-registry类型的secret,用于拉取harbor镜像
---
# 创立一个service,用于露出pod的80端口
apiVersion: v1 
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 80
  type: NodePort

Jenkinsfile


def HARBOR_URL = '你的ubuntu IP'
// podTemplate用法是kubernetes plugins供给的,也能够用声明式语法,都差不多,kubernetes plugins官网能看到各种用法
// 
podTemplate(volumes: [
        // 挂载主机的docker,然后能够运用docker指令,相似于win上的快捷方式,不过这一步要用前面自己构建的容器,不然默许的发动用户没有拜访docker.sock的权限
        hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'), 
        hostPathVolume(mountPath: '/usr/bin/docker', hostPath: '/usr/bin/docker'),
        hostPathVolume(mountPath: '/home/jenkins/agent/.pnpm-store', hostPath: '/root/.local/share/pnpm/'), // 挂载pnpm的全局存储库,减小pnpm装置包的时间,这一步假如有问题也能够去除
    ], 
    // 或许装备 runAsUser: '0'也能够启用root用户
    // 装备容器信息,自己构建容器,加入了kubectl和运用root用户
    containers: [
        containerTemplate(
            name: "jnlp",
            image: "${HARBOR_URL}/my-rep/agent1:latest"
        ),
        containerTemplate(name: "nodejs", image: "node:18-alpine", command: 'sleep', args: '99d') // 要加上sleep指令,不然container发动后主动封闭,没搞懂为啥
    ]) {
    node(POD_LABEL) {
        // 拉取代码并打包
        stage("clone") {
           git credentialsId: 'gitee', url: 'https://gitee.com/xxx/test-jenkins.git'
           container("nodejs") {
                sh '''npm install -g pnpm@7 
                    pnpm i
                    pnpm build
                '''
            }
        }
        // 构建镜像
        stage("build") {
            echo "开端构建docker镜像"
            sh "docker build -t ${HARBOR_URL}/my-rep/nginx:${env.BUILD_NUMBER} ."
            echo "构建完毕"
        }
        // 上传镜像到私有镜像库
        stage("publish") {
            // 获取harbor的用户命和暗码
           withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'HARBOR_SECRET_PSW', usernameVariable: 'HARBOR_SECRET_USR')]) {
                echo "开端推送镜像"
                sh "docker login -u ${HARBOR_SECRET_USR} -p ${HARBOR_SECRET_PSW} http://${HARBOR_URL}"
                sh "docker push ${HARBOR_URL}/my-rep/nginx:${env.BUILD_NUMBER}"
                echo "推送完毕"
            }
        }
        // 进行k8s发布
        stage("deploy") {
            // withKubeConfig由kubernetes cli供给,用于拜访k8s cluster
              // 这一步装备内网ip很重要
              // 这个serverUrl不是经过kubectl cluster-info得到的那个,那个是外部拜访的ip,而这里由于agent是布置在k8s里边的,和k8s cluster在同一个内部网络,需求用内网地址
              // kubectl get services 得到下面的参数,取kubernetes这个ip加端口
              // kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP        23h
              // nginx-service   NodePort    10.108.227.72   <none>        80:30080/TCP   23h
             withKubeConfig(credentialsId: 'sa-secret', serverUrl: 'https://10.96.0.1:443') {
               // 进入deploy目录,由于我项意图装备文件都放在了deploy目录下
                dir('deploy') {
                    def image_name = "${HARBOR_URL}/my-rep/nginx:${env.BUILD_NUMBER}"
                    echo "替换image路径"
                    sh "sed -i 's/IMAGE_PATH/${image_name}/g' deployment.yml"
                    echo "布置app"
                    sh "kubectl apply -f deployment.yml"
                    echo "布置完毕,能够经过履行minikube service nginx-service得到一个可拜访的地址,driver是docker且是wsl或win环境,NodePort类型的service的IP并不能直接被拜访到,所以minikube供给了service指令"
                }
            }
        }
    }
}

一些重要概念

  • jenkins master: 类型于一台主机,能够直接在上面运转使命,官方主张把master设置为制止履行使命,只做操控用
  • jenkins agent:相似于一个只干活的主机,上面会运转jenkins的一个agent.jar,然后与master衔接,master给它分配使命。然后这个agent能够直接其他主机上创立,也能够由k8s帮助创立,而假如是k8s创立,就需求kubernetes plugins,按最基本的装备的话,它会生成一个称号为jnlp的container,用于履行使命以及和master衔接通信,所以假如自己彻底写k8s的装备的话也要写一个name为jnlp的container,同时里边要包括agent.jar的功用,那么直接用agent官方镜像或许集成官方镜像即可

过程中遇到的坑

网络问题

有镜像下载不下来的状况;有连不上docker deamon的状况;minikube start下载镜像贼慢还有或许失利;有连不上k8s cluster的状况;有连不上jenkins master的状况

处理办法:魔法是有必要的,不仅win要魔法,还得开个tun mode给wsl也来个魔法,其次最好有个队友一起搞,这样能知道一些网络问题是哪装备出错了仍是便是网慢

linux权限问题

多次出现各种权限问题,最典型的报错 permission denies,这个引荐没有linux根底的花1h看看linux用户、用户组、文件权限相关的内容, 引荐鸟哥相关linux文章

运用者与群组

Linux文件权限概念

极重要!权限与指令间的联系:

KubeSphere介绍

kubeSphere便是比k8s dashboard功用愈加丰厚,同时它还有许多其他功用,比如集成了jenkins的pipeline,下文主要介绍怎样运用kubesphere的devops功用。kubesphere装置了devops后
会生成jenkins master Pod,当运用pipeline功用时,会主动创立jenkins agent Pod,当然也能够自定义agent

kubesphere装置及devops装置和运用

在k8s中装置kubesphere

参照官网装置,装好后怎样都登录不了,最终发现是k8s版别太高导致,其实官网有阐明只支持到k8s指定版别,没仔细看,反而花了巨多时间查找登录页面的报错

装置KubeSphere DevOps 体系

然后坑又来了,devops插件怎样都装不上,最终尝试装置2.1的kubesphere版别,devops总算ok了

降kubesphere版别过程中,又涉及helm降版别装置,镜像拉不下来,参阅处理k8s helm装置tiller出现ImagePullBackOff,ErrImagePull过错处理了

然后便是创立devops项目,创立流水线。能够直接仿制Jenkinsfile。甚至能够直接用浏览器拜访内部的jenkins,默许的service是ks-jenkins,找到其露出的端口号即可,登录后能看到,kubesphere只是把流水线装备直接放在了pipline里边。
那么用kubesphere作为devops的优势在哪呢,或许是它简化了jenkins的各种插件的杂乱装备?

反正我最终是没有用kubesphere完成过构建,或许是版别太低了,前面手动写的Jenkinsfile放进去履行各种报错,最终抛弃。

最终

以上都是一些最简略的入门,许多总结是自己根据实践猜测的,并没有深化原理,还有许多概念不清不楚,因此或许会有许多过错,还请自行甄别。写这个的意图只是为了让自己了解下CI的东西集,并不打算深化。