本文使用Kubeadm来安装一个单节点的Kubernetes环境,以加深对Kubernetes各个组件和安装过程的理解。

环境准备

请参考 使用RKE安装单节点kubernetes 一文中的环境准备章节。

配置yum源

  1. cat <<EOF > /etc/yum.repos.d/kubernetes.repo
  2. [kubernetes]
  3. name=Kubernetes
  4. baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
  5. enabled=1
  6. gpgcheck=1
  7. gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
  8. http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
  9. EOF

安装并配置IPVS

由于ipvs已经加入到了内核的主干,所以为kube-proxy开启ipvs的前提需要加载以下的内核模块:

  1. cat > /etc/sysconfig/modules/ipvs.modules <<EOF
  2. #!/bin/bash
  3. modprobe -- ip_vs
  4. modprobe -- ip_vs_rr
  5. modprobe -- ip_vs_wrr
  6. modprobe -- ip_vs_sh
  7. modprobe -- nf_conntrack_ipv4
  8. EOF
  9. chmod 755 /etc/sysconfig/modules/ipvs.modules && bash \
  10. /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4

上面脚本创建了的/etc/sysconfig/modules/ipvs.modules文件,保证在节点重启后能自动加载所需模块。 使用lsmod | grep -e ip_vs -e nf_conntrack_ipv4命令查看是否已经正确加载所需的内核模块。

  1. # 检查加载的模块
  2. lsmod | grep -e ipvs -e nf_conntrack_ipv4
  3. # 或者
  4. cut -f1 -d " " /proc/modules | grep -e ip_vs -e nf_conntrack_ipv4

接下来还需要确保各个节点上已经安装了ipset软件包。 为了便于查看ipvs的代理规则,最好安装一下管理工具ipvsadm。

  1. yum install ipset ipvsadm -y

如果以上前提条件如果不满足,则即使kube-proxy的配置开启了ipvs模式,也会退回到iptables模式。

安装组件

  1. yum -y install kubelet kubeadm kubectl kubernetes-cni

