讲docker基础的目的是为了引出 k8s,生产环境里面容器不止一个两个,有可能运行成千上万个,管理起来非常麻烦。

docker 2013年开源

k8s 2014年开源(谷歌公司)

docker公司有自己的容器编排工具,叫 swarm集群,很像k8s(安装和管理方式)。swarm具安装好docker之后,无需额外安装任何包,但是 k8s是一个独立的工具,需要单独去部署。


理解概念:

是k8s管理容器的最小单元/单位。默认情况下,一个pod里面包含了一个容器,一个pod里面也可以包含多个容器。

pod就是k8s集群中管理的最小单位(单元),就像超级英雄穿上了一件外衣,依靠这件外衣,就可以实现高可用。一个pod里面可以有1个或多个容器,在底层,每个pod都会有一个pause容器(我们看不见),该容器是构建网络协议栈使用的,这个pod里面的所有容器都会共享pause构建的网络。

K8s基本概念(kubernetes)_kubernetes

因为容器本来没有高可用,但是pod可以高可用,可以享受k8s给它提供的一系列控制器,享受高级特性。

K8s框架图:

K8s基本概念(kubernetes)_kubernetes_02

和FC特别像

K8s基本概念(kubernetes)_kubernetes_03

master节点:

kube-apiserver:提供k8sapi接口,用于管理和控制整个集群(接受客户端请求)。

kube-scheduler:计算调度,根据资源需求和对应的约束条件,将pod调度到合适的节点上。

kube-controller-manager:包含一组控制器,用户自动化的一些管理操作,比如节点控制器、副本控制器等,该组件维护管理的众多的控制器之一的deployment控制器,批量创建容器。

etcd:kv key-value 键值对存储系统(数据库),用户保存整个集群配置数据和状态信息,我们安装的是单节点的etcd。

coredns:集群内部的域名解析。


node节点:

kubelet:运行在每个节点上,负责pod的管理(创建、删除等),与master进行互通(比如下发一个创建pod的命令,由kubelet接受请求,调用底层的引擎进行创建和维护)。


SVC(集群的概念,逻辑层面,横跨整集群)针对后端的pod就有负载均衡功能。由master节点创建,放在集群里面,把service对外暴露,开源的默认暴露咋爱集群侧,外面访问直接带上端口号就行了,自带内部的负载均衡,怎么把流量转发到Pod上呢??


流量路径:外部——集群(node物理主机)——SVC——pod(SVC到pod是kube-proxy来实现负载均衡转发的)。


pod和主机之间有端口映射,但是我们无法管理,可以用svc批量做端口映射


kube-proxy:运行在每个节点上(master和node都有),负责为后端pod提供网络代理和负载均衡功能的,处理集中网络流量的。kube-proxy转发模式有两种iptables 和 ipvs,默认是前者。

开始搭建k8s

首先修改一下主机名:

hostnamectl set-hostname kmaster/knode1/knode2

远程连接:

1.你没有关闭DNS反向解析 2.没有关闭GSS身份认证

修改配置文件

[root@ljh ~]# vim /etc/ssh/sshd_config

修改里面的内容

UseDNS no
GSSAPIAuthentication no

修改静态IP地址:


[root@knode1 ~]# cd /etc/sysconfig/network-scripts/
[root@knode1 network-scripts]# ls
ifcfg-ens160
[root@knode1 network-scripts]# cat ifcfg-ens160
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=none不让dhcp自动获取IP
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=eui64
NAME=ens160
UUID=fb102c69-b31e-4397-a1d2-9abe9954a16c
DEVICE=ens160
IPADDR=192.168.142.101设置的IP
PREFIX=24子网掩码
GATEWAY=192.168.142.2网关
ONBOOT=yes

跑脚本(.sh)

K8s基本概念(kubernetes)_kubernetes_04

执行之前,注意两点:

1. 因为配置的是本地源,所以虚拟机需要提前挂载光盘

2. 核查自己的主机网卡名称,我叫ens160,所以脚本第29行是ens160,如果不是,需要修改。

[root@master ~]# sh Stream8-k8s-v1.30.0.sh
[root@node1 ~]# sh Stream8-k8s-v1.30.0.sh
[root@node2 ~]# sh Stream8-k8s-v1.30.0.sh

