●Mini kube
Minikube是一个工具,可以在本地快速运行一个单节点微型K8s,仅用于学习预览K8s的一些特性使用
部署地址: https: / /kubernetes.io/docs/setup/minikube
●Kubeadmin
Kubeadmin也是一个工具,提供kubeadm init和kubeadm join,用于快速部署K8S集群,相对简单
https: / /kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
●二进制安装部署
生产首选,从官方下载发行版的二进制包,手动部署每个组件和自签TLS证书,组成K8s集群,新手推荐
https: / /github.com/kubernetes/kubernetes/releases
小结:kubeadm降低部署门槛,但屏蔽了很多细节,遇到问题很难排查,如果想更容易可控,推荐使用二进制包部署kubernetes集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。
环境准备
服务器 | 操作系统 | IP | 组件 |
---|---|---|---|
k8s集群master1 | centos7 | 192.168.100.135 | kube-apiserver kube-controller-manager kube-scheduler etcd |
k8s集群master2 | centos7 | 192.168.100.141 | kube-apiserver kube-controller-manager kube-scheduler etcd |
k8s lb01 | centos7 | 192.168.100.144 | |
k8s lb02 | centos7 | 192.168.100.145 | |
k8s集群node1 | centos7 | 192.168.100.140 | kubelet kube-proxy docker flannel |
k8s集群node2 | centos7 | 192.168.100.142 | kubelet kube-proxy docker flannel |
关闭防火墙,selinux,swap(三台机器上都要操作)
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/enforcing/disabled/' /etc/selinux/config
swapoff -a
sed -ri 's/. *swap. */#&/' /etc/fstab
在master添加hosts
cat >> /etc/hosts < 192.168.100.35 master01
> 192.168.100.142 node01
> 192.168.100.140 node02
> EOF
将桥接的IPv4流量传递到iptables的链
cat > /etc/sysctl.d/k8s.conf <net.bridge.bridge-nf-call-ip6tables = 1
>net.bridge.bridge-nf-call-iptables = 1
>net.ipv6.conf.all.disable_ipv6=1
>net.ipv4.ip_forward=1
> EOF
sysctl --system
根据规划设置主机名
hostnamectl set-hostname master01
hostnamectl set-hostname node01
hostnamectl set-hostname node02
时间同步
yum -y install ntpdate
ntpdate tim.windows.com
部署etcd集群
etcd作为服务发现系统,有以下的特点:
• 简单、安装配置简单,而且提供了HTTP API进行交互,使用也很简单
• 安全: 支持SSL证书验证
• 快速: 单实例支持每秒2k+读操作
• 可靠: 采用raft算法实现分布式系统数据的可用性和一致性
准备签发证书环境:
CFSSL是CloudFlare 公司开源的一款PKI/TLS工具。CESSL 包含一个命令行工具和一个用于签名、验证和捆绑TLS证书的HTTP API服务。使用Go语言编写。
CFSSL使用配置文件生成证书,因此自签之前,需要生成它识别的json 格式的配置文件,CFSSL 提供了方便的命令行生成配置文件。
CFSSL用来为etcd提供TLS证书,它支持签三种类型的证书:
1、client证书,服务端连接客户端时携带的证书,用于客户端验证服务端身份,如kube-apiserver 访问etcd;
2、server证书,客户端连接服务端时携带的证书,用于服务端验证客户端身份,如etcd对外提供服务:
3、peer证书,相互之间连接时使用的证书,如etcd节点之间进行验证和通信。
这里全部都使用同一套证书认证。
注:etcd这里就不做集群了,直接部署在master节点上
1.master节点部署
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/local/bin/cfssl-certinfo
chmod +x /usr/local/bin/cfssl /usr/local/bin/cfssljson /usr/local/bin/cfssl-certinfo chmod +x /usr/local/bin/cfssl
cfssl: 证书签发的工具命令
cfssljson: 将cfssl 生成的证书( json格式)变为文件承载式证书
cfssl-certinfo:验证证书的信息
cfssl-certinfo -cert <证书名称>
我这里直接就拿下载好的用了
生成Etcd证书
mkdir /opt/k8s
cd /opt/k8s
vim etcd-cert.sh
chmod +x *
mkdir etcd-cert
./etcd-cert.sh
#####################################
//etcd二进制包地址: https://github.com/etcd-io/etcd/releases
上传etcd-v3.3.10-1inux-amd64.tar.gz 到/opt/k8s/ 目录中,解压etcd 压缩包
创建用于存放etcd配置文件,命令文件,证书的目录
另外加一个终端查看etcd进程是否正常
把etcd相关证书和命令文件全部拷贝到另外两个etcd集群节点
scp -r /opt/etcd/ root@node01:/opt/
scp -r /opt/etcd/ root@node02:/opt/
把etcd服务管理文件拷贝到另外两个etcd集群节点
scp /usr/lib/systemd/system/etcd.service [email protected]:/usr/lib/systemd/system/
scp /usr/lib/systemd/system/etcd.service [email protected]:/usr/lib/systemd/system/
.在node1与node2节点修改
在node1节点修改
在node2节点修改
在node1 node2 节点启动etcd
systemctl start etcd
systemctl enable etcd.service
查看etcd集群状态
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.100.135:2379,https://192.168.100.142:2379,https://192.168.100.140:2379" endpoint health --write-out=table
查看etcd群集里的成员信息
ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.100.135:2379,https://192.168.100.142:2379,https://192.168.100.140:2379" --write-out=table member list
在master01节点操作
(1)将master.zip k8s-cert.sh 拖入 /opt/k8s 中,并对 master.zip解压
unzip master.zip
(2)给与所有以.sh结尾的文件 可执行权限
chmod +x *.sh
(3)在opt目录下创建 kubernetes组件目录
mkdir -p kubernetes/{bin,cfg,ssl,logs}
(4)在k8s 目录下创建一个 目录作为 cert 的组件目录
mkdir k8s-cert
mv k8s-cert.sh k8s-cert
(5)修改 k8s-cert.sh,并生成CA证书,相关组件的证书和私钥
vim k8s-cert.sh
./k8s-cert.sh
ls *.pem
(6)复制CA证书,apiserver相关证书和私钥到 kubernetes工作目录的ssl子目录中
cp ca*.pem apiserver*.pem /opt/kubernetes/ssl/
(7)上传 kubernetes-server-linux-amd64.tar.gz 到 /opt/k8s 目录中 并解压
tar zxvf kubernetes-server-linux-amd64.tar.gz
(8)复制master组件的关键命令文件到kubernetes工作目录的bin子目录中
cp kube-apiserver kubectl kube-controller-manager kube-scheduler /opt/kubernetes/bin/
ln -s /opt/kubernetes/bin/* /usr/local/bin/
(9)获取随机数前16个字节内容,以十六进制格式输出,并删除其中空格
#生成tocker.csv文件,按照 token序列号,用户名,UID,用户组的格式生成
head -c 16 /dev/urandom | od -An -t x | tr -d ' '
cd /opt/kubernetes/cfg/
vim token.csv
(10) 启动apiserver scheduler controller-manager
vim shceduler.sh
vim controller-manager.sh
########
apiserver.sh这个文件不需要改ip
(11) 生成kubect连接集群的kubeconfig文件
vim admin.sh
./admin.sh
(12) 进行账户授权
kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous
(13)查看master 节点信息
kubectl get cs
(14)查看版本号
kubectl version
//在所有 node 节点上操作
#创建kubernetes工作目录
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
#上传 node.zip 到 /opt 目录中,解压 node.zip 压缩包,获得kubelet.sh、proxy.sh
cd /opt/
unzip node.zip
chmod +x kubelet.sh proxy.sh
//在 master01 节点上操作
#把 kubelet、kube-proxy 拷贝到 node 节点
cd /opt/k8s/kubernetes/server/bin
scp kubelet kube-proxy [email protected]:/opt/kubernetes/bin/
scp kubelet kube-proxy [email protected]:/opt/kubernetes/bin/
#上传 kubeconfig.sh 文件到 /opt/k8s/kubeconfig 目录中,生成 kubeconfig 的配置文件
mkdir /opt/k8s/kubeconfig
cd /opt/k8s/kubeconfig
chmod +x kubeconfig.sh
./kubeconfig.sh 192.168.100.135 /opt/k8s/k8s-cert/
scp bootstrap.kubeconfig kube-proxy.kubeconfig [email protected]:/opt/kubernetes/cfg/
scp bootstrap.kubeconfig kube-proxy.kubeconfig [email protected]:/opt/kubernetes/cfg/
#RBAC授权,使用户 kubelet-bootstrap 能够有权限发起 CSR 请求
kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
//在 node01 node02 节点上操作
//所有 node 节点部署docker引擎
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
systemctl start docker.service
systemctl enable docker.service
#启动 kubelet 服务(node01)
cd /opt/
./kubelet.sh 192.168.100.142
ps aux | grep kubelet
#启动 kubelet 服务(node02)
cd /opt/
./kubelet.sh 192.168.100.140
ps aux | grep kubelet
//在 master01 节点上操作,通过 CSR 请求
#检查到 node01 节点的 kubelet 发起的 CSR 请求,Pending 表示等待集群给该节点签发证书
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE 12s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
#通过 CSR 请求
kubectl certificate approve node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE
#Approved,Issued 表示已授权 CSR 请求并签发证书
kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
node-csr-duiobEzQ0R93HsULoS9NT9JaQylMmid_nBF3Ei3NtFE 2m5s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Approved,Issued
#查看节点,由于网络插件还没有部署,节点会没有准备就绪 NotReady
kubectl get node
NAME STATUS ROLES AGE VERSION
192.168.100.142 NotReady 108s v1.20.11
//在 node01 node02 节点上操作开启ipv4模块
#加载 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.100.142
#查看群集中的节点状态
kubectl get nodes
在node 01 node02 上操作
把cni-plugins-linux-amd64-v0.8.6.tgz,flannel.tar,kube-flannel.yml 导入opt
###传入镜像
docker load -i flannel.tar
mkdir /opt/cni/bin -p
tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin/
ps aux | grep kubelet
在master节点上操作
把kube-flannel.yml导入 /opt/k8s 中
kubectl apply -f kube-flannel.yml
kubectl get node
在所有node 节点上传 coredns.tar软件包
docker load -i coredns.tar
把 coredns 配置文件上传到 master节点
kubectl apply -f coredns.yaml
查看pod运行状态
kubectl get pods -n kube-system
#DNS 解析测试
Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
K8s 中Pod网络通信:
在同一个 Pod 内的容器(Pod 内的容器是不会跨宿主机的)共享同一个网络命名空间,相当于它们在同一台机器上一样,可以用localhost地址访问彼此的端口。
每个 Pod都有一个真实的全局IP地址,同一个Node 内的不同Pod之间可以直接采用对方Pod 的IP地址进行通信,Pod1与 Pod2都是通过veth连接到同一个 docker0 网桥,网段相同,所以它们之间可以直接通信。
Pod地址与docker0在同一网段,docker0网段与宿主机网卡是两个不同的网段,且不同 Node 之间的通信只能通过宿主机的物理网卡进行.要想实现不同Ncod , Pod 之间的通信,就必须想办法通过主机的物理网卡IP地址进行寻址和通信。因此要满足两个条件: Pod 的 IP
不能冲突: 将Pod的 IP和所在的 Node的 IP关联起来,通过这个关联让不同Node 上 Pod之间直接通过内网ⅠP地址通信。
叠加网络,在二层或者三层基础网络上叠加的一种虚拟网络技术模式,该网络中的主机通过
将源数据包封装到UDP中,并使用基础网络的IP/MAC作为外层报文头进行封装,然后在以太网上传输.
到达目的地后由隧道端点解封装并将数据发送给目标地址。
Flannel的功能是让集群中的不同节点主机创建的 Docker容器都具有全集群唯一的虚拟IP地址。
Flannel 是overlay网络的一种,也是将rc 源数据包封装在另一种网络包里面进行路由转发和通信,目前支持 udp、vxlan、host-GM
3种数据转发方式。
数据从node01 .上. pod的源容器中发出后,经由所在主机的 docker0虚拟网卡转发到flannel.1虚拟网卡,flanneld 服务监听在flanel.1虚拟网卡的另外一端。
lannel通过 Etcd服务维护了一张节点间的路由表。源主机 node01的flanneld服务将原本的数据内容封装到 UDP中后根据自己的路由表通过物理网卡投递给目的节点node02的 flanneld 服务,数据到达以后被解包,然后直接进入目的节点的 flannel.1虚拟网卡,之后被转发到目的主机的 docker0虚拟网卡,最后就像本机容器通信一样由 docker0转发到目标容器。
存储管理Flannel可分配的IP地址段资源
监控ETCD中每个Pod 的实际地址,并在内存中建立维护Pod节点路由表
由于udp模式是在用户态做转发,会多一次报文隧道封装,因此性能上会比在内核态做转发的vxlan模式差。
vxlan 是一种overlay(虚拟隧道通信)技术,通过三层网络搭建虚拟的二层网络,跟udp模式具体实现不太一样:
(1) uip模式是在用户态实现的,数据会先经过tun网卡,到应用程序,应用程序再做隧道封装,再进一次内核协议找,而vslan是在内核当中实现的,只经过一次协议栈,在协议栈内就把vxlan包组装好
(2) udp模式的tun网卡是三层转发,使用tun是在物理网络之上构建三层网络,属于ip in udp,vxlan模式是二层实现,overlay是二层帧,属于mac in udp
(3) vxlan由于采用mac in udp的方式,所以实现起来会涉及mac地址学习,arp广播等二层知识,udp模式主要关注路由
vxlan在内核当中实现,当数据包使用vxlan设备发送数据时,会打上vlxan的头部信息,在发送出去,对端解包,flannel.1网卡把原始报文发送到目的服务器。
flannel方案
需要在每个节点上把发向容器的数据包进行封装后,再用隧道将封装后的数据包发送到运行着目标pod的node节点上。目标node节点再负责去掉封装,将去除封装的数据包发送到目标Pod上。数据通信性能则大受影响。
calico方案
Calico不使用隧道或NAT来实现转发,而是把Rost当作Internet中的路由器,使用BGP同步路由,并使用iptables来做安全访问策略,完成跨HOST转发来。
Calico CNI插件:主要负责与kubernetes对接,供kubelet调用使用。
Felix:负责维护宿主机上的路由规则、FIB转发信息库等。
BIRD:负责分发路由规则,类似路由器。
Confd:配置管理组件。
calico是通过路由表来维护每个pod的通信。calico 的 CNI 插件会为每个容器设置一个veth pair设备,然后把另一端接入到宿主机网络空间,由于没有网桥,CNI 插件还需要在宿主机上为每个容器的 veth pair设备配置一条路由规则,用于接收传入的IP包。
有了这样的 veth pair 设备以后,容器发出的IP包就会通过 veth pair设备到达宿主机,然后宿主机根据路由规则的下一跳地址,发送给正确的网关,然后到达目标宿主机,再到达目标容器。
这些路由规则都是Felix维护配置的,而路由信息则是calico BIRD 组件基于BGP分发而来。calico实际上是将集群里所有的节点都当做边界路由器来处理,他们一起组成了一个全互联的网络,彼此之间通过 BGP交换路由,这些节点我们叫/做BGP Peer.
目前比较常用的时flannel和lcalico,flanel的功能比较简单,不具备复杂的网络策略配置能力,calico是比较出色的网络管理插件,但具备复杂网络配置能力的同时,往往意味着本身的配置比较复杂,所以相对而言,比较小而简单的集群使用flanel,考虑到日后扩容,未来网络可能需要加入更多设备,配置更多网络策略,则使用calico更好。
master02 节点部署
####从master01 节点上拷贝证书文件,各master组件的配置文件和服务管理文件到master02 节点
在master01节点 opt目录下
scp -r etcd/ kubernetes/ [email protected]:/opt
cd /usr/lib/systemd/system
scp kube* [email protected]:`pwd`
####切换到master02,修改传过来的配置文件
vim kube-controller-manager.kubeconfig
vim kube-scheduler.kubeconfig
vim kube-apiserver
##启动apiserver
systemctl start kube-apiserver.service
systemctl enable kube-apiserver.service
##启动controller-manager
systemctl start kube-controller-manager.service
systemctl enable kube-controller-manager.service
##启动scheduler
systemctl start kube-scheduler.service
systemctl enable kube-scheduler.service
##给/opt/kubernetes/下的文件做软链接
ln -s /opt/kubernetes/bin/* /usr/local/bin/
##切换到master01 节点 将 根目录下的 .kube 文件传到 master02
scp -r .kube/ 192.168.100.141:`pwd`
##切换到master02 查看是否加入集群
kubectl get node
//配置load balancer集群双机热备负载均衡(nginx实现负载均衡,keepalived实现双机热备)
##### 在lb01、lb02节点上操作 #####
首先安装nginx
//配置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端口(在http块上面配置一个stream块)
vim /etc/nginx/nginx.conf
stream {
upstream k8s-apiserver {
server 192.168.100.135:6443;
server 192.168.100.141:6443;
}
server {
listen 6443;
proxy_pass k8s-apiserver;
}
}
http ..........
systemctl start nginx
systemctl enable nginx
netstat -natp | grep nginx
###部署keeplived服务
yum install keepalived -y
cd /etc/keepalived/
vim keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
[email protected]
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_MASTER
}
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
}
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 {
192.168.100.100
}
track_script {
check_nginx
}
}
vim check_nginx.sh
#!/bin/bash
count=$(ps -ef | grep nginx | egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
systemctl stop keepalived
fi
chmod +x check_nginx.sh
##将修改好的keeplived 和 脚本文件 传到lb02
scp check_nginx.sh keepalived.conf [email protected]:`pwd`
##切换到lb02 修改 keeplived配置文件
vim keepalived.conf
//启动keepalived服务(一定要先启动了nginx服务,再启动keepalived服务)
systemctl start keepalived
systemctl enable keepalived
ip addr
//修改node节点上的bootstrap.kubeconfig,kubelet.kubeconfig配置文件为VIP
cd /opt/kubernetes/cfg/
vim bootstrap.kubeconfig
server: https://192.168.100.100:6443
vim kubelet.kubeconfig
server: https://192.168.100.100:6443
vim kube-proxy.kubeconfig
server: https://192.168.100.100:6443
//在 lb01 上查看 nginx 和 node 、 master 节点的连接状态
netstat -natp | grep nginx
##### pod创建测试 #####
//在master01测试创建pod
kubectl run nginx --image=nginx
//在查看Pod的状态信息
kubectl get pods
kubectl get pods -o wide
//在对应网段的node节点上操作,可以直接使用浏览器或者curl命令访问
curl 172.17.36.2
//查看相关日志
Dashboard 介绍
仪表板是基于Web的Kubernetes用户界面。您可以使用仪表板将容器化应用程序部署到Kubernetes集群,对容器化应用程序进行故障排除,并管理集群本身及其伴随资源。您可以使用仪表板来概述群集上运行的应用程序,以及创建或修改单个Kubernetes资源(例如部署,作业,守护进程等)。例如,您可以使用部署向导扩展部署,启动滚动更新,重新启动Pod或部署新应用程序。仪表板还提供有关群集中Kubernetes资源状态以及可能发生的任何错误的信息。
##### 在 master01 节点上操作 #####
//在k8s工作目录中创建dashborad工作目录 把recommended.yaml导入
mkdir /opt/k8s/dashboard
cd /opt/k8s/dashboard
rz -E
##### 在 node01 node02 节点上操作 #####
这里的软件包我是直接下载拿来用的,如果直接docker pull拉取的话,会非常慢,除开挂梯子
//把 dashboard.tar metrics-scraper.tar 导入 到opt ,上传至容器
docker load -i dashboard.tar
docker load -i metrics-scraper.tar
##### 在 master01 节点上操作 #####
kubectl apply -f recommended.yaml
//查看运行情况
kubectl get pods -n kubernetes-dashboard
##创建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 secret dashboard-admin-token-pcqvs -n kube-system
##打开360浏览器或者火狐进行访问
https://192.168.100.140:30001