01. kubeadm部署kubernetes(v1.26.1)集群

集群规划

系统环境为 CentOS-7.9.2009

主机名 IP地址 组件
k8s-master 192.168.70.100 etcd、apiserver、scheduler、controller-manager、kubeadm、kubeclt、kubelet、kube-proxy
k8s-node1 192.168.70.101 kubeadm、kubelet、kube-proxy
k8s-node2 192.168.70.101 kubeadm、kubelet、kube-proxy

一、系统优化

  • 关闭防火墙---所有节点
systemctl stop firewalld && systemctl disable firewalld
  • 关闭selinux---所有节点
# 临时关闭selinux  
setenforce 0
# 永久关闭selinux
#selinux由enforcing改成disabled

sed -r -i "s/^SELINUX=.*/SELINUX=disabled/"  /etc/sysconfig/selinux   &>/etc/null
sed -r -i "s/^SELINUX=.*/SELINUX=disabled/"  /etc/selinux/config      &>/etc/null

# 检查修改结果
cat /etc/sysconfig/selinux | grep SELINUX | grep -o disabled &&   cat  /etc/selinux/config | grep SELINUX | grep -o disabled 
#出现两个disabled说明修改成功
  • 修改主机名---所有节点
# 永久修改主机名
# 192.168.70.100
hostnamectl set-hostname k8s-master

# 192.168.70.101
hostnamectl set-hostname k8s-node1

# 192.168.70.102
hostnamectl set-hostname k8s-node2

  • 配置域名解析---所有节点
[root@k8s-master kubernetes]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.70.100 k8s-master
192.168.70.101 k8s-node1
192.168.70.102 k8s-node2

  • 配置时间同步---所有节点
yum install -y chrony

# vim /etc/chrony.conf
修改1   server ntp.aliyun.com iburst   时间同步服务器-外部
修改2   allow 10.0.0.0/8  允许访问的网段 从服务器的网段
修改3 打开  local stratum 10
启动  systemctl start chronyd
设置开机自启  systemctl enable chronyd
检查端口  ss -unl | grep 123
  • 关闭交换分区---所有节点
swapoff -a(临时关闭交换分区)

# 永久关闭交换分区  
# vim /etc/fstab  
# /dev/mapper/centos-swap swap  swap    defaults   0 0  # 把这行注释掉,如果没有交换分区,直接跳过
  • 启用br_netfilter内核模块---所有节点
modprobe br_netfilter
echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables

# 如果没有配置会报如下错误
# [ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1
  • 修改内核参数---所有节点
cat > /etc/sysctl.d/k8s.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
vm.swappiness=0
EOF

# 刷新一下
sysctl --system

参数解释

# 也可以使用下面的配置
cat << EOF | 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
net.ipv4.tcp_tw_recycle=0
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.ipv6.conf.all.disable_ipv6=1
net.netfilter.nf_conntrack_max=2310720
EOF


overcommit_memory    是一个内核对内存分配的一种策略,取值又三种分别为0, 1, 2
    overcommit_memory=0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
    overcommit_memory=1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
    overcommit_memory=2, 表示内核允许分配超过所有物理内存和交换空间总和的内存
net.bridge.bridge-nf-call-iptables   设置网桥iptables网络过滤通告
net.ipv4.tcp_tw_recycle    设置 IP_TW 回收
vm.swappiness     禁用swap
vm.panic_on_oom   设置系统oom(内存溢出)
fs.inotify.max_user_watches   允许用户最大监控目录数
fs.file-max    允许系统打开的最大文件数
fs.nr_open     允许单个进程打开的最大文件数
net.ipv6.conf.all.disable_ipv6   禁用ipv6
net.netfilter.nf_conntrack_max    系统的最大连接数
  • 加载ipvs模块
    建议:如果做高可用的话,要打开IP_VS模块 因为:pod的负载均衡是用kube-proxy来实现的,实现方式有两种,一种是默认的iptables,一种是ipvs,ipvs比iptable的性能更好而已。后面master的高可用和集群服务的负载均衡要用到ipvs,所以加载内核的以下模块
# 安装软件
yum -y install ipset ipvsadm

# 修改配置文件
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
modprobe -- br_netfilter
EOF

# 参数解释
# modprobe ip_vs lvs基于4层的负载均很
# modprobe ip_vs_rr 轮询
# modprobe ip_vs_wrr 加权轮询
# modprobe ip_vs_sh 源地址散列调度算法
# modprobe nf_conntrack_ipv4 连接跟踪模块
# modprobe br_netfilter 遍历桥的数据包由iptables进行处理以进行过滤和端口转发


# 授权
chmod +x /etc/sysconfig/modules/ipvs.modules

#  执行文件生效配置
sh  /etc/sysconfig/modules/ipvs.modules