初始化集群(仅master)

[root@master ~]# kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version=v1.30.0 --pod-network-cidr=10.244.0.0/16

配置环境变量(仅master)

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> /etc/profile
source /etc/profile

[root@master ~]# kubectl get node
NAME     STATUS     ROLES           AGE     VERSION
master   NotReady   control-plane   6m54s   v1.30.0


将工作节点加入集群

Then you can join any number of worker nodes by running the following on each as root:


kubeadm join 192.168.44.100:6443 --token iwliyb.oxzbjy94z2wnpbdw \

        --discovery-token-ca-cert-hash sha256:a1b8f52164343307daa223828dbf672e930b30d915575d23d2af40bfbfb79131


将上面的命令分别在不同的节点上去执行即可。

[root@master ~]# kubectl get node
NAME     STATUS     ROLES           AGE     VERSION
master   NotReady   control-plane   9m22s   v1.30.0
node1    NotReady   <none>          30s     v1.30.0
node2    NotReady   <none>          4s      v1.30.0


如果join命令过期了,或者找不到了,在master上重新执行生成即可。

[root@master ~]# kubeadm token create --print-join-command

kubeadm join 192.168.44.100:6443 --token oz26gr.qc0t5j6xgig5nv9q --discovery-token-ca-cert-hash sha256:a1b8f52164343307daa223828dbf672e930b30d915575d23d2af40bfbfb79131


但是现在有个问题

谷歌k8s这个产品,本身是没有去实现跨节点网络互通的功能的。要实现需要借助三方网络插件,我们本次使用calico。

上传calico的yaml文件(仅master)

[root@master ~]# ls
anaconda-ks.cfg  custom-resources-v3.28.0.yamlStream8-k8s-v1.30.0.sh  tigera-operator-v3.28.0.yaml

之前,直接按照顺序执行两个yaml文件即可,会自动去dockerhub拉取calico镜像,但现在需要我们手工导入离线版的calico镜像(最新版本)。

上传calico镜像(3个节点)

[root@master ~]# mkdir /calico
[root@master ~]# cd /calico/
[root@master calico]# ll
total 918768
-rw-r--r--. 1 root root  97941504 Aug 19 16:38 apiserver-v3.28.0.tar
-rw-r--r--. 1 root root 208990208 Aug 19 16:38 cni-v3.28.0.tar
-rw-r--r--. 1 root root  18291712 Aug 19 16:38 csi-v3.28.0.tar
-rw-r--r--. 1 root root  79177216 Aug 19 16:38 kube-controllers-v3.28.0.tar
-rw-r--r--. 1 root root  23545856 Aug 19 16:38 node-driver-registrar-v3.28.0.tar
-rw-r--r--. 1 root root 354560512 Aug 19 16:38 node-v3.28.0.tar
-rw-r--r--. 1 root root  73668608 Aug 19 16:38 operator-v1.34.0.tar
-rw-r--r--. 1 root root  13446144 Aug 19 16:38 pod2daemon-flexvol-v3.28.0.tar
-rw-r--r--. 1 root root  71183360 Aug 19 16:38 typha-v3.28.0.tar

[root@master /]# scp -r calico 192.168.44.101:/
[root@master /]# scp -r calico 192.168.44.102:/


导入calico镜像(3个节点)

cd /calico

ctr -n k8s.io image import apiserver-v3.28.0.tar
ctr -n k8s.io image import cni-v3.28.0.tar csi-v3.28.0.tar
ctr -n k8s.io image import csi-v3.28.0.tar
ctr -n k8s.io image import kube-controllers-v3.28.0.tar
ctr -n k8s.io image import node-driver-registrar-v3.28.0.tar
ctr -n k8s.io image import node-v3.28.0.tar
ctr -n k8s.io image import operator-v1.34.0.tar
ctr -n k8s.io image import pod2daemon-flexvol-v3.28.0.tar
ctr -n k8s.io image import typha-v3.28.0.tar


执行calico脚本(仅master)

[root@master ~]# kubectl create -f tigera-operator-v3.28.0.yaml
[root@master ~]# kubectl create -f custom-resources-v3.28.0.yaml
installation.operator.tigera.io/default created
apiserver.operator.tigera.io/default created
[root@master ~]#
[root@master ~]# watch -n 1 kubectl get pod -n calico-system

