2. Kubernates

1 集群环境容器部署问题

  1. 集群内每台机器应该分配几个容器
  2. 如何根据业务量动态调整容器个数
  3. 机器数量过多,部署工作量大

2 容器编排工具

  1. docker-compose:单击容器编排工具
  2. docker swarm:docker官方提供的集群容器编排工具
  3. kubernetes:简称k8s,因为k和s之间有8个英文字母,google官方提供的容器编排工具,底层完全基于docker,与docker swarm属于竞争关系

3 Kubernetes功能

  1. 自动化容器部署和复制:只需要通过脚本规划好容器在哪些主机运行,运行多少个副本
  2. 随时扩展或收缩容器规模:通过修改参数,可以人工或自动增加计算单元个数,例如将tomcat从10个缩小成5个
  3. 容器分组Group,并提供容器间的负载均衡:没有K8S前需要使用nginx完成负载均衡,K8S本身提供了负载均衡功能
  4. 实时监控, 即时故障发现, 自动替换:K8S提供管理界面,可以实时看到所有容器的情况

4 K8S中基本概念

在这里插入图片描述

  1. 每个方框都代表一台容器的宿主机,他们共同形成了一个K8S集群,这些宿主机根据角色可划分为Master和Node
  2. Master:主服务器,集群管理者。通过主服务器向具体的节点发送创建容器、自动部署、自动发布等命令,外界请求也由Master接收,再由它将请求分配给Node,通常使用一台独立的物理机作为Master
    1. Replication Controller:复制控制器,位于主节点,用于对Pod数量进行监控,例如我们需要三个红色的Pod,如果Replication Controller发现少了一个,他就会额外创建一个新Pod出来。且如果一个Pod失去响应,会将这个Pod剔除,用一个新的替换它。Replication Controller可以根据参数值动态调整Pod个数
  3. Node:节点,通常可以是独立物理机,也可以是虚拟机
    1. Pod:存在于Node中,是K8S控制的最小单元。Pod译为豆角,豆角一个皮中包含很多豆子,意思就是一个Pod中可以包含多个容器(Container)
      1. Pod内部容器网络互通,每个Pod都有独立虚拟IP,由K8S统一管理
      2. 同一节点下Pod间网络互通
      3. 不通节点下Pod间网络不通,需要依靠Service通信
      4. 项目不同,Pod中包含内容不同,对应小公司,一个Pod可能是一套完整环境,包含tomcat、redis、db。而对于大公司,可能一个Pod只部署一个职能,比如只部署tomcat
      5. 每个Pod中都包含一个特殊的容器(Container),叫做Pause,用于提供共享网络空间。如果没有Pause时,一个Pod下两个容器tomcat和nginx彼此通信时,需要通过对方ip或对方容器名进行访问,有了Pause后,可以将Pod看作一个整体,nginx和tomcat使用localhost就能访问彼此,同时Pause会为当前Pod提供一个共享的volume(挂载的数据卷)
    2. Service:可以让两个Pod互通,且可以作为负载均衡对外提供服务
    3. Labels:标签,相当于Pod的别名,定义了标签,K8S的Master才能找到对应的Pod,并对其进行操作
    4. kubelet、kube-proxy、docker:每个Node上都需要安装的应用程序
      1. kubelet:负责启动Pod和容器
      2. kube-proxy:负责Service功能的具体实现

5 k8s安装

  1. 从google中央仓库安装:外网不通
  2. 使用快速部署工具kubeadm:推荐,当前学习的是1.14
  3. 使用阿里公有云平台k8s:收费
  4. 通过yum官方仓库安装:版本太旧
  5. 通过二进制包的形式进行安装:kubeasz (github),这种方式安装的k8s可能有bug,或底层可能被篡改
5.1 CentOS7集群搭建
  1. 环境准备

    1. Master:192.168.246.132
    2. Node1:192.168.163.133
  2. 设置主机名与时区

    timedatectl set-timezone Asia/Shanghai
    #只对master执行
    hostnamectl set-hostname master   
    
  3. 添加hosts网络主机配置

    vim /etc/hosts
    192.168.163.132 master
    192.168.163.133 node1
    
  4. 禁用SELINUX

    #SELINUX:linux内置的安全增强模块,设置起来太费劲,因此禁用掉
    sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
    #设置为临时生效
    setenforce 0
    
  5. 关闭防火墙

    #禁用防火墙
    systemctl disable firewalld
    #停止防火墙
    systemctl stop firewalld
    
