kubeasz下etcd操作、删除worker节点、添加master、worker节点

 

一、coredns

1、coredns解析流程

0、在dns组件中配置转发,将解析不了的域名转发到某个dns服务器(一般为公司内的一个bind,如powerdns)
1、Pod向dns组件发起域名解析请求
2、如Pod请求mysql-vip.online.local,dns组件发现域名后缀不是k8s的权威记录,并且没有缓存,就会进行转发到外部dns服务器(.online.local这些域名后缀一般在这个外部dns服务器上有配置)
3、解析完成后又这个dns服务器返回dns组件,再由dns组件返回pod
4、若dns组件上配置转发的dns服务器也解析不了,会由接收转发请求的dns服务器,再将请求转发给外部dns服务器(如223.6.6.65、再将结果逐步返回

2、dns部署

0、官网:coredns.io
1、在github查找项目:https://github.com/coredns/coredns
2、可以下载二进制,但是不是通过二进制启动,是通过yaml文件部署,镜像启动
3、获取yaml文件(在github获取k8s二进制包)
4、https://github.com/kubernetes/kubernetes/releases

5、在changelog中选择要下载的具体版本
6、如下载1.23.5版本
需要的东西(4个)(只要coredns不用这么多,后期学习集群升级):
    1、Source Code:包括很多脚本、yaml文件
    2、Client Binaries:客户端二进制,kubectl等(注意下载版本)
    3、Server Binaries:apiserver、controller-manager等二进制
    4、Node Binaries:kubelet、kube-proxy等二进制
7、四个文件在同级目录下解压,解压完会放在同一目录(kubernetes)下
8、二进制包在./kubernetes/server/bin 下,
9、插件在./kubernetes/cluster/addons下
10、coredns目录位置:./kubernetes/cluster/addons/dns/coredns
1、进入coredns目录
2、cp coredns.yaml.base /root/coredns.yaml
3、yaml文件内容
    - 创建一个服务账号
    - 进行授权
    - configmap
    - deployment
    - service
    
4、修改内容
    - ConfigMap中的 _DNS_DOMAIN_ 替换为域名后缀,默认需要替换为cluster.local 若安装时在kubeasz的hosts文件中修改过,需要换为修改过的。
    - ConfigMap中的forward,配置dns转发,默认转发到 /etc/resolv.conf中,可直接写为具体dns服务器ip
    - Deployment中的limits的memory:如200Mi
    - Deployment中的image:默认为谷歌的镜像,有可能拉不到,自己改为docker的镜像或者先拉到自己的harbor如:coredns/coredns:1.8.7 
    - Service的ClusterIP改为dns
        问题:我的dns地址是多少呢?
        答:创建一个容器,可以直接去该容器的/etc/resolv.conf中查看 nameserver,该nameserver为coredns组件的service地址
一般来说,集群的第一个地址分给了kube-apiserver的service,
        第二个地址分给dns组件service
5、保存:wq
6、kubectl apply -f coredns.yaml
7、验证,随便进入一个容器,ping一个域名或内部的域名能不能成功
    ping www.baidu.com
    ping servicename.namespace.svc.cluster.local
8、当coredns压力大时,可以将coredns容器副本数增加
    kubectl scale deployment/coredns --replicas=2 -n kube-system
9、注意:安装了coredns,但是在k8s集群中,kubectl get svc的时候,显示的还是kube-dns。
    原因:如dashboard、或者其他组件,都是从kube-dns的服务名去请求,所以直接使用kube-dns的svc名

- 配置文件

# __MACHINE_GENERATED_WARNING__

apiVersion: v1
kind: ServiceAccount
metadata:
  name: coredns
  namespace: kube-system
  labels:
      kubernetes.io/cluster-service: "true"
      addonmanager.kubernetes.io/mode: Reconcile
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
    addonmanager.kubernetes.io/mode: Reconcile
  name: system:coredns
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  - services
  - pods
  - namespaces
  verbs:
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
- apiGroups:
  - discovery.k8s.io
  resources:
  - endpointslices
  verbs:
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
    addonmanager.kubernetes.io/mode: EnsureExists
  name: system:coredns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:coredns
subjects:
- kind: ServiceAccount
  name: coredns
  namespace: kube-system
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
  labels:
      addonmanager.kubernetes.io/mode: EnsureExists
data:
  Corefile: |
    .:53 {
        errors
        health {
            lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
            pods insecure
            fallthrough in-addr.arpa ip6.arpa
            ttl 30
        }
        prometheus :9153
        forward . 223.6.6.6 {
            max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: coredns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/name: "CoreDNS"
spec:
  # replicas: not specified here:
  # 1. In order to make Addon Manager do not reconcile this replicas parameter.
  # 2. Default is 1.
  # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  selector:
    matchLabels:
      k8s-app: kube-dns
  template:
    metadata:
      labels:
        k8s-app: kube-dns
    spec:
      securityContext:
        seccompProfile:
          type: RuntimeDefault
      priorityClassName: system-cluster-critical
      serviceAccountName: coredns
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                  - key: k8s-app
                    operator: In
                    values: ["kube-dns"]
              topologyKey: kubernetes.io/hostname
      tolerations:
        - key: "CriticalAddonsOnly"
          operator: "Exists"
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - name: coredns
        image: coredns/coredns:1.8.7
        imagePullPolicy: IfNotPresent
        resources:
          limits:
            cpu: 500m
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 70Mi
        args: [ "-conf", "/etc/coredns/Corefile" ]
        volumeMounts:
        - name: config-volume
          mountPath: /etc/coredns
          readOnly: true
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        - containerPort: 9153
          name: metrics
          protocol: TCP
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: 8181
            scheme: HTTP
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - all
          readOnlyRootFilesystem: true
      dnsPolicy: Default
      volumes:
        - name: config-volume
          configMap:
            name: coredns
            items:
            - key: Corefile
              path: Corefile
---
apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  annotations:
    prometheus.io/port: "9153"
    prometheus.io/scrape: "true"
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/name: "CoreDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 10.100.0.2
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP
  - name: metrics
    port: 9153
    protocol: TCP

- 查看

 - 进入容器查看是否能够解析

kubectl run nginx --image=nginx:1.21.1

kubectl exec -it nginx -- bash

 

 

 

二、部署dashboard

1、拉取两个镜像    
    kubernetesui/dashboard:v2.5.1
    kubernetesui/metrics-scraper:v1.0.7
2、获取yaml文件
    wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/dashboard-v2.5.1.yaml
    mv recommended.yaml dashboard-v2.5.1.yaml   ##最好写版本注释否则后面可能会忘记具体版本
    kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.1/aio/deploy/dashboard-v2.5.1.yaml
    
3、若通过harbor拉取镜像的话,需要在每个节点先作域名接卸并下发harbor的公钥
    - vim /etc/hosts     域名 IP
    - mkdir -p /etc/docker/certs.d/域名名字/harbor-ca.crt
    - scp /etc/docker/certs.d/域名名字/harbor-ca.crt 节点IP:/etc/docker/certs.d/域名名字/harbor-ca.crt

4、harbor配置为私有时会报错unauthorized to access repository 可设置为公开,或者docker login
    设置公开,选择项目---配置管理--勾选设为公开

5、apply之后,可将svc改为type: nodePort即可通过端口访问服务

6、登陆时没有设置账号名与密码进行登陆,我们可以自己创建账号名与密码,通过一个yaml文件
vim admin-user.yaml  
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authoriation.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kuberbetes-dashboard
  
7、获取admin-user的token进行登陆
    kubectl get secrets -A    |grep admin
    kubectl describe sercets admin-user-token-xxaba
8、使用获得的token进行登陆

 

三、etcd常见操作

1、集群成员    

列出集群成员

# etcdctl member list

 

从左往右的信息依次为:

节点id、节点状态、节点名称、集群地址、客户端地址、是否在同步数据(false为当前未在同步数据)

 

 2、节点监控

#  检查当前服务器

# etcdctl endpoint health

#  一次检查所有服务器

# 声明etcd服务器地址

# export NODE_IPS="192.168.1.10 192.168.1.11 192.168.1.12"

# 通过for循环,指定证书位置、检查节点是否正常

for ip in ${NODE_IPS}; do   ETCDCTL_API=3 /usr/local/bin/etcdctl   --endpoints=https://${ip}:2379    --cacert=/etc/kubernetes/ssl/ca.pem   --cert=/etc/kubernetes/ssl/etcd.pem   --key=/etc/kubernetes/ssl/etcd-key.pem   endpoint health; done

 加 --write-out=table输出表格

 

 

 # 查看节点状态

for ip in ${NODE_IPS}; do   ETCDCTL_API=3 /usr/local/bin/etcdctl  --write-out=table --endpoints=https://${ip}:2379    --cacert=/etc/kubernetes/ssl/ca.pem   --cert=/etc/kubernetes/ssl/etcd.pem   --key=/etc/kubernetes/ssl/etcd-key.pem   endpoint health; done

 

 

 3、获取数据

# 获取etcd的所有key

# etcdctl get / --prefix --keys-only

# 过滤,如找到nginx相关的key

# etcdctl get / --prefix --keys-only |grep nginx

 # 获取某个key的值

# etcdctl get key   ##资源的元数据 如查一个pod 就会有pod地址、信息等等
# etcdctl get /registry/pods/default/nginx

 

 

 4、删除数据

注意,当etcd中数据被删除,k8s无法恢复数据,需要保证etcd数据安全性

etcdctl del keyname
etcdctl del /registry/pods/default/nginx

# 再次查看pod状态
kubectl get pod  

- 重新运行pod查看状态

kubectl run nginx --image=nginx:1.21.1
kubectl get pod
etcdctl
get / --prefix --keys-only

 

 

 5、watch机制

 

基于不断查看数据,发生变化就主动触发通知客户端,ETCD v3支持watch机制支持watch某个固定的key,也支持watch一个范围
支持watch一个存在的key或者不存在的key

  • watch不存在的key

root@master-01:~# etcdctl get /data
root@master-01:~# etcdctl watch data

 - 另一台机器插入数据

root@master-02:~# etcdctl put /data "hello"
  • 查看watch

 

 6、etcd单机备份恢复

创建备份路径

root@master-01:~# mkdir -p /data/etcd-backup
三份数据是一样的,在哪里备份都可以,当然三个地方都备份会更好

#注意:需要恢复到不存在的数据目录,目录存在会报错

root@master-01:~# etcdctl snapshot restore /data/etcd-backup/etcd-backup-202204211442 --data-dir=/data/etcd-backup

 

  • 指定一个不存在的目录进行恢复

root@master-01:~# etcdctl snapshot restore /data/etcd-backup/etcd-backup-202204211442 --data-dir=/data/etcddir

  • 将/etc/systemd/system/etcd.service中的数据目录和工作目录改成这个路径后重载与重启

vim /etc/systemd/system/etcd.service
WorkingDirectory=/data/etcddir

  Execstart=/usr/local/bin/etcd \
    --data-dir=/data/etcddir


systemctl daemon-reload 
systemctl restart etcd

7、ezctl命令  etcd集群数据恢复

恢复原理

## 备份快照
1、进行心跳检测,查看etcd集群是否存活,到存活的第一个节点进行备份
2、获取时间戳
3、创建备份(创建数据目录--进入--snapshot save)
4、拷贝快照到当前kubeasz的节点
5、更新备份(将拷贝的快照复制成snapshot.db  后期的恢复均以snapshot.db这个文件进行恢复,所以每备份一次就会复制一份成为最新的snapshot.db)

## 还原过程
1、清楚etcd数据目录
2、生成备份目录
3、准备指定的备份数据(将快照从kubeasz拷贝到etcd节点上)
4、清理备份目录上次恢复备份的数据
5、etcd数据恢复
6、恢复etcd数据到etcd数据目录
7、检查心跳信息

- 备份集群数据

0、查看当前的Pod
1、在kubeasz节点上进行数据备份
    ./ezctl backup k8sclustername
root@master-01:/etc/kubeasz# ./ezctl backup k8s-cluster1    
2、查看配置文件
    root@master-01:/etc/kubeasz# ls /etc/kubeasz/clusters/k8s-cluster1/backup/

 

 - 备份完毕后,删除一个pod

 

 - 恢复etcd集群数据

root@master-01:/etc/kubeasz# ./ezctl restore k8s-cluster1

5、再次查看Pod,已恢复(192.168.1.21是worker节点,没开机,但上面没有pod,不影响此次实验)

 

 

 

四、k8s集群升级 v1.23.1-->v1.23.5

1、升级过程梳理

1、将二进制下载下来,解压。
2、进入./kubernetes/server/bin中
3、将apiserver、controller-manager、schedule、kubectl、kubelet、kube-proxy替换到master上
    kube-proxy、kubelet替换到node上
4、升级master
    a.在node上,将nginx中对k8smaster的代理进行注释,vim /etc/kube-lb/conf/kube-lb.conf
    b.systemctl restart kube-lb.service
    c.停止服务 systemctl stop kube-apiserver.service kube-scheduler.service kubelet.service kube-proxy.service kube-controller-manager.service
    d.将文件替换 \cp kube-apiserver kube-scheduler kubelet kube-proxy kube-controller-manager /usr/local/bin/
    e.取消/etc/kube-lb/conf/kube-lb.conf ,注释另一个master的负载
    e.启动服务 systemctl stop kube-apiserver.service kube-scheduler.service kubelet.service kube-proxy.service kube-controller-manager.service

5、升级node
    a.驱逐pod kubectl drain nodename --force --ignore-daemonsets --delete-emptydir-data
    b.停止服务  systemctl stop kubelet kubeproxy
    c.拷贝配置文件  scp kubelet.service kube-proxy.service ip:/usr/local/bin/
    d.启动服务 systemctl start kubelet kubeproxy
    e.开启调度 kubectl uncordon nodename

6、将二进制拷贝到kubeasz的二进制目录中,便于后期加入节点时,拷贝的二进制是最新版本
    \cp kube-apiserver kube-scheduler kubelet kube-proxy kube-controller-manager /etc/kubeasz/bin

在之前安装coredns,已经将包解压完毕,现在开始进行升级

2、当前集群信息

192.168.1.21是因为没有开机,所以处于NotReady状态

 3、拷贝二进制文件到/etc/kubeasz/bin 方便后续加入节点直接为1.23.5版本的包

\cp kube-apiserver kube-scheduler kubelet kube-proxy kube-controller-manager /etc/kubeasz/bin

 

4、升级master节点

   1、在每台node上,将kube-lb的配置文件中的当前需要升级的master节点代理取消

root@worker-01:~# vim /etc/kube-lb/conf/kube-lb.conf
user root;
worker_processes 1;

error_log  /etc/kube-lb/logs/error.log warn;

events {
    worker_connections  3000;
}

stream {
    upstream backend {
     #   server 192.168.1.10:6443    max_fails=2 fail_timeout=3s;    ##注释
        server 192.168.1.11:6443    max_fails=2 fail_timeout=3s;
    }

    server {
        listen 127.0.0.1:6443;
        proxy_connect_timeout 1s;
        proxy_pass backend;
    }
}

  2、重启服务

root@worker-01:~# systemctl restart kube-lb.service

  3、在要升级的master节点上,停止服务

root@master-01:~# systemctl stop kube-apiserver.service kube-scheduler.service kubelet.service kube-proxy.service kube-controller-manager.service

  4、将准备好的二进制文件进行替换

#将原来二进制备份
   root@master-01:~# mkdir /root/k8s-v1-23-1
  root@master-01:~# ll /usr/local/bin/k* |grep -v 'kubectl'| awk '{print "mv "$9" ""/root/k8s-v1-23-1"}'|sh
# 替换
  root@master-01:~/k8s-v1.23.5/kubernetes/server/bin# \cp kube-apiserver kube-scheduler kubelet kube-proxy kube-controller-manager /usr/local/bin/

  5、启动服务

root@master-01:~/k8s-v1.23.5/kubernetes/server/bin# systemctl start kube-apiserver.service kube-scheduler.service kubelet.service kube-proxy.service kube-controller-manager.service

  6、查看版本

kubectl get node

   7、在node上取消master注释 并重启

   8、换一个master进行注释,重复上述步骤升级另一个master (包用scp拷过去就行)

5、升级第二个master节点

  1、停止服务

root@master-02:~# systemctl stop kube-apiserver.service kube-scheduler.service kubelet.service kube-proxy.service kube-controller-manager.service

  2、复制二进制包

root@master-01:~/k8s-v1.23.5/kubernetes/server/bin# scp kube-apiserver kube-scheduler kubelet kube-proxy kube-controller-manager 192.168.1.11:/usr/local/bin/

  3、查看版本

 

   4、启动服务

root@master-02:~# systemctl start kube-apiserver.service kube-scheduler.service kubelet.service kube-proxy.service kube-controller-manager.service

  5、查看k8s集群node

  

  6、worker取消注释

6、升级worker节点

  1、驱逐Pod(一般来说worker是多节点的状态,但是在笔记本装资源有限,只开了一台worker,当前有个nginx的pod,当驱逐时Pod将不会调度成功,解决方法为给pod添加容忍、删除master的污点、增加worker节点)

root@master-01:~# kubectl drain 192.168.1.20 --force --ignore-daemonsets --delete-emptydir-data

   2、停止worker节点上的服务

root@worker-01:~# systemctl stop kubelet.service kube-proxy.service 

  3、将二进制拷贝到worker上

root@master-01:~/k8s-v1.23.5/kubernetes/server/bin# scp kubelet kube-proxy  192.168.1.20:/usr/local/bin/

   4、查看版本

   5、启动服务

root@worker-01:~# systemctl start kubelet.service kube-proxy.service 

  6、查看k8s的node状态

  7、恢复调度

root@master-01:~# kubectl uncordon 192.168.1.20

  至此,集群升级完毕!

五、删除、添加节点

1、删除node节点

删除节点同时测试再次加入节点,会不会直接升级节点上的二进制版本

root@master-01:/etc/kubeasz# ./ezctl del-node k8s-cluster1  192.168.1.21

2、添加node节点

# 注意需要免密认证

./ezctl node-add k8s-cluster1 nodeip

# 加完之后,会在kubeasz中的hosts配置文件里面将node的ip加上去


验证完毕,会重新将二进制拷贝到新的node节点

3、添加master节点

# 注意需要免密认证
./ezctl add-master  k8s-cluster1 masterip
# 加完之后,会在kubeasz中的hosts配置文件中将masterip加上去。
    并且node节点的kube-lb配置文件也会将该master加到负载列表中

4、添加master遇到的问题

  当时添加master时,由于机器资源问题导致虚拟机错误关机,ansible只执行了一半,查看k8s的node状态尚未加入,后面第一次尝试重新执行失败,报错为hosts文件中已存在

解决:在kubeasz创建集群后生成的hosts文件中,将master那里的新加入节点的ip去掉,重新执行。

 

posted @ 2022-04-21 23:07  wyllearning  阅读(434)  评论(0)    收藏  举报