K8s基本概念(kubernetes)_kubernetes_05

1/1  2/2  

正常运行了几个/这个pod(器皿)里面有几个容器

【大功告成!集群搭建好了】

[root@master ~]# kubectl get node
NAME     STATUS   ROLES           AGE   VERSION
master   Ready    control-plane   64m   v1.30.0
node1    Ready    <none>          55m   v1.30.0
node2    Ready    <none>          54m   v1.30.0


添加补全功能

[root@master ~]# vim /etc/profile

添加
# /etc/profile
source <(kubectl completion bash)

[root@master ~]# source /etc/profile
[root@master ~]# kubectl get nodes  -命令可以补全

查看节点或容器的使用率

[root@master ~]# kubectl top node
error:Metrics API not available

因为缺少组件,所以无法通过top查看,使用yaml文件创建metrics server

[root@master calico]# kubectl create -f components.yaml
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created


[root@master ~]#kubectl top node
NAME     CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
master   164m         8%     2370Mi          30%
node1    62m          3%     1089Mi          13%
node2    70m          3%     1077Mi          13%


docker和k8s命令区别:


docker (docker) : docker命令行工具无需单独安装。

ctr (containerd) : containerd命令行工具,无需单独安装,集成containerd,多用于测试或开发。

nerdctl(containerd) : containerd客户端工具,使用效果与docker命令的语法一致。需要单独安装。

crictl (kubernetes):遵循CRI接口规范的一个命令行工具,通常用它来检查和管理kubelet节点上的容器运行时和镜像。没有tag和push。

K8s基本概念(kubernetes)_kubernetes_06

K8s自动补全:

echo "source <(kubectl completion bash)" >> /etc/profile

查看资源占用情况:

[root@kmaster ~]# kubectl top node 
NAME      CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
kmaster   239m         5%     1715Mi          21%       
node      82m          2%     1050Mi          13%

cpu 239m  m=1000 ,cpu 239m = 多少个vcpus,239/1000 约0.2vcpus

m代表时间分片,1m代表1000,500m=0.5vcpu


pod管理:

在k8s集群里面,k8s调度的最小单位 pod,pod里面跑容器(containerd)。

如何创建一个pod,通常情况下有两种方式:1.命令行  2.yaml文件(推荐)。

查看命令简称: kubectl api-resources

创建自己的ns:kubectl create ns mememda

查看ns:kubens

切换ns:kubens ns

查看pod:kubectl get pod


Namespace:

横跨整个物理节点,就是做资源隔离。

K8s基本概念(kubernetes)_kubernetes_07

查询命名空间namespace=N S

[root@kmaster ~]# kubectl get ns

切换命名空间的方法

首先查看默认的命名空间是

[root@kmaster ~]# kubectl config get-contexts

也可以下载好脚本kubens,用winscp把脚本传到master节点上,用脚本来查看或者切换命名空间

K8s基本概念(kubernetes)_kubernetes_08

把该文件放在/bin目录下,给脚本加入执行权限,chmod +x  /bin/kubens

执行脚本:kubens +查看当前的命名空间

切换命名空间:kubens +命名空间


命令行创建pod:

我们的集群环境是3台虚拟机,master, node1和node2,默认我们自己创建的业务pod是不会在master上运行的,所以一定会调度到node1或者node2上,具体在那一台node上,怎么查看呢?既可以看到是node1还是node2上了,截图上的环境是只有一台node。

解决方法如下:ucloud上注册账号

https://console.ucloud.cn/uhub/uhub/accelerate_image

用ucloud的镜像加速器来拉取镜像,创建pod

K8s基本概念(kubernetes)_kubernetes_09

查看pod2的详细信息:kubectl describe pods pod2

由于pod1在node上,那镜像肯定在node上


yaml文件创建pod

# 1.每一级标题必须左对齐

# 2.不同级要使用缩进,对于缩进必须使用空格,不能使用tab

--dry-run 参数主要是测试检验语句是否正确,不会影响当前集群现状。

它有3个参数:null / server/client

