自动补全

​ RHEL系默认最小化安装时自动补全仅支持命令和文件名,可以通过安装bash-completion 包使其支持补全命令参数

1
2
sudo dnf install bash-completion
source /usr/share/bash-compldetion/nasj_completion

Docker

添加docker仓库

1
sudo dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装docker

1
2
3
4
# 指定docker版本是需要两个都指定
dnf install docker-ce docker-ce-cli
# 可以通过以下指令查看仓库可用版本
dnf list docker-ce --showduplicates

设置开机自启

1
sudo systemctl enable --now docker

配置国内镜像仓库

1
2
3
4
5
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://docker.1panel.live"]
}
EOF

常用命令

镜像

镜像命令 说明
docker search 检索镜像
docker pull 拉取镜像
docker images 展示已拉取镜像列表
docker rmi 删除本地镜像
docker commit 将容器打包成镜像
docker save 将镜像保存为文件
docker load 将本地镜像加载到docker
1
2
3
4
5
6
7
8
9
docker commit mynginx mynginx:v1.0
-a 作者
-c 更改列表
-m 提交信息(参考Git)

docker save -o mynginx.tar mynginx:v1.0
-o 导出为文件

docker load -i mynginx.tar

容器

容器命令 说明
docker run 使用镜像启动容器
docker ps 展示容器列表
docker stop 停止容器
docker start 启动容器
docker restart 重新启动容器
docker status 查看容器状态
docker logs 查看容器日志
docker exec 进入容器
docker rm 删除容器
docker inspect 查看容器详细信息
1
2
3
4
5
6
7
8
docker run -p 90:80 -e NAME=nginx -d --name mynginx nginx 
-p 端口映射,将容器中的89端口映射到宿主机的90端口
-d 后台运行
--name 容器名称
-e 配置容器环境变量

docker exec -it mynginx bash
-it 以交互模式运行bash命令

数据卷

1
2
3
4
5
6
# 挂载数据卷
docker run -v ~/data:/root/data -d --name mynginx1 centos:7

# 挂载数据卷容器
docker run -p 90:80 -d --name mynginx2 nginx --volumes-from mynginx1 centos:7

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 指定父镜像
FROM centos:7

# 运行命令
RUN echo "Hello Docker"

# 构建时复制文件进镜像
COPY /root

# 构建时添加文件进镜像,可以来源于远程服务
ADD /root

# 环境变量
ENV NAME=test

# 只在构建时使用的参数,如果与ENV同名则会被覆盖
ARG NAME=test

# 指定可以使用-v挂载的目录
VOLUME /etc/nginx

# 指定工作目录
WORKDIR /root

# 指定执行用户
USER root

# 暴露80端口
EXPOSE 80

# 容器启动时执行命令
CMD nginx
1
2
3
docker build -f ./dockerfile -t app .
-f 指定dockerfile文件路径
-t 指定镜像名称

开机自启

1
2
3
4
5
6
7
8
docker run -id --name=rocky --restart=always rockylinux:9

--restart 设置开机自启
on 默认,不重启
on-failure 非正常退出重启
on-failure:n 非正常推出重启,并指定重启次数
always 只要容器退出就重启
unless-stopped 手动退出的重启

网络

网络模式

bridge网络(默认):在这种模式下,每个容器都有自己的虚拟网卡和虚拟 IP 地址。容器通过 docker0 虚拟网桥与宿主机的网络进行通信。外部主机不能直接访问容器内部的服务,需要通过宿主机的端口映射来间接访问

Host模式:容器不会虚拟出网卡,而是与宿主机共享网络,拥有宿主机的IP地址和网卡信息

1
docker run -id --net=host --name=rocky rockylinux:9

Container模式:指定新创建的容器与已存在的容器共享一个网络

1
docker run -id --net=container:rocky2 --name=rocky rockylinux:9

None模式:仅有lo网卡,Docker不会为其配置网络,需要自己为容器添加网卡,配置IP

自定义容器网络

1
2
3
4
5
6
7
8
9
10
11
# 创建自定义网络
docker network create --driver bridge --subnet 10.0.0.0/8 --gateway 10.0.0.254 mynet

# 指定容器使用指定网络
docker run -id --net=mynet --name=rocky rockylinux:9

# 默认网络和自定义网络默认不能通信,可以将容器加入其他网络打通通信
docker network connect mynet rocky

# 将容器移除网络
docker network disconnect mynet rocky

容器互联

容器互联可以实现容器之间通过容器名称进行通信(hosts映射解析)

