---------------第一部分----------------------
一.应用部署方式
1.传统部署:直接部署在物理机上,简单但是耗资
2.虚拟化部署:一台物理机上面有多个虚拟机,提供了虚拟机间一定的安全,但是增加了操作系统,耗费部分资源
3.容器化部署:会共享操作系统
问题:一个容器故障,如何去替补停机的容器
当访问并发量大时,如何实现横向扩容(伸缩)
二.容器编排应用
为了解决上述问题,出现了容器编排的软件
1.Docker自己的编排工具,Docker compose
2.k8s:Google开源容器编排工具
为什么要使用k8s???
1.解决了一个容器故障,在短时间内重新启动新的容器
2.解决了并发访问量大时,横向扩容和自动伸缩问题同时还可以整体迁移
3.如果发现新的版本有问题,可以立即回退到原来版本进行版本回退
4.容器编排,可以根据容器自身的需求自动创建存储卷
举例:
当程序员创建了一个网站,结果访问量大,那么他会多开几台服务器去解决,后面呢,又添加了语音,商场等服务,面对用户千奇百怪的需求,就需要登录到不同server去设置,费时费力,那么可以使用介于应用服务和服务器之间的中间层k8s来管理,同时还能做负载均衡,仅需要一个YAML即可
三.架构:控制平面+工作节点
3.1.k8s-master
①apiserver:不需要登录到每台服务器,只需调用接口,就可以接收命令,进行操作
②scheduler:不用进入每台服务器查看cpu和内存,就可以进行集群资源调度,将pod调度到相应节点
③controller manager:维护集群状态,不需要手动去创建关闭服务
④etcd:存储集群资源信息
3.2.k8s-node
①kubelet:管理和监控pod,创建和销毁容器,同时负责管理资源卷和网络
②pod:资源调度的最小单元
③kube-proxy:将外部请求转发至pod,提供容器内部服务发现和负载均衡
④container runtime:容器运行时组件
kubectl是k8s的内部命令,用于调用k8s的API
Ingress控制器是k8s集群的入口控制器,用于将内部服务暴露给外部使用
四.k8s工作流程
1.写一个YAML文件,里面包含images,cpu,memory等信息
2.kubectl apply xxx.yaml(读取文件,解析后通过api请求发送给k8s的apiserver)
3.apiserver驱使schudule根据etcd数据将资源调度到相应node
4.comtainer manager控制node去创建服务
5.在node节点,首先会基于container runtime去拉取镜像,创建容器,此时,pod完成创建
当外部请求到达Ingress控制器,继而转发至node里面的kube-proxy(干活的),继而会被转发到pod,
---------------第二部分----------------------
一.环境部署
172.25.254.200 harbor rhel9.1 2G 两核
172.25.254.161 k8s_master rhel9.1 4G 4核
172.25.254.162 k8s_node1 rhel9.1 4G 4核
172.25.254.163 k8s_node2 rhel9.1 4G 4核
1.1.基础环境
所有节点禁用selinux和防火墙
所有节点做时间同步和解析
所有节点安装Docker-ce
所有节点禁用swap,同时注释掉/etc/fstab里面关于swap分区的挂载信息
若是发现自己磁盘问题,挂载不对,可以进行修复:
vim /etc/rc.d/rc.local
touch /var/lock/subsys/local
mount /dev/sr1 /rhel9
umount /dev/sr0
/etc/rc.d/rc.local
yum list httpd(测试是否修复)
1.搭建好harbor服务器(参考Docker容器技术)
docker compose down
docker compose up -d
2.安装docker
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://reg.timinglee.org"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
systemctl restart docker
3.k8s_master操作
scp /data/certs/timinglee.org.crt root@172.25.254.161:/etc/docker/certs.d/reg.timninglee.org/ca.crt
4.配置非加密认证(k8s_master)
vim /etc/docker/daemon.json
{
"registry-mirrors":["https://reg.timinglee.org"]
}
5.systemctl restart docker
5.登录harbor
docker login reg.timinglee.org
username:admin
password:Mnwl@0816
k8s_master配置好后(存在ca.crt daemon.json)
scp -r /etc/docker root@172.25.254.162:/etc/
scp -r /etc/docker root@172.25.254.163:/etc/
-r 递归复制
-p 保留文件权限和修改时间
注意:172.25.254.200 reg.timinglee.org
测试拉取镜像,保证harbor无误
1.2.禁用swap分区
swapon -s查看swap分区
swapoff -a 关闭系统所有swap分区
1.当容器应用程序需要更多内存资源时,内核会直接从物理内存中分配资源,而不是从swap分区中读取数据。这可以减少磁盘I/O操作,提高应用程序的运行效率
2.当物理内存不够用时,系统会使用swap分区作为临时存储。但是,由于磁盘I/O操作的延迟较高,使用swap分区会导致应用程序的响应时间增加。关闭swap分区可以有效避免OOM问题的发生
1.3.安装k8s部署工具(都要)
配置好网络源后:
yum search kubeadm
yum search kubelet
yum search cri-tools
yum search kubernetes-cni
发现本地仓库缺少前两个
yum install kubelet-1.30.0-150500.1.1 kubeadm-1.30.0-150500.1.1 --downloadonly --downloaddir=/mnt
可以对软件包进行打包,方便其他server的使用
tar czf k8s-rpm.tar.gz k8s/
[root@k8s-master ~]# dnf install kubelet-1.30.0 kubeadm-1.30.0 kubectl-1.30.0 -y
systemctl enable --now kubelet.service
1.4.设置补全命令
[root@k8s-master ~]# dnf install bash-completion -y
[root@k8s-master ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc
[root@k8s-master ~]# source ~/.bashrc
1.5.安装cri-docker
root@k8s-master ~]# dnf install libcgroup-0.41-19.el8.x86_64.rpm \
> cri-dockerd-0.3.14-3.el8.x86_64.rpm -y
指定网络插件名称及基础镜像
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=reg.timinglee.org/k8s/pause:3.9
[root@k8s-master ~]# systemctl daemon-reload
[root@k8s-master ~]# systemctl start cri-docker
注意:只有把k8s所需镜像拉取下来,才会在harbor里面有基础镜像
1.6.在master节点拉取k8s镜像
root@k8s-master ~]# kubeadm config images pull \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock
上传镜像到harbor仓库
[root@k8s-master ~]# docker images | awk '/google/{ print $1":"$2}' \
| awk -F "/" '{system("docker tag "$0" reg.timinglee.org/k8s/"$3)}'
[root@k8s-master ~]# docker images | awk '/k8s/{system("docker push "$1":"$2)}'
1.7.集群初始化
#启动kubelet服务
[root@k8s-master ~]# systemctl status kubelet.service
#执行初始化命令
[root@k8s-master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 \
--image-repository reg.timinglee.org/k8s \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock
#指定集群配置文件变量
[root@k8s-master ~]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
#当前节点没有就绪,因为还没有安装网络插件,容器没有运行
[root@k8s-master ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master.timinglee.org NotReady control-plane 4m25s v1.30.0
root@k8s-master ~]# kubectl get pod -A
在此阶段如果生成的集群token找不到了可以重新生成
[root@k8s-master ~]# kubeadm token create --print-join-command
1.8.安装flannel网络插件
[root@k8s-master ~]# wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
[root@k8s-master ~]# docker pull docker.io/flannel/flannel:v0.25.5
[root@k8s-master ~]# docekr docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1
[root@k8s-master ~]# docker tag flannel/flannel:v0.25.5 \
reg.timinglee.org/flannel/flannel:v0.25.5
[root@k8s-master ~]# docker tag flannel/flannel-cni-plugin:v1.5.1-flannel1 \
reg.timinglee.org/flannel/flannel-cni-plugin:v1.5.1-flannel
[root@k8s-master ~]# docker push reg.timinglee.org/flannel/flannel:v0.25.5
[root@k8s-master ~]# docker push reg.timinglee.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
#编辑kube-flannel.yml 修改镜像下载位置
[root@k8s-master ~]# vim kube-flannel.yml
146: image: reg.timinglee.org/flannel/flannel:v0.25.5
173: image: reg.timinglee.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
184: image: reg.timinglee.org/flannel/flannel:v0.25.5
#安装flannel网络插件
[root@k8s-master ~]# kubectl apply -f kube-flannel.yml
1.9.节点扩容
[root@k8s-node1 & 2 ~]# kubeadm join 172.25.254.100:6443 --token 5hwptm.zwn7epa6pvatbpwf --discovery-token-ca-cert-hash sha256:52f1a83b70ffc8744db5570288ab51987ef2b563bf906ba4244a300f61e9db23
--cri-socket=unix:///var/run/cri-dockerd.sock
[root@k8s-master ~]# kubectl get nodes
2.0.故障解决
kubectl delete nodes k8s_node1
kubectl delete nodes k8s_node2
kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
再执行初始化命令
二. k8s中的资源
资源管理方式:
1.命令式对象管理(命令行)
2.命令式对象配置(命令(create/patch)+yaml文件)
3.声明式对象配置(apply命令+yaml配置文件)
2.1.命令式对象管理
kubectl get pod 查看所有pod
kubectl get pod pod_name 查看某个pod
kubectl get pod pod_name -o yaml 查看某个pod,以yaml的格式展示结果
2.2.基本命令
1.显示集群版本
[root@k8smaster ~]# kubectl version
2.显示集群信息
[root@k8smaster ~]# kubectl cluster-info
3.给镜像打标签
[root@k8smaster ~]# docker tag busybox:latest reg.timinglee.org/mnwl/busybox:latest
4.上传本地镜像到镜像仓库
[root@k8smaster ~]# docker push reg.timinglee.org/mnwl/busybox:latest
5.创建一个名为webcluster的控制器,pod数量为2
[root@k8smaster ~]# kubectl create deployment webcluster --image reg.timinglee.org/mnwl/nginx:laest --replicas 2
6.查看控制器
[root@k8smaster ~]# kubectl get deployments.apps
7.查看资源帮助
[root@k8smaster ~]# kubectl explain deployment
8.查看控制器参数帮助
[root@k8smaster ~]# kubectl explain deployment.spec
9.编辑控制器
[root@k8smaster ~]# kubectl edit deployment.apps webcluster
10.利用补丁更改控制器数量
[root@k8smaster ~]# kubectl patch deployments.apps webcluster -p '{"spec":{"replicas":3}}'
11.删除控制器资源
[root@k8smaster ~]# kubectl delete deployments.apps webcluster
2.3.运行和调试命令
1.运行pod
[root@k8smaster ~]# kubectl run testpod --image reg.timinglee.org/mnwl/nginx:latest
[root@k8smaster ~]# kubectl get pods
2.端口暴露
[root@k8smaster ~]# kubectl get services
[root@k8smaster ~]# kubectl expose pod testpod --port 80 --target-port 80
3.查看资源详细信息
[root@k8smaster ~]# kubectl describe pods testpod
4.快速删除资源信息
[root@k8smaster ~]# kubectl delete pods/testpod --force
5.查看资源日志
[root@k8smaster ~]# kubectl logs pods/testpod
6.进行交互pod
[root@k8smaster ~]# kubectl run -it testpod --image reg.timinglee.org/mnwl/busybox
[root@k8smaster ~]# kubectl attach pods/testpod -it
[root@k8smaster ~]# kubectl exec -it pods/testpod /bin/sh
7.本机和pod的文件交换
[root@k8smaster ~]# kubectl cp anaconda-ks.cfg testpod:/
2.4.高级命令
1.利用命令生成yaml文件
[root@k8smaster ~]# kubectl create deployment --image reg.timinglee.org/mnwl/nginx webc luster --dry-run=client -o yaml > webcluster.yml
2.利用yaml文件生成资源
[root@k8smaster ~]# kubectl apply -f webcluster.yml
3.管理资源标签
[root@k8smaster ~]# kubectl run nginx --image reg.timinglee.org/mnwl/nginx:latest
[root@k8smaster ~]# kubectl get pods --show-labels
4.添加标签
[root@k8smaster ~]# kubectl label pods nginx app=mnwl
5.更改标签
[root@k8smaster ~]# kubectl label pods nginx app=cluster --overwrite
6.删除标签
[root@k8smaster ~]# kubectl label pods nginx app-
7.用控制器管理的pod,删除pod,会自动创建pod,除非删除控制器
[root@k8smaster network-scripts]# kubectl get pod
NAME READY STATUS RESTARTS AGE
testpod 1/1 Running 0 4h48m
webcluster-7697fbcd88-jmmcp 1/1 Running 0 3h49m
[root@k8smaster ~]# kubectl delete pod webcluster-7697fbcd88-jmmcp
pod "webcluster-7697fbcd88-jmmcp" deleted
[root@k8smaster ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
testpod 1/1 Running 0 4h50m
webcluster-7697fbcd88-9bk8t 1/1 Running 0 4s
2.5. pod
2.5.1.pod的基本命令
1.一个pod代表集群运行的一个进程,每个pod都有一个唯一的ip
2.一个pod里面包含多个容器(通常是Docker)
3.一个pod里面的容器间共享ip,network,namespace
利用控制器管理pod(推荐)!!!
高可用和故障恢复:自动故障恢复,健康检查和自愈
可扩展性:通过更改yaml文件可以增加和减少pod数量,以满足不同的需求
一致的部署方式:在不同的环境(如开发、测试、生产)中,可以使用相同的控制器和配置来部署应用,确保应用在不同环境中的行为一致。这有助于减少部署差异和错误,提高开发和运维效率。
kubectl create deployment timinglee --image nginx
kubectl get pods
#为timinglee扩容
kubectl scale deployment timinglee --replicas 6
#为timinglee缩容
kubectl scale deployment timinglee --replicas 2
#利用控制器建立pod
kubectl create deployment timinglee --image myapp:v1 --replicas 2
#暴露端口
kubectl expose deployment timinglee --port 80 --target-port 80
#查看资源
kubectl get services
#查看历史版本
kubectl rollout history deployment timinglee
#更新控制器镜像版本
kubectl set images deployments/timinglee myapp=myapp:v2
#版本回滚
kubectl rollout undo deployment timinglee --to-revision 1
2.6.用yaml文件部署应用
获取资源帮助:kubectl explain pod.spec.containers
参考文档:
1.注意如果多个容器运行在一个pod中,资源共享的同时在使用相同资源时也会干扰,比如端口 (所以一个pod不能有两个同样的容器,资源会冲突)
2.同在一个pod中的容器公用一个网络
3.资源限制会影响pod的服务质量,资源优先级分为Guaranteed > Burstable > BestEffort
资源设定 | 优先级类型 |
---|---|
资源限定未设定 | BestEffort |
资源限定设定且最大和最小不一致 | Burstable |
资源限定设定且最大和最小一致 | Guaranteed |
4.restartPolicy: Always
容器启动管理:always 总是启动,never,pod终止后不会启动,OnFailure,非正常结束会重启
三.pod的生命周期
在K8S中,如何把Pod调度到某个节点,有哪些方法?-阿里云开发者社区
K8S 亲和性与反亲和性-CSDN博客
前言:pod的调度方法
pod一般会通过deployment根据节点资源的使用情况进行分配,但是我们也可以根据一定的参数设置来进行pod的调度
1.deployment根据一定的算法自动调度
2.Nodename调度:在Pod的定义中直接指定
nodeName
字段,强制将Pod调度到指定的节点3.nodeselector调度:通过在Pod的定义中指定
nodeSelector
可以匹配具有相应标签的节点。4.亲和性反亲和性调度
5.污点容忍调度
3.1.init容器
pod里面有多个容器,其中包括一个或多个先于应用容器启动的init容器,它和普通容器很像,必须在pod就绪之前就运行完成,而且是一个接着一个的运行,如果pod里面的init容器失败,那么k8s会不断重启该pod,直到init容器运行完成,若是pod对应的restartPolicy为Nerver,那么它不会重启
init容器的功能:
- 初始化操作:Init容器可以执行一些需要在主应用启动之前完成的任务,如创建文件、修改内核参数、等待依赖程序启动等。12
- 资源准备:Init容器可以负责从配置存储或其他位置获取额外的资源或文件,如配置文件、SSL证书、密钥等,并将它们复制到应用容器可以访问的位置。
- 数据预处理:Init容器可以在应用容器之前执行数据预处理任务,如解压缩文件、验证数据完整性等,确保应用容器运行时所需的数据已准备就绪。
- 安全运行:Init容器可以以root身份运行,执行一些高权限命令,避免在主应用容器中安装这些工具,从而降低安全风险。5
- 灵活配置:每个Pod中可以包含多个Init容器,允许更灵活地执行各种初始化任务。3
- 延迟应用启动:Init容器可以用于延迟执行应用容器,直到满足特定的条件(如某个服务可用)后才启动应用容器。1
- 访问敏感信息:Init容器可以访问到应用容器不能访问的Secret权限,用于获取配置中心配置等敏感信息
3.2.init容器示例
3.3.探针
探针是由kubelet对容器执行的定期诊断:
ExecAction:在容器内执行指定命令
TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查
HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求
livenessProbe:指示容器是否正在运行---存活探针
readinessProbe:指示容器是否准备好服务请求---就绪探针
startupProbe: 指示容器中的应用是否已经启动--启动探针
3.3.1.存活探针
3.3.2.就绪探针
四.控制器的使用
控制器是管理pod的一种手段,始终需要维持pod副本数量,是管理Pod的中间层,如果Pod资源在运行中出现故障,那么它会基于指定策略重新编排Pod
当建立控制器后,会把期望值写入etcd,k8s中的apiserver检索etcd中我们保存的期望状态信息,并对比Pod的当前状态,如果出现差异代码会立即恢复
常用类型:
ReplicaSet:确保pod副本数量
Deployment:确保副本数量,版本升级更新回滚
DaemonSet:确保全指定节点上运行一个Pod副本
cronJob:基于时间调度的jobs
4.1.replicaset控制器
回收资源:
[root@k8s2 pod]# kubectl delete -f rs-example.yml
4.2.deployment控制器
1.Deployment控制器并不直接管理pod,而是通过管理ReplicaSet来间接管理Pod
2.运行无状态应用(不会对本地环境产生依赖,不会依赖上次应用的运行状态)
3.Deployment 为 Pod 和 ReplicaSet 提供了一个申明式的定义方法
4.在Deployment中ReplicaSet相当于一个版本
比如说一个deployment指向一组由replicaset控制的pod,当有新的版本时,deployment通过改变对于repicaset控制的pod的指向来进行版本升级更新和回退
deployment也支持标签匹配,来维护pod数量,若是更新版本,只需修改yaml配置文件即可
4.3.daemonset控制器
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时, 也会为他们新增一个 Pod ,当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod
可以在每个节点上运行集群存储ceph,日志收集,运行监控如prometheus或者zabbix agent
4.4.job控制器
Job,主要用于负责批量处理(一次要处理指定数量任务)短暂的一次性(每个任务仅运行一次就结束)任务
特点:
当Job创建的pod执行成功结束时,Job将记录成功结束的pod数量
当成功结束的pod达到指定的数量时,Job将完成执行
4.5.cronjob控制器
Cron Job 创建基于时间调度的 Jobs
管控job控制器资源
注:cronjob通过job控制pod,每分钟执行完后不会重启,只会建立新的pod(Onfailure)
五.k8s中的微服务
用控制器来完成器群工作调度发现负载,如何将应用暴露出去?需要通过微服务暴露出去才能被访问
Service是一组提供相同服务的Pod对外开放的接口。
借助Service,应用可以实现服务发现和负载均衡
service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)
注:可以把微服务理解为控制器对外开放的一个端口,可以通过标签的对比来实现服务的自动发现,和负载均衡
k8s服务LoadBalancer模式 k8s中service_mob64ca1418aeab的技术博客_51CTO博客https://blog.51cto.com/u_16213718/11622308
微服务类型:
ClusterIP:默认,k8s给service自动分配的虚拟IP,只能在集群内部访问
NodePort:外部可以访问,本机IP+最后暴露的端口,可以将路由转到ClusterIP,从而在集群外部可以访问到集群内部
LoadBalaner:外接负载均衡器实现服务的负载分发,需要外部云环境的支持
ExternalName:把集群外部的服务引入集群内部,直接使用(使用服务的迁移)
5.1.iptables模式
#生成控制器文件并建立控制器
[root@k8s-master ~]# kubectl create deployment timinglee --image myapp:v1 --replicas 2 --dry-run=client -o yaml > timinglee.yaml
[root@k8s-master ~]# kubectl apply -f timinglee.yaml
#生成微服务yaml追加到已有yaml中
[root@k8s-master ~]# kubectl expose deployment timinglee --port 80 --target-port 80 --dry-run=client -o yaml >> timinglee.yaml
[root@k8s-master ~]# vim timinglee.yaml
5.2.ipvs模式
我们k8s微服务默认使用kube-proxy+iptables实现端口暴露,但是过多的pod会不断刷新iptables规则,每一条路由规则都是需要消耗大量cpu,因此改为ipvsadm来实现路由转发更能节约资源。并且也可以实现服务的自动发现。
yum install ipvsadm -y
#修改master节点的代理配置
kubectl -n kube-system edit cm kube-proxy
mode: "ipvs"
#重启pod,可以将proxy-pass相关的pod删除,他会根据新的配置文件去重新生成pod
[root@k8s-master ~]# kubectl -n kube-system get pods | awk '/kube-proxy/{system("kubectl -n kube-system delete pods "$1)}'
注意:切换ipvs模式之后,kube-proxy会在宿主机上面添加一个虚拟网卡,kubectl-ipvs0,并且分配所有service ip
5.3.clusterip
5.4.clusterip的无头服务
对于无头
Services
并不会分配 Cluster IP,kube-proxy不会处理它们, 而且平台也不会为它们进行负载均衡和路由,集群访问通过dns解析直接指向到业务pod上的IP,所有的调度有dns单独完成
5.5.nodeport
5.6.loadbalancer
5.6.1 .下载metallb
kubectl edit configmap -n kube-system kube-proxy
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: true
[root@k8smaster ~]# docker load -i metalLB.tag.gz
5..6.2.上传metallb到harbor仓库
[root@k8smaster ~]# docker tag quay.io/metallb/controller:v0.14.8 reg.timinglee.org/metallb/controller:v0.14.8
[root@k8smaster ~]# docker tag quay.io/metallb/speaker:v0.14.8 reg.timinglee.org/metallb/speaker:v0.14.8
[root@k8smaster ~]# docker push reg.timinglee.org/metallb/controller:v0.14.8
[root@k8smaster ~]# docker push reg.timinglee.org/metallb/speaker:v0.14.8
5.6.3.修改配置文件
[root@k8smaster ~]# kubectl apply -f timinglee.yml
[root@k8smaster ~]# kubectl apply -f metallb-native.yaml
[root@k8smaster ~]# kubectl apply -f configmap.yml
5.6.4.测试
5.7.externalname
在应用向集群迁移时,externalname在过渡阶段起作用,在迁移过程中IP会变化,可通过域名+dns解析来解决ip变化的问题。
即在内部定义一个svc,和外部资源进行绑定
5.8. ingress-nginx
5.8.1.部署ingress
[root@k8smaster ~]# docker load -i ingress-nginx-1.11.2.tar.gz
Loaded image: reg.harbor.org/ingress-nginx/controller:v1.11.2
Loaded image: reg.harbor.org/ingress-nginx/kube-webhook-certgen:v1.4.3
[root@k8smaster ~]# docker tag reg.harbor.org/ingress-nginx/controller:v1.11.2 reg.timinglee.org/ingress-nginx/controller:v1.11.2
[root@k8smaster ~]# docker tag reg.harbor.org/ingress-nginx/kube-webhook-certgen:v1.4.3 reg.timinglee.org/ingress-nginx/kube-webhook-certge n:v1.4.3
[root@k8smaster ~]# docker push reg.timinglee.org/ingress-nginx/controller:v1.11.2
[root@k8smaster ~]# docker push reg.timinglee.org/ingress-nginx/kube-webhook-certgen:v1.4.3
#修改镜像位置为仓库位置
[root@k8smaster ~]# kubectl apply -f deploy.yaml
5.8.2.测试ingress
[root@k8smaster ~]# kubectl -n ingress-nginx edit svc ingress-nginx-controlle
5.8.3.ingress基于路径的访问
前面说过了,可以建立一个与svc一样名称的ingress去进行外部到内部的访问,但是我们也可以在一个ingress的yaml文件中定义多个路径从而实现对不同的微服务进行访问
注意:里面必须是域名
5.8.4.ingress基于域名的访问
5.8.5.建立tls加密
#建立证书
[root@k8smaster ~]# openssl req -newkey rsa:2048 -nodes -keyout tls.key -x509 -days 365 -subj "/CN=nginxsvc/O=nginxsvc" -out tls.crt
#建立k8s加密的资源类型
[root@k8smaster ~]# kubectl create secret tls web-tls-secret --key tls.key --cert tls.crt
注:secret通常在k8s中存放敏感信息,并不是一种加密方式
5.8.6.建立auth认证
#建立认证文件
[root@k8s-master app]# dnf install httpd-tools -y
[root@k8s-master app]# htpasswd -cm auth lee
[root@k8s-master app]# cat auth
lee:$apr1$BohBRkkI$hZzRDfpdtNzue98bFgcU10
#建立认证类型资源
[root@k8s-master app]# kubectl create secret generic auth-web --from-file auth
root@k8s-master app]# kubectl describe secrets auth-web
5.3.5.rewrite重定向
5.9.Canary金丝雀发布
5.9.1.基于http包头的发布
5.9.2.基于权重的发布
六.k8s中的存储
6.1.configmap
6.1.1.字面键值创建
6.1.2.文件创建
6.1.3.目录创建
6.1.4.yaml文件创建
6.2.configmap的使用方式
6.2.1.使用configmap填充环境变量
将cm中的内容映射为指定变量
将cm中的值直接映射为变量
在pod命令行中使用变量
6.2.2.通过数据卷使用configmap
6.2.3.利用configmap填充pod配置文件
举个例子吧,若是部署一个Nginx服务,但是当我们需要更改配置文件,就需要进入每一个主机的pod里面去更改,那么利用configmap去填充一个配置文件,利用deployment去管理各个主机内的Nginx服务,相当于把配置文件挂载在了pod的具体目录下,只需要在外部更改文件内容,然后删除pod,deployment会重新创建pod,就相当于重启了pod,也就是重新加载了配置文件
利用热更新修改cm修改配置
6.3.secerts的创建
6.3.1.文件方式创建
6.3.2.yaml方式创建
6.4.secret的使用方法
6.4.1.将secret挂载到Volume中
6.4.2.更改挂载路径
6.4.3.将secret设置为环境变量
6.4.4.存储docker registry的认证信息
6.5.volumes配置管理
官网:卷 | Kubernetes
6.5.1.emptyDir卷
6.5.2.hostPath卷
6.5.3.nfs卷(数据和集群分离)
yum install nfs-utils -y
6.6.PersistentVolume持久卷(pv)
静态持久卷pv 静态持久卷声明pvc
6.6.存储类storageclass
官网: GitHub - kubernetes-sigs/nfs-subdir-external-provisioner: Dynamic sub-dir volume provisioner on a remote NFS server.
StorageClass是Kubernetes中一种重要的资源类型,是一种逻辑上的存储分类,主要目的是动态创建PV,当用户请求一个PVC时,Kubernetes可以根据定义的StorageClass动态地创建和配置相应的PV,从而实现存储资源的自动化管理和优化分配。
StorageClass的优势在于支持PV的动态创建,这对于需要大量存储资源或者管理员手动创建的PV无法满足PVC所有需求的情况非常有用。通过这种方式,Kubernetes为存储管理带来了极大的灵活性,同时也提高了存储资源的利用率和系统的可扩展性。
属性说明:存储类 | Kubernetes
Provisioner(存储分配器):用来决定使用哪个卷插件分配 PV,该字段必须指定。可以指定内部分配器,也可以指定外部分配器。外部分配器的代码地址为: kubernetes-incubator/external-storage,其中包括NFS和Ceph等。
Reclaim Policy(回收策略):通过reclaimPolicy字段指定创建的Persistent Volume的回收策略,回收策略包括:Delete 或者 Retain,没有指定默认为Delete。
6.6.1.创建sa并授权
首先需要有nfs环境:在上面官网中具体配置内容和步骤
kind: Namespace
metadata:
name: nfs-client-provisioner
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: nfs-client-provisioner
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: nfs-client-provisioner
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
创建命名空间以及主体(服务账号)
定义集群角色以及此命名空间的权限
角色绑定
6.6.2.部署应用
前提:上传镜像到本地harbor仓库
6.6.3.创建存储类
6.6.4.创建PVC请求
6.6.5.创建测试pod
pod的创建的卷的请求和pvc请求名关联,pvc请求和存储类关联,存储类被nfs存储分配器以变量的形式监控着
6.6.6.默认存储类
6.7.statefulset控制器
主要是为了解决deployment控制每次创建pod的名称和IP不一样的这种无状态的情况
6.7.1.建立无头服务
6.7.2.建立statefulset
6.7.3.测试
6.7.4.ststefulset的弹缩
方法一:kubectl scale statefulset <stateful-set-name> --replicas=<new-replicas>
方法二:kubectl edit statefulsets.apps <stateful-set-name>
七.k8s网络通信
7.1.k8s通信整体架构
1.k8s通过cni接入其他插件来实现网络通信,比较流行的有flannel,calico等
2.cni插件存在位置:/etc/cni/net.d/10-flannel.conflist
容器间通讯:
1.同一个pod内的容器通讯:本地回环接口(lo)
2.同一个节点的pod通讯:cni网桥转发数据包
3.不同节点的pod:网络插件
pod和service通信:
iptables:可以做nat转换,端口转发,流量过滤
ipvs:可以做负载均衡,服务器健康检查
pod和集群外部客户端通信:
1.nodeport:主机IP+暴露的端口(消耗端口)
2.loadbalancer:依靠云平台,并且会自动分配一个虚拟IP(172.25.254.180)
3.ingress:代理,可以处理http和https请求,流量到达ingresscontronal--ingressconfig--service--endpoints--pod(可以基于域名或者路径访问到不同service)
7.2.flannel插件
1.当容器发送IP包,发往本机的cni网桥,再路由到本机的flannel.1设备进行处理
2.flannel.1设备根据arp广播只知道另一端flannel.1设备所在的主机的MAC地址,却不知道对应的宿主机地址是什么
3.linux内核在IP包前面加上VXLAN Header,把目标节点的MAC地址填进去 ,数据包就从本机eth0传送到了对端eth0
4.对端根据VLAN Header找到对方的flanner插件,然后将数据包发往cni网桥,进而到达目标容器
7.3.calico网络插件
Install Calico networking and network policy for on-premises deployments | Calico Documentation
纯三层转发,转发效率好,calico仅依赖三层路由可达,依赖较少,能适配所有的VM,container,白盒或者混合环境场景
7.3.1.部署calico
[root@k8smaster ~]# kubectl delete -f kube-flannel.yml
#每个节点删除,防止冲突
[root@k8snode2 ~]# rm -f /etc/cni/net.d/10-flannel.conflist
[root@k8smaster ~]# docker load -i calico
[root@k8smaster ~]# docker tag calico/cni:v3.28.1 reg.timinglee.org/calico/cni:v3.28.1
[root@k8smaster ~]# docker tag calico/node:v3.28.1 reg.timinglee.org/calico/node:v3.28.1
[root@k8smaster ~]# docker tag calico/kube-controllers:v3.28.1 reg.timinglee.org/calico/kube-controllers:v3.28.1
[root@k8smaster ~]# docker tag calico/typha:v3.28.1 reg.timinglee.org/calico/typha:v3.28.1
[root@k8smaster ~]# docker push reg.timinglee.org/calico/cni:v3.28.1
[root@k8smaster ~]# docker push reg.timinglee.org/calico/node:v3.28.1
[root@k8smaster ~]# docker push reg.timinglee.org/calico/kube-controllers:v3.28.1
[root@k8smaster ~]# docker push reg.timinglee.org/calico/typha:v3.28.1
[root@k8smaster ~]# kubectl apply -f calico.yaml
kubectl apply -f calico.yaml
7.3.2.测试calico
7.4.scheduling调度
调度器通过 kubernetes 的 watch 机制来发现集群中新创建且尚未被调度到 Node 上的 Pod
调度器会将发现的每一个未调度的 Pod 调度到一个合适的 Node 上来运行
调度原理:
7.4.1.nodename调度
[root@k8smaster schrduling]# kubectl run testpod --image mnwl/myapp1:v1 --dry-run=client -o yaml > example.yml
[root@k8smaster schrduling]# vim example.yml
[root@k8smaster schrduling]# kubectl apply -f example.yml
7.4.2.nodeselector调度
7.5.k8s中的认证授权
Kubernetes(k8s)服务账号Service Accounts - 人生的哲理 - 博客园Kubernetes(k8s)服务账号Service Accounts,服务账号Service Accounts简介,用户账号与服务账号区别,创建服务账号(Service Accounts),对服务账号(Service Accounts)授权,在pod里使用服务账号(Service Accountshttps://www.cnblogs.com/renshengdezheli/p/17512947.html
1.建立账户:建立sa(服务账户),创建后命名空间默认,其他都为空,
2.建立认证:每一个服务账户都对应一个密码认证(secrets),建立secrets,将密码注入到sa,进行pod的身份验证
3.授权:pod和sa进行绑定,授予pod权限
限制了pod的权限
7.5.1.serviceaccount认证授权
步骤一:
#创建sa并查看
[root@k8smaster ~]# kubectl create sa timinglee
[root@k8smaster ~]# kubectl describe sa timinglee
步骤二:
#对harbar仓库创建认证,生成密码,并注入到sa
[root@k8smaster ~]# kubectl create secret docker-registry docker-login --docker-username admin --docker-password Mnwl@0816 --docker-server reg.timinglee.org --docker-email lee@timinglee.org
步骤三:
#sa对pod进行授权(也就是pod和sa绑定,既然sa的认证密码里面就是登录harbor的信息,那么pod也就可以拉取镜像)
apiVersion: v1
kind: Pod
metadata:
labels:
run: testpod
name: testpod
spec:
serviceAccountName: timinglee
containers:
- image: mnwl/myapp1:v1
name: testpod
7.6.2.用户认证
k8s不会管理用户,比如我们外部使用的kubectl就是使用了用户认证,user是通过名字进行唯一标识的,我们进行用户认证只是为了k8s能够认知此用户,并且控制用户在k8s中的权限
#切换目录,此目录常用来存放关键证书和密钥文件
[root@k8s-master auth]# cd /etc/kubernetes/pki/
#生成私钥
[root@k8s-master pki]# openssl genrsa -out timinglee.key 2048
#利用私钥生成签名请求文件timinglee.csr
[root@k8s-master pki]# openssl req -new -key timinglee.key -out timinglee.csr -subj "/CN=timinglee"
#利用ca证书和私钥签署csr,生成x509格式的证书
[root@k8s-master pki]# openssl x509 -req -in timinglee.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out timinglee.crt -days 365
Certificate request self-signature ok
#查看证书timinglee.crt
[root@k8s-master pki]# openssl x509 -in timinglee.crt -text -noout
#在 Kubernetes 配置中设置一个名为 timinglee 的用户凭证
[root@k8s-master pki]# kubectl config set-credentials timinglee --client-certificate /etc/kubernetes/pki/timinglee.crt --client-key /etc/kubernetes/pki/timinglee.key --embed-certs=true
#创建一个名为 timinglee@kubernetes 的上下文
[oot@k8s-master ~]# kubectl config set-context timinglee@kubernetes \
--cluster=kubernetes \
--user=timinglee
#查看当前的 Kubernetes 配置信息
[root@k8s-master pki]# kubectl config view
八.helm包管理工具
简介:
8.1.helm部署
[root@k8s-master helm]# tar zxf helm-v3.15.4-linux-amd64.tar.gz
[root@k8s-master helm]# cd linux-amd64/
[root@k8s-master linux-amd64]# cp -p helm /usr/local/bin/
#配置命令补齐
[root@k8s-master linux-amd64]# echo "source <(helm completion bash)" >> ~/.bashrc
[root@k8s-master linux-amd64]# source ~/.bashrc
[root@k8s-master linux-amd64]# helm version
#在官方仓库搜索nginx
[root@k8s-master helm]# helm search hub nginx
#在本地仓库搜索nginx
[root@k8s-master helm]# helm search repo nginx
#添加仓库
[root@k8s-master helm]# helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
[root@k8s-master helm]# helm repo add bitnami https://charts.bitnami.com/bitnami
#查看仓库信息
[root@k8s-master helm]# helm repo list
#查看仓库清单
[root@k8s-master helm]# helm search repo aliyun
#删除第三方仓库
[root@k8s-master helm]# helm repo remove aliyun
8.2.helm的简单使用
#查找chart
[root@k8s-master helm]# helm search repo nginx
#查看chart信息
[root@k8s-master helm]# helm show chart bitnami/nginx
#安装chart包
[root@k8s-master ~]# helm install timinglee bitnami/nginx
[root@k8s-master ~]# kubectl get pods
#查看项目状态
[root@k8s-master ~]# helm status timinglee
#卸载项目
[root@k8s-master nginx]# helm uninstall timinglee
[root@k8s-master nginx]# kubectl get pods
[root@k8s-master nginx]# helm list
#拉取项目
[root@k8s-master helm]# helm pull bitnami/nginx -version 18.1.11(项目版本)
[root@k8s-master helm]# ls
nginx-18.1.11.tgz(存放项目文件)
[root@k8s-master helm]# tar zxf nginx-18.1.11.tgz
[root@k8s-master helm]# ls
nginx nginx-18.1.11.tgz
[root@k8s-master helm]# cd nginx/
[root@k8s-master nginx]# vim values.yaml #项目变量文件
13 imageRegistry: "reg.timinglee.org"
#上传项目所需要镜像到仓库
[root@k8s-master ~]# docker tag bitnami/nginx:1.27.1 reg.timinglee.org/bitnami/nginx:1.27.1-debian-12-r2
[root@k8s-master ~]# docker push reg.timinglee.org/bitnami/nginx:1.27.1-debian-12-r2
#安装本地项目
[root@k8s-master nginx]# helm install timinglee /root/helm/nginx
[root@k8s-master nginx]# kubectl get svc
#更新项目
[root@k8s-master nginx]# vim values.yaml #更新变量文件
624 type: ClusterIP
751 enabled: true
763 hostname: myapp.timinglee.org
783 ingressClassName: "nginx"
[root@k8s-master nginx]# helm upgrade timinglee .
[root@k8s-master nginx]# curl myapp.timinglee.org
#查看历史
[root@k8s-master nginx]# helm history timinglee
#删除项目
[root@k8s-master nginx]# helm uninstall timinglee
8.3.构建helm中的chart包
1.建立chart项目
[root@k8s-master helm]# helm create timinglee
_helpers.stl #放置模板助手的地方,可以在整个 chart 中重复使用
[root@k8s-master timinglee]# vim Chart.yaml
apiVersion: v2
name: timinglee
description: A Helm chart for Kubernetes
type: application
version: 0.1.0 #项目版本
appVersion: "v1" #软件版本
[root@k8s-master timinglee]# vim values.yaml
image:
repository: mnwl/myapp1 #镜像位置
pullPolicy: IfNotPresent #拉取镜像策略
tag: "v1"
ingress:
enabled: true
className: "nginx" #kubectl get ingress
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: myapp.timinglee.org
paths:
- path: /
pathType: ImplementationSpecific
#语法检测
[root@k8s-master timinglee]# helm lint .
#项目打包
[root@k8s-master timinglee]# cd ..
[root@k8s-master helm]# helm package timinglee/
#项目可以通过各种分享方式发方为任何人后部署即可
[root@k8s-master helm]# helm install timinglee timinglee-0.1.0.tgz
8.4.chart仓库
官方网址:GitHub - chartmuseum/helm-push: Helm plugin to push chart package to ChartMuseum
#在线安装
[root@k8s-master helm]# dnf install git -y
[root@k8s-master helm]# helm plugin install https://github.com/chartmuseum/helm-push
#离线安装
8.5.helm的版本迭代
九.Prometheus监控
Prometheus是一个开源的服务监控报警系统和时序数据库,提供了数据模型和接口,它的核心组件Prometheus服务器定期目标中通过http主动拉取数据 ,中间网关进行数据推送,新拉取到的数据大会持久化到存储设备当中,优势就是易于管理,高效,可视化等。
架构:
9.1.部署
#在helm中添加Prometheus仓库
[root@k8s-master helm]# helm repo add prometheus-community https://prometheuscommunity.github.io/helm-charts
#下载Prometheus项目
[root@k8s-master helm]# helm pull prometheus-community/kube-prometheus-stack
[root@k8s-master helm]# ls
kube-prometheus-stack-62.6.0.tgz
#解压项目包
[root@k8s-master helm]# tar zxf kube-prometheus-stack-62.6.0.tgz
[root@k8s-master helm]# ls
kube-prometheus-stack kube-prometheus-stack-62.6.0.tgz
[root@k8s-master helm]# cd kube-prometheus-stack/
[root@k8s-master kube-prometheus-stack]# ls
Chart.lock charts Chart.yaml CONTRIBUTING.md README.md templates
values.yam
###根据所有项目中的value.yaml将images上传至harbor仓库
#利用helm安装Prometheus
[root@k8s-master kube-prometheus-stack]# kubectl create namespace kube-prometheus-stack
[root@k8s-master kube-prometheus-stack]# helm -n kube-prometheus-stack install
kube-prometheus-stack .
#查看所有pod是否运行
[root@k8s-master kube-prometheus-stack]# kubectl --namespace kube-prometheusstack get pods
#查看svc
[root@k8s-master kube-prometheus-stack]# kubectl -n kube-prometheus-stack get svc
#修改暴漏方式
[root@k8s-master kube-prometheus-stack]# kubectl -n kube-prometheus-stack edit
svc kube-prometheus-stack-grafana
type: LoadBalancer
9.2.登录grafana
针对于整个集群创建一个监控面板:13105
访问主程序:
两个pod是因为一个是nginx,一个是nginx的监控组件的pod