server:它会把这个语句发送给服务端 kube-apiserver,但是服务器端不会给你执行该语句,服务端仅仅会返回命令创建的整个资源信息(相当于在服务端模拟一下),因为经过了服务端,所以返回的参数非常多,服务端用得到的用不到的信息全都出来了,不好去编辑。

可以一个pod里面启动多个容器吗?可以,yaml文件实现

[root@kmaster ~]# vim pod3.yaml
[root@kmaster ~]# cat pod3.yaml 
apiVersion:v1
kind:Pod
metadata:
creationTimestamp:null
labels:
run:pod3
name:pod3
spec:
containers:
- args:
- sleep
- "3600"  
image:uhub.service.ucloud.cn/hciecloud/nginx
imagePullPolicy:IfNotPresent
name: r1
resources:{}
- image:nginx 
imagePullPolicy:IfNotPresent
name: r2
resources:{}
dnsPolicy:ClusterFirst
restartPolicy:Always
status:{}
[root@kmaster ~]# kubectl apply -f pod3.yaml
Pod/pod3 created

登录pod3 默认连接到容器r1:

kubectl exce -ti pod3 -- bash

如果想登录r2 用-c指定r2即可:

kubectl exce -ti pod3 -c r2 -- bash

查看pod:kubectl get pod

删除pod:kubectl delete pods/pod1

查看镜像:crictl  images

K8s基本概念(kubernetes)_kubernetes_10


镜像的下载策略

Always:它每次都会联网检查最新的镜像,不管你本地有没有镜像,都会到互联网上拉取镜像(动作:会有联网和拉取这两个动作),最慢的

Never:它只会使用本地镜像,从不去互联网拉取镜像,如果本地没有镜像,则启动pod会失败,如果本地有镜像,则启动速度是最快的

IfNotPresent:它会先检测本地有没有镜像,本地没有镜像,则联网拉取镜像,再启动pod,如果有镜像,联网检测本地的镜像版本是否是latest最新版本,本地的镜像如果是最新版本,则使用本地镜像启动pod,本地镜像如果不是最新版本,则拉取latest版本镜像,再启动pod,但是如果联不通外网,而且本地有镜像,则直接用本地镜像。速度是介于两者之间。


镜像重启策略

restartPolicy:Always  /  Never / OnFailure

Always:默认。不管是正常退出,还是非正常退出,反复一直重启

Never: 不管正常退出还是非正常退出,都不重启

OnFailure: 正常退出 不重启,非正常退出,要重启。


比如手工指定了一个命令sleep 30,运行完毕后,退出的叫正常退出;

比如容器挂掉了,参数错误,命令错误导致的退出,叫非正常退出。


标签:主机标签和pod标签


主机标签

[root@master ~]# kubectl get nodes master --show-labels

NAME     STATUS   ROLES           AGE   VERSION   LABELS

master   Ready    control-plane   19h   v1.30.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=master,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=

标签的规则由键值对构成  xx=yy 键key=值value

key的格式可以是 xxx   xx.xx  xx.xx/xx.xx

[root@master ~]# kubectl label nodes node2 disk=ssd
node/node2 labeled

[root@master ~]# kubectl get nodes node2 --show-labels

NAME    STATUS   ROLES    AGE   VERSION   LABELS

node2   Ready    <none>   19h   v1.30.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disk=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=node2,kubernetes.io/os=linux


[root@master ~]# kubectl label nodes node2 disk-
node/node2 unlabeled

[root@master ~]# kubectl get nodes node2 --show-labels

NAME    STATUS   ROLES    AGE   VERSION   LABELS

node2   Ready    <none>   19h   v1.30.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=node2,kubernetes.io/os=linux


pod标签

pod标签不能是纯数字,如果是纯数字要加单引号,变成字符串的格式,

而且冒号后面要有空格

[root@master ~]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
aaa: bbb
ccc: ddd
kkk: '111'
name: pod1
spec:
containers:
- image: swr.cn-north-4.myhuaweicloud.com/tianmeili/nginx:1.0
imagePullPolicy: Never
name: pod1
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}


[root@master ~]# kubectl label pod pod1 xxx=yyy
pod/pod1 labeled
[root@master ~]# kubectl get pod --show-labels
NAME   READY   STATUS    RESTARTS   AGE     LABELS
pod1   1/1     Running   0          2m18s   aaa=bbb,ccc=ddd,kkk=111,run=pod1,xxx=yyy