5.2 离线安装kubeadmin、docker、导入k8s镜像
  1. 将镜像包kubernetes-1.14上传至各服务器

    mkdir /usr/local/k8s-install
    cd /usr/local/k8s-install
    cp -r /mnt/hgfs/wusihan/Downloads/kubernetes-1.14 .
    
  2. 安装、启动docker-ce,如果已经安装了docker,可以跳过

    cd ./kubernetes-1.14
    tar -zxvf docker-ce-18.09.tar.gz
    cd docker
    #localinstall:表示加载当前目录下所有rpm文件,自动完成安装
    yum localinstall -y *.rpm
    #启动docker
    systemctl start docker
    #设置docker为开机自动启动
    systemctl enable docker
    
  3. 确保两台机器的cgroups在同一个groupfs上

    #1. cgroups是control groups的简称,是linux内核提供的一种机制,可以实现Docker中资源管理、控制
    #2. 同一集群中的所有docker的cgroups必须相同
    #3. 默认cgroups都应该是cgroupfs
    docker info | grep cgroup
    #4. 如果不同需要修改
    cat << EOF > /etc/docker/daemon.json
    {
      "exec-opts": ["native.cgroupdriver=cgroupfs"]
    }
    EOF
    systemctl daemon-reload && systemctl restart docker
    
  4. 安装kubeadm

    cd /usr/local/k8s-install/kubernetes-1.14
    tar -zxvf kube114-rpm.tar.gz
    cd kube114-rpm
    yum localinstall -y *.rpm
    
  5. 关闭交换区

    #1. 交换分区类似windows虚拟内存,就是内存不足时,写入内存的操作会被写入硬盘,读取内存操作从硬盘读取,所以虚拟内存可能导致系统性能降低
    #2. k8s的环境下, 一般内存都充裕,不建议使用交换分区,可能影响性能
    swapoff -a
    #将swap那行注释
    vi /etc/fstab
    
  6. 配置网桥

    #iptable是linux中的网络工具,用于对我们的包按规则进行过滤,此处配置表示在k8s容器间进行网络通信时,也要遵循iptable的规则,这样可以提升系统间网络传输的安全性
    cat <<EOF >  /etc/sysctl.d/k8s.conf
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    EOF
    #检查是否修改成功
    sysctl --system
    
  7. 导入k8s相关镜像

    cd /usr/local/k8s-install/kubernetes-1.14
    #1. docker load : 导入使用docker save命令导出的镜像
    #2. 导入k8s相关的一系列镜像:kube-proxy、kube-apiserver、kube-controller-manager、kube-scheduler、coredns、etcd、pause
    docker load -i k8s-114-images.tar.gz
    #3. 导入监控集群状态工具:kubernetes-dashboard-amd64、flannel
    docker load -i flannel-dashboard.tar.gz
    #4. 查看新增的镜像
    #a. kube-proxy:用于实现Service
    #b. kube-apiserver:api服务端
    #c. kube-controller-manager:集群控制器
    #d. kube-scheduler:负责任务调度
    #e. flannel:coredns进行跨Pod通信依赖的组件
    #f. coredns:每个节点中基础的网络应用
    #g. kubernetes-dashboard-amd64:kubernetes官方提供的web管理界面,用于监控集群状态
    #h. etcd:数据存储模块
    #i. pause:用于网络命名空间的共享(localhost)以及共享数据卷
    docker images
    
