原来Kubernetes部署如此简单,看完全明白了

杰哥的IT之旅

共 17897字,需浏览 36分钟

 ·

2021-03-14 20:21

公众号关注“杰哥的IT之旅”,

选择“星标”,重磅干货,第一时间送达!


来自:51CTO博客,作者:wx5c1cfd6e22842

链接:https://blog.51cto.com/14143894/2437186

制作镜像

制作镜像分为三步:


  • 第一步基础镜像,是基于哪个操作系统,比如CentOS 7或者其他的

  • 第二步中间件镜像,比如服务镜像,跑的像Nginx服务,Tomcat服务

  • 第三步项目镜像,它是服务镜像之上的,将你的项目打包进去,那么这个项目就能在你这个服务镜像里面运行了



一般我们运维人员都是提前将我们的镜像做好,而开发人员就能直接拿这个镜像去用,这个镜像一定要符合现在环境部署的环境。

控制器管理Pod

也就是Kubernetes去部署这个镜像了,一般我们都会去拿控制器去部署,用的最多的就是Deployment。

  • Deployment:无状态部署

  • StatefulSet:有状态部署

  • DaemonSet:守护进程部署

  • Job & CronJob:批处理


无状态和有状态的有什么区别?

有状态的是有身份的,比如网络ID、存储,这两个是提前规划好的,有序启动/停止。

Pod数据持久化

Pod数据持久化主要是应对一个应用程序说的,比如开发一个项目,这个项目有没有落地到本地文件,如果有落的话,就保证他持久的有了,那就必须要用到Pod数据的持久化了。


容器部署过程中一般有以下三种数据:

  • 启动时需要的初始数据,可以是配置文件

  • 启动过程中产生的临时数据,该临时数据需要多个容器间共享

  • 启动过程中产生的持久化数据

暴露应用

在Kubernetes中,部署一个Deployment是无法对外进行访问的,就是别的应用程序要想访问部署的Deployment,找不到该怎么去访问,为什么这么讲,因为Deployment一般都是多副本部署的,有可能会分布在不同的节点之上,而且重建Pod IP也会变,重新发布一下也会改变,所以没有办法去固定去访问哪个Pod,即使固定了,其他的Pod也访问不了,要想做到多个Pod都去提供服务,前面就必须要加一个负载均衡,提供一个访问入口,只有访问这个统一入口,才能转发到后端多个Pod上,只要访问这个Cluster IP就能转发到后端的Pod上。


Service

  • Service定义了Pod的逻辑集合和访问这个集合的策略

  • Service的引入为解决Pod的动态变化,提供了服务发现和负载均衡

  • 使用CoreDNS解析Service名称

对外发布应用


暴露出去之后,也就是需要让用户去访问,比如搭建一个电商网站,让用户去访问,Ingress相对于Service,是一个互补的状态,Service主要提供了集群内部的访问,也可以暴露一个TCP/UDP的端口,而Ingress主要是一个7层的转发,也就是提供一个统一的入口,只要访问Ingress Controller,就能帮你转发你部署所有的项目,也就是所有的项目都使用域名去访问。

传统部署与Kubernetes部署的区别


传统部署首先开发者将代码部署到你的代码仓库中,主流是使用Git或者GitLab,提交完代码通过CI/CD平台需要对代码进行拉取、编译、构建,产生一个War包,交给Ansible,然后发送到云主机上/物理机,之后通过负载均衡将项目暴露出去,最后会有数据库,监控系统,日志系统来提供相关的服务。


Kubernetes部署首先也是开发将代码放在代码仓库,然后通过Jenkins去完成拉取代码,编译,上传到我们的镜像仓库,这里是将代码打包成一个镜像,而不是刻意执行的war或者jar包,这个镜像包含了你项目的运行环境和项目代码,这个镜像可以放在任何Docker上去run起来,都可以去访问,首先得保证能够在Docker上去部署起来,再部署到Kubernetes上,打出来的镜像去放在镜像仓库中,来集中管理这些镜像。

因为每天会产生几十或者上百个镜像,所以必须通过镜像仓库去管理,这里可能会去写一个脚本去连接Kubernetes Master,而Kubernetes会根据自己的部署去调度这些Pod,然后通过Ingress去发布我们的应用,让用户去访问。每个Ingress会关联一组Pod,而Service会创建这组Pod的负载均衡,通过Service去区分这些节点上的Pod,数据库放在集群之外,监控系统、日志系统也可以放在Kubernetes集群去部署,也可以放在集群之外。我们是放在Kubernetes集群内的,也不是特别敏感,主要用来运维和开发调试用,不会影响到我们的业务,所以我们优先去Kubernetes中部署。

现在我们去部署一个Java项目到我们的Kubernetes中。

1、安装OpenJDK
[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
2、使用Maven进行编译

这里我们需要配置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 .
3、上传到我们的镜像仓库
[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


4、控制器管理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 --docker-email=111@qq.com --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的控制器,这个网上都可以找到,官方也有,我这里是按DaemonSet的方式去部署的,所以每个节点都会跑一个控制器。
[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

发布应用

这里注意两点,一个是网站域名,一个是Service的命名空间。
[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
另外我这边是测试的,所以绑定我本地的hosts来进行访问。在hosts文件里面加入域名和节点IP就能访问到我们的项目了。

推荐阅读

超详细!K8S 面试题总结

IT运维面试问题总结-LVS、Keepalived、HAProxy、Kubernetes、OpenShift等

2020 年度开发者工具 TOP 100 名单!

又一款 Nginx 管理可视化神器!通过界面完成配置监控

速度快,性能好!压缩神器 zstd

浏览 51
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报