1
2
docker run -id --name=rocky01 rockylinux:9
docker run -id --name=rocky02 --link rocky01 rockylinux:9

资源限制

1
2
3
4
docker run -d --name=rocky01 -m 200m --cpuset-cpus 1 rockylinux:9.0
-m 限制使用多少内存
--cpuset-cpus 1 限制使用cpu核心数(0是一核心)
docker update -m 300m --cpuset-cpus 2 rocky01

docker-complete

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: '3.8'					# dockercomplete版本
services:
db: # 服务名称
container_name: mysql # 容器名称
image: wp-mysql:8.0 # 容器镜像
expose: # 暴露端口
- 3306
ports: # 端口映射
- 3306:3306
volumes: # 挂在数据卷
- ./mysql_data/:/var/lib/mysql

wordpress:
container_name: wordpress
image: wordpress:v6.0
expose:
- 80
ports:
- 80:80
1
2
3
4
5
6
7
8
9
10
11
12
# 输出配置文件
docker-compose cofig
# 创建容器(默认扫描当前目录docker-compose.yaml文件)
docker-compose up -d
# 查看容器信息
docker-compose ps
# 停止容器
docker-compose stop
# 启动容器
docker-compose start
# 删除容器
docker-compose down

Kubernetes

单主集群部署

配置主机名本地解析

1
2
3
4
5
vim /etc/hosts

192.168.122.100 master
192.168.122.101 node1
192.168.122.102 node2

开启bridge网桥过滤

配置内核参数,并加载使其生效

1
2
3
4
5
6
7
8
9
10
11
12
13
# /etc/sysctl.d目录用来存放内核参数配置文件

cat > /etc/sysctl.d/k8s.conf <<EOF
# 对网桥上的IPv6数据包通过iptables处理
net.bridge.bridge-nf-call-ip6tables = 1
# 对网桥上的IPv4数据包通过iptables处理
net.bridge.bridge-nf-call-iptables = 1
# 开启IPv4路由转发,用来实现集群中容器跨网段通信
net.ipv4.ip_forward = 1
EOF

# 加载配置文件
sysctl -p /etc/sysctl.d/k8s.conf

加载br_netfillter模块并验证是否成功

1
2
3
4
5
# modprobe命令用来自动加载指定模块
modprobe br_netfilter

# 验证是否成功
lsmod | grep br_netfilter

安装IPvs代理模块

1
dnf -y install ipset ipvsadm

将模块加载进系统

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# /etc/modules-load.d用来存放用户需要加载的自定义模块
cat > /etc/modules-load.d/ipvs.conf <<EOF
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF

# 重启服务
systemctl restart systemd-modules-load.service

# 验证
lsmod | grep ip_vs

关闭SWAP分区

1
2
3
# 关闭swap分区
swapoff
# 修改fstab文件删除swap分区自动挂载

安装docker

tip:docker版本需要在20.10之前,之后的版本k8s官方没有做过检测

需要启用Docker Cgroup,用来限制给容器分配的资源

1
2
3
4
5
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"]
"registry-mirrors": ["https://docker.1ms.run"]
}

配置k8s镜像仓库

1
2
3
4
5
6
7
8
9
10
11
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
# 关闭selinux
setenforce 0

安装集群相关软件

kubeadm:用于初始化集群,并配置集群所需的组件并生成对应的安全证书和令牌(使用docker安装1.24之前版本)

kubelet:负责与Master节点通信,并根据Master节点的调度决策来创建、更新和删除Pod,同时维护Node节点上的容器状态

kubectl:用于管理集群的命令行工具

1
dnf install kubeadm-1.23.10 kubelet-1.23.10 kubectl-1.23.10

开启kubelet Cgroup

1
2
3
tee > /etc/sysconfig/kubelet <<EOF
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
EOF

设置开机自启

1
systemctl enable kubelet

初始化集群(mater)

查看k8s组件镜像

1
kubeadm config images list

初始化配置文件

1
kubeadm config print init-defaults > kube-init.yml

修改配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
# 管理节点ip
advertiseAddress: 192.168.177.201
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
imagePullPolicy: IfNotPresent
# 节点在集群中的名称
name: master
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.23.0
networking:
dnsDomain: cluster.local
serviceSubnet: 10.96.0.0/12
scheduler: {}

通过配置文件初始化
1
kubeadm init --config kube-init.yml

生成集群token并将节点加入集群

1
2
3
# 生成token
kubeadm token create --print-join-command
# 在需要加入的节点输入打印命令