5.3 利用kubeadm构建k8s集群
  1. 使用kubeadm构建Master

    #只在master执行,kubernetes-version:指明要安装的k8s的版本,--pod-network-cidr:指定k8s创建的Pod的虚拟ip的范围
    kubeadm init --kubernetes-version=v1.14.1 --pod-network-cidr=10.244.0.0/16
    #如果构建Master失败,可以通过如下命令重置环境,之后可以重新执行kubeadm init命令
    kubeadm reset 
    
  2. 执行完毕后,相当于k8s就已经搭建好了,docker ps发现多了很多容器,所以说,kubeadm的作用,可以简单的理解为,通过k8s相关镜像,快速启动一系列k8s相关的容器,从而完成整个k8s环境的创建

  3. 创建kubeadm对当前k8s集群的核心配置文件

    #只在master中执行
    #下方脚本在步骤1控制台中打印
    mkdir -p $HOME/.kube
    #admin.conf:kubeadm对于当前集群的核心配置文件,里面有关于该集群安全的授权信息,master的节点的信息,例如ip地址等
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
  4. 此时k8s环境已经搭建完毕,可以通过kubectl对k8s集群进行管理

    #1. 查看k8s中各节点状态
    kubectl get nodes
    
    #2. 发现master状态为NotReady,这可能是因为master中有Pod未正常启动导致
    kubectl get pod --all-namespaces
    
    #3. 发现有些status为CrashLoopBackOff:表示前面创建失败了,后台在尝试不断创建,restarts为5表示重建了5次,这种状态一般等一会自己就能创建好,如果长时间反复出现CrashLoopBackOff,代表硬件条件不够,需要增加硬件
    
    #4. 还有一些status为Pending,表示等待状态,例如coredns,这是因为底层缺少额外的flannel网络组件导致,flannel是k8s中跨pod通信最底层依赖的网络协议
    #5. 安装flannel网络组件后,Pod全部变为Running,且master变为Ready状态
    cd /usr/local/k8s-install/kubernetes-1.14
    kubectl create -f kube-flannel.yml
    
  5. 将node1加入k8s集群

    #下方脚本在步骤1控制台中打印,只在node1中执行
    #1. 如果没有kubeadm,加入集群比较麻烦,有了kubeadm只需要如下一行代码
    kubeadm join 192.168.246.132:6443 --token r8k7mb.x20z1g9lylrxynpb --discovery-token-ca-cert-hash sha256:a5f2252c8c9250fd5fdbb4c4da85b9426124503d758548ab2050c5cb4da35f2d
        
    #2. 如果第一步执行后,没有记录控制台打印日志,可以在master上执行如下命令查看令牌列表,为r8k7mb.x20z1g9lylrxynpb
    kubeadm token list
    #在node上执行如下命令加入k8s集群,--discovery-token-unsafe-skip-ca-verification:表示不进行token的安全校验
    kubeadm join 192.168.163.132:6443 --token r8k7mb.x20z1g9lylrxynpb --discovery-token-unsafe-skip-ca-verification
    
5.4 kubelet启动节点
  1. kubelet运行在所有节点上,负责启动POD和容器,以系统服务形式出现

  2. 当master或node1宕机重启后,需要依赖kubelet服务启动k8s集群或重新加入集群

    #master或node1重启后,需要执行如下命令恢复集群
    systemctl start kubelet
    #设置kubelet开机启动,这样不必每次重启master或node1都要手工启动kubelet
    systemctl enable kubelet
    

6 启用Dashboard

  1. Dashboard翻译过来是仪表盘,是kubernetes官方提供的web管理界面,只需在master上部署

    cd /usr/local/k8s-install/kubernetes-1.14
    #kubectl apply -f:利用部署文件,创建、更新Pod,其实就是创建了一个Pod,Pod包含一个dashboard容器和一个pause容器
    #1. kubernetes-dashboard.yaml:Dashboard的核心配置
    kubectl apply -f kubernetes-dashboard.yaml
    #2. admin-role.yaml:表示管理员的角色,以及有哪些职能
    kubectl apply -f admin-role.yaml
    #3. rbac为基于角色进行访问控制,该文件定义了系统应用权限所在
    kubectl apply -f kubernetes-dashboard-admin.rbac.yaml
    #4. 获取kube-system下服务有哪些,发现kubernetes-dashboard出现,对外暴露端口为32000
    kubectl -n kube-system get svc
    
  2. 通过http://192.168.246.132:32000 访问Dashboard

7 利用Dashboard部署tomcat集群

  1. 保证两台机器都配置了docker镜像加速,否则创建容器可能无法下载

  2. Dashboard运行在master上,master发送创建容器请求给node1,node1收到后,先下载镜像,再启动容器

  3. 进入Dashboard–工作负载–部署容器应用–创建应用

    1. 应用名称:my-tomcat1
    2. 容器镜像:tomcat:latest
    3. 容器个数:2,表示在两台node上布置几个tomcat副本
    4. 服务:外部,表示对外暴露创建的tomcat容器的端口,其他电脑可以通过网络访问到这些创建的容器,如果不是外部服务,其他电脑无法访问
      1. 端口:8000,表示Pod的端口,并不是kubernetes所在宿主机的端口,外界不是通过该端口访问tomcat
      2. 目标端口:8080,表示容器对Pod暴露的端口
    5. 部署
  4. docker images发现多了一个tomcat镜像 ,docker ps发现多了一个tomcat容器

  5. 查看tomcat集群状态:进入Dashboard–副本集–my-tomcat1-69b7b678d5–服务–my-tomcat1–容器组,可以看到两个容器所在节点、状态、以及日志信息

  6. 查看tomcat集群对外暴露的端口号:进入Dashboard–副本集–my-tomcat1-69b7b678d5–服务–内部端点,显示端口号为31455,这个端口号是随机生成的,虽然两个tomcat容器都在node1上,但在外部通过http://192.168.246.132:31455/http://192.168.246.133:31455/都能访问tomcat服务

  7. 模拟一台tomcat宕机的情况

    #node1上执行,f07e06106503为其中一个tomcat容器的id
    docker rm -f f07e06106503
    #k8s会实时监控集群中各容器状态,一旦发现容器挂掉,会自动重启该容器,发现过一会,tomcat容器会被自动重启,docker ps发现容器重新出现
    

