K8S网络模型设计

我们知道的是,在K8S上的网络通信包含以下几类:

  • 容器间的通信:同一个Pod内的多个容器间的通信,它们之间通过lo网卡进行通信。

  • Pod之间的通信:通过Pod IP地址进行通信。

  • Pod和Service之间的通信:Pod IP地址和Service IP进行通信,两者并不属于同一网络,实现方式是通过IPVS或iptables规则转发。

  • Service和集群外部客户端的通信,实现方式:Ingress、NodePort、Loadbalance

K8S网络的实现不是集群内部自己实现,而是依赖于第三方网络插件----CNI(Container Network Interface)

本教程将以两台服务器进行实践,一台服务器作为主节点,一台服务器作为普通节点,使用Flannel为网络插件。

常用类型网络插件介绍:

Flannel:为Kubernetes提供叠加网络的网络插件,基于TUN/TAP隧道技术,使用UDP封装IP报文进行创建叠 加网络,借助etcd维护网络的分配情况,缺点:无法支持网络策略访问控制。

Calico:基于BGP的三层网络插件,也支持网络策略进而实现网络的访问控制;它在每台主机上都运行一个虚拟路由,利用Linux内核转发网络数据包,并借助iptables实现防火墙功能。实际上Calico最后的实现就是将每台主机都变成了一台路由器,将各个网络进行连接起来,实现跨主机通信的功能。

Canal:由Flannel和Calico联合发布的一个统一网络插件,提供CNI网络插件,并支持网络策略实现。

k8s定义的flannel网络为10.244.0.0/16,各主机的flannel从这个网络申请一个子网。pod1所在的主机的flannel子网为10.244.2.0/24,pod2所在主机的flannel子网为10.244.1.0/24。每台主机有cni0和flannel.1虚拟网卡。cni0为在同一主机pod共用的网桥,当kubelet创建容器时,将为此容器创建虚拟网卡vethxxx,并桥接到cni0网桥。flannel.1是一个tun虚拟网卡,接收不在同一主机的POD的数据,然后将收到的数据转发给flanneld进程。

在这里插入图片描述

环境准备

环境说明

本次操作使用2台电脑,2台电脑配置相同

系统与软件版本说明
CentOS7.64核8G
Docker18.09.4

Kubernetes节点设置:

IP角色hostname
192.168.0.100masterbadou2018c
192.168.0.200普通节点badou2018b

部署前操作

部署前需要对服务器的部分配置进行修改,下面的操作需要在两台服务器中进行。

临时禁用与永久禁用区别在于重启后,临时禁用需要重新设置,永久禁用不需要。

关闭selinux

临时禁用
setenforce 0
永久禁用

修改/etc/sysconfig/selinux文件设置

sed -i 's/SELINUX=permissive/SELINUX=disabled/' /etc/sysconfig/selinux
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config

禁用交换分区

临时禁用
swapoff -a
永久禁用

打开/etc/fstab注释掉swap那一行,具体脚本如下

sed -i 's/.*swap.*/#&/' /etc/fstab

修改内核参数

cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

执行配置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=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

安装k8s工具

k8s安装工具主要包括:

  • kubelet 运行在集群所有节点上,用于启动Pod和容器等对象的工具
  • kubeadm 用于初始化集群,启动集群的命令工具
  • kubectl 用于和集群通信的命令行,通过kubectl可以部署和管理应用,查看各种资源,创建、删除和更新各种组件

两个节点所在服务器输入以下命令(使用用户root或sudo)

yum install -y kubectl-1.16.0-0 kubeadm-1.16.0-0 kubelet-1.16.0-0

检验是否安装成功,控制台输入以下命令,没有输出找不到kubectl即安装成功,其余的同样操作

kubectl 

下载K8S-1.16.0配置文件

本实践提供完整配置文件,不需要手动修改配置。

下载地址:https://github.com/llzz9595/k8s

目录说明:

  • /etc/systemd/system/kubelet.service.d

    包含k8s启动配置文件

  • k8s-1.16.0-deploy/k8s

    包含k8s1.16.0网络搭建配置,包括Flannel网络组件、DashBoard监控面板、Metrics性能监控组件等配置文件

添加k8s启动配置

编辑/etc/systemd/system/kubelet.service.d/10-kubeadm.conf如下

该文件已在下载目录,将/etc/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/default/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS --resolv-conf=/root/resolv/resolv.conf  $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS --eviction-hard=nodefs.available<5%

启动master节点

master 角色服务器,使用root角色执行以下命令

kubeadm init --apiserver-advertise-address  192.168.0.100  --pod-network-cidr=10.244.0.0/16     --image-repository=registry.aliyuncs.com/google_containers
  • –apiserver-advertise-address: kubenetes api服务,配置master节点IP地址,需要与其他节点互通。