验证

1
kubectl get nodes

如果节点出现问题可以重置节点

1
kubectl restart

部署Pod网络 Calico是k8s网络插件,可以为集群中的Pod提供网络功能

1
2
3
4
5
6
7
8
# 在master节点拉去Calico配置文件
wget https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/calico.yaml

# 创建calico网络
kubectl apply -f calico.yaml

# 查看Pod状态
kubectl get pod -n kube-system

安装Web界面

安装kuboard

1
2
3
4
5
6
7
8
9
docker run -d \
--restart=unless-stopped \
--name=kuboard \
-p 80:80/tcp \
-p 10081:10081/tcp \
-e KUBOARD_ENDPOINT="http://内网IP:80" \
-e KUBOARD_AGENT_SERVER_TCP_PORT="10081" \
-v /root/kuboard-data:/data \
eipwork/kuboard:v3

资源管理方式

查看所有资源对象

1
kubectl api-resources

常用资源对象

资源名称 资源作用
nodes 集群节点
namespaces 名称空间
pods 容器组
services 四层代理
ingress 七层代理
persistentvolumes 存储卷
persistentvolumeclaims 存储卷
configmaps 配置资源
secrets 密钥资源
serviceaccount 服务账户

kubeclt命令

命令 作用
create 创建资源
apply 创建/更新资源
edit 编辑资源
get 查看资源
delete 删除资源
explain 查看资源文档
describe 显示资源详细信息
logs 输出pod中容器日志
expose 在命令行暴露资源端口
run 在命令行运行一个容器
exec 进入pod中的容器
cp 在pod内外复制文件
rollout 管理资源的版本
scale 扩/缩pod的数量
label 标签管理
cluster-info 显示集群信息

命令格式

1
2
3
4
5
kubeclt [command] [type] [name] [flags]
--command: 指定指定命令
--type:指定资源对象类型
--name:指定资源对象名称
--flags:指定格外可选参数
### namespace名称空间 | 名称 | 存在资源对象 | 作用 | | —————- | :————–: | ———— | | defalut | | 默认名称空间 | | kube-node-lease | lease | 集群健康状态 | | kube-public | configmap&secret | 存储集群公共信息,证书等 | | kube-kube-system | | k8s系统组件 | ### YAML方式操作
1
2
3
4
5
6
7
8
9
# 通过kubectl explain 资源对象   查看支持属性
---
apiVersion: v1
kind: Namespace
metadata
name: kuboard
---
apiVersion: 版本 通过kubectl api-resources查看
kind: 资源类型

Pod控制器

Pod控制器主要用于对Pod生命周期,副本数等进行管理 1. 副本管理:指定Pod在集群中的副本数 2. 自我修复:通过控制器监控Pod状态,发现异常或删除会自动修复或创建 3. 扩/缩容:动态增加副本数 4. 版本管理:通过控制器可实现程序的升级和回退

Pod各阶段状态

  1. Pending:Pod已经被系统接收,但是它需要完成一些准备工作才能运行。这些工作包括分配到指定节点上,下载容器镜像等。这个阶段就是Pod的“准备”阶段。
  2. Running: Pod已经被分配到节点上,同时Pod中容器已经常见,至少有一个容器在运行或处于启动重启状态,这个阶段可以被看做是Pod的“运行”阶段。
  3. Succeeded: Pod的所有容器都已经成功完成了它们的任务,并且都成功地终止了且不会再重启。这个阶段看作是Pod的”完成“阶段。
  4. Error: Pod中的容器时因为启动或运行失败而停止的,这个阶段可以被看做是Pod的”失败“阶段。
  5. Unkonow: 系统无法确定Pod的状态。通常是因为与Pod所在的主机通讯失败导致,这个阶段可以被看做是Pod的”未知“阶段。
  6. CrashLoopBackOff: 这个状态通常意味着Pod中的一个或多个容器在启动后立即崩溃,系统在重新启动它,但是连续多次尝试都失败了。 ### ReplicaSet控制器

ReplicaSet控制器具备副本管理、自我修复、扩缩容、Pod调度等功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
---

apiVersion: v1
kind: Namespace
metadata:
name: rs-ns

---

apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-nginx
namespace: rs-ns
spec:
replicas: 2
selector:
matchExpressions:
- key: app
operator: In
values:
- nginx
template:
metadata:
labels:
app: nginx
namespace: rs-ns
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: http
containerPort: 80
hostPort: 80
protocol: TCP

