k8s中的通信模式
1、pod内部之间容器与容器之间的通信,在同一个pod 中的容器共享资源和网络,使用同一个网络命名空间,可以直接通信的
2、同一个node节点之内,不同pod之间的通信,每个pod都有一个全局的真实的IP地址,同一个node直接的不同pod可以直接使用对方pod的IP地址通信
pod1和pod2是通过docker0的网桥来进行通信
3、不同node节点的上的pod之间如何进行通信?
cni的插件
cni是一个标准接口,用于容器运行时调用网络插件,配置容器网络,负责设置容器的网络命名空间,IP地址,路由等等参数
flannel插件:功能就是让集群之中不同节点的docker容器具有全集群唯一的虚拟IP地址
overlay网络,在底层物理网络的基础之上,创建一个逻辑的网络层,二层和三层的集合,二层是物理网络,三层是逻辑上的网络层,overlay网络也是一种网络虚拟化的技术
flannel支持的数据转发方式
1、UDP模式,默认模式,应用转发,配置简单,但是性能最差
2、vlan,基于内核转发,也是最常用的网络类型(一般都是小集群)
3、host-gw(性能最好,但是配置麻烦)
UDP:基于应用转发,fannel提供路由表,flannel封装数据包,解封装
node都会有一个flannel的虚拟网卡
vxlan:使用的就是overlay的虚拟隧道通信技术,二层+三层的模式
upd基于应用层,用户态
vxlan:flannel提供路由表,内核封装解封装
在 node01 节点上操作
#上传 cni-plugins-linux-amd64-v0.8.6.tgz 和 flannel.tar 到 /opt 目录中
cd /opt/
docker load -i flannel.tar
mkdir -p /opt/cni/bin
tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin
//在 master01 节点上操作
#上传 kube-flannel.yml 文件到 /opt/k8s 目录中,部署 CNI 网络
cd /opt/k8s
kubectl apply -f kube-flannel.yml
kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
kube-flannel-ds-hjtc7 1/1 Running 0 7s
kubectl get nodes
NAME STATUS ROLES AGE VERSION
192.168.80.11 Ready <none> 81m v1.20.11
flannel:每个发向容器的数据包进行封装,vxlan通过vtep打包数据,由内核封装成数据包----转发目标的node节点---到了目标node节点,还有一个解封装的过程,再发送目标pod,性能是有一定影响的
Calico插件
calico:采用直接路由的方式,BGP路由,不需要修改报文,统一直接通过路由表转发,路由表会相当复杂,运行维护的要求比较高
BGP模式的特点:交换路由信息的外部网关协议,可以连接不同的node节点,node节点可能不是一个网段,BGP实现可靠的,最佳的,而且是动态的路由选择,自动识别相邻的路由设备
calico不使用overlay,也不需要交换,直接通过虚拟路由实现,每台虚拟路由都通过BGP
核心组件
felix:也是运行在主机中的一个个pod,一个进程,k8s daemont set 会在每个node节点部署相同的pod,后台的运行方式
负载宿主机上插入路由规则,维护calico需要的网络设备,网络接口管理,监听,路由等等
BGP client:bird BGP的客户端,专门负责在集群中分发在集群中分发路由规则的信息,每一个节点都会有一个BGP client
BGP协议广播方式通知其他节点的,分发路由的规则,实现网络互通
etcd 报讯路由信息,负责网络元数据的一致性,保证网络状态的一致和准确
calico的工作原理
路由表来维护每个pod之间的通信,创建好pod之后,添加一个设备cali veth pair设备
虚拟网卡:veth pair 是一对设备,虚拟的以太网设备
一头连接在容器的网络命名空间eth0
另一头连接宿主机的网络命名空间 cali
ip地址fenpei:veth pair连接容器的部分给容器分配一个IP地址,这个IP地址是唯一标识,宿主机也会被veth pair分配一个calico网络的内部IP地址,和其他节点上的容器进行通信
veth设备,容器发出的IP地址通过veth pair设备到宿主机,宿主机根据路由规则的下一跳,发送到网关(目标宿主机)
数据包到达目标宿主机,veth pair设备,目标宿主机噎死根据路由规则,下一跳地址,转发到目标容器
ipip模式:会生成一个tunnel,数据包都在tunnel内部打包,封装:宿主机ip 容器内部的IP地址
部署calico
在 master01 节点上操作
#上传 calico.yaml 文件到 /opt/k8s 目录中,部署 CNI 网络
cd /opt/k8s
vim calico.yaml
#修改里面定义 Pod 的网络(CALICO_IPV4POOL_CIDR),需与前面 kube-controller-manager 配置文件指定的 cluster-cidr 网段一样
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16" #Calico 默认使用的网段为 192.168.0.0/16
kubectl apply -f calico.yaml
kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-659bd7879c-4h8vk 1/1 Running 0 58s
calico-node-nsm6b 1/1 Running 0 58s
calico-node-tdt8v 1/1 Running 0 58s
#等 Calico Pod 都 Running,节点也会准备就绪
kubectl get nodes
在 node01 节点上操作
cd /opt/
scp kubelet.sh proxy.sh root@192.168.233.93:/opt/
scp kubelet.sh proxy.sh root@192.168.233.94:/opt/
scp -r /opt/cni root@192.168.233.93:/opt/
scp -r /opt/cni root@192.168.233.94:/opt/
//在 node02 节点上操作
#启动kubelet服务
cd /opt/
chmod +x kubelet.sh
./kubelet.sh 192.168.233.94
//在 master01 节点上操作
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
node-csr-BbqEh6LvhD4R6YdDUeEPthkb6T_CJDcpVsmdvnh81y0 10s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE 85m kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Approved,Issued
#通过 CSR 请求
kubectl certificate approve node-csr-BbqEh6LvhD4R6YdDUeEPthkb6T_CJDcpVsmdvnh81y0
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
node-csr-BbqEh6LvhD4R6YdDUeEPthkb6T_CJDcpVsmdvnh81y0 23s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Approved,Issued
node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE 85m kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Approved,Issued
#加载 ipvs 模块
for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done
#使用proxy.sh脚本启动proxy服务
cd /opt/
chmod +x proxy.sh
./proxy.sh 192.168.233.94
#查看群集中的节点状态
kubectl get nodes
coredns
可以集群当中的service资源创建一个域名和ip进行对应解析的关系
service是对外提供访问的地址,现在我们加入DNS机制之后,可以直接访问访问服务名,
部署coreDNS
在所有 node 节点上操作
#上传 coredns.tar 到 /opt 目录中
cd /opt
docker load -i coredns.tar
//在 master01 节点上操作
#上传 coredns.yaml 文件到 /opt/k8s 目录中,部署 CoreDNS
cd /opt/k8s
kubectl apply -f coredns.yaml
kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-5ffbfd976d-j6shb 1/1 Running 0 32s
#DNS 解析测试
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
kubectl run -it --rm dns-test --image=busybox:1.28.4 sh
If you don't see a command prompt, try pressing enter.
/ # nslookup kubernetes
Server: 10.0.0.2
Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local
Name: kubernetes
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
exit
部署msater02
从 master01 节点上拷贝证书文件、各master组件的配置文件和服务管理文件到 master02 节点
scp -r /opt/etcd/ root@20.0.0.71:/opt/
scp -r /opt/kubernetes/ root@20.0.0.71:/opt
scp -r /root/.kube root@20.0.0.71:/root
scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@20.0.0.71:/usr/lib/systemd/system/
//修改配置文件kube-apiserver中的IP
vim /opt/kubernetes/cfg/kube-apiserver
KUBE_APISERVER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--etcd-servers=https://20.0.0.70:2379,https://20.0.0.72:2379,https://20.0.0.73:2379 \
--bind-address=20.0.0.71 \
--secure-port=6443 \
--advertise-address=20.0.0.71 \
--allow-privileged=true \
--service-cluster-ip-range=10.0.0.0/24 \
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \
--authorization-mode=RBAC,Node \
--enable-bootstrap-token-auth=true \
--token-auth-file=/opt/kubernetes/cfg/token.csv \
--service-node-port-range=30000-50000 \
--kubelet-client-certificate=/opt/kubernetes/ssl/apiserver.pem \
--kubelet-client-key=/opt/kubernetes/ssl/apiserver-key.pem \
--tls-cert-file=/opt/kubernetes/ssl/apiserver.pem \
--tls-private-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
--client-ca-file=/opt/kubernetes/ssl/ca.pem \
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
--service-account-issuer=api \
--service-account-signing-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
--etcd-cafile=/opt/etcd/ssl/ca.pem \
--etcd-certfile=/opt/etcd/ssl/server.pem \
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \
--requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \
--proxy-client-cert-file=/opt/kubernetes/ssl/apiserver.pem \
--proxy-client-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
--requestheader-allowed-names=kubernetes \
--requestheader-extra-headers-prefix=X-Remote-Extra- \
--requestheader-group-headers=X-Remote-Group \
--requestheader-username-headers=X-Remote-User \
--enable-aggregator-routing=true \
--audit-log-maxage=30 \
--audit-log-maxbackup=3 \
--audit-log-maxsize=100 \
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"
......
//在 master02 节点上启动各服务并设置开机自启
systemctl start kube-apiserver.service
systemctl enable kube-apiserver.service
systemctl start kube-controller-manager.service
systemctl enable kube-controller-manager.service
systemctl start kube-scheduler.service
systemctl enable kube-scheduler.service
//查看node节点状态
ln -s /opt/kubernetes/bin/* /usr/local/bin/
kubectl get nodes
kubectl get nodes -o wide #-o=wide:输出额外信息;对于Pod,将输出Pod所在的Node名
//此时在master02节点查到的node节点状态仅是从etcd查询到的信息,
而此时node节点实际上并未与master02节点建立通信连接,因此需要使用一个VIP把node节点与master节点都关联起来
负载均衡部署
配置nginx的官方在线yum源,配置本地nginx的yum源
cat > /etc/yum.repos.d/nginx.repo << 'EOF'
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
EOF
yum install nginx -y
//修改nginx配置文件,配置四层反向代理负载均衡,指定k8s群集2台master的节点ip和6443端口
vim /etc/nginx/nginx.conf
stream {
log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent';
#日志记录格式
#$remote_addr: 客户端的 IP 地址。
#$upstream_addr: 上游服务器的地址。
#[$time_local]: 访问时间,使用本地时间。
#$status: HTTP 响应状态码。
#$upstream_bytes_sent: 从上游服务器发送到客户端的字节数。
access_log /var/log/nginx/k8s-access.log main;
upstream k8s-apiserver {
server 20.0.0.70:6443;
server 20.0.0.71:6443;
}
server {
listen 6443;
proxy_pass k8s-apiserver;
}
}
检查配置文件语法
nginx -t
//启动nginx服务,查看已监听6443端口
systemctl start nginx
systemctl enable nginx
netstat -natp | grep nginx
//部署keepalived服务
yum install keepalived -y
//修改keepalived配置文件
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_MASTER
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script check_nginx {
script "/etc/nginx/check_nginx.sh"
interval 5
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
20.0.0.100/24
}
track_script {
check_nginx
}
}
从
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_BACKUP
vrrp_skip_check_adv_addr
#vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
vrrp_script check_nginx {
script "/etc/nginx/check_nginx.sh"
interval 5
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
20.0.0.100/24
}
track_script {
check_nginx
}
}
创建nginx状态检查脚本
vim /etc/nginx/check_nginx.sh
#!/bin/bash
/usr/bin/curl -I http://localhost &>/dev/null
if [ $? -ne 0 ];then
# /etc/init.d/keepalived stop
systemctl stop keepalived
fi
chmod +x /etc/nginx/check_nginx.sh
//启动keepalived服务(一定要先启动了nginx服务,再启动keepalived服务)
systemctl start keepalived
systemctl enable keepalived
ip addr #查看VIP是否生成
修改node节点上的bootstrap.kubeconfig,kubelet.kubeconfig配置文件为VIP
cd /opt/kubernetes/cfg/
vim bootstrap.kubeconfig
server: https://192.168.233.100:6443
vim kubelet.kubeconfig
server: https://192.168.233.100:6443
vim kube-proxy.kubeconfig
server: https://192.168.233.100:6443
//重启kubelet和kube-proxy服务
systemctl restart kubelet.service
systemctl restart kube-proxy.service
在 lb01 上查看 nginx 和 node 、 master 节点的连接状态
netstat -natp | grep nginx
tcp 0 0 0.0.0.0:6443 0.0.0.0:* LISTEN 4141/nginx: master
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4141/nginx: master
tcp 0 0 20.0.0.74:43860 20.0.0.71:6443 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.73:47114 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.74:43848 20.0.0.71:6443 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.72:50436 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.72:50444 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.72:50474 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.74:43870 20.0.0.71:6443 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.74:52370 20.0.0.70:6443 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.72:50446 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.72:50420 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.73:47112 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.74:43842 20.0.0.71:6443 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.72:50438 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.73:47090 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.72:50448 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.74:43838 20.0.0.71:6443 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.74:43862 20.0.0.71:6443 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.74:52372 20.0.0.70:6443 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.74:52380 20.0.0.70:6443 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.74:43852 20.0.0.71:6443 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.74:52394 20.0.0.70:6443 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.73:47128 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.73:47116 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.74:52358 20.0.0.70:6443 ESTABLISHED 4143/nginx: worker
tcp 0 0 20.0.0.74:52384 20.0.0.70:6443 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.73:47108 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.100:6443 20.0.0.73:47106 ESTABLISHED 4142/nginx: worker
tcp 0 0 20.0.0.74:52362 20.0.0.70:6443 ESTABLISHED 4142/nginx: worker
部署 Dashboard
在 master01 节点上操作
#上传 recommended.yaml 文件到 /opt/k8s 目录中
cd /opt/k8s
vim recommended.yaml
#默认Dashboard只能集群内部访问,修改Service为NodePort类型,暴露到外部:
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
nodePort: 30001 #添加
type: NodePort #添加
selector:
k8s-app: kubernetes-dashboard
kubectl apply -f recommended.yaml
#创建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登录Dashboard
https://20.0.0.72:30001/#/login