使用kubeadm搭建多节点k8s集群(chrono《kubernetes入门实战课》笔记整理)
已经重装2次,确定可用,都是泪。。。。。。。。过程中请注意我的“一定一定”,不然会坑你好久好久,5555
【集群架构】
通过使用minikube,做完了k8s的基础学习和练习,今天开始,使用kubeadm,来搭建更复杂更贴合实际工作的k8s集群。
多节点集群,应该有大于等于2台node,实验中,先如上图,只有master和worker两个,先进行学习,后期也可以扩充。Master 节点需要运行 apiserver、etcd、scheduler、controller-manager 等组件,管理整个集群,所以对配置要求比较高,至少是 2 核 CPU、4GB 的内存。而 Worker 节点没有管理工作,只运行业务应用,所以配置可以低一些,为了节省资源我给它分配了 1 核 CPU 和 1GB 的内存。我的实验室环境是:
1、master:32vcpu,64g,500g硬盘
2、worker1:16vcpu、64g,200g硬盘
3、worker2:16vcpu、64g、100g硬盘
【准备工作】--均在worker,master上都要做
1、修改worker,master节点的hostname。我这里就直接命名为master,worker了;
2、woker,master安装docker做为容器运行时(可参考之前docker安装的笔记);
3、在“/etc/docker/daemon.json”里把 cgroup 的驱动程序改成 systemd ,然后重启 Docker,具体命令如下:
cat <<EOF | sudo tee /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2" } EOF sudo systemctl enable docker sudo systemctl daemon-reload sudo systemctl restart docker
4、为了让 Kubernetes 能够检查、转发网络流量,需要修改 iptables 的配置,启用“br_netfilter”模块:
1)vi /etc/modules-load.d/k8s.conf,添加br_netfilter;
2)vi /etc/sysctl.d/k8s.conf,输入:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward=1 # better than modify /etc/sysctl.conf
3)sysctl --system
5、修改“/etc/fstab”,关闭 Linux 的 swap 分区,提升 Kubernetes 的性能:
1)swapoff -a
2)sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab
6、确认一下时间,一定一定一定一定要,确认一下时间,输入date看看对不对,不对就ntpdate cn.pool.ntp.org一下。否则后面worker加入k8s集群会有报错x509: certificate has expired or is not yet valid;
7、重启,做一下快照
【安装kubeadm等组件】--worker,master都要做
1、修改软件源:vi /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.cloud.tencent.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
2、安装:yum install -y kubeadm-1.23.6 kubelet-1.23.6 kubectl-1.23.6,安装好后执行一下开机启动kubelet的命令:systemctl enable kubelet,否则关机重启后,kubelet没起来,使用kubectl会报错The connection to the server 10.66.213.101:6443 was refused。
3、检查版本:
4、锁定版本,避免更新:
1)yum install -y yum-plugin-versionlock
2)yum versionlock add docker-ce docker-ce-cli kubeadm kubelet kubectl
3)yum versionlock list 查看锁定列表
4)yum versionlock clear 清除锁定
5、下载组件的镜像。kubeadm 把 apiserver、etcd、scheduler 等组件都打包成了镜像,以容器的方式启动 Kubernetes,但这些镜像不是放在 Docker Hub 上,而是放在 Google 自己的镜像仓库网站 gcr.io,而它在国内的访问很困难,直接拉取镜像几乎是不可能的。写一个sh脚本,添加如下内容,就可以快速拉齐了:
repo=registry.aliyuncs.com/google_containers
for name in `kubeadm config images list --kubernetes-version v1.23.6`; do
src_name=${name#k8s.gcr.io/}
src_name=${src_name#coredns/}
docker pull $repo/$src_name
docker tag $repo/$src_name $name
docker rmi $repo/$src_name
done
【安装master】
1、输入如下命令进行安装。kubeadm 的用法非常简单,只需要一个命令 kubeadm init 就可以把组件在 Master 节点上运行起来,不过它还有很多参数用来调整集群的配置,你可以用 -h 查看。这里说明一下几个重要参数:
- --pod-network-cidr,设置集群里 Pod 的 IP 地址段;
- --apiserver-advertise-address,设置 apiserver 的 IP 地址,这里一定一定要注意,需要为ifconfig下的一个真实ip,这里建议直接使用本机的ip,否则会卡在[kubelet-check] Initial timeout of 40s passed.失败;
- --kubernetes-version,指定 Kubernetes 的版本号。一定要用1.24以下的,因为1.24之后,k8s弃用了docker。
具体输入命令为: kubeadm init --apiserver-advertise-address=10.66.213.105 --kubernetes-version=v1.23.6 --image-repository registry.aliyuncs.com/google_containers --pod-network-cidr=10.244.0.0/16
2、在提示成功后,还有一段信息,提示我们要继续操作:
所以我们继续操作这三条命令:
1)mkdir -p $HOME/.kube
2)sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
3)sudo chown $(id -u):$(id -g) $HOME/.kube/config
如果是临时方式,可以输入export KUBECONFIG=/etc/kubernetes/admin.conf。
3、之后注意,最下面还有kubeadm join的提示。其他节点如果想加入集群,需要使用截图中的token和ca证书,所以一定要保存好。真的忘了,就用kubeadm token create --print-join-command生成一条新的即可。
4、现在可以使用kubectl get node命令,检查一下node的添加情况了。这里注意,状态是notready,这是由于还缺少网络插件,集群的内部网络还没有正常运作。
【安装Flannel 网络插件】
1、vi kube-flannel.yml,注意修改net-conf.json中的network为pod-network-cidr的网段;
--- apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: psp.flannel.unprivileged annotations: seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default spec: privileged: false volumes: - configMap - secret - emptyDir - hostPath allowedHostPaths: - pathPrefix: "/etc/cni/net.d" - pathPrefix: "/etc/kube-flannel" - pathPrefix: "/run/flannel" readOnlyRootFilesystem: false runAsUser: rule: RunAsAny supplementalGroups: rule: RunAsAny fsGroup: rule: RunAsAny allowPrivilegeEscalation: false defaultAllowPrivilegeEscalation: false allowedCapabilities: ['NET_ADMIN', 'NET_RAW'] defaultAddCapabilities: [] requiredDropCapabilities: [] hostPID: false hostIPC: false hostNetwork: true hostPorts: - min: 0 max: 65535 seLinux: rule: 'RunAsAny' --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: flannel rules: - apiGroups: ['extensions'] resources: ['podsecuritypolicies'] verbs: ['use'] resourceNames: ['psp.flannel.unprivileged'] - apiGroups: - "" resources: - pods verbs: - get - apiGroups: - "" resources: - nodes verbs: - list - watch - apiGroups: - "" resources: - nodes/status verbs: - patch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: flannel roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: flannel subjects: - kind: ServiceAccount name: flannel namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: flannel namespace: kube-system --- kind: ConfigMap apiVersion: v1 metadata: name: kube-flannel-cfg namespace: kube-system labels: tier: node app: flannel data: cni-conf.json: | { "name": "cbr0", "cniVersion": "0.3.1", "plugins": [ { "type": "flannel", "delegate": { "hairpinMode": true, "isDefaultGateway": true } }, { "type": "portmap", "capabilities": { "portMappings": true } } ] } net-conf.json: | { "Network": "10.244.0.0/16", "Backend": { "Type": "vxlan" } } --- apiVersion: apps/v1 kind: DaemonSet metadata: name: kube-flannel-ds namespace: kube-system labels: tier: node app: flannel spec: selector: matchLabels: app: flannel template: metadata: labels: tier: node app: flannel spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/os operator: In values: - linux hostNetwork: true priorityClassName: system-node-critical tolerations: - operator: Exists effect: NoSchedule serviceAccountName: flannel initContainers: - name: install-cni-plugin image: rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0 command: - cp args: - -f - /flannel - /opt/cni/bin/flannel volumeMounts: - name: cni-plugin mountPath: /opt/cni/bin - name: install-cni image: rancher/mirrored-flannelcni-flannel:v0.18.1 command: - cp args: - -f - /etc/kube-flannel/cni-conf.json - /etc/cni/net.d/10-flannel.conflist volumeMounts: - name: cni mountPath: /etc/cni/net.d - name: flannel-cfg mountPath: /etc/kube-flannel/ containers: - name: kube-flannel image: rancher/mirrored-flannelcni-flannel:v0.18.1 command: - /opt/bin/flanneld args: - --ip-masq - --kube-subnet-mgr resources: requests: cpu: "100m" memory: "50Mi" limits: cpu: "100m" memory: "50Mi" securityContext: privileged: false capabilities: add: ["NET_ADMIN", "NET_RAW"] env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: EVENT_QUEUE_DEPTH value: "5000" volumeMounts: - name: run mountPath: /run/flannel - name: flannel-cfg mountPath: /etc/kube-flannel/ - name: xtables-lock mountPath: /run/xtables.lock volumes: - name: run hostPath: path: /run/flannel - name: cni-plugin hostPath: path: /opt/cni/bin - name: cni hostPath: path: /etc/cni/net.d - name: flannel-cfg configMap: name: kube-flannel-cfg - name: xtables-lock hostPath: path: /run/xtables.lock type: FileOrCreate
2、kubectl apply -f kube-flannel.yml,安装 Flannel 网络;
3、查看pod和node,都正常了。
4、关一下selinux和防火墙,否则worker加入的时候可能会报错dial tcp 10.66.213.105:6443: connect: no route to host
1)setenforce 0
2) sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
3) systemctl disable firewalld --now
【安装worker节点】
1、关一下selinux和防火墙,否则worker加入的时候可能会报错dial tcp 10.66.213.105:6443: connect: no route to host
1)setenforce 0
2) sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
3) systemctl disable firewalld --now
2、master节点再次生成一下加入命令:kubeadm token create --print-join-command
3、在worker节点运行上面生成的命令: kubeadm join 10.66.213.105:6443 --token 1oyr2c.zlg8srcmocnj7eej --discovery-token-ca-cert-hash sha256:dde7f87338550c3fe667470319b9efa569e1e65501903a24616eedb27e385f8f
4、等待自动拉取镜像,安装flannel插件等;
5、在master上查看,已经加入:
6、在worker节点上也输入如下三步,才可以查看pod,node等状态,否则会报错The connection to the server localhost:8080 was refused - did you specify the right host or port。从master上scp /etc/kubernetes/admin.conf到worker上,worker上继续执行:
1) mkdir -p $HOME/.kube;
2)cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
3)chown $(id -u):$(id -g) $HOME/.kube/config
终于装完了。。。
【FAQ】
1、如果这里加入集群的时候报错:error execution phase preflight: couldn't validate the identity of the API Server: Get "https://10.66.213.105:6443/api/v1/namespaces/kube-public/configmaps/cluster-info?timeout=10s": dial tcp 10.66.213.105:6443: connect: no route to host,可以在master和worker上都执行:
1)setenforce 0
2) sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
3) systemctl disable firewalld --now
2、如果修改后,变成x509错误,是时间问题,如果按照上面步骤操作,就不会有这问题了,出现后我的解决方法就是重新来,所以建议根据上面步骤做,可以避免。这里也看到一个应该可以解决问题的方式,但我没试过,不想重装可以试试:https://blog.51cto.com/mshxuyi/5858689;
3、worker上一开始无法查看pod等信息,报错如下:
解决方式:从master上scp /etc/kubernetes/admin.conf到worker上,worker上继续执行如下命令,就可以看到了:
1) mkdir -p $HOME/.kube;
2)cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
3)chown $(id -u):$(id -g) $HOME/.kube/config
4、关机重启后,kubectl get报错The connection to the server localhost:8080 was refused
原因是kubelet没有启动,通过systemctl status kubelet可以看到是inactive的,临时解决办法是systemctl start kubelet就可以了。永久解决办法是配置一下开机启动systemctl enable kubelet
5、安装节点的时候,出现任何头疼的问题,都可以通过kubeadm reset后,重新init来再操作,重启是万能的,重装也是万能的。
本文来自博客园,作者:1234roro 当你迷惘的时候,开始学习吧!当你目标清晰的时候,开始学习吧!转载请注明原文链接:https://www.cnblogs.com/1234roro/p/16998127.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了