lihy0 2017-12-30
目的:学习、实践K8S
各组件介绍:
1. git 无
2. Harbor当镜像仓库,如果你的k8s master slave在一台机器上则不用搭建
3. jenkins 做CI CD,从GIT拉取代码,打包,生成docker镜像、推送Harbor仓库,然后deploy服务到k8s
4. consul 用来做服务发现注册中心和配置中心
5. springcloud 做2个demo ,一个product 服务端,一个 cust 消费端,保证能动态扩展
最后,将部署到k8s环境中,有dev、test2套环境,用户最终通过 traefik做LB
如果单个来看,都很简单。关键是和K8S结合,感受K8S之美,第3条也是这次研究的目的。
我的设计思路:
1. springcloud 工程存放2个 yaml 文件,一份是deployment,一份service
将namespace、image用占位符填充(后面 在jenkins里面的shell中替换)
这里说明下args 里面为何写了2个参数,我的预期设计是这样的:
一般公司会架设一个DNS服务器,开发的同学连consul的时候是 dev.consul.com
但是部署到K8S后,dev.consul.com在pod里面是无法访问的,pod里面应该访问的serviceName
当然你可以把serviceName都写一样,但是并不好。所以利用args进行了一次重写,这种传参是springboot里面内容了,也可以用env方式。
svc.yaml
2. jenkins中调用一个自己写的shell脚本,执行的时候传入2个参数。 比如:
/opt/jenkins/push.sh dev appName 其中 dev 表示开发环境、appName 表示工程名
重点在这个shell是怎么写的。
#!/bin/bash namespace=$1 name=$2 echo "" echo "=================== 1. maven ${JOB_NAME} =============" echo "" docker run --rm --name mvn -v /mnt/maven:/root/.m2 -v $WORKSPACE:/usr/src/mvn -w /usr/src/mvn/ maven:3.3.9-jdk-8 mvn clean insta ll echo "" echo "=================== 2.build docker image ==================" echo "" DOCKER_IMAGE=www.harbor.host/library/$name:`date +%y%m%d-%H-%M` docker build -t $DOCKER_IMAGE $WORKSPACE/. echo "" echo "=================== 3. push harbor =================" echo "" docker login -u name -p pwd www.harbor.host docker push $DOCKER_IMAGE docker logout www.harbor.host
echo "" echo "=================== 4.deploy kubernetes ==============" echo "" sed -i "s|\$NS|${namespace}|g" $WORKSPACE/kubernetes.yaml sed -i "s|\$IMAGE|${DOCKER_IMAGE}|g" $WORKSPACE/kubernetes.yaml sed -i "s|\$NS|${namespace}|g" $WORKSPACE/svc.yaml if kubectl get svc -n $namespace | grep $name; then echo "has svc ${name}" else kubectl create -f $WORKSPACE/svc.yaml fi kubectl apply -f $WORKSPACE/kubernetes.yaml
其实写到这里,老司机们应该看懂了,这里有一点不好,那就是jenkins部署在物理机上,应该是部署到kubernetes里面,然后通过API访问,主要是找的插件都不好用,所以就放物理机了。
另外还有一点,当你部署了一个statefulsets的应用的时候,比如mongo,在JAVA程序里面是无法直接通过svcName ping通的,因为这是一个无头服务。思路是 JAVA程序启动的时候,访问k8s的 endpoints API 就可以拿到。 代码类似下面:
当然要想访问API,记得加上serviceAccountName,和RBAC赋权。
实现是没什么时间,以后有空了再细化吧。