组件说明:

  • kubeadm:用于初始化 Kubernetes 集群
  • kubectl:Kubernetes 的命令行工具,主要作用是部署和管理应用,查看各种资源,创建,删除和更新组件
  • kubelet:主要负责启动 Pod 和容器

    启动kubelet服务

    ``` systemctl enable kubelet && systemctl start kubelet
  1. # 生成配置文件

kubeadm config print init-defaults —kubeconfig ClusterConfiguration > kubeadm.yml

修改镜像和kubernetes版本

sed -i ‘s/^imageRepository: k8s.gcr.io/imageRepository: registry.aliyuncs.com\/google_containers/g’\ kubeadm.yml

sed -i -e “s|^kubernetesVersion.*|kubernetesVersion: v1.16.2}|g” kubeadm.yml

  1. 修改配置文件:

apiVersion: kubeadm.k8s.io/v1beta2 bootstrapTokens:

  • groups:
    • system:bootstrappers:kubeadm:default-node-token token: abcdef.0123456789abcdef ttl: 24h0m0s usages:
    • signing
    • authentication kind: InitConfiguration localAPIEndpoint:

      修改为主节点 IP

      advertiseAddress: 192.168.56.120 bindPort: 6443 nodeRegistration: criSocket: /var/run/dockershim.sock name: k8s-node0 taints:
    • effect: NoSchedule key: node-role.kubernetes.io/master

apiServer: timeoutForControlPlane: 4m0s apiVersion: kubeadm.k8s.io/v1beta2 certificatesDir: /etc/kubernetes/pki clusterName: kubernetes controllerManager: {} dns: type: CoreDNS etcd: local: dataDir: /var/lib/etcd

国内不能访问 Google,修改为阿里云

imageRepository: registry.aliyuncs.com/google_containers kind: ClusterConfiguration kubernetesVersion: v1.16.2 networking: dnsDomain: cluster.local

替换 Calico 网段为我们虚拟机不重叠的网段(这里用的是 Flannel 默认网段)

podSubnet: “10.244.0.0/16” serviceSubnet: 10.96.0.0/12 scheduler: {}

—- #下面有增加的三行配置,用于设置Kubeproxy使用LVS apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: ipvs

  1. > 注意:
  2. > podSubnet 在集群模式下,不能和虚拟机网络重叠,所以这里使用Flannel默认的网段。单机模式,重叠没影响。
  3. > ![image.png](https://tva1.sinaimg.cn/large/006y8mN6gy1g8hqkzfo8aj30x30i776q.jpg)
  4. 修改配置文件,在文件末尾增加IPVS配置:

开启 IPVS 模式

apiVersion: kubeadm.k8s.io/v1beta2 kind: KubeProxyConfiguration featureGates: SupportIPVSProxyMode: true mode: ipvs

  1. # 查看和拉取镜像
  2. 通过生成的配置文件,提前下载镜像:

查看所需镜像列表

kubeadm config images list —config kubeadm.yml

拉取镜像

kubeadm config images pull —config kubeadm.yml

  1. # 初始化master节点
  2. 你可以使用上面的配置文件初始化:

kubeadm init —config kubeadm.yml

  1. 也可以通过命令行方式出似乎还,并指定镜像仓库,则可以不用提前拉取镜像了,也可以不使用kubeadm.yml配置文件(除非,需要定制化yml文件)

IPADDR=$(ifconfig eth1|grep inet|grep -v inet6|awk ‘{print $2}’) kubeadm init —apiserver-advertise-address $IPADDR \ —apiserver-cert-extra-sans $IPADDR \ —service-cidr 10.96.0.0/12 \ —pod-network-cidr 10.244.0.0/16 \ —kubernetes-version v1.16.2 \ —image-repository registry.aliyuncs.com/google_containers —token-ttl 0

  1. 查看节点状态:

kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-kube-node1 NotReady master 53s v1.16.2

  1. 可以看到节点还没有Readydns的两个pod也没不正常,还需要安装网络配置。
  2. # 配置 kubectl
  3. kubectl默认会在执行的用户家目录下面的.kube目录下寻找config文件。这里是将在初始化时[kubeconfig]步骤生成的admin.conf拷贝到.kube/config

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

  1. # 使master node参与工作负载
  2. 使用kubeadm初始化的集群,出于安全考虑master node不参与工作负载,也就是说我们无法在master node上运行服务。 这里搭建的环境目前只有一个master node,可以使用下面的命令使master node参与工作负载。

kubectl taint nodes —all node-role.kubernetes.io/master-

  1. 这会从配置了 `node-role.kubernetes.io/master` 污染标志的节点,移除污染标志。 包括主节点,这表示scheduler可以在任何节点上安排运行pod
  2. # 安装网络插件
  3. 安装calico插件

wget https://docs.projectcalico.org/v3.9/manifests/calico.yaml sed -i ‘/CALICO_IPV4POOL_IPIP/{n;s/Always/off/g}’ calico.yaml

多网卡问题 interface=eth0 interface=eth.* first-found

sed -i ‘/name: IP/{s/name: IP/name: IP_AUTODETECTION_METHOD/}’ calico.yaml sed -i ‘/\”autodetect\”/{s/\”autodetect\”/\”interface=eth1\”/}’ calico.yaml kubectl apply -f calico.yaml

  1. 执行成功后,节点并不能马上变成Ready状态,稍等几分钟,就可以看到所有状态都正常了。

watch kubectl get pods —all-namespaces

Every 2.0s: kubectl get pods —all-namespaces Wed Sep 11 19:52:24 2019

NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-65b8787765-krgls 1/1 Running 0 5m7s kube-system calico-node-7pf6h 1/1 Running 0 5m7s kube-system coredns-bccdc95cf-4gsw6 1/1 Running 0 5m43s kube-system coredns-bccdc95cf-9q6qv 1/1 Running 0 5m43s kube-system etcd-node1 1/1 Running 0 4m57s kube-system kube-apiserver-node1 1/1 Running 0 4m44s kube-system kube-controller-manager-node1 1/1 Running 0 4m42s kube-system kube-proxy-5fnkj 1/1 Running 0 5m42s kube-system kube-scheduler-node1 1/1 Running 0 5m2s

  1. # 验证是否成功
  2. ## 检查组件运行状态

[root@k8s-kube-node1 ~]# kubectl get cs NAME STATUS MESSAGE ERROR

调度服务,主要作用是将 POD 调度到 Node

scheduler Healthy ok

自动化修复服务,主要作用是 Node 宕机后自动修复 Node 回到正常的工作状态

controller-manager Healthy ok

服务注册与发现

etcd-0 Healthy {“health”:”true”}

  1. ## 检查 Master 状态

[root@k8s-kube-node1 ~]# kubectl cluster-info Kubernetes master is running at https://192.168.56.120:6443 KubeDNS is running at https://192.168.56.120:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use ‘kubectl cluster-info dump’.

  1. ## 检查 Nodes 状态

[root@k8s-kube-node1 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-kube-node1 Ready master 13h v1.16.2

  1. 查看节点详细信息:

[root@k8s-kube-node1 ~]# kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME k8s-kube-node1 Ready master 3m23s v1.16.2 192.168.56.120 CentOS Linux 7 (Core) 3.10.0-957.5.1.el7.x86_64 docker://1.13.1

  1. ## 测试DNS

kubectl run curl —image=radial/busyboxplus:curl -i —tty

  1. 进入后执行nslookup kubernetes.default确认解析正常。

[ root@curl-2421989462-vldmp:/ ]$ nslookup kubernetes.default

  1. 测试OK后,删除掉curl这个Pod

kubectl delete deploy curl

  1. # kube-proxy 开启 ipvs
  2. 如果在初始化时kubeadm.yml中没有配置ipvs,则可以修改ConfigMapkube-system/kube-proxy中的config.confmode: ipvs

kubectl edit cm kube-proxy -n kube-system

  1. 查看kube-proxy pod

[root@k8s-kube-node1 ~]# kubectl get pods -n kube-system|grep proxy kube-proxy-5fnkj 1/1 Running 1 14h

  1. 对于Kubernetes来说,可以直接将这上面这些Pod删除之后,会自动重建。<br />批量删除 kube-proxy

kubectl get pod -n kube-system | grep kube-proxy | awk\ ‘{system(“kubectl delete pod “$1” -n kube-system”)}’

  1. 由于你已经通过ConfigMap修改了kube-proxy的配置,所以后期增加的Node节点,会直接使用ipvs模式。<br />再次查看:

[root@k8s-kube-node1 ~]# kubectl get pods -n kube-system|grep proxy kube-proxy-z7k4f 1/1 Running 0 16s

  1. 查看日志:

kubectl logs kube-proxy-z7k4f -n kube-system

  1. 日志中打印出了Using ipvs Proxier,说明ipvs模式已经开启。<br />使用ipvsadm测试,可以查看之前创建的Service已经使用LVS创建了集群。

[root@k8s-kube-node1 ~]# ipvsadm -Ln

  1. # 配置 Node 节点
  2. node 节点加入到集群中很简单,只需要在 node 服务器上安装 kubeadmkubectlkubelet 三个工具,然后使用 `kubeadm join` 命令加入即可。<br />在master节点上配置从节点:

kubeadm join 192.168.56.120:6443 —token abcdef.0123456789abcdef \ —discovery-token-ca-cert-hash \ sha256:40405f03230b7c9b872110aaa28e222bed3dca3663c4e3b9dcdad572fbbf5be2

  1. 说明:
  2. -
  3. token
  4. -
  5. - 可以通过安装 master 时的日志查看 token 信息
  6. - 可以通过 `kubeadm token list`命令打印出 token 信息
  7. - 如果 token 过期,可以使用 `kubeadm token create --print-join-command` 命令**创建新的 token**
  8. -
  9. discovery-token-ca-cert-hash
  10. -
  11. - 可以通过安装 master 时的日志查看 sha256 信息
  12. - 可以通过 `openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'` 命令查看 sha256 信息
  13. 添加参数忽略错误:

