K8s基础12——etcd数据备份与恢复、集群版本升级、网络策略

一、etcd备份与恢复

基本了解:

  1. K8s 使用etcd数据库实时存储集群中的数据,安全起见,一定要备份!
  2. 备份只需要在一个节点上备就可以了,每个节点上的数据是同步的;但是数据恢复是需要在每个节点上进行。
  3. ectd容器是与宿主机网络共享的,采用hostNetwork方式,2379数据端口就可以在宿主机上查看到。
    在这里插入图片描述
  4. kubeadm方式部署的集群,其中etcd是通过静态pod方式部署启动,在/etc/kubernetes/manifests目录下有它的yaml文件,里面记录了启动镜像、版本、证书路劲、数据目录等内容。
    在这里插入图片描述
    在这里插入图片描述

注意事项:

  1. 使用yum安装的etcd版本比较低,因为etcd现有两个版本,2和3,两个版本之间的api改动较大,现在使用之前都需要先指定到3版本。
    在这里插入图片描述

1.1 kubeadm部署方式

1.1.1 备份

1.安装etcd。

[root@k8s-master opt]# yum -y install etcd

在这里插入图片描述
2.查看当前pod,待会备份后删除它,再数据恢复查看效果。
在这里插入图片描述
3.备份,导出的数据文件是qingjun.db。

ETCDCTL_API=3 etcdctl snapshot save qingjun.db \
--endpoints=https://127.0.0.1:2379 \             ##指定etcd地址端口。
--cacert=/etc/kubernetes/pki/etcd/ca.crt \      ##指定etcd根证书。
--cert=/etc/kubernetes/pki/etcd/server.crt \     ##指定etcd客户端数字证书。
--key=/etc/kubernetes/pki/etcd/server.key      ##指定key。

在这里插入图片描述
4.删除pod,恢复查看效果。

在这里插入图片描述

1.1.2 恢复

5.先停止api server 和etcd服务。因为是静态Pod部署,监控这个目录下的yaml文件,当把目录备份后就直接相当于停服。

[root@k8s-master manifests]# pwd
/etc/kubernetes/manifests

[root@k8s-master manifests]# mv /etc/kubernetes/manifests /etc/kubernetes/manifests.bck
[root@k8s-master manifests]# mv /var/lib/etcd /var/lib/etcd.bck

在这里插入图片描述
6.使用qingjun.db文件恢复数据到/var/lib/etcd目录。

[root@k8s-master opt]# ETCDCTL_API=3 etcdctl snapshot restore qingjun.db --data-dir=/var/lib/etcd

7.启动kube-apiserver和etcd容器。

[root@k8s-master opt]# mv /etc/kubernetes/manifests.bck /etc/kubernetes/manifests

8.查看结果,数据恢复。
在这里插入图片描述

1.2 单etcd二进制部署方式

1.2.1 部署

1.提前准备etcd二进制安装包,下载地址
在这里插入图片描述
2.解压安装包。

[root@k8s-node2 opt]# tar zxf etcd-v3.5.1-linux-amd64.tar.gz 
[root@k8s-node2 opt]# cd etcd-v3.5.1-linux-amd64/
[root@k8s-node2 etcd-v3.5.1-linux-amd64]# cp etcd etcdctl /usr/bin/

3.准备配置文件

[root@k8s-node2 etcd-v3.5.1-linux-amd64]# cat /etc/etcd.conf 
ETCD_NAME="etcd"     ##节点名称
ETCD_DATA_DIR="/var/lib/etcd"      ##数据目录
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"      ##监听地址
ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379"     ##别人连我的地址

4.设置为systemd系统服务。

[root@k8s-node2 etcd-v3.5.1-linux-amd64]# cat /usr/lib/systemd/system/etcd.service 
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
EnvironmentFile=/etc/etcd.conf
ExecStart=/usr/bin/etcd
Restart=on-failure
LimitNOFILE=65536

