一.总结kube-apiserver、kube-controler-manager、kube-scheduler、kube-proxy、kubelet等各组件的功能
官方文档:https://kubernetes.io/zh-cn/docs/home/
1、kube-apiserver
KubernetesAPIserver提供了k8s各类资源对象的增删改查及watch等HTTP Rest接口,这些对象包括pods,services,replicationcontrollers等,apiserver为REST风格的网络接口,为REST操作提供服务,并为集群的共享状态提供前端,所有其他组件都通过该前端进行交互,也就是客户访问服务的接口。
该端口的默认值为6443,可以通过启动参数“–secure-port”修改默认值,默认监听IP为0.0.0.0及本机所有IP,可以通过启动参数“–bind-address”设置监听指定的内网IP,可以用来接收客户端或dashboard等外部HTTPS请求,实现基于Tocken文件或客户端证书及HTTP Base的认证,实现基于策略的账户鉴权及准入,客户端通过APIServer实现对kubernetes的API远程以实现对kubernetes内部资源的增删改查等管理任务的分发。
API的版本:
Alpha:预览版,可能包含bug或错误,后期版本会修复且不兼容之前的版本,不建议使用。
Beta:测试版,如storage.k8s.io/v1beta1,该版本可能存在不稳定或者潜在的bug,不建议生产使用。
v1/v2/vX:稳定版,如apps/v1,经过验证的stable版本,可以生产环境使用。
kubernetesAPI测试
#curl--cacert/etc/kubernetes/ssl/ca.pem-H"Authorization:Bearer${TOKEN}"https://172.31.7.101:6443
#curl127.0.0.1:6443/#返回所有的API列表
#curl127.0.0.1:6443/apis#分组API
#curl127.0.0.1:6443/api/v1#带具体版本号的API
#curl127.0.0.1:6443/version#API版本信息
#curl127.0.0.1:6443/healthz/etcd#与etcd的心跳监测
#curl127.0.0.1:6443/apis/autoscaling/v1#指定API的详细信息
#curl127.0.0.1:6443/metrics#指标数据
2、kube-scheduler
kube-scheduler是一个控制面进程,负责将pods的按照一定的调度策略指派到不同的目的节点上。通过调度算法从node列表中选择一个最合适的node,并将信息写入到etcd中,node节点上的kubelet通过API Server产生的Pod绑定信息,获取对应的Pod清单,下载镜像并启动容器。
调度策略:
阶段一:预选策略NoDiskConflict,先通过kube-scheduler内置的一些函数算法剔除掉完全不符合条件的节点。
NoDiskConflict:
Pod所需的卷是否和节点已存在的卷冲突。
PodFitsResources:
判断备选节点的资源是否满足备选Pod的需求。
PodSelectorMatches:
判断备选节点是否包含备选pod的标签选择器指定的标签
MatchInterPodAffinity:
节点亲和性筛选
PodToleratesNodeTaints
根据taints和toleration的关系判断Pod是否可以调度到节点上Pod是否满足节点容忍的一些条件。
阶段二:优选策略,通过预选策略剩下的节点中进行评分筛选,选择最优的节点产生Pod。
LeastRequestedPriority
优先从备选节点列表中选择资源消耗最小的节点(CPU+内存)。
CalculateNodeLabelPriority
优先选择含有指定Label的节点。
BalancedResourceAllocation
优先从备选节点列表中选择各项资源使用率最均衡的节点。
TaintTolerationPriority
使用Pod中tolerationList与节点Taint进行匹配并实现pod调度
3、kube-controller-manager
Kubernetes 控制器管理器是一个守护进程 , 内嵌随 Kubernetes 一起发布的核心控制回路, 控制回路是一个永不休止的循环,用于调节系统状态 。 每个控制器是一个控制回路,通过 API 服务器监视集群的共享状态, 并尝试进行更改以将当前状态转为期望状态。包括的子控制器有副本控制器,节点控制器,命名空间控制器和服务账号控制器等,作为集群内部的管理控制中心,负责集群内的Node、Pod副本,服务断点,命名空间,服务账号,资源定额。例如当某个Node意外宕机时,kube-controller-manager会及时发现并执行自动化修复流程,确保集群状态处于预期状态工作。
controller-manager的高可用机制:每5秒检查一次,收到节点心跳后将node标记为不可达,在不可达状态等待40秒后被标记为无法访问,被标记为无法访问状态后如果5分钟还没有恢复就会删除改node上的pod,并且在其他节点重新创建。
# 高可用机制
controller-manager控制器每间隔5秒检查一次节点的状态。
如果controller-manager控制器没有收到自节点的心跳,则将该node节点被标记为不可达。
controller-manager将在标记为无法访问之前等待40秒。
如果该node节点被标记为无法访问后5分钟还没有恢复,controller-manager会删除当前node节点的所有pod并在其它可用节点重建这些pod。
4、kube-proxy
Kubernetes网络代理运行在node上,它反映了node上KubernetesAPI中定义的服务,并可以通过一组后端进行简单的TCP、UDP和SCTP流转发或者在一组后端进行循环TCP、UDP和SCTP转发,用户必须使用apiserverAPI创建一个服务来配置代理,其实就是kube-proxy通过在主机上维护网络规则并执行连接转发来实现Kubernetes服务访问。
kube-proxy运行在每个节点上,监听APIServer中服务对象的变化,再通过管理IPtables或者IPVS规则来实现网络的转发。
Kube-Proxy不同的版本可支持三种工作模式:
UserSpace:k8sv1.1之前使用,k8s1.2及以后就已经淘汰
IPtables:k8s1.1版本开始支持,1.2开始为默认
IPVS:k8s1.9引入到1.11为正式版本,需要安装ipvsadm、ipset工具包和加载ip_vs内核模块
IPVS相对IPtables效率会更高一些,使用IPVS模式需要在运行Kube-Proxy的节点上安装ipvsadm、ipset工具包和加载ip_vs内核模块,当Kube-Proxy以IPVS代理模式启动时,Kube-Proxy将验证节点上是否安装了IPVS模块,如果未安装,则Kube-Proxy将回退到IPtables代理模式。
使用IPVS模式,Kube-Proxy会监视KubernetesService对象和Endpoints,调用宿主机内核Netlink接口以相应地创建IPVS规则并定期与KubernetesService对象Endpoints对象同步IPVS规则,以确保IPVS状态与期望一致,访问服务时,流量将被重定向到其中一个后端Pod,IPVS使用哈希表作为底层数据结构并在内核空间中工作,这意味着IPVS可以更快地重定向流量,并且在同步代理规则时具有更好的性能,此外,IPVS为负载均衡算法提供了更多选项,例如:rr(轮询调度)、lc(最小连接数)、dh(目标哈希)、sh(源哈希)、sed(最短期望延迟)、nq(不排队调度)等。
kubernetesv1.11之后默认使用IPVS,默认调度算法为rr。
cat/var/lib/kube-proxy/kube-proxy-config.yaml
kind:KubeProxyConfiguration
apiVersion:kubeproxy.config.k8s.io/v1alpha1
bindAddress:172.31.7.111clientConnection:
kubeconfig:"/etc/kubernetes/kube-proxy.kubeconfig"
clusterCIDR:"10.100.0.0/16"conntrack:
maxPerCore:32768
min:131072
tcpCloseWaitTimeout:1h0m0s
tcpEstablishedTimeout:24h0m0s
healthzBindAddress:172.31.7.111:10256
hostnameOverride:"172.31.7.111"
metricsBindAddress:172.31.7.111:10249
mode:"ipvs" # 指定使用ipvs及调度算法ipvs:
scheduler:sh # 使用hash调度算法
5、kubelet
kubelet 是在每个节点上运行的主要 “节点代理”。它可以使用以下方式之一向 API 服务器注册:
-
主机名(hostname);
-
覆盖主机名的参数;
-
特定于某云驱动的逻辑。
是一个通过命令行对kubernetes集群进行管理的客户端工具。kubectl在$HOME/.kube目录中查找一个名为config的配置文件。你可以通过设置KUBECONFIG环境变量或设置–kubeconfig参数来指定其它kubeconfig文件。
6、etcd
etcd是CoreOS公司开发目前是Kubernetes默认使用的key-value数据存储系统,用于保存kubernetes的所有集群数据,etcd支持分布式集群功能,生产环境使用时需要为etcd数据提供定期备份机制。etcd在生产环境最好在单独的服务器上运行,部署分布式高可用集群。
7、DNS
NS负责为整个集群提供DNS服务,从而实现服务之间的访问。
coredns
kube-dns:1.18
sky-dns
8、Dashboard
Dashboard是基于网页的Kubernetes用户界面,可以使用Dashboard获取运行在集群中的应用的概览信息,也可以创建或者修改Kubernetes资源(如Deployment,Job,DaemonSet等等),也可以对Deployment实现弹性伸缩、发起滚动升级、删除Pod或者使用向导创建新的应用。
二.基于Kubeadm在私有云部署高可用kubernetes环境
部署环境信息
主机地址 | 主机名 | 配置信息 | 作用 | linux版本 |
---|---|---|---|---|
172.18.10.100/16 | k8s-master1 | 2c2g | k8s的master1节点 | centos7.7 |
172.18.10.101/16 | k8s-master2 | 2c2g | k8s的master2节点 | centos7.7 |
172.18.10.102/16 | k8s-node1 | 2c2g | k8s的node1节点 | centos7.7 |
172.18.10.103/16 | k8s-node2 | 2c2g | k8s的node2节点 | centos7.7 |
172.18.10.104/16 | k8s-ha1 | 2c2g | HAporxy和Keepalived节点,vip:172.18.10.188 | centos7.7 |
172.18.10.105/16 | k8s-ha2 | 2c2g | HAporxy和Keepalived备份节点,vip:172.18.10.188 | centos7.7 |
1、安装HAporxy和Keepalived,配置负载均衡和高可用
[root@k8s-ha1 ~]# yum install keepalived -y
[root@k8s-ha1 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state MASTER
interface ens33
garp_master_delay 10
smtp_alert
virtual_router_id 55
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
172.18.10.188 dev ens33 label ens33:0
172.18.10.189 dev ens33 label ens33:1
172.18.10.190 dev ens33 label ens33:2
}
}
[root@k8s-ha1 ~]# systemctl restart keepalived.service
[root@k8s-ha1 ~]# systemctl enable keepalived.service
# 验证虚拟ip是否可用,正常可用即可
[root@k8s-ha2 ~]# ping 172.18.10.188
[root@k8s-ha2 ~]# yum install keepalived -y
[root@k8s-ha2 ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state MASTER
interface ens33
garp_master_delay 10
smtp_alert
virtual_router_id 55
priority 80 # 修改优先级
advert_int 1
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
172.18.10.188 dev ens33 label ens33:0
172.18.10.189 dev ens33 label ens33:1
172.18.10.190 dev ens33 label ens33:2
}
}
[root@k8s-ha2 ~]# systemctl restart keepalived.service
[root@k8s-ha2 ~]# systemctl enable keepalived.service
# 测试停掉ha1上的keepalived后ha2上是否可以看到vip
[root@k8s-ha2 ~]# ifconfig
# 停止ha1上的keepalived
[root@k8s-ha1 keepalived]# systemctl stop keepalived.service
# 再次查看ha2上的vip
# 主节点和备份节点安装haproxy做反向代理
[root@k8s-ha1 ~]# yum install -y haproxy
[root@k8s-ha1 ~]# vim /etc/haproxy/haproxy.cfg # 在配置文件末尾添加
listen k8s-api-6443
bind 172.18.10.188:6443 # 绑定的ip端口,被访问时跳转到server配置
mode tcp # 模式
server server1 172.18.10.100:6443 check inter 3s fall 3 rise 3 # 跳转到master的api server,开启检查每隔3s检查一次
server server2 172.18.10.101:6443 check inter 3s fall 3 rise 3 # 跳转到master的api server,开启检查每隔3s检查一次
[root@k8s-ha1 ~]# systemctl restart haproxy.service
[root@k8s-ha1 ~]# systemctl enable haproxy.service
# 验证k8s-ha1端口是否启动
[root@k8s-ha1 ~]# ss -tnl |grep 6443
LISTEN 0 128 172.18.10.188:6443 *:*
[root@k8s-ha2 ~]# yum install -y haproxy
# 拷贝配置文件过去
[root@k8s-ha1 ~]# scp /etc/haproxy/haproxy.cfg root@172.18.10.105:/etc/haproxy/
[root@k8s-ha2 ~]# systemctl restart haproxy.service
[root@k8s-ha2 ~]# systemctl enable haproxy.service
# 验证k8s-ha2端口是否启动
[root@k8s-ha2 ~]# ss -tnl |grep 6443
LISTEN 0 128 172.18.10.188:6443 *:*
#########################################################################
# 如果haproxy监听不到端口,可能是因为本地没有这个地址,无法绑定不存在的ip,可以设置参数进行绑定不存在的ip,执行一下操作重启haproxy即可
[root@k8s-ha1 ~]# vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
[root@k8s-ha1 ~]# sysctl -p
[root@k8s-ha1 ~]# systemctl restart haproxy.service
2、配置k8s的master和node节点部分
# master和node节点上安装containerd运行时,以下操作分别在172.10.100-103上执行
[root@k8s-master1 install]# cd /usr/local/src/
[root@k8s-master1 src]# tar -xf runtime-docker24.0.2-containerd1.6.21-binary-install.tar.gz
[root@k8s-master1 src]# bash runtime-install.sh containerd
[root@k8s-master2 install]# cd /usr/local/src/
[root@k8s-master2 src]# tar -xf runtime-docker24.0.2-containerd1.6.21-binary-install.tar.gz
[root@k8s-master2 src]# bash runtime-install.sh containerd
[root@k8s-node1 install]# cd /usr/local/src/
[root@k8s-node1 src]# tar -xf runtime-docker24.0.2-containerd1.6.21-binary-install.tar.gz
[root@k8s-node1 src]# bash runtime-install.sh containerd
[root@k8s-node2 install]# cd /usr/local/src/
[root@k8s-node2 src]# tar -xf runtime-docker24.0.2-containerd1.6.21-binary-install.tar.gz
[root@k8s-node2 src]# bash runtime-install.sh containerd
# 安装kubeadm、kubectl、kubelet,以下操作分别在172.10.100-103上执行
[root@k8s-master1 src]# 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
[root@k8s-master1 src]# yum install -y kubelet kubeadm kubectl
[root@k8s-master1 src]# systemctl enable kubelet && systemctl start kubelet
# 参数优化,以下操作分别在172.10.100-103上执行
[root@k8s-master1 src]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward=1
vm.max_map_count=262144
kernel.pid_max=4194303
fs.file-max=1000000
net.ipv4.tcp_max_tw_buckets=6000
net.netfilter.nf_conntrack_max=2097152
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness=0
# 内核模块开机挂载:
[root@k8s-master1 src]# cat /etc/modules-load.d/modules.conf
ip_vs
ip_vs_lc
ip_vs_lblc
ip_vs_lblcr
ip_vs_rr
ip_vs_wrr
ip_vs_sh
ip_vs_dh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
ip_tables
ip_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
xt_set
br_netfilter
nf_conntrack
overlay
# 各节点重启后验证内核模块与内存参数:
[root@k8s-master1 src]# reboot
[root@k8s-master1 ~]# lsmod | grep br_netfilter
br_netfilter 22256 0
bridge 151336 1 br_netfilter
[root@k8s-master1 ~]# sysctl -a | grep bridge-nf-call-iptables
net.bridge.bridge-nf-call-iptables = 1
# 集群初始化,如果使用的是docker运行时,记得将资源限制引擎更改为systemd,不要使用cgroup
# 修改containerd的资源限制引擎systemd
[root@k8s-master1 ~]# vim /etc/containerd/config.toml
125 SystemdCgroup = true
# 初始化方式,方式一,命令行方式,本实验使用的方式二,可以忽略方式一
#单master
# kubeadm init --apiserver-advertise-address=172.18.10.100 --control-plane-endpoint=172.18.10.188 --apiserver-bind-port=6443 --kubernetes-version=v1.27.4 --pod-network-cidr=10.200.0.0/16 --service-cidr=10.100.0.0/16 --service-dns-domain=cluster.local --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --ignore-preflight-errors=swap
#多master
# kubeadm init --apiserver-advertise-address=172.31.7.201 --control-plane-endpoint=172.31.7.188 --apiserver-bind-port=6443 --kubernetes-version=v1.27.4 --pod-network-cidr=10.200.0.0/16 --service-cidr=10.100.0.0/16 --service-dns-domain=cluster.local --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers --ignore-preflight-errors=swap
# --apiserver-advertise-address 指定本机ip地址
# --control-plane- endpoint 指定一个虚拟ip,如果有的话
# --apiserver-bind-port 指定端口
# --kubernetes-version 指定版本
# --pod-network-cidr pod网络
# --service-cidr service网络范围
# --service-dns-domain service的域名后缀,默认为cluster.local
# --image-repository 指定镜像仓库,在国内可以指向阿里云,默认指向官方
# --ignore-preflight-errors 忽略交换分区检查,否则会报错,不建议使用交换分区
# 推荐使用方式二进行初始化,使用文件初始化,在k8s-master1上执行
[root@k8s-master1 ~]# kubeadm config print init-defaults # 输出默认初始化配置
[root@k8s-master1 ~]# kubeadm config print init-defaults > kubeadm-init.yaml #将默认配置输出⾄⽂件
[root@k8s-master1 ~]# cat kubeadm-init.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 172.18.10.100 # 指定当前节点监听ip
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock # 1.22以及之后默认使用containerd运行时,保持默认即可,1.22之前的版本使用的docker
imagePullPolicy: IfNotPresent
name: k8s-master1 # 当前主机名称,在同一个k8s环境中主机名不能重复
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s # 超时时间
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: 172.18.10.188:6443 # 负载均衡使用的vip
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers # 镜像仓库,改为本地
kind: ClusterConfiguration
kubernetesVersion: 1.27.4
networking:
dnsDomain: cluster.local # service 域名后缀
podSubnet: 10.200.0.0/16 # pod⼦⽹范围
serviceSubnet: 10.100.0.0/16 # service⼦⽹范围
scheduler: {}
--- #指定kubelet使⽤systemd
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
--- #指定KubeProxy使⽤ipvs
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
# 两个master节点提前下载指定镜像
[root@k8s-master1:~# kubeadm config images list --kubernetes-version v1.27.4 # 查看需要的镜像
[root@k8s-master1:~# vim images-down.sh
#!/bin/bash
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.27.4
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-
manager:v1.27.4
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.27.4
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.27.4
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.7-0
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.10.1
[root@k8s-master1:~# bash images-down.sh
或:
# 两个master节点提前下载指定镜像
[root@k8s-master1 ~]# kubeadm config images pull --image-repository="registry.cn-hangzhou.aliyuncs.com/google_containers" --kubernetes-version=v1.27.4
[root@k8s-master2 ~]# kubeadm config images pull --image-repository="registry.cn-hangzhou.aliyuncs.com/google_containers" --kubernetes-version=v1.27.4
# 两个node节点拉去镜像:
[root@k8s-node1 ~]# nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.27.4
[root@k8s-node1 ~]# nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9
[root@k8s-node1 ~]# nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.7-0
[root@k8s-node1 ~]# nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.10.1
[root@k8s-node2 ~]# nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.27.4
[root@k8s-node2 ~]# nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9
[root@k8s-node2 ~]# nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.7-0
[root@k8s-node2 ~]# nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.10.1
# 初始化
[root@k8s-master1 ~]# kubeadm init --config kubeadm-init.yaml
# 如果初始化报错,关闭swap分区后重新执行初始化命令,
# 报错信息:[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-master1 ~]# swapoff -a
[root@k8s-master1 ~]# swapon -s
[root@k8s-master1 ~]# kubeadm reset
[root@k8s-master1 ~]# kubeadm init --config kubeadm-init.yaml
# 出现以下界面则表示成功
# 使用集群前,执行提示的命令
[root@k8s-master1 ~]# mkdir -p $HOME/.kube
[root@k8s-master1 ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-master1 ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 执行集群命令
[root@k8s-master1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master1 Ready control-plane 6m48s v1.27.4
# 添加node节点
[root@k8s-node1 ~]# kubeadm join 172.18.10.188:6443 --token abcdef.0123456789abcdef \
> --discovery-token-ca-cert-hash sha256:3a43e1a8270b51a6cccb7446601051a636a195572414d8330dbc292c6728b374
[root@k8s-node2 ~]# kubeadm join 172.18.10.188:6443 --token abcdef.0123456789abcdef \
> --discovery-token-ca-cert-hash sha256:3a43e1a8270b51a6cccb7446601051a636a195572414d8330dbc292c6728b374
# 添加master节点
[root@docker-master1 ~]# kubeadm init phase upload-certs --upload-certs
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
c6cea574878bd6b1ee083b935a8608f1e9f9d8acb2e7c981b984cf1a29322c96
[root@k8s-master2 ~]# kubeadm join 172.18.10.188:6443 --token abcdef.0123456789abcdef \
> --discovery-token-ca-cert-hash sha256:3a43e1a8270b51a6cccb7446601051a636a195572414d8330dbc292c6728b374 \
> --control-plane --certificate-key c6cea574878bd6b1ee083b935a8608f1e9f9d8acb2e7c981b984cf1a29322c96
三.部署网络组件calico或flannel(上课有提供yaml文件)
# 部署calico网络组件
# 上传yaml文件
[root@k8s-master1 ~]# ll calico3.26.1-ipip_ubuntu2204-k8s-1.27.x.yaml
-rw-rw-rw- 1 root root 245781 7月 30 21:09 calico3.26.1-ipip_ubuntu2204-k8s-1.27.x.yaml
# 如果网卡不是eth0记得修改yaml文件中的网卡名
[root@k8s-master1 ~]# vim calico3.26.1-ipip_ubuntu2204-k8s-1.27.x.yaml # 如果pod地址范围不一样记得修改
- name: CALICO_IPV4POOL_CIDR
value: "10.200.0.0/16"
[root@k8s-master1 ~]# kubectl apply -f calico3.26.1-ipip_ubuntu2204-k8s-1.27.x.yaml
# 如果calico可以尝试指定网卡:kubectl set env daemonset/calico-node -n kube-system IP_AUTODETECTION_METHOD=interface=ens33,ens*
四.总结nginx的yaml文件的编写
# pwd
/opt/k8s-data/yaml/linux36
# mkdir nginx tomcat-app1 tomcat-app2
# cd nginx/
# pwd
/opt/k8s-data/yaml/linux36/nginx
# cat nginx.yaml
kind: Deployment #类型,是deployment控制器,kubectl explain Deployment
apiVersion: extensions/v1beta1 #API版本,# kubectl explain Deployment.apiVersion
metadata: #pod的元数据信息,kubectl explain Deployment.metadata
labels: #自定义pod的标签,# kubectl explain Deployment.metadata.labels
app: linux36-nginx-deployment-label #标签名称为app值为linux36-nginx-deployment-label,后面会用到此标签
name: linux36-nginx-deployment #pod的名称
namespace: linux36 #pod的namespace,默认是defaule
spec: #定义deployment中容器的详细信息,kubectl explain Deployment.spec
replicas: 1 #创建出的pod的副本数,即多少个pod,默认值为1
selector: #定义标签选择器
matchLabels: #定义匹配的标签,必须要设置
app: linux36-nginx-selector #匹配的目标标签,
template: #定义模板,必须定义,模板是起到描述要创建的pod的作用
metadata: #定义模板元数据
labels: #定义模板label,Deployment.spec.template.metadata.labels
app: linux36-nginx-selector #定义标签,等于Deployment.spec.selector.matchLabels
spec: #定义pod信息
containers:#定义pod中容器列表,可以多个至少一个,pod不能动态增减容器
- name: linux36-nginx-container #容器名称
image: harbor.magedu.net/linux36/nginx-web1:v1 #镜像地址
#command: ["/apps/tomcat/bin/run_tomcat.sh"] #容器启动执行的命令或脚本
#imagePullPolicy: IfNotPresent
imagePullPolicy: Always #拉取镜像策略
ports: #定义容器端口列表
- containerPort: 80 #定义一个端口
protocol: TCP #端口协议
name: http #端口名称
- containerPort: 443 #定义一个端口
protocol: TCP #端口协议
name: https #端口名称
env: #配置环境变量
- name: "password" #变量名称。必须要用引号引起来
value: "123456" #当前变量的值
- name: "age" #另一个变量名称
value: "18" #另一个变量的值
resources: #对资源的请求设置和限制设置
limits: #资源限制设置,上限
cpu: 500m #cpu的限制,单位为core数,可以写0.5或者500m等CPU压缩值
memory: 2Gi #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置
cpu: 200m #cpu请求数,容器启动的初始可用数量,可以写0.5或者500m等CPU压缩值
memory: 512Mi #内存请求大小,容器启动的初始可用数量,用于调度pod时候使用
---
kind: Service #类型为service
apiVersion: v1 #service API版本, service.apiVersion
metadata: #定义service元数据,service.metadata
labels: #自定义标签,service.metadata.labels
app: linux36-nginx #定义service标签的内容
name: linux36-nginx-spec #定义service的名称,此名称会被DNS解析
namespace: linux36 #该service隶属于的namespaces名称,即把service创建到哪个namespace里面
spec: #定义service的详细信息,service.spec
type: NodePort #service的类型,定义服务的访问方式,默认为ClusterIP, service.spec.type
ports: #定义访问端口, service.spec.ports
- name: http #定义一个端口名称
port: 80 #service 80端口
protocol: TCP #协议类型
targetPort: 80 #目标pod的端口
nodePort: 30001 #node节点暴露的端口
- name: https #SSL 端口
port: 443 #service 443端口
protocol: TCP #端口协议
targetPort: 443 #目标pod端口
nodePort: 30043 #node节点暴露的SSL端口
selector: #service的标签选择器,定义要访问的目标pod
app: linux36-nginx #将流量路到选择的pod上,须等于Deployment.spec.selector.matchLabels
五.公有创建Kubernetes集群
1、创建私有网络,一个nat子网,一个云主机子网
子网信息
2、创建nat网关,NAT网关不能和云主机再一个子网
3、配置子网路由使用nat网关
4、新建路由表使用nat网关,用于内网主机通过nat网关连接外网使用。
配置路由策略
关联子网
5、创建云主机验证通信
验证主机和公网通信
6、创建负载均衡
添加监听
验证后端服务状态
7、集群初始化
以下命令再master和node节点上均执行,以master为例
# 参数优化
root@k8s-master:~# vim /etc/sysctl.conf
net.ipv4.ip_forward=1
vm.max_map_count=262144
kernel.pid_max=4194303
fs.file-max=1000000
net.ipv4.tcp_max_tw_buckets=6000
net.netfilter.nf_conntrack_max=2097152
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
vm.swappiness=0
root@k8s-master:~# cat /etc/modules-load.d/modules.conf
ip_vs
ip_vs_lc
ip_vs_lblc
ip_vs_lblcr
ip_vs_rr
ip_vs_wrr
ip_vs_sh
ip_vs_dh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
ip_tables
ip_set
ipt_set
ipt_rpfilter
ipt_REJ
ipip
br_netfilter
overlay
# 重启后验证
root@k8s-master:~# lsmod | grep br_netfilter
br_netfilter 28672 0
bridge 172032 1 br_netfilter
root@k8s-master:~# sysctl -a | grep bridge-nf-call-iptables
net.bridge.bridge-nf-call-iptables = 1
# 格式化磁盘挂载
root@k8s-master:~# fdisk /dev/vdb
root@k8s-master:~# mkfs.xfs /dev/vdb1
root@k8s-master:~# mkdir -p /var/lib/containerd
root@k8s-master:~# vim /etc/fstab # 挂载以下添加条目
/dev/vdb1 /var/lib/containerd xfs defaults,_netdev 0 0
root@k8s-master:~# mount -a
root@k8s-master:~# df -h
root@k8s-master:~# cd /usr/local/src/
root@k8s-master:/usr/local/src# wget http://118.89.124.114/zxw.tar.gz # 下载containerd安装脚本
root@k8s-master:/usr/local/src# tar -xf zxw.tar.gz
root@k8s-master:/usr/local/src# bash runtime-install.sh containerd
root@k8s-master:~# apt-get update && apt-get install -y apt-transport-https -y
root@k8s-master:~# curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg |apt-key add -
root@k8s-master:~# cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
root@k8s-master:~# apt-get update && apt-cache madison kubeadm
root@k8s-master:~# apt-get install -y kubeadm=1.27.2-00 kubectl=1.27.2-00 kubelet=1.27.2-00
下载镜像
# 查看所需镜像
root@k8s-master:~# kubeadm config images list --kubernetes-version v1.27.2
# 下载镜像
root@k8s-master:~# cat images-down.sh
#!/bin/bash
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.27.2
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-controller-manager:v1.27.2
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-scheduler:v1.27.2
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy:v1.27.2
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.7-0
nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:v1.10.1
root@k8s-master:~# bash images-down.sh
执行kubernets集群初始化
root@k8s-master:~# vim kubeadm-init.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 10.2.0.7 # master ip
bindPort: 6443
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
imagePullPolicy: IfNotPresent
name: k8s.cnlogs.com
taints: null
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers # 替换国内镜像地址
kind: ClusterConfiguration
kubernetesVersion: 1.27.0
networking:
dnsDomain: cluster.local
podSubnet: 10.200.0.0/16
serviceSubnet: 10.100.0.0/16
scheduler: {}
--- # 指定kubelet使用systemd
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
--- # 指定kubeProxy使用ipvs
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
# 使用文件方式初始化集群
root@k8s-master:~# kubeadm init --config kubeadm-init.yaml
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 10.2.0.11:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1f51a1dbc03248807524cef9c9674314768529fd3d8aa671fa636d3834cc50b4
root@k8s-master:~# mkdir -p $HOME/.kube
root@k8s-master:~# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
root@k8s-master:~# chown $(id -u):$(id -g) $HOME/.kube/config
root@k8s-master:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s.cnlogs.com NotReady control-plane 2m5s v1.27.4
# 添加node节点
root@k8s-node1:~# kubeadm join 10.2.0.11:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1f51a1dbc03248807524cef9c9674314768529fd3d8aa671fa636d3834cc50b4
root@k8s-node2:~# kubeadm join 10.2.0.11:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1f51a1dbc03248807524cef9c9674314768529fd3d8aa671fa636d3834cc50b4
root@k8s-master:~# kubectl apply -f kube-flannel-2023.yml
root@k8s-master:~# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-node1 Ready <none> 23m v1.27.4
k8s-node2 Ready <none> 22m v1.27.4
k8s.cnlogs.com Ready control-plane 27m v1.27.4
六.公有云Kubernetes部署web服务、并通过SLB进行服务的访问(本次使用本地环境部署)
[root@k8s-master1 ~]# kubectl apply -f myserver-namespace.yaml
namespace/myserver created
[root@k8s-master1 ~]# kubectl apply -f nginx.yaml
deployment.apps/myserver-nginx-deployment created
service/myserver-nginx-service created
[root@k8s-master1 ~]# kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.100.0.1 <none> 443/TCP 2d2h
kube-system kube-dns ClusterIP 10.100.0.10 <none> 53/UDP,53/TCP,9153/TCP 2d2h
myserver myserver-nginx-service NodePort 10.100.10.67 <none> 80:30004/TCP,443:30443/TCP 3m6s
[root@k8s-master1 ~]# curl 172.18.10.100:30004