基于京东云Kubernetes集群的 SpringBoot+MySQL 应用示例

Kubernetes 是目前最主流的开源容器编排技术,用于自动部署,扩展和管理容器化应用程序,其提供应用部署、维护、 扩展机制等一系列完整功能,极大提高了容器集群管理的便捷性。

京东早在2016年年底上线了京东新一代容器引擎平台JDOS2.0,成功从OpenStack切换到Kubernetes技术栈,打造了完整高效的PaaS平台;拥有全球最大规模的Docker集群,容器数量超过20万,节点数超过8000台,集群支撑万亿电商交易,支撑多次6.18和11.11大促的考验。

京东云Kubernetes整合京东云虚拟化、存储和网络能力,提供高性能可伸缩的容器应用管理能力,简化集群的搭建和扩容等工作,让用户专注于容器化的应用的开发与管理。

用户可以在京东云创建一个安全高可用的 Kubernetes 集群,并由京东云完全托管 Kubernetes 服务,并保证集群的稳定性和可靠性。让用户可以方便地在京东云上使用 Kubernetes 管理容器应用。

京东云Kubernetes集群:https://www.jdcloud.com/cn/products/jcs-for-kubernetes

京东云MySQL:https://www.jdcloud.com/cn/products/jcs-for-mysql

规划

本文将使用京东云Kubernetes集群,在京东云VPC内通过Maven及Docker构建SpringBoot镜像,并将镜像部署至Kubernetes,SpringBoot使用京东云MySQL提供稳定可靠的云数据库服务。

image

  • 管理构建节点:k8s集群客户端、Maven构建、镜像构建
  • Kubernetes集群:京东云托管,负责承载运行Spring应用
  • 外部RDS服务:使用京东云MySQL服务
  • 负载均衡:利用京东云负载均衡提供到k8s内部应用的访问

操作步骤

新建私有网络VPC

本例中的操作均在一个私有网络VPC内,包括kubernetes集群、管理构建节点、Mysql实例:

VPC名称:SprintBoot-K8S
CIDR:10.0.0.0/16

image

创建kubernetes集群

集群创建

集群配置:
名称:k8s-sprintboot
管理节点CIDR:192.168.0.0/24 (管理节点CIDR不必预先创建,与工作节点CIDR不能重复)
添加可用京东云AccessKey

工作节点配置:
私有网络:使用刚创建的VPC(SprintBoot-K8S)
工作节点CIDR:10.0.0.0/18 (该CIDR在”SprintBoot-K8S” VPC内,k8s会在该CIDR下创建多个子网)
工作节点数量:3
工作节点组:springboot-group-1

image

image

集群创建中:
image

Kubernetes集群创建完成后:
image

Kubernetes集群信息

控制台上进入kubernetes集群页面:

集群详细信息(服务端点为k8s API Server对外地址):
image

工作节点组:
image

客户端配置页面:
image

云主机页面下,可以看到3个工作节点+1个nat节点(nat节点用于k8s工作节点访问外部网络):
image

Kubernetes在VPC下新建4个子网,分别为:nat、service、pod、node:
image

配置管理构建节点

创建云主机

SprintBoot-K8S私有网络内新建子网:

CIDR:10.0.64.0/18 (与kubernetes集群子网区分)

image

子网内新建云主机:
名称:SpringBoot-forbuild
OS:CentOS 7.4
子网选择刚创建的子网

image
image
image

云主机环境配置

安装Docker
# yum install -y docker
# systemctl start docker
# systemctl enable docker
# docker version
Client:
 Version:         1.13.1
 API version:     1.26
 Package version: docker-1.13.1-74.git6e3bb8e.el7.centos.x86_64
 Go version:      go1.9.4
 Git commit:      6e3bb8e/1.13.1
 Built:           Tue Aug 21 15:23:37 2018
 OS/Arch:         linux/amd64

Server:
 Version:         1.13.1
 API version:     1.26 (minimum version 1.12)
 Package version: docker-1.13.1-74.git6e3bb8e.el7.centos.x86_64
 Go version:      go1.9.4
 Git commit:      6e3bb8e/1.13.1
 Built:           Tue Aug 21 15:23:37 2018
 OS/Arch:         linux/amd64
 Experimental:    false
安装Git
# yum install –y git
安装Maven
# yum install -y maven
# mvn -version
Apache Maven 3.0.5 (Red Hat 3.0.5-17)
Maven home: /usr/share/maven
Java version: 1.8.0_181, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-693.17.1.el7.x86_64", arch: "amd64", family: "unix"
配置kubectl(版本1.8.12)

kubectl客户端下载页面:
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md

本例中安装kubectl 1.8.12,与集群版本一致,由于云主机无法访问google,可先将kubectl二进制tar包下载至本地,然后上传至云主机:

# ll kubernetes-client-linux-amd64.tar.gz 
-rw-r--r-- 1 root root 26148129 Aug 23 11:04 kubernetes-client-linux-amd64.tar.gz

解压:

# tar -xvf kubernetes-client-linux-amd64.tar.gz

将kubectl移动至/usr/local/bin/目录下:

