微服务

使用minikube实现微服务的CI/CD

2021-03-13  本文已影响0人  惜鸟

一、概述

最近在研究基于k8s实现一套devops流程,由于搭建一套k8s集群比较麻烦,所有打算使用minikube在我本地的windows上面实现整套devops流程,在这里记录一下整个实践过程,希望对需要的同学提供一些参考,也便于自己以后查阅。

minikube官方地址:https://minikube.sigs.k8s.io/docs/start/

运行环境

windows 10
minikube 1.18.1
kubernetes 1.20.2

二、安装minikube

minikube是本地的Kubernetes,致力于使Kubernetes易于学习和开发。
你需要的只是Docker(或类似兼容)容器或虚拟机环境,只需一个命令即可: minikube start即可在本地启动一个kubernetes集群。

1. 运行minikube的条件

说明:minikube 提供了跨平台搭建k8s的能力,支持mac ,linux ,windows平台,每一个平台上也支持多种驱动架构,windows 支持docker,Hyper-V,virtualBox等,由于win10已经内置了Hyper-V,这里选择Hyper-V。

2. 在windows中开启Hyper-V

Hyper-V是内置于现代Microsoft Windows版本中的本机虚拟机管理程序,需要是Windows 10企业版,专业版或教育版的64位版本系统才能开启,我这里使用的是windows 10 专业版系统,通过如下方式开启Hyper-V。

image.png
以管理员身份打开PowerShell控制台,然后运行以下命令:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

如果Hyper-V先前未处于活动状态,则需要重新启动。我这里已经开启了,所以如下图所示,显示online ,并且不需要重新。


image.png

3. 下载minikube

下载并运行Windows安装程序

image.png
安装完成后,搜索cmd并以管理员身份打开
image.png

4. 启动minikube

使用如下命令启动minikube会导致有的镜像无法拉取,接着往下面看成功的运行命令

minikube start --driver=hyperv --registry-mirror=https://registry.docker-cn.com,https://shraym0v.mirror.aliyuncs.com --embed-certs=true --image-mirror-country=cn --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers

参数说明
可以通过minikube start --help查看其它参数的详细说明,这里说明上面使用的参数

说明:通过上面的命令启动minikube,会出现有的镜像无法拉取的问题,也就是说registry.cn-hangzhou.aliyuncs.com/google_containers镜像仓库很多镜像不存在,经过不断的测试,使用如下命令就可以正常启动并拉取镜像,所有我们不需要设置这两个参数:--image-mirror-country=cn--image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers

成功启动minikube的命令如下:

minikube start --driver=hyperv --registry-mirror=https://registry.docker-cn.com,https://shraym0v.mirror.aliyuncs.com --embed-certs=true

5. 验证minikube

使用如下命令查看minikube的状态

C:\WINDOWS\system32>minikube status
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
timeToStop: Nonexistent
# 这里会自动下载kubectl工具
C:\WINDOWS\system32>minikube kubectl get node
NAME       STATUS   ROLES                  AGE   VERSION
minikube   Ready    control-plane,master   11m   v1.20.2

部署一个nginx,快速体验minikube

C:\WINDOWS\system32>kubectl create deployment nginx --image=nginx
deployment.apps/nginx created

C:\WINDOWS\system32>kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-6799fc88d8-z7xzh   1/1     Running   0          33s

C:\WINDOWS\system32>kubectl expose deployment nginx --type=NodePort --port=80
service/nginx exposed

C:\WINDOWS\system32>minikube service nginx
|-----------|-------|-------------|----------------------------|
| NAMESPACE | NAME  | TARGET PORT |            URL             |
|-----------|-------|-------------|----------------------------|
| default   | nginx |          80 | http://172.23.130.60:31593 |
|-----------|-------|-------------|----------------------------|
* 正通过默认浏览器打开服务 default/nginx...

C:\WINDOWS\system32>

会自动打开默认浏览器,如下图所示:


image.png

使用如下命令启动k8s的dashboard

C:\WINDOWS\system32>minikube dashboard
* 正在开启 dashboard ...
  - Using image kubernetesui/dashboard:v2.1.0
  - Using image kubernetesui/metrics-scraper:v1.0.4
* 正在验证 dashboard 运行情况 ...
* Launching proxy ...
* 正在验证 proxy 运行状况 ...
* Opening http://127.0.0.1:61589/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/ in your default browser...