5.启动服务并设置开机启动

[root@k8s-node2 etcd-v3.5.1-linux-amd64]# systemctl daemon-reload
[root@k8s-node2 etcd-v3.5.1-linux-amd64]# systemctl start etcd
[root@k8s-node2 etcd-v3.5.1-linux-amd64]# systemctl enable etcd

6.查看etcd状态。

[root@k8s-node2 etcd-v3.5.1-linux-amd64]# etcdctl endpoint status --write-out=table

在这里插入图片描述

1.2.2 备份

1.查看etcd服务,需要提前部署。
在这里插入图片描述
2.备份。

##这里没有指定证书,所以就是http。
[root@k8s-node2 ~]# ETCDCTL_API=3 etcdctl snapshot save baimu.db --endpoints=http://127.0.0.1:2379

在这里插入图片描述

1.2.3 恢复

3.先停止etcd服务。

[root@k8s-node2 ~]# systemctl stop etcd
[root@k8s-node2 ~]# mv /var/lib/etcd /var/lib/etcd.bck

4.恢复数据到指定目录。

[root@k8s-node2 ~]# ETCDCTL_API=3 etcdctl snapshot restore baimu.db --data-dir=/var/lib/etcd

5.启动服务即可。

[root@k8s-node2 ~]# systemctl start etcd

1.2.4 K8s集群二进制部署方式恢复

  • 上面演示的只是单etcd是二进制部署,一般情况下二进制部署都是成套的,也就是说所有组件都用二进制方式部署。所以在停止、启动服务时有点区别。

1、先暂停kube-apiserver和etcd。

systemctl stop kube-apiserver 
systemctl stop etcd
mv /var/lib/etcd/default.etcd /var/lib/etcd/default.etcd.bak

2、在每个节点上恢复。

注意:不管哪种方式恢复数据,都是在每个节点上进行恢复。所以这里就需要指定集群信息。

ETCDCTL_API=3 etcdctl snapshot restore snap.db \
--name etcd-1 \     ##节点名称
--initial-cluster="etcd-1=https://192.168.31.71:2380,etcd-2=https://192.168.31.72:2380,etcd-3=https://192.168.31.73:2380" \  ##集群地址
--initial-cluster-token=etcd-cluster \    
--initial-advertise-peer-urls=https://192.168.31.71:2380 \     ##当前恢复的etcd节点地址
--data-dir=/var/lib/etcd   ##数据恢复到哪里,默认就是数据目录。

3、启动kube-apiserver和etcd

systemctl start kube-apiserver 
systemctl start etcd

二、集群版本升级

升级思路:

  1. 先升级master1节点,再升级master2、master3等管理节点,再升级node1、node2等工作节点。
  2. 升级存在风险,所以需要先对升级的节点做数据备份。
  3. 升级时,先驱逐节点上的pod,在设置为不可调度。因为升级存在风险,若升级失败,也不会影响业务。

注意事项:

  • 升级前必须备份所有组件及数据,例如etcd
  • 千万不要跨多个小版本进行升级,例如从1.16升级到1.19
  • 在测试环境经过多次演练、实操,没问题后才能上生产环境。

2.1 升级master节点

1.查找最新版本号。

[root@k8s-master bck]# yum list --showduplicates kubeadm

在这里插入图片描述
2.先升级kubeadm。

[root@k8s-master bck]# yum install -y kubeadm-1.26.3-0

3.驱逐node上的pod,且不可调度。

#ignore-daemonsets参数:忽略无法驱逐的pod。
[root@k8s-master bck]# kubectl drain k8s-master --ignore-daemonsets

4.查看该节点pod状态,检查是否驱逐成功。此时该节点没有任何pod业务,可开始升级。
在这里插入图片描述
5.查看集群是否可以升级。

[root@k8s-master bck]# kubeadm upgrade plan

在这里插入图片描述
6.升级。

