基于k8s搭建maven nexus私服

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lusyoe/article/details/79946951

前言

最近一段时间对k8s非常感兴趣,恨不得将所有东西都搬上去,这个周末就尝试着把家里的nexus私服给迁移上去啦。

环境

  • kubernetes 1.5.2
  • docker 1.13.1
  • nexus 3.9.0-01

这里环境搭建就不多说了,nexus直接从官网下载就好了。

配置nexus

从官网下载了nexus之后还需要进行一些配置。
编辑bin/nexus.vmoptions 调整后的如下:

-Xms600M
-Xmx800M
-XX:MaxDirectMemorySize=1G
-XX:+UnlockDiagnosticVMOptions
-XX:+UnsyncloadClass
-XX:+LogVMOutput 
-XX:LogFile=/data/maven-nexus/log/jvm.log
-XX:-OmitStackTraceInFastThrow
-Djava.net.preferIPv4Stack=true
-Dkaraf.home=.
-Dkaraf.base=.
-Dkaraf.etc=etc/karaf
-Djava.util.logging.config.file=etc/karaf/java.util.logging.properties
-Dkaraf.data=/data/maven-nexus/data
-Djava.io.tmpdir=/data/maven-nexus/tmp
-Dkaraf.startLocalConsole=false

其中除了1,2行的jvm内存配置之外,最关键的就是,以下几个属性配置:

-XX:LogFile=/data/maven-nexus/log/jvm.log   # 日志文件生成位置
-Dkaraf.data=/data/maven-nexus/data         # 仓库数据存放位置(上传的jar包)
-Djava.io.tmpdir=/data/maven-nexus/tmp      # 临时文件存放位置

这几个参数不能错了。为了防止容器重启数据丢失,我们需要挂载主机的卷空间,这几个路径都是映射放在宿主主机上的。

制作Docker镜像

配置好nexus之后,我们需要再制作自己的docker镜像啦,因为k8s就是调度镜像容器的嘛。
docker镜像的制作也很简单,新建一个Dockerfile文件只需要添加以下3行就够了:

FROM registry.cn-hangzhou.aliyuncs.com/luhaoyuan/oracle-jdk8:latest

ADD nexus-3.9.0-01-my.tar.gz /opt

ENTRYPOINT ["/opt/nexus-3.9.0-01/bin/nexus", "run"]

第一行:nexus的运行是依赖JDK环境的,所以我们这里就使用jdk作为基础镜像;
第二行:将我们配置过后的nexus再重新打包一下,添加到容器中;
第三行:启动容器时,执行的命令,nexus的启动命令有startrun,由于start默认是启动在后台进程的,这样容器一启动就退出了。所以这里必须要使用run命令启动了。

最后构建我们的Docker镜像吧,执行以下命令:
docker build -t e5:8889/tools/nexus:latest .

配置k8s PV-PVC

我们刚前面说了,为了避免容器重启数据丢失,我们需要挂载主机的卷空间。
在k8s中,pod挂载主机的存储卷,就需要使用到了PV(PersistentVolume)和PVC(PersistentVolumeClaim)。
这里就不过多介绍概念性的东西了,直奔主题了哈,新建nexus-pv-pvc.yaml文件:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nexus3-data-pv
  labels:
    app: nexus3-data-pv
spec:
  capacity:
    storage: 500Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  hostPath:
    path: /data/maven-nexus

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nexus3-data-pvc
  labels:
    app: nexus3-data-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Gi
  selector:
    matchLabels:
      app: nexus3-data-pv

这里说一个重要的地方,PV中的hostPath,指定了宿主主机上的挂载路径。

配置k8s Deployment

在k8s早期更多的是使用ReplicationController (RC)来控制保障pod,不过后来又出现了Deployment
Deployment不仅包含了RC的所有功能,还具有:版本记录、回滚、暂停和启动等多种额外的强大功能。
所以我们后面可以尽量都使用Deployment啦。
废话不多说,直接上配置,新建nexus-deployment.yaml文件:

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  labels:
    app: nexus3
  name: nexus3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nexus3
  template:
    metadata:
      labels:
        app: nexus3
    spec:
      containers:
        - name: nexus3
          image: e5:8889/tools/nexus:latest
          imagePullPolicy: IfNotPresent
          ports:
          - containerPort: 8081
            protocol: TCP
          volumeMounts:
          - name: nexus-data
            mountPath: /data/maven-nexus
      volumes:
        - name: nexus-data
          persistentVolumeClaim:
            claimName: nexus3-data-pvc
      nodeSelector:
        kubernetes.io/hostname: e5

配置较为简单,这里说一下关键地方吧,我们是在volumes结点上引用之前创建的PVC:

volumes:
  - name: nexus-data
    persistentVolumeClaim:
      claimName: nexus3-data-pvc

