每个公司的业务系统都各不相同,但常见的服务可能有这些:

1. java定时任务

2. springboot服务

3. dubbo服务

4. web服务

 

无状态的服务(如nginx,tomcat)有利于容器化,迁移到k8s中非常合适,因为有自动伸缩和负载均衡。而对于有状态的服务(如mysql、kafka)一般不建议容器化。

如何将公司的业务系统迁移到k8s中?可分为两步:

1. 把服务做成镜像:
        确定基础镜像
        确定服务运行的相关文件
        Dockerfile构建镜像

2. 根据镜像创建k8s服务,并调度:
        确定服务发现的策略
        编写k8s配置文件
        k8s调度

 

准备工作已完成:搭建k8s集群业务系统迁移准备


Java定时任务迁移

Java开发过程中经常会遇到使用定时任务的情况。

把java的定时任务做成镜像,并推送到harbor仓库hub.lzxlinux.cn,再部署到k8s集群中。

  • 拉取基础镜像(harbor1):
# docker login hub.lzxlinux.cn# docker pull openjdk:8-jre-alpine# docker tag openjdk:8-jre-alpine hub.lzxlinux.cn/kubernetes/openjdk:8-jre-alpine# docker push !$

 

  • 安装jdk和maven(harbor1):
# cd /software# lsharbor  harbor-offline-installer-v1.9.1.tgz  jdk-8u191-linux-x64.tar.gz# tar xf jdk-8u191-linux-x64.tar.gz# mv jdk1.8.0_191/ /usr/local/jdk# wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.2/binaries/apache-maven-3.6.2-bin.tar.gz# tar xf apache-maven-3.6.2-bin.tar.gz# mv apache-maven-3.6.2 /usr/local/maven# vim /etc/profile              #添加JAVA_HOME=/usr/local/jdk
MAVEN_HOME=/usr/local/maven
PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$MAVEN_HOME/bin
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/jre/libexport JAVA_HOME PATH CLASSPATH# source /etc/profile

 

  • 生成jar包并运行测试(harbor1):
# cd /software# git clone https://git.imooc.com/LZXLINUX/mooc-k8s-demo-docker.git# cd mooc-k8s-demo-docker/cronjob-demo/# mvn package# cd target/# java -cp cronjob-demo-1.0-SNAPSHOT.jar com.mooc.demo.cronjob.MainI will working for 28 seconds!All work is done! Bye!

 

可以看到,运行没有问题。

  • 生成镜像(harbor1):
# cd /software/mooc-k8s-demo-docker/cronjob-demo/# vim Dockerfile

 

FROM hub.lzxlinux.cn/kubernetes/openjdk:8-jre-alpine

COPY target/cronjob-demo-1.0-SNAPSHOT.jar /cronjob-demo.jar

ENTRYPOINT ["java", "-cp", "/cronjob-demo.jar", "com.mooc.demo.cronjob.Main"]

 

# docker build -t cronjob:v1 .# docker run -it --rm cronjob:v1I will working for 21 seconds!All work is done! Bye!# docker tag cronjob:v1 hub.lzxlinux.cn/kubernetes/cronjob:v1# docker push !$

 

  • k8s集群配置:

所有的k8s节点配置登录harbor仓库。以master1节点为例,

# echo '192.168.1.59 hub.lzxlinux.cn' >> /etc/hosts# echo '192.168.1.60 harbor.lzxlinux.cn' >> /etc/hosts# cat << EOF > /etc/docker/daemon.json{
    "exec-opts":["native.cgroupdriver=systemd"],    "registry-mirrors": ["http://f1361db2.m.daocloud.io"],    "insecure-registries": ["hub.lzxlinux.cn", "harbor.lzxlinux.cn"]}EOF# systemctl restart docker# docker login hub.lzxlinux.cn# docker login harbor.lzxlinux.cn

 

  • 部署到k8s(master1):
# cd /software# vim cronjob.yaml

 

apiVersion: batch/v1beta1kind: CronJobmetadata:
  name: cronjob-demospec:
  schedule: "*/1 * * * *"
  successfulJobsHistoryLimit: 3
  suspend: false
  concurrencyPolicy: Forbid  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: cronjob-demo        spec:
          restartPolicy: Never          containers:
          - name: cronjob-demo            image: hub.lzxlinux.cn/kubernetes/cronjob:v1            imagePullPolicy: Always

 