# 检查配置
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
cut -f1 -d " "  /proc/modules | grep -e ip_vs -e nf_conntrack_ipv4
  • 配置阿里yum源
# 备份原始系统自带的文件
mkdir -p /etc/yum.repos.d/repo-backup
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/repo-backup

#centOS-7  yum源
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

#centOS-7  epel源
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

二、安装Kubernetes集群

  • 安装docker-ce---所有节点
# step 1: 安装必要的一些系统工具
yum install -y yum-utils device-mapper-persistent-data lvm2

# Step 2: 添加软件源信息
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum makecache fast
# yum list docker-ce --showduplicates |sort -r  # 列出所有docker-ce版本

# Step 3: 安装Docker-CE
yum  install  -y  docker-ce  # 默认安装最新版本 
# 安装指定版本docker
# yum -y install docker-ce-19.03.15-3.el7
# yum -y install docker-ce-20.10.10-3.el7
# yum install -y docker-ce-[versionNum]

systemctl start docker
systemctl enable docker

# Step 4:  配置docker镜像加速器
mkdir -p  /etc/docker

# 复制下面的内容记得把注释内容删除,否则容器无法启动
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "http://hub-mirror.c.163.com",
    "https://registry.docker-cn.com"
    ],
"exec-opts": ["native.cgroupdriver=systemd"],
"data-root": "/var/lib/docker",
"log-driver": "json-file",
"log-opts": {
    "max-size": "100m"
  },
"storage-driver": "overlay2",
"storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

# Step 5: 开启Docker服务
systemctl enable docker  &&  systemctl start docker && systemctl status docker 

# Step 6: 检查驱动类型
#  docker  info | grep -i cgroup 
Cgroup Driver: systemd

  • 安装k8s组件---所有节点

配置安装源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF


#重建yum缓存
yum clean all && yum -y makecache

安装kubelet组件,所有节点都要执行,安装kubelet kubectl kubeadm三个组件

# 默认安装最新版
yum install -y kubelet  kubeadm   kubectl

或者安装指定版本

yum install -y kubelet-1.20.0 kubeadm-1.20.0 kubectl-1.20.0

修改k8s配置文件

# vim /etc/sysconfig/kubelet
# 配置驱动类型
KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"
# 忽略交换分区错误---前面已经关闭了交换分区,这里可以忽略
KUBELET_EXTRA_ARGS="--fail-swap-on=false"

配置kubelet的cgroup drive

确保docker 的cgroup drive 和kubelet的cgroup drive一样:

[root@k8s-master ~]# docker info | grep -i cgroup
 Cgroup Driver: systemd
 Cgroup Version: 1

#  然后再查看我们的kubectl的Cgroup
[root@k8s-master ~]# cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
cat: /etc/systemd/system/kubelet.service.d/10-kubeadm.conf: 没有那个文件或目录
# 如果提示找不到该文件,就再去我们的:/usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf

[root@k8s-master opt]# cat /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf 
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/sysconfig/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=systemd"
Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true --fail-swap-on=false"

# 然后使用命令重新加载一下:
[root@k8s-master ~]# systemctl daemon-reload
  • 将 sandbox_image 镜像源设置为阿里云 google_containers 镜像源---所有节点
# 导出默认配置,config.toml这个文件默认是不存在的
containerd config default > /etc/containerd/config.toml
grep sandbox_image  /etc/containerd/config.toml
sed -i "s#k8s.gcr.io/pause#registry.aliyuncs.com/google_containers/pause#g"       /etc/containerd/config.toml
grep sandbox_image  /etc/containerd/config.toml
  • 配置 containerd cgroup 驱动程序 systemd---所有节点
sed -i 's#SystemdCgroup = false#SystemdCgroup = true#g' /etc/containerd/config.toml
# 应用所有更改后,重新启动containerd
systemctl restart containerd
  • 启动k8s---所有节点

安装kubelet、kubeadm、kubectl三者后,要求启动kubelet

systemctl enable kubelet && systemctl start kubelet    # 启动kubelet并设置开机自启,此时启动kubelet会失败,没有对应文件,集群初始化后,生成文件后再启动
systemctl status kubelet  # 检查kubelet状态

# 查看kubeadm版本
kubeadm version
  • 配置自动补全---master节点
#安装bash自动补全插件
yum install bash-completion -y
#设置kubectl与kubeadm命令补全,下次login生效
kubectl completion bash > /etc/bash_completion.d/kubectl
kubeadm completion bash > /etc/bash_completion.d/kubeadm
  • 初始化配置文件---master节点
# 导出所有默认的配置
kubeadm config print init-defaults > kubeadm.yaml