# mv kubernetes/client/bin/kubectl /usr/local/bin/
配置kubectl自动补全
# source <(kubectl completion bash)
# echo "source <(kubectl completion bash)" >> ~/.bashrc

重新登录shell

配置集群凭据

切换到k8s集群的客户端配置页面,可按照说明配置kubectl客户端:
image

将配置信息写入~/.kube/config:

# mkdir ~/.kube
# vim ~/.kube/config

image

创建Spring namespace

创建新的namespace用于运行Spring应用:

# kubectl create namespace spring-mysql
namespace "spring-mysql" created
# kubectl get namespace
NAME           STATUS    AGE
default        Active    1h
kube-public    Active    1h
kube-system    Active    1h
libing-test    Active    40m
spring-mysql   Active    15s

image

Kubernetes集群验证

验证集群信息

查看版本信息:

# kubectl version

image

查看3个工作node节点:

# kubectl get node

image

查看kubernetes集群默认的namespace:

# kubectl get namespace

image

查看各个组件是否正常运行:

# kubectl get pod -n kube-system

image

上图看到各个组件均处于running的状态。

创建Nginx应用

本节创建一个简单nginx应用验证kubernetes集群功能,以下操作在管理构建云主机” SpringBoot-forbuild”上操作,测试yaml文件存放于Github:
https://github.com/jcloud-architecture/gs-accessing-data-mysql/tree/master/complete/yaml

  1. 创建测试namespace
# kubectl create namespace libing-test
namespace "libing-test" created
  1. 创建Nginx deployment
# kubectl create -f https://raw.githubusercontent.com/jcloud-architecture/gs-accessing-data-mysql/master/complete/yaml/nginx-deployment.yaml -n libing-test
deployment "my-nginx" created
  1. 查看Pod是否运行
# kubectl get pod -n libing-test

image

  1. 创建Nginx service
# kubectl create -f https://raw.githubusercontent.com/jcloud-architecture/gs-accessing-data-mysql/master/complete/yaml/nginx-svc.yaml -n libing-test

image

  1. 验证Nginx是否可以正常访问

本例中创建的为LoadBalancer类型的service,会自动创建一个负载均衡如下:
image

负载均衡后端端口为30062(将流量转发至各node节点的30062端口):
image

Node节点的kube-proxy组件负责将访问30062端口的流量转至Pod的80端口。以下为service的具体配置:
image

Kubectl也可以查看External IP,为京东云LB的公网IP:

# kubectl get svc -n libing-test

image

访问Nginx正常:
image

Kubernetes集群测试完毕,应用可正常运行!

Mysql服务配置

本节将在创建京东云Mysql实例,然后通过手动配置Service Endpoint将Mysql服务导入kubernetes集群。

创建MySQL专属子网

MySQL服务配置信息如下:

VPC:SprintBoot-K8S  
子网名称:mysql-forSpring  
CIDR:10.0.128.18

image

创建MySQL实例

选择对应VPC和子网:
image

配置响应的实例、库、账号、密码:
实例名称:mysqlforspring
库名称:mysqlforspring
账号:mysqlforspring
image

创建MySQL Endpoint

Kubernetes集群内创建用于访问mysql外部服务的endpoint:

MySQL yaml文件中指定mysql服务的内部IP和端口:

# cat mysql-endpoint.yaml 
kind: Endpoints
apiVersion: v1
metadata:
  name: mysql
subsets:
  - addresses:
      - ip: 10.0.128.5 
    ports:
      - port: 3306

创建MySQL endpoint:

# kubectl create -f mysql-endpoint.yaml -n spring-mysql

创建成功:

# kubectl get endpoints -n spring-mysql

image

创建MySQL Service

创建MySQL service关联上小节的MySQL endpoint:

如下为mysql service的yaml文件:

# cat mysql-service.yaml 
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  ports:
- port: 3306

创建mysql service:

# kubectl create -f mysql-service.yaml -n spring-mysql

查看mysql service:

# kubectl describe svc/mysql -n spring-mysql

image

上图可以看到service ip为10.0.62.175,且service已经与MySQL外部服务绑定。

下一节Spring应用便通过该Service访问mysql服务。

Spring镜像构建

下载源码

Spring源码存放在Github:

# git clone https://github.com/jcloud-architecture/gs-accessing-data-mysql.git
Cloning into 'gs-accessing-data-mysql'...
remote: Counting objects: 703, done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 703 (delta 4), reused 13 (delta 4), pack-reused 684
Receiving objects: 100% (703/703), 297.47 KiB | 224.00 KiB/s, done.
Resolving deltas: 100% (491/491), done.

更新properties

更改properties中的jdbc以及mysql用户名密码:

# vim gs-accessing-data-mysql/complete/src/main/resources/application.properties
spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=jdbc:mysql://mysql.spring-mysql.svc.cluster.local:3306/mysqlforspring
spring.datasource.username=mysqlforspring
spring.datasource.password=yourpassword

image

Kubernetes中service的默认DNS为:

<my-svc>.<my-namespace>.svc.cluster.local

集群内部可以直接访问service该域名访问后端服务。

Maven构建

进入complete目录:

# cd gs-accessing-data-mysql/complete/