8 kubectl使用yaml资源文件部署tomcat集群

  1. 所谓部署指master向node发送指令,创建容器的过程

  2. Kubernetes支持yml格式的部署脚本

  3. kubectl部署相关命令

    #1. 部署一个新Pod
    kubectl create -f 部署脚本
    #2. 创建或更新部署过的Pod
    kubectl apply -f 部署脚本
    #3. 查看所有已部署的Pod,-o wide为可选参数,让显示的信息更全面,例如能够显示这些Pod所在节点、pod的ip等
    kubectl get pods <-o wide>
    #4. 查看所有命名空间下的pods,也就是不只查看人为部署的pod,还查看创建k8s集群时,创建的那些pod(这些pod命名空间为kube-system)
    kubectl get pods --all-namespaces
    #5. 查看Pod详细信息,无法查看kube-system命名空间下的pod
    kubectl describe pod <pod名>
    #查看指定pod的控制台日志,-f表示是否实时更新日志,例如pod里如果只创建了一个tomcat容器,那么此处看的就是tomcat控制台日志
    kubectl logs <-f> pod名
    
8.1 部署tomcat集群
  1. 创建用于部署的资源文件tomcat-deploy.yml

    #文件名写什么都可以
    vi /root/k8s/tomcat-deploy/tomcat-deploy.yml
    
  2. tomcat-deploy.yml

    #1. 解析yml文件使用的api版本,可以通过kubectl api-versions查看支持的api版本
    apiVersion: extensions/v1beta1
    #2. pod、service、deployment都可以看作是一种资源,yaml的用处就是创建这些资源中的一种,此处用于指定要创建的资源为deployment
    #3. deployment是K8S中负责管理Pod的资源对象,它定义Pod的部署属性,比如有几个副本,副本异常怎么处理等
    kind: Deployment
    metadata:
      #4. 资源的名字,通过kubectl get deployment查到的部署名就是这个,在同一个namespace中必须唯一
      name: tomcat-deploy
    #5. 当前资源规范
    spec: 
      #6. Pod副本个数
      replicas: 2
      #7. Pod使用的模版,也就是这两个Pod应该如何创建
      template:
        metadata:
          #8. labels:Pod的标签,也可以看作为Pod起了一个别名
          labels:
            app: tomcat-cluster
        #9. 定义Pod的资源规范
        spec:
          #10. 对Pod中容器进行设置
          containers: 
          #11. -代表containers下的集合,这里表示containers这个集合中,有一个元素,这个元素有name、image、ports三个属性,而ports属性也是一个集合,起内有一个元素containerPort
          #12. 容器别名为tomcat-cluster,该名和app中的名字通常设成一样的
          - name: tomcat-cluster
            #13. 表示使用tomcat镜像
            image: tomcat:latest
            #14. 容器对外暴露的端口号
            ports: 
            - containerPort: 8080
    
  3. 创建部署

    #1. 创建部署,部署创建成功不代表Pod和容器创建成功,所以需要进一步查看Pod和容器的状态
    kubectl create -f ./tomcat-deploy.yml
    #2. 查看所有部署,READY为2/2表示一个部署中有两个Pod,且都已创建完毕,AVAILABLE为2表示两个Pod都可用
    kubectl get deployment
    #3. 查看Pod的详细信息
    #NAME:Pod名
    #STATUS:Running表示正在运行
    #IP:Pod的虚拟ip,这个ip无法从外界直接访问
    #NODE:Pod所在节点
    #READY:1/1表示Pod中有一个容器,这个容器现在状态是READY
    kubectl get pod -o wide
    #4. 查看Pod更加详细的描述
    #Events:Pod从创建到现在都经历了什么
    kubectl describe pod pod名
    #5. 查看Pod日志
    kubectl logs pod名
    
