使用Kubeadm工具快速部署一个最小化的Kubernetes v1.22.1集群

简介: 使用Kubeadm工具快速部署一个最小化的Kubernetes v1.22.1集群

环境介绍:


master 192.168.2.18


node1 192.168.2.19


node2 192.168.2.20


CentOS 7.5


Docker 19.03.13


2核+CPU,2GB+内存


Kubernetes架构图

1.png

准备工作:


1.修改/etc/hostname文件更改三台主机名称(不是必须)

[root@localhost ~]# cat > /etc/hostname << EOF
> k8s-master
> EOF
[root@localhost ~]# cat /etc/hostname
k8s-master
[root@localhost ~]# hostname k8s-master
[root@localhost ~]# cat > /etc/hostname << EOF
> k8s-node1
> EOF
[root@localhost ~]# hostname k8s-ndoe1
[root@localhost ~]# 登出(Ctrl+D退出当前终端,重新连接就会显示新主机名)

2.更改/etc/hosts文件添加主机名与IP映射关系


master、node1、node2三台主机都需要操作。

[root@k8s-master ~]# cat >> /etc/hosts << EOF
> 192.168.1.18 k8s-master
> 192.168.1.19 k8s-node1
> 192.168.1.20 k8s-node2
> EOF
[root@k8s-master ~]# cat /etc/hosts
...
192.168.1.18 k8s-master
192.168.1.19 k8s-node1
192.168.1.20 k8s-node2
[root@k8s-master ~]# for i in {19,20}        //发送/etc/hosts文件到两台node节点
> do
> scp /etc/hosts root@192.168.1.$i:/etc/
> done

验证:

[root@k8s-ndoe1 ~]# cat /etc/hosts
...
192.168.1.18 k8s-master
192.168.1.19 k8s-node1
192.168.1.20 k8s-node2
[root@k8s-node2 ~]# cat /etc/hosts
...
192.168.1.18 k8s-master
192.168.1.19 k8s-node1
192.168.1.20 k8s-node2
[root@k8s-master ~]# ping -c 2 k8s-node1
PING k8s-node1 (192.168.1.19) 56(84) bytes of data.
64 bytes from k8s-node1 (192.168.1.19): icmp_seq=1 ttl=64 time=0.180 ms
...
[root@k8s-master ~]# ping -c 2 k8s-node2
PING k8s-node2 (192.168.1.20) 56(84) bytes of data.
64 bytes from k8s-node2 (192.168.1.20): icmp_seq=1 ttl=64 time=0.166 ms
...

3.清空Iptables规则并永久关闭防火墙和Selinux


master、node1、node2三台主机都需要操作。

[root@k8s-master ~]# iptables -F
[root@k8s-master ~]# systemctl stop firewalld
[root@k8s-master ~]# systemctl disable firewalld
[root@k8s-master ~]# sed -i 's/enforcing/disabled/' /etc/selinux/config
[root@k8s-master ~]# setenforce 0
setenforce: SELinux is disabled
[root@k8s-master ~]# getenforce
Disabled

4.校正系统时间


系统时间如果不一致,会导致node节点无法加入集群中。(三台主机都需要操作)

[root@k8s-master ~]# yum -y install ntp
[root@k8s-master ~]# ntpdate cn.pool.ntp.org

5.关闭swap分区


编辑etc/fstab将swap那一行注释掉,因为K8S中不支持swap分区。

[root@k8s-master ~]# swapoff -a   //临时关闭
[root@k8s-master ~]# vim /etc/fstab    //永久关闭(注释掉最后一条配置)
...
#/dev/mapper/centos-swap swap                    swap    defaults        0 0
[root@k8s-master ~]# free -h | grep Swap   //验证Swap关闭情况(显示0代表成功关闭)
Swap:            0B          0B          0B

6.将桥接的IPv4流量传递到iptables的链

