JAVA based kubernetes deployment project
will move the project to k8s platform is how to achieve?
1 mirrored
2 Management Controller Pod
. 3 Pod data persistence
4 is exposed to the application
5 Application released
6 logs / monitor
1 mirrored divided into three steps: first base image, which is based on the operating system, or other such Centos7
second step middleware Mirror, mirror such as service, run like nginx service, tomcat service
third step mirror project, it service on the mirror will pack into your project, then the project will be able to serve you the inside running for mirroring
Generally, we are ahead of the operation and maintenance personnel will do our mirrors, while developers will be able to directly take to use this image, this image must be in line with current environment deployment environment,
2 controller manages the pod
is deployed k8s to this image, and in general we will pick up the controller to deploy, use the most is the deployment of
• Deployment: Stateless deployment
• StatefulSet: stateful deployment
• DaemonSet: daemon deployment
• Job & CronJob: Batch
Stateless and stateful What is the difference?
There is a state of identity, such as network ID, storage, this is two ahead of planned, orderly start / stop
persistent and non-persistent
3 Pod Data Persistence
pod data persistence is mainly due to say an application, such as the development of a project, the project has not landed to a local file, if there is fall, then it has to ensure that his long-lasting, it must use to pod data the persistence.
Container deployment process generally have the following three types of data:
• Start the initial data when needed, can be a configuration file
for temporary data generated during startup • The need for temporary data sharing among multiple containers
• Start persistent data generated in the process
4 exposed applications
in k8s, the deployment of a deployment, it can not be accessed outside, is another application in order to access the deployment of the deployment, it can not find how to access this, why go so to speak, because deployment usually to deploy multiple copies, there may be distributed over different nodes, but also reconstruction pod ip changes, and republish it also will become, so there is no way to fix the pod which to visit, even if fixed, the other pod can not access, in order to achieve more pod are to provide services, then there must be added a front load balancing, providing an access entrance, this is the only access to the unified entrance, can be forwarded to multiple back-end pod, as long as access on the Cluster IP can be forwarded to the back-end POD
service
• service defines a logical collection and access Pod this policy sets the
• service introduced in order to address the dynamic changes Pod provides service discovery and load balancing
• use CoreDNS resolve the service name
5 released application
after exposed to it, is the need for users to access, such as to build a electricity supplier site that allows users to access, ingress with respect to the service, it is a complementary state to make up their own, service mainly to provide a cluster access to internal, you can also expose a TCP / UDP port, and ingress primarily a forward layer 7, that is, to provide a unified entrance, simply go to ingress controller, it can help you to forward deploy all your projects, It is that all projects use to access the domain name.
传统部署与K8S部署区别
首先开发者将代码部署到你的代码仓库中,主流的用的Git或者gitlab,提交完代码通过CI/CD平台需要对代码进行拉取、编译、构建,产生一个War包,然后交给Ansible然后发送到云主机上/物理机,然后通过负载均衡将项目暴露出去,然后会有数据库,监控系统,日志系统来提供相关的服务。
首先也是开发将代码放在代码仓库,然后通过jenkins去完成拉取代码,编译,上传到我们的镜像仓库这里是将代码打包成一个镜像,而不是刻意执行的war或者jar包,这个镜像包含了你的项目的运行环境和项目代码,这个镜像可以放在任何docker上去run起来,都可以去访问,首先得保证能够在docker上去部署起来,再部署到k8s上,打出来的镜像去放在镜像仓库中,来集中的去管理这些镜像,因为每天会产生几十个或者上百个镜像,必须通过镜像仓库去管理,这里可能会去写一个脚本去连接k8smaster,而k8s会根据自己的部署去调度这些pod,然后通过ingress去发布我们的应用,让用户去访问,每个ingress会关联一组pod,而service会创建这组pod的负载均衡,通过service去区分这些节点上的Pod,然后数据库是放在集群之外,监控系统日志系统也可以放在k8s集群放在去部署,也可以放在之外
,我们是放在k8s集群内的,也不是特别敏感,主要用来运维和开发调试用的,不会影响到我们的业务,所以我们优先去k8s中去部署。
现在我们去部署一个JAVA项目到我们的k8s中
一、安装一个openjdk还是maven用来编译
[root@k8s-master ~]# yum -y install java-1.8.0-openjdk.x86_64 maven
[root@k8s-master ~]# java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
然后我们将代码拉到本地一般Dockerfile中跟我们的代码都放在同一目录下,
[root@k8s-master tomcat-java-demo-master]# ls
db Dockerfile LICENSE pom.xml README.md src
[root@k8s-master tomcat-java-demo-master]# vim Dockerfile
FROM lizhenliang/tomcat
LABEL maintainer zhaochengcheng
RUN rm -rf /usr/local/tomcat/webapps/*
ADD target/*.war /usr/local/tomcat/webapps/ROOT.war
二、进行编译
然后这里我们需要配置maven的国内源,这样的话就比较快一点
[root@k8s-master CI]# vim /etc/maven/settings.xml
<mirror>
<id>central</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
[root@k8s-master tomcat-java-demo-master]# mvn clean package -D maven test.skip=true
[root@k8s-master tomcat-java-demo-master]# ls
db Dockerfile LICENSE pom.xml README.md src target
[root@k8s-master tomcat-java-demo-master]# cd target/
[root@k8s-master target]# ls
classes generated-sources ly-simple-tomcat-0.0.1-SNAPSHOT ly-simple-tomcat-0.0.1-SNAPSHOT.war maven-archiver maven-status
[root@k8s-master tomcat-java-demo-master]# cd target/
我们就使用这个编译好的war包,然后打成镜像,上传到我们的Harbor仓库里
[root@k8s-master target]# ls
classes ly-simple-tomcat-0.0.1-SNAPSHOT maven-archiver
generated-sources ly-simple-tomcat-0.0.1-SNAPSHOT.war maven-status
[root@k8s-master tomcat-java-demo-master]# docker build -t 192.168.30.24/library/java-demo:latest .
三、然后上传到我们的镜像仓库
[root@k8s-master tomcat-java-demo-master]# docker login 192.168.30.24
Username: admin
Password:
Error response from daemon: Get https://192.168.30.24/v2/: dial tcp 192.168.30.24:443: connect: connection refused
这里报错,其实我们需要在每台docker下都要写入对harbor仓库的信任才可以,后面上传镜像也会用
[root@k8s-master java-demo]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"insecure-registries": ["192.168.30.24"]
}
再等录一下push就可以了[root@k8s-master tomcat-java-demo-master]# docker push 192.168.30.24/library/java-demo:latest
四、控制器管理pod
编写deployment,一般项目都写到自定义的命名空间下,名称写项目名称,方便记忆, name: tomcat-java-demo
namespace: test
另外就是下一个项目名称,这里分为多个,一般有很多的组件组成,所以下面可以写个app的名称,比如组件1、2、3,起码标签有这两个维度
project: www
app: java-demo
另外就是镜像拉取,在哪个仓库去下载,这里我建议镜像仓库的项目名称和我们定义的是一种,避免混了
我重新打个标签,并传到我们的私有镜像仓库中
[root@k8s-master java-demo]# docker tag 192.168.30.24/library/java-demo 192.168.30.24/tomcat-java-demo/java-demo
[root@k8s-master java-demo]# docker push 192.168.30.24/tomcat-java-demo/java-demo:latest
镜像地址也改一下地址
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: tomcat
image: 192.168.30.24/tomcat-java-demo/java-demo:latest
现在开始创建我们的yaml
创建项目的命名空间
[root@k8s-master java-demo]# vim namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
[root@k8s-master java-demo]# kubectl create -f namespace.yaml
namespace/test created
[root@k8s-master java-demo]# kubectl get ns
NAME STATUS AGE
default Active 22h
kube-node-lease Active 22h
kube-public Active 22h
kube-system Active 22h
test Active 5s
创建一个secret来保证我们harbor镜像仓库的认证信息,这里一定要写上我们的项目的命名空间
[root@k8s-master java-demo]# kubectl create secret docker-registry registry-pull-secret --docker-username=admin --docker-password=Harbor12345 [email protected] --docker-server=192.168.30.24 -n test
secret/registry-pull-secret created
[root@k8s-master java-demo]# kubectl get ns
NAME STATUS AGE
default Active 23h
kube-node-lease Active 23h
kube-public Active 23h
kube-system Active 23h
test Active 6m39s
[root@k8s-master java-demo]# kubectl get secret
NAME TYPE DATA AGE
default-token-2vtgm kubernetes.io/service-account-token 3 23h
registry-pull-secret kubernetes.io/dockerconfigjson 1 46s
[root@k8s-master java-demo]# vim deployment.yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: tomcat-java-demo
namespace: test
spec:
replicas: 3
selector:
matchLabels:
project: www
app: java-demo
template:
metadata:
labels:
project: www
app: java-demo
spec:
imagePullSecrets:
- name: registry-pull-secret
containers:
- name: tomcat
image: 192.168.30.24/tomcat-java-demo/java-demo:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
name: web
protocol: TCP
resources:
requests:
cpu: 0.5
memory: 1Gi
limits:
cpu: 1
memory: 2Gi
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 20
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 60
timeoutSeconds: 20
[root@k8s-master java-demo]# kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
tomcat-java-demo-6d798c6996-fjjvk 1/1 Running 0 2m58s
tomcat-java-demo-6d798c6996-lbklf 1/1 Running 0 2m58s
tomcat-java-demo-6d798c6996-strth 1/1 Running 0 2m58s
另外就是暴露一个Service,这里的标签也要保持一致,不然他找不到相应的标签就提供不了服务,这里我们是使用ingress来访问发布应该,直接使用ClusterIP就可以
[root@k8s-master java-demo]# vim service.yaml
apiVersion: v1
kind: Service
metadata:
name: tomcat-java-demo
namespace: test
spec:
selector:
project: www
app: java-demo
ports:
- name: web
port: 80
targetPort: 8080
[root@k8s-master java-demo]# kubectl get pod,svc -n test
NAME READY STATUS RESTARTS AGE
pod/tomcat-java-demo-6d798c6996-fjjvk 1/1 Running 0 37m
pod/tomcat-java-demo-6d798c6996-lbklf 1/1 Running 0 37m
pod/tomcat-java-demo-6d798c6996-strth 1/1 Running 0 37m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tomcat-java-demo ClusterIP 10.1.175.191 <none> 80/TCP 19s
测试访问我们的项目,是可以的,现在要发布出去通过ingress
[root@k8s-master java-demo]# curl 10.1.175.191
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>把美女带回家应用案例</title>
<meta name="description" content="把美女带回家应用案例">
<meta name="keywords" content="index">
Ingress-nginx now deploy a controller, which can be found online, the official there, I am here by DaemonSet way to deployment, each node will run a controller
[root@k8s-master java-demo]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-g95pp 1/1 Running 0 3m6s
nginx-ingress-controller-wq6l6 1/1 Running 0 3m6s
Published Application
here two things, first is the site domain name, a namespace is a service of
[root@k8s-master java-demo]# kubectl get pod,svc -n test
NAME READY STATUS RESTARTS AGE
pod/tomcat-java-demo-6d798c6996-fjjvk 1/1 Running 0 53m
pod/tomcat-java-demo-6d798c6996-lbklf 1/1 Running 0 53m
pod/tomcat-java-demo-6d798c6996-strth 1/1 Running 0 53m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tomcat-java-demo ClusterIP 10.1.175.191 <none> 80/TCP 16m
[root@k8s-master java-demo]# vim service.yaml
[root@k8s-master java-demo]# kubectl create -f ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: tomcat-java-demo
namespace: test
spec:
rules:
- host: java.maidikebi.com
http:
paths:
- path: /
backend:
serviceName: tomcat-java-demo
servicePort: 80
In addition, I was testing here, so bind my local hosts to access the
join node and domain name and ip in hosts file which will be able to visit our project of