---

Deployment控制器

Deployment控制器在RS上进行扩展,具备RS所有功能并支持版本的滚动更新和版本回退。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
---
apiVersion: v1
kind: Namespace
metadata:
name: dm-ns

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dm-nginx
namespace: dm-ns
spec:
replicas: 2
selector:
matchLabels
app: nginx
template:
metadata:
labels:
app: nginx
namespace: dm-ns
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: http
containerPort: 80
hostPort: 80
protocol: TCP
---

operator标签选取策略

matchLabels属性用于设置控制器所管理容器标签策略,共支持四种策略。 1. In: key相同同时value包含在列表中。 2. NotIn: key相同但value不在列表中。 3. Exist: 不指定value,只要key相同即可。 4. DoesNotExist: key不存在。 #### 镜像拉取策略

spec.containers.imagePullPolicy 属性用于设置镜像拉取策略,共支持三种策略 1. Always: 总是从远程仓库拉取镜像。 2. IfNotPresent: 本地有则使用本地镜像,本地没有则从远程仓库拉取。 3. Never: 只使用本地仓库,本地没有则报错。

资源限制

spec.containers.resources 属性用于设置容器资源限制,支持对CPU和内存。 1. limits: 限制容器资源上限,当容器超出该使用量时,容器会被终止并重启。 2. requests: 限制容器资源下限,当资源不足时容器会启动失败。

1
2
3
4
5
6
7
resources: 
limits:
memory: "100M"
cpu: "1000m" #1000m代表1核心,也可以用0表示1核心
requests:
memory: "10M"
cpu: "100m"
#### Pod中多容器及管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-nginx
namespace: rs-ns
spec:
replicas: 2
selector:
matchExpressions:
- key: app
operator: In
values:
- nginx
template:
metadata:
labels:
app: nginx
namespace: rs-ns
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- name: http
containerPort: 80
hostPort: 80
protocol: TCP
- name: redis
image: redis:latest
ports:
- name: redis
containerPort: 6379
protocol: TCP

单Pod多容器进入容器执行命令时需要指定容器,否则默认会进入到第一个容器中。

1
2
3
4
# kubectl exec -it -n 名称空间 Pod名称 -c 容器名称 -- 命令
kubectl exec -it -n test nginx-dbcc-aw23k -c redis -- bash
-c 指定需要进入的容器名称
-- bash 需要执行的命令

配置容器变量

spec.containers.env 属性用于设置容器环境变量。 - name : 定义环境变量名称。 - value : 定义变量值。

1
2
3
4
5
env:
- name: TZ
value: "Asia/Shanghai"
- name: MYSQL_ROOT_PASSWORD
value: Admin123...

Pod调度策略

Pod调度默认情况下由Scheduler进行角度,可以通过修改调度策略来将Pod调度到指定节点上。 - 定向调度: 通过在Pod上声明nodeName或者nodeSelector将pod调度到指定节点,该调度属于强制调度,即使不存在也会向节点调度,但是会运行失败。 - 亲和度调度: 指定Pod调度到某些存在标签匹配的Pod的节点 - 反亲和度调度: 指定Pod不调度到某些存在标签匹配的Pod的节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 定向调度
# nodeSelector是通过node标签指定node,通过以下命令打标签
# kubectl label node node01 selector=node01
---
# nodeName
spec:
nodeName: node01
---
# nodeSelector
spec:
nodeSelector:
selector: node01
---
# requiredDuringSchedulingIgnoredDuringExecution:硬亲和,必须满足要求。
# preferredDuringSchedulingIgnoredDuringExecution:软亲和,当资源不足是可以不满足要求

# 亲和度调度
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
db: mysql #期望亲和的pod标签
---
# 反亲和度调度
spec:
affinity:
podAntAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
db: mysql
---

Pod污点与容忍

  • 污点(Taint): 通过在节点添加污点属性,可避免Pod被分配到不合适的节点。
    • PreferNoSchedule: 避免调度(软限制)除非没有其他节点可调度。
    • NoSchedule: 拒绝调度(硬限制)不影响当前节点已存在的Pod。
    • NoExecute: 拒绝调度,同时驱逐已经在的Pod。
1
2
3
4
# 给节点添加/更新污点
kubectl tain node node01 node=node01:PreferNoSchedule
# 删除节点污点
kubectl tain node node01 node=node01:PreferNoSchedule-
  • 容忍(Toleration): 通过在Pod上添加容忍属性,允许Pod被调度到带有污点的节点上。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Equal检查key和value必须都相等