[root@master ~]# kubectl label pod pod1 xxx-
pod/pod1 unlabeled
[root@master ~]# kubectl label pod pod1 aaa-
pod/pod1 unlabeled
[root@master ~]# kubectl label pod pod1 kkk-
pod/pod1 unlabeled
[root@master ~]# kubectl get pod --show-labels
NAME   READY   STATUS    RESTARTS   AGE     LABELS
pod1   1/1     Running   0          3m11s   ccc=ddd,run=pod1

K8s基本概念(kubernetes)_kubernetes_11

[root@master ~]# kubectl label nodes node2 disk=ssd
node/node2 labeled

[root@master ~]# vim pod1.yaml
[root@master ~]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
aaa: bbb
ccc: ddd
kkk: '111'
name: pod1
spec:
  nodeSelector:
disk: ssd
containers:
- image: swr.cn-north-4.myhuaweicloud.com/tianmeili/nginx:1.0
imagePullPolicy: Never
name: pod1
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
[root@master ~]# kubectl apply -f pod1.yaml
pod/pod1 created
[root@master ~]# kubectl get pod -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP              NODE    NOMINATED NODE   READINESS GATES
pod1   1/1     Running   0          6s    10.244.104.16   node2   <none>           <none>

加入容器匹配的标签,在主机节点上没有,怎么办

[root@master ~]# vim pod2.yaml
[root@master ~]# cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod2
aaa: bbb
ccc: ddd
kkk: '111'
name: pod2
spec:
nodeSelector:
disk: aaaaa
containers:
- image: swr.cn-north-4.myhuaweicloud.com/tianmeili/nginx:1.0
imagePullPolicy: Never
name: pod2
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
[root@master ~]# kubectl apply -f pod2.yaml
pod/pod2 created
[root@master ~]# kubectl get pod -o wide
NAME   READY   STATUS    RESTARTS   AGE    IP              NODE     NOMINATED NODE   READINESS GATES
pod1   1/1     Running   0          2m7s   10.244.104.16   node2    <none>           <none>
pod2   0/1     Pending   0          6s     <none>          <none>   <none>           <none>


特殊标签

特殊标签默认是在master节点上:node-role.kubernetes.io/control-plane=

这个标签其实就是指定集群里面节点角色使用的标签。

K8s基本概念(kubernetes)_kubernetes_12

node-role.kubernetes.io/control-plane= 定义角色

[root@master ~]# kubectl label nodes master node-role.kubernetes.io/control-plane-

node/master unlabeled

[root@master ~]# kubectl get nodes

NAME     STATUS   ROLES    AGE   VERSION

master   Ready    <none>   22h   v1.30.0

node1    Ready    <none>   22h   v1.30.0

node2    Ready    <none>   22h   v1.30.0

[root@master ~]# kubectl label nodes master node-role.kubernetes.io/master=

node/master labeled

[root@master ~]# kubectl get nodes

NAME     STATUS   ROLES    AGE   VERSION

master   Ready    master   22h   v1.30.0

node1    Ready    <none>   22h   v1.30.0

node2    Ready    <none>   22h   v1.30.0

[root@master ~]# kubectl label nodes node1 node-role.kubernetes.io/node1=

node/node1 labeled

[root@master ~]# kubectl get nodes

NAME     STATUS   ROLES    AGE   VERSION

master   Ready    master   22h   v1.30.0

node1    Ready    node1    22h   v1.30.0

node2    Ready    <none>   22h   v1.30.0

[root@master ~]# kubectl label nodes node2 node-role.kubernetes.io/node2=

node/node2 labeled

[root@master ~]# kubectl get nodes

NAME     STATUS   ROLES    AGE   VERSION

master   Ready    master   22h   v1.30.0

node1    Ready    node1    22h   v1.30.0

node2    Ready    node2    22h   v1.30.0


为pod指定运行节点:

yaml文件中 指定标签匹配,容器就会创建在node2上面。关联主机的是nodeSelector节点选择器,

K8s基本概念(kubernetes)_kubernetes_13