如下图所示:


image.png

三、安装jenkins

我这里使用yaml的方式部署jenkins,并且创建pv和pvc来持久化jenkins的数据,所有创建三个文件:

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: jenkins-pvc
  namespace: devops
spec:
  accessModes:
  - ReadWriteMany
  # 如果集群中有一个默认的storageClass能满足需求,这里可以不用配置storageClass
  storageClassName: standard
  resources:
    requests:
      storage: 5Gi

说明:因为使用minikube创建的k8s集群默认已经创建了一个基于hostpathstorageClass,通过如下命令查看

C:\windows\system32>kubectl get sc
NAME                 PROVISIONER                RECLAIMPOLICY   VOLUMEBINDINGMODE   >ALLOWVOLUMEEXPANSION   AGE
standard (default)   k8s.io/minikube-hostpath   Delete          Immediate           false                  98m

storageClass会自动创建pv,并将pv和pvc进行绑定,所以我们无需自己创建pv。

jenkins-rbac.yaml文件内容如下:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins-sa
  namespace: devops

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: jenkins-cr
rules:
  - apiGroups: ["extensions", "apps"]
    resources: ["deployments"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get","list","watch"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: jenkins-crd
roleRef:
  kind: ClusterRole
  name: jenkins-cr
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: jenkins-sa
  namespace: devops

jenkins-deploy.yaml文件内容如下:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  namespace: devops 
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      terminationGracePeriodSeconds: 10
      serviceAccount: jenkins-sa
      containers:
      - name: jenkins
        image: jenkins/jenkins:latest
        imagePullPolicy: IfNotPresent
        env:
        - name: JAVA_OPTS
          value: -Duser.timezone=Asia/Shanghai
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        - containerPort: 50000
          name: agent
          protocol: TCP
        resources:
          limits:
            cpu: 1000m
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        readinessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        volumeMounts:
          - name: jenkinshome
            mountPath: /var/jenkins_home
      volumes:
        - name: jenkinshome
          persistentVolumeClaim:
            claimName: jenkins-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: jenkins
  namespace: devops 
  labels:
    app: jenkins
spec:
  selector:
    app: jenkins
  type: NodePort
  ports:
  - name: web
    port: 8080
    targetPort: web
    
    
---
apiVersion: v1
kind: Service
metadata:
  name: jenkins-agent
  namespace: devops 
  labels:
    app: jenkins
spec:
  selector:
    app: jenkins
  type: ClusterIP
  ports:
  - name: agent
    port: 50000
    targetPort: agent

使用下面的命令部署jenkins

  1. 创建devops命名空间
C:\WINDOWS\system32>kubectl create namespace devops
namespace/devops created
  1. 执行下面的命令启动jenkins
kubectl apply -f jenkins-pvc.yaml
kubectl apply -f jenkins-rbac.yaml
kubectl apply -f jenkins-deploy.yaml
  1. 使用minikube service命令提供浏览器访问地址
C:\WINDOWS\system32>minikube service jenkins -n devops
|-----------|---------|-------------|----------------------------|
| NAMESPACE |  NAME   | TARGET PORT |            URL             |
|-----------|---------|-------------|----------------------------|
| devops    | jenkins | web/8080    | http://172.23.130.60:30002 |
|-----------|---------|-------------|----------------------------|
* 正通过默认浏览器打开服务 devops/jenkins...
image.png
  1. 使用如下命令查看登录jenkins的初始密码
C:\WINDOWS\system32>kubectl get pod -n devops
NAME                       READY   STATUS    RESTARTS   AGE
jenkins-6bb66dcf88-2c4tv   1/1     Running   0          9m59s

C:\WINDOWS\system32>kubectl logs -f jenkins-6bb66dcf88-2c4tv -n devops

查看jenkins初始密码如下图:


image.png

选择自定义插件安装,因为回去官网下载插件,下载比较慢,而且很多插件我们不需要


image.png
取消推荐插件的选择
image.png

创建一个管理员账号


image.png
开始使用jenkins
image.png

Jenkins下载插件设置国内源

image.png

安装如下插件


image.png

四、在jenkins中配置k8s实现CI/CD

1. k8s相关配置

注意: 这里不是 kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
这里遇到一个问题,docker 无法推送镜像,报错显示docker没有登录私有仓库,查询原因发现因为我使用docker-registry创建了my-secret,当我改为generic就可以了,详细信息可以查看k8s的secret说明文档。

image.png

五、使用jenkins CI/CD demo演示

5、任务流水线配置


image.png

说明: 这里使用的仓库代码示例地址如下:https://gitee.com/peterwd/devops-demo.git
在仓库中需要添加三个文件才能实现此devops流程:Jenkinsfile、Dockerfile、deployment.yaml
文件的内容可以点击到仓库中查看。

这里打包阶段用时比较长,那是因为每次构建都需要下载依赖,因为slave运行完成就会被销毁,默认下载的依赖就在slave容器中,会随着slave容器的销毁而消失,所以我们应该把下载的依赖持久化下来,下面介绍如何实现:
1、将下载的依赖持久化到宿主机,使用如下方式配置:
在maven容器中,默认将依赖包放在/root/.m2/repository目录下面,所以我们可以将宿主机的指定目录挂载到此目录中:

image.png
再次构建可以通过如下方式登录到宿主机查看下载的依赖已经持久化到宿主机对应的目录中:
# 登录到minikube节点中
C:\windows\system32>minikube ssh
                         _             _
            _         _ ( )           ( )
  ___ ___  (_)  ___  (_)| |/')  _   _ | |_      __
/' _ ` _ `\| |/' _ `\| || , <  ( ) ( )| '_`\  /'__`\
| ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )(  ___/
(_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____)

$ cd /tmp/maven/repository/
$ ls -al
total 0
drwxr-xr-x 16 root root 320 Mar 15 10:25 .
drwxr-xr-x  3 root root  60 Mar 15 10:21 ..
drwxr-xr-x  3 root root  60 Mar 15 10:24 backport-util-concurrent
drwxr-xr-x  3 root root  60 Mar 15 10:22 ch
drwxr-xr-x  3 root root  60 Mar 15 10:23 classworlds
drwxr-xr-x  5 root root 100 Mar 15 10:24 com
drwxr-xr-x  3 root root  60 Mar 15 10:23 commons-cli
drwxr-xr-x  3 root root  60 Mar 15 10:25 commons-codec
drwxr-xr-x  3 root root  60 Mar 15 10:25 commons-lang
drwxr-xr-x  4 root root  80 Mar 15 10:25 commons-logging
drwxr-xr-x  8 root root 160 Mar 15 10:22 io
drwxr-xr-x  3 root root  60 Mar 15 10:22 jakarta
drwxr-xr-x  3 root root  60 Mar 15 10:23 junit
drwxr-xr-x  3 root root  60 Mar 15 10:24 log4j
drwxr-xr-x  3 root root  60 Mar 15 10:25 net
drwxr-xr-x 13 root root 260 Mar 15 10:23 org
$

2、使用pvc 持久化mave的依赖包,进行如下图所示配置:


image.png

遇到的问题

1. minikube启动失败

* 正在 Docker 20.10.3 中准备 Kubernetes v1.20.2…| E0313 13:19:52.379165   33644 start.go:99] Unable to get host IP: No virtual switch found
X Exiting due to GUEST_START: Failed to setup kubeconfig: No virtual switch found

如下图所示:

image.png
出现错误的原因
第一次由于电脑内存不足导致安装失败,再次启动minikube时报出此错误。
解决方式
执行如下命令,删除所有minikube集群,再重新启动即可恢复正常:
minikube delete --all

2. jenkins插件下载失败

部分插件由于缺少依赖无法加载。要恢复这些插件提供的功能,需要修复这些问题并重启 Jenkins。
Dependency errors:
SSH Credentials Plugin (1.18.2)
Jenkins (2.282) or higher required
由于一个或者多个上面的错误导致这些插件无法加载。修复后插件将会再次加载。

image.png
解决方式
升级jenkins版本为提示的版本,可以直接修改jenkins-deploy.yaml文件中的image: jenkins/jenkins:latestimage: jenkins/jenkins:2.283

参考文章
minikube快速搭建k8s
kubernetes中部署Jenkins并简单使用
Jenkins 和 Kubernetes -云上的神秘代理
k8s学习笔记之StorageClass+NFS

上一篇下一篇

猜你喜欢

热点阅读