# kubectl apply -f cronjob.yaml# kubectl get cronjobs.batchNAME           SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob-demo   */1 * * * *   False     1        15s             37s# kubectl get pods -o wideNAME                            READY   STATUS      RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
cronjob-demo-1574157480-6rtft   0/1     Completed   0          101s    172.10.2.4    node2   <none>           <none>cronjob-demo-1574157540-gkg9k   0/1     Completed   0          40s     172.10.5.9    node3   <none>           <none>tomcat-demo-6bc7d5b6f4-rnqlm    1/1     Running     3          3h55m   172.10.4.12   node1   <none>           <none># kubectl logs pods/cronjob-demo-1574157480-6rtftI will working for 11 seconds!All work is done! Bye!# kubectl logs pods/cronjob-demo-1574157540-gkg9kI will working for 28 seconds!All work is done! Bye!

 

至此,java的定时任务在k8s中正常运行,迁移到k8s中完成。


SpringBoot的web服务迁移

SpringBoot可以非常容易地创建一个独立的、生产级别的、基于Spring的应用,它大量简化了使用Spring带来的繁琐的配置。

把springboot的web服务做成镜像,并推送到harbor仓库hub.lzxlinux.cn,再部署到k8s集群中。

前面已有基础镜像,且harbor1节点已安装jdk和maven。

  • 生成jar包并运行测试(harbor1):
# cd /software/mooc-k8s-demo-docker/springboot-web-demo/# mvn package               #若失败再执行一次# cd target/# java -jar springboot-web-demo-1.0-SNAPSHOT.jar

 

浏览器访问,

5. 业务系统迁移实践_业务系统

可以看到,jar包运行没有问题。

  • 生成镜像(harbor1):
# cd /software/mooc-k8s-demo-docker/springboot-web-demo/# vim Dockerfile

 

FROM hub.lzxlinux.cn/kubernetes/openjdk:8-jre-alpine

COPY target/springboot-web-demo-1.0-SNAPSHOT.jar /springboot-web.jar

ENTRYPOINT ["java", "-jar", "/springboot-web.jar"]

 

# docker build -t springboot-web:v1 .# docker run -d --rm -p 8080:8080 springboot-web:v1

 

浏览器访问,

5. 业务系统迁移实践_业务系统_02

可以看到,容器运行没有问题。

# docker tag springboot-web:v1 hub.lzxlinux.cn/kubernetes/springboot-web:v1# docker push !$

 

  • 部署到k8s(master1):
# cd /software# vim springboot-web.yaml

 

#deployapiVersion: apps/v1kind: Deploymentmetadata:
  name: springboot-web-demospec:
  selector:
    matchLabels:
      app: springboot-web-demo  replicas: 1
  template:
    metadata:
      labels:
        app: springboot-web-demo    spec:
      containers:
      - name: springboot-web-demo        image: hub.lzxlinux.cn/kubernetes/springboot-web:v1        imagePullPolicy: Always        ports:
        - containerPort: 8080---#serviceapiVersion: v1kind: Servicemetadata:
  name: springboot-web-demospec:
  ports:
  - port: 80
    protocol: TCP    targetPort: 8080
  selector:
    app: springboot-web-demo  type: ClusterIP---#ingressapiVersion: extensions/v1beta1kind: Ingressmetadata:
  name: springboot-web-demospec:
  rules:
  - host: springboot.lzxlinux.cn    http:
      paths:
      - path: /        backend:
          serviceName: springboot-web-demo          servicePort: 80

 

# kubectl apply -f springboot-web.yaml# kubectl get pods -o wideNAME                                  READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
springboot-web-demo-5bd7f7788-5852n   1/1     Running   0          41s   172.10.5.151   node3   <none>           <none>

 

可以看到,该pod在node3节点上运行。在Windows电脑hosts文件中添加本地dns:

192.168.1.56 springboot.lzxlinux.cn

 

访问springboot.lzxlinux.cn

5. 业务系统迁移实践_Kubernetes_03

至此,springboot的web服务在k8s中正常运行,迁移到k8s中完成。


传统Dubbo服务迁移

Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,服务注册和发现。

