基于k8s 动态配置及扩容maven nexus私服

配置nexus

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-Xms600M
-Xmx600M
-XX:MaxDirectMemorySize=1G
-XX:+UnlockDiagnosticVMOptions
-XX:+UnsyncloadClass
-XX:+LogVMOutput
-XX:LogFile=/data/docker/soft/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/docker/soft/nexus/data
-Djava.io.tmpdir=/data/docker/soft/nexus/tmp
-Dkaraf.startLocalConsole=false

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

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

制作Docker镜像

配置好nexus之后,需要再制作自己的docker镜像,因为k8s就是调度镜像容器的。

1
2
3
4
5
6
7
8
9
[root@master nexus]# pwd
/data/docker/dockerfile/nexus
[root@master nexus]# ls -lth
total 223M
-rw-r--r-- 1 root root 146 Jun 21 16:06 Dockerfile
-rw-r--r-- 1 root root 108M Jun 21 16:02 nexus3.tar.gz
drwxr-xr-x 3 root root 4.0K Jun 21 15:53 sonatype-work
drwxr-xr-x 9 root root 4.0K Jun 21 15:53 nexus-3.12.1-01
-rw-r--r-- 1 root root 115M Jun 21 15:36 nexus-3.12.1-01-unix.tar.gz.org

docker镜像的制作很简单,新建一个Dockerfile文件:

1
2
3
4
5
6
[root@master nexus]# cat Dockerfile 
FROM registry.cn-hangzhou.aliyuncs.com/luhaoyuan/oracle-jdk8:latest

ADD nexus3.tar.gz /opt

ENTRYPOINT ["/opt/nexus-3.12.1-01/bin/nexus", "run"]
  • 第一行:nexus的运行是依赖JDK环境的,所以我们这里就使用jdk作为基础镜像;(镜像是基于centos7,比较大,后续可以考虑修改为alpine_3.6)
  • 第二行:将我们配置过后的nexus(nexus-3.12.1-01)再重新打包一下,添加到容器中;
  • 第三行:启动容器时,执行的命令,nexus的启动命令有start和run,由于start默认是启动在后台进程的,这样容器一启动就退出了。所以这里必须要使用run命令启动了。

最后构建Docker镜像:
docker build -t registry.martin.com:5000/tools/nexus:3.12.1 .
registry.martin.com:5000为我registry地址,构建之后将改image push到私库,当然也可以用harbor
如果有做ca校验,需要将证书拷贝到指定的:/etc/docker/certs.d/xxx/ca.crt,然后docker login校验
再docker push registry.martin.com:5000/tools/nexus:3.12.1,不然会提示x509认证失败

配置k8s PV-PVC

为了避免容器重启数据丢失,需要挂载主机的卷空间。
在k8s中,pod挂载主机的存储卷,就需要使用到了PV(PersistentVolume)和PVC(PersistentVolumeClaim)。
新建nexus3-pv-pvc.yaml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[root@master nexus]# pwd
/data/k8s/nexus
[root@master nexus]# ls -lth
total 12K
-rw-r--r-- 1 root root 777 Jun 21 18:49 nexus3-deployment.yaml
-rw-r--r-- 1 root root 370 Jun 21 17:12 nexus3-service.yaml
-rw-r--r-- 1 root root 525 Jun 21 16:49 nexus3-pv-pvc.yaml
[root@master nexus]# cat nexus3-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/docker/soft/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
[root@master nexus]#

==注意:PV中的hostPath,指定了宿主主机上的挂载路径(node节点最好全部先创建好)==

配置k8s Deployment

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[root@master nexus]# cat nexus3-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: registry.martin.com:5000/tools/nexus:3.12.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9193
protocol: TCP
volumeMounts:
- name: nexus-data
mountPath: /data/docker/soft/nexus
volumes:
- name: nexus-data
persistentVolumeClaim:
claimName: nexus3-data-pvc
nodeSelector:
kubernetes.io/hostname: 192.168.0.15

需要在volumes结点上引用之前创建的PVC:

1
2
3
4
volumes:
- name: nexus-data
persistentVolumeClaim:
claimName: nexus3-data-pvc

在volumeMounts结点上,配置了挂载到容器中的路径:/data/docker/soft/nexus(node节点最好全部先创建好)

1
2
3
volumeMounts:
- name: nexus-data
mountPath: /data/docker/soft/nexus

最后的nodeSelector表示pod只在某个主机上运行,可以通过在k8s的master上使用:kubectl get nodes查看

配置k8s Service

k8s中的pod的访问是不可靠的,随时可能发生pod停止-漂移-创建的过程。
所以要想能够稳定的访问,就必须要创建Service进行服务发现了,在Service中是根据selector来寻找pod的。
最后k8s上的Service只能在集群节点上访问,如果我们想要在集群外部进行访问的话,只有三种方式:

  • NodePort、
  • LoadBalancer、
  • Ingress。

这里使用NodePort,绑定宿主机的端口来进行暴露服务。跟docker run -p 看上去效果相似。
新建nexus3-service.yaml文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@master nexus]# cat nexus3-service.yaml 
apiVersion: v1
kind: Service
metadata:
labels:
app: nexus3
name: nexus3
spec:
type: NodePort
ports:
- port: 8081
targetPort: 8081
nodePort: 30031
name: web-ui
selector:
app: nexus3
[root@master nexus]#

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

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

k8s部署访问

创建 PV-PVC

根据配置文件,创建PV-PVC:

kubectl create -f nexus3-pv-pvc.yaml

创建完成后,查看一下状态,是否正常:

kubectl get pv

1
2
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                     STORAGECLASS   REASON    AGE
nexus3-data-pv 500Gi RWO Recycle Bound default/nexus3-data-pvc 17h

创建Deployment

继续创建Deployment,创建完后会自动创建pod的,并维护pod数量始终为1。

kubectl create -f nexus3-deployment.yaml

稍等几秒钟,查看pod状态:

kubectl get pod -o wide

1
2
NAME                      READY     STATUS    RESTARTS   AGE       IP           NODE
nexus3-68f55d9746-vfnf8 1/1 Running 0 12h 10.20.7.12 192.168.0.15

==注意:默认不用-n指定namespace的都是用的default,-o wide可以看到详细的IP及node信息==

创建Service

创建Service,暴露服务:

1
kubectl create -f nexus3-service.yaml

查看状态:

1
2
3
4
5
 kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.10.0.1 <none> 443/TCP 13d
nexus3 NodePort 10.10.165.3 <none> 8081:30031/TCP,5000:30032/TCP,8889:30033/TCP 12h
nginx-service ClusterIP 10.10.147.216 <none> 80/TCP 10d

==注意这里的访问,是访问宿主机的IP+端口,至于CLUSTER-IP这些都是虚拟的IP,无法在外部进行访问的==。

访问Nexus

http://192.168.1.2:30031 (pod内container端口为:8081)

升级

借用k8s Deployment的升级方式:

  1. 从官网下载最新的nexus安装包;
  2. 修改nexus配置文件,将上面旧版本的配置覆盖过来就行了;
  3. 修改Dockerfile文件,构建新的Docker镜像,将新打包的nexus放入镜像中。
    如:docker build -t registry.martin.com:5000/tools/nexus:3.12.2 .
    Ps: 不要忘记启动命令路径也要调整!
  4. 使用k8s命令升级Deployment:
    如:kubectl set image deployment/nexus3 nexus3=registry.martin.com:5000/tools/nexus:3.12.2
  5. 回滚升级,如果发现升级了的不好用,或者出现问题,也可以回滚:
    如:kubectl rollout undo deployment/nexus3

总结

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