[root@k8s-master bck]# kubeadm upgrade apply v1.26.3

在这里插入图片描述
7.升级kubelet和kubectl,和kubeadm版本要一致。

[root@k8s-master bck]# yum install -y kubelet-1.26.3-0 kubectl-1.26.3-0

8.重启kubelet,再次查看版本已经被升级到新版本。

[root@k8s-master bck]# systemctl daemon-reload
[root@k8s-master bck]# systemctl restart kubelet

在这里插入图片描述
9.取消不可调度,重新上线。

[root@k8s-master bck]# kubectl uncordon k8s-master

2.2 升级node节点

1.先查看当前版本。
在这里插入图片描述
2.升级kubeadm版本。

[root@k8s-node2 ~]# yum install -y kubeadm-1.26.3-0

3.驱逐node1上的pod,且不可调度。

kubectl drain k8s-node1 --ignore-daemonsets

3、升级kubelet配置

kubeadm upgrade node

4、升级kubelet和kubectl

yum install -y kubelet-1.26.3-0 kubectl-1.26.3-0

5、重启kubelet

systemctl daemon-reload
systemctl restart kubelet

6、取消不可调度,重新上线。

kubectl uncordon k8s-node1

三、网络策略

基本了解:

  • 网络策略通过网络插件来实现,创建一个 NetworkPolicy 资源对象而没有控制器来使它生效的话,是没有任何作用的,而我们搭建K8s集群时安装的calico网络组件就支持网络策略。
  • 默认情况下,K8s 集群网络没任何网络限制,Pod 可以与任何其他 Pod 通信,在某些场景下就需要进行网络控制,减少网络攻击面,提高安全性,这就会用到网络策略。
  • 网络策略是一个K8s资源,需要管理员写yaml定义规则的,用于限制Pod出入流量,提供Pod级别和Namespace级别网络访问控制。

应用场景:

  1. 应用程序间的访问控制,例如项目A不能访问项目B的Pod。
  2. 开发环境命名空间不能访问测试环境命名空间Pod。
  3. 当Pod暴露到外部时,需要做Pod白名单。
  4. 多租户网络环境隔离。

网络策略工作流程:

  1. 使用kubectl提交yaml文件给api server创建Network Policy资源。
  2. api server 收到之后存到etcd数据库中。
  3. Policy Controller组件监控网络策略,同步并通知节点上程序。
  4. 节点上DaemonSet运行的程序从etcd中获取Policy,调用本地Iptables创建防火墙规则。

在这里插入图片描述

注意事项:

  1. calico网络组件是以Daemonset方式部署到每个节点,其中红色框的pod负责calico录入表的维护,网络策略的执行和下发。
  2. 有的网络组件没有这个红色个框的控制器,只有agent-pod。
    在这里插入图片描述
  3. 也有特定需求是网络策略当前实现不了的,可以通过操作系统组件、准入控制器来实现。
    在这里插入图片描述

3.1 核心字段释义

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy        ##自定义网络策略名称。
  namespace: default            ##定义对哪个命名空间的Pod进行限制,这里就是对default命名空间下的pod生效。
spec:
  podSelector:               ##目标Pod,对哪个Pod生效。
    matchLabels:
      role: db       ##根据标签选择。
  policyTypes:     ##策略类型。
    - Ingress        ##入站流量,谁能访问我。
    - Egress        ##出站流量,我能访问谁。
  ingress:
    - from:          ##from是可以访问的白名单,可以来自于IP段、命名空间、Pod标签等,ports是可以访问的端口。
        - ipBlock:     ##可以访问我的IP段,除了 172.17.1.0/24 之外的所有 172.17.0.0/16网络中的pod都可以访问我。
            cidr: 172.17.0.0/16
            except:
              - 172.17.1.0/24
        - namespaceSelector:   ##命名空间的标签为project=myproject,且其下pod标签为role=client的pod可以访问我。
            matchLabels:
              project: myproject
          podSelector:
            matchLabels:
              role: client
        - podSelector:        ##任何名字空间中,标签为role=frontend的Pod可以访问我。
            matchLabels:
              role: frontend
      ports:                  ##白名单能基于TCP协议访问我的6379端口。
        - protocol: TCP
          port: 6379            
  egress:             ##我能访问10.0.0.0/24网段中的5978 TCP端口。 
    - to:
        - ipBlock:             
            cidr: 10.0.0.0/24
      ports:
        - protocol: TCP
          port: 5978