# Exists不需要检查value,只需要key和类型匹配即可
---
spec:
tolerations:
- key: node
operator: "Equal"
value: "node01"
---
spec:
tolerations:
- key: node
operator: "Exists"
effect: PreferNoSchedule
--

容器探测检查

pod.spec.containers 下探针属性用于检查,判断容器中的程序是否可以正常工作。 - livenessProbe: 存活探针,检测容器是否为正常运行状态,否则容器会重启。 - readinessProbe: 就绪探针,检测容器当前是否能接受请求,如果不能,则不会分配流量,但不会被重启。

探针下属性 说明
exec 通过在容器内执行命令,判断是否正常
tcpSocket 通过访问容器特定端口,判断是否正常
httpGet 通过向容器发送HTTP请求,根据返回状态码,判断是否正常
initialDelaySeconds 启动后等待多少秒执行第一次探测
timeoutSeconds 探测超时时间
failureThreshold 连续探测多少次才认定失败,默认3次
periodSeconds 执行探测频率,默认是10秒探测一次,最小可设置1秒
successThreshold 连续探测多少次才认定成功,默认1次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
---
spec:
containers:
livenessProbe:
exec:
command:
- /ls
- /etc/passwd
---
spec:
containers:
livenessProbe:
tcpSocket:
port: 80
---
spec:
containers:
livenessProbe:
httpGet:
port: 80
path:/user/index.html
---

Pod重启策略

pod.spec.containers.restartPolicy 用于控制Pod的重启策略,k8s共支持三种重启策略,初始化容器时才能使用。 - Always: 容器异常时,自动重启容器(默认)。 - OnFailure: 容器异常终止运行时,自动重启该容器。 - Never: 无论容器状态如何,都不重启该容器。

Pod更新策略

Deployment控制器支持两种Pod更新,通过deployment.spec.strategy 属性配置 - Recreate: 重建更新,首先停止所有旧的Pod,然后创建新的Pod。 - RollingUpdate: 滚动更新,逐步替换旧的Pod,以确保更新过程中服务持续可用。

1
2
3
4
5
6
7
8
9
10
11
---
spec:
strategy:
type: Recreate
---
spec:
strategy:
rollingUpdate:
maxUnavailable: 1 #每次停止的pod数量
maxSurge: 1 #每次创建的pod数量
---

Pod版本回退

1
kubectl rollout <command> --option
命令 说明
histroy 查看版本历史
undo 回退版本
status 显示升级状态
pause 暂停升级
resume 继续升级
restart 重启升级过程

DaemonSet控制器

功能与Deployment几乎一样,适合部署系统级别的服务,如日志收集,节点监控,网络插件。(Deployment不能保证每个pod跑在每个节点中,DaemonSet能保证每个节点都运行一个Pod副本)

HPA自动伸缩控制器

HPA(Horizontal Pod Autoscaler)控制器,可以帮助Deployment或者StatefulSet控制器自动调整Pod副本数量,需要Metrics Server组件。 Metrics Server 是k8s的一个核心监控组件,用于收集和存储每个节点Pod的CPU和内存资源使用情况。(有坑)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: hap-nginx
namespace: dm-ns
spec:
# 定义需要控制的控制器类型和名称
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: dm-nginx
# 最小Pod数
minReplicas: 1
# 最大Pod数
maxReplicas: 10
metrics:
# 扩容条件类型为资源
- type: Resource
resource:
# 资源类型menery
name: cpu
target:
# 监控类型,百分比,绝对值,平均值
type: Utilization
# 扩容的条件,cpu占用达到上限50%时扩容
averageUtilization: 50

负载均衡

因为Pod是经常创建、销毁,因此Pod对应的IP经常会发生变化,k8s通过Service来解决这一问题,在Pod前使用Service对Pod进行代理,Service通过Pod的标签将流量转发到Pod中。 Service本质就是一条代理规则,真正实现代理功能的是Kube-Proxy组件,创建Service时相当于创建了一条代理规则,然后Kube-Proxy负责在Pod之间进行负载均衡。 #### Kube-Proxy代理模式

Kube-Proxy使用iptables和ipvs模式来处理流量,iptable是一个防火墙应用程序,ipvs是linux内核提供的一个负载均衡处理模块。 iptables:该模式下当Service被创建时,Kube-Proxy会给每个节点添加相应的iptables规则,iptables在处理规则时会遍历规则表,从上到下逐条匹配,所以iptables规则越多则查询速度就越慢,同时会消耗大量CPU资源导致性能下降。 ipvs: 该模式下Kube-Proxy会生成一个ipvs规则表,表中记录着Service的虚拟IP地址,以及Service代理的后端Pod地址,通过哈希表ipvs实现快速查找转发。