8.2 外部访问tomcat集群
  1. 通过资源文件部署的tomcat集群,到现在为止,还无法被外界访问

  2. 在K8S中,Service是对Pod对象的抽象,通常Pod会以多副本的形式部署,每个Pod都有自己的IP,都可以对外提供服务,但Pod随时都有可能被频繁地销毁和重启,IP也会随之改变,会导致服务的访问出现问题。Service就是提出来解决这个问题的,它定义了一个虚拟IP(集群IP),这个 IP在Service的整个生命周期内都不会改变,我们可以将请求发送给Service,Service会将请求导向给Pod,如果存在多个Pod,Service还能实现负载均衡

  3. 设置Service时,也可以同时将Pod内部端口与其所在宿主机端口进行映射,这样可以不通过Service,而是直接访问Pod的宿主机来访问Pod中的服务,但这样做不推荐,因为这样Service提供的负载均衡功能就失效了

    在这里插入图片描述

  4. 创建Service资源文件tomcat-service.yml

    vim /root/k8s/tomcat-service/tomcat-service.yml
    
  5. tomcat-service.yml

    #1. 解析yml文件使用的api版本,用v1或之前的extensions/v1beta1都可以
    apiVersion: v1
    #2. 说明当前yml文件,用于配置一个service
    kind: Service
    metadata:
      name: tomcat-service
      #为当前资源打一个标签,用于后面引用
      labels:
        app: tomcat-service
    spec: 
      #3. 设置Service类型为NodePort,表示创建的Service,会在每个Node中开辟一个端口,和tomcat容器进行端口映射
      type: NodePort
      #4. 上面的yml文件中,通过labels中定义了Pod的标签,此处可以通过selector中填写该Pod标签,当前资源可以与标签为tomcat-cluster的资源互通
      selector:
        app: tomcat-cluster
      ports:
      #5. 设置Service接收服务的端口
      - port: 8000
        #6. tomcat容器对外暴露的端口
        targetPort: 8080
        #7. 用宿主机上的32500端口与tomcat容器的8080端口映射
        nodePort: 32500
    
  6. 创建Service

    kubectl create -f ./tomcat-service.yml
    #查看所有的Service
    kubectl get service
    #查看Service的详细描述
    #NodePort:宿主机上暴露的端口
    #Endpoints:tomcat容器的ip和对外暴露的端口,这两个端口和宿主机上的端口进行映射
    #IP:Service的虚拟IP
    #Port:Service提供服务的端口号
    kubectl describe service Service名
    
  7. 此时可以输入MasterIP:32500或Node1IP:32500完成Node1一个节点上,两个tomcat的负载访问,注意如果两个tomcat不在一个pod中,例如图中所示,NodePort类型的Service就无法完成负载功能了

9 基于NFS实现集群内的文件共享

  1. NFS:Network File System,网络文件系统,是由SUN公司研制的文件传输协议,采用远程过程调用RPC机制,实现文件在网络中进行共享和传输,配置NFS后,读写网络中文件时,就像在本地操作文件一样方便

  2. 项目拓扑

    在这里插入图片描述

9.1 NFS配置
  1. master安装NFS

    #下面命令需要在文件提供方进行安装,这里我们选master为文件提供方
    #1. nfs-utils为nfs工具集,rpcbind为rpc协议底层支持
    yum install -y nfs-utils rpcbind
    #2. 创建需共享的文件夹,www-data最后就是tomcat下的webapps
    mkdir -p /usr/local/data/www-data
    
  2. master设置对外暴露的文件夹

    vim /etc/exports
    
    #/usr/local/data/www-data:对外暴露的文件夹
    #192.168.246.132:文件夹所在的主机的IP
    #24:子网掩码
    #rw:共享的目录可读可写
    #sync:同步写入,一旦远程或本地产生了文件变化,文件内容都会即时更新
    /usr/local/data/www-data 192.168.246.132/24(rw,sync)
    
  3. master启动NFS服务:master执行

    #1. 启动nfs服务
    systemctl start nfs.service
    #2. 启动rpc绑定服务
    systemctl start rpcbind.service
    #3. 设置开机启动
    systemctl enable nfs.service
    systemctl enable rpcbind.service
    #4. 查看文件共享列表,如果出现了刚才的设置,证明配置正确
    exportfs
    
  4. node1安装NFS并挂载远程目录到本地

    #1. 只需要安装nfs-utils,不需要安装rpcbind
    yum install -y nfs-utils
    #2. 设置NFS开机启动
    systemctl enable nfs.service
    #3. 查看192.168.246.132上,对外共享文件夹有哪些
    showmount -e 192.168.246.132
    #4. 挂载远程目录到本地的/mnt下
    mount 192.168.246.132:/usr/local/data/www-data /mnt
    