# 修改 kubeadm.yaml 文件
# vim kubeadm.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.70.100   # 修改为API Server的地址,master主机地址
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  name: k8s-master     # 给节点取个名字,根据自己的情况修改
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {} 
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers    # 修改为阿里云镜像仓库,有条件上外网的默认即可
kind: ClusterConfiguration
kubernetesVersion: 1.26.0          # 修改为具体的版本
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/16         #修改Service的网络
  podSubnet: 10.244.0.0/16     podSubnet网络设置,这里推荐改成10.244.0.0/16
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs

  • 拉取所需镜像---master节点
# 查看镜像列表
[root@k8s-master opt]# kubeadm config images list --config kubeadm.yaml
registry.aliyuncs.com/google_containers/kube-apiserver:v1.21.0
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.20.0
registry.aliyuncs.com/google_containers/kube-scheduler:v1.21.0
registry.aliyuncs.com/google_containers/kube-proxy:v1.21.0
registry.aliyuncs.com/google_containers/pause:3.4.1
registry.aliyuncs.com/google_containers/etcd:3.4.13-0
registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0

# 拉取镜像
#提前下载镜像到本地,可节约启动k8s集群时间,不然可能会等很久
kubeadm config images pull --config kubeadm.yaml
  • 初始化master节点
kubeadm init --config kubeadm.yaml
这里省略了所有输出,初始化操作主要经历了下面15个步骤,每个阶段均输出均使用[步骤名称]作为开头:

[init]:指定版本进行初始化操作
[preflight] :初始化前的检查和下载所需要的Docker镜像文件。
[kubelet-start]:生成kubelet的配置文件”/var/lib/kubelet/config.yaml”,没有这个文件kubelet无法启动,所以初始化之前的kubelet实际上启动失败。
[certificates]:生成Kubernetes使用的证书,存放在/etc/kubernetes/pki目录中。
[kubeconfig] :生成 KubeConfig文件,存放在/etc/kubernetes目录中,组件之间通信需要使用对应文件。
[control-plane]:使用/etc/kubernetes/manifest目录下的YAML文件,安装 Master组件。
[etcd]:使用/etc/kubernetes/manifest/etcd.yaml安装Etcd服务。
[wait-control-plane]:等待control-plan部署的Master组件启动。
[apiclient]:检查Master组件服务状态。
[uploadconfig]:更新配置
[kubelet]:使用configMap配置kubelet。
[patchnode]:更新CNI信息到Node上,通过注释的方式记录。
[mark-control-plane]:为当前节点打标签,打了角色Master,和不可调度标签,这样默认就不会使用Master节点来运行Pod。
[bootstrap-token]:生成token记录下来,后边使用kubeadm join往集群中添加节点时会用到
[addons]:安装附加组件CoreDNS和kube-proxy

成功执行之后,你会看到下面的输出:

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.70.100:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:a0b701d7172bd9c8a7d7b748776668fcd424625c1dd47e422ce0f41bc9eb8

如果执行失败,那意味着之前的操作存在问题,检查顺序如下:

**基础环境:**
主机名是否可以解析,SELinux,iptables是否关闭。
交换分区是否存在free -m查看
内核参数是否修改、IPVS是否修改(目前阶段不会造成失败)

**基础软件:**
Docker是否安装并启动
Kubelet是否安装并启动
执行kubeadm是否有别的报错是否忽略
systemctl status kubelet查看kubelet是否启动
如果kubelet无法启动,查看日志有什么报错,并解决报错。

**以上都解决完毕,需要重新初始化**

kubeadm reset 进行重置(**生产千万不要执行,会直接删除集群**)
根据kubeadm reset提示,清除iptables和LVS。

为kubectl准备Kubeconfig文件

kubectl默认会在执行的用户家目录下面的.kube目录下寻找config文件。

这里是将在初始化时[kubeconfig]步骤生成的admin.conf拷贝到.kube/config。

# 直接执行下面三行命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

在该配置文件中,记录了API Server的访问地址,所以后面直接执行kubectl命令就可以正常连接到API Server中

使用kubectl命令查看组件状态

[root@master ~]# kubectl get cs
NAME                 STATUS    MESSAGE             ERROR
controller-manager   Healthy   ok                  
scheduler            Healthy   ok                  
etcd-0               Healthy   {"health":"true"}

如果报如下错如:

[root@master ~]# kubectl get cs
Warning: v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS      MESSAGE                                                                                       ERROR
controller-manager   Unhealthy   Get "http://127.0.0.1:10252/healthz": dial tcp 127.0.0.1:10252: connect: connection refused   
scheduler            Unhealthy   Get "http://127.0.0.1:10251/healthz": dial tcp 127.0.0.1:10251: connect: connection refused   
etcd-0               Healthy     {"health":"true"}

解决方法: 修改/etc/kubernetes/manifests 目录下 kube-scheduler.yaml 和 kube-controller-manager.yaml 文件