volumeMounts结点上,配置了挂载到容器中的路径:

volumeMounts:
   - name: nexus-data
     mountPath: /data/maven-nexus

最后的nodeSelector表示pod只在某个主机上运行。

配置k8s Service

我们知道k8s中的pod的访问是不可靠的,随时可能发生pod停止-漂移-创建的过程。
所以要想能够稳定的访问,就必须要创建Service进行服务发现了,在Service中是根据selector来寻找pod的。
最后k8s上的Service只能在集群节点上访问,如果我们想要在集群外部进行访问的话,只有三种方式:NodePort、LoadBalancer、Ingress。
这里我们就使用NodePort,绑定宿主机的端口来进行暴露服务吧。跟docker run -p 看上去效果相似。
废话不多说了,直接上配置,新建nexus-svc.yaml文件:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nexus3
  name: nexus3
spec:
  type: NodePort
  ports:
  - port: 8081
    targetPort: 8081
    nodePort: 8081
    name: web-ui
  - port: 5000
    targetPort: 5000
    nodePort: 5000
    name: docker-group
  - port: 8889
    targetPort: 8889
    nodePort: 8889
    name: docker-push
  selector:
    app: nexus3

其中关键的地方就是spec.type节点配置NodePort类型了。
再说明下的ports 端口的配置:

  • port 属性定义了Service的虚端口;
  • targetPort 属性指定了后面pod上提供的端口,如果没有指定则默认与port相同(这里我们显视的指定了);
  • nodePort 属性指定了绑定在宿主机上的端口号,我们可以通过宿主机IP + 端口的形式就可以访问到后方pod中的服务啦。
  • name 如果有多个port配置的话,必须要为每个port指定一个名称。

k8s部署访问

经过编写上面的一堆配置,我们要到验收成果的时候啦。

创建 PV-PVC

首先根据配置文件,创建PV-PVC:
kubectl create -f nexus-pv-pvc.yaml
创建完成后,查看一下状态,是否正常:
kubectl get pv

NAME             CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS    CLAIM 
nexus3-data-pv   500Gi      RWO           Recycle         Bound     default/nexus3-data-pvc

查看到STATUS状态字段为Bound,则表示创建成功啦。

创建Deployment

继续创建Deployment,创建完后会自动创建pod的,并维护pod数量始终为1。
kubectl create -f nexus-deployment.yaml
稍等几秒钟,查看pod状态:
kubectl get pod

NAME                            READY     STATUS    RESTARTS
nexus3-3942485411-0hc6j         1/1       Running   0

查看到STATUS状态字段为Running,则表示运行成功啦。

创建Service

还有最后一步,我们就可以访问到nexus啦
创建Service,暴露服务:

kubectl create -f nexus-svc.yaml

老规则,创建完后,看下状态:
kubectl get svc

NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)        
nexus3         10.254.99.100   <nodes>       8081:8081/TCP,5000:5000/TCP,8889:8889/TCP

OK,一切正常,开始访问吧,注意这里的访问,是访问宿主机的IP+端口,至于CLUSTER-IP这些都是虚拟的IP,无法在外部进行访问的。

访问Nexus

http://192.168.1.2:8081
nexus
nexus-repo

最后看下私服上传下载 jar包、docker镜像什么都是正常的就OK啦。

升级

这里再额外补充点内容,由于nexus3更新算是比较频繁的,我们如何无缝升级呢?
这里就借用k8s Deployment的升级方式就好了。

  • 第一步:从官网下载最新的nexus安装包;
  • 第二步:修改nexus配置文件,将上面旧版本的配置覆盖过来就行了;
  • 第三步:修改Dockerfile文件,构建新的Docker镜像,将新打包的nexus放入镜像中。
    如:docker build -t e5:8889/tools/nexus:v3.10 .
    Ps: 不要忘记启动命令路径也要调整哟
  • 第四步:使用k8s命令升级Deployment:
    如:kubectl set image deployment/nexus3 nexus3=e5:8889/tools/nexus:v3.10
  • 第五步:回滚升级,如果发现升级了的不好用,或者出现问题,也可以回滚哦:
    如:kubectl rollout undo deployment/nexus3

访问一下:
nexus-new

搞定收工~

后续

其实这个过程中里复杂了一部分,也简化了一部分。
复杂了pv-pvc过程,pv-pvc不用创建直接在Deployment中挂载hostPath也是可以的。
这里只是为了将学习到的东西进行了实践,感觉还是挺好的。
简化了Deployment,这里其实应该还需要加上cpu、内存等资源限制的。
这里只是在nexus配置文件中做了限制,如果出现内存泄漏问题,还是没办法解决的。

最最后,学习到的东西一定要经过实践,总结,写blog,这样才能更好的消化:)

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页