执行完成后毫无意外,应该输出以下日志,提示安装成功。

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

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.0.100:6443 --token q2t59b.yt2bgit8co9wuawv \
    --discovery-token-ca-cert-hash sha256:1bcb0673c6ddad964c1fde6f1d1c265a62b620e1776eec954asdasa4fb9662b97 
    

复制上面普通节点加入网络的命令:(没复制不要紧,可以命令重新生成,命令在后面补充)

kubeadm join 192.168.1.100:6443 --token q2t59b.yt2bgit8co9wuawv \
    --discovery-token-ca-cert-hash sha256:1bcb0673c6ddad964c1fde6f1d1c265a62b620e1776eec954asdasa4fb9662b97 
    

按照日志提示,在master节点,继续执行以下命令:

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

设置开机启动kubelet

k8s网络的启动不需要一个个服务启动,只需要启动kubelet服务即可全网服务启动,超巨方便/

为了方便我们使用,设置开机启动k8s,具体命令如下:

systemctl enable kubelet && systemctl start kubelet

检验master节点是否成功启动,输入以下命令:

kubectl get nodes

输出以下日志即表示启动成功

NAME         STATUS     ROLES    AGE     VERSION
badou2018c   NotReady   master   2m54s   v1.16.0

启动普通节点

将上面复制的节点加入网络命令在普通节点192.168.0.200中执行(使用root用户)

kubeadm join 192.168.0.100:6443 --token q2t59b.yt2bgit8co9wuawv \
    --discovery-token-ca-cert-hash sha256:1bcb0673c6ddad964c1fde6f1d1c265a62b620e1776eec954adb7a4fb9662b97 

执行完成后,输出日志如下:

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.

执行以下命令查看普通节点是否成功启动

export KUBECONFIG=/etc/kubernetes/kubelet.conf && kubectl get nodes

控制台输出k8s网络中所有节点的信息状态如下:

NAME         STATUS     ROLES    AGE   VERSION
badou2018b   NotReady   <none>   87s   v1.16.0
badou2018c   NotReady   master   12m   v1.16.0

搭建flannel

进入master节点,使用root角色

进入项目目录执行flannel搭建

cd ~/k8s-1.16.0-deploy/k8s 
kubectl apply -f kube-flannel.yml

控制台输出以下日志:

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-amd64 created
daemonset.apps/kube-flannel-ds-arm64 created
daemonset.apps/kube-flannel-ds-arm created
daemonset.apps/kube-flannel-ds-ppc64le created
daemonset.apps/kube-flannel-ds-s390x created

等待1-2分钟(等待flannel服务启动),输入命令kubectl get nodes可以看到两个节点的状态从Not Ready 变成 Ready 表示Flannel搭建成功

NAME         STATUS   ROLES    AGE   VERSION
badou2018b   Ready    <none>   61m   v1.16.0
badou2018c   Ready    master   72m   v1.16.0

搭建metrics

自kubernetes 1.8开始,资源使用指标(如容器 CPU 和内存使用率)通过 Metrics API 在 Kubernetes 中获取,metrics-server 替代了heapster。Metrics Server 实现了Resource Metrics API,Metrics Server 是集群范围资源使用数据的聚合器。
Metrics Server 从每个节点上的 Kubelet 公开的 Summary API 中采集指标信息。

进入master节点,使用root角色

进入项目目录执行以下命令:

cd ~/k8s-1.16.0-deploy/k8s 
kubectl apply -f metrics.yml

输入 kubectl get pods -A -o wide 查看metrics-server状态,Running就是启动成功。

搭建dashboard

简单的说,K8S Dashboard是官方的一个基于WEB的用户界面,专门用来管理K8S集群,并可展示集群的状态。

进入master节点,使用root角色

cd ~/k8s-1.16.0-deploy/k8s进入项目目录,编辑 vim dashboard.yml

:44 :修改监控面板开放节点端口

在这里插入图片描述

dashboard的外部端口默认只能选择端口范围:30000-32767,其余端口无效,报错如下

The Service “dashboard” is invalid: spec.ports[0].nodePort: Invalid value: 6379: provided port is not in the valid range. The range of valid ports is 30000-32767

修改配置实现自定义端口范围

具体参考:https://blog.csdn.net/fenglailea/article/details/91869648

创建key文件

进入证书保存文件夹cd ~/k8s-1.16.0-deploy/k8s/dashboard-certs,生成证书

openssl genrsa -out dashboard.key 2048
openssl req -days 36000 -new -out dashboard.csr -key dashboard.key -subj '/CN=dashboard-cert'
openssl x509 -req -in dashboard.csr -signkey dashboard.key -out dashboard.crt