K8S里面不是之前的云HCS的里面的逻辑,pod的标签和节点的标签是没有关系的,虽然都叫labels,但是他们没有关联性,pod的标签labeles是匹配未来我们要讲的deployment控制器的

pod如果想要对应到节点,不是通过匹配节点labels来实现的,而是通过pod定义的一个参数,podselector选择器参数来实现的。[root@kmaster 20240727]# kubectl get nodes knode2 --show-labels

NAME     STATUS   ROLES    AGE   VERSION   LABELS

knode2   Ready    <none>   21h   v1.30.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=knode2,kubernetes.io/os=linux

[root@kmaster 20240727]# kubectl label nodes knode2 disk=ssd


pod调度:

包含3个规则

cordon:告警警戒,拉一条警戒线

drain:包含两个动作,一个是cordon警戒,一个是evicted驱逐,配合控制器使用。

taint:污点

第一个cordon:如果我要临时维护knode2,那么我就拉起一条警戒线,提出告警,从现在开始,新增的pod不要往我这个node上调度了,已经存在的pod不受影响。

[root@kmaster]# kubectl cordon knode2

怎么解除knode2的cordon警戒呢?

[root@kmaster]# kubectl uncordon knode2

第二个叫drain(先cordon拉警戒线,就是该节点状态会带上SchedulingDisabled,同时会evicted驱逐/删除该节点上之前创建好的pod,但是因为生产环境中deployment里面有个replications副本数,所以pod会在其他节点上重新创建出来)

理论上是这样的,当执行drain操作后,节点拉起警戒线,在该节点上的pod(因为是控制器管理,一般都会副本,比如3副本)就会被删除,然后在其他节点上重新创建出来。但是我们现在的环境,是单个pod,还没有讲到控制器,因此只会删除,不会在其他节点上重建出来。

实验一:

[root@kmaster 20240727]# kubectl drain knode2

创建的适合回车,提示你什么,就往后面加参数--什么什么,之间往后面加就行了。

[root@kmaster 20240727]#kubectl drain knode2 --ignore-daemonsets --force --delete-emptydir-data

先cordon,再evicted驱逐(删除)。

[root@kmaster 20240727]# kubectl get pod -o wide

No resources found in memeda namespace.

本来pod1,pod2 ,pod3都在knode2上,现在都没有,因为都被删掉了。

实验二:可以更直观的看到驱逐的动作

[root@kmaster ~]# kubectl create deployment web1 --image nginx --dry-run=client -o yaml > web1.yaml

Web1.yaml文件的replicas是副本数,

[root@kmaster ~]# kubectl apply -f web1.yaml

[root@kmaster ~]# kubectl get pod -o wide

就可以看见创建了6个pod

[root@kmaster ~]# kubectl get deployments.apps

[root@kmaster ~]# kubectl drain knode2 

查看还是6个pod,因为drain 驱逐:一旦设置了drain,不仅会cordon,还会evicted驱逐。(本意是把该节点上的pod删除掉,并在其他node上启动,始终保证我有6个可用pod)

[root@kmaster ~]# kubectl uncordonknode2

taint污点:

不管创建多少个容器pod,默认都不会在master节点上创建。

带上污点后,默认pod不能调度到该节点了。

但是,如果未来想让pod调度到带有污点的节点上。可以使用容忍度参数toleration来容忍它的污点。 toleration和污点配合使用。

在yaml文件里面复制之前,输入:set  paste设置按格式复制,不是复制完成后变成纯文本了

K8s基本概念(kubernetes)_kubernetes_14

k8s存储:

存储volume

docker默认情况下,数据保存在容器层,一旦删除容器,数据也随之删除。

在k8s环境里,pod运行容器,之前也没有指定存储,当删除pod的时候,之前在pod里面写入的数据就没有了。

如何需要数据永久存储怎么办?三个方面:1.本地存储2.网络存储3.持久化存储(重点,是一种管理方式) persistent  volume (pv) pvc  claim

docker启动一个容器:


本地存储:

emptyDir:是临时在pod所在的节点上随机生成一个临时目录,会随着pod删除而删除。

hostPath:是一个永久手工指定的目录,删除pod,不会删除hostPath类型的目录。