3.2 测试案例

案例1:拒绝命名空间下所有Pod出入站流量

  • 需求:拒绝test命名空间下所有Pod入、出站流量。
  • 解读:test命名空间下的pod不能访问别人,也不允许让别人访问test命名空间下的所有pod。

1.创建test命名空间,并生成一个deploy,名为nginx,在defalue空间生成一个测试pod,名为bs。

[root@k8s-master1 networkpolicy]# kubectl  create ns test
[root@k8s-master1 networkpolicy]# kubectl  create deployment nginx --image=nginx  -n test 
[root@k8s-master1 networkpolicy]# kubectl  run bs --image=busybox -- sleep 24h

2.此时bs容器可以ping通nginx网络。
在这里插入图片描述
3.编写yaml文件,生成网络策略。

[root@k8s-master1 networkpolicy]# cat network1.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: qingjun1
  namespace: test
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
[root@k8s-master1 networkpolicy]# kubectl  apply -f network1.yaml

4.此时再用bs就ping不同nginx的网络。
在这里插入图片描述

案例2:拒绝其他命名空间pod访问

  • 需求:test命名空间下所有pod可以互相访问,也可以访问其他命名空间Pod,但其他命名空间不能访问test命名空间Pod。
  • 解读:test命名空间的pod可以访问别人,但别人不能访问它。

1.生成网络策略。

[root@k8s-master1 networkpolicy]# cat network2.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: qingjun2
  namespace: test
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector: {}   # 匹配test命名空间所有pod,其他所有命名空间下的pod都不能访问我。

[root@k8s-master1 networkpolicy]# kubectl  apply -f network2.yaml 

2.测试效果。

在这里插入图片描述

案例3:允许其他命名空间pod访问指定应用

  • 需求:允许其他命名空间访问test命名空间里的指定pod,但test命名空间的其他pod不能访问这个指定的pod。
  • 解读:默认情况下是能访问test命名空间的pod,所以可以叠加使用两个网络策略。

1.生成第一个网络策略,允许所有命名空间下的pod可以访问test命名空间下的带有标签为app=nginx的pod。

[root@k8s-master1 networkpolicy]# cat network3.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: qingjun3
  namespace: test
spec:
  podSelector:
    matchLabels:
      app: nginx
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector: {}    # 匹配所有命名空间的pod

[root@k8s-master1 networkpolicy]# kubectl  apply -f network3.yaml 

2.再添加第二个策略,禁止所有流量进出。此时两个网络策略共同起作用。

[root@k8s-master1 networkpolicy]# cat network1.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: qingjun1
  namespace: test
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

[root@k8s-master1 networkpolicy]# kubectl apply -f network1.yaml 

在这里插入图片描述
3.测试效果,其他命名空间下的pod可以访问text命名空间下标签为app=nginx的pod,同时test命名空间下的其他pod不能访问text命名空间下标签为app=nginx的pod。
在这里插入图片描述

案例4:同一个命名空间下应用之间限制访问

需求:将test命名空间中标签为app=nginx的pod隔离,只允许text命名空间下的标签为run=client1的pod访问它的80端口,其他命名空间的所有pod都不能访问。

1.生成网络策略。

[root@k8s-master1 networkpolicy]# cat network4.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: qingjun4
  namespace: test
spec:
  podSelector:
    matchLabels:
      app: nginx
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              run: client1
      ports:
        - protocol: TCP
          port: 80

          
