k8s CICD流程

Posted wodongshixiaobai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s CICD流程相关的知识,希望对你有一定的参考价值。

 k8s(kubeadm) + Harbor + jenkins + git

实验环境:k8s单节点部署、Harbor、jenkins部署在k8s外部

CICD流程:

1、从github中拉取代码
2、jenkins进行打包、构建docker镜像
3、将镜像push到镜像仓库Harbor中
4、提前编写yaml资源清单
5、jenkins利用kubectl工具对资源进行更新 


一、部署

 1、Harbor镜像仓库部署

# 下载在线安装包
wget https://storage.googleapis.com/harbor-releases/release-1.8.0/harbor-online-installer-v1.8.1.tgz

# 解压安装包
tar zxvf harbor-online-installer-v1.8.1.tgz -C /usr/src/
cd /usr/src/harbor

# 修改配置文件
vim harbor.yml
# 修改本机地址
hostname: 10.0.1.84

# 查看配置文件其他参数,将配置文件改成如下示例
cat harbor.yml |grep -v "^#"|grep -v "  #"|grep -v "^$"

hostname: 10.0.1.84
http:
  port: 18000
harbor_admin_password: Harbor12345
database:
  password: root123
data_volume: /data
clair: 
  updaters_interval: 12
  http_proxy:
  https_proxy:
  no_proxy: 127.0.0.1,localhost,core,registry
jobservice:
  max_job_workers: 10
chart:
  absolute_url: disabled
log:
  level: info
  rotate_count: 50
  rotate_size: 200M
  location: /var/log/harbor
_version: 1.8.0

# 执行
./install.sh

# 出现提示,安装成功
✔ ----Harbor has been installed and started successfully.----

# 默认账户
admin  Harbor12345


# 基本使用
docker pull nginx:latest     # 拉取镜像

docker tag nginx:latest 10.0.1.84/library/nginx      # 给镜像打tag

docker push 10.0.1.84/library/nginx      # 推送镜像

docker pull 10.0.1.84:18000/library/nginx:latest     # 从Harbor镜像仓库拉取镜像

 2、docker部署jenkins

# 需提前部署docker、docker-compose
# docker启动jenkins
docker run \\
  -u root \\
  -d \\
  -p 8080:8080 \\
  -p 50000:50000 \\
  -v /data/docker/jenkins_home:/var/jenkins_home \\
  -v /var/run/docker.sock:/var/run/docker.sock \\
  -v "$HOME":/home \\
  jenkinsci/blueocean

# 初始密码位置
/data/docker/jenkins_home/secrets/initialAdminPassword

3、kubeadm部署k8s

环境:10.0.1.84:master
     10.0.1.83:node
     两个节点需要提前安装docker
     
master和node节点:

1、修改主机名(可不做)
hostnamectl set-hostname kube-master
hostnamectl set-hostname kube-node

2、关闭防火墙、关闭交换分区
swapoff -a  (临时)
或
sed -i '/ swap / s/^\\(.*\\)$/#\\1/g' /etc/fstab

3、部署kubernetes
# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
# cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
# apt-get update
# apt-get install -y kubectl kubeadm kubectl

master节点:

4、初始化master节点(网络插件下面对应)

如果使用 calico 作为网络插件,要给 kubeadm init 带上 --pod-network-cidr=192.168.0.0/16
如果使用 flannel 作为网络插件,要给 kubeadm init 带上 --pod-network-cidr=10.244.0.0/16

# kubeadm init
......
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 10.0.1.84:6443 --token 93wgb0.cktng34w2sif8vqc \\
    --discovery-token-ca-cert-hash sha256:9438180169b6369417e465526d07beaceb3d480a38ad9c5680f3ebfe7f30879f
    
# 根据提示执行
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 记录下来,用来node节点加入集群使用
  kubeadm join 10.0.1.84:6443 --token 93wgb0.cktng34w2sif8vqc \\
    --discovery-token-ca-cert-hash sha256:9438180169b6369417e465526d07beaceb3d480a38ad9c5680f3ebfe7f30879f
 
注意:此时查看master节点状态(kubectl get nodes)会发现STATUS是NotReady,因为还没有安装网络插件

5、网络插件
# Weave Net
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\\n')"
# Flannel(可选)
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# Calico(可选)
kubectl apply -f https://docs.projectcalico.org/v2.0/getting-started/kubernetes/installation/hosted/kubeadm/calico.yaml

# 查看pod状态
kubectl get pods -n kube-system (STATUS都Running)

# 此时在查看master节点状态(kubectl get nodes)STATUS变成了Ready