9.2 将/mnt中内容映射到tomcat容器的webapps
  1. 由于之前启动了一个tomcat集群,因此需要先将该集群服务删除

    #master中执行
    #1. 查看现有部署,其实也可以在现有部署上进行更新
    kubectl get deployment
    #2. 删除部署
    kubectrl delete deployment 部署名
    #3. 部署删除后,pod也会被自动删除
    kubectrl get pod
    #4. 部署删除后,容器也会被自动删除
    docker ps
    #5. service不会被自动删除,需要手动删除
    kubectl get service
    #6. 删除service 
    kubectl delete service service名
    
  2. 修改tomcat-deploy.yml完成数据卷挂载

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: tomcat-deploy
    spec: 
      replicas: 2
      template:
        metadata:
          labels:
            app: tomcat-cluster
        spec:
          #在原基础上增加volumes,表示增加数据卷,表示将宿主机某个文件夹,向容器内进行挂载
          volumes:
          #定义挂载的数据卷的别名
          - name: web-app
            #设置宿主机原始目录
            hostPath:
              path: /mnt
          containers: 
          - name: tomcat-cluster
            image: tomcat:latest
            ports: 
            - containerPort: 8080
            #表示将web-app挂载到/usr/local/tomcat/webapps,就是用/mnt中文件,替代/usr/local/tomcat/webapps中文件
            volumeMounts:
            - name: web-app
              mountPath: /usr/local/tomcat/webapps
    
  3. 重新创建部署

    #1. 创建部署
    kubectl create -f tomcat-deploy.yml
    #2. 查看部署
    kubectl get deployment
    #3. 查看pod
    kubectl get pod
    #4. 查看tomcat容器id,node1上执行
    docker ps
    #5. 进入容器查看/usr/local/tomcat/webapps中内容是否和NFS配置的共享文件夹中内容相同
    docker exec -it 容器id /bin/bash
    #6. 修改master上共享文件夹中内容,再次查看tomcat容器中webapps中内容,确实被实时修改
    #7. 还可以在master中执行如下命令进入Pod进行验证
    kubectl get pod -o wide
    #8. 进入pod所在节点的tomcat容器中,在这里也可以查看/usr/local/tomcat/webapps中内容
    kubectl exec -it pod名 /bin/bash
    

10 Service负载均衡

  1. 修改tomcat-service.yml

    apiVersion: v1
    kind: Service
    metadata:
      name: tomcat-service
      labels:
        app: tomcat-service
    spec: 
      #只要将如下两行注释掉即可
      #type: NodePort
      selector:
        app: tomcat-cluster
      ports:
      - port: 8000
        targetPort: 8080
        #nodePort: 32500
    
  2. 创建Service

    kubectl create -f tomcat-service.yml
    #查看service
    kubectl get service
    #查看service详细信息
    #发现宿主机上暴露的端口,NodePort项不在了
    kubectl describe service tomcat-service
    
  3. master上访问Service

    #使用curl命令,向Service的ip和port上发送请求,发现会返回404错误,说明请求被转发到了node1或node2上的服务上
    curl 10.100.95.153:8000
    
  4. 通过NFS完成tomcat部署

    #由于master已经共享给了node,可以通过修改master中内容,完成应用部署,master上执行
    cd /usr/local/data/www-data
    mkdir test 
    cd test
    vi index.jsp
    
  5. index.jsp

    //输出本机的ip,这样我们就能知道负载均衡访问的是具体哪个节点了
    <%=request.getLocalAddr()%>;
    
  6. 再次访问Service

    #多次执行,打印ip不同,可能打印node1上第一个Pod的ip也可能是node1上第二个Pod的ip,负载均衡策略为随机分配
    curl 10.100.95.153:8000/test/index.jsp
    

