简介
部署应用程序分为三个主要阶段:
- 传统部署
将应用程序直接部署在物理机上,计算机自主为应用程序调度资源。
- 虚拟化部署
一台物理机上运行多个虚拟机,每个虚拟机都分配有独立的环境和资源。
- 容器化部署
虚拟服务与环境共享物理机资源
运行在容器上的应用程序有自己的文件系统、CPU、内存、进程等。容器的运行环境共享主机的资源。
在容器部署时常遇到的问题是当一个容器宕机后另一容器如何及时顶上,当访问量变大时如何横向扩展容器。这些问题统称为容器编排
问题。容器编排的软件:
Swarm
:docker官方的容器编排工具。Mesos
:Apache的一个资源管控工具,需要和Marathon结合使用。Kubernetes
:Google开源的容器编排工具。
Kubernetes 本质上是一组服务器集群。它可以在集群上的每个节点上运行特定的程序来管理节点的容器。目的是实现资源管理的自动化。主要提供以下主要功能:
- 自愈:一旦容器宕机,会很快找到新的容器来补充;
- 自动伸缩:根据需要自动调整集群中运行的容器数量;
- 服务发现:服务可以通过自动发现找到依赖的服务;
- 负载均衡:一个服务启动多个容器,可以自动实现请求的负载均衡;
- 版本回滚:如果新发布的版本出现问题,可以自动回滚到旧版本;
- 存储编排:根据容器本身的需求创建数据卷。
Kubenetes
一个kubenetes集群主要由控制节点master和工作节点node组成。每个节点安装在不同的组件上。
Kubernetes集群主要有以下几个部分:
集群环境搭建
-
集群类型
-
安装方法
- 主持人策划
新建三台虚拟机,分别配置静态ip,其IP地址分为为:
CPU名称 | IP地址 |
---|---|
xwh(主节点) | 192.168.42.128 |
节点(从节点1) | 192.168.42.129 |
服务器(从节点2) | 192.168.42.130 |
分别开启
依次连接
- 配置本地DNS服务器
连接到同一局域网的三个虚拟机属于同一网段,可以互相访问。但必须配置DNS服务器,否则它们将不知道对方的存在。
hosts
文件就是主机上的本地的DNS服务器,sudo vi /etc/hosts
配置配置ip域名的列表,如下
前一个参数是ip后一个是域名,配置了DNS服务器后本机就记录了局域网中存在的子网的计算机了,就可以通过局域网访问了。
如上图所示ping
一下测试连通性没问题。
- 时间同步
kubenetes集群要求集群的的主机及节点的时间必需是一致的,使用chronyd
服务实现网络同步时间。
-
安装
sudo apt install chrony
-
启动服务
sudo systemctl start chronyd
-
配置开机启动
sudo systemctl enable chronyd
-
date测试
- 关闭防火墙,避免不必要的麻烦
sudo ufw disable
- 禁用
selinux
/etc/selinux/config
SELINUX=disabled
reboot
Ubuntu目录发生了变化,如下
- 禁用交换分区
swapoff -a
sudo vi /etc/fstab
注释有swap的一行。或者直接使用systemctl disable swap.target
命令。
reboot now
- 配置基于 kubenetes 的配置文件
- 编辑配置
sudo vi /etc/sysctl.d/kubenetes.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
- 重新加载
sysctl -p
- 加载桥式滤波器模块
sudo modprobe br_netfilter
- 检查是否成功
lsmod | grep br_netfilter
- 配置ipvs功能
- 安装
ipset
和ipvsadm
sudo apt -y install ipvsadm ipset sysstat conntrack
- 写入参数配置
#创建目录
mkdir ~/k8s-init/
#写入参数配置
tee ~/k8s-init/ipvs.modules <<'EOF' #!/bin/bash modprobe -- ip_vs modprobe -- ip_vs_lc modprobe -- ip_vs_lblc modprobe -- ip_vs_lblcr modprobe -- ip_vs_rr modprobe -- ip_vs_wrr modprobe -- ip_vs_sh modprobe -- ip_vs_dh modprobe -- ip_vs_fo modprobe -- ip_vs_nq modprobe -- ip_vs_sed modprobe -- ip_vs_ftp modprobe -- ip_vs_sh modprobe -- ip_tables modprobe -- ip_set modprobe -- ipt_set modprobe -- ipt_rpfilter modprobe -- ipt_REJECT modprobe -- ipip modprobe -- xt_set modprobe -- br_netfilter modprobe -- nf_conntrack EOF
- 文件授权
# 赋权
chmod 755 ~/k8s-init/ipvs.modules
# 执行脚本
sudo bash ~/k8s-init/ipvs.modules
- 检查模块是否加载成功
lsmod | grep -e ip_vs -e nf_conntrack
出现如上图所示表示ipvs功能配置完成。到此集群的基本环境也搭建完成了。
安装docker
安装docker时,注意docker和k8s版本的对应关系。不要安装最新版本。
sudo apt install docker.io
安装kubenetes组件
- 允许apt在HTTPS上使用存储库:
apt update && apt install -y apt-transport-https
如果显示如上所示错误,直接切换root用户再次安装su root
,没有root用户就创建sudo passwd root
。
- 添加访问公钥
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add -
- 添加来源
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF
- 安装最新版本的 kubelet kubeadm kubectl
sudo apt-get install -y kubelet kubeadm kubectl
安装指定版本
sudo apt-get install -y kubelet=1.22.2-00 kubeadm=1.22.2-00 kubectl=1.22.2-00
- 设置启动
systemctl enable kubelet.service
- 测试安装成功
kubeadm version
初始化集群
初始化集群只需在master节点上操作:
sudo kubeadm init \
--kubernetes-version=1.22.1 \
--apiserver-advertise-address=192.168.186.111 \
--pod-network-cidr=10.244.0.0/16 \
--image-repository registry.aliyuncs.com/google_containers
#kubernetes-version,是k8s的版本,不设置默认是最新
#apiserver-advertise-address是填 master节点的IP
#pod-network-cidr pod的网络,取决了flannel的网络(本文)
#image-repository 镜像源地址
报错如下:
container runtime is not running: output: time="2023-09-18T02:45:06Z" level=fatal msg="validate service
connection: CRI v1 runtime API is not implemented for endpoint \"unix:///var/run/containerd/containerd.sock\": rpc
error: code = Unimplemented desc = unknown service runtime.v1.RuntimeService"
解决方案:
rm -rf /etc/containerd/config.toml
systemctl restart containerd
在这里运行如下
又报错,如下 It seems like the kubelet isn't running or healthy
sudo vi /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://registry.docker-cn.com"]
}
systemctl daemon-reload
sudo systemctl restart docker
sudo systemctl restart kubelet
由于之前初始化过一次后就无法再次初始化,所以需要先删除之前初始化过的文件。一方面,它们可以手动或通过组件删除。
kubeadm reset
sudo kubeadm init \
--apiserver-advertise-address=192.168.42.128 \
--pod-network-cidr=10.244.0.0/16 \
--image-repository registry.aliyuncs.com/google_containers
经过上述步骤,初始化后k8s仍然无法启动。检查时发现kubelet已经停止,如下:
使用kubectl version
查看kube
的日志 journalctl -fu kubelet
failed to run Kubelet: running with swap on is not supported, please disable swap
只需再次禁用交换分区即可。
又遇到一个新错误[kubelet-check] Initial timeout of 40s passed
缺少关键文件,网站咨询。
- 安装网络组件
#使用gitee,github因为网络原因可能无法正常下载
git clone --depth 1 https://gitee.com/CaiJinHao/flannel.git
#安装
kubectl apply -f flannel/Documentation/kube-flannel.yml
#查看pod状态,当flannel状态为Running的时候就表示安装完成
kubectl get pod -n kube-system
- 配置 kube-proxy 启用 IPVS 模式
kubectl edit configmap kube-proxy -n kube-system
#把原来mode配置为ipvs,默认是空
42 kind: KubeProxyConfiguration
43 metricsBindAddress: ""
44 mode: "ipvs"
45 nodePortAddresses: null
- 重启 kube-proxy pod 并检查状态
#删除pod重新运行
kubectl delete pod -n kube-system kube-proxy-mtkns
#查看状态
ipvsadm -Ln
- 添加节点
#运行此命令把其他node节点加入集群,具体命令是自己集群kubeadm初始化完成之后的提示命令中
kubeadm join 192.168.186.111:6443 --token hhwuqb.cs92xded67e0cj8v \
--discovery-token-ca-cert-hash sha256:6f318d778732870d8b9fdaacf8522c47fe28a1d441da0db90f14535484f5434c