node节点:
# 加入k8s集群    (如果报错,去掉\\,将命令变成一行)
kubeadm join 10.211.55.86:6443 --token 96we7u.s9fzr0hes09nzh31 \\
    --discovery-token-ca-cert-hash sha256:92bd946186fdfec3080d7570bca4bad6183f8cb19782784d2c855649e2832107


# master节点:
# 查看集群状态
NAME          STATUS   ROLES                  AGE     VERSION
kube-master   Ready    control-plane,master   4d22h   v1.23.1
kube-node     Ready    <none>                 4d22h   v1.23.1

注意:kubectl命令只能在master上执行,如果想在其他node执行
复制master节点下的 ~/.kube/config 到其他node节点

二、jenkins连接k8s

 1、安装插件

kubernetes plugin(如果没有,安装kubernetes插件)

Git Parameter

 2、配置kubernetes plugin插件

 系统管理——>节点管理——>Configure Clouds——>Add a new cloud

# Kubernetes 地址:一般都是master地址+6443
# Kubernetes 证书:
  cat ~/.kube/config

创建 ca.crt、cli.crt、cli.key
# ca.crt
  echo  xxxx(复制上图密钥) | base64 -d > ca.crt
# cli.crt
  echo  xxxx |  base64 -d  > cli.crt
# cli.key
  echo xxxx > | base64 -d > cli.key
# 合并
  openssl pkcs12 -export -out cert.pfx -inkey cli.key -in cli.crt -certfile ca.crt
  Enter Export Password:  <<<------输入密码     注意:密码要记住,创建jenkins凭证有用
  Verifying - Enter Export Password:   <<<------输入密码
# 创建出来的 cert.pfx 留着创建凭据
# 将ca.crt里面的内容复制到 Kubernetes 服务证书 key 中
# 提前创建命名空间namespaces,以kube-ops为例
# 创建凭据,如下图
  添加——>jenkins

# 将 cert.pfx 上传
# 密码输入之前设置的密码
# 凭据创建成功后,进行连接性测试,出现 Connected to Kubernetes v1.23.1 代表成功
# 下方的Jenkins 地址,填写安装的地址

 三、测试

1、创建流水线项目,进入配置,构建分支等等(看具体需要)  

 2、配置jenkins-harbor-creds、jenkins-k8s-config参数

 系统管理——>管理凭据——>添加全局凭据

配置jenkins-harbor-creds 

harbor的用户密码,ID"jenkins-harbor-creds" 必须和jenkinsfile保持一致

 配置jenkins-k8s-config

cp ~/.kube/config /tmp/kube-config.yml

base64 kube-config.yml > kube-config.txt

cat kube-config.txt 将里面的内容复制出来,写到Secret里面,ID"jenkins-k8s-config" 必须和jenkinsfile保持一致

 3、创建流水线,选择Pipeline script

// 需要在jenkins的Credentials设置中配置jenkins-harbor-creds、jenkins-k8s-config参数
 
pipeline 
    agent any
    environment 
        url = "github代码仓库位置"  //8000 8001
		    credentialsId = "github代码凭证"
        HARBOR_CREDS = credentials('jenkins-harbor-creds')
        K8S_CONFIG = credentials('jenkins-k8s-config')
        GIT_TAG = sh(returnStdout: true,script: 'git describe --tags --always').trim()
    
    parameters 
        gitParameter(name: 'BRANCH', type: 'PT_BRANCH', defaultValue: 'main')
        string(name: 'HARBOR_HOST', defaultValue: '10.0.1.84:18000', description: 'harbor仓库地址')
        string(name: 'K8S_NAMESPACE', defaultValue: 'kube-ops', description: 'k8s的namespace名称')
    
    stages 
        stage('Checkout') 
			steps 
				checkout([$class: 'GitSCM',
					branches: [[name: "$params.BRANCH"]],
					doGenerateSubmoduleConfigurations: false,
					extensions: [],
					gitTool: 'Default',
					submoduleCfg: [],
					userRemoteConfigs: [[url: "$url",credentialsId: "$credentialsId"]]
				])
			
		
        stage('Docker Build') 
            agent any
            steps 
                sh "docker login 10.0.1.84:18000 --username admin --password 123456"
                sh "sh debug.sh"
                sh "docker build -t ew -f Dockerfile ."
                sh "docker tag ew:latest 10.0.1.84:18000/jenkins/ew"
                sh "docker push 10.0.1.84:18000/jenkins/ew"
                sh "docker rmi 10.0.1.84:18000/jenkins/ew"
            
            
        
        stage('Deploy') 
            when  
                allOf 
                    expression  env.GIT_TAG != null 
                
            
            agent 
                docker 
                    image 'lwolf/helm-kubectl-docker'
                
            
            steps 
                sh "rm -rf ~/.kube && mkdir ~/.kube"
                sh "echo $K8S_CONFIG | base64 -d > ~/.kube/config"
                sh "kubectl apply -f deployment.yaml -n $K8S_NAMESPACE"   # 根据业务提前编写deployment.yaml
            
            
        
        
    