11 使用Rinetd将Service服务对外暴露

  1. service的IP为10.100.95.153,这不是一个有效的真实的IP,这个IP在master、node1上是可以访问的,但在外部192.168网段无法访问

  2. Rinetd是Linux操作系统中为重定向传输控制协议工具,可以将源IP端口数据转发至目标IP端口,我们可以利用Rinetd将Service的IP端口,与其所在宿主机的物理IP和端口进行映射,从而将Service服务对外暴露

  3. Rinetd安装

    cd /usr/local
    #上传rinetd源码包
    cp ./Downloads/rinetd.tar.gz /usr/local/rinetd.tar.gz
    #对gz进行解压
    tar -zxvf rinetd.tar.gz
    cd rinetd
    #调整允许的端口映射范围
    sed -i 's/65536/65535/g' rinetd.c
    #/usr/man为rinetd软件强制要求创建的目录
    mkdir -p /usr/man
    yum install -y gcc
    #提示install -m 700和644,说名rinetd安装成功
    make && make install
    
  4. 配置端口映射

    #1. 配置端口映射
    vim /etc/rinetd.conf
    #0.0.0.0:表示所有ip可以对当前宿主机发送请求
    #8000:表示在master上开通一个8000端口
    #10.100.95.153 8000:表示每当8000端口接收到外来请求,都转发给内部service的8000端口
    0.0.0.0 8000 10.100.95.153 8000
    #2. 加载该配置文件
    rinetd -c /etc/rinetd.conf
    #3. 查看是否映射成功,成功后,master上应该启动了一个8000端口
    netstat -tulpn|grep 8000
    
  5. 此时外界就可以通过<192.168.246.132:8000/test/index.jsp>访问service了,service会将请求负载给两个Pod中的tomcat容器

12 集群配置调整与资源限定

  1. 配置调整:例如原来2个tomcat,现在改为3个tomcat。k8s会采用可用资源优先原则,也就是哪个服务器负载低,就把新Pod发布在哪个节点上,这只是其中一个策略,我们也可以人为指定发布Pod到哪个节点

    #1. 修改yml文件
    #2. 使用新文件更新
    kubectl apply -f yml文件路径
    #3. 或者也可以删除部署和Service之后重新创建
    kubectl delete deployment/service 部署/服务名
    
  2. 资源限定:限制创建的容器使用多少cpu,和多少内存,修改tomcat-deploy.yml

    containers:
    - name: tomcat-cluster
      image: tomcat:latest
      resources:
        #1. request:设置当前容器运行的最低系统要求
        requests:
          #2. 目标节点至少有0.5核cpu空闲,此处cpu可以为小数
          cpu: 0.5
          #3. 目标节点至少有200M内存空闲
          memory: 200Mi
        #2. limits:设置最大不超过多少
        limits: 
          cpu: 1
          memory: 512Mi
    

13 k8s构建贝亲婴童商城

  1. 项目拓扑:由于资源有限,不搭建Node2,而是在Node1上部署两个tomcat应用

    在这里插入图片描述

  2. beiqin文件夹介绍

    1. dist
      1. application.yml:springboot配置文件,连接到哪个数据库都在其内配置
      2. beiqin-app.jar:贝亲商城应用
    2. sql
      1. beiqin.sql:数据库初始化脚本
13.1 将文件夹beiqin共享给Node1
#1. 将beiqin文件夹拷贝到共享目录/usr/local/beiqin中
cd /usr/local
cp -r /mnt/hgfs//wusihan/Downloads/源代码/k8s/beiqin .
#2. 配置文件共享路径,将beiqin中两个文件夹共享给其他节点
vim /etc/exports
/usr/local/beiqin/dist 192.168.163.132/24(rw,sync)
/usr/local/beiqin/sql 192.168.163.132/24(rw,sync)
#3. 重启服务
systemctl restart nfs.service
systemctl restart rpcbind.service
#4. 查看是否成功
exportfs
#5. node1上实现挂载
mkdir /usr/local/beiqin-dist
mkdir /usr/local/beiqin-sql
mount 192.168.246.132:/usr/local/beiqin/dist /usr/local/beiqin-dist
mount 192.168.246.132:/usr/local/beiqin/sql /usr/local/beiqin-sql
#6. 验证是否挂载成功,node1执行,如果有master上那几个文件,说明挂载成功
ls /usr/local/beiqin-dist
ls /usr/local/beiqin-sql
13.2 部署数据库
  1. 编写部署脚本,master执行vi /usr/local/beiqin/beiqin-db-deploy.yml

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: beiqin-db-deploy
    spec: 
      replicas: 1
      template:
        metadata:
          labels:
            app: beiqin-db-deploy
        spec:
          volumes:
          - name: beiqin-db-volume
            hostPath:
              path: /usr/local/beiqin-sql
          containers: 
          - name: beiqin-db-deploy
            image: mysql:5.7
            ports: 
            - containerPort: 3306
            #设置环境变量
            env: 
            - name: MYSQL_ROOT_PASSWORD
              value: "root"
            volumeMounts:
            - name: beiqin-db-volume
              #该路径为保存初始化脚本路径
              mountPath: /docker-entrypoint-initdb.d
    
  2. 创建部署

    kubectl create -f beiqin-db-deploy.yml
    #查看pod
    kubectl get pod
    #进入该i容器
    kubectl exec -it pod名 /bin/bash
    #登陆mysql
    mysql -uroot -proot
    #发现beiqin数据库存在
    use beiqin
    show tables
    select count(*) from t_goods;
    
