最近一段时间对k8s非常感兴趣,恨不得将所有东西都搬上去,这个周末就尝试着把家里的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 # 临时文件存放位置
这几个参数不能错了。为了防止容器重启数据丢失,我们需要挂载主机的卷空间,这几个路径都是映射放在宿主主机上的。
配置好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的启动命令有start
和run
,由于start
默认是启动在后台进程的,这样容器一启动就退出了。所以这里必须要使用run命令启动了。
最后构建我们的Docker镜像吧,执行以下命令:
docker build -t e5:8889/tools/nexus:latest .
我们刚前面说了,为了避免容器重启数据丢失,我们需要挂载主机的卷空间。
在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早期更多的是使用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中的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 端口的配置:
经过编写上面的一堆配置,我们要到验收成果的时候啦。
首先根据配置文件,创建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,创建完后会自动创建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,则表示运行成功啦。
还有最后一步,我们就可以访问到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,无法在外部进行访问的。
最后看下私服上传下载 jar包、docker镜像什么都是正常的就OK啦。
这里再额外补充点内容,由于nexus3更新算是比较频繁的,我们如何无缝升级呢?
这里就借用k8s Deployment的升级方式就好了。
Dockerfile
文件,构建新的Docker镜像,将新打包的nexus放入镜像中。 docker build -t e5:8889/tools/nexus:v3.10 .
kubectl set image deployment/nexus3 nexus3=e5:8889/tools/nexus:v3.10
kubectl rollout undo deployment/nexus3
搞定收工~
其实这个过程中里复杂了一部分,也简化了一部分。
复杂了pv-pvc过程,pv-pvc不用创建直接在Deployment中挂载hostPath也是可以的。
这里只是为了将学习到的东西进行了实践,感觉还是挺好的。
简化了Deployment,这里其实应该还需要加上cpu、内存等资源限制的。
这里只是在nexus配置文件中做了限制,如果出现内存泄漏问题,还是没办法解决的。
最最后,学习到的东西一定要经过实践,总结,写blog,这样才能更好的消化:)