K8S

K8S
Noah序号 主机名 IP 地址 角色 系统版本 硬件配置
1 k8s-master 192.168.92.141 管理节点 centos7 2CPU/4G 内存/30G 存储
2 k8s-node1 192.168.92.142 工作节点 centos7 2CPU/4G 内存/30G 存储
3 k8s-node2 192.168.92.143 工作节点 centos7 2CPU/4G 内存/30G 存储
kubernetes
一.K8S 介绍及部署
1.Kubernetes 介绍
Kubernetes 是一个开源的容器编排引擎,用来对容器化应用进行自动化部署、 扩缩和管理。该项目托管在 CNCF。
Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。
Google 在 2014 年开源了 Kubernetes 项目。
2.k8s 组件介绍 3.主机硬件配置说明 4.主机名配置 5.主机名与 IP 地址解析
apiserver:所有服务访问统一入口
CrontrollerManager:维持副本期望数目
Scheduler:选择合适的节点进行分配任务
ETCD:存储 k8s 集群所有重要信息
kubectl:用来与集群通信的命令行工具
Kubelet:和容器交互
kubeadm:用来初始化集群的指令。
kube-proxy:负责写入规则,实现服务映射
coredns:创建集群中域名 ip 对应关系解析
dashboard:提供 B/S 结构访问体系
ingress:提供七层代理
federation:提供一个人可以跨集群中心多 k8s 统一管理功能
prometheus:提供 k8s 集群监控能力
hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2 6.安装工具依赖包 7.关闭 selinux 8.关闭 swap 分区
kubernetes 要求必须关闭 swap 分区 9.主机系统时间同步 10.内核升级
升级原因:CentOS 7.x 系统自带的 3.10.x 内核存在一些 Bugs,导致运行的 Docker、Kubernetes 不稳定,配置后重
启电脑。
11.k8s 内核优化
转发 IPv4 并让 iptables 看到桥接流量,
cat >> /etc/hosts << EOF
192.168.92.141 k8s-master
192.168.92.142 k8s-node1
192.168.92.143 k8s-node2
EOF
yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
vim net-tools git lrzsz
setenforce 0
sed -ri ‘s/SELINUX=enforcing/SELINUX=disabled/g’ /etc/selinux/config
swapoff -a && sed -ri ‘s/.swap./#&/‘ /etc/fstab
安装软件
yum -y install ntpdate
制定时间同步计划任务
crontab -e
0 _/1 _ * * ntpdate time1.aliyun.com #查看内核版本
[root@localhost ~]# uname -r
3.10.0-1062.el7.x86_64 #下载
yum -y install http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm #安装
yum –enablerepo=elrepo-kernel install -y kernel-lt #设置内核
grub2-set-default ‘CentOS Linux (5.4.251-1.el7.elrepo.x86_64) 7 (Core)’
cat <
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 131072
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF #执行
sysctl –system
应用 sysctl 参数而不重新启动
modprobe bridge #如果上一条命令报错可尝试使用本命令修复之后再使用 sysctl 命令加载配置 #内核参数说明
net.ipv4.ip_forward = 1 #其值为 0,说明禁止进行 IP 转发;如果是 1,则说明 IP 转发功能已经打开。
net.bridge.bridge-nf-call-iptables = 1 #二层的网桥在转发包时也会被 iptables 的 FORWARD 规则所过滤,这样
有时会出现 L3 层的 iptables rules 去过滤 L2 的帧的问题
net.bridge.bridge-nf-call-ip6tables = 1 #是否在 ip6tables 链中过滤 IPv6 包
fs.may_detach_mounts = 1 #当系统有容器运行时,需要设置为 1
vm.overcommit_memory=1
#0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,
并把错误返回给应用进程。
#1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
#2, 表示内核允许分配超过所有物理内存和交换空间总和的内存
vm.panic_on_oom=0
#OOM 就是 out of memory 的缩写,遇到内存耗尽、无法分配的状况。kernel 面对 OOM 的时候,咱们也不能慌乱,要根据 OOM
参数来进行相应的处理。 #值为 0:内存不足时,启动 OOM killer。 #值为 1:内存不足时,有可能会触发 kernel panic(系统重启),也有可能启动 OOM killer。 #值为 2:内存不足时,表示强制触发 kernel panic,内核崩溃 GG(系统重启)。
fs.inotify.max_user_watches=89100 #表示同一用户同时可以添加的 watch 数目(watch 一般是针对目录,决定了同
时同一用户可以监控的目录数量)
fs.file-max=52706963 #所有进程最大的文件数
fs.nr_open=52706963 #单个进程可分配的最大文件数
net.netfilter.nf_conntrack_max=2310720 #连接跟踪表的大小,建议根据内存计算该值 CONNTRACK_MAX =
RAMSIZE (in bytes) / 16384 / (x / 32),并满足 nf_conntrack_max=4nf_conntrack_buckets,默认
262144
net.ipv4.tcp_keepalive_time = 600 #KeepAlive 的空闲时长,或者说每次正常发送心跳的周期,默认值为
7200s(2 小时)
net.ipv4.tcp_keepalive_probes = 3 #在 tcp_keepalive_time 之后,没有接收到对方确认,继续发送保活探测包次
数,默认值为 9(次)
net.ipv4.tcp_keepalive_intvl =15 #KeepAlive 探测包的发送间隔,默认值为 75s
net.ipv4.tcp_max_tw_buckets = 36000 #Nginx 之类的中间代理一定要关注这个值,因为它对你的系统起到一个保护
的作用,一旦端口全部被占用,服务就异常了。 tcp_max_tw_buckets 能帮你降低这种情况的发生概率,争取补救时间。
net.ipv4.tcp_tw_reuse = 1 #只对客户端起作用,开启后客户端在 1s 内回收
net.ipv4.tcp_max_orphans = 327680 #这个值表示系统所能处理不属于任何进程的 socket 数量,当我们需要快速建立
大量连接时,就需要关注下这个值了。
net.ipv4.tcp_orphan_retries = 3 #出现大量 fin-wait-1 #首先,fin 发送之后,有可能会丢弃,那么发送多少次这样的 fin 包呢?fin 包的重传,也会采用退避方式,在 2.6.358 内核
中采用的是指数退避,2s,4s,最后的重试次数是由 tcp_orphan_retries 来限制的。
net.ipv4.tcp_syncookies = 1 #tcp_syncookies 是一个开关,是否打开 SYN Cookie 功能,该功能可以防止部分 SYN
攻击。tcp_synack_retries 和 tcp_syn_retries 定义 SYN 的重试次数。
net.ipv4.tcp_max_syn_backlog = 16384 #进入 SYN 包的最大请求队列.默认 1024.对重负载服务器,增加该值显然有好
处.
net.ipv4.ip_conntrack_max = 65536 #表明系统将对最大跟踪的 TCP 连接数限制默认为 65536
net.ipv4.tcp_max_syn_backlog = 16384 #指定所能接受 SYN 同步包的最大客户端数量,即半连接上限;
net.ipv4.tcp_timestamps = 0 #在使用 iptables 做 nat 时,发现内网机器 ping 某个域名 ping 的通,而使用
curl 测试不通, 原来是 net.ipv4.tcp_timestamps 设置了为 1 ,即启用时间戳
net.core.somaxconn = 16384 #Linux 中的一个 kernel 参数,表示 socket 监听(listen)的 backlog 上限。什么是
backlog 呢?backlog 就是 socket 的监听队列,当一个请求(request)尚未被处理或建立时,他会进入 backlog。而
socket server 可以一次性处理 backlog 中的所有请求,处理后的请求不再位于监听队列中。当 server 处理请求较慢,以至
于监听队列被填满后,新来的请求会被拒绝。 12.安装 docker #安装 docker 需要的工具
yum install -y yum-utils #配置镜像仓库
yum-config-manager
–add-repo
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #安装
yum -y install docker-ce-20.10. docker-ce-cli-20.10.* containerd.io #启动
systemctl enable docker && systemctl start docker #修改 docker 配置(所有节点)
kubernetes 官方推荐 docker 等使用 systemd 作为 cgroupdriver,否则 kubelet 启动不了
mkdir /etc/docker
cat <
{
“exec-opts”: [“native.cgroupdriver=systemd”],
“registry-mirrors”: [“https://ud6340vz.mirror.aliyuncs.com"]
}
EOF
重启生效
systemctl daemon-reload
systemctl restart docker
13.k8s 部署 1.配置 k8s 阿里源
cat <
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF 2.配置 ipvs 功能
在 kubernetes 中 Service 有两种代理模式,一种是基于 iptables 的,一种是基于 ipvs,两者对比 ipvs 负载均衡算法更加
的灵活,且带有健康检查的功能,如果想要使用 ipvs 模式,需要手动载入 ipvs 模块 #模块加载
modprobe br_netfilter #创建 /etc/modules-load.d/ipvs.conf 并加入以下内容:
cat >/etc/modules-load.d/ipvs.conf <<EOF
ip_vs
ip_vs_lc
ip_vs_wlc
ip_vs_rr
ip_vs_wrr
ip_vs_lblc
ip_vs_lblcr
ip_vs_dh
ip_vs_sh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
ip_vs_sh
nf_conntrack #内核小于 4.18,把这行改成 nf_conntrack_ipv4
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF #加载 containerd 相关内核模块
cat > /etc/modules-load.d/kunenetes.conf << EOF
overlay
br_netfilter
EOF #然后执行
systemctl enable –now systemd-modules-load.service #所有节点配置完内核后,重启服务器,保证重启后内核依旧加载
reboot -h now #重启后查看 ipvs 模块加载情况:
lsmod | grep –color=auto -e ip_vs -e nf_conntrack #重启后查看 containerd 相关模块加载情况:
lsmod | egrep ‘br_netfilter | overlay’ 3.安装 kubeadm、kubectl 和 kubelet #指定版本安装
yum install -y kubelet-1.22.10 kubectl-1.22.10 kubeadm-1.22.10 #启动
systemctl enable kubelet && systemctl start kubelet 4.初始化主节点(仅在主节点跑) #生成配置文件
kubeadm config print init-defaults > kubeadm-config.yaml #修改配置文件
修改内容如下:
第 12 行配置主节点 IP 地址 advertiseAddress: 192.168.92.141
第 17 行修改 name: k8s-master
第 30 行修改 imageRepository: registry.aliyuncs.com/google_containers
第 34 行修改版本为 v.1.15.1
第 37 行新增 podSubnet: “10.244.0.0/16”
并在尾末加入下方配置:
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs #初始化安装
kubeadm init –config=kubeadm-config.yaml –upload-certs | tee kubeadm-init.log #根据日志提供执行以下操作为 kebuctl 提供
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubeadm-config.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: 192.168.180.11#这个地址需要修改为 master 节点地址
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
imagePullPolicy: IfNotPresent
name: k8s-master#需要和 master 的 hostname 匹配,否则会报错
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.aliyuncs.com/google_containers#修改为阿里云仓库,否则拉不下来镜像
kind: ClusterConfiguration
kubernetesVersion: v1.22.10#版本需要对应好,否则可能有兼容性问题
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16 #指定 pod 子网
serviceSubnet: 10.96.0.0/12#指定 svc 子网
scheduler: {}
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs 5.安装网络插件
kubernetes 网络插件有很多,比如 flannel、calico 等等,具体区别可以自行查询,本次我选用的是 calico,网络插件需
安装否则 node 是 NotReady 状态(主节点跑) #下载部署 Calicos’s
curl -O https://docs.tigera.io/archive/v3.25/manifests/calico.yaml #修改文件 vim calico
3683 - name: CALICOIPV4POOL_CIDR
3684 value: “10.244.0.0/16” #应用文件
kubectl apply -f calico.yaml
以下代表安装成功
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane,master 9h v1.22.10
k8s-node1 Ready
k8s-node2 Ready
############
[root@k8s-master ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-68d86f8988-p6fjr 1/1 Running 0 (4m1s ago) 17m
序号 主机名 IP 地址 角色 系统版本 硬件配置
1 k8s-master 192.168.134.10 管理节点 centos7 2CPU/4G 内存/30G 存储
2 k8s-node1 192.168.134.11 工作节点 centos7 2CPU/4G 内存/30G 存储
3 k8s-node2 192.168.134.12 工作节点 centos7 2CPU/4G 内存/30G 存储
calico-node-fbgvw 1/1 Running 0 17m
calico-node-n7nzd 1/1 Running 0 (8m37s ago) 17m
calico-node-rjfdl 1/1 Running 0 (8m35s ago) 17m
coredns-7f6cbbb7b8-7md2b 1/1 Running 0 (8m32s ago) 9h
coredns-7f6cbbb7b8-fccb2 1/1 Running 0 (8m32s ago) 9h
etcd-k8s-master 1/1 Running 0 (8m37s ago) 9h
kube-apiserver-k8s-master 1/1 Running 0 (8m35s ago) 9h
kube-controller-manager-k8s-master 1/1 Running 0 (8m38s ago) 9h
kube-proxy-2sz87 1/1 Running 0 (8m37s ago) 9h
kube-proxy-fb4dj 1/1 Running 0 (8m35s ago) 9h
kube-proxy-v72c2 1/1 Running 0 (8m37s ago) 9h
kube-scheduler-k8s-master 1/1 Running 0 (8m37s ago) 9h
二、K8S 介绍及前置配置
1.Kubernetes 介绍
Kubernetes 是一个开源的容器编排引擎,用来对容器化应用进行自动化部署、 扩缩和管理。该项目托管在 CNCF。
Kubernetes 这个名字源于希腊语,意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。
Google 在 2014 年开源了 Kubernetes 项目。
2.k8s 组件介绍
apiserver:所有服务访问统一入口
CrontrollerManager:维持副本期望数目
Scheduler:选择合适的节点进行分配任务
ETCD:存储 k8s 集群所有重要信息
kubectl:用来与集群通信的命令行工具
Kubelet:和容器交互
kubeadm:用来初始化集群的指令。
kube-proxy:负责写入规则,实现服务映射
coredns:创建集群中域名 ip 对应关系解析
dashboard:提供 B/S 结构访问体系
ingress:提供七层代理
federation:提供一个人可以跨集群中心多 k8s 统一管理功能
prometheus:提供 k8s 集群监控能力 3.主机硬件配置说明 4.主机名配置
hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-node1
hostnamectl set-hostname k8s-node2 5.主机名与 IP 地址解析
cat >> /etc/hosts << EOF
192.168.134.10 k8s-master
192.168.134.11 k8s-node1
192.168.134.12 k8s-node2
EOF 6.安装工具依赖包
yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget
vim net-tools git lrzsz 7.关闭 selinux
setenforce 0
sed -ri ‘s/SELINUX=enforcing/SELINUX=disabled/g’ /etc/selinux/config 8.关闭 swap 分区
kubernetes 要求必须关闭 swap 分区
swapoff -a && sed -ri ‘s/._swap.
安装软件
yum -y install ntpdate
制定时间同步计划任务
crontab -e
0 _/1 _ * * ntpdate time1.aliyun.com 10.内核升级
升级原因:CentOS 7.x 系统自带的 3.10.x 内核存在一些 Bugs,导致运行的 Docker、Kubernetes 不稳定,配置后重
启电脑。 #查看内核版本
[root@localhost ~]# uname -r
3.10.0-1062.el7.x86_64 #下载
yum -y install http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm #安装
yum –enablerepo=elrepo-kernel install -y kernel-lt #设置内核
grub2-set-default ‘CentOS Linux (5.4.259-1.el7.elrepo.x86_64) 7 (Core)’
11.k8s 内核优化
转发 IPv4 并让 iptables 看到桥接流量,
cat <
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.swappiness=0
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.netfilter.nf_conntrack_max=2310720
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 131072
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF #执行
sysctl –system
应用 sysctl 参数而不重新启动
modprobe bridge #如果上一条命令报错可尝试使用本命令修复之后再使用 sysctl 命令加载配置 #内核参数说明
net.ipv4.ip_forward = 1 #其值为 0,说明禁止进行 IP 转发;如果是 1,则说明 IP 转发功能已经打开。
net.bridge.bridge-nf-call-iptables = 1 #二层的网桥在转发包时也会被 iptables 的 FORWARD 规则所过滤,这样
有时会出现 L3 层的 iptables rules 去过滤 L2 的帧的问题
net.bridge.bridge-nf-call-ip6tables = 1 #是否在 ip6tables 链中过滤 IPv6 包
fs.may_detach_mounts = 1 #当系统有容器运行时,需要设置为 1
vm.overcommit_memory=1
#0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,
并把错误返回给应用进程。
#1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
#2, 表示内核允许分配超过所有物理内存和交换空间总和的内存
vm.panic_on_oom=0
#OOM 就是 out of memory 的缩写,遇到内存耗尽、无法分配的状况。kernel 面对 OOM 的时候,咱们也不能慌乱,要根据 OOM
参数来进行相应的处理。 #值为 0:内存不足时,启动 OOM killer。 #值为 1:内存不足时,有可能会触发 kernel panic(系统重启),也有可能启动 OOM killer。 #值为 2:内存不足时,表示强制触发 kernel panic,内核崩溃 GG(系统重启)。
fs.inotify.max_user_watches=89100 #表示同一用户同时可以添加的 watch 数目(watch 一般是针对目录,决定了同
时同一用户可以监控的目录数量)
fs.file-max=52706963 #所有进程最大的文件数
fs.nr_open=52706963 #单个进程可分配的最大文件数
net.netfilter.nf_conntrack_max=2310720 #连接跟踪表的大小,建议根据内存计算该值 CONNTRACK_MAX =
RAMSIZE (in bytes) / 16384 / (x / 32),并满足 nf_conntrack_max=4nf_conntrack_buckets,默认
262144
net.ipv4.tcp_keepalive_time = 600 #KeepAlive 的空闲时长,或者说每次正常发送心跳的周期,默认值为
7200s(2 小时)
net.ipv4.tcp_keepalive_probes = 3 #在 tcp_keepalive_time 之后,没有接收到对方确认,继续发送保活探测包次
数,默认值为 9(次)
net.ipv4.tcp_keepalive_intvl =15 #KeepAlive 探测包的发送间隔,默认值为 75s
net.ipv4.tcp_max_tw_buckets = 36000 #Nginx 之类的中间代理一定要关注这个值,因为它对你的系统起到一个保护
的作用,一旦端口全部被占用,服务就异常了。 tcp_max_tw_buckets 能帮你降低这种情况的发生概率,争取补救时间。
net.ipv4.tcp_tw_reuse = 1 #只对客户端起作用,开启后客户端在 1s 内回收
net.ipv4.tcp_max_orphans = 327680 #这个值表示系统所能处理不属于任何进程的 socket 数量,当我们需要快速建立
大量连接时,就需要关注下这个值了。
net.ipv4.tcp_orphan_retries = 3 #出现大量 fin-wait-1 #首先,fin 发送之后,有可能会丢弃,那么发送多少次这样的 fin 包呢?fin 包的重传,也会采用退避方式,在 2.6.358 内核
中采用的是指数退避,2s,4s,最后的重试次数是由 tcp_orphan_retries 来限制的。
net.ipv4.tcp_syncookies = 1 #tcp_syncookies 是一个开关,是否打开 SYN Cookie 功能,该功能可以防止部分 SYN
攻击。tcp_synack_retries 和 tcp_syn_retries 定义 SYN 的重试次数。
net.ipv4.tcp_max_syn_backlog = 16384 #进入 SYN 包的最大请求队列.默认 1024.对重负载服务器,增加该值显然有好
处.
net.ipv4.ip_conntrack_max = 65536 #表明系统将对最大跟踪的 TCP 连接数限制默认为 65536
net.ipv4.tcp_max_syn_backlog = 16384 #指定所能接受 SYN 同步包的最大客户端数量,即半连接上限;
net.ipv4.tcp_timestamps = 0 #在使用 iptables 做 nat 时,发现内网机器 ping 某个域名 ping 的通,而使用
curl 测试不通, 原来是 net.ipv4.tcp_timestamps 设置了为 1 ,即启用时间戳
net.core.somaxconn = 16384 #Linux 中的一个 kernel 参数,表示 socket 监听(listen)的 backlog 上限。什么是
backlog 呢?backlog 就是 socket 的监听队列,当一个请求(request)尚未被处理或建立时,他会进入 backlog。而
socket server 可以一次性处理 backlog 中的所有请求,处理后的请求不再位于监听队列中。当 server 处理请求较慢,以至
于监听队列被填满后,新来的请求会被拒绝。 12.安装 docker #安装 docker 需要的工具
yum install -y yum-utils #配置镜像仓库
yum-config-manager
–add-repo
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #安装
yum -y install docker-ce-20.10. docker-ce-cli-20.10.* containerd.io #启动
systemctl enable docker && systemctl start docker #修改 docker 配置(所有节点)
kubernetes 官方推荐 docker 等使用 systemd 作为 cgroupdriver,否则 kubelet 启动不了
mkdir /etc/docker
cat <
{
“exec-opts”: [“native.cgroupdriver=systemd”],
“registry-mirrors”: [“https://ud6340vz.mirror.aliyuncs.com"]
}
EOF
重启生效
systemctl daemon-reload
systemctl restart docker
k8s 二进制部署 1.部署 Etcd 集群
使⽤ cfssl 来⽣成⾃签证书,任何机器都⾏,证书这块⼉知道怎么⽣成、怎么⽤即可,暂且不⽤过多研究 (这个证书随
便在那台机器⽣成都可以。哪⾥⽤将证书拷⻉到哪⾥就可以了。) 1.下载 cfssl ⼯具 #创建一个文件夹,用来下载工具
mkdir -p /opt/soft/cfssl && cd /opt/soft/cfssl #下载 cfssl*linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 #下载 cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 #下载 cfssl-certinfo_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 #将下载的证书添加一个可执行权限
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64 #移动证书
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo 2.⽣成 Etcd 证书 #创建文件夹
mkdir -p /opt/soft/cert && cd /opt/soft/cert #配置 ca-csr.json 证书请求文件
cat > ca-csr.json <<”EOF”
{
“CN”: “kubernetes”,
“key”: {
“algo”: “rsa”,
“size”: 2048
},
“names”: [
{
“C”: “CN”,
“ST”: “CQ”,
“L”: “CQ”,
“O”: “kubemsb”,
“OU”: “CN”
}
],
“ca”: {
“expiry”: “87600h”
}
}
EOF
/*
说明
CN: COMMON NAME , 及名称,对于 ssl 证书,这里一般是网站域名, 而这里是签发的 CA 根证书,所以随便写都行。
Key:用于配置证书加密算法
Names: 用于配置企业信息,分别为: C:国家 ST:省。 L:所在地。 O:单位 OU:组织, 除此之外还有:E: 邮箱。
G: 其它姓名。 介绍: ,Phone:格式要求 + 国家区号 城市区号 电话号码,如: +86 732 88888888
,STREET: ,PostalCode 等。
_/ #配置 ca-config.json 证书策略
cat > ca-config.json <<”EOF”
{
“signing”: {
“default”: {
“expiry”: “87600h”
},
“profiles”: {
“kubernetes”: {
“usages”: [
“signing”,
“key encipherment”,
“server auth”,
“client auth”
],
“expiry”: “87600h”
}
}
}
}
EOF
说明
server auth 表示 client 可以对使用该 ca 对 server 提供的证书进行验证
client auth 表示 server 可以使用该 ca 对 client 提供的证书进行验证 #配置 etcd-csr.json 请求文件
cat > etcd-csr.json <<”EOF”
{
“CN”: “etcd”,
“hosts”: [
“127.0.0.1”,
“192.168.134.10”,
“192.168.134.11”,
“192.168.134.12”
],
“key”: {
“algo”: “rsa”,
“size”: 2048
},
“names”: [{
“C”: “CN”,
“ST”: “CQ”,
“L”: “CQ”,
“O”: “kubemsb”,
“OU”: “CN”
}]
}
EOF #生成 etcd 证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes etcdcsr.json | cfssljson -bare etcd #查看刚刚生成的证书
[root@k8s-master cert]# ls _pem
ca-key.pem ca.pem etcd-key.pem etcd.pem 3.安装 Etcd #切换目录
cd /opt/soft #下载包
wget https://github.com/etcd-io/etcd/releases/download/v3.2.12/etcd-v3.2.12-linuxamd64.tar.gz
#etcd 软件包安装
tar -xf etcd-v3.4.13-linux-amd64.tar.gz –strip-components=1 -C /usr/local/bin/ etcdv3.4.13-linux-amd64/etcd_ #创建 etcd 配置文件,3 个节点都要配置,并修改 ETCD_NAME,ETCD_LISTEN_PEER_URLS,
ETCD_LISTEN_CLIENT_URLS,ETCD_INITIAL_ADVERTISE_PEER_URLS,ETCD_ADVERTISE_CLIENT_URLS
mkdir /etc/etcd
cat > /etc/etcd/etcd.conf <<”EOF” #[Member]
ETCD_NAME=”etcd1”
ETCD_DATA_DIR=”/var/lib/etcd/default.etcd”
ETCD_LISTEN_PEER_URLS=”https://192.168.134.10:2380“
ETCD_LISTEN_CLIENT_URLS=”https://192.168.134.10:2379,http://127.0.0.1:2379“ #[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS=”https://192.168.134.10:2380“
ETCD_ADVERTISE_CLIENT_URLS=”https://192.168.134.10:2379“
ETCD_INITIAL_CLUSTER=”etcd1=https://192.168.134.10:2380,etcd2=https://192.168.134.11:2380,et
cd3=https://192.168.134.12:2380“
ETCD_INITIAL_CLUSTER_TOKEN=”etcd-cluster”
ETCD_INITIAL_CLUSTER_STATE=”new”
EOF
/** 参数解释:
- ETCD_NAME 节点名称,每个节点名称不⼀样
- ETCD_DATA_DIR 存储数据⽬录(他是⼀个数据库,不是存在内存的,存在硬盘中的,所有和 k8s
有关的信息都会存到 etcd ⾥⾯的) - ETCD_LISTEN_PEER_URLS 集群通信监听地址
- ETCD_LISTEN_CLIENT_URLS 客户端访问监听地址
- ETCD_INITIAL_ADVERTISE_PEER_URLS 集群通告地址
- ETCD_ADVERTISE_CLIENT_URLS 客户端通告地址
- ETCD_INITIAL_CLUSTER 集群节点地址
- ETCD_INITIAL_CLUSTER_TOKEN 集群 Token
- ETCD*INITIAL_CLUSTER_STATE 加⼊集群的当前状态,new 是新集群,existing 表示加⼊已有集群 */ #创建 systemd 管理 etcd
cat > /usr/lib/systemd/system/etcd.service <<”EOF”
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/etc/etcd/etcd.conf
ExecStart=/usr/local/bin/etcd
–cert-file=/etc/etcd/ssl/etcd.pem
–key-file=/etc/etcd/ssl/etcd-key.pem
–trusted-ca-file=/etc/etcd/ssl/ca.pem
–peer-cert-file=/etc/etcd/ssl/etcd.pem
–peer-key-file=/etc/etcd/ssl/etcd-key.pem
–peer-trusted-ca-file=/etc/etcd/ssl/ca.pem
–peer-client-cert-auth
–client-cert-auth
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF #创建启动 etcd 需要的目录
mkdir -p /etc/etcd/ssl
mkdir -p /var/lib/etcd/default.etcd #将证书复制到/etc/etcd/ssl
cp /opt/soft/cert/ca_.pem /etc/etcd/ssl
cp /opt/soft/cert/etcd*.pem /etc/etcd/ssl #全部启动并设置开启启动,启动时一定要同时启动,否则会报错
systemctl daemon-reload && systemctl start etcd && systemctl enable etcd #验证是否安装成功
ETCDCTL_API=3 /usr/local/bin/etcdctl –write-out=table –cacert=/etc/etcd/ssl/ca.pem –
cert=/etc/etcd/ssl/etcd.pem –key=/etc/etcd/ssl/etcd-key.pem –
endpoints=https://192.168.134.10:2379,https://192.168.134.11:2379,https://192.168.134.12:237
9 endpoint health 2.部署 api-server
在 master 节点部署 api-server,master 节点操作–给 api-server 创建的证书。别的服务访问 api-server 的时候需要通过
证书认证 #下载软件包
wget https://dl.k8s.io/v1.20.10/kubernetes-server-linux-amd64.tar.gz #解压包到/usr/local/bin 下
tar -xf kubernetes-server-linux-amd64.tar.gz –strip-components=3 -C /usr/local/bin
kubernetes/server/bin/kube{let,ctl,-apiserver,-controller-manager,-scheduler,-proxy} #将 k8s 程序传到 node
scp /usr/local/bin/kube{let,-proxy} root@k8s-node1:/usr/local/bin
scp /usr/local/bin/kube{let,-proxy} root@k8s-node2:/usr/local/bin #在 master 节点创建以下文件夹
mkdir -p /etc/kubernetes/
mkdir -p /etc/kubernetes/ssl
mkdir -p /var/log/kubernetes 1.生成 apiserver 证书 #创建目录用来生成证书
cd /opt/soft/cert #创建 apiserver 证书请求文件
cat > kube-apiserver-csr.json << “EOF”
{
“CN”: “kubernetes”,
“hosts”: [
“127.0.0.1”,
“192.168.134.10”,
“192.168.134.11”,
“192.168.134.12”,
“10.96.0.1”,
“kubernetes”,
“kubernetes.default”,
“kubernetes.default.svc”,
“kubernetes.default.svc.cluster”,
“kubernetes.default.svc.cluster.local”
],
“key”: {
“algo”: “rsa”,
“size”: 2048
},
“names”: [
{
“C”: “CN”,
“ST”: “CQ”,
“L”: “CQ”,
“O”: “kubemsb”,
“OU”: “CN”
}
]
}
EOF #说明:
如果 hosts 字段不为空则需要指定授权使用该证书的 IP(含 VIP) 或域名列表。由于该证书被 集群使用,需要将节点的
IP 都填上,为了方便后期扩容可以多写几个预留的 IP。
同时还需要填写 service 网络的首个 IP(一般是 kube-apiserver 指定的 service-cluster-ip-range 网段的第一
个 IP,如 10.96.0.1)。 #生成 apiserver 证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubeapiserver-csr.json | cfssljson -bare kube-apiserver #生成 token 文件
cat > token.csv << EOF
$(head -c 16 /dev/urandom | od -An -t x | tr -d ‘ ‘),kubeletbootstrap,10001,”system:kubelet-bootstrap”
EOF #说明:
创建 TLS 机制所需 TOKEN
TLS Bootstraping:Master apiserver 启用 TLS 认证后,Node 节点 kubelet 和 kube-proxy 与 kube-apiserver 进行
通信,必须使用 CA 签发的有效证书才可以,当 Node 节点很多时,这种客户端证书颁发需要大量工作,同样也会增加集群扩展复
杂度。为了简化流程,Kubernetes 引入了 TLS bootstraping 机制来自动颁发客户端证书,kubelet 会以一个低权限用户自
动向 apiserver 申请证书,kubelet 的证书由 apiserver 动态签署。所以强烈建议在 Node 上使用这种方式,目前主要用于
kubelet,kube-proxy 还是由我们统一颁发一个证书。 #将证书复制到/etc/kubernetes/ssl
cp ca-key.pem ca.pem token.csv kube-apiserver-key.pem kube-apiserver.pem
/etc/kubernetes/ssl/ 2.创建 apiserver 服务配置文件
cat > /etc/kubernetes/kube-apiserver.conf << “EOF”
KUBE_APISERVER_OPTS=”–enable-admissionplugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,Re
sourceQuota
–anonymous-auth=false
–bind-address=192.168.134.10
–secure-port=6443
–advertise-address=192.168.134.10
–insecure-port=0
–authorization-mode=Node,RBAC
–runtime-config=api/all=true
–enable-bootstrap-token-auth
–service-cluster-ip-range=10.96.0.0/16
–token-auth-file=/etc/kubernetes/ssl/token.csv
–service-node-port-range=30000-32767
–tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem
–tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem
–client-ca-file=/etc/kubernetes/ssl/ca.pem
–kubelet-client-certificate=/etc/kubernetes/ssl/kube-apiserver.pem
–kubelet-client-key=/etc/kubernetes/ssl/kube-apiserver-key.pem
–service-account-key-file=/etc/kubernetes/ssl/ca-key.pem
–service-account-signing-key-file=/etc/kubernetes/ssl/ca-key.pem
–service-account-issuer=api
–etcd-cafile=/etc/etcd/ssl/ca.pem
–etcd-certfile=/etc/etcd/ssl/etcd.pem
–etcd-keyfile=/etc/etcd/ssl/etcd-key.pem
–etcdservers=https://192.168.134.10:2379,https://192.168.134.11:2379,https://192.168.134.12:2379
–enable-swagger-ui=true
–allow-privileged=true
–apiserver-count=3
–audit-log-maxage=30
–audit-log-maxbackup=3
–audit-log-maxsize=100
–audit-log-path=/var/log/kube-apiserver-audit.log
–event-ttl=1h
–alsologtostderr=true
–logtostderr=false
–log-dir=/var/log/kubernetes
–v=4”
EOF #创建 systemd 管理 apiserver
cat > /usr/lib/systemd/system/kube-apiserver.service << “EOF”
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
After=etcd.service
Wants=etcd.service
[Service]
EnvironmentFile=-/etc/kubernetes/kube-apiserver.conf
ExecStart=/usr/local/bin/kube-apiserver $KUBE_APISERVER_OPTS
Restart=on-failure
RestartSec=5
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF #启动 apiserver 服务
systemctl daemon-reload
systemctl enable –now kube-apiserver
systemctl status kube-apiserver
测试
curl –insecure https://192.168.134.10:6443/
curl –insecure https://192.168.134.11:6443/
curl –insecure https://192.168.134.12:6443/ 3.部署 kubectl 1.生成 kubectl 证书
cd /opt/soft/cert #创建 kubectl 证书请求文件
cat > admin-csr.json << “EOF”
{
“CN”: “admin”,
“hosts”: [],
“key”: {
“algo”: “rsa”,
“size”: 2048
},
“names”: [
{
“C”: “CN”,
“ST”: “CQ”,
“L”: “CQ”,
“O”: “system:masters”,
“OU”: “system”
}
]
}
EOF #说明:
后续 kube-apiserver 使用 RBAC 对客户端(如 kubelet、kube-proxy、Pod)请求进行授权;
kube-apiserver 预定义了一些 RBAC 使用的 RoleBindings,如 cluster-admin 将 Group system:masters 与
Role cluster-admin 绑定,该 Role 授予了调用 kube-apiserver 的所有 API 的权限;
O 指定该证书的 Group 为 system:masters,kubelet 使用该证书访问 kube-apiserver 时 ,由于证书被 CA 签
名,所以认证通过,同时由于证书用户组为经过预授权的 system:masters,所以被授予访问所有 API 的权限;
注:
这个 admin 证书,是将来生成管理员用的 kubeconfig 配置文件用的,现在我们一般建议使用 RBAC 来对 kubernetes 进行
角色权限控制, kubernetes 将证书中的 CN 字段 作为 User, O 字段作为 Group;
“O”: “system:masters”, 必须是 system:masters,否则后面 kubectl create clusterrolebinding 报错。 #生成证书文件
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes
admin-csr.json | cfssljson -bare admin #复制文件到指定目录
cp admin*.pem /etc/kubernetes/ssl/ 2.生成 kubeconfig 配置文件
#kube.config 为 kubectl 的配置文件,包含访问 apiserver 的所有信息,如 apiserver 地址、CA 证书和自身使
用的证书
kubectl config set-cluster kubernetes –certificate-authority=ca.pem –embed-certs=true –
server=https://192.168.134.10:6443 –kubeconfig=kube.config
kubectl config set-credentials admin –client-certificate=admin.pem –client-key=adminkey.pem –embed-certs=true –kubeconfig=kube.config
kubectl config set-context kubernetes –cluster=kubernetes –user=admin –
kubeconfig=kube.config
kubectl config use-context kubernetes –kubeconfig=kube.config #准备 kubectl 配置文件并进行角色绑定
mkdir ~/.kube
cp kube.config ~/.kube/config
kubectl create clusterrolebinding kube-apiserver:kubelet-apis –clusterrole=system:kubeletapi-admin –user kubernetes –kubeconfig=/root/.kube/config #查看集群状态
export KUBECONFIG=$HOME/.kube/config #查看集群信息
kubectl cluster-info #查看集群组件状态
kubectl get componentstatuses #查看命名空间中资源对象
kubectl get all –all-namespaces 4.部署 kube-controller-manager 1.生成 kube-controller-manager 证书 #切换目录
cd /opt/soft/cert #创建证书文件
cat > kube-controller-manager-csr.json << “EOF”
{
“CN”: “system:kube-controller-manager”,
“key”: {
“algo”: “rsa”,
“size”: 2048
},
“hosts”: [
“127.0.0.1”,
“192.168.134.10”
],
“names”: [
{
“C”: “CN”,
“ST”: “CQ”,
“L”: “CQ”,
“O”: “system:kube-controller-manager”,
“OU”: “system”
}
]
}
EOF
说明:
hosts 列表包含所有 kube-controller-manager 节点 IP;
CN 为 system:kube-controller-manager;
O 为 system:kube-controller-manager,kubernetes 内置的 ClusterRoleBindings system:kubecontroller-manager 赋予 kube-controller-manager 工作所需的权限 #创建 kube-controller-manager 证书文件
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubecontroller-manager-csr.json | cfssljson -bare kube-controller-manager #创建 kube-controller-manager 的 kube-controller-manager.kubeconfig
kubectl config set-cluster kubernetes –certificate-authority=ca.pem –embed-certs=true –
server=https://192.168.134.10:6443 –kubeconfig=kube-controller-manager.kubeconfig
kubectl config set-credentials system:kube-controller-manager –client-certificate=kubecontroller-manager.pem –client-key=kube-controller-manager-key.pem –embed-certs=true –
kubeconfig=kube-controller-manager.kubeconfig
kubectl config set-context system:kube-controller-manager –cluster=kubernetes –
user=system:kube-controller-manager –kubeconfig=kube-controller-manager.kubeconfig
kubectl config use-context system:kube-controller-manager –kubeconfig=kube-controllermanager.kubeconfig #复制到配置文件
cp kube-controller-manager*.pem /etc/kubernetes/ssl/
cp kube-controller-manager.kubeconfig /etc/kubernetes/ 2.创建 kube-controller-manager 配置文件和服务
cat > /etc/kubernetes/kube-controller-manager.conf << “EOF”
KUBE_CONTROLLER_MANAGER_OPTS=”–secure-port=10257
–bind-address=127.0.0.1
–kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig
–service-cluster-ip-range=10.96.0.0/16
–cluster-name=kubernetes
–cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem
–cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem
–allocate-node-cidrs=true
–cluster-cidr=10.244.0.0/16
–experimental-cluster-signing-duration=87600h
–root-ca-file=/etc/kubernetes/ssl/ca.pem
–service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem
–leader-elect=true
–feature-gates=RotateKubeletServerCertificate=true
–controllers=*,bootstrapsigner,tokencleaner
–horizontal-pod-autoscaler-sync-period=10s
–tls-cert-file=/etc/kubernetes/ssl/kube-controller-manager.pem
–tls-private-key-file=/etc/kubernetes/ssl/kube-controller-manager-key.pem
–use-service-account-credentials=true
–alsologtostderr=true
–logtostderr=false
–log-dir=/var/log/kubernetes
–v=2”
EOF #创建 systemd 管理 kube-controller-manager
cat > /usr/lib/systemd/system/kube-controller-manager.service << “EOF”
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/kube-controller-manager.conf
ExecStart=/usr/local/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
启动服务
systemctl daemon-reload
systemctl enable –now kube-controller-manager
systemctl status kube-controller-manager 5.部署 kube-scheduler 1.生成 kube-scheduler 证书 #切换目录
cd /opt/soft/cert #创建 kube-scheduler-csr.json 文件
cat > kube-scheduler-csr.json << “EOF”
{
“CN”: “system:kube-scheduler”,
“hosts”: [
“127.0.0.1”,
“192.168.134.10”
],
“key”: {
“algo”: “rsa”,
“size”: 2048
},
“names”: [
{
“C”: “CN”,
“ST”: “CQ”,
“L”: “CQ”,
“O”: “system:kube-scheduler”,
“OU”: “system”
}
]
}
EOF #生成 kube-scheduler 证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubescheduler-csr.json | cfssljson -bare kube-scheduler #创建 ube-scheduler 的 kubeconfig
kubectl config set-cluster kubernetes –certificate-authority=ca.pem –embed-certs=true –
server=https://192.168.134.10:6443 –kubeconfig=kube-scheduler.kubeconfig
kubectl config set-credentials system:kube-scheduler –client-certificate=kube-scheduler.pem
–client-key=kube-scheduler-key.pem –embed-certs=true –kubeconfig=kubescheduler.kubeconfig
kubectl config set-context system:kube-scheduler –cluster=kubernetes –user=system:kubescheduler –kubeconfig=kube-scheduler.kubeconfig
kubectl config use-context system:kube-scheduler –kubeconfig=kube-scheduler.kubeconfig #复制证书到证书存放目录
cp kube-scheduler*.pem /etc/kubernetes/ssl/ #复制配置文件到/etc/kubernetes/
cp kube-scheduler.kubeconfig /etc/kubernetes/ 2.创建 scheduler 配置文件和服务 #创建服务配置文件
cat > /etc/kubernetes/kube-scheduler.conf << “EOF”
KUBE_SCHEDULER_OPTS=”–address=127.0.0.1
–kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig
–leader-elect=true
–alsologtostderr=true
–logtostderr=false
–log-dir=/var/log/kubernetes
–v=2”
EOF #创建服务启动配置文件
cat > /usr/lib/systemd/system/kube-scheduler.service << “EOF”
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/kube-scheduler.conf
ExecStart=/usr/local/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
#启动服务
systemctl daemon-reload
systemctl enable –now kube-scheduler
systemctl status kube-scheduler
6.部署kubelet
#创建kubelet-bootstrap.kubeconfig
BOOTSTRAP_TOKEN=$(awk -F “,” ‘{print $1}’ /etc/kubernetes/ssl/token.csv)
kubectl config set-cluster kubernetes –certificate-authority=ca.pem –embed-certs=true –
server=https://192.168.134.10:6443 –kubeconfig=kubelet-bootstrap.kubeconfig
kubectl config set-credentials kubelet-bootstrap –token=${BOOTSTRAP_TOKEN} –
kubeconfig=kubelet-bootstrap.kubeconfig
kubectl config set-context default –cluster=kubernetes –user=kubelet-bootstrap –
kubeconfig=kubelet-bootstrap.kubeconfig
kubectl config use-context default –kubeconfig=kubelet-bootstrap.kubeconfig
kubectl create clusterrolebinding cluster-system-anonymous –clusterrole=cluster-admin –
user=kubelet-bootstrap
kubectl create clusterrolebinding kubelet-bootstrap –clusterrole=system:node-bootstrapper -
-user=kubelet-bootstrap –kubeconfig=kubelet-bootstrap.kubeconfig
kubectl describe clusterrolebinding cluster-system-anonymous
kubectl describe clusterrolebinding kubelet-bootstrap #复制到配置目录
cp kubelet-bootstrap.kubeconfig /etc/kubernetes/
创建 kubelet 配置文件
cat > /etc/kubernetes/kubelet.json << “EOF”
{
“kind”: “KubeletConfiguration”,
“apiVersion”: “kubelet.config.k8s.io/v1beta1”,
“authentication”: {
“x509”: {
“clientCAFile”: “/etc/kubernetes/ssl/ca.pem”
},
“webhook”: {
“enabled”: true,
“cacheTTL”: “2m0s”
},
“anonymous”: {
“enabled”: false
}
},
“authorization”: {
“mode”: “Webhook”,
“webhook”: {
“cacheAuthorizedTTL”: “5m0s”,
“cacheUnauthorizedTTL”: “30s”
}
},
“address”: “192.168.134.10”,
“port”: 10250,
“readOnlyPort”: 10255,
“cgroupDriver”: “systemd”,
“hairpinMode”: “promiscuous-bridge”,
“serializeImagePulls”: false,
“clusterDomain”: “cluster.local.”,
“clusterDNS”: [“10.96.0.2”]
}
EOF #创建 kubelet 服务启动管理文件
cat > /usr/lib/systemd/system/kubelet.service << “EOF”
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
ExecStart=/usr/local/bin/kubelet
–bootstrap-kubeconfig=/etc/kubernetes/kubelet-bootstrap.kubeconfig
–cert-dir=/etc/kubernetes/ssl
–kubeconfig=/etc/kubernetes/kubelet.kubeconfig
–config=/etc/kubernetes/kubelet.json
–container-runtime-endpoint=unix:///run/containerd/containerd.sock
–rotate-certificates
–pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.2
–alsologtostderr=true
–logtostderr=false
–log-dir=/var/log/kubernetes
–v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF #创建目录及启动服务
mkdir -p /var/lib/kubelet
mkdir -p /var/log/kubernetes
systemctl daemon-reload
systemctl enable –now kubelet
systemctl status kubelet #查看节点
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready
cd /opt/soft/cert/
创建 kube-proxy 证书请求文件
cat > kube-proxy-csr.json << “EOF”
{
“CN”: “system:kube-proxy”,
“key”: {
“algo”: “rsa”,
“size”: 2048
},
“names”: [
{
“C”: “CN”,
“ST”: “CQ”,
“L”: “CQ”,
“O”: “kubemsb”,
“OU”: “CN”
}
]
}
EOF #生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kubeproxy-csr.json | cfssljson -bare kube-proxy #创建 kubeconfig 文件
kubectl config set-cluster kubernetes –certificate-authority=ca.pem –embed-certs=true –
server=https://192.168.134.10:6443 –kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy –client-certificate=kube-proxy.pem –clientkey=kube-proxy-key.pem –embed-certs=true –kubeconfig=kube-proxy.kubeconfig
kubectl config set-context default –cluster=kubernetes –user=kube-proxy –kubeconfig=kubeproxy.kubeconfig
kubectl config use-context default –kubeconfig=kube-proxy.kubeconfig #创建服务配置文件
cat > kube-proxy.yaml << “EOF”
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 192.168.134.10
clientConnection:
kubeconfig: /etc/kubernetes/kube-proxy.kubeconfig
clusterCIDR: 10.244.0.0/16
healthzBindAddress: 192.168.134.10:10256
kind: KubeProxyConfiguration
metricsBindAddress: 192.168.134.10:10249
mode: “ipvs”
EOF #创建服务启动管理文件
cat > /usr/lib/systemd/system/kube-proxy.service << “EOF”
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/kubernetes/kubernetes
After=network.target
[Service]
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/usr/local/bin/kube-proxy
–config=/etc/kubernetes/kube-proxy.yaml
–alsologtostderr=true
–logtostderr=false
–log-dir=/var/log/kubernetes
–v=2
Restart=on-failure
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF #复制到配置文件目录
cp kube-proxy*.pem /etc/kubernetes/ssl/
cp kube-proxy.kubeconfig kube-proxy.yaml /etc/kubernetes/
服务启动
mkdir -p /var/lib/kube-proxy
systemctl daemon-reload
systemctl enable –now kube-proxy
systemctl status kube-proxy 8.工作节点安装 1.工作节点部署 kubelet #在 master 节点切换目录
cd /opt/soft/cert #在工作节点创建目录
mkdir /etc/kubernetes/
mkdir /etc/kubernetes/ssl #同步至集群节点
for i in k8s-node1 k8s-node2;do scp /etc/kubernetes/kubelet-bootstrap.kubeconfig
/etc/kubernetes/kubelet.json $i:/etc/kubernetes/;done
for i in k8s-node1 k8s-node2;do scp ca.pem $i:/etc/kubernetes/ssl/;done
for i in k8s-node1 k8s-node2;do scp /usr/lib/systemd/system/kubelet.service
$i:/usr/lib/systemd/system/;done #复制到工作节点后需要修改一下工作节点中 ip
sed -ri ‘s/“address”: “192.168.134.10”/“address”: “192.168.134.11”/g’
/etc/kubernetes/kubelet.json
sed -ri ‘s/“address”: “192.168.134.10”/“address”: “192.168.134.12”/g’
/etc/kubernetes/kubelet.json #在工作节点执行创建目录及启动服务
mkdir -p /var/lib/kubelet
mkdir -p /var/log/kubernetes
systemctl daemon-reload
systemctl enable –now kubelet
systemctl status kubelet #查看节点
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready
k8s-node1 Ready
k8s-node2 Ready
for i in k8s-node1 k8s-node2;do scp /etc/kubernetes/kube-proxy.kubeconfig
/etc/kubernetes/kube-proxy.yaml $i:/etc/kubernetes/;done
for i in k8s-node1 k8s-node2;do scp /usr/lib/systemd/system/kube-proxy.service
$i:/usr/lib/systemd/system/;done
服务启动
mkdir -p /var/lib/kube-proxy
systemctl daemon-reload
systemctl enable –now kube-proxy
systemctl status kube-proxy 9.网络组件部署 Calico
资源名称 缩写 资源作用
nodes no 查看 k8s 中的所有节点
namespaces ns 名称空间,隔离 pod
pods po,pod 装载容器(容器组)
replicationcontrollers rc 控制 pod 资源
replicasets rs 控制 pod 资源
deployments deploy 控制 pod 资源
daemonsets ds 控制 pod 资源
jobs 控制 pod 资源
cronjobs cj 控制 pod 资源
horizontalpodautoscalers hpa 控制 pod 资源
statefulsets sts 控制 pod 资源
services svc 4 层负载均衡,pod 对外接口
ingress ing 7 层负载均衡,pod 对外接口
volumeattachments 存储资源
persistentvolumes pv 存储资源
persistentvolumeclaims pvc 存储资源
configmaps cm 配置资源
secrets 加密配置资源
serviceaccount sa 服务账户 #下载部署 Calico
wget https://docs.projectcalico.org/v3.19/manifests/calico.yaml #修改文件 vim calico
3683 - name: CALICO_IPV4POOL_CIDR
3684 value: “10.244.0.0/16” #应用文件
kubectl apply -f calico.yaml
二.k8s 资源管理
1.K8s 资源类型介绍
2.k8s 集群管理方式介绍
直接使用 kubectl 命令去管理 k8s 集群
命令 作用
create 创建一个资源
edit 编辑一个资源
get 获取一个资源
patch 更新一个资源
delete 删除一个资源
explain 展示资源文档
run 在命令行运行一个容器
expose 在命令行暴露资源端口
describe 显示资源内部信息
logs 输出容器在 pod 中的日志
exec 进入运行中的容器
cp 在 pod 内外复制文件
rollout 管理资源的发布
scale 扩(缩)容 pod 的数量
autoscale 自动调整 pod 的数量
apply 创建资源/更新资源
label 标签管理命令
cluster-info 显示集群信息
version 显示当前 Server 和 Client 版本信息
kubectl run nginx-pod –image=nginx:1.18.0 –port=80
将配置写入到 yaml 文件,通过文件去管理 k8s 集群
kubectl create/patch -f nginx-pod.yaml
3.kubectl 命令介绍
是 kubernetes 集群的命令行工具,通过它能过够对集群本身进行管理,并能够在集群上进行容器化应用的安装部
署。
kubectl 常用命令如下
命令格式:
kubectl [command] [type] [name] [flags] #参数详情
command:指定要对资源执行的操作,例如:create、get、delete
type:指定资源类型,例如:deployment、pod、
servicename:指定资源名称,名称区分大小写
flags:指定额外的可选参数,例如:-o wide
4.kubectl 命令练习 #查看所有 pod
kubectl get pod #查看所有节点
kubectl get nodes #查看指定的 pod(根据 pod 名字查找)
kubectl get pod pod 名称 #查看指定 pod,通过额外参数显示 pod 详细信息,包括 pod 的 IP 地址,pod 运行的节点等
kubectl get pod pod 名称 -o wide #查看指定 pod,通过额外参数显示 pod 信息,以 json 格式显示
kubectl get pod pod 名称 -o json #查看指定 pod,通过额外参数显示 pod 信息,以 yaml 格式显示
kubectl get pod pod 名称 -o yaml #显示指定 pod 资源内部信息
kubectl describe pod pod 名称 #显示当前 Server 和 Client 版本信息
kubectl version #显示集群信息
kubectl cluster-info
三.Namespace 名称空间
Namespace(名称空间)是 kubernetes 系统中的一种非常重要的资源,它的主要作用是用来实现资源隔离(例如生
活中的房间)可以将不同的 Pod 划分到不同的 Namespace(名称空间)进行隔离。 1.查看名称空间
[root@k8s-master ~]# kubectl get ns/namespace
NAME STATUS AGE
default Active 32h #不指定时默然创建到此空间
kube-node-lease Active 32h #集群节点之间的心跳维护
kube-public Active 32h #该名称空间下的资源可以被所有人访问
kube-system Active 32h #系统创建的资源 2.查看指定 ns 的信息
[root@k8s-master ~]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-68d86f8988-qthn9 1/1 Running 0 32h
calico-node-cqj84 1/1 Running 0 32h
calico-node-qcxmb 1/1 Running 0 32h
calico-node-vgcbp 1/1 Running 1 (31h ago) 32h
coredns-7f6cbbb7b8-sftmg 1/1 Running 0 32h
coredns-7f6cbbb7b8-zbhqt 1/1 Running 0 32h
etcd-k8s-master 1/1 Running 6 (31h ago) 32h
kube-apiserver-k8s-master 1/1 Running 6 (31h ago) 32h
kube-controller-manager-k8s-master 1/1 Running 6 (31h ago) 32h
kube-proxy-f25zd 1/1 Running 0 32h
kube-proxy-jrrng 1/1 Running 1 (31h ago) 32h
kube-proxy-sdkrd 1/1 Running 0 32h
kube-scheduler-k8s-master 1/1 Running 0 7h19m 3.创建一个名称空间
kubectl create namespace test
或者
kubectl create ns test 4.删除名称空间
kubectl delete namespace test
或者
kubectl delete ns test
5.yaml 创建
#vim test_namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
创建命令
kubectl create/apply -f test_namespace.yaml
四.资源管理语言 yaml
k8s 中几乎所有的资源都可以通 YAML 编排来创建。
1.YAML 的语法特点
严格区分大小写
使用缩进表示层级关系
缩进不允许使用 tab 键,只允许使用空格,缩进的空格数量没有严格要求,只要相同层级左对齐即可 #号表示注释
书写 YAML 切记:后边要加一个空格
如果需要将多段 YAML 配置放在同一个文件中,中间需要用—作为分格
2.YAML 常用数据结构
对象(Object):键值对的集合,又称为映射(mapping)/哈希(hashes)/字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence)/列表(list)
对象键值对类型
xxx:
key: value
数组类型:一组连词线开头的行,构成一个数组
- xxx:
key: value
复合结构:对象和数组可以结合使用,形成复合结构
xxx:
key: v - key: v
key: v
3.K8s 资源对象描述
在 kubernetes 中基本所有资源的一级属性都是一样的,主要分为五部分:
apiVersion:资源版本,由 k8s 内部定义,版本号必须可以通过 kubectl
api-versions 查询到
kind:资源类型,由 k8s 内部定义,类型必须可以通过 kubectl api-resources 查询到
metadata:元数据,主要是指定资源标识与说明,常用的有 name、namespace、labels 等
spec:资源描述,这是配置中最重要的一部分,里边对各种资源配置的详细描述
status:资源状态信息,里边的内容不需要定义,有 k8s 自动生成
4.YAML 文件创建资源
使用 yaml 创建一个简单的 pod
#vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 2
selector:
matchLabels:
app: deploy-nginx
template:
metadata:
labels:
app: deploy-nginx
spec:
containers: - name: nginx
image: nginx:1.18.0
五.pod 与 pod 控制器
1.Pod 概念介绍
Pod 是 kubernetes 集群进行管理的最小单元,程序必须部署在容器中,而容器必须存在于 Pod 中,kubernetes 集群
启动以后,集群中的各个组件也都是以 Pod 方式运行。
Pod 是容器组,一个 Pod 中可以存在一个或多个容器,这些容器共享 Pod 中的存储、网络等资源,所以我们可以把
Pod 看做一台物理服务器一样(Pod 不是进程,而是容器运行的环境),其中包含一个或多个应用容器,这些容器中
运行着用户应用程序。
pod 的创建方式分为两类:
静态 Pod:也称之为无控制器管理的自主式 pod,直接由特定节点上的 kubelet 守护进程管理,不需要 API 服务器看到
它们,对于静态 Pod 而言,kubelet 直接监控每个 Pod,这种 pod 删除后就没有了,也不会重建。
示例
vim nginx-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-web
labels:
spec:
containers:
- name: nginx-web
image: nginx:1.18.0
ports: - name: nginx-web
containerPort: 80 #执行创建
kubectl create -f nginx-web.yaml #查看 pod
kubectl get pod #删除 pod
kubectl delete pod nginx-web
控制器管理的 pod:控制器可以控制 pod 的副本数,扩容与缩容、版本更新、版本回滚等。
pod 控制器是管理 pod 的中间层,使用了 pod 控制器之后,我们只需要告诉 pod 控制器,需要多少个什么样的 pod 就可
以了,它就会创建出满足条件的 pod,并确保每一个 pod 处于用户期望的状态,如果 pod 在运行中出现故障,控制器
会基于指定的策略重新启动或重建 pod
常见 pod 控制器种类:
ReplicationController:比较原始的 pod 控制器,目前已经被废弃,由 ReplicaSet 代替
ReplicaSet:保证指定数量的 pod 运行,并支持 pod 数量变更,镜像版本变更
Deployment:通过控制 ReplicaSet 来控制 pod,包含 ReplicaSet 所有功能,还支持滚动升级,版本回退
Horizontal Pod Autoscaler:可以根据集群负载自动调整 pod 数量,实现 pod 扩容缩
DaemonSet:节点级别控制器,确保全部每一个节点上运行一个 Pod 的副本,当有 Node 加入集群时,也会为他们新增一个
Pod,当有 Node 从集群移除时,这些 Pod 也会被回收,删除 DaemonSet 将会删除它创建的所有 Pod
Job:运行一次性任务的 Pod,它创建的 pod 只要完成就立即退出(健康检查,数据备份)
示例:
#vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 2
selector:
matchLabels:
app: deploy-nginx
template:
metadata:
labels:
app: deploy-nginx
spec:
containers: - name: nginx
image: nginx:1.18.0
2.Pod 资源清单介绍
KIND: Pod #资源类型类型
VERSION: v1 #资源版本
DESCRIPTION: #资源描述
FIELDS: #资源可配置的属性,如下
apiVersion: v1 #必选的一级属性,版本号,例如 v1
kind: Pod #必选的一级属性,资源类型,例如 Pod
metadata: #必选的一级属性,元数据
name: #必选的二级属性,Pod 名称
namespace: dev #二级属性,Pod 所属的名称空间,例如 dev,默认为 default 名称空间
labels: #二级属性,自定义标签列表 - name: #三级属性,标签名称
spec: #必选的一级属性,Pod 中容器的详细定义
containers: #必选的二级属性,Pod 中容器列表 - name: #必选的三级属性,容器名称
image: #必选的三级属性,容器镜像名称
imagePullPolicy: #三级属性,镜像的拉取策略
command: #三级属性,容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: #三级属性,容器的启动命令参数列表
workingDir: #三级属性,容器的工作目录
volumeMounts: #三级属性,挂载到容器内部的存储卷配置 - name: #四级属性,引用 pod 定义的共享存储卷的名称
mountPath: #四级属性,存储卷在容器内 mount 的绝对路径,应少于 512 字节
readOnly: #四级属性,是否为只读模式
ports: #三级属性,需要暴露的端口库号列表 - name: #四级属性,端口的名称
containerPort: #四级属性,容器需要监听的端口号
hostPort: #四级属性,容器所在的主机需要监听的端口号,默认与 Container 相同
protocol: #四级属性,端口协议,支持 TCP/UDP,默认为 TCP
env: #三级属性,容器运行前需要设置的环境变量列表 - name: #四级属性,环境变量名称
value: #四级属性,环境变量的值
resources: #三级属性,资源限制和请求的设置
limits: #四级属性,资源最大限制的设置
CPU: #五级属性,CPU 资源限制,单位为 core 数,将用于 docker run –cpu-shares 参数
memory: #五级属性,内存资源限制,单位可以为 Mib/Gib,将用于 docker run –memory 参数
requests: #四级属性,资源最小请求的设置
CPU: #五级属性,CPU 请求,容器启动的初始可用数量
memory: #五级属性,内存请求,容器启动的初始可用数量
lifecycle: #三级属性,生命周期钩子
postStart: #四级属性,容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #四级属性,容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: #三级属性,对 Pod 内个容器健康检查设置,当探测容器无响应后将自动重启该容器
tcpSocket: #三级属性,对 Pod 内容器健康检查方式
initialDelaySeconds: #三级属性,容器启动完成后,首次探测时间,单位为秒
timeoutSeconds: #三级属性,对容器健康检查探测等待相应的超时时间,单位秒,默认 1 秒
periodSeconds: #三级属性,对容器监控检查的定期探测时间设置,单位秒,默认 10 秒一次
restartPolicy: #二级属性,Pod 的重启策略
nodeName: #二级属性,设置 pod 调度到指定的 node 节点上
nodeSelector: #二级属性,设置 Pod 调度到指定的 label 的 node 节点上
imagePullSecrets: #二级属性,拉取镜像时,使用 secret 名称,以 key:secretkey 格式指定
hostNetwork: #二级属性,是否使用主机网络模式,默认为 false,如果设置为 true,表示使用宿主机网络
volumes: #二级属性,在该 Pod 上定义共享存储卷列表 - name: #三级属性,共享存储卷名称
emptyDir: #三级属性,类型为 emptyDir 的存储卷,与 Pod 同生命周期的一个临时目录,为空值
hostPath: #三级属性,类型为 hostPath 的存储卷,挂载集群与定义的 secret 对象到容器内部
path: #四级属性,Pod 所在宿主机的目录,将被用于容器中挂载的目录
secret: #三级属性,类型为 secret 的存储卷,挂载集群与定义的 secret 对象到容器内部
configMap: #三级属性,类型为 configMap 的存储卷,挂载预定义的 configMap 对象到容器内部
3.Pod 控制器 ReplicaSet
ReplicaSet 的主要作用是保证一定数量的 pod 能够正常的运行,它会持续监听这些 pod 的运行状态,一旦 pod 发生故
障,就会重启或重建 pod,同时还支持对 pod 数量的扩缩容和版本镜像的变更
1.ReplicaSet 应用案例
#vim rs_nginx.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-nginx
namespace: test
spec:
replicas: 3 #创建 pod 的副本数量,默认为 1
selector: #标签选择器,通过它指定 RS 管理哪些 pod
matchLabels: #标签类型(key=value)
app: rs-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板,通过模板创建 Pod
metadata: #定义模板的元数据信息
labels: #定义 Pod 的标签
app: rs-nginx #Pod 的标签
spec:
containers: - name: nginx
image: nginx:1.18.0
2.ReplicaSet 扩缩容
通过 RS 控制器实现 Pod 数量的扩缩容功能 #通过 edit(配置文件形式)可直接在线修改资源的配置
kubectl edit rs rs-nginx -n test
spec:
replicas: 6 #直接根据需求修改 pod 的副本数量即可 #查看 pod 信息
kubectl get pod -n test
3.ReplicaSet 版本变更
通过 RS 控制器实现镜像版本变更 #通过 edit(配置文件形式)可直接修改镜像版本
kubectl edit rs rs-nginx -n test
spec:
containers: - image: nginx:1.18.0 #修改为 1.18.0 版本 #查看 rs 详细信息
kubectl get rs -n test -o wide 5.删除 RS 方式
命令删除方式
kubectl delete rs rs-nginx -n test
查看 rs 信息
kubectl get rs -n test
配置文件删除方式
kubectl delete -f rs-nginx.yml
4.Pod 控制器 Deployment
为了更好的解决服务编排问题,k8s 在 v1.2 版本开始,引入了 Deployment(Deploy)控制器,该 pod 控制器不会去
直接管理 pod,而是通过管理 ReplicaSet 来间接的管理 pod,所以 Deployment 比 ReplicaSet 功能更强大
Deployment 功能如下:
支持 RS 所有功能
支持发布的停止、继续
支持版本滚动更新和版本回退
1.Deployment 应用案列
vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 3 #创建 pod 的副本数量,默认为 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
containers:
- name: nginx
image: nginx:1.18.0 #创建 deploy
kubectl create -f deplo_nginx.yml #查看 deploy 详细信息
kubectl get deploy -n test
kubectl get deploy -n test -o wide
5.Pod 镜像拉取策略
imagePullPolicy 用于设置镜像拉取策略,k8s 支持三种拉取策略,可通过下边命令查看:
kubectl explain pod.spec.containers.imagePullPolicy
Always 总是从远程仓库拉取镜像
IfNotPresent 本地有则使用本地镜像,本地没有则从远程仓库拉取镜像
Never 只使用本地镜像,从不去远程仓库拉取,本地如果没有就报错
1.Pod 镜像拉取策略 Never
案例:创建 pod,并指定镜像拉取策略为 Never,只使用本地镜像,从不去远程仓库拉取,本地如果没有就报错。
vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
containers:
- name: nginx
image: nginx:1.20.0 #指定一个本地不存的镜像版本
imagePullPolicy: Never #设置镜像拉取策略 #创建 pod
kubectl create -f deploy_nginx.yml #查看 pod 信息
kubectl get pod -n test #查看 pod 详细描述信息
kubectl describe pod -n test #删除 deploy
kubectl delete -f deploy_nginx.yml
2.Pod 镜像拉取策略 IfNotPresent
案例:创建 pod,并指定镜像拉取策略为 IfNotPresent,本地有则使用本地镜像,本地没有则从远程仓库拉取镜像
vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
containers:
- name: nginx
image: nginx:1.20.0 #指定一个本地不存的镜像版本
imagePullPolicy: IfNotPresent #设置镜像拉取策略 #创建 pod
kubectl create -f deploy_nginx.yml #查看 pod 信息
kubectl get pod -n test #查看 pod 详细描述信息
kubectl describe pod -n test #删除 deploy
kubectl delete -f deploy_nginx.yml
6.Pod 端口设置
ports 属性用于配置容器需要暴露的端口列表 #通过下边命令可以获取 ports 可以使用的子属性
kubectl explain pod.spec.containers.ports
containerPort #容器要监听的端口(不定义,采用默认端口)
name #端口名称,如果指定,必须保证名称在该 pod 中是唯一的
protocol #端口协议,必须是 TCP、UDP 或 SCTP,默认为 TCP
案例:创建 Pod 并指定容器暴露 80 端口
vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
containers:
- name: nginx
image: nginx:1.20.0
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义容器端口 - containerPort: #80 端口(必须为数组类型)
protocol: TCP #端口协议
创建 pod
kubectl create -f deploy_nginx.yml
查看 pod 信息
kubectl get pod -n test
curl ip:80
删除 deploy
kubectl delete -f deploy_nginx.yml
7.Pod 资源配额
resources 属性用于限制 Pod 中的容器对系统的资源的使用量(资源配额),避免容器出现问题大量吞噬系统资源,
k8s 目前提供了对内存和 CPU 的资源限制 当我们对 Pod 中的容器配置资源限额以后,如果容器超出资源使用量,k8s
则会认位该容器出现故障,则重新启动该容器
resources 属性提供了两个子属性用于资源限制,可通过下边命令查看:
kubectl explain pod.spec.containers.resources
limits #资源上限:限制容器运行时最大的资源使用量,当容器超出该使用量时,容器会被终止,并进行重启
requests #资源下限:用于限制容器需要的最小资源,如果环境资源不够,容器将无法启动
案例:创建 pod 并设置容器资源的上下限
vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
containers:
- name: nginx
image: nginx:1.20.0
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义容器端口 - containerPort: #80 端口(必须为数组类型)
protocol: TCP #端口协议
resources: #定义资源限额
limits: #资源上限
cpu: “500m” #500m 表示 0.5 个逻辑核心,1000m 表示一个逻辑核心
memory: “128Mi” #内存单位可以使用 Gi、Mi、G、M 等形式
requests: #资源下限
cpu: “250m” #250m 表示 0.25 个逻辑核心
memory: “64Mi” #所需最低内存资源(如果不足 64M,容器无法启动) #创建 pod
kubectl create -f deploy_nginx.yml #查看 pod 信息
kubectl get pod -n test
curl ip:80 #删除 deploy
kubectl delete -f deploy_nginx.yml
8.Pod 多容器创建方式
案例:将 nginx 与 tomcat 放在同一个 Pod 中运行
vim deploy_nginx_tomcat.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx-tomcat
namespace: test
spec:
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx-tomcat #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx-tomcat #pod 的标签
spec:
containers:
- name: nginx
image: nginx:1.20.0
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义容器端口 - containerPort: 80 #端口(必须为数组类型)
protocol: TCP #端口协议
resources: #定义资源限额
limits: #资源上限
cpu: “500m” #500m 表示 0.5 个逻辑核心,1000m 表示一个逻辑核心
memory: “128Mi” #内存单位可以使用 Gi、Mi、G、M 等形式
requests: #资源下限
cpu: “250m” #250m 表示 0.25 个逻辑核心
memory: “64Mi” #所需最低内存资源(如果不足 64M,容器无法启动) - name: tomcat
image: tomcat:8.5
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义容器端口 - containerPort: 8080 #端口(必须为数组类型)
protocol: TCP #端口协议
resources: #定义资源限额
limits: #资源上限
cpu: “500m” #500m 表示 0.5 个逻辑核心,1000m 表示一个逻辑核心
memory: “128Mi” #内存单位可以使用 Gi、Mi、G、M 等形式
requests: #资源下限
cpu: “250m” #250m 表示 0.25 个逻辑核心
memory: “64Mi” #所需最低内存资源(如果不足 64M,容器无法启动) #创建 pod
kubectl create -f deploy_nginx_tomcat.yml #查看 pod 信息
kubectl get pod -n test
curl ip:80 #删除 deploy
kubectl delete -f deploy_nginx_tomcat.yml
9.Pod 环境变量
evn 属性是用于设置容器环境变量的列表,环境变量的定义要根据容器具体需求定义。
可通过下方命令获取 env 文档帮助:
kubectl explain pod.spec.containers.env
name 定义环境变量名称
value 定义变量值
案例:为 MySQL 添加环境变量设置 root 密码
vim env_mysql.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: env-mysql
namespace: test
spec:
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: env-mysql #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: env-mysql #pod 的标签
spec:
containers:
- name: mysql
image: mysql:5.7 #镜像版本
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义端口 - containerPort: 3306 #端口
protocol: TCP #端口协议
env: #定义环境变量 - name: “MYSQL_ROOT_PASSWORD” #变量名称(必须为数组类型)
value: “123456” #值 #创建 Pod
kubectl create -f env_mysql.yml #查看 Pod 信息
kubectl get pod -n test #查看 Pod 详细描述
kubectl describe pod -n test
10.Pod 容器进入方式
格式:kubectl exec -n 命名空间 -it pod 名称 -c 容器名称 – /bin/bash
-c 容器名为可选项,如果是 1 个 pod 中 1 个容器,则不用指定;
如果是 1 个 pod 中多个容器,不指定默认为第 1 个。
案例:进入上述案例中创建的 mysql 容器
kubectl exec -n test -it env-mysql-5f5548cd6c-45n47 -c mysql – /bin/bash
Pod 容器执行命令方式
kubectl exec deploy-nginx-698c84cc44-82mj9 -n test -c nginx – ls /etc/nginx
11.Pod 调度概述
在默认情况下,一个 pod 被调度到哪个 Node 节点运行是由 Scheduler 组件采用相应的算法计算出来的,这个过程是不
受人工控制的,但是在实际工作中,我们想要控制某些 pod 调度到指定的 Node 节点,就需要用到 pod 调度
k8s 提供了四种调度方式:
自动调度:pod 运行在哪个 Node 节点上,完全由 Scheduler 经过算法分配(默认的调度策略)
定向调度:NodeName、NodeSelector
亲和性调度与反亲和性调度:NodeAffinity、PodAffinity、PodAntiAffinity
污点(容忍)调度:Taints、Toleration
1.Pod 定向调度 NodeName
定向调度是通过在 pod 上声明 NodeName 或者 NodeSelector,以此将 pod 调度到指定的节点上,但是定向调度属于
强制调度,即使指定的 Node 节点不存在,也会向该节点进行调度,但是 pod 运行失败
案例:创建 pod,并通过节点名称将 Pod 调度到 k8s-node1 节点
#vim pod-nodename.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 1 #创建 pod 的副本数量,默认为 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
nodeName: k8s-node1 #定义调度策略,并指定 k8s-node1 节点
containers: - name: nginx
image: nginx:1.18.0
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义容器端口 - containerPort: #80 端口(必须为数组类型)
protocol: TCP #端口协议 #创建 deploy
kubectl create -f deplo_nginx.yml #查看 deploy 详细信息
kubectl get deploy -n test #删除
kubectl delete -f deplo_nginx.yml
2.Pod 定向调度 NodeSelector
nodeSelector 用于将 pod 调度到添加了指定标签的 node 节点上,该调度规则也是强制调度
案例:先为 k8s-node2 节点打标签,然后创建一个 pod,并通过 nodeSelector 进行调度 #打标签
kubectl label node k8s-node2 node=k8s-node2 #查看节点标签
kubectl get node k8s-node2 –show-labels | grep k8s-node2
创建 Pod 并通过 NodeSelector 进行调度
vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
nodeSelector: #定义 nodeSelector
node: k8s-node2 #指定节点标签
containers:
- name: nginx
image: nginx:1.20.0
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义容器端口 - containerPort: #80 端口(必须为数组类型)
protocol: TCP #端口协议 #创建 pod
kubectl create -f deploy_nginx.yml #查看 pod 详细信息
kubectl get pod -n test
kubectl get pod -n test -o wide #删除 deploy
kubectl delete -f deploy_nginx.yml
3.Pod 污点 Taints 概述
调度方式都是站在 pod 的角度上,通过在 pod 上添加属性,来确定 pod 是否要调度到指定的 node 上,其实也可以站在
node 的角度上,通过在 node 上添加污点属性,来决定是否允许 pod 调度过来 node 被设置上污点以后,就和 pod 之间
存在了一种相互排斥的关系,进而拒绝 pod 调度进来,甚至可以将已经存在的 pod 驱逐出去
污点的格式:key:污点,key 和 value 是污点的标签,目前支持如下三个污点:
PreferNoSchedule:尽量避免调度(软限制),除非没有其他节点可调度
NoSchedule:拒绝调度(硬限制),但不会影响当前已经存在的 pod
NoExecute:拒绝调度,同时也会将节点上已经存在的 pod 清除(尽量不要设置,会导致 Pod 异常)
使用 kubectl 设置和去除污点的命令实例如下:
设置污点
kubectl taint nodes k8s-node1 key:污点
去除污点
kubectl taint nodes k8s-node1 key:污点-
去除所有污点
kubectl taint nodes k8s-node1 key-
4.Pod 调度容忍 Toleration
污点的作用,可以通过在 worker 节点添加污点用于拒绝 pod 调度上来,但如果我们非要将一个 pod 调度到一个有污点
的 node 上,通过容忍(忽略污点)可以实现
案例:继上述案例,创建 pod 并添加容忍,然后将 pod 调度到 k8s-node1 节点
vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
tolerations: #添加容忍
- key: “k8s-node1” #污点的 key(必须引起来)
effect: NoSchedule #污点类型
containers: - name: nginx
image: nginx:1.20.0
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义容器端口 - containerPort: #80 端口(必须为数组类型)
protocol: TCP #端口协议 #创建 pod
kubectl create -f deploy_nginx.yml #查看 pod 详细信息
kubectl get pod -n test
kubectl get pod -n test -o wide #删除 deploy
kubectl delete -f deploy_nginx.yml
12.Pod 容器探测
容器探测类似于对容器进行健康检查,用来探测容器中的程序是否可以正常工作,如果探测到容器出现故障,k8s 会
尝试重启容器,如果重启失败,k8s 不会将流量分配给该容器,不承担业务流量。
k8s 提供了两种探针来实现容器的探测,可通过下边命令查看:
kubectl explain pod.spec.containsers
livenessProbe #存活性探针,用于检测容器当前是否处于正常运行状态,如果不是,容器将会被重启。
readinessProbe #就绪性探针,用于检测容器当前是否可以接收请求,如果不能,k8s 不会转发流量。
以上两种探针目前均支持多种探测方式,可通过下边命令查看:
kubectl explain pod.spec.containers.livenessProbe
kubectl explain pod.spec.containers.readinessProbe
FIELDS:
exec 命令探测方式
tcpSocket 端口探测方式
httpGet URL 请求探测方式
initialDelaySeconds 容器启动后等待多少秒执行第一次探测
timeoutSeconds 探测超时时间,默认 1 秒,最小可设置 1 秒
failureThreshold 连续探测失败多少次才被认定失败,默认 3 次为失败,最小可设置 1
periodSeconds 执行探测频率,默认是 10 秒,最小可设置 1 秒
successThreshold 连续探测成功多少次才被认定为成功,默认 1 次
以 livenessProbe 存活性探针的两种常用的探测方式:
1.Pod 容器探测 exec
方式一:exec 命令探测方式,在容器内执行一次命令,如果命令执行的退出码为 0,则认位程序正常,否则不正常。
vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
tolerations: #添加容忍
- key: “k8s-node1” #污点的 key(必须引起来)
effect: NoSchedule #污点类型
containers: - name: nginx
image: nginx:1.20.0
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义容器端口 - containerPort: #80 端口(必须为数组类型)
protocol: TCP #端口协议
livenessProbe: #存活性探针
exec: #命令探测方式
command: [/bin/ls,/etc/hello.txt] #探测一个不存在的文件 #创建 pod
kubectl create -f deploy_nginx.yml #查看 pod 详细信息
kubectl get pod -n test
kubectl get pod -n test -o wide #删除 deploy
kubectl delete -f deploy_nginx.yml
2.Pod 容器探测 tcpSocket
方式二:tcpSocket 端口探测方式,访问容器的端口,如果能够建立连接,则认位程序正常,否则不正常。
vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
tolerations: #添加容忍
- key: “k8s-node1” #污点的 key(必须引起来)
effect: NoSchedule #污点类型
containers: - name: nginx
image: nginx:1.20.0
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义容器端口 - containerPort: #80 端口(必须为数组类型)
protocol: TCP #端口协议
livenessProbe: #存活性探针
tcpSocket: #端口探测方式
port: 8080 #探测一个不存在的端口 #创建 pod
kubectl create -f deploy_nginx.yml #查看 pod 详细信息
kubectl get pod -n test
kubectl get pod -n test -o wide #删除 deploy
kubectl delete -f deploy_nginx.yml
13.Pod 容器重启策略
容器一旦出现了问题,K8s 就会对容器所在的 pod 进行重启,重启操作是由 pod 的重启策略决定的,pod 的重启策略有
三种,可通过下边命令查看
kubectl explain pod.spec.restartPolicy
Always:容器失效时,自动重启该容器,默认策略
OnFailure:容器终止运行且退出码不为 0 时重启(异常终止)
Never:无论容器状态如何,都不重启该容器
重启策略适用于 pod 中的所有容器,首次需要重启的容器,将在其需要时立即进行重启,随后再次需要重启的操作将
由 kubelet 延迟一段时间后进行,且反复的重启操作延时时长为 10s、20s、40s、80s、160s、300s,最长延时为
300s,以后重启延时均为 300s,直至重启成功
14.Pod 数量扩缩容
案例:通过 Deploy 对 pod 数量进行扩缩容
kubectl edit deploy deploy-nginx -n test
…
replicas: 2 #修改 pod 数量
15.Pod 版本更新策略
Deploy 支持两种镜像更新的策略:通过 strategy 属性进行配置
kubectl explain deploy.spec.strategy
Recreate:重建更新策略,一次性将所有旧版本 pod 全部重建成新版本 pod
RollingUpdat:滚动更新策略(默认策略),先删除一部分旧版本 pod,在更新成新版本 pod
1.Pod 版本更新 Recreate
案例:通过 Recreate 对 Pod 进行重建更新
vim deploy_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
strategy: #Pod 更新策略
type: Recreate #重建更新
replicas: 1
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
containers:
- name: nginx
image: nginx:1.20.0
imagePullPolicy: IfNotPresent #设置镜像拉取策略
ports: #定义容器端口 - containerPort: #80 端口(必须为数组类型)
protocol: TCP #端口协议 #创建 pod
kubectl create -f deploy_nginx.yml #查看 pod 信息
kubectl get pod -n test #删除 deploy
kubectl delete -f deploy_nginx.yml
2.Pod 版本更新 RollingUpdat
案例:通过 RollingUpdat 对 Pod 进行滚动更新(默认策略,无需指定,只需要将前边配置文件中的其他更新策略删除
即可)
16.Pod 版本回退
Deploy 支持版本升级过程中的暂停、继续、回退等功能,具体功能如下:
status #显示当前升级状态
history #显示升级历史记录
pause #暂停版本升级过程
resume #继续已经暂停的版本升级过程
restart #重启版本升级过程
undo #回滚到上一级版本(可以通过–to-revision 回滚到指定版本)
案例:多次更新镜像版本,随后对镜像版本进行回退 #查看升级历史记录
kubectl rollout history deploy deploy-nginx -n test #查看具体版本详细信息:–revision=版本编号
kubectl rollout history deploy deploy-nginx –revision=2 -n test #查看当前所有版本(通过 rs 可以查看)
kubectl get rs -o wide -n test #查看当前使用版本(查看 deploy)
kubectl get deploy -o wide -n test #版本回退:通过–to-revision=1,可直接回滚到 1 版本,如果省略这个选项,就是回退到上个版本
kubectl rollout undo deploy deploy-nginx –to-revision=2 -n test #查看当前使用的版本
kubectl get deploy -o wide -n test #查看升级历史记录
kubectl rollout history deploy deploy-nginx -n test
17.DaemonSet 控制器
DaemonSet(DS)控制器在功能方面与 Deployment 控制器几乎一样,支持滚动更新、版本回退等,只不过它在创
建 Pod 时,可以保障集群中的每一个节点上都运行(Pod 数量与节点数量保持一致)。
DaemonSet 控制器的特点:
每当像集群添加一个节点时,指定的 pod 副本也将添加到该节点上 当节点从集群中移除时,pod 也就被垃圾回收
1.DaemonSet 应用案例
案例:通过 daemonset 控制器创建 Nginx Pod,并保证在每个节点都运行。
vim ds_nginx.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-nginx
namespace: test
spec:
selector:
matchLabels:
name: ds-nginx
template:
metadata:
labels:
name: ds-nginx
spec:
tolerations: # 添加容忍,否则 pod 无法被调度到 master 节点
- key: node-role.kubernetes.io/master # 污点 key
effect: NoSchedule # 污点类型
containers: - name: nginx
image: nginx:1.18.0
ports: - containerPort: 80 #创建 pod
kubectl create -f ds_nginx.yml #查看 ds 信息
kubectl get ds -n test #查看 pod 详细信息
kubectl get pod -n test -o wide #删除 ds
kubectl delete -f ds_nginx.yml
18.HPA
Horizontal Pod Autoscaler(HPA)可以实现 pod 数量的自动扩缩容,对比于前边手动对 pod 数量进行调整,HPA 更
加的智能。
HPA 可以获取每个 pod 的资源利用率,然后和 HPA 中定义的资源利用率指标进行对比,同时计算出需要伸缩的具体
值,最后实现 pod 的数量的自动(非手动)调整。
案例:创建 HPA,通过 HPA 对 Pod 数量进行弹性自动伸缩
vim hpa-deploy_nginx.yml
apiVersion: autoscaling/v1 #自动扩缩容版本
kind: HorizontalPodAutoscaler
metadata:
name: hpa-nginx
namespace: test
spec:
minReplicas: 1 #最小的 pod 数量
maxReplicas: 10 #最大的 pod 数量
targetCPUUtilizationPercentage: 1 #cpu 使用指标,表示 10%(生产环境建议定义在 6-8)
scaleTargetRef: #指定要控制的 deploy 信息
apiVersion: apps/v1 #deploy 版本
kind: Deployment #deploy 类型
name: deploy-nginx #deploy 名称
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels:
app: deploy-nginx #标签
template: #创建 Pod 模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
containers:
- name: nginx
image: nginx:1.18.0
imagePullPolicy: IfNotPresent
ports: - containerPort: 80
六.K8s Service 四层负载均衡
k8s 的流量负载组件:Service 与 ingress,Service 用于 4 层流量的负载,ingress 用于 7 层流量负载。
kubernetes 集群中有三类网络,一类是真实存在的,如:Node 节点网络、Pod 网络,这两种网络均提供真实 IP 地
址。
还有一类是虚拟的 Service 网络,提供虚拟 cluster IP(VIP)地址,这个地址不会出现在接口上,仅会出现在 Service
当中。
在 kubernetes 集群时,由于 Pod 经常处于用后即焚状态,Pod 经常被重新生成,因此 Pod 对应的 IP 地址也会经常变
化,导致无法直接访问 Pod 提供的服务。
Kubernetes 中使用了 Service 来解决这一问题,即在 Pod 前面使用 Service 对 Pod 进行代理,无论 Pod 怎样变化 ,只要
有 Label,就可以让 Service 能够联系上 Pod,进而实现通过 Service 访问 Pod 目的。
1.Service 常用访问方式介绍
ClusterIP:默认访问方式,分配一个集群内部可以访问的虚拟 IP(该方式只能用于集群内部访问,外部无法访问)
NodePort:在每个 Node 上分配一个端口作为外部访问入口,端口范围为 30000-32767(该访问适用于外部访问)
LoadBalancer:通过在集群外部的公有云平台上,例如:阿里云、华为云、AWS 等做一个负载均衡,通过外部负载均衡将流
量转发到集群中。
访问过程:用户—–>域名—–>云服务提供商提供 LB 负载均衡设备—–>NodeIP:Port(service IP)—->Pod
IP:端口
2.Service 资源清单文件介绍
kubectl explain svc 查看 service 资源支持的属性
apiVersion: v1 #版本
kind: Service #资源类型
metadata: #元数据
name: #资源名称
namespace: #所属名称空间
spec: #描述
selector: #标签选择器,用于确定当前 service 代理哪些 pod
app: #标签
type: #Service 类型
clusterIP: #clusterIP 访问方式
ports: #端口信息 - protocol: TCP #端口协议
port: #访问 Service 使用的端口
targetPort: 3pod 中容器的端口
nodePort: #node 端口(Service 需要暴露给外部访问的节点端口,端口范围:30000-32767)
3.Cluster IP 应用案例
案例:通过 HPA 创建 3 个 Pod 并设置标签为 app=deploy-nginx 通过 Service ClusterIP 访问方式进行代理
vim hpa-deploy_nginx.yml
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: test
spec:
type: ClusterIP #service 默认访问方式
ports: #定义端口信息
- port: 80 #访问 service 使用的内部端口,可自定义
targetPort: 80 #指定 pod 中容器端口
selector: #标签选择器(基于标签选择代理的 Pod)
app: deploy-nginx #标签(需要与代理的 Pod 标签一致)
apiVersion: autoscaling/v1 #自动扩缩容版本
kind: HorizontalPodAutoscaler #类型
metadata:
name: hpa-nginx
namespace: test
spec:
minReplicas: 3 #最小的 pod 数量
maxReplicas: 10 #最大的 pod 数量
targetCPUUtilizationPercentage: 6 #cpu 使用指标,表示 60%
scaleTargetRef: #指定要控制的 nginx 信息
apiVersion: apps/v1
kind: Deployment #deploy 类型
name: deploy-nginx #deploy 名称
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 3
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
containers:
- name: nginx
image: nginx:1.18.0 #指定镜像
ports: #定义端口 - containerPort: 80 #端口
protocol: TCP #端口协议
resources: #资源限额
limits: #资源上限
cpu: 600m #cpu 1 核心的 60%的资源 #创建 Pod
kubectl create -f hpa-deploy_nginx.yml #查看 Pod 信息
kubectl get pod -n test #查看 Service 信息
kubectl get svc -n test #删除 Pod
kubectl delete -f hpa-deploy_nginx.yml
4.NodePort 应用案例
在生产环境中,Service 是需要暴露给外部访问的,那么就要用到 NodePort 类型的 Service,NodePort 的工作原理其
实就是在 Node 节点上暴露一个端口,然后外部主机就可以通过节点 IP+暴露端口来访问集群中的 pod 了
案例:将前边案例中的清单文件 Cluster IP 改为 NodePort 类型,实现外部访问。
vim hpa-deploy_nginx.yml
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: test
spec:
type: NodePort #service 类型
ports: #定义端口信息
- port: 80 #访问 service 使用的内部端口,可自定义
targetPort: 80 #指定 pod 中容器端口
nodePort: 30007 #外部访问 service 的端口
selector: #标签选择器(基于标签选择代理的 Pod)
app: deploy-nginx #标签(需要与代理的 Pod 标签一致)
apiVersion: autoscaling/v1 #自动扩缩容版本
kind: HorizontalPodAutoscaler #类型
metadata:
name: hpa-nginx
namespace: test
spec:
minReplicas: 3 #最小的 pod 数量
maxReplicas: 10 #最大的 pod 数量
targetCPUUtilizationPercentage: 6 #cpu 使用指标,表示 60%
scaleTargetRef: #指定要控制的 nginx 信息
apiVersion: apps/v1
kind: Deployment #deploy 类型
name: deploy-nginx #deploy 名称
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
replicas: 3
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
containers:
- name: nginx
image: nginx:1.17.0 #指定镜像
ports: #定义端口 - containerPort: 80 #端口
protocol: TCP #端口协议
resources: #资源限额
limits: #资源上限
cpu: 600m #cpu 1 核心的 60%的资源 #创建 Pod
kubectl create -f hpa-deploy_nginx.yml #查看 Pod 信息
kubectl get pod -n test #查看 Service 信息
kubectl get svc -n test #删除 Pod
kubectl delete -f hpa-deploy_nginx.yml
七.K8s Ingress 七层负载均衡
Ingress 相当于一个 7 层的负载均衡器,是 k8s 对反向代理的一个抽象,它的工作原理类似于 Nginx 反向代理
- 用户编写 Ingress 规则,说明哪个域名对应集群中的 Service
- Ingress 控制器动态感知 Ingress 服务规则的变化,然后生成一段对应的 Nginx 反向代理配置进行流量转发
1.Nginx Ingress 环境搭建
ingress-nginx 资源清单文件下载地址:https://raw.githubusercontent.com/kubernetes/ingressnginx/main/deploy/static/provider/baremetal/deploy.yaml #创建 ingress-nginx
kubectl create -f deploy.yaml #查看 ns(会有一个 ingress-nginx 的命名空间)
kubectl get ns #查看详细信息时会出现如下报错:
kubectl describe pod -n ingress-nginx
MountVolume.SetUp failed for volume “webhook-cert” :
secret “ingress-nginx-admission-token-bnrl4” not found
这个报错原因是当前运行的 ingress-nginx-admission-token 名称与 deploys.yml 文件中的名称不一致,需要对文件进
行修改 #解决方法:查看 ingress 的 secret
kubectl get secret -A |grep ingress
复制名字修改 yaml 中的名字后更新文件 #查看 ingress-nginx 空间的 pod(有两个 Pod 用于执行一次性任务,状态为 Completed(完成),这种 Pod 执行后即退
出。)
kubectl get po -n ingress-nginx
2.Nginx Ingress HTTP 应用案例
案例:通过 Deployment 部署 tomcat 与 nginx 的 pod,并通过 Nginx Ingress 进行 HTTP 访问
vim ingress-http.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
selector:
matchLabels:
app: deploy-nginx
template:
metadata:
labels:
app: deploy-nginx
spec:
containers:
- name: nginx
image: nginx:1.18.0
ports: - containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: test
spec:
selector:
app: deploy-nginx
clusterIP: None
type: ClusterIP #service 类型
ports:
- port: 80
targetPort: 80
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-tomcat
namespace: test
spec:
selector:
matchLabels:
app: deploy-tomcat
template:
metadata:
labels:
app: deploy-tomcat
spec:
containers:
- name: tomcat
image: tomcat:8.5-jre10-slim
ports: - containerPort: 8080
apiVersion: v1
kind: Service
metadata:
name: svc-tomcat
namespace: test
spec:
selector:
app: deploy-tomcat
clusterIP: None
type: ClusterIP #service 类型
ports:
- port: 8080
targetPort: 8080
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-http #自定义 ingress 名称
namespace: test
annotations:
ingressclass.kubernetes.io/is-default-class: “true”
kubernetes.io/ingress.class: nginx #指定控制器的类别为 nginx
spec:
rules: #定义主机列表
- host: www.nginx.com #自定义域名
http:
paths: - pathType: Prefix #路径类型
path: “/“ #定义站点路径
backend: #定义后端引用的服务
service: #关联 service
name: svc-nginx #对应上面创建的 service 名称
port:
number: 80 #service 端口 - host: www.tomcat.com #自定义域名
http:
paths: - pathType: Prefix #路径类型
path: “/“ #定义站点路径
backend: #定义后端引用的服务
service: #关联 service
name: svc-tomcat #对应上面创建的 service 名称
port:
number: 8080 #service 端口
创建
创建 ingress 报错
[root@master01 data]# kubectl apply -f ingress-nginx.yml
Error from server (InternalError): error when creating
“ingress-nginx.yml”: Internal error occurred: failed
calling webhook “validate.nginx.ingress.kubernetes.io”:
failed to call webhook: Post “https://ingress-nginxcontrolleradmission.ingressnginx.svc:443/networking/v1/ingresses?timeout=10s“: remote
error: tls: internal error
查看 ingress-nginx-admission
kubectl get validatingwebhookconfigurations
删除 ingress-nginx-admission
kubectl delete -A ValidatingWebhookConfiguration
ingress-nginx-admission
重新创建 ingress
kubectl apply -f ingress-nginx.yml
查看信息
[root@master01 ~]# kubectl get all -n test
查看 ingress 信息
[root@master01 ~]# kubectl get ing -n test
八.configmap,secret 配置与秘钥管理
1.ConfigMap
我们在部署应用的时候, 许多应用程序会从配置文件、命令行参数或环境变量中读取所需的配置信息,这些配置信
息需要与 docker image 解耦,不然你总不能每修改一个配置就重做一个 image 。
如果这些应用数量较多且分散在集群的不同节点上,而我们又需要对这些节点的服务配置进行批量修改,如果每个服
务都单独修改的话,那么更新配置就很麻烦, 所以 k8s 中引入了 Configmap 资源对象, 提供了向容器中注入配置信
息的机制,主要作用就是为了让服务和配置文件解耦,以便实现配置的统一管理。
Configmap 是 k8s 中的资源,以键值对的形式保存一些非机密性数据, 相当于配置文件。 1.使用 ConfigMap 的限制条件:
- ConfigMap 需要在 Pod 启动前创建出来;
- 并且只有当 ConfigMap 和 Pod 处于同一命名空间时,才可以被 Pod 引用;
- 当 Pod 挂载 ConfigMap 绑定的目录时,目录下的目录并不会挂载到 Pod 内,只有目录下的文件会被挂载。
- ConfigMap 在设计上不是用来保存大量数据的,在 ConfigMap 中保存的数据不可超过 1 MiB,如果你需要保存超出此限制
的数据,可以考虑挂载存储卷。
2.ConfigMap 创建与使用
kubectl create cm cm-ngx-config –fromfile=/opt/nginx.conf -n test
kubectl get cm -n test
kubectl describe cm cm-ngx-config -n test
创建 nginx 的 Pod,并使用 Volume 将 ConfigMap 挂载到 nginx 容器中
#vim cm-nginx-config.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-nginx
namespace: test
spec:
replicas: 1
selector:
matchLabels:
app: web-nginx
template:
metadata:
labels:
app: web-nginx
spec:
volumes:
- name: nginx-config # 卷的名称(自定义)
configMap: # 卷类型是 configMap
name: cm-ngx-config # configmap 的名称
containers: - name: web-nginx
image: nginx:1.18-alpine
ports: - containerPort: 80
volumeMounts: # 定义在容器中挂载的信息 - name: nginx-config # 挂载的名称(上边定义的卷的名称)
mountPath: /etc/nginx/conf.d # 挂载到容器的路径 #创建
kubectl create -f cm-nginx-configmap.yml
2.Secret
Secret 与 ConfigMap 类似,主要的区别是 ConfigMap 存储的是明文,而 Secret 存储的是密文。
可以用于存储和管理一些敏感数据,比如密码,token,密钥,证书等敏感信息。
它把 Pod 想要访问的加密数据存放到 Etcd 中,然后用户就可以通过在 Pod 的容器里挂载 Volume 的方式或者环境变
量的方式访问到这些 Secret 里保存的信息了。
1.Secret 有 4 种类型
Opaque: base64 编码格式的 Secret,用来存储密码、密钥,类型标识符为 generic
Service Account: 用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 pod
的/var/run/secrets/kubernetes.io/serviceaccount 目录中
kubernetes.io/dockerconfigjson: 用来存储私有 docker registry 的认证信息,类型标识为 docker-registry。
kubernetes.io/tls: 用于为 SSL 通信模式存储证书和私钥文件,命令式创建类型标识为 tls。
2.Secret 应用案例
vim secret-mysql.yml
apiVersion: v1
kind: Secret
metadata:
name: secret-mysql
namespace: test
data:
password: MTIzNDU2 #创建
kubectl apply -f secret-mysql.yml
kubectl get secret -test |grep secret-mysql
3.Secret 的使用方式
创建 MySQL 的 Pod,并通过环境变量的方式传递给 pod 使用。
#vim pod-mysql-secret.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-mysql
namespace: test
spec:
selector:
matchLabels:
app: deploy-mysql
template:
metadata:
labels:
app: deploy-mysql
spec:
containers: - name: mysql
image: mysql:5.7
ports: - containerPort: 80
env: - name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: secret-mysql # 对应创建的 secret 名字
key: password #创建
kubectl apply -f pod-mysql-secret.yml
九.认证及 Service Account、鉴权 RBAC
k8s 作为一个分布式集群的管理工具,保证集群的安全性是非常重要的任务,所谓的安全性其实就是保证对 k8s 的各种
客户端进行认证和鉴权操作。
k8s 集群的所有的操作基本上都是通过 apiserver 这个组件进行的,k8s 对于访问 API 来说提供了三个步骤的安全措
施:认证、鉴权、准入控制。
k8s 的认证机制非常多,要想一个个搞清楚也绝非易事,我们只需要掌握几个比较重要且使用广泛的认证机制即可。
1.k8s 用户分类
普通用户(k8s 用户):可以理解为人通过 kubectl 以及一些客户端工具访问 apiserver 时所需要认证的用户,此类用户
嵌入在客户端的证书中。
ServiceAccount(服务账户): 指在 kubernetes 集群中的 pod 要访问 apiserver 时所使用的,也就是
serviceaccounts。
2.k8s 鉴权及 RBAC
ApiServer 目前支持以下几种鉴权策略: AlwaysDeny:表示拒绝所有请求,一般用于测试 AlwaysAllow:允许接收
所有请求,相当于集群不需要授权流程 ABAC:基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行
匹配和控制 Webhook:通过调用外部 REST 服务对用户进行授权 Node:是一种专用模式,用于对 k8s 发出的请求进
行访问控制
十.K8S 数据存储
由于容器的生命周期不稳定,可能随时被创建与销毁,如果容器被销毁后,在容器中产生的数据也会被清除,如果需
要对容器内的数据实现持久化保存,我们需要将容器内的数据与 pod 分离,将数据放在专门的存储卷上 1.存储卷的分类
kubernetes 支持的存储卷类型非常丰富,使用下面的命令查看
kubectl explain pod.spec.volumes
K8s 支持的存储类型大体分为如下几类:
本地存储卷
emptyDir(空目录临时存储):pod 删除,数据也会被清除, 用于数据的临时存储
hostPath:宿主机目录映射(本地存储卷),pod 删除,目录中的数据不会被清楚,适合数据的永久保存
网络存储卷
NAS 网络附加存储: nfs 等
分布式网络附加存储: glusterfs,cephfs,rbd(chph 中的存储类型),cinder(OpenStack 中的存储类型)等
SAN 块存储: iscsi,FC 等
云存储: aws,azurefile 等 2.本地存储 EmptyDir
EmptyDir 是最基础的存储类型,一个 EmptyDir 就是主机上的一个空目录 EmptyDir 是在 Pod 被分配到 Node 节点时创
建的,它的初始内容为空,并且无需指定宿主机上对应的目录文件,应为 k8s 会自动分配一个空目录,当 Pod 销毁
时,EmptyDir 中的数据也会被永久删除。
EmptyDir 用途如下:
临时存储空间,例如用于某些应用程序运行时所需要的临时目录,且无需永久保留
同一个 Pod 中容器需要从另一个容器中获取数据的目录(多容器间共享数据)
案例:通过创建一个 nginx 的 Pod 并使用 emptydir 作为数据的临时存储
#vim emptydir_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
volumes: 声明 volume 存储卷
- name: nginx-logs 定义 volume 卷名称
emptyDir: {} 类型为 emptyDir,{}表示空目录
containers: - name: nginx
image: nginx:1.17.0 #指定镜像
ports: #定义端口 - containerPort: 80 #端口
volumeMounts: - name: nginx-logs 指定挂载的 volume 名称
mountPath: /var/log/nginx 容器内挂载点目录 #创建
kubectl create -f emptydir_nginx.yml 3.本地存储 HostPath
HostPath 是将 Node 节点中一个实际目录挂载到 Pod 中,以供容器使用,这样的设计可以保证 Pod 销毁了,但是数据
仍然可以保存在宿主机上,实现数据永久保存。
案例:创建 nginx,并通过 hostPath 存储卷方式对 nginx 实现数据持久化保存。
vim hostpath_nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-nginx
namespace: test
spec:
selector: #标签选择器(基于选择器匹配 Pod)
matchLabels: #标签类型
app: deploy-nginx #匹配 pod 的标签(表示 deploy 管理带有此标签的 Pod)
template: #pod 的配置模板
metadata:
labels:
app: deploy-nginx #pod 的标签
spec:
volumes: 声明 volume 存储卷
- name: nginx-html 定义 volume 卷名称
hostpath: 类型 hostPath
type: DirectoryOrCreate 目录存在就使用,不存在就先创建后使用
path: /nginx/html 指定 node 节点目录(存放页面)
containers: - name: nginx
image: nginx:1.17.0 #指定镜像
ports: #定义端口 - containerPort: 80 #端口
volumeMounts: - name: nginx-html 指定挂载的 volume 名称
mountPath: /usr/share/nginx/html 容器内挂载点目录 #创建 pod
kubectl create -f hostpath_nginx.yml