把dubbo服务做成镜像,并推送到harbor仓库hub.lzxlinux.cn,再部署到k8s集群中。

  • 运行zookeeper容器(harbor1):
# docker pull zookeeper# docker run -d -p 2181:2181 --name zookeeper zookeeper

 

  • 修改配置(harbor1):
# vim /software/mooc-k8s-demo-docker/dubbo-demo/src/main/resources/dubbo.propertiesdubbo.application.name=demo
dubbo.registry.address=zookeeper://192.168.1.59:2181
dubbo.spring.config=classpath*:spring/provider.xml
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880

 

  • 生成jar包并运行测试(harbor1):

前面已有基础镜像,且harbor1节点已安装jdk和maven。

# cd /software/mooc-k8s-demo-docker/dubbo-demo-api/# mvn install# cd /software/mooc-k8s-demo-docker/dubbo-demo/# mvn package# cd target/# mkdir ROOT && cd ROOT# mv ../dubbo-demo-1.0-SNAPSHOT-assembly.tar.gz .# tar xf dubbo-demo-1.0-SNAPSHOT-assembly.tar.gz# rm -rf dubbo-demo-1.0-SNAPSHOT-assembly.tar.gz# ./bin/start.sh Starting the demo ...PID: 11003
STDOUT: /software/mooc-k8s-demo-docker/dubbo-demo/target/ROOT/logs/stdout.log# netstat -lntp |grep 20880tcp        0      0 0.0.0.0:20880           0.0.0.0:*               LISTEN      11003/java# telnet 192.168.1.59 20880dubbo>ls
com.mooc.demo.api.DemoService

dubbo>ls com.mooc.demo.api.DemoService
sayHello

dubbo>invoke com.mooc.demo.api.DemoService.sayHello("LZXLINUX")    "Hello LZXLINUX"elapsed: 8 ms.

 

可以看到,dubbo服务运行没有问题。

  • 生成镜像(harbor1):
# cd /software/mooc-k8s-demo-docker/dubbo-demo/# vim Dockerfile

 

FROM hub.lzxlinux.cn/kubernetes/openjdk:8-jre-alpine

COPY target/ROOT /ROOT

CMD sh /ROOT/bin/start.sh && tail -f /ROOT/logs/stdout.log

 

# docker build -t dubbo:v1 .# docker run -d --rm -p 20881:20880 dubbo:v1# telnet 192.168.1.59 20881dubbo>ls
com.mooc.demo.api.DemoService

dubbo>ls com.mooc.demo.api.DemoService
sayHello

dubbo>invoke com.mooc.demo.api.DemoService.sayHello("Dubbo")"Hello Dubbo"elapsed: 15 ms.

 

可以看到,容器运行没有问题。

# docker tag dubbo:v1 hub.lzxlinux.cn/kubernetes/dubbo:v1# docker push !$

 

  • 部署到k8s(master1):
# cd /software# vim dubbo.yaml

 

#deployapiVersion: apps/v1kind: Deploymentmetadata:
  name: dubbo-demospec:
  selector:
    matchLabels:
      app: dubbo-demo  replicas: 1
  template:
    metadata:
      labels:
        app: dubbo-demo    spec:
      hostNetwork: true
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app                operator: In                values:
                - dubbo-demo            topologyKey: "kubernetes.io/hostname"
      containers:
      - name: dubbo-demo        image: hub.lzxlinux.cn/kubernetes/dubbo:v1        imagePullPolicy: Always        ports:
        - containerPort: 20881
        env:
        - name: DUBBO_PORT          value: "20881"

 

# kubectl apply -f dubbo.yaml# kubectl get pod -o wideNAME                                  READY   STATUS    RESTARTS   AGE     IP             NODE    NOMINATED NODE   READINESS GATES
dubbo-demo-5d5f6fc68d-mf2sg           1/1     Running   0          5s      192.168.1.55   node2   <none>           <none>springboot-web-demo-5bd7f7788-5852n   1/1     Running   0          3h10m   172.10.5.151   node3   <none>           <none>

 

可以看到,该pod在node2节点上运行。到node2节点操作,

# netstat -lntp |grep 20881tcp        0      0 0.0.0.0:20881           0.0.0.0:*               LISTEN      28521/java# telnet 192.168.1.55 20881dubbo>ls 
com.mooc.demo.api.DemoService

