1 集群环境容器部署问题
- 集群内每台机器应该分配几个容器
- 如何根据业务量动态调整容器个数
- 机器数量过多,部署工作量大
2 容器编排工具
- docker-compose:单击容器编排工具
- docker swarm:docker官方提供的集群容器编排工具
- kubernetes:简称k8s,因为k和s之间有8个英文字母,google官方提供的容器编排工具,底层完全基于docker,与docker swarm属于竞争关系
3 Kubernetes功能
- 自动化容器部署和复制:只需要通过脚本规划好容器在哪些主机运行,运行多少个副本
- 随时扩展或收缩容器规模:通过修改参数,可以人工或自动增加计算单元个数,例如将tomcat从10个缩小成5个
- 容器分组Group,并提供容器间的负载均衡:没有K8S前需要使用nginx完成负载均衡,K8S本身提供了负载均衡功能
- 实时监控, 即时故障发现, 自动替换:K8S提供管理界面,可以实时看到所有容器的情况
4 K8S中基本概念
- 每个方框都代表一台容器的宿主机,他们共同形成了一个K8S集群,这些宿主机根据角色可划分为Master和Node
- Master:主服务器,集群管理者。通过主服务器向具体的节点发送创建容器、自动部署、自动发布等命令,外界请求也由Master接收,再由它将请求分配给Node,通常使用一台独立的物理机作为Master
- Replication Controller:复制控制器,位于主节点,用于对Pod数量进行监控,例如我们需要三个红色的Pod,如果Replication Controller发现少了一个,他就会额外创建一个新Pod出来。且如果一个Pod失去响应,会将这个Pod剔除,用一个新的替换它。Replication Controller可以根据参数值动态调整Pod个数
- Node:节点,通常可以是独立物理机,也可以是虚拟机
- Pod:存在于Node中,是K8S控制的最小单元。Pod译为豆角,豆角一个皮中包含很多豆子,意思就是一个Pod中可以包含多个容器(Container)
- Pod内部容器网络互通,每个Pod都有独立虚拟IP,由K8S统一管理
- 同一节点下Pod间网络互通
- 不通节点下Pod间网络不通,需要依靠Service通信
- 项目不同,Pod中包含内容不同,对应小公司,一个Pod可能是一套完整环境,包含tomcat、redis、db。而对于大公司,可能一个Pod只部署一个职能,比如只部署tomcat
- 每个Pod中都包含一个特殊的容器(Container),叫做Pause,用于提供共享网络空间。如果没有Pause时,一个Pod下两个容器tomcat和nginx彼此通信时,需要通过对方ip或对方容器名进行访问,有了Pause后,可以将Pod看作一个整体,nginx和tomcat使用localhost就能访问彼此,同时Pause会为当前Pod提供一个共享的volume(挂载的数据卷)
- Service:可以让两个Pod互通,且可以作为负载均衡对外提供服务
- Labels:标签,相当于Pod的别名,定义了标签,K8S的Master才能找到对应的Pod,并对其进行操作
- kubelet、kube-proxy、docker:每个Node上都需要安装的应用程序
- kubelet:负责启动Pod和容器
- kube-proxy:负责Service功能的具体实现
- Pod:存在于Node中,是K8S控制的最小单元。Pod译为豆角,豆角一个皮中包含很多豆子,意思就是一个Pod中可以包含多个容器(Container)
5 k8s安装
- 从google中央仓库安装:外网不通
- 使用快速部署工具kubeadm:推荐,当前学习的是1.14
- 使用阿里公有云平台k8s:收费
- 通过yum官方仓库安装:版本太旧
- 通过二进制包的形式进行安装:kubeasz (github),这种方式安装的k8s可能有bug,或底层可能被篡改
5.1 CentOS7集群搭建
-
环境准备
- Master:192.168.246.132
- Node1:192.168.163.133
-
设置主机名与时区
timedatectl set-timezone Asia/Shanghai #只对master执行 hostnamectl set-hostname master
-
添加hosts网络主机配置
vim /etc/hosts 192.168.163.132 master 192.168.163.133 node1
-
禁用SELINUX
#SELINUX:linux内置的安全增强模块,设置起来太费劲,因此禁用掉 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config #设置为临时生效 setenforce 0
-
关闭防火墙
#禁用防火墙 systemctl disable firewalld #停止防火墙 systemctl stop firewalld
5.2 离线安装kubeadmin、docker、导入k8s镜像
-
将镜像包kubernetes-1.14上传至各服务器
mkdir /usr/local/k8s-install cd /usr/local/k8s-install cp -r /mnt/hgfs/wusihan/Downloads/kubernetes-1.14 .
-
安装、启动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
-
确保两台机器的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
-
安装kubeadm
cd /usr/local/k8s-install/kubernetes-1.14 tar -zxvf kube114-rpm.tar.gz cd kube114-rpm yum localinstall -y *.rpm
-
关闭交换区
#1. 交换分区类似windows虚拟内存,就是内存不足时,写入内存的操作会被写入硬盘,读取内存操作从硬盘读取,所以虚拟内存可能导致系统性能降低 #2. k8s的环境下, 一般内存都充裕,不建议使用交换分区,可能影响性能 swapoff -a #将swap那行注释 vi /etc/fstab
-
配置网桥
#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
-
导入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集群
-
使用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
-
执行完毕后,相当于k8s就已经搭建好了,docker ps发现多了很多容器,所以说,kubeadm的作用,可以简单的理解为,通过k8s相关镜像,快速启动一系列k8s相关的容器,从而完成整个k8s环境的创建
-
创建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
-
此时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
-
将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启动节点
-
kubelet运行在所有节点上,负责启动POD和容器,以系统服务形式出现
-
当master或node1宕机重启后,需要依赖kubelet服务启动k8s集群或重新加入集群
#master或node1重启后,需要执行如下命令恢复集群 systemctl start kubelet #设置kubelet开机启动,这样不必每次重启master或node1都要手工启动kubelet systemctl enable kubelet
6 启用Dashboard
-
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
-
通过http://192.168.246.132:32000 访问Dashboard
7 利用Dashboard部署tomcat集群
-
保证两台机器都配置了docker镜像加速,否则创建容器可能无法下载
-
Dashboard运行在master上,master发送创建容器请求给node1,node1收到后,先下载镜像,再启动容器
-
进入Dashboard–工作负载–部署容器应用–创建应用
- 应用名称:my-tomcat1
- 容器镜像:tomcat:latest
- 容器个数:2,表示在两台node上布置几个tomcat副本
- 服务:外部,表示对外暴露创建的tomcat容器的端口,其他电脑可以通过网络访问到这些创建的容器,如果不是外部服务,其他电脑无法访问
- 端口:8000,表示Pod的端口,并不是kubernetes所在宿主机的端口,外界不是通过该端口访问tomcat
- 目标端口:8080,表示容器对Pod暴露的端口
- 部署
-
docker images
发现多了一个tomcat镜像 ,docker ps
发现多了一个tomcat容器 -
查看tomcat集群状态:进入Dashboard–副本集–
my-tomcat1-69b7b678d5
–服务–my-tomcat1
–容器组,可以看到两个容器所在节点、状态、以及日志信息 -
查看tomcat集群对外暴露的端口号:进入Dashboard–副本集–
my-tomcat1-69b7b678d5
–服务–内部端点,显示端口号为31455,这个端口号是随机生成的,虽然两个tomcat容器都在node1上,但在外部通过http://192.168.246.132:31455/和http://192.168.246.133:31455/都能访问tomcat服务 -
模拟一台tomcat宕机的情况
#node1上执行,f07e06106503为其中一个tomcat容器的id docker rm -f f07e06106503 #k8s会实时监控集群中各容器状态,一旦发现容器挂掉,会自动重启该容器,发现过一会,tomcat容器会被自动重启,docker ps发现容器重新出现
8 kubectl使用yaml资源文件部署tomcat集群
-
所谓部署指master向node发送指令,创建容器的过程
-
Kubernetes支持yml格式的部署脚本
-
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集群
-
创建用于部署的资源文件tomcat-deploy.yml
#文件名写什么都可以 vi /root/k8s/tomcat-deploy/tomcat-deploy.yml
-
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
-
创建部署
#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集群
-
通过资源文件部署的tomcat集群,到现在为止,还无法被外界访问
-
在K8S中,Service是对Pod对象的抽象,通常Pod会以多副本的形式部署,每个Pod都有自己的IP,都可以对外提供服务,但Pod随时都有可能被频繁地销毁和重启,IP也会随之改变,会导致服务的访问出现问题。Service就是提出来解决这个问题的,它定义了一个虚拟IP(集群IP),这个 IP在Service的整个生命周期内都不会改变,我们可以将请求发送给Service,Service会将请求导向给Pod,如果存在多个Pod,Service还能实现负载均衡
-
设置Service时,也可以同时将Pod内部端口与其所在宿主机端口进行映射,这样可以不通过Service,而是直接访问Pod的宿主机来访问Pod中的服务,但这样做不推荐,因为这样Service提供的负载均衡功能就失效了
-
创建Service资源文件tomcat-service.yml
vim /root/k8s/tomcat-service/tomcat-service.yml
-
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
-
创建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名
-
此时可以输入MasterIP:32500或Node1IP:32500完成Node1一个节点上,两个tomcat的负载访问,注意如果两个tomcat不在一个pod中,例如图中所示,NodePort类型的Service就无法完成负载功能了
9 基于NFS实现集群内的文件共享
-
NFS:Network File System,网络文件系统,是由SUN公司研制的文件传输协议,采用远程过程调用RPC机制,实现文件在网络中进行共享和传输,配置NFS后,读写网络中文件时,就像在本地操作文件一样方便
-
项目拓扑
9.1 NFS配置
-
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
-
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)
-
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
-
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
-
由于之前启动了一个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名
-
修改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
-
重新创建部署
#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负载均衡
-
修改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
-
创建Service
kubectl create -f tomcat-service.yml #查看service kubectl get service #查看service详细信息 #发现宿主机上暴露的端口,NodePort项不在了 kubectl describe service tomcat-service
-
master上访问Service
#使用curl命令,向Service的ip和port上发送请求,发现会返回404错误,说明请求被转发到了node1或node2上的服务上 curl 10.100.95.153:8000
-
通过NFS完成tomcat部署
#由于master已经共享给了node,可以通过修改master中内容,完成应用部署,master上执行 cd /usr/local/data/www-data mkdir test cd test vi index.jsp
-
index.jsp
//输出本机的ip,这样我们就能知道负载均衡访问的是具体哪个节点了 <%=request.getLocalAddr()%>;
-
再次访问Service
#多次执行,打印ip不同,可能打印node1上第一个Pod的ip也可能是node1上第二个Pod的ip,负载均衡策略为随机分配 curl 10.100.95.153:8000/test/index.jsp
11 使用Rinetd将Service服务对外暴露
-
service的IP为10.100.95.153,这不是一个有效的真实的IP,这个IP在master、node1上是可以访问的,但在外部192.168网段无法访问
-
Rinetd是Linux操作系统中为重定向传输控制协议工具,可以将源IP端口数据转发至目标IP端口,我们可以利用Rinetd将Service的IP端口,与其所在宿主机的物理IP和端口进行映射,从而将Service服务对外暴露
-
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
-
配置端口映射
#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
-
此时外界就可以通过<192.168.246.132:8000/test/index.jsp>访问service了,service会将请求负载给两个Pod中的tomcat容器
12 集群配置调整与资源限定
-
配置调整:例如原来2个tomcat,现在改为3个tomcat。k8s会采用可用资源优先原则,也就是哪个服务器负载低,就把新Pod发布在哪个节点上,这只是其中一个策略,我们也可以人为指定发布Pod到哪个节点
#1. 修改yml文件 #2. 使用新文件更新 kubectl apply -f yml文件路径 #3. 或者也可以删除部署和Service之后重新创建 kubectl delete deployment/service 部署/服务名
-
资源限定:限制创建的容器使用多少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构建贝亲婴童商城
-
项目拓扑:由于资源有限,不搭建Node2,而是在Node1上部署两个tomcat应用
-
beiqin文件夹介绍
- dist
- application.yml:springboot配置文件,连接到哪个数据库都在其内配置
- beiqin-app.jar:贝亲商城应用
- sql
- beiqin.sql:数据库初始化脚本
- dist
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 部署数据库
-
编写部署脚本,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
-
创建部署
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
-
图中数据库在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
-
创建Service
kubectl create -f beiqin-db-service.yml #查看服务,service可以简写为svc kubectl get svc
13.4 部署应用
-
编写部署脚本,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
-
创建部署
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
-
此时如果日志中显示无法连接数据库,是因为application.yml中数据库url没改导致,原配置为localhost,可以改为数据库的service的ip,或service名
-
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
-
编写脚本:
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
-
创建Service:
kubectl create -f beiqin-app-service.yml
-
查看Service的IP,为10.108.195.224:
kubectl describe service beiqin-app-service
-
尝试通过应用的Service的ip访问:
curl 10.108.195.224/goods?gid=1788
-
完成Service的80端口到master上80端口的端口映射
vim /etc/rinetd.conf 0.0.0.0 80 10.108.195.224 80 rinetd -c /etc/rinetd.conf
-
此时外界通过浏览器访问http://192.168.246.132/goods?gid=1788,就可以查看到商城内各商品信息,修改gid的值,就可以切换到不同商品