LinkedKeeper部署阿里云Kubernetes版
您目前处于:云计算  2021-07-07

系列文章:

• How to build aliyun service

• Linkedkeeper 架构演进赏析

• 阿里云 ECS 部署 Linkedkeeper 服务

• Linkedkeeper部署Kubernetes

• LinkedKeeper部署阿里云Kubernetes

• 一个小网站的云原生实践

• 阿里云CDN域名被恶意盗刷


本篇文章,我们看一下如何基于阿里云K8S部署自己的应用。从整体部署来看,首先,阿里云提供了容器镜像服务,可用于我们应用基于容器化Dockerfile的镜像构建,其次,基于容器服务 - Kubernetess实现了容器化部署,整个过程如下图所示,不过其中还使用到了SLB、EIP、NAT、ECS、VPC、VSW等等,我们来一起看下。

First,我们通过阿里云容器服务 - Kubernetess创建一个K8S集群:

成功创建了K8S集群之后,如何把它做成Docker镜像?

步骤一:在Dockerfile中使用多阶段构建打包Java应用镜像

从Docker 17.05版本开始,使用docker build命令开始支持多阶段构建。

多阶段构建指在Dockerfile中使用多个FROM语句,每个FROM指令都可以使用不同的基础镜像,并且是一个独立的子构建阶段,多条FROM就是多阶段构建,虽然最后生成的镜像只能是最后一个阶段的结果,但是,能够将前置阶段中的文件拷贝到后边的阶段中,这就是多阶段构建的最大意义。最大的使用场景是将编译环境和运行环境分离,直接一个Dockerfile就可以解决。

什么是基础镜像?

LinkedKeeper托管在Github上,通过阿里云容器镜像服务(ACR)的镜像构建服务,进行多阶段构建。

Second,开通阿里云容器镜像服务,绑定Github代码源,创建镜像仓库。

使用多阶段构建Dockerfile(multi-stage)

在LinkedKeeper Maven项目中新建Dockerfile文件,并在Dockerfile文件添加以下内容。

# First stage: complete build environment
FROM maven:3.5.0-jdk-8-alpine AS builder

# add pom.xml and source code
ADD ./pom.xml pom.xml
ADD ./linkedkeeper-web /linkedkeeper-web
ADD ./linkedkeeper-usercenter /linkedkeeper-usercenter
ADD ./linkedkeeper-service /linkedkeeper-service
ADD ./linkedkeeper-manager /linkedkeeper-manager
ADD ./linkedkeeper-dao /linkedkeeper-dao
ADD ./linkedkeeper-domain /linkedkeeper-domain

# package jar
RUN mvn clean package

# Second stage: minimal runtime environment
FROM openjdk:8-jre-alpine
FROM tomcat:8.5.32-jre8