[root@k8s-master ~]# cat > /etc/sysctl.d/k8s.conf <<EOF
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> net.ipv4.ip_forward = 1
> vm.swappiness = 0
> EOF
[root@k8s-master ~]# sysctl --system
* Applying /usr/lib/sysctl.d/00-system.conf ...
* Applying /usr/lib/sysctl.d/10-default-yama-scope.conf ...
kernel.yama.ptrace_scope = 0
* Applying /usr/lib/sysctl.d/50-default.conf ...
kernel.sysrq = 16
kernel.core_uses_pid = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.promote_secondaries = 1
net.ipv4.conf.all.promote_secondaries = 1
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.d/k8s.conf ...
net.ipv4.ip_forward = 1
vm.swappiness = 0
* Applying /etc/sysctl.conf ...

7.保证每个节点唯一主机名、Mac地址、Product_uuid


-使用命令 ip link 或 ifconfig -a 来获取网络接口的 MAC 地址


-使用 sudo cat /sys/class/dmi/id/product_uuid 命令对 product_uuid 校验

-master-
[root@k8s-master ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:39:01:df brd ff:ff:ff:ff:ff:ff
[root@k8s-master ~]# cat /sys/class/dmi/id/product_uuid
76574D56-B953-9DBB-B691-256C8B3901DF
-node1-
[root@k8s-ndoe1 ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:11:c3:a5 brd ff:ff:ff:ff:ff:ff
[root@k8s-ndoe1 ~]# cat /sys/class/dmi/id/product_uuid
84FD4D56-EC2A-420E-194E-D8827711C3A5
-node2-
[root@k8s-node2 ~]# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:78:d8:be brd ff:ff:ff:ff:ff:ff
[root@k8s-node2 ~]# cat /sys/class/dmi/id/product_uuid
AC234D56-C031-0FF5-14B5-56608678D8BE

安装Docker


master、node1、node2三台主机都需要操作。


Docker与Kubernetes的关系:

2.png

Docker安装部署详解:https://blog.csdn.net/qq_44895681/article/details/105540702


[root@k8s-master/node1/2 ~]# cd /etc/yum.repos.d/
[root@k8s-master/node1/2 ~]#wget  https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo   //添加阿里云docker yum源
[root@k8s-master/node1/2 ~]# systemctl start docker
[root@k8s-master/node1/2 ~]# docker version
Client: Docker Engine - Community
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 17:03:45 2020
 OS/Arch:           linux/amd64
 Experimental:      false
 ...

安装 kubeadm工具


 Kubeadm工具的出发点很简单:就是把大部分组件都容器化,并通过StaticPod方式运行,大大简化了集群的配置及认证等工作,就是尽可能简单的部署一个生产可用的Kubernetes集群。Kubeadm部署实际要安装的组件有Kubeadm、Kubelet、Kubectl三个。Kubeadm部署Kubernetes集群的基本步骤如下:


  • kubeadm:引导集群的命令


  • kubelet:集群中运行任务的代理程序


  • kubectl:命令行管理工具


master、node1、node2三台主机都需要操作。


1.添加阿里云K8s的yum源

[root@k8s-master ~]# cat >> /etc/yum.repos.d/kubernetes.repo << EOF
> [kubernetes]
> name=Kubernetes Repo
> baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
> gpgcheck=1
> gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
> enabled=1
> EOF
[root@k8s-master ~]# for i in {19,20}         //拷贝阿里云kubernetes的yum源至其他节点
> do
> scp /etc/yum.repos.d/kubernetes.repo root@192.168.1.$i:/etc/yum.repos.d/
> done

2.安装Kubeadm、Kubelet、Kubectl组件


本次安装部署的K8s版本为1.22.1

[root@k8s-master ~]# yum  list  |grep kubeadm   //搜索kubeadm相关包
kubeadm.x86_64                              1.22.1-0                   kubernetes
[root@k8s-master ~]# yum -y install kubelet-1.22.1-0 kubeadm-1.22.1-0 kubectl-1.22.1-0  //指定版本号部署
...
已安装:
  kubeadm.x86_64 0:1.22.1-0                    kubectl.x86_64 0:1.22.1-0                    kubelet.x86_64 0:1.22.1-0
作为依赖被安装:
  conntrack-tools.x86_64 0:1.4.4-7.el7         cri-tools.x86_64 0:1.13.0-0                  kubernetes-cni.x86_64 0:0.8.7-0
  libnetfilter_cthelper.x86_64 0:1.0.0-11.el7  libnetfilter_cttimeout.x86_64 0:1.0.0-7.el7  libnetfilter_queue.x86_64 0:1.0.2-2.el7_2
  socat.x86_64 0:1.7.3.2-2.el7
完毕!

3.配置开机自启动


  暂时不需要手动启动kubelet,初始化的时候会自动启动。

[root@k8s-master ~]# systemctl start docker && systemctl enable docker
[root@k8s-master ~]# systemctl enable kubelet

初始化Kubernetes Master


只在master主机上操作。


 记住在执行下面的初始化命令的时候,最好是加上--kubernetes-version=v “版本号”,避免后面因为版本问题报错。

[root@k8s-master ~]# kubeadm init --kubernetes-version=v1.22.1  --apiserver-advertise-address=192.168.1.18  --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --image-repository registry.aliyuncs.com/google_containers
[init] Using Kubernetes version: v1.22.1
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[certs] Using certificateDir folder "/etc/kubernetes/pki"
...
...
[bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: 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.1.18:6443 --token 57y0v6.x6vl5kvcp9lqp6sj \
        --discovery-token-ca-cert-hash sha256:4e50e411707160bf753ad1490a4e495d402f11290cfe240a268fff7efda328fb

 出现上面的successfully信息之后,表示初始化已经完成,继续执行初始化完成后提示的命令。


 记住上面kubeadm join完整命令,因为后续node节点加入集群是需要用到,其中包含token。

[root@k8s-master ~]# mkdir -p $HOME/.kube
[root@k8s-master ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-master ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config

注意:


 在初始化的时候可能会遇到下面的报错:error: Get "http://localhost:10248/healthz":

...
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.
[kubelet-check] It seems like the kubelet isn't running or healthy.
[kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused.

解决方法:

[root@k8s-master ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://hx983jf6.mirror.aliyuncs.com"],
"graph": "/mnt/data",
"exec-opts": ["native.cgroupdriver=systemd"]   //添加这行配置
}
[root@k8s-master ~]# systemctl restart docker
[root@k8s-master ~]# kubeadm reset -f
//执行清除kubeadm信息后,再执行初始化命令即可。


 当出现同样这个报错,如果使用以上这个方法无法解决时,也可以试试另外一种方法,也是我其中一次遇到并且使用该方法解决过的。


  初始化Kubenetes报错1:https://blog.csdn.net/qq_44895681/article/details/10741


  Kubernetes v1.22.1部署问题2:https://blog.csdn.net/qq_44895681/article/details/119947343?spm=1001.2014.3001.5501


两台Node节点加入集群


使用上面Master节点初始化完成时最后一行的kubeadm join完整命令将k8s node节点加入集群,如果这期间超过24小时,则需要重新生成token。


1.Master主机重新生成新的token


默认token的有效期为24小时,当过期之后,该token就不可用了,以后加入节点需要新token。

[root@k8s-master ~]# kubeadm token create
c4jjui.bpppj490ggpnmi3u
[root@k8s-master ~]# kubeadm token list
TOKEN                     TTL       EXPIRES                     USAGES                   DESCRIPTION                                                EXTRA GROUPS
c4jjui.bpppj490ggpnmi3u   22h       2020-07-21T14:37:12+08:00   authentication,signing   The default bootstrap token generated by 'kubeadm init'.   system:bootstrappers:kubeadm:default-node-token

获取ca证书sha256编码hash值

[root@k8s-master ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt|openssl rsa -pubin -outform der 2>/dev/null|openssl dgst -sha256 -hex|awk '{print $NF}'
c1df6d1ad77fbc0cbdf2bb3dccd5d87eac41b936a5f3fb944f2c14b79af4de55

2.两台Node节点加入集群

kubeadm join 192.168.1.18:6443 --token 57y0v6.x6vl5kvcp9lqp6sj \
        --discovery-token-ca-cert-hash sha256:4e50e411707160bf753ad1490a4e495d402f11290cfe240a268fff7efda328fb

 - -注意- -:


  在节点加入集群时可能也会报上面初始化时报:error: Get "http://localhost:10248/healthz":这个错误,直接按照上面初始化时的处理方法即可。

[root@k8s-ndoe1 ~]# kubeadm join 192.168.1.18:6443 --token 57y0v6.x6vl5kvcp9lqp6sj \
>         --discovery-token-ca-cert-hash sha256:4e50e411707160bf753ad1490a4e495d402f11290cfe240a268fff7efda328fb
[preflight] Running pre-flight checks
        [WARNING Hostname]: hostname "k8s-ndoe1" could not be reached
        [WARNING Hostname]: hostname "k8s-ndoe1": lookup k8s-ndoe1 on 192.168.1.1:53: no such host
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
[root@k8s-node2 ~]# kubeadm join 192.168.1.18:6443 --token 57y0v6.x6vl5kvcp9lqp6sj \
>         --discovery-token-ca-cert-hash sha256:4e50e411707160bf753ad1490a4e495d402f11290cfe240a268fff7efda328fb
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

3.Master节点上查看集群状态

[root@k8s-master ~]# kubectl get nodes     //查看master节点跟其他node节点状态
NAME         STATUS     ROLES                  AGE     VERSION
k8s-master   NotReady   control-plane,master   3m53s   v1.22.1
k8s-ndoe1    NotReady   <none>                 119s    v1.22.1
k8s-node2    NotReady   <none>                 111s    v1.22.1

 可以看到集群中的节点都显示NotReady状态,需要安装完Flannel网络插件后才会变成Ready状态。

[root@k8s-master ~]# kubectl get pod -n kube-system   //查看kube-system命名空间中的pod信息
NAME                                 READY   STATUS    RESTARTS   AGE
coredns-7f6cbbb7b8-4j4x2             0/1     Pending   0          10m
coredns-7f6cbbb7b8-86j9t             0/1     Pending   0          10m
etcd-k8s-master                      1/1     Running   1          10m
kube-apiserver-k8s-master            1/1     Running   1          10m
kube-controller-manager-k8s-master   1/1     Running   1          10m
kube-proxy-5jjqg                     1/1     Running   0          10m
kube-proxy-fdq25                     1/1     Running   0          8m51s
kube-proxy-lmntm                     1/1     Running   0          8m43s
kube-scheduler-k8s-master            1/1     Running   1          10m
--这个时候还没有安装flannel插件,需要安装--

Flannel原理


 Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。但在默认的Docker配置中,每个Node的Docker服务会分别负责所在节点容器的IP分配。Node内部得容器之间可以相互访问,但是跨主机(Node)网络相互间是不能通信。


 Flannel设计目的就是为集群中所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得"同属一个内网"且"不重复的"IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。


 Flannel 使用etcd存储配置数据和子网分配信息。flannel 启动之后,后台进程首先检索配置和正在使用的子网列表,然后选择一个可用的子网,然后尝试去注册它。etcd也存储这个每个主机对应的ip。flannel 使用etcd的watch机制监视/coreos.com/network/subnets下面所有元素的变化信息,并且根据它来维护一个路由表。为了提高性能,flannel优化了Universal TAP/TUN设备,对TUN和UDP之间的ip分片做了代理。

3.png

解释上图Flannel的工作原理如下:


数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。

   ·

Flannel通过Etcd服务维护了一张节点间的路由表,该张表里保存了各个节点主机的子网网段信息。

      ·

源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一样的由docker0路由到达目标容器。


安装Flannel网络插件


 以下安装部署Flannel网络插件的yaml文件内容可以直接复制使用。

[root@k8s-master ~]# cat kube-flannel.yaml
---
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
  # Users and groups
  runAsUser:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  # Privilege Escalation
  allowPrivilegeEscalation: false
  defaultAllowPrivilegeEscalation: false
  # Capabilities
  allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
  defaultAddCapabilities: []
  requiredDropCapabilities: []
  # Host namespaces
  hostPID: false
  hostIPC: false
  hostNetwork: true
  hostPorts:
  - min: 0
    max: 65535
  # SELinux
  seLinux:
    # SELinux is unused in CaaSP
    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
        image: quay.io/coreos/flannel:v0.14.0
        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: quay.io/coreos/flannel:v0.14.0
        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
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
      - name: run
        hostPath:
          path: /run/flannel
      - name: cni
        hostPath:
          path: /etc/cni/net.d
      - name: flannel-cfg
        configMap:
          name: kube-flannel-cfg
[root@k8s-master ~]# kubectl apply -f kube-flannel.yaml       //将kube-flannel.yaml中的配置应用到一个新的pod中(安装flannel插件)
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
--上面的信息可以不用管它,会拉取flannel镜像(init表示正在拉取)--
[root@k8s-master ~]# kubectl get pod -n kube-system     //查看kube-system命名空间中的pod信息
NAMESPACE     NAME                                 READY   STATUS     RESTARTS   AGE
kube-system   coredns-7f6cbbb7b8-4j4x2             0/1     Pending    0          111m
kube-system   coredns-7f6cbbb7b8-86j9t             0/1     Pending    0          111m
kube-system   etcd-k8s-master                      1/1     Running    1          111m
kube-system   kube-apiserver-k8s-master            1/1     Running    1          111m
kube-system   kube-controller-manager-k8s-master   1/1     Running    1          111m
kube-system   kube-flannel-ds-amd64-clh6j          0/1     Init:0/1   0          2m45s
kube-system   kube-flannel-ds-amd64-ljs2t          0/1     Init:0/1   0          2m45s
kube-system   kube-flannel-ds-amd64-mw748          0/1     Init:0/1   0          2m45s
kube-system   kube-proxy-5jjqg                     1/1     Running    0          111m
kube-system   kube-proxy-fdq25                     1/1     Running    0          110m
kube-system   kube-proxy-lmntm                     1/1     Running    0          109m
kube-system   kube-scheduler-k8s-master            1/1     Running    1          111m

 镜像拉取应该会很慢,可以手动拉取,或者从其他地方拉取。(也可以将其中成功拉取了flannel镜像的节点上的flannel镜像docker save导出来,然后到docker load导入到其他拉取flannel镜像失败的节点中)


 例子:


      - 导出:docker save -o my_ubuntu.tar runoob/ubuntu:v3

     

       - 导入:docker load < my_ubuntu.tar

[root@k8s-master ~]# kubectl  describe pod  kube-flannel-ds-amd64-clh6j -n kube-system      //查看kube-system命名空间中的kube-flannel-ds-amd64-clh6j名称的pod详细信息
Name:         kube-flannel-ds-amd64-clh6j   //pod名字为kube-flannel-ds-amd64-clh6j
Namespace:    kube-system         //命名空间为kube-system
Priority:     0
Node:         k8s-ndoe1/192.168.1.19   //属于k8s-ndoe1/192.168.1.19这台节点
Start Time:   Fri, 27 Aug 2021 20:37:44 +0800
Labels:       app=flannel
              controller-revision-hash=76ccd4ff4f
              pod-template-generation=1
              tier=node
Annotations:  <none>
Status:       Pending
IP:           192.168.1.19
...
...
Node-Selectors:              <none>
Tolerations:                 :NoSchedule op=Exists
                             node.kubernetes.io/disk-pressure:NoSchedule op=Exists
                             node.kubernetes.io/memory-pressure:NoSchedule op=Exists
                             node.kubernetes.io/network-unavailable:NoSchedule op=Exists
                             node.kubernetes.io/not-ready:NoExecute op=Exists
                             node.kubernetes.io/pid-pressure:NoSchedule op=Exists
                             node.kubernetes.io/unreachable:NoExecute op=Exists
                             node.kubernetes.io/unschedulable:NoSchedule op=Exists
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  6m56s  default-scheduler  Successfully assigned kube-system/kube-flannel-ds-amd64-clh6j to k8s-ndoe1
  Normal  Pulling    6m55s  kubelet            Pulling image "quay.io/coreos/flannel:v0.11.0-amd64"
--》从上面的信息可以看到k8s-node1这个节点已经成功拉取到这个flannel镜像

查看flannel网络插件状态

[root@k8s-master ~]# kubectl get pod  -n kube-system
NAME                                 READY   STATUS    RESTARTS        AGE
coredns-7f6cbbb7b8-4j4x2             1/1     Running   2 (2d11h ago)   10d
coredns-7f6cbbb7b8-86j9t             1/1     Running   2 (2d11h ago)   10d
etcd-k8s-master                      1/1     Running   2 (2d11h ago)   10d
kube-apiserver-k8s-master            1/1     Running   2 (2d11h ago)   10d
kube-controller-manager-k8s-master   1/1     Running   3 (2d11h ago)   6d1h
kube-flannel-ds-kngqd                1/1     Running   1 (14h ago)     10d
kube-flannel-ds-lzdpk                1/1     Running   0               10d
kube-flannel-ds-r7f4v                1/1     Running   2 (14h ago)     10d
kube-proxy-5jjqg                     1/1     Running   1 (2d11h ago)   10d
kube-proxy-fdq25                     1/1     Running   0               10d
kube-proxy-lmntm                     1/1     Running   1 (14h ago)     10d
kube-scheduler-k8s-master            1/1     Running   3 (2d11h ago)   6d1h

从上面的信息可以看到在所有K8s节点都成功安装flannel网络插件后,kube-system命名空间内的所有pod都已经是running运行状态。


再查看node节点状态:

[root@k8s-master ~]# kubectl get nodes
NAME         STATUS   ROLES                  AGE   VERSION
k8s-master   Ready    control-plane,master   10d   v1.22.1
k8s-ndoe1    Ready    <none>                 10d   v1.22.1
k8s-node2    Ready    <none>                 10d   v1.22.1

现在所有K8s节点状态都已经为Ready状态,接下来就可以使用K8s来创建发布自己的服务了!


注意:


 使用Kubeadm工具部署的K8s集群,会出现获取kube-scheduler和kube-controller-manager组件状态异常的问题,可以参考上面的文章(使用Kubeadm安装的K8s集群获取kube-scheduler和kube-controller-manager组件状态异常问题)解决。

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
1天前
|
运维 Kubernetes 监控
Kubernetes 集群的监控与维护策略
【4月更文挑战第30天】 在现代云计算环境中,容器化技术已成为应用程序部署和管理的重要手段。其中,Kubernetes 作为一个开源的容器编排平台,以其强大的功能和灵活性受到广泛欢迎。然而,随之而来的是对 Kubernetes 集群监控和维护的复杂性增加。本文将探讨针对 Kubernetes 集群的监控策略和维护技巧,旨在帮助运维人员确保集群的稳定性和高效性。通过分析常见的性能瓶颈、故障诊断方法以及自动化维护工具的应用,我们将提供一套实用的解决方案,以优化 Kubernetes 环境的性能和可靠性。
|
1天前
|
运维 Kubernetes 监控
Kubernetes集群的持续性能优化策略
【4月更文挑战第30天】 在动态且不断扩展的云计算环境中,保持应用性能的稳定性是一个持续的挑战。本文将探讨针对Kubernetes集群的持续性能优化策略,旨在为运维工程师提供一套系统化的性能调优框架。通过分析集群监控数据,我们将讨论如何诊断常见问题、实施有效的资源管理和调度策略,以及采用自动化工具来简化这一过程。
|
1天前
|
Prometheus 监控 Kubernetes
Kubernetes 集群的监控与日志管理策略
【4月更文挑战第30天】 在微服务架构日益普及的当下,容器化技术与编排工具如Kubernetes成为了运维领域的重要话题。有效的监控和日志管理对于保障系统的高可用性和故障快速定位至关重要。本文将探讨在Kubernetes环境中实施监控和日志管理的最佳实践,包括选用合适的工具、部署策略以及如何整合这些工具来提供端到端的可见性。我们将重点讨论Prometheus监控解决方案和EFK(Elasticsearch, Fluentd, Kibana)日志管理堆栈,分析其在Kubernetes集群中的应用,并给出优化建议。
|
2天前
|
Kubernetes 应用服务中间件 nginx
K8S二进制部署详解,一文教会你部署高可用K8S集群(二)
K8S二进制部署详解,一文教会你部署高可用K8S集群(二)
|
2天前
|
Kubernetes 网络安全 数据安全/隐私保护
K8S二进制部署详解,一文教会你部署高可用K8S集群(一)
K8S二进制部署详解,一文教会你部署高可用K8S集群(一)
|
3天前
|
Kubernetes 网络协议 Python
一文教会你,如何通过kubeadm,在生产环境部署K8S高可用集群(二)
一文教会你,如何通过kubeadm,在生产环境部署K8S高可用集群(二)
|
3天前
|
Kubernetes 应用服务中间件 开发工具
一文教会你,如何通过kubeadm,在生产环境部署K8S高可用集群(一)
一文教会你,如何通过kubeadm,在生产环境部署K8S高可用集群(一)
|
5天前
|
运维 Kubernetes 监控
Kubernetes 集群的持续性能优化实践
【4月更文挑战第26天】 在动态且不断增长的云计算环境中,维护高性能的 Kubernetes 集群是一个挑战。本文将探讨一系列实用的策略和工具,旨在帮助运维专家监控、分析和优化 Kubernetes 集群的性能。我们将讨论资源分配的最佳实践,包括 CPU 和内存管理,以及集群规模调整的策略。此外,文中还将介绍延迟和吞吐量的重要性,并提供日志和监控工具的使用技巧,以实现持续改进的目标。
|
8天前
|
存储 运维 Kubernetes
Kubernetes 集群的监控与维护策略
【4月更文挑战第23天】 在微服务架构日益盛行的当下,容器编排工具如 Kubernetes 成为了运维工作的重要环节。然而,随着集群规模的增长和复杂性的提升,如何确保 Kubernetes 集群的高效稳定运行成为了一大挑战。本文将深入探讨 Kubernetes 集群的监控要点、常见问题及解决方案,并提出一系列切实可行的维护策略,旨在帮助运维人员有效管理和维护 Kubernetes 环境,保障服务的持续可用性和性能优化。
|
9天前
|
存储 运维 Kubernetes
Kubernetes 集群的持续性能优化实践
【4月更文挑战第22天】在动态且复杂的微服务架构中,确保 Kubernetes 集群的高性能运行是至关重要的。本文将深入探讨针对 Kubernetes 集群性能优化的策略与实践,从节点资源配置、网络优化到应用部署模式等多个维度展开,旨在为运维工程师提供一套系统的性能调优方法论。通过实际案例分析与经验总结,读者可以掌握持续优化 Kubernetes 集群性能的有效手段,以适应不断变化的业务需求和技术挑战。

推荐镜像

更多