对应docker有没有带-v (volume卷),没有带-v参数,那么也是随机生成目录,随容器删除而删除。如果带了-v,就是永久保留。


网络存储:

NFS Network FileSystem 网络存储支持很多种类型nfs/ceph/iscsi等都可以作为后端存储来使用,举例NFS。


持久化存储:

持久化存储不是一种存储类型,而是一种管理存储的方案。

持久化存储有两个类型:PersistentVolume/PersistentVolumeClaim,持久卷/持久卷申领,简称为PV/PVC

所谓的持久化存储,它只是一种k8s里面针对存储管理的一种机制。后端该对接什么存储,就对接什么存储(NFS/AWS/Ceph。。。。)

master上有很多命名空间 N1和N2,不同用户连接到不同的命名空间里面。用户管理pod,而专员管理存储,分开管理。

下面是一个存储服务器,共享多个目录,由专门的管理员管理。管理员会在集群中创建 PersistentVolume(PV),这个PV是全局可见的。该PV会和存储服务器中的某个目录关联。

用户要做的就是创建自己的 PVC,PVC是基于命名空间进行隔离的。而PV是全局可见的。之后把PVC和PV关联在一起。

用户是关联命名空间,管理命名空间里面的pod的,存储管理员是管理PV的,管理员创建PV的时候会和底层的目录空间对应,用户在创建PVC的时候会和PV对应,用户在命名空间里面创建pod的时候会指定要使用的PVC,所以持久卷是一种管理机制,后端存储类型可以是lun,nfs共享目录,ceph分布式存储等等

使用持久卷管理机制的流程:首先创建PV,之后再创建PVC,会自动关联,最后创建pod

K8s基本概念(kubernetes)_kubernetes_15

创建pv

[root@master ~]# vim pv01.yaml
[root@master ~]# cat pv01.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
storageClassName: manual
nfs:
path: "/share_data"
server: 192.168.44.159
[root@master ~]# kubectl apply -f pv01.yaml
persistentvolume/pv01 created


创建pvc

[root@master ~]# vim pvc01.yaml
[root@master ~]# cat pvc01.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc01
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
[root@master ~]# kubectl apply -f pvc01.yaml
persistentvolumeclaim/pvc01 created
[root@master ~]# kubectl get pvc
NAME    STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
pvc01   Bound    pv01     5Gi        RWO            manual         <unset>                 4s
[root@master ~]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM          STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pv01   5Gi        RWO            Retain           Bound    memeda/pvc01   manual         <unset>

创建pod

[root@master ~]# vim pod1.yaml
[root@master ~]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
volumes:
- name: v1
emptyDir: {}
- name: v2
hostPath:
path: /physical_dir
- name: v3
nfs:
server: 192.168.44.159
path: /share_data
- name: v4
persistentVolumeClaim:
claimName: pvc01
containers:
- image: swr.cn-north-4.myhuaweicloud.com/tianmeili/nginx:1.0
imagePullPolicy: Never
name: pod1
resources: {}
volumeMounts:
- name: v4
mountPath: /pvcpvc
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
[root@master ~]# kubectl get pod
No resources found in memeda namespace.
[root@master ~]# kubectl apply -f pod1.yaml
pod/pod1 created
[root@master ~]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
pod1   1/1     Running   0          4s
[root@master ~]# kubectl exec -ti pod1 -- bash
root@pod1:/# cd /pvcpvc/
root@pod1:/pvcpvc# touch {a,b,c}{1,2,3}.txt
root@pod1:/pvcpvc# ls
111  a1.txt  a2.txt  a3.txt  b1.txt  b2.txt  b3.txt  c1.txt  c2.txt  c3.txt
root@pod1:/pvcpvc#

[root@nfs ~]# ls /share_data/
111  a1.txt  a2.txt  a3.txt  b1.txt  b2.txt  b3.txt  c1.txt  c2.txt  c3.txt
[root@nfs ~]#


现在,把容器删除,PVC和PV都删除,NFS内容是否会删除呢?不会,因为pv默认的保留策略是retain

[root@master ~]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM          STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pv01   5Gi        RWO            RetainBound    memeda/pvc01   manual         <unset>


有没有可以删除pvc之后,带着pv和底层数据一起删除呢?有,需要使用动态制备卷功能。