# copy jar from the first stage
RUN rm -rf /usr/local/tomcat/webapps/*
COPY --from=builder /linkedkeeper-web/target/linkedkeeper-web-1.0-SNAPSHOT.war /usr/local/tomcat/webapps/ROOT.war

RUN mkdir -p /usr/local/tomcat/upload/temp/

EXPOSE 8080

# startup tomcat
CMD ["/usr/local/tomcat/bin/catalina.sh", "run"]

说明:该Dockerfile文件使用了二阶段构建。

  • 第一阶段(编译阶段):选择Maven基础镜像完成项目编译,拷贝源代码到基础镜像并运行RUN命令,从而构建Jar包。

  • 第二阶段(运行阶段):拷贝第一阶段生成的Jar包到OpenJDK镜像中,设置CMD运行命令。

构建成功之后,我们通过登录阿里云Dockder Registry检查镜像。

我们首先本地拉取镜像。

% docker login --username=ran****@sohu.com registry.cn-beijing.aliyuncs.com
Password: 
Login Succeeded
% docker pull registry.cn-beijing.aliyuncs.com/linkedkeeper_k8s/linkedkeeper.com:1.0.0
1.0.0: Pulling from linkedkeeper_k8s/linkedkeeper.com
55cbf04beb70: Pull complete 
1607093a898c: Pull complete 
9a8ea045c926: Pull complete 
1290813abd9d: Pull complete 
8a6b982ad6d7: Pull complete 
abb029e68402: Pull complete 
d068d0a738e5: Pull complete 
42ee47bb0c52: Pull complete 
ae9c861aed25: Pull complete 
60bba9d0dc8d: Pull complete 
15222e409530: Pull complete 
2dcc81b69024: Pull complete 
Digest: sha256:cfb3b2e7b51dbe53ef029cfa4739527b55f0797fdbfc5f87078fbdd63f1b3ebe
Status: Downloaded newer image for registry.cn-beijing.aliyuncs.com/linkedkeeper_k8s/linkedkeeper.com:1.0.0
registry.cn-beijing.aliyuncs.com/linkedkeeper_k8s/linkedkeeper.com:1.0.0
% docker images
REPOSITORY                                                           TAG       IMAGE ID       CREATED       SIZE
registry.cn-beijing.aliyuncs.com/linkedkeeper_k8s/linkedkeeper.com   1.0.0     1e7c9da6e6db   2 years ago   463MB

登录本地docker查看镜像:

我们在本地docker运行试一下:

登录docker看下服务:

% docker ps
CONTAINER ID   IMAGE                                                                      COMMAND                  CREATED         STATUS         PORTS                    NAMES
a78c66a2fc26   registry.cn-beijing.aliyuncs.com/linkedkeeper_k8s/linkedkeeper.com:1.0.0   "/usr/local/tomcat/b…"   2 minutes ago   Up 2 minutes   0.0.0.0:8888->8080/tcp   relaxed_sanderson

步骤二:使用镜像创建无状态Deployment应用

登录容器服务管理控制台

进入目标集群。

选择工作负载,在无状态页面中,单击使用镜像创建。配置容器的镜像与资源、端口、环境变量、健康检查、生命周期、数据卷和日志等。

其中,资源限制是应用所能使用的资源上限,包括CPU、内存和ephemeral-storage三种资源,防止占用过多资源;所需资源是应用预留资源额度,即容器独占该资源,防止因资源不足而被其他服务或进程争夺资源,导致应用不可用。容器启动项里stdi是将控制台输入发送到容器,tty是将标准输入控制台作为容器的控制台输入。

在高级配置配置中设置访问、伸缩、调度和标签注解。在访问设置区域,设置暴露后端Pod的方式。通过虚拟集群IP和路由(Ingress),构建一个公网可访问的Nginx应用。

LinkedKeeper本次使用SLB模式,创建一个公网SLB,提供对外IP绑定DNS域名提供对外服务。

SLB创建之后,在K8S集群的服务路由里,就可以看到K8S集群开放对外的路由地址。

同时,在阿里云负载均衡实例管理里,也可会看到被创建的SLB实例。

步骤三:网络互通

由于LinkedKeeper之前使用的RDB和Reds都是部署在经典网络里的,所以VPC网路与经典网络互通,需要进行网络打通。这个操作需要在VPC网络配置里开启ClassicLink。

其次,在ECS的安全组规则里配置VPC网络与经典网络的ClassicLink的规则组。

经典网络增加VPC网络互通规则:

VPC网络增加经典网络互通规则:

不过,经过上述一通搞,发现VPC还是无法访问经典网络,在阿里云提交了工单,最终采取的方案将RDS和Reds迁移到VPC网络里。

这里特别详细说下:

首先判断连接RDS的内网的地址还是外网地址:

  • 内网连接同VPC下:看一下集群网络插件时flannel,还是terway,如果是flannel插件,需要把节点和pod网段添加到RDS的白名单中,如果是terway需要添加pod网段。

  • 外网连接同VPC下:需要把NAT网关的IP添加到RDS的白名单中。

这里,LinkedKeeper连接的RDS是内网地址,而且K8S集群网络插件是Flannel,那么,我们登录RDS和Redis的安全组和白名单配置K8S的pod网关和ecs白名单。

步骤四:访问外网

LinkedKeeper使用了QQ和微博实现第三方登录,这要求第三方登录之后需要容器服务调用第三方获取token,这就涉及到访问网关的问题,那么Docker如何访问网关呢?

这个解决需要部署NAT和EIP绑定VPC网段,就可以实现了。

有了NAT之后,我们还需要配置SNAT,配置SNAT首先要绑定访问公网的VPC网络或是ECS集群:

其次,配置SNAT还需要绑定EIP:

总结

LinkedKeeper升级K8S容器化部署,从部署上的确标准化了,但是从成本上也着实贵了很多,以前的架构部署ECS、RDB、Redis、OSS、DNS、域名就可以了,现在都多出了镜像服务、K8S、SLB、NAT、EIP着实也是越来越重了,希望一直坚持自己构建应用的小伙伴,一期努力共勉。

Reference

https://help.aliyun.com/document_detail/86745.html

https://help.aliyun.com/document_detail/173175.htm

https://help.aliyun.com/document_detail/87784.htm

https://help.aliyun.com/document_detail/102576.html

https://help.aliyun.com/document_detail/185275.html

https://blog.csdn.net/kevin_loving/article/details/80912268

http://jvm123.com/2020/05/dockerfile-duo-jie.html

https://maichong.io/help/docker/induction.html

https://www.kancloud.cn/docker_practice/docker_practice/469763


本文受原创保护,未经作者授权,禁止转载。 linkedkeeper.com (文/张松然)  ©著作权归作者所有