13.3 为数据库创建Service
  1. 图中数据库在Node1中,Node2上的Pod默认无法访问Node1上的Pod,所以需要配置Service,将mysql所在Pod的ip端口暴露给Service。vi /usr/local/beiqin/beiqin-db-service.yml

    apiVersion: v1
    kind: Service
    metadata:
      name: beiqin-db-service
      labels:
        app: beiqin-db-service
    spec: 
      #表示当前Service需要和beiqin-db-deploy联通
      selector:
        app: beiqin-db-deploy
      ports:
      #Service上3310端口对应mysql所在Pod的3306端口
      - port: 3310
        targetPort: 3306
    
  2. 创建Service

    kubectl create -f beiqin-db-service.yml
    #查看服务,service可以简写为svc
    kubectl get svc
    
13.4 部署应用
  1. 编写部署脚本,master执行vi /usr/local/beiqin/beiqin-app-deploy.yml

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      name: beiqin-app-deploy
    spec: 
      replicas: 2
      template:
        metadata:
          labels:
            app: beiqin-app-deploy
        spec:
          volumes:
          - name: beiqin-app-volume
            hostPath:
              path: /usr/local/beiqin-dist
          containers: 
          - name: beiqin-app-deploy
            image: openjdk:8u222-jre
            #容器部署完后自动执行的命令,此处使用exec格式
            command: ["/bin/sh"]
            #实际上执行的就是/bin/sh -c cd /usr/local/beiqin-dist;java -jar beiqin-app.jar
            args: ["-c","cd /usr/local/beiqin-dist;java -jar beiqin-app.jar"]
            volumeMounts:
            - name: beiqin-app-volume
              mountPath: /usr/local/beiqin-dist
    
  2. 创建部署

    kubectl create -f beiqin-app-deploy.yml
    #查看
    kubectl get pod
    #如果发现创建Pod失败,可以查看Pod详细描述
    kubectl describe pod beiqin-app-deploy-79db95fbc6-22whv
    #也可以查看Pod日志,beiqin-app-deploy-79db95fbc6-bzxqv为app对应的Pod名
    kubectl logs -f beiqin-app-deploy-79db95fbc6-22whv
    
  3. 此时如果日志中显示无法连接数据库,是因为application.yml中数据库url没改导致,原配置为localhost,可以改为数据库的service的ip,或service名

  4. master上访问tomcat

    #查看tomcat所在pod的ip地址,分别为10.244.1.23和10.244.1.22
    kubectl get pod -o wide
    #执行成功说明tomcat已能正确提供服务
    curl 10.244.1.23/goods?gid=1788
    
13.5 为应用创建Service
  1. 编写脚本:vi /usr/local/beiqin/beiqin-app-service.yml

    apiVersion: v1
    kind: Service
    metadata:
      name: beiqin-app-service
      labels:
        app: beiqin-app-service
    spec: 
      selector:
        app: beiqin-app-deploy
      ports:
      - port: 80
        targetPort: 80
    
  2. 创建Service:kubectl create -f beiqin-app-service.yml

  3. 查看Service的IP,为10.108.195.224:kubectl describe service beiqin-app-service

  4. 尝试通过应用的Service的ip访问:curl 10.108.195.224/goods?gid=1788

  5. 完成Service的80端口到master上80端口的端口映射

    vim /etc/rinetd.conf
    0.0.0.0 80 10.108.195.224 80
    rinetd -c /etc/rinetd.conf
    
  6. 此时外界通过浏览器访问http://192.168.246.132/goods?gid=1788,就可以查看到商城内各商品信息,修改gid的值,就可以切换到不同商品

14 参考资料

  1. https://www.cnblogs.com/bakari/tag/Kubernetes/
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值