开始构建:

# mvn clean package

Build成功后会在target目录下生成JAR包:

# ls target/

image

下一步将该Jar包打包进Docker镜像。

镜像构建

创建用于docker build的目录:

# mkdir ~/build
# cp ~/gs-accessing-data-mysql/complete/target/gs-mysql-data-0.1.0.jar ~/build/
# cd ~/build
# ls
gs-mysql-data-0.1.0.jar

build目录下创建Dockerfile:

# vim Dockerfile 
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

开始构建:

# docker build -t bingli7/spring-mysql:0823 --build-arg JAR_FILE=gs-mysql-data-0.1.0.jar .
Sending build context to Docker daemon 30.19 MB
Step 1/5 : FROM openjdk:8-jdk-alpine
Trying to pull repository docker.io/library/openjdk ... 
8-jdk-alpine: Pulling from docker.io/library/openjdk
8e3ba11ec2a2: Pull complete 
311ad0da4533: Pull complete 
df312c74ce16: Pull complete 
Digest: sha256:1fd5a77d82536c88486e526da26ae79b6cd8a14006eb3da3a25eb8d2d682ccd6
Status: Downloaded newer image for docker.io/openjdk:8-jdk-alpine
 ---> 5801f7d008e5
Step 2/5 : VOLUME /tmp
 ---> Running in 17d44204a97c
 ---> aa1087be0d45
Removing intermediate container 17d44204a97c
Step 3/5 : ARG JAR_FILE
 ---> Running in 0aec21218c2c
 ---> 14b6bedd0971
Removing intermediate container 0aec21218c2c
Step 4/5 : COPY ${JAR_FILE} app.jar
 ---> 6c62bb3a1b28
Removing intermediate container 2ab4e026c801
Step 5/5 : ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar /app.jar
 ---> Running in 55fdc8c4ee34
 ---> bad4a64850cf
Removing intermediate container 55fdc8c4ee34
Successfully built bad4a64850cf

构建成功!
注:
Docker build命令中,-t指定了镜像的名字为bingli7/spring-mysql:0823 (bingli7是docker hub账户名,0823是镜像tag)
JAR_FILE=gs-mysql-data-0.1.0.jar表示当前目录下的JAR文件,对应Dockerfile中的JAR_FILE变量

查看镜像:

# docker images

image

Spring-mysql为刚build成功的镜像,openjdk为build基础镜像。

推送镜像至Github

本例中使用Docker Hub存储镜像。

登录Docker Hub:

# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: bingli7
Password: 
Login Succeeded

推送镜像至Docker Hub:

# docker push bingli7/spring-mysql:0823

image

Push成功!

Spring 应用部署

部署 Spring 镜像

本节将会使用build成功的镜像在kubernetes集群中部署Spring应用。

Spring deployment Yaml文件:

# vim spring-mysql.yaml 
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: spring-mysql
spec:
  selector:
    matchLabels:
      run: spring-mysql
  replicas: 1
  template:
    metadata:
      labels:
        run: spring-mysql
    spec:
      containers:
      - name: spring-mysql
        image: bingli7/spring-mysql:0823
        ports:
        - containerPort: 8080

注:
image: bingli7/spring-mysql:0823为上节推送至docker hub的镜像,kubernetes默认会从docker hub上pull该镜像

部署Spring应用:

# kubectl create -f spring-mysql.yaml -n spring-mysql 
deployment "spring-mysql" created

image

Pod 状态已经running

查看pod的日志:

# kubectl logs pod/spring-mysql-bb4b5db69-f7cp4 -n spring-mysql

image
image

Spring应用运行正常!

配置Spring应用外部访问

本节配置LB类型的service,供集群外部用户访问k8s内部的Spring application:

# vim spring-mysql-svc.yaml 
kind: Service
apiVersion: v1
metadata:
  name: spring-mysql
  labels:
    run: spring-mysql
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
      nodePort: 30066
  type: LoadBalancer
  selector:
     run: spring-mysql

创建service:

# kubectl create -f spring-mysql-svc.yaml -n spring-mysql 
service "spring-mysql" created

创建成功后:
image

EXTERNAL-IP为京东云负载均衡公网IP。

京东云控制台上可以查看LB信息:
image

Spring应用访问验证

外部插入数据

插入一条用户数据至mysql:

# curl 'http://116.196.122.119/demo/add?name=libing&email=libing18@jd.com'
Saved

116.196.122.119为spring app的外部访问地址,即LB公网IP。

访问验证

访问Spring应用:

# curl http://116.196.122.119/demo/all
[{"id":1,"name":"libing","email":"libing18@jd.com"}]

返回用户数据!

或者浏览器访问http://116.196.122.119/demo/all

image

数据正常返回!

提升应用副本数量

提升spring pod副本数量至3个:

# kubectl scale deployment spring-mysql --replicas=3 -n spring-mysql 
deployment "spring-mysql" scaled

新的pod已生成,并正常运行:
image

查看spring service状态:
image

Spring-mysql有3个endpoint,ip分别为3个spring pod的IP地址。

现在,访问Spring应用可以负载均衡到3个pod上。

以上。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值