使用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来再操作,重启是万能的,重装也是万能的。

 

posted @   1234roro  阅读(284)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示