美文网首页微服务
使用minikube实现微服务的CI/CD

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

作者: 惜鸟 | 来源:发表于2021-03-13 22:52 被阅读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 start:启动一个本地单节点kubernetes集群。
    • --driver=hyperv:指定驱动为hyperv,默认为自动检测(virtualbox, vmwarefusion, hyperv, vmware, docker, ssh)中的一个。
    • --registry-mirror=https://registry.docker-cn.com:使用国内的镜像地址来提高拉取镜像的速度,可以设置多个用,分割即可。
    • --embed-certs=true: 如果为true,将在kubeconfig中嵌入证书,默认为false,在kubeconfig中将以绝对路径的方式读取证书文件。
    • --image-mirror-country=cn:需要使用的镜像的国家/地区代码,留空以使用全球代码,对于中国大陆用户,请将其设置为 cn
    • --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers:设置用来拉取 Kubernetes 集群所需镜像的仓库,如果无法访问gcr.io可以设置为 "auto" 让minikube 为你自动选择可以访问的镜像仓库。对于中国大陆用户可以设置registry.cn-hangzhou.aliyuncs.com/google_containers,但是我设置此参数导致有的镜像无法拉取。

    说明:通过上面的命令启动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的数据,所有创建三个文件:

    • jenkins-pvc.yaml:设置jenkins数据持久化方式。
    • jenkins-rbac.yaml:设置jenkins用户访问权限。
    • jenkins-deploy.yaml:创建jenkins的deployment 和 service。
      jenkins-pvc.yaml文件内容如下:
    ---
    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相关配置

    • 选择 [节点管理] -> [Configure Clouds]


      image.png
    • 安装了kubernetes插件就可看到下图所示,添加一个kubernetes的cloud


      image.png
    • 配置连接k8s的api server


      image.png
    • 创建pod template


      image.png
    • 添加第一个容器 jnlp(jnlp-slave)


      image.png
      image.png
    • 添加第二个容器 docker(因为要在pipeline中构建镜像,需要使用docker客户端,此镜像提供了docker客户端)


      image.png
    • 添加第三个容器 maven (这里使用的镜像为:registry.cn-beijing.aliyuncs.com/acs-sample/jenkins-slave-maven:3.3.9-jdk-8-alpine, 也可以使用自定义的maven镜像)


      image.png
    • pod 模板的数据卷的设置,如下图所示:
      创建docker推送镜像到私用仓库的secret
      命令如下:kubectl create secret generic my-secret --from-file=/root/.docker/config.json

    注意: 这里不是 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
    • [Manage Credentials] -> [jenkins] -> [全局凭据] -> [添加凭据]
      配置访问k8s的kubeconfig,在pipeline中使用kubernetesDeploy的时候会使用到

      image.png
    • [Manage Credentials] -> [jenkins] -> [全局凭据] -> [添加凭据]
      设置登录私有镜像仓库的用户名和密码


      image.png

    五、使用jenkins CI/CD demo演示

    • 新建一个任务 devops-demo


      image.png
    • devops-demo任务配置如下:
      1、指定docker私有仓库地址


      image.png

      2、指定项目名称


      image.png
      3、指定要部署的命名空间
      image.png
      4、选择构建的分支
      image.png

    5、任务流水线配置


    image.png

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

    • 保存配置并构建如下图所示


      image.png
    • 构建成功的效果如下


      image.png

    这里打包阶段用时比较长,那是因为每次构建都需要下载依赖,因为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
    • 持久化maven依赖包,再次构建耗时对比如下:


      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

    相关文章

      网友评论

        本文标题:使用minikube实现微服务的CI/CD

        本文链接:https://www.haomeiwen.com/subject/uhcaqltx.html