创建kubernetes-dashboard-certs对象

cd ~/k8s-1.16.0-deploy/k8s/dashboard-certs执行以下命令

kubectl create namespace kubernetes-dashboard

kubectl create secret generic kubernetes-dashboard-certs --from-file=dashboard.key --from-file=dashboard.crt -n kubernetes-dashboard

部署Dashboard

安装

kubectl apply -f  ../dashboard.yml

检查结果

 kubectl get pods -A  -o wide
 kubectl get service -n kubernetes-dashboard  -o wide

创建dashboard管理员

kubectl apply -f dashboard-admin.yaml
kubectl apply -f dashboard-admin-bind-cluster-role.yaml

获取登录token

创建service account并绑定默认cluster-admin管理员集群角色:

kubectl create serviceaccount dashboard-admin -n kube-system
kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin

获取登录token

kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')

控制台输出token

Type:  kubernetes.io/service-account-token

ouput

ca.crt:     1025 bytes
namespace:  11 bytes
token:      xxx

进入dashboard

dashboard地址为:https://普通节点IP:NodePort

这里的案例就是 https://192.168.0.200:30002

进入页面如下:
在这里插入图片描述

查看节点状态

进入后,可以查看k8s网络所有节点状态

在这里插入图片描述

查看每个namespace的service、deployments、pod信息状态

在这里插入图片描述

管理pod

在这里插入图片描述

  • 日志: 查看日志
  • 执行: 进入容器内部执行命令
  • 编辑: 编辑pod配置
  • 删除: 删除pod
弹性伸缩

在这里插入图片描述

删除网络

kubeadm reset

常见错误及解决方案

1.普通节点内执行kubectl top node出现以下错误

Error from server (Forbidden): nodes.metrics.k8s.io is forbidden: User "system:node:badou2018b" cannot list resource "nodes" in API group "metrics.k8s.io" at the cluster scope

解决方法:

将Master节点的/etc/kubernetes/admin.conf复制到普通节点
然后在普通节点使用root用户执行以下命令:

export KUBECONFIG=/etc/kubernetes/admin.conf
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile

这时候重新输入kubectl top node就可以看到结果

kubectl top node
NAME         CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
badou2018b   67m          1%     2431Mi          31%       
badou2018c   166m         4%     4794Mi          62%

2.部署DaemonSet、deployment的时候出现以下错误

no matches for kind "Deployment" in version "extensions/v1beta1"

k8s1.16之后版本api发生了变化,不再支持extensions/v1beta1, apps/v1beta1, or apps/v1beta2

解决方法:

将对应错误的apiVersion修改为apps/v1

3.selector缺失错误

error: error validating "prometheus-deployment.yaml": error validating data: ValidationError(Deployment.spec): missing required field "selector" in io.k8s.api.apps.v1.DeploymentSpec; if you choose to ignore these errors, turn validation off with --validate=false

解决方法:

添加spec.selector.matchLabels,spec.selector.matchLabels的值保证与spec.labels保持一致

如:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    k8s-app: metrics-server
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server

4.成功部署metrics之后,输入kubectl top node,控制台输出提示信息如下:

error: metrics not available yet

解决方法:

打开metrics部署文件,修改Deployment里面template.spec.args,添加--kubelet-insecure-tls 和和--kubelet-preferred-address-types=InternalIP

如:

  args:
          - --cert-dir=/tmp
          - --secure-port=4443
          - --kubelet-preferred-address-types=InternalIP
          - --kubelet-insecure-tls

5.在工作节点执行命令输出以下错误:

“The connection to the server localhost:8080 was refused”

解决方法:

将Master节点的/etc/kubernetes/admin.conf复制到普通节点
然后在普通节点使用root用户执行以下命令:

export KUBECONFIG=/etc/kubernetes/admin.conf
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile

常用命令

  • kubectl get nodes 查看节点

  • kubectl get ns (namespace) 查看命名空间

  • kubectl cluster-info 查看集群的信息,主要是host

  • kubectl get svc (service ) 获取服务

  • kubectl get deployment 获取部署

  • kubectl get cs 获取集群健康状态

  • kubectl get csr

  • kubectl get rs (replicaset)

  • kubectl get rc (replicatcontroller 获取副本控制器吧自己理解的 )

  • kubectl get pods --all-namespaces 获取所有的pod命名空间的pod

  • kubectl get pod 查看默认的pod

  • kubectl get pod -n kube-system 查看命令空间为kube-system 的pod

  • https://www.cnblogs.com/ricklz/p/12259110.html 重新获取节点加入token

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