kubeadm join 192.168.56.120:6443 —token abcdef.0123456789abcdef \ —discovery-token-ca-cert-hash \ sha256:40405f03230b7c9b872110aaa28e222bed3dca3663c4e3b9dcdad572fbbf5be2\ —ignore-preflight-errors=all

  1. ## 验证是否成功
  2. 回到 master 服务器,查看节点状态:

[root@k8s-kube-node1 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-kube-node1 NotReady master 12m v1.16.2 k8s-kube-node2 NotReady 12m v1.16.2

  1. > 如果 node 节点加入 master 时配置有问题可以在 node 节点上使用 kubeadm reset 重置配置再使用 kubeadm join 命令重新加入即可。希望在 master 节点删除 node ,可以使用 kubeadm delete nodes 删除。
  2. ## 查看 pod 状态

kubectl get pod -n kube-system kubectl get pod -n kube-system -o wide

  1. # 可选操作
  2. ## 从非主节点上管理集群
  3. 将主节点中的 /etc/kubernetes/admin.conf 文件拷贝到从节点相同目录下:

scp /etc/kubernetes/admin.conf k8s-kube-node1:/etc/kubernetes/

  1. 运行下面命令:

kubectl —kubeconfig /etc/kubernetes/admin.conf get nodes

  1. 或者,配置环境变量:

echo “export KUBECONFIG=/etc/kubernetes/admin.conf” >> ~/.bash_profile source ~/.bash_profile

  1. 然后,可以执行下面命令:

[root@k8s-kube-node1 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-kube-node1 NotReady master 12m v1.16.2 k8s-kube-node2 NotReady 12m v1.16.2

  1. ## 映射API服务到本地
  2. 如果你想从集群外部连接到API服务,可以使用工具`kubectl proxy。`<br />参考上面,先拷贝文件,配置环境变量,然后执行:

[root@k8s-kube-node1 ~]# kubectl proxy —address=192.168.56.120 Starting to serve on 192.168.56.120:8001

  1. 你现在就可以在本地这样 [http://192.168.56.120:8001/api/v1](http://192.168.56.120:8001/api/v1) 访问到API服务了。
  2. # 重置集群

kubeadm reset -y rm -rf /var/lib/etcd

kubectl drain k8s-kube-node1 —delete-local-data —force —ignore-daemonsets kubectl delete node k8s-kube-node2 k8s-kube-node1 ifconfig tunl0 down ip link delete tunl0

```

总结

以上是使用RKE安装单节点k8s的记录,其实稍加修改配置文件,就可以安装集群。
这里,我把上面的所有命令整理了一下,提交到了 github,供大家参考。

参考文章