4、根据业务编写yaml资源清单

apiVersion: apps/v1      #指定api版本标签
kind: Deployment            #定义资源的类型/角色,deployment为控制器
metadata:                  #定义资源的元数据信息
  name: ew-test        #定义资源的名称,在同一个namespace空间中必须是唯一的
  namespaces: kube-ops
  labels:                 #定义资源标签
    app: ew
spec:
  replicas: 1          #定义副本数量
  selector:                #定义选择器
    matchLabels:           #匹配上面的标签
      app: ew           #匹配模板名称
  template:                #定义模板
    metadata:
      labels:
        app: ew
    spec:
      containers:                #定义容器信息
      - name: ew-test
        image: 10.0.1.84:18000/jenkins/ew
        imagePullPolicy: IfNotPresent      #容器使用的镜像以及版本
        ports:
        - name: httpport
          containerPort: 8000
        - name: wsport
          containerPort: 8001         #定义容器的对外端口



---
apiVersion: v1
kind: Service
metadata:
  name: ew-service
  labels:
    app: ew
spec:
  type: NodePort
  ports:
  - name: httpport
    port: 8086
    targetPort: 8000
    nodePort: 32301
  - name: wsport
    port: 8087
    targetPort: 8001
    nodePort: 32302
  selector:
    app: ew

service port问题

# 端口问题:
  targetPort:pod端口
  port:service端口
  nodePort:节点端口
  port映射到targetPort
  访问:10.0.1.83:32301
  集群内访问:虚拟ip:service port

5、build测试 

 登录Harbor仓库查看

可以看到镜像成功被push到仓库中

 kubernetes查看

 # kubectl get pods --all-namespaces -owide
  可以看到在node节点创建了该pod

# kubectl get svc --all-namespaces -owide
  service也创建出来了

# kubectl get deployment --all-namespaces -owide
  可以看到镜像是从Harbor仓库中拉取下来的

 网页测试访问

10.0.1.84:32301

10.0.1.84:32302

四、kubectl基础命令 

# 查看所有命名空间
  kubectl get namespaces
# 创建命名空间
  kubectl create namespaces xxx
# 查看命名空间下的pod
  kubectl get pods -n xxx
# 查看所有pod信息(创建在那个节点、节点ip等)
  kubectl get pods --all-namespaces -owide
# 查看deployment资源
  kubectl get deployment --all-namespaces -owide
# 查看service信息
  kubectl get svc --all-namespaces -owide
# 查看describe详细信息
  kubectl describe pod pod名字 -n namespace
# 利用资源清单创建/删除pod
  kubectl apply -f xxx.yaml
  kubectl delete -f xxx.yaml
# 删除pod
  kubectl delete pod pod名字 -n namespace
# 进入pod
  kubectl exec -it  pod名字 -n namespace -- /bin/bash (bash不行就用sh)

 五、问题总结

Harbor相关问题: 

1、docker login 连接不上Harbor

报错信息;

Error response from daemon: Get https://10.0.1.84:18000/v2/: 
dial tcp 10.0.1.84:18000: connect: connection refused

问题原因:不支持https

解决:

# vim /etc/docker/daemon.json

"insecure-registries": ["10.0.1.84:18000"]

# systemctl daemon-reload
# systemctl restart docker

pod创建在其他节点,需要用到Harbor都要有daemon.json

k8s相关问题: 

1、init初始化不成功

报错信息:

failed to create kubelet: misconfiguration: kubelet cgroup driver: "cgroupfs" is different from docker cgroup driver: "systemd"

问题原因:kubelet和docker驱动不一致

解决:

驱动有两种:systemd和cgroupfs
# 查看docker驱动
  docker info
  查看Cgroup Driver: 类型 (我的是cgroupfs)
# 修改成systemd

  "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]

systemctl daemon-reload
systemctl restart docker

以上是关于k8s CICD流程的主要内容,如果未能解决你的问题,请参考以下文章

基于k8s构建企业jenkins CICD

基于K8s Jenkins CICD和RBAC角色权限控制

第四十四章 微服务CICD- gitlab + jenkins + docker + k8s

cicd与devops区别是啥?

DEVOPS架构师 -- 06基于sharedLibrary进行CICD流程的优化

如何搭建自己的CI/CD平台:Gitlab+Jenkins+Docker+Harbor+K8s集群搭建CICD平台(持续集成部署Hexo博客Demo)