背景
三台opencloudos 8,内网互通,分别如下:
10.0.20.14-master
10.0.8.2-node1
10.0.24.6-node2
一、配置系统参数
1.配置主机名
hostnamectl set-hostname master # 在master机
hostnamectl set-hostname node1 # 在node1机
hostnamectl set-hostname node2 # 在node2机
hostnamectl # 查看主机名配置情况
2.配置hosts
vim /etc/hosts
10.0.20.14 master
10.0.8.2 node1
10.0.24.6 node2
3.配置时间对齐并安装工具包
timedatectl set-timezone Asia/Shanghai
yum install -y yum-utils device-mapper-persistent-data lvm2
date # 三台机一起执行查看时间是否一致
注:
- yum-utils是yum工具
- device-mapper-persistent-data和lvm2是逻辑卷工具
4.关闭一系列配置
# 关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
systemctl stop iptables.service && systemctl disable iptables.service
# 关闭SELinux
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# 关闭swap
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
注:
- 要开firewalld的话要注意放通k8s的流量
- 关闭iptable是因为k8s会使用到iptable规则分发流量,若开启系统的iptable可能会冲突
- 要开启SELinux会加大k8s运维压力,不关闭要注意是否拦截了k8s流量
- 关闭swap是为了减小k8s资源计算压力
5.转发 IPv4 并让 iptables 看到桥接流量
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
6.设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# 应用sysctl参数
sudo sysctl --system
二、安装一系列组件并配置
1.配置docker
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install -y docker-ce
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"registry-mirrors": ["https://wkxfupsi.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
注:
- 加速镜像可以自己登录阿里云,找到容器镜像服务页,使用自己的加速镜像链接。
- k8s 在1.2.x版本后就逐渐不再使用docker,但已经可以使用docker来构建容器、管理容器上传、拉取
2.安装ipset和ipvsadm
yum install ipset ipvsadm -y
cat <<EOF> /etc/sysconfig/modules/ipvs.modules
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
EOF
chmod +x /etc/sysconfig/modules/ipvs.modules && /bin/bash /etc/sysconfig/modules/ipvs.modules
# 查看对应的模块是否加载成功
lsmod | grep -e ip_vs -e nf_conntrack
注:
- 这里是配置安装k8s使用的代理服务模块
3.配置k8s部分组件
3.1 配置k8s的yum源地址并安装
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum install -y kubeadm-1.24.6 kubectl-1.24.6 kubelet-1.24.6
systemctl enable --now kubelet
3.2 配置kubelet 使用与 Docker 守护进程相同的 cgroup 驱动程序,并配置使用ipvs作为k8s的服务代理
vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
3.3 开机自启
systemctl enable kubelet
4.配置容器containerd
4.1 重置config.toml文件
containerd config default > /etc/containerd/config.toml
4.2 确认k8s集群版本
kubeadm config images list
注:
1.留意里面的pause版本
4.3 编辑配置文件,修改SystemdCgroup 和sandbox_image
vim /etc/containerd/config.toml
SystemdCgroup = true
sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.7"
注:
- 这里的版本3.7要和上一步查出来的pause版本一致
4.4 重启并配置开启自启
systemctl restart containerd
systemctl enable containerd
ctr images ls # 查看容器镜像测试配置,没报错则成功
5 预安装k8s集群
5.1 查看k8s集群版本
kubeadm config images list
5.2 安装
images=(
kube-apiserver:v1.24.17
kube-controller-manager:v1.24.17
kube-scheduler:v1.24.17
kube-proxy:v1.24.17
pause:3.7
etcd:3.5.3-0
coredns:v1.8.6
)
for imageName in ${images[@]};do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
done
注:
- 这里的版本要和上一步查出来的版本完全一致
三、初始化k8s集群并配置(这一步只需在master节点执行)
1.初始化
kubeadm init \
--apiserver-advertise-address=10.0.20.14 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version=v1.24.17 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
注:
- apiserver-advertise-address 是master ip
- image-repository 指定k8s仓库地址
- kubernetes-version 是k8s版本,要与二的5.1里查到的版本一致
- service-cidr 集群内部虚拟网络,Pod统一访问入口
- pod-network-cidr Pod网络,与下面部署的CNI网络组件yaml中保持一致
2.创建k8s配置文件/目录及环境变量
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
注:
- 执行你自己上一步得到的反馈信息,不要执行我的
- 只在master节点执行
3.安装配置集群网络组件
wget https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
vim kube-flannel.yml
"Network": "10.244.0.0/16"
注:
- “Network”: “10.244.0.0/16” 要与初始化时pod-network-cidr的值一致
4.安装
kubectl create -f kube-flannel.yml
5.检查
kubectl get nodes
注:
- 需等待一段时间,约1到2分钟才会加载完成
- status是ready时表示成功
四、往集群加入node节点(node节点执行)
1.执行连接master节点命令
kubeadm join 10.0.20.14:6443 --token b73swc.ylv4veq40jobgd34 \
--discovery-token-ca-cert-hash sha256:e0eb386eba286752f7068690ee0e3bf1276c5768f0c6161482044989cf58818c
注:
- 忘记连接主节点的token时,可重新生成一个,master执行命令:
kubeadm token create --print-join-command
2.如果想加入一个master节点
kubeadm join 10.0.20.14:6443 --token b73swc.ylv4veq40jobgd34 \
--discovery-token-ca-cert-hash sha256:e0eb386eba286752f7068690ee0e3bf1276c5768f0c6161482044989cf58818c
--control-plane
3.检查-等待1到2分钟加载(master节点执行)
kubectl get nodes
kubectl get pod --all-namespaces
注:
- 当所有的节点都是Ready,所有的pod都是running则k8s成功完成部署
五、namespace命令
1.查看
1.1 查看所有命名空间
kubectl get namespace
kubectl get ns
1.2 查看名叫kube-system的命名空间
kubectl get ns kube-system
1.3 查看kube-system并指定输出格式
kubectl get ns kube-system -o yaml
kubectl get ns kube-system -o wide
kubectl get ns kube-system -o json
1.4 查看kube-system的详细信息
kubectl describe ns kube-system
2.创建命名空间:dev
kubectl create ns dev
3.删除命名空间:dev
kubectl delete ns dev
4.配置文件的方式创建
vim ns-dev.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
# 创建
kubectl apply -f ns-dev.yaml
# 查看
kubectl get ns dev
注:
- apiVersion: v1和kind: Namespace 是固定格式,可以通过kubectl explain ns查看
- apply:不存在时创建,存在时更新,有时候可能会存在部分参数不会更新
- create: 创建
5.配置文件的方式删除
kubectl delete -f ns-dev.yaml
六、pod命令
1.在dev区创建pod
# 方式一:创建pod控制器,让控制器创建nginx
kubectl create deploy nginx-deploy --image=nginx:latest --port=80 -n dev
# 方式二:直接创建pod,不会有pod控制器运维
kubectl run nginx --image=nginx:latest --port=80 -n dev
注:
- -n 指定命名空间
2.查看
2.1 查看default区的pod基本信息
kubectl get pod
2.2 查看dev区的pod基本信息
kubectl get pod -n dev
2.3 查看dev区的pod的详细信息
kubectl describe pod -n dev
# 查看该区内指定名字为nginx1的pod
kubectl describe pod -name=nginx1 -n dev
2.4 以不同输出方式查看dev区的pod信息
kubectl get pod -n dev -o wide
kubectl get pod -n dev -o yaml
kubectl get pod -n dev -o json
3.访问
curl http://ip:80
注:
- 此处访问是集群内部访问
- ip可以通过 -o wide的方式查看确认
4.删除
4.1 删除指定pod
kubectl delete pod <pod name> -n dev
kubectl delete pod nginx-deploy-665779d9f4-fxff6 -n dev
注:
- 如果是pod控制器创建的pod,因pod控制器在维护pod,此处删除后,控制器会马上启动一个相同镜像的pod,想要完全删除需要删除pod控制器
4.2 查看dev区的pod控制器
kubectl get deploy -n dev
4.3 删除pod控制器
kubectl delete deploy nginx-deploy -n dev
5.配置文件的方式创建
vim pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
kubectl apply -f pod-nginx.yaml
kubectl get pod -n dev -o wide
注:
- apiVersion: v1和kind: Pod 是固定格式,可以通过kubectl explain pod查看
6.配置文件的方式删除
kubectl delete -f pod-nginx.yaml
七、label命令
1.打标签
kubectl label pod nginx-6664759f4f-mgzvd version=1.25.5 -n dev
注:
- 这是往dev区的pod nginx-6664759f4f-mgzvd 添加标签version=1.25.5
- 这里要注意nginx-6664759f4f-mgzvd换成你自己的pod name
2.更新标签
kubectl label pod nginx-6664759f4f-mgzvd version=1.25 -n dev --overwrite
3.查看所有标签
kubectl get pod nginx-6664759f4f-mgzvd -n dev --show-labels
4.以标签为条件筛选pod
kubectl get pod -n dev -l version=1.25 --show-labels
# 不包括标签version=1.25
kubectl get pod -n dev -l version!=1.25 --show-labels
5.删除标签
kubectl label pod nginx-6664759f4f-mgzvd -n dev version-
6.配置方式
vim label-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
labels:
version: "3.0"
env: "test"
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
# 创建
kubectl apply -f label-pod.yaml
# 删除
kubectl delete -f label-pod.yaml
八、deploy命令
1.创建
kubectl create deploy nginx-deploy --port=80 --image=nginx:1.25.5 -n dev --replicas=3
注:
- –replicas=3 :创建3个pod副本
- 在较新版本的 Kubernetes 中,kubectl run 命令已不再支持直接设置 replicas(副本数量),应该使用 kubectl create deploy 命令
2.查看控制器及其运维的pod
kubectl get deploy nginx-deploy -n dev
kubectl get pod -n dev -l app=nginx-deploy
3.查看控制器详细信息
kubectl describe deploy nginx-deploy -n dev
4.删除
kubectl delete deploy nginx-deploy -n dev
5.配置文件
vim deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- image: nginx:1.25.5
name: nginx
ports:
- containerPort: 80
protocol: TCP
# 创建
kubectl apply -f deploy-nginx.yaml
# 删除
kubectl delete -f deploy-nginx.yaml
九、server命令
1.创建
kubectl expose deploy nginx-deploy --name=svc-nginx --type=ClusterIP --port=80 --target-port=80 -n dev
注:
- expose deploy nginx-deploy: 暴露控制器nginx-deploy的端口
- –port=80:暴露端口80-集群内部可访问的端口,映射至容器端口
- –target-port=80:容器的端口
- –type=NodePort:让外部可以访问
- –type=ClusterIP:只能集群内部访问
2.查看
kubectl get svc svc-nginx -n dev -o wide
kubectl describe svc svc-nginx -n dev
3.访问
curl -vv http://ip:80
注:
- ip由上一步查看所得
4.删除
kubectl delete svc svc-nginx -n dev
5.配置文件
vim svc-nginx.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: dev
spec:
selector:
app: nginx-pod
type: NodePort # service类型
ports:
- port: 80
nodePort: 30002 # 指定绑定的node的端口(默认的取值范围是:30000-32767), 如果不指定,会默认分配
targetPort: 80
# 创建
kubectl apply -f svc-nginx.yaml
# 删除
kubectl delete -f svc-nginx.yaml
注:
- selector 是筛选具备该标签的pod归此server代理,可以通过describe命令查看它代理了哪些pod
- 这个配置是另外部可访问的,外部主机访问:http://公网ip:30002
十、部署可视化界面-dashboard
背景:k8s集群是v1.24版本,集群服务器是云服务器
1.下载pod配置文件并修改
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/recommended.yaml
vim recommended.yaml
# 找到service的配置,注意有两个service,要找到name: kubernetes-dashboard的
# 新增
type: NodePort
# 保存
:wq
# 安装
kubectl apply -f recommended.yaml
注:
- 注意这里wget链接的v2.4.0,要是太低了会出告警
2.配置用户
vim dash-user.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
# 保存
:wq
kubectl apply -f dash-user.yaml
3.获取授权token
kubectl create token admin-user -n kubernetes-dashboard
4.获取ui界面端口
kubectl get pod,svc -n kubernetes-dashboard -o wide
5.访问并登录
https://master节点公网ip:30009
注:
- 选择Token,并输入之前得到的token
正常界面
十一、k8s组件介绍
1.各组件介绍
- master:集群的控制平面,负责集群的决策 ( 管理 )-主节点
- ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制
- Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上
- ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等
- Etcd :负责存储集群中各种资源对象的信息
- node:集群的数据平面,负责为容器提供运行环境 ( 干活 )-工作节点
- Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器
- KubeProxy : 负责提供集群内部的服务发现和负载均衡
- Docker : 负责节点上容器的各种操作
2.调用案例:部署nginx服务:
- kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中
- 一个nginx服务的安装请求会首先被发送到master节点的apiServer组件
- apiServer组件会调用scheduler组件来决定到底应该把这个服务安装到哪个node节点上,在此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知apiServer
- apiServer调用controller-manager去调度Node节点安装nginx服务
- kubelet接收到指令后,会通知docker,然后由docker来启动一个nginx的pod。pod是kubernetes的最小操作单元,容器必须跑在pod中至此,
- 一个nginx服务就运行了,如果需要访问nginx,就需要通过kube-proxy来对pod产生访问的代理
3.k8s概念资源组件介绍
- NameSpace:命名空间,用来隔离pod的运行环境,不同区的pod相互隔离
- Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器
- Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签,比如控制器nginx-deploy创建的pod,会加一个标签:app=nginx-deploy
- Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等
- Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod,Service可以看作是一组同类Pod对外的访问接口,会创建一个代理内网ip,访问pod容器,借助Service,应用可以方便地实现服务发现和负载均衡
十二、问题整理
1.节点重启:
systemctl daemon-reload
systemctl restart docker
systemctl restart kubelet
systemctl restart kube-proxy
2.watch kubectl get pods --all-namespaces,检测到flannel大部分时间都是error,restart次数很多,如下:
kube-flannel kube-flannel-ds-rz2wc 1/1 Running 0 25s
kube-flannel kube-flannel-ds-wb9x6 0/1 Error 2 (20s ago) 25s
kube-flannel kube-flannel-ds-wqksb 0/1 Error 2 (19s ago) 25s
2.1 检测日志:
kubectl logs kube-flannel-ds-wb9x6 -n kube-flannel
发现:
- E0417 11:18:03.273562 1 main.go:333] Error registering network: failed to acquire lease: subnet “10.244.0.0/16” specified in the flannel net config does not contain “192.168.0.0/24” PodCIDR of the “master” node
- 问题解析:
Flannel 配置中指定的网络 10.244.0.0/16 并不包含节点分配的 192.168.0.0/24 PodCIDR。这是一个配置冲突问题
2.2解决方案
# 卸载:
kubectl delete -f kube-flannel.yml
# 修改kube-flannel.yml的network里的网段为kubeadm init时配置的pod-network-cidr指定的ip
# 重装
kubectl apply -f kube-flannel.yml
#再检测flannel是否有问题
watch kubectl get pods --all-namespaces
3.Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of “crypto/rsa: verification error” while trying to verify candidate authority certificate “kubernetes”)
- 问题分析:执行了集群重建kubeadm reset
- 处理:删除集群,重建
4.检查pod时发现coredns点异常
kube-system coredns-7f74c56694-6bdrc 0/1 Pending 0 6m14s
kube-system coredns-7f74c56694-6dtbf 0/1 Pending 0 6m14s
- 分析:应该是所有节点都是notready状态导致的
- 解决:先检查/按照网络插件,将节点变成ready再检查
5.忘记连接主节点的token时,可重新生成一个
kubeadm token create --print-join-command