dubbo>ls com.mooc.demo.api.DemoService
sayHello

dubbo>invoke com.mooc.demo.api.DemoService.sayHello("Kubernetes")"Hello Kubernetes"elapsed: 12 ms.

 

至此,传统的dubbo服务在k8s中正常运行,迁移到k8s中完成。通过使用hostNetwork暴露dubbo服务的端口,且可以直接在yaml文件中定义变量设置dubbo服务的端口。


传统Web服务迁移

传统的Web服务由nginx、tomcat等web服务器提供服务,Web服务器只负责处理HTTP协议,只能发送静态页面的内容。

把web服务做成镜像,并推送到harbor仓库hub.lzxlinux.cn,再部署到k8s集群中。

该web服务需要前面的zookeeper服务与dubbo服务支持,不用关闭前面的zookeeper服务和dubbo服务。

  • 拉取基础镜像(harbor1):
# docker pull registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine# docker tag registry.cn-hangzhou.aliyuncs.com/liuyi01/tomcat:8.0.51-alpine hub.lzxlinux.cn/kubernetes/tomcat:8.0.51-alpine# docker push !$

 

  • 修改配置(harbor1):
# vim /software/mooc-k8s-demo-docker/web-demo/src/main/resources/applicationContext-service-config.xml<dubbo:registry address="zookeeper://192.168.1.59:2181" />

 

  • 生成war包(harbor1):
# cd /software/mooc-k8s-demo-docker/web-demo/# mvn package# cd target/# mkdir ROOT && cd ROOT# mv ../web-demo-1.0-SNAPSHOT.war .# jar -xf web-demo-1.0-SNAPSHOT.war# rm -rf web-demo-1.0-SNAPSHOT.war

 

  • 生成镜像(harbor1):
# cd /software/mooc-k8s-demo-docker/web-demo/# vim Dockerfile

 

FROM hub.lzxlinux.cn/kubernetes/tomcat:8.0.51-alpine

COPY target/ROOT /usr/local/tomcat/webapps/ROOT

CMD sh /usr/local/tomcat/bin/startup.sh && tail -f /usr/local/tomcat/logs/catalina.out

 

# docker build -t web:v1 .# docker run -d -p 8080:8080 --rm --name web web:v1

 

浏览器访问192.168.1.59:8080/hello?name=LZX

5. 业务系统迁移实践_业务系统_04

可以看到,容器运行没有问题。

# docker tag web:v1 hub.lzxlinux.cn/kubernetes/web:v1# docker push !$

 

  • 部署到k8s(master1):
# cd /software# vim web.yaml

 

#deployapiVersion: apps/v1kind: Deploymentmetadata:
  name: web-demospec:
  selector:
    matchLabels:
      app: web-demo  replicas: 1
  template:
    metadata:
      labels:
        app: web-demo    spec:
      containers:
      - name: web-demo        image: hub.lzxlinux.cn/kubernetes/web:v1        imagePullPolicy: Always        ports:
        - containerPort: 8080---#serviceapiVersion: v1kind: Servicemetadata:
  name: web-demospec:
  ports:
  - port: 80
    protocol: TCP    targetPort: 8080
  selector:
    app: web-demo  type: ClusterIP---#ingressapiVersion: extensions/v1beta1kind: Ingressmetadata:
  name: web-demospec:
  rules:
  - host: web.lzxlinux.cn    http:
      paths:
      - path: /        backend:
          serviceName: web-demo          servicePort: 80

 

# kubectl apply -f web.yaml# kubectl get pod -o wideNAME                          READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
dubbo-demo-5d5f6fc68d-mf2sg   1/1     Running   0          36m   192.168.1.55   node2   <none>           <none>web-demo-6bcd75d5b-msxht      1/1     Running   0          26s   172.10.4.163   node1   <none>           <none>

 

可以看到,该pod在node1节点上运行。在Windows电脑hosts文件中添加本地dns:

192.168.1.54 web.lzxlinux.cn

 

访问web.lzxlinux.cn/hello?name=K8S

5. 业务系统迁移实践_业务系统_05

至此,传统的web服务在k8s中正常运行,迁移到k8s中完成。