切换ipvs模式

1
2
3
4
5
6
7
8
9
10
11
12
查看cm
kubectl get cm -n kube-system
#编辑kube-proxy
kubectl edit cm kube-proxy -n kube-system
#修改mode选项为ipvs
mode: "ipvs"
#重启kube-proxy pod
#查看kube-proxy pod 携带的标签
kubectl get pod -n kube-system --show-labels
#根据标签删除所有kube-proxy pod
kubectl delete pod -l k8s-app=kube-proxy -n kube-system

Service访问方式

Service工作在第4层(运输层),处理基于IP和端口的流量,主要用于集群內部的服务发现和负载均衡。 - ClusterIP:默认访问方式,分配一个集群内部可以访问的虚拟IP,该方式仅限集群內部使用,外部无法访问。 - NodePort:在集群每个节点上暴露一个端口作为外部访问入口,客户端可以通过任何节点访问Service,端口范围在30000-32767。 - LoadBalancer:通过在集群外部的公有云平台上做一个负载均衡,通过外部负载均衡接受请求后,将流量路由到集群中的NodePort上。 #### ClusterIP

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: dm-ns
spec:
selector:
app: nginx #容器标签
ports:
- protocol: TCP
port: 80
targetPort: 80 #目标端口(转发到容器的端口)

NodePort

1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: dm-ns
spec:
type: NodePort
selector:
app: nginx #容器标签
ports:
- protocol: TCP
port: 80 #集群内部端口
targetPort: 80 #目标端口(转发到容器的端口)
nodePort: 80 #暴露给外部的端口

Nginx+NodePort和LoadBalancer区别

  1. loadbalancer会自动创建云服务厂商提供的负载均衡器访问节点,高可用由云运营商保障。
  2. loadbalancer会动态添加节点,nginx需要手动添加/删除节点。
  3. loadbalancer会自动隔离故障节点,nginx需要手动干预。

Ingress

Ingress工作在第7层(应用层),处理基于HTTP/HTTPS协议的流量,提供基于域名和路径的流量管理。

下载yaml并应用(nginx类型)

1
2
3
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/baremetal/deploy.yaml

kubectl apply -f deploy.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx
namespace: test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx # ingress类型
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80 # services的端口
host: web.nginx.com # 解析域名

kubernetes遇见问题

1. 安装metrics-server后无法就绪

通过查看日志发现是因为kubernetes通过自签证书的方式认证,导致metrices-server向kubernetes发起请求时tls认证失败

解决方法1:通过修改metrics-server.yaml部署文件直接跳过metrics-server的TLS验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rbac.authorization.k8s.io/aggregate-to-view: "true"
name: system:aggregated-metrics-reader
rules:
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
- apiGroups:
- ""
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server-auth-reader
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:metrics-server
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
ports:
- appProtocol: https
name: https
port: 443
protocol: TCP
targetPort: https
selector:
k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: metrics-server
strategy:
rollingUpdate:
maxUnavailable: 0
template:
metadata:
labels:
k8s-app: metrics-server
spec:
containers:
- args:
- --cert-dir=/tmp
# 跳过证书验证
- --kubelet-insecure-tls
- --secure-port=10250
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
image: registry.k8s.io/metrics-server/metrics-server:v0.8.0
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /livez
port: https
scheme: HTTPS
periodSeconds: 10
name: metrics-server
ports:
- containerPort: 10250
name: https
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /readyz
port: https
scheme: HTTPS
initialDelaySeconds: 20
periodSeconds: 10
resources:
requests:
cpu: 100m
memory: 200Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
volumeMounts:
- mountPath: /tmp
name: tmp-dir
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
serviceAccountName: metrics-server
volumes:
- emptyDir: {}
name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
labels:
k8s-app: metrics-server
name: v1beta1.metrics.k8s.io
spec:
group: metrics.k8s.io
groupPriorityMinimum: 100
insecureSkipTLSVerify: true
service:
name: metrics-server
namespace: kube-system
version: v1beta1
versionPriority: 100

未验证 解决方法2:通过CA签发kubelet server证书彻底解决metrics-tls认证问题
kube apiserver开启kubelet服务端证书校验 - shelterCJJ - 博客园