1.部署模式的变迁
2.为什么用Kubernetes
3.Kubernetes安装
1.部署模式的变迁
作为应用的开发人员,我们不该只关心应用的开发,应用的部署也同样重要,(当我们有了三五年的开发经验后,会陷入一个难以提升的瓶颈,此时学习一些运维技能,可以拓宽我们的视野),帮助我们突破瓶颈。在部署应用的方式上,我们主要经历了三个时代:
传统部署时代:
部署特点:
- 直接在 物理机上部署 我们的应用程序。(打成jar包直接在物理机上java -jar运行)
缺点:
- 无法限制应用的资源边界,有资源分配等问题。
例如,我们在一台服务器上启动多个应用程序,可能会出现一个应用程序占大部分的资源,导致挤压到其它应用程序的资源,使其性能下降,但是如果一台机器只部署一个应用,就会导致资源利用率不足,扩展性差等缺点。为了解决上面这些问题,我们进入了虚拟化部署时代。
虚拟化部署时代:
部署特点:
- 虚拟化技术允许在单个服务器上运行多个虚拟机,隔离资源。
- 一个应用的信息不能被另外一个应用访问到,提高了安全性。
- 可以更轻松地添加或者更新应用程序,可以实现更好的伸缩性,降低硬件成本。
缺点:
- 虚拟层冗余导致重复安装操作系统,会有资源的浪费与性能下降。
容器化部署时代:
部署特点:
- 容器类似于VM,但是可以在应用程序之间共享操作系统。
- 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。
容器的优势:
- 容器类似于VM,但是可以在应用程序之间共享操作系统。
- 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。
- 具体优势可以参照以前写的博客。系统学习Docker——Docker的简介与安装
当然容器化也带来了一系列的问题:
- 容器一多带来的运维困难
- 高性能的负载均衡访问机制
- 便捷的自动扩缩容
- 自动化的资源监测
- ......
市面上有非常多的管理容器的工具,但是Kubernetes占比最高,所以我们来学习它。
2.为什么用Kubernetes
容器是打包和运行程序的高效的方式。但是在生产环境中,会有非常多的问题,比如如何确保容器不停机,如何确保容器出问题的时候自动重启,容器规模一大如何管理等,Kubernetes提供了非常多的方法来解决一系列容器管理问题,提供了一个可弹性运行分部署系统的框架。
Kubernetes会满足我们的扩缩容,部署模式,故障转移等等,为我们提供的主要功能如下:
自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
存储编排
Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
自动完成装箱计算
Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源。
自我修复
Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。
密钥与配置管理
Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥
3.Kubernetes安装
在安装之前,我们先了解一下Kubernetes的架构。
3.1 master-node 架构
Kubernetes的master-node架构并非主从复制架构,而是一种类似于地主+奴隶的组合。
master: 主节点,主要分配任务的节点。
node: work节点(工作节点),具体部署服务(干活)的节点。
pod:是k8s运行容器的最小单元,k8s中的pod就如docker中的容器,区别是pod里可以由多个容器组成。
3.2 Kubernetes 工作原理
我们先介绍一下K8S个钟组件的名称以及作用:
- kubectl: 程序员使用的命令工具,就和docker一样,docker的命令都是以docker开头,k8s的命令都是以kubectl开头。
- api-server: 集群中所有操作的入口点,各个组件之间的交互都要通过api-server进行调度,犹如微服务的注册中心一般。
- controller-manager: 负责运行集群的控制器,由它调度节点部署一些服务。
- Scheduler: 负责决定pod应该运行在哪个k8s节点上。
- etcd: 键值存储系统,用来存储部署信息等。
- kubelet: 在每个 Node 上运行的代理,负责监控 Pod 的生命周期,确保 Pod 中的容器启动、运行并报告状态。
当k8s发布一次部署服务命令的时候,具体执行过程如下图所示:
假设让k8s部署一个tomcat服务:
1.启动k8s集群,所有工作节点的kubelet,master节点的schedule,controller manager一直监听master的api-server发来的事件信息。
2.程序员使用部署命令,kubectl create deploy tomcat --image=tomcat8 告诉master让集群使用tomcat8镜像,部署一个tomncat8服务。
3.kubectl将命令发送给api-server,api-server保存此次创建信息到etcd。
4.etcd给api-server上报事件,说刚才有人给我保存了一个信息。(部署tomcat)
5.controller-manager监听到api-server的事件,是部署toncat,并生成pod信息。
6.controller-manager把pod信息交给api-server,再保存到etcd。
7.etcd再次上报pod信息给api-server.
8.schedule专门监听pod信息,拿到pod信息的内容,看哪个节点适合部署这个pod,生成pod调度过后的信息。
9.scheduler把pod调度过的信息交给api-server,保存到etcd。
10.etcd上报pod调度过后的信息,交给api-server。
11.其他节点的kubelet专门监听pod调度过后的信息,集群所有kubelet从api-server拿到了调度过后的pod信息。
12.每个节点判断部署这个tomcat服务,是否属于自己的事情,其中一个工作节点判断这个部署信息属于它的工作。
13.工作节点启动这个pod,汇报给master节点当前启动好的所有信息。
安装过程:
我们先准备3台centos,内网互通,且能上网。
1.基础环境
先将装好的虚拟机能联网:
先让centos能上网,修改网关配置:
vi /etc/sysconfig/network-scripts/ifcfg-ens33
#把onboot修改为:
onboot = yes
#重启
nmcli c reload
#关闭防火墙: 如果是云服务器,需要设置安全组策略放行端口
systemctl stop firewalld
systemctl disable firewalld
# 修改 hostname
hostnamectl set-hostname k8s-01
# 查看修改结果
hostnamectl status
# 设置 hostname 解析
echo "127.0.0.1 $(hostname)" >> /etc/hosts
#关闭 selinux:
sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce 0
#关闭 swap:
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
2.docker环境
sudo yum remove docker*
sudo yum install -y yum-utils
#配置docker yum 源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#安装docker 19.03.9
yum install -y docker-ce-3:19.03.9-3.el7.x86_64 docker-ce-cli-3:19.03.9-3.el7.x86_64 containerd.io
#安装docker 19.03.9 docker-ce 19.03.9
yum install -y docker-ce-19.03.9-3 docker-ce-cli-19.03.9 containerd.io
#启动服务
systemctl start docker
systemctl enable docker
#配置加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://82m9ar63.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3.安装k8s核心
# 配置K8S的yum源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
# 卸载旧版本
yum remove -y kubelet kubeadm kubectl
# 查看可以安装的版本
yum list kubelet --showduplicates | sort -r
# 安装kubelet、kubeadm、kubectl 指定版本
yum install -y kubelet-1.21.0 kubeadm-1.21.0 kubectl-1.21.0
# 开机启动kubelet
systemctl enable kubelet && systemctl start kubelet
4.初始化master节点
############下载核心镜像 kubeadm config images list:查看需要哪些镜像###########
####封装成images.sh文件
#!/bin/bash
images=(
kube-apiserver:v1.21.0
kube-proxy:v1.21.0
kube-controller-manager:v1.21.0
kube-scheduler:v1.21.0
coredns:v1.8.0
etcd:3.4.13-0
pause:3.4.1
)
for imageName in ${images[@]} ; do
docker pull registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/$imageName
done
#####封装结束
chmod +x images.sh && ./images.sh
docker pull registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/pause:3.4.1
# registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/coredns:v1.8.0
##注意1.21.0版本的k8s coredns镜像比较特殊,结合阿里云需要特殊处理,重新打标签
docker tag registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/coredns:v1.8.0 registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/coredns/coredns:v1.8.0
# 这里的advertise-address 是虚拟机ip地址
########kubeadm init 一个master########################
########kubeadm join 其他worker########################
kubeadm init \
--apiserver-advertise-address=192.168.91.152 \
--image-repository registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images \
--kubernetes-version v1.21.0 \
--service-cidr=10.96.0.0/16 \
--pod-network-cidr=192.168.0.0/16
## 注意:pod-cidr与service-cidr
# cidr 无类别域间路由(Classless Inter-Domain Routing、CIDR)
# 指定一个网络可达范围 pod的子网范围+service负载均衡网络的子网范围+本机ip的子网范围不能有重复域
kubeadm join 192.168.91.148:6443 --token 5qgew7.xotpict8okggqpgh
--discovery-token-ca-cert-hash sha256:02458de1c9f2aa40ffce7453a1a38c688ef78990894fb52d55b9d9408fbcc8af
######按照提示继续######
## init完成后第一步:复制相关文件夹
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
## 导出环境变量
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
### 部署一个pod网络
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
##############如下:安装calico#####################
#kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
#第一条命令不能用,用下面这条,目的是为了安装一个网络通信组件
kubectl apply -f https://docs.projectcalico.org/v3.8/manifests/calico.yaml
### 命令检查
kubectl get pod -A ##获取集群中所有部署好的应用Pod
kubectl get nodes ##查看集群所有机器的状态
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 172.24.80.222:6443 --token nz9azl.9bl27pyr4exy2wz4 \
--discovery-token-ca-cert-hash sha256:4bdc81a83b80f6bdd30bb56225f9013006a45ed423f131ac256ffe16bae73a20
5.初始化worker节点
## 用master生成的命令即可
kubeadm join 172.24.80.222:6443 --token nz9azl.9bl27pyr4exy2wz4 \
--discovery-token-ca-cert-hash sha256:4bdc81a83b80f6bdd30bb56225f9013006a45ed423f131ac256ffe16bae73a20
##过期怎么办
kubeadm token create --print-join-command
kubeadm token create --ttl 0 --print-join-command
kubeadm join --token y1eyw5.ylg568kvohfdsfco --discovery-token-ca-cert-hash sha256: 6c35e4f73f72afd89bf1c8c303ee55677d2cdb1342d67bb23c852aba2efc7c73
6、验证集群
#获取所有节点
kubectl get nodes
#给节点打标签
## k8s中万物皆对象。node:机器 Pod:应用容器
###加标签 《h1》
kubectl label node k8s-02 node-role.kubernetes.io/worker=''
###去标签
kubectl label node k8s-02 node-role.kubernetes.io/worker-
## k8s集群,机器重启了会自动再加入集群,master重启了会自动再加入集群控制中心
从此k8s就安装完毕了!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。