网盘资料地址
https://pan.baidu.com/s/15DLwyQlWLw18Yzsz2Ef9dA
mif2
01 内容编排与Kubernetes介绍
集群环境容器部署的困境一个应用集群 10台服务器
Nginx 10 + Tomcat 10 + Mysql 4 + redis 1
资源如何充分利用
2万台服务器怎么办
容器编排:在哪些宿主机上安装什么容器,这些容器以什么样的方式通信与被管理
容器编排工具对比
docker compose 单机容器编排
docker swarm docker官方集群容器编排
kubernetes Google官方集群容器编排
k8s:kubernetes k+8个英文字母+s
Kubernetes的职责
自动化容器的部署和复制
随时扩展或收缩容器规模 (扩展机器数量只需要修改参数)
容器分组Group,并且提供容器间的负载均衡
实时监控(内置管理工具),及时故障发现,自动替换
[
](https://blog.csdn.net/SUNGGGM/article/details/108249632)
02-K8S基本概念
k8s基本结构
K8s Master
Node
POD(豆荚-一个应用)
- POD是“容器”的容器,可以包含多个“Container”
- POD是K8S最小可部署的单元,一个POD就是一个进程
- POD内部容器网络互通,每个POD都有独立虚拟IP
- POD都是部署完整的应用或模块
POD中内置了Pause容器
- 提供共享的网络命名空间
- 为当前的POD提供共享的Volume,挂载数据卷
Pause容器使得pod内的容器通过localhost就能相互访问
Replication Controller(复制控制器)
- 创建指定数量的POD
-
Service
k8s核心组件
etcd保存了整个集群的状态;
- apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
- controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
- kubelet负责维护容器的生命周期,同时也负责Volume(CSI)和网络(CNI)的管理;
- Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
- kube-proxy负责为Service提供cluster内部的服务发现和负载均衡
03-K8S集群部署
国内安装K8S的四种途径
- 使用kubeadmin通过离线镜像安装
- 使用阿里公有云平台k8s,需要舍得花钱
- 通过yum官方仓库安装,上古版本 v1.5
- 二进制包的形式进行安装,kubeasz(GitHub)
本文通过第一种方式安装k8s集群
环境准备
k8s最小集群,1个Master节点,2个Node节点,共3台虚拟机
- Centos 7 Master * 1
- Master:192.168.0.31
- Centos Node * 2
- Node1:192.168.0.41
- Node2:192.168.0.42
如下操作每个节点主机都需要进行设置,个别命令注意区分执行节点
设置主机名与时区
# 都要执行
timedatectl set-timezone Asia/Shanghai
# 31上执行
hostnamectl set-hostname master
# 41上执行
hostnamectl set-hostname node1
# 42上执行
hostnamectl set-hostname node2
添加hosts网络主机配置
三台虚拟机都要设置
vim /etc/hosts
192.168.0.31 master
192.168.0.41 node1
192.168.0.42 node2
关闭防火墙 (生产勿执行)
三台虚拟机都要设置,生产环境跳过这一步
# SELINUX为安全增强模块
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
systemctl disable firewalld
systemctl stop firewalld
安装基础工具
安装资源上传
将资源包上传至每台虚拟
mkdir /usr/local/k8s-install
cd /usr/local/k8s-install
安装Docker
tar -zxvf docker-ce-18.09.tar.gz
cd docker
yum localinstall -y *.rpm
systemctl start docker
systemctl enable docker
确保cgroups在同一组
docker info |grep cgroup
> cgroups
安装kubeadm
kubeadm是k8s集群部署工具
cd /usr/local/k8s-install/kubernetes-1.14
tar -zxvf kube114-rpm.tar.gz
cd kube114-rpm
yum localinstall -y *.rpm
关闭交换区
防止k8s安装与运行过程中使用swap分区导致的异常,需要关闭交换分区
swapoff -a
vi /etc/fstab
#swap一行注释
配置网桥
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镜像
docker load -i k8s-114-images.tar.gz
docker load -i flannel-dashboard.tar.gz
利用kubeadm部署集群
配置Master主服务器
在Master节点上执行如下命令
kubeadm init --kubernetes-version=v1.14.1 --pod-network-cidr=10.244.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes
#查看pod情况
kubectl get pod --all-namespaces
#安装flannel网络组件
kubectl create -f kube-flannel.yml
加入NODE节点
kubeadm join 192.168.0.31:6443 --token o6of46.215n8pmrgk613jhi \
--discovery-token-ca-cert-hash sha256:5163e0acf843ccf5d6c63b674c87949fd12f95a771f0628df73f76bf361c547b
样例如上,具体命令复制Master节点上的输出
在Master上执行如下命令,观察节点状态
kubectl get nodes
Master开启仪表盘
在Master节点上执行如下命令,开启仪表盘(Web访问界面)
kubectl apply -f kubernetes-dashboard.yaml
kubectl apply -f admin-role.yaml
kubectl apply -f kubernetes-dashboard-admin.rbac.yaml
kubectl -n kube-system get svc
仪表盘访问地址:http://192.168.0.31:32000,即http://{{Master IP}}:32000
04-Deployment脚本部署Tomcat集群
Deployment(部署)
- 部署是指Kubernetes向Node节点发送指令,创建容器的过程
- Kubernetes支持yml格式的部署脚本
- kubectl create -f 部署yml文件 #创建部署
yml部署脚本范本
```bash apiVersion: extensions/v1beta1 #kubectl api版本 kind: Deployment # 资源类型 metadata: # 元数据 name: tomcat-deploy # 该Deployment的名称 spec: replicas: 2 # 副本数量 template: # 部署模板 metadata:
spec:labels: # pod的标识
app: tomcat-cluster # 自定义标识
containers: # 容器组信息
- name: tomcat-cluster # 容器名称
image: tomcat # 容器使用的镜像
ports:
- containerPort: 8080 # 声明容器对外的端口
<a name="URQlU"></a>
## 与部署相关常用命令
```bash
# 创建部署
kubectl create -f 部署yml文件
# 更新部署配置,或第一次创建=create
kubectl apply -f 部署yml文件
# 查看已部署pod
kubectl get pod [-o wide]
# 查看Pod详细信息
kubectl describe pod pod名称
# 查看pod输出日志
kubectl logs [-f] pod名称
部署Tomcat集群
kubectl create -f tomcat-deploy.yml
kubectl get pods
kubectl describe pod tomcat-deploy-5fd4fc7ddb-r2nrj
外部访问Tomcat集群
NodePort方式
NodePort:使用Service(一个特殊的pod)在每个节点开辟一个端口与容器内部端口进行映射
创建tomcat-service.yml,内容如下
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
labels:
app: tomcat-service # Service也是一个特殊的pod,需要设置lables
spec:
type: NodePort # Service类型
selector:
app: tomcat-cluster # 指定绑定的pod
ports:
- port: 8000 # Service在k8s集群内部暴露的端口
targetPort: 8080 # 被映射的容器暴露端口
nodePort: 32500 # 集群每个Node节点上对外暴露的端口
创建Service
kubectl create -f tomcat-service.yml
查看Service列表
kubectl get svc
# 或
kubectl get services
查看Service详细信息
kubectl describe service tomcat-servic
在浏览器中输入http://{{任意Node节点IP}}:32500 即可访问tomcat
05-基于NFS的集群文件共享
NFS简介
- NFS,是由SUN公司研制的文件传输协议,全称Network File System
- NFS主要是采用远程过程调用RPC机制实现文件传输
- 安装命令yum install -y nfs-utils rpcbind
集群文件共享
如何解决集群中文件的统一修改、统一使用?共享
通过在宿主机上安装NFS,将文件共享给多个容器
NFS使用示例
安装NFS服务
执行如下命令,在宿主机上安装NFS,这里我们选择Master节点
yum install -y nfs-utils rpcbind
执行如下命令,配置并启动文件共享
# 创建共享目录
mkdir -p /datda/www-data
# 设置NFS共享文件
echo "/data/www-data 192.168.0.31/24(rw,sync)" > /etc/exports
# 启动nfs服务
systemctl start nfs
# 启动rpcbind服务
systemctl start rpcbind
# 设置服务开机自启动
systemctl enable nfs
systemctl enable rpcbind
# 查看文件共享情况
exportfs
# /data/www-data 192.168.0.31/24
客户端使用NFS服务
在Node节点上执行如下命令,安装NFS客户端
yum install -y nfs-utils
挂载共享文件
# 创建目录
mkdir -p /data/www-data
# 挂载目录
mount 192.168.0.31:/data/www-data /data/www-data
设置开机启动
systemctl enable nfs
辅助命令,查看nfs共享了哪些目录showmount -e 192.168.0.31
容器中使用nfs共享文件
延用之前的Tomcat集群,来加载nfs共享文件,变更该Tomcat集群可以通过kube apply命令修改集群,或者使用kube delete删除集群相关资源,再创建集群。这里我们使用第二种方法。
清理Tomcat集群
# 查看deployment列表
kubectl get deployment
# 删除名为tomcat-deploy的deployment
kubectl delete deployment tomcat-deploy
# 查看service列表
kubectl get service
# 删除名为tomcat-deploy的service
kubectl delete service tomcat-deploy
修改delployment
修改tomcat-deploy.yml内容如下
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: tomcat-deploy
spec:
replicas: 2
template:
metadata:
labels:
app: tomcat-cluster
spec:
volumes: # 创建volume数据卷
- name: web-app # 数据卷名称
hostPath: # 数据卷在宿主机上的路径
path: /data/www-data
containers:
- name: tomcat-cluster
image: tomcat:latest
ports:
- containerPort: 8080
volumeMounts: # 绑定数据卷
- name: web-app # 匹配之前创建的数据卷名称
mountPath: /usr/local/tomcat/webapps # 指定容器中的挂载目录
创建deployment
kubectl create -f tomcat-deploy.yml
使用命令查看生效情况
# 查看deployment状态
kubectl get deployment
# 查看pod状态
kubectl get pod
# 进入容器,查看文件是否挂载成功
kubectl exec -it tomcat-deploy-6cc6d68877-9wkwm /bin/bash
# 在容器内查看文件
ls /usr/local/tomcat/webapps
# 在nfs宿主机的/data/www-data目录新增、修改文件,观察内容是否同步
配置客户端的NFS自动挂载
使用mount命令挂载,重启系统后将失效,需配置/etc/fstab
# /etc/fstab中添加如下配置
192.168.0.31:/data/www-data /data/www-data nfs defaults 0 0
06-基于Rinted的Service负载均衡
Service提供负载均衡实现
这里我们直接使用Service的负载均衡,不再将端口直接暴露在宿主机节点上,集群内部通过k8s内部网络相互访问。由tomcat-service这个特殊的pod来实现流量转发与负载均衡。
修改tomcat-service.yml如下:
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
labels:
app: tomcat-service # Service也是一个特殊的pod,需要设置lables
spec:
# type: NodePort # Service类型
selector:
app: tomcat-cluster # 指定绑定的pod
ports:
- port: 8000 # Service在k8s集群内部暴露的端口
targetPort: 8080 # 被映射的容器暴露端口
# nodePort: 32500 # 集群每个Node节点上对外暴露的端口
仅需注释如下两行内容
# type: NodePort # Service类型
# nodePort: 32500 # 集群每个Node节点上对外暴露的端口
变更service
kubectl apply -f tomcat-service.yml
在NFS共享目录中增加测试index.jsp,验证负载均衡效果
# 在Master节点(NFS Server)中执行如下命令
mkdir /data/www-data/test/
echo "IP:<%=request.getLocalAddr()%>" > /data/www-data/test/index.jsp
# 查看Service内部IP
kubectl get service tomcat-service
# 使用curl测试,10.103.113.6为上一步中获取的ClusterIP
curl 10.103.113.6:8000/test/index.jsp
# 返回处理请求的pod容器的ip
# IP:10.244.1.17
端口转发工具-Rinetd
上一步中10.*段的IP为K8S集群内部通信使用的IP,如何将这些IP提供的端口映射到外部呢?
- Rinetd是Linux操作系统中为重定向传输控制协议工具
- 可将源IP端口数据转发至目标IP端口
- 在Kubernetes中用于将service服务对外暴露
rinted安装
rinted源码无法从官网下载,资源以事先准备好
这里我们使用Master节点作为端口转发宿主机,所有rinted安装在Master节点(192.168.0.31)上,以下命令均在该节点执行。# 解压rinted源码
tar -zxf rinetd.tar.gz
cd rinetd/
# 修改rinted运行映射的端口范围
sed -i 's/65536/65535/g' rinted.c
# 创建rinted依赖目录
mkdir -p /usr/man/
# 安装C语言编译器
yum install -y gcc
# 编译并安装
make && make install
配置rinted
增加配置文件/etc/rinetd.conf ```bash宿主机映射监听的IP+端口(0.0.0.0表示所有IP)、映射目的IP+端口
10.103.113.6即tomcat-service使用的ClusterIP
0.0.0.0 8000 10.103.113.6 8000
运行rintedrinetd -c /etc/rinetd.conf
<a name="qD8li"></a>
### 查看映射情况
使用netstat -nptl可以看到rinetd开启了8000端口
使用如下地址可在浏览器中访问rinted+service提供的服务
[http://192.168.0.31:8000/test/index.jsp](http://192.168.0.31:8000/test/index.jsp)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/22142574/1628988920240-edacbeef-149c-4d24-ba88-3ce9df2ddad5.png#clientId=u649d21b7-b323-4&from=paste&id=ua836ae39&margin=%5Bobject%20Object%5D&name=image.png&originHeight=164&originWidth=1010&originalType=url&ratio=1&size=22111&status=done&style=none&taskId=u9c528d6b-2a28-40df-8d74-04212b7fff3)
总结目前我们已经学习了k8s集群对外暴露服务的两种方式
使用Service提供的NodePort,在每一个Node节点开启端口映射,实现流量的转发<br />Rinted+Service,使用Rinted设置对外暴露的IP+端口,通过Service实现访问的负载均衡<br />一般而言,Rinted+Service性能上会略胜一筹,大型集群应用优先考虑选择该种方式。<br />[
](https://blog.csdn.net/SUNGGGM/article/details/108303192)
<a name="IzzO0"></a>
# 07-集群配置调整与资源限定
<a name="pY7LQ"></a>
## K8S部署调整命令
更新集群配置
```bash
kubectl apply -f yml文件路径
删除部署(Deployment)|服务(Service)
kubectl delete deployment|service 部署|服务名称
资源限定
containers:
- name: tomcat-cluster
image: tomcat:latest
resources:
requests: # 容器运行最小所需的资源,不满足则无法运行
cpu: 1 # 可以是小数,如0.5
memory: 500Mi
limits: # 容器运行过程中,对多能暂用的资源
cpu: 2
memory: 1024Mi
requests设置了创建容器的基本需要
limits限定了容器使用的最大资源
Tomcat部署实验
修改tomcat-deploy.yml,增加resource配置
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: tomcat-deploy
spec:
replicas: 2
template:
metadata:
labels:
app: tomcat-cluster
spec:
volumes:
- name: web-app
hostPath:
path: /data/www-data
containers:
- name: tomcat-cluster
image: tomcat:latest
resources:
requests:
cpu: 0.5
memory: 200Mi
limits:
cpu: 1
memory: 512Mi
ports:
- containerPort: 8080
volumeMounts:
- name: web-app
mountPath: /usr/local/tomcat/webapps
生效配置
kubectl apply -f tomcat-deploy.yml
查看配置生效情况
kubectl describe pod tomcat-deploy-779d75c8f-ccjgl
08-项目实战:K8S构建贝亲婴童商城
项目拓扑
该项目拓扑结构如图所示,基本说明如下
- 使用文件共享区的数据库脚本初始化mysql数据库
- 使用beiqin-db-service在集群内部暴露mysql服务
- 使用openjdk:8u222作为基础镜像,部署web应用(SpringBoot开发)
- 使用beiqin-app-service暴露应用的端口
部署所需资源文件
部署所需资源均在文末的百度网盘中,所需资源目录结构如下 ```bash [root@master www-data]# tree beiqin beiqin ├── beiqin-app-deploy.yml # web应用部署文件 ├── beiqin-app-service.yml # web应用service部署文件 ├── beiqin-db-deploy.yml # 数据库部署文件 ├── beiqin-db-service.yml # 数据库service部署文件 ├── dist │ ├── application.yml # 应用程序配置文件 │ └── beiqin-app.jar # SpringBoot应用程序 └── sql └── beiqin.sql # 数据库初始化sql
<a name="lUuDN"></a>
## 设置并挂载NFS文件
为了简化操作步骤,这里我们延用《05-基于NFS的集群文件共享》中的NFS设置,将Master节点中的/data/www-data共享到Node节点中的/data/www-data目录中<br />将需要共享的文件复制到Master节点的/data/www-data目录即可
<a name="gCDg8"></a>
## 部署并初始化数据库
编写beiqin-db-deploy.yml
```bash
apiVersion: apps/v1beta1 # 等价于extensions/v1beta1(1.6版本以前),1.6版本之后都可以使用apps/*
kind: Deployment # 这是一个部署脚本
metadata: # 元数据信息
name: beiqin-db-deploy # deployment的名称
spec: # 详细信息
replicas: 1 # 部署的副本数量
template: # 模板的设置选项
metadata:
labels: # 标签
app: beiqin-db-deploy # 自定义app标签
spec:
volumes: # 定义数据卷
- name: beiqin-db-volume # 数据卷名称
hostPath: # 主机路径
path: /data/www-data/beiqin/sql/ # Node宿主机上共享文件夹的路径
containers:
- name: beiqin-db-deploy
image: mysql:5.7 # 容器使用镜像
ports:
- containerPort: 3306 # 容器对外声明的暴露端口
env:
- name: MYSQL_ROOT_PASSWORD # 设置mysql的root密码
value: "root"
volumeMounts: # 设置挂载点
- name: beiqin-db-volume # 挂载之前定义的数据卷
mountPath: /docker-entrypoint-initdb.d # 挂载到容器的目录,docker-entrypoint-initdb.d为mysql初始化脚本的目录
部署数据库
kubectl create -f beiqin-db-deploy.yml
验证部署情况
# 查看pod
kubectl get pods
# 进入pod实例内部
kubectl exec -it beiqin-db-deploy-869d9cbdcb-6j567 /bin/bash
# 在容器内部登录mysql
mysql -uroot -proot
# 查看数据库
show databases;
# 使用beiqin db,统计t_goods表
use beiqin;
show tables;
select count(*) from t_goods;
创建db服务
编写beiqin-db-service.yml
apiVersion: v1
kind: Service
metadata:
name: beiqin-db-service
labels: # Service是特殊的pod,也必须定义labels
app: beiqin-db-service
spec:
selector:
app: beiqin-db-deploy
ports:
- port: 3310 # service对外暴露端口(对外指的是:容器外,K8S集群内部)
targetPort: 3306 # 容器内部端口
创建beiqin-db-service
kubectl create -f beiqin-db-service.yml
验证
查看service列表
kubectl get svc
查看beiqin-db-service详情
kubectl describe svc beiqin-db-service
部署Web应用
编写beiqin-app-deploy.yml,大部分字段意义与beiqin-db-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 : beqin-app-volume
hostPath:
path: /data/www-data/beiqin/dist
containers:
- name: beiqin-app-deploy
image: openjdk:8u222-jre
command: ["/bin/sh"] # 容器部署完成后默认执行的命令
args: ["-c","cd /usr/local/beiqin-dist;java -jar beiqin-app.jar"] # 启动web应用的命令
volumeMounts:
- name: beqin-app-volume
mountPath: /usr/local/beiqin-dist
部署web应用
kubectl create -f beiqin-app-deploy.yml
查看应用状态
# 查看pod列表
kubectl get pods
# 查看容器日志
kubectl logs -f beiqin-app-deploy-5bc96d54d9-pjnvf
确认beiqin-app.jar使用的配置文件application.yml
server:
port: 80
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://beiqin-db-service:3310/beiqin?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: root
mvc:
favicon:
enabled: false
mybatis:
mapper-locations: classpath:/mapper/*.xml
configuration:
map-underscore-to-camel-case: true
注意url: jdbc:mysql://beiqin-db-service:3310/beiqin?useUnicode=true&characterEncoding=utf-8&useSSL=false,数据库连接不再直接使用数据库的IP,而是使用DB Service中定义的服务名称/主机名称,这样配置文件就不用写死IP。
创建应用服务
编写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
创建beiqin-app-service
kubectl create -f beiqin-app-service.yml
验证
# 查看service的CLUSTER-IP
kubectl get svc
# 验证web应用接口
curl 10.101.231.228/goods?gid=1788
使用rinetd实现端口转发
在Master节点上修改/etc/rinetd.conf
0.0.0.0 80 10.101.231.228 80
加载rinetd配置
rinetd -c /etc/rinetd.conf
在浏览器中访问如下地址(192.168.0.31为Master节点/IP),就能看到商城的页面了。
http://192.168.0.31/goods?gid=1788
版权说明
本文章内容为马士兵教育《架构师高级技能kubernetes入门到精通》课程的学习笔记
百度网盘上相关源码资料包 提取码:xdji