# vim  /etc/kubernetes/manifests/kube-scheduler.yaml
# vim  /etc/kubernetes/manifests/kube-controller-manager.yaml
1、注释 #- --port=0  这行
#- --port=0  

2、重启kubelet服务
systemctl restart kubelet

为什么上面的输出没有显示API Server组件的状态?

因为API Server是Kubernetes集群的入口,所有和Kubernetes集群的交互都必须经过APIServer,kubectl命令也是连接到API Server上进行交互,所以如果能够正常使用kubectl执行命令,意味着API Server运行正常。

使用kubectl获取Node信息

目前只有一个节点,角色是Master,状态是NotReady。

[root@master ~]# kubectl get nodes
NAME         STATUS     ROLES                  AGE     VERSION
master       NotReady   control-plane,master   2m37s   v1.26.1
  • 根据提示命令将node节点加入到master中
kubeadm join 192.168.70.100:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:a0b701d7172bd9c8a7d7b748776668fcd424625c1dd47e422ce0f41bc9eb8
    
    # 如果不报错,执行下面的命令,结果如下
[root@k8s-master ~]# kubectl get nodes
NAME         STATUS      ROLES                  AGE     VERSION
k8s-master   NotReady    control-plane,master   3m40s   v1.26.1
k8s-node1    NotReady    <none>                 2m10s   v1.26.1
k8s-node2    NotReady    <none>                 2m20s   v1.26.1

# 因为还没有部署网络插件,所以都是NotRead,接下来部署网络插件
  • 部署flannel网络插件

vim kube-flannel.yml
---
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

kubectl apply -f kube-flannel.yml
# 注意:如果不想要这些东西了,可以将apply改成delete,重新执行,就可以删除刚才apply安装的内容
# kubectl delete -f kube-flannel.yml

[root@k8s-master opt]# kubectl apply -f kube-flannel.yml
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/psp.flannel.unprivileged created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created

操作完以后需要等待一段时间,拉取镜像需要时间,耐心等待即可,如果长时间等不到结果,检查网络,然后清除上述操作重新再执行

在主master节点上运行kubectl get nodes

# 正常情况下,结果如下
[root@k8s-master opt]# kubectl get nodes
NAME         STATUS   ROLES                  AGE   VERSION
k8s-master   Ready    control-plane,master   27h   v1.26.1
k8s-node1    Ready    <none>                 27h   v1.26.1
k8s-node2    Ready    <none>                 27h   v1.26.1

也可以使用如下命令,实时观察执行结果

watch -n 1 "kubectl get nodes" # 1秒钟查看一次执行情况

# 查看所有pod运行状态
# [root@k8s-master opt]# watch -n 1 "kubectl get pods --all-namespaces"
Every 1.0s: kubectl get pods --all-namespaces                                       Thu May 13 15:10:49 2022

NAMESPACE     NAME                                 READY   STATUS    RESTARTS   AGE
kube-system   coredns-558bd4d5db-c68k7             1/1     Running   1          5m23s
kube-system   coredns-558bd4d5db-w2s7j             1/1     Running   1          5m23s
kube-system   etcd-k8s-master                      1/1     Running   1          5m23s
kube-system   kube-apiserver-k8s-master            1/1     Running   2          5m23s
kube-system   kube-controller-manager-k8s-master   1/1     Running   1          5m23s
kube-system   kube-flannel-ds-5m8qn                1/1     Running   0          33s
kube-system   kube-flannel-ds-fxgnr                1/1     Running   0          33s
kube-system   kube-flannel-ds-plpfp                1/1     Running   0          33s
kube-system   kube-flannel-ds-whx4m                1/1     Running   0          33s
kube-system   kube-proxy-8jg7s                     1/1     Running   1          5m23s
kube-system   kube-proxy-9fxp9                     1/1     Running   1          5m23s
kube-system   kube-proxy-mj4kx                     1/1     Running   2          5m23s
kube-system   kube-proxy-rmzcm                     1/1     Running   1          5m23s
kube-system   kube-scheduler-k8s-master            1/1     Running   1          5m23s
  • 将master标记为可调度---master节点【可选】
# master节点是默认不允许调度pod 的,需要执行
kubectl taint nodes --all node-role.kubernetes.io/master-
  • kube-proxy 开启 ipvs【可选】
kubectl get configmap kube-proxy -n kube-system -o yaml > kube-proxy-configmap.yaml

# 将默认模式修改为ipvs模式
sed -i 's/mode: ""/mode: "ipvs"/' kube-proxy-configmap.yaml

kubectl apply -f kube-proxy-configmap.yaml

kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
  • 执行 crictl 报如下错误的解决办法
cat <<EOF> /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF

至此,K8S集群部署完毕,下面进行基本服务检查

posted @ 2023-05-24 15:32  dqforgive-sudo  阅读(32)  评论(0)    收藏  举报