[root@k8s-master1 networkpolicy]# kubectl  apply  -f network4.yaml 

2.测试效果。带有run=client1标签的pod可以访问到app=nginx标签的pod,带有run=bs标签的pod访问不了app=nginx标签的pod。

在这里插入图片描述

案例5:只允许指定命名空间中的应用访问

需求:限制dev命名空间标签为env=dev的pod,只允许prod命名空间中的pod访问,并且允许所有命名空间run=client1标签pod访问。

1.创建dev、prod命名空间,并在其下面创建2个pod。

[root@k8s-master1 networkpolicy]# kubectl  create ns dev
[root@k8s-master1 networkpolicy]# kubectl create  ns prod

[root@k8s-master1 networkpolicy]# kubectl  run bs --image=busybox -n prod   -- sleep 24h 
[root@k8s-master1 networkpolicy]# kubectl  create deployment dev --image=nginx -n dev 

在这里插入图片描述
2.生成网络策略。

[root@k8s-master1 networkpolicy]# cat network5.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: qingjun5
  namespace: dev
spec:
  podSelector:
    matchLabels:
      env: dev
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:                 # 既允许prod命名空间中的pod访问。
            matchLabels:
              kubernetes.io/metadata.name: prod
        - namespaceSelector: {}             # 也允许所有命名空间下pod标签为app=client1的pod访问。
          podSelector:
            matchLabels:
              run: client1

[root@k8s-master1 networkpolicy]# kubectl  apply -f network5.yaml 

3.测试效果。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

案例6:限制端口范围

需求:允许名字空间default中所有带有标签 role=db 的pod使用TCP协议与 10.0.0.0/24 范围内的 IP 通信,只要目标端口介于 32000 和 32768 之间就可以。

1.编写策略。

注意事项:

  • endPort 字段必须等于或者大于 port 字段的值
  • 只有在定义了 port 时才能定义 endPort。
  • 两个字段的设置值都只能是数字。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: multi-port-egress
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 10.0.0.0/24
      ports:
        - protocol: TCP
          port: 32000
          endPort: 32768
  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Kubernetesk8s集群中,etcd是一个关键组件,它存储了整个集群的配置信息、状态信息和元数据。对于生产环境中的 k8s 集群备份恢复 etcd 数据是非常重要的,以确保集群的可用性和数据的完整性。 以下是备份恢复 etcd 数据的步骤: 备份 etcd 数据: 1. 连接到 etcd 集群中的任意一个节点。 2. 运行以下命令备份 etcd 数据: ``` ETCDCTL_API=3 etcdctl --endpoints=<etcd-endpoint> snapshot save <backup-file> ``` 其中,`<etcd-endpoint>` 是 etcd 集群的地址,`<backup-file>` 是备份文件的路径和名称。 3. 备份完成后,将备份文件复制到安全的位置进行存储。 恢复 etcd 数据: 1. 连接到新的 etcd 集群中的任意一个节点。 2. 运行以下命令恢复 etcd 数据: ``` ETCDCTL_API=3 etcdctl snapshot restore <backup-file> \ --name <name> \ --initial-cluster <initial-cluster> \ --initial-cluster-token <initial-token> \ --initial-advertise-peer-urls <peer-url> ``` 其中,`<backup-file>` 是备份文件的路径和名称,`<name>` 是新的 etcd 集群名称,`<initial-cluster>` 是新的 etcd 集群成员列表,`<initial-token>` 是新的 etcd 集群令牌,`<peer-url>` 是新的 etcd 集群成员的地址。 3. 恢复完成后,重启 etcd 服务,以使其使用新的数据。 需要注意的是,备份恢复 etcd 数据需要谨慎操作,以免造成数据丢失或不一致。建议在进行备份恢复操作前先进行测试,并确保备份文件的存储位置安全可靠。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百慕卿君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值