一、k8s简介及部署方法
1、k8s简介
kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:
自我修复:一旦某一个容器崩溃,能够在1秒中左右迅速启动新的容器
弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
服务发现:服务可以通过自动发现的形式找到它所依赖的服务
负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡
版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本
存储编排:可以根据容器自身的需求自动创建存储卷
2、k8s的设计架构
一个kubernetes集群主要是由控制节点(master)、工作节点(node)构成,每个节点上都会安装不同的组件
2.1、k8s-master节点组件
apiserver:不需要登录到每台服务器,只需调用接口,就可以接收命令,进行操作
scheduler:不用进入每台服务器查看cpu和内存,就可以进行集群资源调度,将pod调度到相应节点
controller manager:维护集群状态,不需要手动去创建关闭服务
etcd:存储集群资源信息
2.2、k8s-node节点组件
- kubelet:管理和监控pod,创建和销毁容器,同时负责管理资源卷和网络
- pod:资源调度的最小单元
- kube-proxy:将外部请求转发至pod,提供容器内部服务发现和负载均衡
- container runtime:容器运行时组件
2.3、k8s各组件之间的调用关系
当我们要运行一个服务时
- k8s环境启动后,master和nide都会将自身的信息存储到etcd数据库中
- web服务的安装请求会首先被发送到master节点的apiServer组件
- apiServer组件会调用scheduler组件来决定应该把这个服务安装到哪一个node节点,scheduler组件会从etcd数据库中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果返回apiServer
- apiServer调用controller-manager去调度Node节点安装对应服务
- kubelet接收到指令后,会通知docker,然后由docker启动一个对应服务的pod
- 如果需要访问web服务,就需要通过kube-proxy来对pod产生访问的代理
2.4、k8s的常用名词
- master:集群控制节点,每个集群需要至少一个master节点负责集群的管控
- node:工作节点,由master分配容器到这个node工作节点上
- pod:k8s的最小控制单元,容器都是运行在pod中,一个pod可有一个或多个容器
- controller:控制器,通过它实现对pod的管理,如启动pod,停止pod,伸缩pod数量等
- service:微服务,pod对外服务的统一入口,下面可以维护同一类的多个pod
- label:标签,用于对pod进行分类,同一类的pod拥有相同的标签
- nameSpace:命名空间,用来隔离pod的运行环境
3、k8s集群环境搭建
3.1、集群环境规划
主机名 | IP | 角色 |
www.yjun.com | 192.168.220.100 | harbor仓库 |
k8s-master | 192.168.220.10 | k8s集群控制节点 |
k8s-node1 | 192.168.220.20 | k8s集群工作节点 |
k8s-node2 | 192.168.220.30 | k8s集群工作节点 |
3.2、集群环境初始化
所有节点关闭selinux和防火墙,并将其上锁防止其他服务将其打开
systemctl stop firewalld.service
systemctl disabled firewalld.service
systemctl mask firewalld.service
grubby --update-kernel ALL --args selinux=0
所有节点在每次开启的时候禁用交换分区
#查看交换运行的交换分区
[root@www ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 4108284 41984 -2vim /etc/rc.d/rc.local
swapoff /dev/dm-1
chmod +x /etc/rc.d/rc.local
所有节点做好dns解析
[root@k8s-master ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.220.10 k8s-master
192.168.220.20 k8s-node1
192.168.220.30 k8s-node2
192.168.220.100 www.yjun.com
所有节点安装docker
#配置docker的yum仓库
[root@k8s-master ~]# cat /etc/yum.repos.d/docker.repo
[docker]
name=docker
baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/rhel/9/x86_64/stable/
gpgcheck=0#下载docker
yum install docker-ce -y
所有节点复制harbor仓库中的证书并启动docker
#创建证书存放目录
[root@k8s-master ~]# mkdir -p /etc/docker/certs.d/www.yjun.com#把harbor仓库中的证书拷贝到k8s所有的节点
scp /data/cert/yjun.com.crt root@192.168.220.10:/etc/docker/certs.d/www.yjun.com/#启动docker
systemctl enable --now docker
登录并查看harbor仓库的认证
#登录harbor
[root@k8s-master ~]# docker login www.yjun.com
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-storesLogin Succeeded#查看认证
[root@k8s-master ~]# docker info
Client: Docker Engine - CommunityVersion: 27.2.1Context: defaultDebug Mode: falsePlugins:buildx: Docker Buildx (Docker Inc.)Version: v0.16.2Path: /usr/libexec/docker/cli-plugins/docker-buildxcompose: Docker Compose (Docker Inc.)Version: v2.29.2Path: /usr/libexec/docker/cli-plugins/docker-composeServer:Containers: 34Running: 16Paused: 0Stopped: 18Images: 15Server Version: 27.2.1Storage Driver: overlay2Backing Filesystem: xfsSupports d_type: trueUsing metacopy: falseNative Overlay Diff: trueuserxattr: falseLogging Driver: json-fileCgroup Driver: systemdCgroup Version: 2Plugins:Volume: localNetwork: bridge host ipvlan macvlan null overlayLog: awslogs fluentd gcplogs gelf journald json-file local splunk syslogSwarm: inactiveRuntimes: io.containerd.runc.v2 runcDefault Runtime: runcInit Binary: docker-initcontainerd version: 7f7fdf5fed64eb6a7caf99b3e12efcf9d60e311crunc version: v1.1.14-0-g2c9f560init version: de40ad0Security Options:seccompProfile: builtincgroupnsKernel Version: 5.14.0-162.6.1.el9_1.x86_64Operating System: Red Hat Enterprise Linux 9.1 (Plow)OSType: linuxArchitecture: x86_64CPUs: 2Total Memory: 3.543GiBName: k8s-masterID: 35ee361d-0286-4227-8971-46729c61148cDocker Root Dir: /var/lib/dockerDebug Mode: falseExperimental: falseInsecure Registries:127.0.0.0/8Registry Mirrors:https://www.yjun.com/ #认证成功Live Restore Enabled: false
3.3、安装k8s部署工具
在所有节点配置k8s的yum源
[root@k8s-master ~]# cat /etc/yum.repos.d/k8s.repo
[k8s]
name=k8s
baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.30/rpm
gpgcheck=0
在所有节点下载部署工具
yum install kubelet-1.30.0 kubeadm-1.30.0 kubectl-1.30.0 -y
在所有节点设置kubectl命令补齐功能
[root@k8s-master ~]# yum install bash-completion -y
[root@k8s-master ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc
[root@k8s-master ~]# source ~/.bashrc
在所有节点安装cri-docker
dnf install libcgroup-0.41-19.el8.x86_64.rpm cri-dockerd-0.3.14-3.el8.x86_64.rpm -y
指定网络插件名称以及基础容器镜像
[root@k8s-master ~]# cat /lib/systemd/system/cri-docker.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=www.yjun.com/k8s/pause:3.9
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity
Delegate=yes
KillMode=process[Install]
WantedBy=multi-user.target[root@k8s-master ~]# systemctl daemon-reload
[root@k8s-master ~]# systemctl start cri-docker
在master节点拉取k8s所需镜像并上传镜像到harbor仓库
#拉取所需镜像
[root@k8s-master ~]# kubeadm config images pull --image-repository registry.aliyuncs.com/google_contaniers --kubernetes-version v1.30.0 --cri-socket=unix:///var/run/cri-dockerd.sock#镜像重命名
[root@k8s-master ~]# docker images | awk '/google/{ print $1":"$2}' | awk -F "/" '{system("docker tag "$0" www.yjun.com/k8s/"$3)}'#上传至harbor之间需要在harbor中建立对应的项目k8s#上传镜像至harbor
[root@k8s-master ~]# docker images | awk '/k8s/{system("docker push "$1":"$2)}'
3.4、集群初始化
启动kubelet服务
[root@k8s-master ~]# systemctl enable --now kubelet[root@k8s-master ~]# systemctl status kubelet.service
● kubelet.service - kubelet: The Kubernetes Node AgentLoaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)Drop-In: /usr/lib/systemd/system/kubelet.service.d└─10-kubeadm.confActive: active (running) since Wed 2024-10-09 20:25:22 CST; 1h 28min agoDocs: https://kubernetes.io/docs/Main PID: 939 (kubelet)Tasks: 12 (limit: 22946)Memory: 111.5MCPU: 1min 1.293sCGroup: /system.slice/kubelet.service
执行初始化命令
[root@k8s-master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 --image-repository www.yjun.com/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
安装flannel网络插件
# 下载flannel的yaml部署文件
wget https://github.com/flanne7.io/flannel/releases/latest/download/kube-flannel.yml#拉取镜像
docker pull docker.io/flannel/flannel:v0.25.5
docekr docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1#上传镜像
docker tag flannel/flannel:v0.25.5 www.yjun.com/flannel/flannel:v0.25.5
docker tag flannel/flannel-cni-plugin:v1.5.1-flannel1 www.yjun.com/flannel/flannel-cni-plugin:v1.5.1-flanneldocker push www.yjun.com/flannel/flannel:v0.25.5
docker push www.yjun.com/flannel/flannel-cni-plugin:v1.5.1-flannel#修改flannel的yml文件,更改镜像下载位置
vim kube-flannel.yml
...
image: flannel/flannel:v0.25.5
image: flannel/flannel-cni-plugin:v1.5.1-flannel1
image: flannel/flannel:v0.25.5
...#安装flannel网络插件
kubectl apply -f kube-flannel.yml
增加工作节点
#生成加入集群指令
[root@k8s-master ~]# kubeadm token create --print-join-command
kubeadm join 192.168.220.10:6443 --token 0kyf9x.5x69jlkby5eaq0s2 --discovery-token-ca-cert-hash sha256:8bd45b603a176204de3bfeeabbd1433b783f61848985a83289bcd76e7b40aa3f[root@k8s-node1 ~]# kubeadm join 192.168.220.10:6443 --token 0kyf9x.5x69jlkby5eaq0s2 --discovery-token-ca-cert-hash sha256:8bd45b603a176204de3bfeeabbd1433b783f61848985a83289bcd76e7b40aa3f --cri-socket=unix:///var/run/cri-dockerd.sock#在master上验证,ready则说明配置完成
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 13d v1.30.5
k8s-node1 Ready <none> 13d v1.30.5
k8s-node2 Ready <none> 13d v1.30.5
二、kubernetes中pod的管理及优化
1、kubernetes中的资源
1.1、资源介绍管理
在kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理kubernetes。
kubernetes的本质上就是一个集群系统,用户可以在集群中部署各种服务
所谓的部署服务,其实就是在kubernetes集群中运行一个个的容器,并将指定的程序跑在容器中。
kubernetes的最小管理单元是pod而不是容器,只能将容器放在
Pod
中kubernetes一般也不会直接管理Pod,而是通过
Pod控制器
来管理Pod的。Pod中服务服务的访问是由kubernetes提供的
Service
资源来实现。Pod中程序的数据需要持久化是由kubernetes提供的各种
存储
系统来实现
1.2、资源管理方式
- 命令式对象管理:直接使用命令去操作kubernetes资源
kubectl run nginx-pod --image=nginx:latest --port=80
- 命令式对象配置:通过命令配置和配置文件去操作kubernetes资源
kubectl create/patch -f nginx-pod.yaml
- 声明式对象配置:通过apply命令和配置文件去操作kubernetes资源
kubectl apply -f nginx-pod.yaml
类型 | 适用环境 | 优点 | 缺点 |
命令式对象管理 | 测试 | 简单 | 只能操作活动对象,无法审计、跟踪 |
命令式对象配置 | 开发 | 可以审计、跟踪 | 项目大时,配置文件多,操作麻烦 |
声明式对象配置 | 开发 | 支持目录操作 | 意外情况下难以调试 |
1.2.1、命令式对象管理
语法:kubectl [command] [type] [name] [flags]
command:指定要对资源执行的操作,例如create、get、delete
type:指定资源类型,比如deployment、pod、service
name:指定资源的名字,名称大小写敏感
flags:指定额外的可选参数
例:
kubectl get all #查看默认命名空间内所有内容
kubectl get pod pod_name #查看某个pod
kubectl get pod pod_name -o yaml #查看某个pod,以yaml格式展示结果
1.2.2、基本命令
#显示所有的资源
kubectl api-resources#显示集群版本
kubectl version#显示集群信息
kubectl cluster-info#创建控制器
kubectl create deployment webcluster --image nginx --replicas 2#查看控制器
kubectl get deployment.app#查看资源帮助
kubectl explain resources_name#编辑控制器配置(相当于修改yaml文件)
kubectl edit deployment.app webcluster#利用补丁更改控制器配置
kubectl patch deployment.app webcluster -p '{"spec":{"replicas":4}}'#删除资源
kubectl delete deployment.app webcluster#运行pod
kubectl run nginx --image nginx#查看pod详细信息
kubectl get pods -o wide#端口暴露
kubectl expose pod nginx --port 80 --target-port 80 #查看端口暴露
kubectl get services -o wide #查看资源详细信息
kubectl describe pods nginx#查看资源日志
kubectl logs pods/nginx#运行交互pod
kubectl run test -it --image busybox#退出不停止交互pod
ctil + p + q#进入到已经运行的容器,且容器由交互环境
kubectl attach pods/nginx -it#在已经运行的pod中运行指定命令
kubectl exec -it pods/nginx /bin/bash#把宿主机文件传送到pod中
kubectl cp test nginx:/#复制pod中的文件到宿主机
kubectl cp nginx:/test test#利用命令生成yaml模板文件
kubectl create deployment webcluster --image nginx --dry-run=client -o yaml > webcluster.yaml#利用yaml文件生成资源
kubectl apply -f webcluster.yaml#删除yaml文件生成的资源
kubectl delete -f webcluster.yaml#查看资源标签
kubectl get pods --show-labels#更改资源标签
kubectl label pods nginx app=webcluster --overwrite#删除标签
kubectl label pods nginx app-