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/initialAdminPassword3、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 </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 4d22h v1.23.1
注意:kubectl命令只能在master上执行,如果想在其他node执行
复制master节点下的 ~/.kube/config 到其他node节点
二、jenkins连接k8s1、安装插件
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-credsharbor的用户密码,ID"jenkins-harbor-creds" 必须和jenkinsfile保持一致
配置jenkins-k8s-config3、创建流水线,选择Pipeline scriptcp ~/.kube/config /tmp/kube-config.yml
base64 kube-config.yml > kube-config.txt
cat kube-config.txt 将里面的内容复制出来,写到Secret里面,ID"jenkins-k8s-config" 必须和jenkinsfile保持一致
// 需要在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 dockerpod创建在其他节点,需要用到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



