K8S尝试和集群搭建
1.准备四台阿里云服务器2核4G2.检查环境版本:uname -r3.解析主机名:vim /etc/hosts走私网,省流量[root@bobo1 ~]# vim /etc/hosts::1localhostlocalhost.localdomainlocalhost6localhost6.localdomain6127.0.0.1localhostlocalhost.localdomainlo.
新林的k8s安装教程很好搭配着看
k8s-(五)最全的安装教程(使用kubeadm在Centos7上部署kubernetes1.18)以及安装异常问题记录_新林。的博客-CSDN博客_kubernetes
K8s集群搭建教程 - 手把手搭建已避免各种坑_Fred-X的博客-CSDN博客_k8s集群搭建
使用kubeadm的形式启动master之后如何将node节点重新加入到集群_qq_42533216的博客-CSDN博客_kubeadm重新加入
设置主机名:hostnamectl set-hostname k8s-master
hostnamectl set-hostname k8s-master
修改host,配置主机名
cat >> /etc/hosts << EOF
172.26.144.94 master
172.26.144.96 node01
172.26.144.97 node02
172.26.144.95 node03
EOF
一件安装docker,kubeadm,kubectl脚本,自己创建sh文件执行即可:
#! /bin/bash
echo "正在卸载旧版本docker"
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
echo"旧版本卸载完毕"
echo" =======正在删除旧版本文件夹======="
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
echo "开始安装docker程序"
echo "=========基本环境安装扫描=========="
yum install -y yum-utils
yum install -y yum-utils device-mapper-persistent-data lvm2
echo "========设置阿里云镜像仓库========="
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
echo "正在更新索引"
yum makecache
yum makecache fast
echo "======开始安装docker引擎========"
yum install docker-ce docker-ce-cli containerd.io -y
echo "=======启动dokcer查看版本"
systemctl start docker
docker version
echo "=========运行hello-world=======检查docker是否可用"
docker run hello-world
docker images
echo "====hello-world程序出现代表可用======"
echo "配置阿里云镜像加速器"
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"exec-opts": [
"native.cgroupdriver=systemd"
],
"registry-mirrors": ["https://wy2ktaj3.mirror.aliyuncs.com"]
}
EOF
echo "重启docker"
sudo systemctl daemon-reload
echo "查看docker"
docker version
echo "===========安装结束,恭喜波波!!!!================"
sudo systemctl restart docker
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[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
echo "=======安装kubeadm、kubelet和kubectl=========="
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
echo "修改driver为一致"
cat > /etc/sysconfig/kubelet << EOF
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
EOF
echo "设置开机自启"
systemctl enable kubelet
手动安装:
一、基础环境配置
1.准备四台阿里云服务器2核4G
2.检查环境版本:
uname -r
3.解析主机名:
vim /etc/hosts
走私网,省流量
[root@bobo1 ~]# vim /etc/hosts
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
172.23.6.46 master
172.23.6.44 node1
172.23.6.45 node2
172.23.6.43 node3
设置好后尝试ping通:
ping master
ping node1
确认都可以ping通
4.时间同步:这里使用网络同步服务,企业内部推荐自己搭建:
启动时间同步器:
systemctl start chronyd
设置开机时间同步自启
systemctl enable chronyd
使用date参看时间:
date
date
Tue Mar 15 09:48:44 PM CST 2022
5.测试环境才能关-----禁用系统iptables和firewalld服务:
[root@bobo1 ~]# systemctl stop firewalld
[root@bobo1 ~]# systemctl disable firewalld
[root@bobo1 ~]# systemctl stop iptables
[root@bobo1 ~]# systemctl disable iptables
6.禁用selinu安全服务----这玩意不好用
vim /etc/selinux/config
12行
SELINUX=disabled
- 永久关闭selinux,需要重启:
sed -i 's/enforcing/disabled/' /etc/selinux/config
输入getenforce参看状态:
[root@bobo1 selinux]# getenforce
Disabled
7.强制要求------禁用swap分区:虚拟内存分区,对性能产生巨大影响
vim /etc/fstab
或者:
sed -ri 's/.*swap.*/#&/' /etc/fstab
8.强制要求--修改linux内核参数:
vim /etc/sysctl.d/kubernetes.conf
写入文件:
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
重新加载让文件生效:sysctl -p
[root@bobo1 ~]# sysctl -p
vm.swappiness = 0
kernel.sysrq = 1
net.ipv4.neigh.default.gc_stale_time = 120
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_slow_start_after_idle = 0
加载网桥过滤模块:
modprobe br_netfilter
查看是否加载成功:
[root@bobo1 ~]# lsmod | grep br_netfilter
br_netfilter 32768 0
bridge 266240 1 br_netfilter
9..配置ipvs功能:ipvs性能比iptables高
安装ipset和ipvsadm,用来管理ips
yum install -y ipset ipvsadm
在所有节点执行脚本:
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
EOF
检查是否加载成功:
lsmod | grep -e ipvs -e nf_conntrack_ipv4
第二个红线那是5个模块:
上述全部成功后重启linux
reboot
swap分区是0就是对的
二、每个节点安装Docker、kubeadm、kubelet和kubectl
2.1docker的安装详见:
docker尝试和Swarm集群搭建_波波爱下班的博客-CSDN博客
1.配置阿里镜像源
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
2.更新索引包:
yum makecache
3,安装docker引擎:
yum install docker-ce docker-ce-cli containerd.io
4.设置docker开机自启:
systemctl enable docker && systemctl start docker
5.查看docker是否配置成功:
docker version
6.配置阿里云镜像
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"exec-opts": [
"native.cgroupdriver=systemd"
],
"registry-mirrors": ["https://wy2ktaj3.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
7.配置完毕重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker
挂载
docker run --name=mynginx \
-d --restart=always \
-p 88:80 -v /data/html:/usr/share/nginx/html:ro \
nginx
# 修改页面只需要去 主机的 /data/html
2.2安装kubeadm、kubelet和kubectl
1.配置阿里镜像源
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[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.由于版本更新频繁,这里指定版本号部署kubeadm:kubelet和kubectl
yum install -y kubelet-1.18.0 kubeadm-1.18.0 kubectl-1.18.0
3.为了实现Docker使用的cgroup drvier和kubelet使用的cgroup drver一致,建议修改"/etc/sysconfig/kubelet"文件的内容:
vim /etc/sysconfig/kubelet
# 修改
KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"
KUBE_PROXY_MODE="ipvs"
4.设置为开机自启动即可,由于没有生成配置文件,集群初始化后自动启动:
systemctl enable kubelet
2.3 准备集群镜像---就是安装一系列组件
1)查看k8s所需镜像
kubeadm config images list
2.4 部署k8s的Master节点,
停掉键盘同时输入,每一个都单独配置
1.部署k8s的Master节点 自己的(172.23.6.46):
# 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里需要指定阿里云镜像仓库地址
只把aipserver改成你的内网地址:其他不要动:
# 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里需要指定阿里云镜像仓库地址
# 由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里需要指定阿里云镜像仓库地址
kubeadm init \
--apiserver-advertise-address=172.26.144.85 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.18.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
出现join就是成功了:
2.创建kubectl
注:
1.不配置$HOME/.kube/config的话,kubectl命令不可用,
2.node节点写法有点不一样,node节点的这行为:sudo cp -i /etc/kubernetes/kubelet.conf.conf $HOME/.kube/config
上图表示运行成功了,想要啥啥啥就执行蓝色框的
想要运行网络 执行红色的token在node节点上
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 默认的token有效期为2小时,当过期之后,该token就不能用了,这时可以使用如下的命令创建token:
-
kubeadm token create --print-join-command
# 生成一个永不过期的token kubeadm token create --ttl 0 --print-join-command
在master上查看当前节点;
kubectl get nodes
显示notReady----------------------这里要安装网络插件,插件安装完后会变成Ready
3.安装calico网络(master节点)
查看版本:
kubectl version
根据版本改v3.18的值
官网文件已更新:
Install Calico networking and network policy for on-premises deployments
curl https://docs.projectcalico.org/v3.18/manifests/calico.yaml -O
原来的
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
或者用这个:
curl https://docs.projectcalico.org/v3.18/manifests/calico.yaml -O
kubectl apply -f calico.yaml
查看:
kubectl get pod --all-namespaces
查看:插件安装完后会变成Ready
安装calico网络网络后过一会再输入kubectl get node,可以看到节点的STATUS由NotReady变为Ready
kubectl get node
2.5.node节点加入集群(node节点)
1)如果忘了token 在master上用 kubeadm reset重置
kubeadm reset
master节点然后重新init:token就出来了
kubeadm init --kubernetes-version=1.18.0 \
--apiserver-advertise-address=172.26.144.85 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.10.0.0/16 --pod-network-cidr=10.122.0.0/16
注:
1.kubeadm init后得到的token有效期为24小时,过期后需要重新创建token,执行:kubeadm token create获取新token
2.kubeadm token list 查看token列表,如果说服务没停下:
kubeadm reset重置master节点,然后重新执行init
2)3个node节点加入master:
kubeadm join 172.26.144.85:6443 --token q23hcq.8aeavy88ux5pjngo \
--discovery-token-ca-cert-hash sha256:36ee0ac166f95cec98342cf43e51ec4504f23926b17b997cdfc7756c37dca403
不然:/etc/kubernetes/会为空:
加入之后
会出现配置文件:
3)node节点的kubectl配置和主节点有细微区别:
注:
1.不配置$HOME/.kube/config的话,kubectl命令不可用,
2.node节点写法有点不一样,node节点的这行为:sudo cp -i /etc/kubernetes/kubelet.conf $HOME/.kube/config
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/kubelet.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
到了这步,把所有的node节点加入mater节点后,k8s的环境已经安装完成了
在node节点查看:
kubectl get node
9.安装kubernetes-dashboard(master节点)
Dashboard是可视化插件,它可以给用户提供一个可视化的 Web 界面来查看当前集群的各种信息。用户可以用 Kubernetes Dashboard 部署容器化的应用、监控应用的状态、执行故障排查任务以及管理 Kubernetes 各种资源。
官方部署dashboard的服务没使用nodeport,将yaml文件下载到本地,在service里添加nodeport
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc7/aio/deploy/recommended.yaml
vim recommended.yaml
加入两行:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort // 有配置NodePort,外部流量可访问k8s中的服务
ports:
- port: 30080 // 服务访问端口
targetPort: 80 // 容器端口
nodePort: 30001 // NodePort
selector:
name: nginx-pod
kubectl create -f recommended.yaml
如果报错:
报错原因,之前在这台机器使用kubeadm搭建过k8s集群,之前为了可以使当前用户可以使用kubectl命令,做了如下操作。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
1
2
3
解决
删除$HOME/.kube
rm -rf $HOME/.kube
————————————————
版权声明:本文为CSDN博主「瑾川的三行情诗」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fake_hydra/article/details/109119701
执行kubectl create -f recommended.yaml命令后,再执行下面这行,可以看到dashboard已启动
kubectl get svc -n kubernetes-dashboard
如果两个都是ClusterIP就是有问题错的,重新检查yaml文件:
下图是错的情况:
如果说已经存在:如果执行kubectl create -f recommended.yaml 显示exist
则删除原来配置:重新配置:
kubectl delete -f recommended.yaml
重新配置:
kubectl get svc -n kubernetes-dashboard
执行,查看NodePort是否成功:
kubectl get svc -n kubernetes-dashboard
测试nginx能不能访问:
部署nginx:
kubectl create deployment nginx --image=nginx:1.14-alpine
暴露端口:外网可通过端口访问:
kubectl expose deployment nginx --port=80 --type=NodePort
查看服务状态:
kubectl get pods,svc
如果内网可以访问,外网不能访问:设置阿里云安全组!!!!
3 资源管理方式:
3.1命令式对象管理:
查看某个pod:
kubectl get pods
通过pod名查看:
kubectl get pod pod_name
查看某个pod,已yaml或者json展开:
kubectl get pod pod_name -o yaml
kubectl get pod pod_name -o json
常用命令:
3.2.3 资源类型(type):
3.2.4 应用示例:创建容器空间,创建pod并删除:、
命令式对象管理:
1)创建容器空间:容器空间 /空间名
[root@master01 ~]# kubectl create namespace dev
namespace/dev created
2)查看容器空间:找到自己创建的空间dev
[root@master01 ~]# kubectl get ns
NAME STATUS AGE
default Active 7h29m
dev Active 71s
kube-node-lease Active 7h29m
kube-public Active 7h29m
kube-system Active 7h29m
kubernetes-dashboard Active 7h16m
3)运行一个pod,pod里运行一个镜像:
运行pod 镜像 -n在容器空间dev空间里运行
[root@master01 ~]# kubectl run pod --image=nginx -n dev
pod/pod created
[root@master01 ~]# kubectl run pod --image=nginx -n dev
pod/pod created
4)查看pod里面镜像是否运行:
[root@master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pod 1/1 Running 0 2m
5)查看pod运行过程:
[root@master01 ~]# kubectl describe pods pod -n dev
1)分配给node2干活
2)从仓库拉取镜像:
3)镜像拉起成功
4)创建一个pod
5)启动一个容器
6)删除一个pod:
delete pods pod名 空间名
[root@master01 ~]# kubectl delete pods pod -n dev
pod "pod" deleted
7)删除容器空间:
查看容器空间:
kubectl get ns
删除容器空间:
[root@master01 ~]# kubectl delete ns dev
namespace "dev" deleted
3.3 命令式对象配置
3.3.1 概述
- 命令式对象配置:通过命令配置和配置文件去操作kubernetes的资源
要自己准备好yaml文件:
创建资源:创建一个nginx.yaml文件:
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Pod
metadata:
name: nginxpod
namespace: dev
spec:
containers:
- name: nginx-containers
image: nginx:1.17.1
kubectl get -f nginx.yaml
查看资源:
kubectl get -f nginx.yaml
删除资源:
kubectl delete -f nginx.yaml
3.6 扩展:kubectl可以在Node上运行:
scp -r $HOME/.kube k8s-node1:$HOME
scp -r $HOME/.kube k8s-node1:$HOME
失败的话检查环境:查看是都添加主机映射
cat /etc/hosts
- kubectl的运行需要进行配置,它的配置文件是$HOME/.kube,如果想要在Node节点上运行此命令,需要将Master节点的.kube文件夹复制到Node节点上,即在Master节点上执行下面的操作:
- scp -r $HOME/.kube k8s-node1:$HOME
四、Namespace相关
1.查看名称空间
kubelctl get ns
2.查看名称空间里的pods
kubectl get pods -n 名字
3.查看名称空间详情:
kubectl describe ns
4,容器空间的创建和删除:
[root@master01 ~]# kubectl create ns bobo
namespace/bobo created
[root@master01 ~]# kubectl delete ns bobo
namespace "bobo" deleted
5.通过YAML文件创建和删除容器空间:
kubectl create -f xxx.yaml
kubectl delete -f xxx.yaml
Pod:
一个pod里可以有多个容器
1.查看名称空间里的pod
[root@master01 ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-5b57744b7c-br82t 1/1 Running 5 18h
calico-node-7dfhs 1/1 Running 3 18h
calico-node-8gqrn 1/1 Running 3 18h
calico-node-rg5zs 1/1 Running 3 18h
calico-node-rwm9t 1/1 Running 3 18h
coredns-7ff77c879f-2fwxz 1/1 Running 3 19h
coredns-7ff77c879f-zv58n 1/1 Running 3 19h
etcd-master01 1/1 Running 3 19h
2.运行pod:
kubectl run nginx --image=nginx:1.17.1 --port=80 --namespace dev
注:先要创建一个namespace
3.查询namespace中正在运行的pods
kubectl get pod -n dev -o wide
4.查看pod的详细信息:
kubectl describe pod nginxpod -n dev
5.pod的访问,上一个命令会出来个ip地址:
# 通过curl访问
curl ip:端口
6.删除指定的容器---要删除pod控制器:
查看pod控制器的名称:
kubectl get deployment -n dev
删除pod控制器:
kubectl delete deployment 控制器名称 -n dev
7.给容器打标签:
查看容器标签:
kubectl get pod bobo0318bginx -n bobo0318 --show-labels
打标签:
kubectl label pod bobo0318bginx -n bobo0318 version=1.0
可以再次查看变化:
挑选标签:
[root@master01 ~]# kubectl get pods -l "version=1.0" -n bobo0318 --show-labels
NAME READY STATUS RESTARTS AGE LABELS
bobo0318bginx 1/1 Running 0 30m run=bobo0318bginx,version=1.0
删除标签:
kubectl label pod bobo0318bginx -n bobo0318 version-
4.2:Pod控制器Deployment
1.创建deployment:
[root@master01 ~]# kubectl create deployment bobodeployment --image=nginx -n dev
deployment.apps/bobodeployment created
2.产看容器空间里的控制器:
[root@master01 ~]# kubectl get deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
bobodeployment 1/1 1 1 114s
3.根据指定的语法创建pod控制器:创建多个副本
[root@master01 ~]# kubectl scale deployment bobodeployment --replicas=4 -n dev
deployment.apps/bobodeployment scaled
4,再次查看容器空间的pod控制器:发现变成4个
[root@master01 ~]# kubectl get deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
bobodeployment 4/4 4 4 5m53s
5.
- 语法:命令式对象配置
- ① 创建一个deploy-nginx.yaml,内容如下:
-
apiVersion: apps/v1 kind: Deployment metadata: name: nginx namespace: dev spec: replicas: 3 selector: matchLabels: run: nginx template: metadata: labels: run: nginx spec: containers: - image: nginx:1.17.1 name: nginx ports: - containerPort: 80 protocol: TCP
执行创建和删除命令:
-
创建:
-
kubectl create -f deploy-nginx.yaml
[root@master01 ~]# kubectl create -f deploy-nginx.yaml deployment.apps/nginx created
删除:
-
[root@master01 ~]# kubectl delete -f deploy-nginx.yaml deployment.apps "nginx" deleted
- 示例:查看名称为dev的namespace下通过deployment创建的3个Pod:
-
[root@master01 ~]# kubectl get pods -n dev NAME READY STATUS RESTARTS AGE bobodeployment-7665c4c946-5n6px 1/1 Running 0 5m18s bobodeployment-7665c4c946-7kp7m 1/1 Running 0 5m18s bobodeployment-7665c4c946-kpp7w 1/1 Running 0 5m18s bobodeployment-7665c4c946-xjsx9 1/1 Running 0 10m nginx 1/1 Running 0 16m
- 示例:查看名称为dev的namespace下的deployment:
-
[root@master01 ~]# kubectl get deployment -n dev NAME READY UP-TO-DATE AVAILABLE AGE bobodeployment 4/4 4 4 11m
- 示例:查看名为dev的namespace下的名为nginx的deployment的详细信息
-
[root@master01 ~]# kubectl describe deployment bobodeployment -n dev Name: bobodeployment Namespace: dev CreationTimestamp: Fri, 18 Mar 2022 07:29:27 +0800 Labels: app=bobodeployment Annotations: deployment.kubernetes.io/revision: 1 Selector: app=bobodeployment Replicas: 4 desired | 4 updated | 4 total | 4 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=bobodeployment Containers: nginx: Image: nginx Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Progressing True NewReplicaSetAvailable Available True MinimumReplicasAvailable OldReplicaSets: <none> NewReplicaSet: bobodeployment-7665c4c946 (4/4 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 12m deployment-controller Scaled up replica set bobodeployment-7665c4c946 to 1 Normal ScalingReplicaSet 8m1s deployment-controller Scaled up replica set bobodeployment-7665c4c946 to 4
- 示例:删除名为dev的namespace下的名为nginx的deployment:
-
kubectl delete deployment nginx -n dev
[root@master01 ~]# kubectl delete deployment bobodeployment -n dev deployment.apps "bobodeployment" deleted
-
4.3 Service
- 我们已经能够利用Deployment来创建一组Pod来提供具有高可用性的服务,虽然每个Pod都会分配一个单独的Pod的IP地址,但是却存在如下的问题:
- Pod的IP会随着Pod的重建产生变化。
- Pod的IP仅仅是集群内部可见的虚拟的IP,外部无法访问。
-
kubectl create -f deploy-nginx.yaml
查看pods详细信息:
-
[root@master01 ~]# kubectl get pods -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 27m 10.244.186.204 node03 <none> <none> nginx-755c49cf64-h25dp 1/1 Running 0 58s 10.244.248.208 node04 <none> <none> nginx-755c49cf64-s6k4r 1/1 Running 0 58s 10.244.140.80 node02 <none> <none> nginx-755c49cf64-zc58z 1/1 Running 0 58s 10.244.186.207 node03 <none> <none>
Pod的IP仅仅是集群内部可见的虚拟的IP,外部无法访问:
-
curl 10.244.186.204:80
如果pods意外退出,会自动重建新的pod,生成新的虚拟ip地址:
解决外部无法访问问题:
- Service可以看做是一组同类的Pod对外的访问接口,借助Service,应用可以方便的实现服务发现和负载均衡。
4.2 service语法及应用示例
6.2.1 创建集群内部可访问的Service
service是对外请求的暴露接口
- 语法:暴露Service
- kubectl expose deployment xxx --name=服务名 --type=ClusterIP --port=暴露的端口 --target-port=指向集群中的Pod的端口 [-n 命名空间] # 会产生一个CLUSTER-IP,这个就是service的IP,在Service的生命周期内,这个地址是不会变化的
- 示例:暴露名为test的namespace下的名为nginx的deployment,并设置服务名为svc-nginx1;
kubectl expose deployment nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n test
[root@master01 ~]# kubectl expose deployment nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx1 exposed
查看service:
kubectl get service -n test
[root@master01 ~]# kubectl get service -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx1 ClusterIP 10.106.12.4 <none> 80/TCP 98s
4。2.1 创建集群外部部可访问的Service----重点在--type=NodePort
- 示例:暴露名为test的namespace下的名为nginx的deployment,并设置服务名为svc-nginx2
kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n test
自己的:
[root@master01 ~]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev
service/svc-nginx2 exposed
示例:查看名为test的命名空间的所有Service
[root@master01 ~]# kubectl get service -n test
No resources found in test namespace.
[root@master01 ~]# kubectl get service -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx1 ClusterIP 10.106.12.4 <none> 80/TCP 22m
svc-nginx2 NodePort 10.100.154.59 <none> 80:31061/TCP 5m45s
外网测试访问:该端口:http://121.40.179.30:31061/
--type NpdePort --port:80
注:所有集群的ip该端口都可访问:测试通过,所有外网访问ip+端口都可以
4.2.2 删除service服务:
kubectl delete service svc-nginx1 -n test
4.2.3 对象配置方式:
- 示例:对象配置方式
- ① 新建svc-nginx.yaml,内容如下:
-
apiVersion: v1 kind: Service metadata: name: svc-nginx namespace: dev spec: clusterIP: 10.109.179.231 ports: - port: 80 protocol: TCP targetPort: 80 selector: run: nginx type: ClusterIP
执行创建和删除命令:
-
kubectl create -f svc-nginx.yaml
kubectl delete -f svc-nginx.yaml
5.POD详解
方法:explain
kubectl explain pod
看二级属性,上级属性类似:
kubectl explain pod.metadata
5.1pod的配置:
基本格式:
# 返回的重要属性
KIND: Pod
VERSION: v1
RESOURCE: containers <[]Object> # 数组,代表可以有多个容器FIELDS:
name <string> # 容器名称
image <string> # 容器需要的镜像地址
imagePullPolicy <string> # 镜像拉取策略
command <[]string> # 容器的启动命令列表,如不指定,使用打包时使用的启动命令
args <[]string> # 容器的启动命令需要的参数列表
env <[]Object> # 容器环境变量的配置
ports <[]Object> # 容器需要暴露的端口号列表
resources <Object> # 资源限制和资源请求的设置
pod的基本配置yaml:
apiVersion: v1
kind: Pod
metadata:
name: pod-base
namespace: dev
labels:
user: xudaxian
spec:
containers:
- name: nginx # 容器名称
image: nginx:1.17.1 # 容器需要的镜像地址
- name: busybox # 容器名称
image: busybox:1.30 # 容器需要的镜像地址
创建容器空间:
kubectl create ns dev
运行yaml文件:
kubectl create -f pod-base.yaml
[root@master01 ~]# kubectl create -f pod-base.yaml
pod/pod-base created
查看pods:
[root@master01 ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-base 1/2 CrashLoopBackOff 4 3m3s 10.244.140.82 node02 <none> <none>
说明这个pod有问题:只准备好了一个,状态是CrashLoop,重启了5次
用describe 参看pod的详细信息:
kubectl describe pods pod-base -n dev
这里很明显busy有问题:
5.2镜像拉取策略:
- imagePullPolicy:用于设置镜像拉取的策略,kubernetes支持配置三种拉取策略:
-
- Always:总是从远程仓库拉取镜像(一直远程下载)。
-
- IfNotPresent:本地有则使用本地镜像,本地没有则从远程仓库拉取镜像(本地有就用本地,本地没有就使用远程下载)。
-
- Never:只使用本地镜像,从不去远程仓库拉取,本地没有就报错(一直使用本地,没有就报错)。
-
[root@master01 ~]# vim pod-imagepullpolicy.yaml [root@master01 ~]# kubectl create -f pod-imagepullpolicy.yaml pod/pod-imagepullpolicy created
启动成功:(这里我自己修改了yaml文件内容,没有让同时运行两个容器)
5.2.3command命令:
原来这个busybox没跑起来,是因为docker默认无进程退出
清除原来的容器,不然会报容器已经存在:
容器名写你自己的
[root@master01 ~]# kubectl delete pod pod-bobo -n dev
pod "pod-bobo" deleted
可以加个command让他一致运行:写个死循环
apiVersion: v1
kind: Pod
metadata:
name: pod-base
namespace: dev
labels:
user: xudaxian
spec:
containers:
- name: nginx # 容器名称
image: nginx:1.17.1 # 容器需要的镜像地址
- name: busybox # 容器名称
image: busybox:1.30 # 容器需要的镜像地址
加上死循环的目的是不然busybox退出
- name: busybox # 容器名称
image: busybox:1.30 # 容器需要的镜像地址
command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt;sleep 3;done;"]
执行yaml文件,运行成功:
[root@master01 ~]# vim pod-imagepullpolicy.yaml
[root@master01 ~]# kubectl create -f pod-imagepullpolicy.yaml -n dev
pod/pod-bobo created
[root@master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pod-base 1/2 CrashLoopBackOff 13 45m
pod-bobo 2/2 Running 0 20s
进入容器查看是否写入文件:
[root@master01 ~]# kubectl exec pod-bobo -n dev -it -c busybox /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
/ #
/ #
/ #
/ #
/ # cd /tmp
/tmp # ld
/bin/sh: ld: not found
/tmp # ls
hello.txt
/tmp # tail -f bobo.txt
tail: can't open 'bobo.txt': No such file or directory
tail: no files
/tmp # tail -f hello.txt
5.2.4端口设置:
参数:
KIND: Pod
VERSION: v1
RESOURCE: ports <[]Object>
FIELDS:
name <string> # 端口名称,如果指定,必须保证name在pod中是唯一的
containerPort <integer> # 容器要监听的端口(0<x<65536)
hostPort <integer> # 容器要在主机上公开的端口,如果设置,主机上只能运行容器的一个副本(一般省略)
hostIP <string> # 要将外部端口绑定到的主机IP(一般省略)
protocol <string> # 端口协议。必须是UDP、TCP或SCTP。默认为“TCP”
暴露端口:容器内部可以访问:
顺便记一下怎么才能让外网访问:NodePort
apiVersion: v1
kind: Pod
metadata:
name: pod-ports
namespace: dev
labels:
user: xudaxian
spec:
containers:
- name: nginx # 容器名称
image: nginx:1.17.1 # 容器需要的镜像地址
imagePullPolicy: IfNotPresent # 设置镜像拉取策略
ports:
- name: nginx-port # 端口名称,如果执行,必须保证name在Pod中是唯一的
containerPort: 80 # 容器要监听的端口 (0~65536)
protocol: TCP # 端口协议
访问Pod中的容器中的程序使用的是PodIp:containerPort。
5.2.5资源配置,防止某个容器吃掉大量资源,导致其他容器不能正常运行:
resources
limit最大
request:最小
apiVersion: v1
kind: Pod
metadata:
name: pod-resoures
namespace: dev
labels:
user: xudaxian
spec:
containers:
- name: nginx # 容器名称
image: nginx:1.17.1 # 容器需要的镜像地址
imagePullPolicy: IfNotPresent # 设置镜像拉取策略
ports: # 端口设置
- name: nginx-port # 端口名称,如果执行,必须保证name在Pod中是唯一的
containerPort: 80 # 容器要监听的端口 (0~65536)
protocol: TCP # 端口协议
resources: # 资源配额
limits: # 限制资源的上限
cpu: "2" # CPU限制,单位是core数
memory: "10Gi" # 内存限制
requests: # 限制资源的下限
cpu: "1" # CPU限制,单位是core数
memory: "10Mi" # 内存限制
5.3Pod的生命周期
- 我们一般将Pod对象从创建到终止的这段时间范围称为Pod的生命周期,它主要包含下面的过程:
- Pod创建过程。
- 运行初始化容器(init container)过程。
- 运行主容器(main container):
- 容器启动后钩子(post start)、容器终止前钩子(pre stop)。
- 容器的存活性探测(liveness probe)、就绪性探测(readiness probe)。
- Pod终止过程。
5.3.1Pod的创建和终止:
5.3.2初始化容器:
顺序执行:
接下来做一个案例,模拟下面这个需求:
- 假设要以主容器来运行Nginx,但是要求在运行Nginx之前要能够连接上MySQL和Redis所在的服务器。
- 为了简化测试,事先规定好MySQL和Redis所在的IP地址分别为192.168.18.103和192.168.18.104(注意,这两个IP都不能ping通,因为环境中没有这两个IP)。
- 创建文件:
apiVersion: v1
kind: Pod
metadata:
name: pod-initcontainer
namespace: dev
labels:
user: xudaxian
spec:
containers: # 容器配置
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
resources:
limits:
cpu: "2"
memory: "10Gi"
requests:
cpu: "1"
memory: "10Mi"
initContainers: # 初始化容器配置
- name: test-mysql
image: busybox:1.30
command: ["sh","-c","until ping 192.168.18.103 -c 1;do echo waiting for mysql ...;sleep 2;done;"]
securityContext:
privileged: true # 使用特权模式运行容器
- name: test-redis
image: busybox:1.30 #没通就一致等待
command: ["sh","-c","until ping 192.168.18.104 -c 1;do echo waiting for redis ...;sleep 2;done;"]
执行yaml文件:
pod/pod-initcontainer created
[root@master01 ~]# kubectl get pods pod-initcontainer -n dev
NAME READY STATUS RESTARTS AGE
pod-initcontainer 0/1 Init:0/2 0 82s
[root@master01 ~]#
查看pod状态:
kubectl describe pod pod-initcontainer -n dev
新开一个窗口:
加入指定ip:command里面的ip改成自己的端口的,
ifconfig ens33:1 172.26.144.855 netmask 255.255.255.0 up
5.3.3容器钩子
-
- ① exec命令:在容器内执行一次命令。-------用的比较多点
○② tcpSocket:在当前容器尝试访问指定的socket。
-
- ③ httpGet:在当前容器中向某url发起HTTP请求。
5.3.4容器探测:
exec方式:
创建一个pod-liveness-exec.yaml文件内容如下:
’livenessProbe: # 存活性探针
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-exec
namespace: dev
labels:
user: xudaxian
spec:
containers: # 容器配置
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe: # 存活性探针
exec:
command: ["/bin/cat","/tmp/hello.txt"] # 执行一个查看文件的命令,必须失败,因为根本没有这个文件
重启了,探测失败,容器重启
describe查看详细信息
tcpSocket方式
httpGet方式
重启策略
6.Pod的调度
解决怎么控制某些pod到指定的node去:
自动调度:
定向调度:
亲和度调度:声明和谁关系好
污点容忍调度:
6.1定向调度:
指得是在pod上nodeName或者nodeSelector,从而到期望的node上-----强制性的
nodeName:
- 创建一个pod-nodename.yaml文件,内容如下:
-
apiVersion: v1 kind: Pod metadata: name: pod-nodename namespace: dev labels: user: xudaxian spec: containers: # 容器配置 - name: nginx image: nginx:1.17.1 imagePullPolicy: IfNotPresent ports: - name: nginx-port containerPort: 80 protocol: TCP nodeName: k8s-node1 # 指定调度到k8s-node1节点上
创建pod:
-
kubectl create -f pod-nodename.yaml
查看是否到了指定节点:
kubectl get pod pod-nodename -n dev -o wide
nodeSelector:打标签,按照标签执行:
[root@master01 ~]# kubectl label node node03 nodeevn=pro
node/node03 labeled
[root@master01 ~]# kubectl label node node04 nodeevn02=test
node/node04 labeled
查看nodes的标签:
kubectl get node --show-labels
- 创建pod-nodeselector.yaml文件,内容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeselector
namespace: dev
spec:
containers: # 容器配置
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
nodeSelector:
nodeenv02: test # 指定调度到具有nodeenv=pro的Node节点上
执行yaml文件:
[root@master01 ~]# kubectl create -f pod-nodeselector.yaml
pod/pod-nodeselector created
6.2node亲和度调度
6.2.1 nodeAffinity-
- 查看nodeAffinity的可选配置项:
pod.spec.affinity.nodeAffinity
requiredDuringSchedulingIgnoredDuringExecution Node节点必须满足指定的所有规则才可以,相当于硬限制
nodeSelectorTerms 节点选择列表
matchFields 按节点字段列出的节点选择器要求列表
matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
key 键
values 值
operator 关系符 支持Exists, DoesNotExist, In, NotIn, Gt, Lt
preferredDuringSchedulingIgnoredDuringExecution 优先调度到满足指定的规则的Node,相当于软限制 (倾向)
preference 一个节点选择器项,与相应的权重相关联
matchFields 按节点字段列出的节点选择器要求列表
matchExpressions 按节点标签列出的节点选择器要求列表(推荐)
key 键
values 值
operator 关系符 支持In, NotIn, Exists, DoesNotExist, Gt, Lt
weight 倾向权重,在范围1-100。
-------硬限制调度
满足规则则优先找满足规则的,没找到就挂起
创建:pod-nodeaffinity-required.yaml文件
内容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity-required
namespace: dev
spec:
containers: # 容器配置
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
affinity: # 亲和性配置
nodeAffinity: # node亲和性配置
requiredDuringSchedulingIgnoredDuringExecution: # Node节点必须满足指定的所有规则才可以,相当于硬规则,类似于定向调度
nodeSelectorTerms: # 节点选择列表
- matchExpressions:
- key: nodeenv # 匹配存在标签的key为nodeenv的节点,并且value是"xxx"或"yyy"的节点
operator: In
values:
- "xxx"
- "yyy"
挂起:
软限制调度:preferredDuringSchedulingIgnoredDuringExecution:
创建pod-nodeaffinity-preferred.yaml文件,内容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity-preferred
namespace: dev
spec:
containers: # 容器配置
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
affinity: # 亲和性配置
nodeAffinity: # node亲和性配置
preferredDuringSchedulingIgnoredDuringExecution: # 优先调度到满足指定的规则的Node,相当于软限制 (倾向)
- preference: # 一个节点选择器项,与相应的权重相关联
matchExpressions:
- key: nodeenv
operator: In
values:
- "xxx"
- "yyy"
weight: 1
软限制调度调度成功:
优先调度满足条件的,没有在给别的node
node亲和性只在调度是生效
6.3Pod亲和性
演示硬限制:
创建参照pod
创建pod-podaffinity-target.yaml内容如下:
apiVersion: v1
kind: Pod
metadata:
name: pod-podaffinity-target
namespace: dev
labels:
podenv: pro # 设置标签
spec:
containers: # 容器配置
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
nodeName: node02 # 将目标pod定向调度到node02
成功运行到node02里面
查看标签:
[root@master01 ~]# kubectl get pods pod-podaffinity-target -n dev -owide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
pod-podaffinity-target 1/1 Running 0 2m34s 10.244.140.89 node02 <none> <none> podenv=pro
自定义pod:硬限制:
- 创建Pod过程:
-
- 创建pod-podaffinity-requred.yaml文件,内容如下:
-
apiVersion: v1 kind: Pod metadata: name: pod-podaffinity-requred namespace: dev spec: containers: # 容器配置 - name: nginx image: nginx:1.17.1 imagePullPolicy: IfNotPresent ports: - name: nginx-port containerPort: 80 protocol: TCP affinity: # 亲和性配置 podAffinity: # Pod亲和性 requiredDuringSchedulingIgnoredDuringExecution: # 硬限制 - labelSelector: matchExpressions: # 该Pod必须和拥有标签podenv=xxx或者podenv=yyy的Pod在同一个Node上,显然没有这样的Pod - key: podenv operator: In values: - "xxx" - "yyy" topologyKey: kubernetes.io/hostname
运行yaml文件:
-
查看pod详细信息 ,没跑起来
尝试修改yam文件中标签匹配值:
vim pod-podaffinity-requred.yaml
再次查看结果是正常运行:Running,且放到了参照的node2节点,运行成功
kubectl create -f pod-podaffinity-requred.yaml
查看详细信息和标签
kubectl get pods pod-podaffinity-requred -n dev -o wide --show-labels
反亲和性:podAntiAffinity
- 反亲和性:创建pod-podantiaffinity-requred.yaml文件,内容如下:
-
apiVersion: v1 kind: Pod metadata: name: pod-podantiaffinity-requred namespace: dev spec: containers: # 容器配置 - name: nginx image: nginx:1.17.1 imagePullPolicy: IfNotPresent ports: - name: nginx-port containerPort: 80 protocol: TCP affinity: # 亲和性配置 podAntiAffinity: # Pod反亲和性 requiredDuringSchedulingIgnoredDuringExecution: # 硬限制 - labelSelector: matchExpressions: - key: podenv operator: In values: - "pro" topologyKey: kubernetes.io/hostname
创建并执行yaml文件:查看详细信息
-
因为设置反亲和性,不会和参照节点放到同一节点上
6.4污点和容忍
污点的三种状态:
设置污点:
kubectl taint node xxx key=value:effect
去除污点:
kubectl taint node xxx key:effect-
去除所有污点:
kubectl taint node xxx key-
- 接下来,演示污点效果:
- ① 准备节点k8s-node1(为了演示效果更加明显,暂时停止k8s-node2节点)。
- ② 为k8s-node1节点设置一个污点:
tag=xudaxian:PreferNoSchedule
,然后创建Pod1(Pod1可以)。 - ③ 修改k8s-node1节点的污点为:
tag=xudaxian:NoSchedule
,然后创建Pod2(Pod1可以正常运行,Pod2失败)。 - ④ 修改k8s-node1节点的污点为:
tag=xudaxian:NoExecute
,然后创建Pod3(Pod1、Pod2、Pod3失败)。
给node1设置污点:
kubectl taint node node02 tag=bobo:PreferNoSchedule
[root@master01 ~]# kubectl taint node node02 tag=bobo:PreferNoSchedule
node/node02 tainted
查看污点:
kubectl describe nodes node02
创建Pod1:
kubectl run pod1 --image=nginx:1.17.1 -n dev
查看pod
kubectl get pod pod1 -n dev -o wide
设置污点后,尽量不往污点去:所以不会去noed02
为node02取消污点(PreferNoSchedule),并设置污点(NoSchedule):
kubectl taint node node02 tag:PreferNoSchedule-
[root@master01 ~]# kubectl taint node node02 tag:PreferNoSchedule-
node/node02 untainted
master节点是默认有污点的:看一下
[root@master01 ~]# kubectl describe nodes master01
Name: master01
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=master01
kubernetes.io/os=linux
node-role.kubernetes.io/master=
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
projectcalico.org/IPv4Address: 172.26.144.85/20
projectcalico.org/IPv4IPIPTunnelAddr: 10.244.241.64
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Thu, 17 Mar 2022 00:34:06 +0800
Taints: node-role.kubernetes.io/master:NoSchedule
6.4.2容忍
Pod非要想到污点里去,在POD声明容忍:
容忍的详细配置:
kubectl explain pod.spec.tolerations
......
FIELDS:
key # 对应着要容忍的污点的键,空意味着匹配所有的键
value # 对应着要容忍的污点的值
operator # key-value的运算符,支持Equal和Exists(默认)
effect # 对应污点的effect,空意味着匹配所有影响
tolerationSeconds # 容忍时间, 当effect为NoExecute时生效,表示pod在Node上的停留时间
tolerations: # 容忍
- key: "tag" # 要容忍的污点的key
operator: Exists # 操作符
effect: NoExecute # 添加容忍的规则,这里必须和标记的污点规则相同
创建一个yaml文件,加入容忍:
运行yaml文件,并查看pods、
apiVersion: v1
kind: Pod
metadata:
name: pod-toleration
namespace: dev
spec:
containers: # 容器配置
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
tolerations: # 容忍
- key: "tag" # 要容忍的污点的key
operator: Equal # 操作符
value: "bobo" # 要容忍的污点的value
effect: NoExecute # 添加容忍的规则,这里必须和标记的污点规则相同
发现本来不然去node02的也让去了
[root@master01 ~]# kubectl get pods pod-toleration -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-toleration 1/1 Running 0 107s 10.244.140.91 node02 <none> <none>
7.Pod控制器
在kubernetes中,有很多类型的Pod控制器,每种都有自己的适合的场景,常见的有下面这些:
- ReplicationController:比较原始的Pod控制器,已经被废弃,由ReplicaSet替代。
- ReplicaSet:保证指定数量的Pod运行,并支持Pod数量变更,镜像版本变更。
- Deployment:通过控制ReplicaSet来控制Pod,并支持滚动升级、版本回退。
- Horizontal Pod Autoscaler:可以根据集群负载自动调整Pod的数量,实现削峰填谷。
- DaemonSet:在集群中的指定Node上都运行一个副本,一般用于守护进程类的任务。
- Job:它创建出来的Pod只要完成任务就立即退出,用于执行一次性任务。
- CronJob:它创建的Pod会周期性的执行,用于执行周期性的任务。
- StatefulSet:管理有状态的应用。
7.1RS
- ReplicaSet的资源清单文件:
apiVersion: apps/v1 # 版本号
kind: ReplicaSet # 类型
metadata: # 元数据
name: # rs名称
namespace: # 所属命名空间
labels: #标签
controller: rs
spec: # 详情描述
replicas: 3 # 副本数量
selector: # 选择器,通过它指定该控制器管理哪些po
matchLabels: # Labels匹配规则
app: nginx-pod
matchExpressions: # Expressions匹配规则
- {key: app, operator: In, values: [nginx-pod]}
template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
7.1.2创建ReplicaSet:
- 创建pc-replicaset.yaml文件,内容如下:
apiVersion: apps/v1 # 版本号
kind: ReplicaSet # 类型
metadata: # 元数据
name: pc-replicaset # rs名称
namespace: dev # 命名类型
spec: # 详细描述
replicas: 3 # 副本数量
selector: # 选择器,通过它指定该控制器可以管理哪些Pod
matchLabels: # Labels匹配规则
app: nginx-pod
template: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx # 容器名称
image: nginx:1.17.1 # 容器需要的镜像地址
ports:
- containerPort: 80 # 容器所监听的端口
运行yaml文件:
[root@master01 ~]# kubectl create -f pc-replicaset.yaml
replicaset.apps/pc-replicaset created
[root@master01 ~]# kubectl get rs pc-replicaset -n dev -o wide
查看RS
[root@master01 ~]# kubectl get rs pc-replicaset -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 3
查看pods:
7.1.3RS实现pods的扩缩容:
方法一:这方法用的少,有点麻烦
[root@master01 ~]# kubectl edit rs pc-replicaset -n dev
replicaset.apps/pc-replicaset edited
自己改数字。注意位置
查看结果:
[root@master01 ~]# kubectl get rs pc-replicaset -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 6 6 6 12m nginx nginx:1.17.1 app=nginx-pod
kubectl get pods -n dev
方法二:常用,简单方便:
scale命令
kubectl scale rs pc-replicaset --replicas=2 -n dev
查看:
[root@master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-replicaset-4dfdd 0/1 Terminating 0 4m8s
pc-replicaset-4xz4f 0/1 Terminating 0 4m8s
pc-replicaset-6sq87 1/1 Running 0 16m
pc-replicaset-7drw4 0/1 Terminating 0 16m
pc-replicaset-bm9v8 1/1 Running 0 16m
pc-replicaset-m5tkn 0/1 Terminating 0 4m8s
发现缩容成了2个:
7.1.4镜像升级:
set:
[root@master01 ~]# kubectl set image rs pc-replicaset nginx=nginx:1.17.2 -n dev
replicaset.apps/pc-replicaset image updated
查看升级成功:
[root@master01 ~]# kubectl get rs pc-replicaset -n dev -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
pc-replicaset 2 2 2 21m nginx nginx:1.17.2 app=nginx-pod
7.1.5删除RS
- 使用kubectl delete rs 命令会删除ReplicaSet和其管理的Pod。
-
# 在kubernetes删除ReplicaSet前,会将ReplicaSet的replicas调整为0,等到所有的Pod被删除后,再执行ReplicaSet对象的删除 kubectl delete rs pc-replicaset -n dev
常用方法:
使用yaml直接删除(推荐):
使用yaml直接删除(推荐):
kubectl delete -f pc-replicaset.yaml
8.Deployment
企业中一般用deployment,
- 支持ReplicaSet的所有功能。
- 支持发布的停止、继续。
- 支持版本滚动更新和版本回退。
8.1 创建Deployment
创建建pc-deployment.yaml文件,内容如下:
apiVersion: apps/v1 # 版本号
kind: Deployment # 类型
metadata: # 元数据
name: pc-deployment # deployment的名称
namespace: dev # 命名类型
spec: # 详细描述
replicas: 3 # 副本数量
selector: # 选择器,通过它指定该控制器可以管理哪些Pod
matchLabels: # Labels匹配规则
app: nginx-pod
template: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx # 容器名称
image: nginx:1.17.1 # 容器需要的镜像地址
ports:
- containerPort: 80 # 容器所监听的端口
创建:
[root@master01 ~]# kubectl create -f pc-deployment.yaml
deployment.apps/pc-deployment created
查看deployment:
[root@master01 ~]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
pc-deployment 3/3 3 3 77s nginx nginx:1.17.1 app=nginx-pod
查看pc-deployment对应的rs:
[root@master01 ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-7d7dd5499b 3 3 3 4m12s
pc-replicaset 2 2 2 173m
查看rs对应的POD:
[root@master01 ~]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-7d7dd5499b-8v25l 1/1 Running 0 4m44s
pc-deployment-7d7dd5499b-jx48r 1/1 Running 0 4m44s
pc-deployment-7d7dd5499b-thtkm 1/1 Running 0 4m44s
8.2Deployment的扩缩容:
8.2.1scale命令实现扩缩容:
kubectl scale deploy pc-deployment --replicas=5 -n dev
结果:扩容成功
[root@master01 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pc-deployment-7d7dd5499b-8v25l 1/1 Running 0 7m39s
pc-deployment-7d7dd5499b-fm9gj 1/1 Running 0 13s
pc-deployment-7d7dd5499b-jx48r 1/1 Running 0 7m39s
pc-deployment-7d7dd5499b-thtkm 1/1 Running 0 7m39s
pc-deployment-7d7dd5499b-wvp4t 1/1 Running 0 13s
8.2.2编辑形式实现扩缩容:
也是把replicas改成自己想要的数量就行
[root@master01 ~]# kubectl edit deploy pc-deployment -n dev
Edit cancelled, no changes made.
8.3镜像更新策略:
重建更新和滚动更新(默认25%更新):
strategy: 指定新的Pod替代旧的Pod的策略,支持两个属性
type: 指定策略类型,支持两种策略
Recreate:在创建出新的Pod之前会先杀掉所有已经存在的Pod
RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本的Pod
rollingUpdate:当type为RollingUpdate的时候生效,用于为rollingUpdate设置参数,支持两个属性:
maxUnavailable:用来指定在升级过程中不可用的Pod的最大数量,默认为25%。
maxSurge: 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。
8.3.1重建更新:
辑pc-deployment.yaml文件,在spec节点下添加更新策略:
apiVersion: apps/v1 # 版本号
kind: Deployment # 类型
metadata: # 元数据
name: pc-deployment # deployment的名称
namespace: dev # 命名类型
spec: # 详细描述
replicas: 3 # 副本数量
strategy: # 镜像更新策略
type: Recreate # Recreate:在创建出新的Pod之前会先杀掉所有已经存在的Pod
selector: # 选择器,通过它指定该控制器可以管理哪些Pod
matchLabels: # Labels匹配规则
app: nginx-pod
template: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx # 容器名称
image: nginx:1.17.3 # 容器需要的镜像地址
ports:
- containerPort: 80 # 容器所监听的端口
应用一下更新:
[root@master01 ~]# kubectl apply -f pc-deployment.yaml
deployment.apps/pc-deployment configured
监控容器状态:
kubectl get pods -n dev -w
或者用set images指定版本:另外一个窗口监控,效果差不多
[root@master01 ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.5 -n dev
deployment.apps/pc-deployment image updated
发现真是全关了,在重启:
状态是Termi是重启---penging挂起
8.3.2滚动更新:
修改yaml文件的值为滚动更新:
type:RollingUpdate
修改完记得用apply命令应用:
通过set images来更新nginx:
[root@master01 ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.7 -n dev
另外一个端口监控:
kubectl get pods -n dev -w
监控到是先启动一个新容器在停止:
8.3.3版本回退:
删除原来的配置重新创建:--record记录下整个更新过程
[root@master01 ~]# kubectl delete -f pc-deployment.yaml
deployment.apps "pc-deployment" deleted
[root@master01 ~]# kubectl create -f pc-deployment.yaml --record
deployment.apps/pc-deployment created
查看状态:应用成功
[root@master01 ~]# kubectl get deploy,rs,pod -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/pc-deployment 3/3 3 3 75s
NAME DESIRED CURRENT READY AGE
replicaset.apps/pc-deployment-56f77b8695 3 3 3 75s
replicaset.apps/pc-replicaset 2 2 2 3h45m
NAME READY STATUS RESTARTS AGE
pod/pc-deployment-56f77b8695-bfvt2 1/1 Running 0 75s
pod/pc-deployment-56f77b8695-lcm79 1/1 Running 0 75s
pod/pc-deployment-56f77b8695-zjr42 1/1 Running 0 75s
进行镜像更新,另两个个窗口监听一个监听rs一个监听pod:
主窗口进行镜像更新:
[root@master01 ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.8 -n dev
deployment.apps/pc-deployment image updated
查看监听端口:
pod监听;
kubectl get pod -n dev -w
rs监听:
kubectl get rs -n dev -w
版本更新成功
新的RS起来了,老的RS空间还在,目的是为了版本回退:
怎么退回去呢?
8.3.4版本回退:
# 版本升级相关功能
kubetl rollout 参数 deploy xx # 支持下面的选择
# status 显示当前升级的状态
# history 显示升级历史记录
# pause 暂停版本升级过程
# resume 继续已经暂停的版本升级过程
# restart 重启版本升级过程
# undo 回滚到上一级版本 (可以使用--to-revision回滚到指定的版本)
status状态:successfully
[root@master01 ~]# kubectl rollout status deploy pc-deployment -n dev
deployment "pc-deployment" successfully rolled out
查看升级历史history:加了--record才会有这个历史记录
1,2,3,4,是记录的版本号,以后回退就用他
[root@master01 ~]# kubectl rollout history deploy pc-deployment -n dev
deployment.apps/pc-deployment
REVISION CHANGE-CAUSE
1 kubectl create --filename=pc-deployment.yaml --record=true
2 kubectl create --filename=pc-deployment.yaml --record=true
3 kubectl create --filename=pc-deployment.yaml --record=true
4 kubectl create --filename=pc-deployment.yaml --record=true
正在升级状态演示:
[root@master01 ~]# kubectl rollout status deploy pc-deployment -n dev
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "pc-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "pc-deployment" successfully rolled out
undo回滚到上一版本:
或者回归到记录的版本:undo deployment pc-deployment --to-revision=1
[root@master01 ~]# kubectl rollout undo deployment pc-deployment --to-revision=1 -n dev
deployment.apps/pc-deployment rolled back
去另一个端口查看RS号版本,发现版本回退成功
通过history查看版本发现1消失了,因为现在1和最后一个版本一样:
[root@master01 ~]# kubectl rollout history deploy pc-deployment -n dev
deployment.apps/pc-deployment
REVISION CHANGE-CAUSE
2 kubectl create --filename=pc-deployment.yaml --record=true
3 kubectl create --filename=pc-deployment.yaml --record=true
4 kubectl create --filename=pc-deployment.yaml --record=true
5 kubectl create --filename=pc-deployment.yaml --record=true
6 kubectl create --filename=pc-deployment.yaml --record=true
8.3.5金丝雀发布
kubectl set image deployment pc-deployment nginx=nginx:1.17.4 -n dev && kubectl rollout pause deployment pc-deployment -n dev
[root@master01 ~]# kubectl set image deployment pc-deployment nginx=nginx:1.19 -n dev && kubectl rollout pause deployment pc-deployment -n dev
deployment.apps/pc-deployment image updated
deployment.apps/pc-deployment paused
查看状态:
老的还没死,新的已经产生,可以用来测试
[root@master01 ~]# kubectl get rs -n dev
NAME DESIRED CURRENT READY AGE
pc-deployment-56f77b8695 3 3 3 14s
pc-deployment-75fc5ffd55 1 1 1 10s
pc-replicaset 2 2 2 5h40m
查看状态:
[root@master01 ~]# kubectl rollout status deploy pc-deployment -n dev
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
继续:
[root@master01 ~]# kubectl rollout resume deploy pc-deployment -n dev
deployment.apps/pc-deployment resumed
[root@master01 ~]# kubectl rollout status deploy pc-deployment -n dev
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment spec update to be observed...
Waiting for deployment spec update to be observed...
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "pc-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "pc-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "pc-deployment" successfully rolled out
查看更新后的状态:
9.Horizontal Pod Autoscaler(HPA)自动化扩缩容:
9.1 安装metrics-server(v0.3.6)
●metrics-server可以用来收集集群中的资源使用情况:
wget https://github.com/kubernetes-sigs/metrics-server/archive/v0.3.6.tar.gz
解压:
tar -zxvf v0.3.6.tar.gz
cd metrics-server-0.3.6/deploy/1.8+/
编辑文件:
vim metrics-server-deployment.yaml
按图中添加下面选项
hostNetwork: true
image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
args:
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
[root@master01 1.8+]# vim metrics-server-deployment.yaml
[root@master01 1.8+]# kubectl apply -f ./
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
serviceaccount/metrics-server created
deployment.apps/metrics-server created
service/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
- 查看metrics-server生成的Pod:
- 查看资源使用情况:
-
kubectl top node
[root@master01 ~]# kubectl top node NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% master01 125m 6% 1416Mi 80% node02 65m 3% 990Mi 56% node03 100m 5% 1151Mi 65% node04 71m 3% 1096Mi 62%
[root@master01 ~]# kubectl top pod -n kube-system NAME CPU(cores) MEMORY(bytes) calico-kube-controllers-5b57744b7c-br82t 2m 40Mi calico-node-8gqrn 27m 218Mi calico-node-rg5zs 21m 196Mi calico-node-rwm9t 16m 217Mi calico-node-xkckz 22m 225Mi coredns-7ff77c879f-2fwxz 2m 20Mi coredns-7ff77c879f-zv58n 2m 14Mi etcd-master01 9m 68Mi kube-apiserver-master01 19m 404Mi kube-controller-manager-master01 6m 74Mi kube-proxy-c2xmv 1m 36Mi kube-proxy-c4xpl 1m 35Mi kube-proxy-m6bwz 1m 23Mi kube-proxy-rkqsq 1m 24Mi kube-scheduler-master01 2m 35Mi metrics-server-5f55b696bd-564js 1m 11Mi
-
- 创建nginx.yaml文件,内容如下:
apiVersion: apps/v1 # 版本号
kind: Deployment # 类型
metadata: # 元数据
name: nginx # deployment的名称
namespace: dev # 命名类型
spec: # 详细描述
selector: # 选择器,通过它指定该控制器可以管理哪些Pod
matchLabels: # Labels匹配规则
app: nginx-pod
template: # 模块 当副本数据不足的时候,会根据下面的模板创建Pod副本
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx # 容器名称
image: nginx:1.17.1 # 容器需要的镜像地址
ports:
- containerPort: 80 # 容器所监听的端口
resources: # 资源限制
requests:
cpu: "100m" # 100m表示100millicpu,即0.1个CPU
运行yaml文件并查看pod和控制器:
[root@master01 ~]# vim nginx.yaml
[root@master01 ~]# kubectl create -f nginx.yaml
deployment.apps/nginx created
[root@master01 ~]# kubectl get pod,deploy -n dev
NAME READY STATUS RESTARTS AGE
pod/nginx-587f44948f-lrj7n 1/1 Running 0 9s
pod/pc-deployment-75fc5ffd55-dqg7j 1/1 Running 0 35m
pod/pc-deployment-75fc5ffd55-qx4f6 1/1 Running 0 35m
pod/pc-deployment-75fc5ffd55-wn2f6 1/1 Running 0 40m
pod/pc-replicaset-6sq87 1/1 Running 0 6h20m
pod/pc-replicaset-bm9v8 1/1 Running 0 6h20m
pod/pod-initcontainer 0/1 Init:0/2 1 20h
pod/pod-liveness-exec 0/1 CrashLoopBackOff 210 19h
pod/pod-nodeaffinity-preferred 1/1 Running 0 8h
pod/pod-nodeaffinity-required 0/1 Pending 0 8h
pod/pod-nodeselector 0/1 Pending 0 8h
pod/pod-podantiaffinity-requred 1/1 Running 0 7h24m
pod/pod-ports 1/1 Running 1 20h
pod/pod-toleration 1/1 Running 0 6h46m
pod/pod1 1/1 Running 0 7h6m
pod/pod2 1/1 Running 0 7h1m
pod/pod3 1/1 Running 0 6h59m
创建service:
暴露80端口和外网端口:
[root@master01 ~]# kubectl expose deployment nginx --name=nginx --type=NodePort --port=80 --target-port=80 -n dev
service/nginx exposed
查看service:
[root@master01 ~]# kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx NodePort 10.100.15.117 <none> 80:32679/TCP 48s
尝试访问:外网内网都可以访问就没问题
10.部署HPA
- 创建pc-hpa.yaml文件,内容如下:
- 注意最大最小pod的设置,
- CPU的使用指标
-
apiVersion: autoscaling/v1 # 版本号 kind: HorizontalPodAutoscaler # 类型 metadata: # 元数据 name: pc-hpa # deployment的名称 namespace: dev # 命名类型 spec: minReplicas: 1 # 最小Pod数量 maxReplicas: 10 # 最大Pod数量 targetCPUUtilizationPercentage: 3 # CPU使用率指标 scaleTargetRef: # 指定要控制的Nginx的信息 apiVersion: apps/v1 kind: Deployment name: nginx
运行文件并查看hpa pod
-
[root@master01 ~]# vim pc-hpa.yaml [root@master01 ~]# kubectl create -f pc-hpa.yaml horizontalpodautoscaler.autoscaling/pc-hpa created [root@master01 ~]# kubectl get hpa -n dev NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE pc-hpa Deployment/nginx <unknown>/3% 1 10 0 9s
10.2 压测测试----自己写个python脚本或者Jmeter来压测:
监控pod--gha和deployment的变化:
kubectl get hpa -n dev -w
kubectl get deployment -n dev -w
对服务器进行压测:
11.DS---DaemonSet
指定每个 node 一个运行一个
比较简单,需要在来看
12.Job
每个任务仅运行一次就结束,
成功执行时记录pod数量:
达到指定数量时,完成工作-------相当于有效数量
设置总数,可以并行,可以设置最大时间期限:
关于模板中的重启策略的说明:
- 如果设置为OnFailure,则Job会在Pod出现故障的时候重启容器,而不是创建Pod,failed次数不变。
- 如果设置为Never,则Job会在Pod出现故障的时候创建新的Pod,并且故障Pod不会消失,也不会重启,failed次数+1。
- 如果指定为Always的话,就意味着一直重启,意味着Pod任务会重复执行,这和Job的定义冲突,所以不能设置为Always。
13.CronJob
可以定时间执行,可以在特定时间点反复执行,可以设置是否并发执行:
资源清单;
apiVersion: batch/v1beta1 # 版本号
kind: CronJob # 类型
metadata: # 元数据
name: # 名称
namespace: #命名空间
labels:
controller: cronjob
spec: # 详情描述
schedule: # cron格式的作业调度运行时间点,用于控制任务任务时间执行
concurrencyPolicy: # 并发执行策略
failedJobsHistoryLimit: # 为失败的任务执行保留的历史记录数,默认为1
successfulJobsHistoryLimit: # 为成功的任务执行保留的历史记录数,默认为3
jobTemplate: # job控制器模板,用于为cronjob控制器生成job对象,下面其实就是job的定义
metadata: {}
spec:
completions: 1 # 指定Job需要成功运行Pod的总次数,默认为1
parallelism: 1 # 指定Job在任一时刻应该并发运行Pod的数量,默认为1
activeDeadlineSeconds: 30 # 指定Job可以运行的时间期限,超过时间还没结束,系统将会尝试进行终止
backoffLimit: 6 # 指定Job失败后进行重试的次数,默认为6
template: # 模板,当副本数量不足时,会根据下面的模板创建Pod模板
spec:
restartPolicy: Never # 重启策略只能设置为Never或OnFailure
containers:
- name: counter
image: busybox:1.30
command: [ "/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 20;done" ]
概述解释:
schedule:cron表达式,用于指定任务的执行时间。
- */1 * * * *:
- 分钟 小时 日 月份 星期。
- 分钟的值从0到59。
- 小时的值从0到23。
- 日的值从1到31。
- 月的值从1到12。
- 星期的值从0到6,0表示星期日。
- 多个时间可以用逗号隔开,范围可以用连字符给出:* 可以作为通配符,/表示每...
concurrencyPolicy:并发执行策略
- Allow:运行Job并发运行(默认)。
- Forbid:禁止并发运行,如果上一次运行尚未完成,则跳过下一次运行。
- Replace:替换,取消当前正在运行的作业并使用新作业替换它。
创建cronjob:
pc-cronjob.yaml
apiVersion: batch/v1beta1 # 版本号
kind: CronJob # 类型
metadata: # 元数据
name: pc-cronjob # 名称
namespace: dev #命名空间
spec: # 详情描述
schedule: "*/1 * * * * " # cron格式的作业调度运行时间点,用于控制任务任务时间执行
jobTemplate: # job控制器模板,用于为cronjob控制器生成job对象,下面其实就是job的定义
metadata: {}
spec:
template: # 模板,当副本数量不足时,会根据下面的模板创建Pod模板
spec:
restartPolicy: Never # 重启策略只能设置为Never或OnFailure
containers:
- name: counter
image: busybox:1.30
command: [ "/bin/sh","-c","for i in 9 8 7 6 5 4 3 2 1;do echo $i;sleep 2;done" ]
kubectl create -f pc-cronjob.yaml
监控job:
kubectl get cronjob -n dev -w
监控pod:
kubectl get pod -n dev -w
14.Service--ipvs
ipvs效率最高,首先得装这个模块,我们前面已经装了,
ipvsadm里面没什么内容代表没生效:
[root@master01 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
让它生效:
1.编辑把mode改成ipvs
[root@master01 ~]# kubectl edit cm kube-proxy -n kube-system
configmap/kube-proxy edited
/mode搜索mode
2.删除code重新创建:----生产环境别这么做
[root@master01 ~]# kubectl delete pod -l k8s-app=kube-proxy -n kube-system
pod "kube-proxy-c2xmv" deleted
pod "kube-proxy-c4xpl" deleted
pod "kube-proxy-m6bwz" deleted
pod "kube-proxy-rkqsq" deleted
3.使用ipvsadm -Ln命令再次查看
会通过rr的轮循转发--------通过标签选择器
[root@master01 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 127.0.0.1:30000 rr
-> 10.244.186.216:8443 Masq 1 0 0
TCP 172.17.0.1:30000 rr
-> 10.244.186.216:8443 Masq 1 0 0
TCP 172.17.0.1:32679 rr
-> 10.244.186.203:80 Masq 1 0 0
-> 10.244.186.209:80 Masq 1 0 0
-> 10.244.186.212:80 Masq 1 0 0
-> 10.244.186.213:80 Masq 1 0 0
-> 10.244.186.221:80 Masq 1 0 0
-> 10.244.186.223:80 Masq 1 0 0
TCP 172.26.144.85:30000 rr
-> 10.244.186.216:8443 Masq 1 0 0
TCP 172.26.144.85:31993 rr
-> 10.244.248.219:80 Masq 1 0 0
TCP 172.26.144.85:32679 rr
-> 10.244.186.203:80 Masq 1 0 0
-> 10.244.186.209:80 Masq 1 0 0
-> 10.244.186.212:80 Masq 1 0 0
-> 10.244.186.213:80 Masq 1 0 0
-> 10.244.186.221:80 Masq 1 0 0
-> 10.244.186.223:80 Masq 1 0 0
TCP 10.96.0.1:443 rr
-> 172.26.144.85:6443 Masq 1 0 0
TCP 10.96.0.10:53 rr
-> 10.244.241.77:53 Masq 1 0 0
-> 10.244.241.78:53 Masq 1 0 0
TCP 10.96.0.10:9153 rr
15-Service
资源清单:
apiVersion: v1 # 版本
kind: Service # 类型
metadata: # 元数据
name: # 资源名称
namespace: # 命名空间
spec:
selector: # 标签选择器,用于确定当前Service代理那些Pod
app: nginx
type: NodePort # Service的类型,指定Service的访问方式
clusterIP: # 虚拟服务的IP地址
sessionAffinity: # session亲和性,支持ClientIP、None两个选项,默认值为None
ports: # 端口信息
- port: 8080 # Service端口
protocol: TCP # 协议
targetPort : # Pod端口
nodePort: # 主机端口
spec.type的说明:
- ClusterIP:默认值,它是kubernetes系统自动分配的虚拟IP,只能在集群内部访问。
- NodePort:将Service通过指定的Node上的端口暴露给外部,通过此方法,就可以在集群外部访问服务。
- LoadBalancer:使用外接负载均衡器完成到服务的负载分发,注意此模式需要外部云环境的支持。
- ExternalName:把集群外部的服务引入集群内部,直接使用。
15.1Service实验环境准备
1)创建deployment.yaml文件,内容为:
apiVersion: apps/v1
kind: Deployment
metadata:
name: pc-deployment
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
2运行yaml文件:
kubectl create -f deployment.yaml
3查看pods的详细信息:
4内网测试是否可以访问:
[root@master01 ~]# curl 10.244.248.225:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@master01 ~]#
5修改nginx主页:
首先进入pod里面:
[root@master01 ~]# kubectl exec -it pc-deployment-7d7dd5499b-s2xcv -c nginx -n dev /bin/sh
进去以后输入:改变主页
# echo "bobobobobobobobobobobo" > /usr/share/nginx/html/index.html
三个都改成不同的内容:
[root@master01 ~]# curl 10.244.248.226:80
lelelelleleleleel
15.2ClusterIP类型的Service
创建文件service-clusterip.yaml,内容如下:
apiVersion: v1
kind: Service
metadata:
name: service-clusterip
namespace: dev
spec:
selector:
app: nginx-pod
clusterIP: 10.97.97.97 # service的IP地址,如果不写,默认会生成一个
type: ClusterIP
ports:
- port: 80 # Service的端口
targetPort: 80 # Pod的端口
[root@master01 ~]# vim service-clusterip.yaml
[root@master01 ~]# kubectl create -f service-clusterip.yaml
service/service-clusterip created
[root@master01 ~]#
查看service:
[root@master01 ~]# kubectl get svc service-clusterip -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service-clusterip ClusterIP 10.97.97.97 <none> 80/TCP 102s app=nginx-pod
详细信息:
Endpoints有三个ip+端口-------建立service和pod之间的关联
Endpoints是实际的端口集合
[root@master01 ~]# kubectl describe svc service-clusterip -n dev
Name: service-clusterip
Namespace: dev
Labels: <none>
Annotations: <none>
Selector: app=nginx-pod
Type: ClusterIP
IP: 10.97.97.97
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.186.213:80,10.244.186.221:80,10.244.186.223:80 + 3 more...
Session Affinity: None
Events: <none>
service的映射规则:实际上是kube-proxy在起作用
当请求访问端口时,轮询策略转到下面的的地址-----各个pod
脚本循环发请求,测试轮询策略:
while true;do curl 10.97.97.97:80; sleep 5; done;
也可以设置,来每次分配到同一个pod
15.3HeadLiness类型:
无头服务
创建service-headliness.yaml
apiVersion: v1
kind: Service
metadata:
name: service-headliness
namespace: dev
spec:
selector:
app: nginx-pod
clusterIP: None # 将clusterIP设置为None,即可创建headliness Service
type: ClusterIP
ports:
- port: 80 # Service的端口
targetPort: 80 # Pod的端口
查看service:
kubectl get svc service-headliness -n dev -o wide
查看service详情:
kubectl describe svc service-headliness -n dev
关联还在---------这是想访问只能通过域名
15.3.4查看域名解析情况
kubectl get pod -n dev
- 进入Pod中,执行cat /etc/resolv.conf命令:
kubectl exec -it pc-deployment-7d7dd5499b-rgwkq -n dev /bin/bash
root@pc-deployment-7d7dd5499b-rgwkq:/# cat /etc/resolv.conf
nameserver 10.96.0.10
search dev.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
root@pc-deployment-7d7dd5499b-rgwkq:/#
通过service的域名访问:
dig @10.96.0.10 service-headliness.dev.svc.cluster.local
16.NodePort类型的service
一般在yaml文件中就创建好暴露端口:
创建yaml文件,内容如下:
apiVersion: v1
kind: Service
metadata:
name: service-nodeport
namespace: dev
spec:
selector:
app: nginx-pod
type: NodePort # Service类型为NodePort
ports:
- port: 80 # Service的端口
targetPort: 80 # Pod的端口
nodePort: 30002 # 指定绑定的node的端口(默认取值范围是30000~32767),如果不指定,会默认分配
外网成功访问
16.Ingress
16.1Ingress环境准备:
1)创建文件夹并进入
mkdir ingress-controller
cd ingress-controller
2)获取ingress-nginx,本次使用的是0.30版本,
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
3)创建Ingress-nginx:
kubectl apply -f ./
4)查看Ingress-nginx
kubectl get pod -n ingress-nginx
[root@master01 ingress-controller]# kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-5bb8fb4bb6-6k9gk 0/1 ContainerCreating 0 7s
5)查看service:
[root@master01 ingress-controller]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.104.11.17 <none> 80:31048/TCP,443:30868/TCP 2m22s
16.2准备Service和Pod
1)创建tomcat-nginx.yaml文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: tomcat-pod
template:
metadata:
labels:
app: tomcat-pod
spec:
containers:
- name: tomcat
image: tomcat:8.5-jre10-slim
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: dev
spec:
selector:
app: nginx-pod
clusterIP: None
type: ClusterIP
ports:
- port: 80
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
namespace: dev
spec:
selector:
app: tomcat-pod
clusterIP: None
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
2)创建Service和Pod:
kubectl create -f tomcat-nginx.yaml
3)查看service和pod
kubectl get svc,pod -n dev
16.3Http代理(还没整理好)
1)创建ingress-http.yaml文件,内容如下:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-http
namespace: dev
spec:
rules:
- host: nginx.xudaxian.com
http:
paths:
- path: /
backend:
serviceName: nginx-service
servicePort: 80
- host: tomcat.xudaxian.com
http:
paths:
- path: /
backend:
serviceName: tomcat-service
servicePort: 8080
2)创建和查看:
[root@master01 ingress-controller]# vim ingress-http.yaml
[root@master01 ingress-controller]# kubectl create -f ingress-http.yaml
ingress.extensions/ingress-http created
[root@master01 ingress-controller]# kubectl get ingress ingress-http -n dev
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-http <none> nginx.xudaxian.com,tomcat.xudaxian.com 80 8s
[root@master01 ingress-controller]#
查看详情:
kubectl describe ingress ingress-http -n dev
3)修改host文件为了做测试:
cd /etc
vim hosts
4)查看ingress-nginx暴露的端口号:
[root@master01 etc]# kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.104.11.17 <none> 80:31048/TCP,443:30868/TCP 30m
16.4Https代理
生成证书:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=xudaxian.com"
创建密钥:
kubectl create secret tls tls-secret --key tls.key --cert tls.crt
创建ingress-https.yaml文件,内容如下:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-https
namespace: dev
spec:
tls:
- hosts:
- nginx.xudaxian.com
- tomcat.xudaxian.com
secretName: tls-secret # 指定秘钥
rules:
- host: nginx.xudaxian.com
http:
paths:
- path: /
backend:
serviceName: nginx-service
servicePort: 80
- host: tomcat.xudaxian.com
http:
paths:
- path: /
backend:
serviceName: tomcat-service
servicePort: 8080
运行:
kubectl create -f ingress-https.yaml
查看:
kubectl get ingress ingress-https -n dev
查看详情:
kubectl describe ingress ingress-https -n dev
访问https:
https://114.55.92.89:30868/
17.数据存储
Volume的生命周期不和Pod中的单个容器的生命周期有关,当容器终止或者重启的时候,Volume中的数据也不会丢失
- kubernetes的Volume支持多种类型,比较常见的有下面的几个:
-
- 简单存储:EmptyDir、HostPath、NFS。
-
- 高级存储:PV、PVC。
-
- 配置存储:ConfigMap、Secret。
17.1EmptyDir
EmptyDir不能做持久化,生命周期和pod一样,
作用是作为临时存储空间,同一个Pod的多个容器之间共享数据
实验;
- 在一个Pod中准备两个容器nginx和busybox,然后声明一个volume分别挂载到两个容器的目录中,然后nginx容器负责向volume中写日志,busybox中通过命令将日志内容读到控制台。
1)创建volume-emptydir.yaml文件
apiVersion: v1
kind: Pod
metadata:
name: volume-emptydir
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts: # 将logs-volume挂载到nginx容器中对应的目录,该目录为/var/log/nginx
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:1.30
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","tail -f /logs/access.log"] # 初始命令,动态读取指定文件
volumeMounts: # 将logs-volume挂载到busybox容器中的对应目录,该目录为/logs
- name: logs-volume
mountPath: /logs
volumes: # 声明volume,name为logs-volume,类型为emptyDir
- name: logs-volume
emptyDir: {}
创建和查看:
kubectl create -f volume-emptydir.yaml
kubectl get pod volume-emptydir -n dev -o wide
访问容器中的nginx:
curl 10.244.248.233
查看指定容器的标准输出:
[root@master01 ~]# kubectl logs -f volume-emptydir -n dev -c busybox
10.244.241.64 - - [20/Mar/2022:03:35:55 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.61.1" "-"
10.244.241.64 - - [20/Mar/2022:03:38:02 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.61.1" "-"
不停的访问nginx就会产生日志:
17.2 HostPath
- HostPath就是将Node主机中的一个实际目录挂载到Pod中,以供容器使用,这样的设计就可以保证Pod销毁了,但是数据依旧可以保存在Node主机上。
创建volume-hostpath.yaml文件,内容如下:
apiVersion: v1
kind: Pod
metadata:
name: volume-hostpath
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts: # 将logs-volume挂载到nginx容器中对应的目录,该目录为/var/log/nginx
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:1.30
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","tail -f /logs/access.log"] # 初始命令,动态读取指定文件
volumeMounts: # 将logs-volume挂载到busybox容器中的对应目录,该目录为/logs
- name: logs-volume
mountPath: /logs
volumes: # 声明volume,name为logs-volume,类型为hostPath
- name: logs-volume
hostPath:
path: /root/logs
type: DirectoryOrCreate # 目录存在就使用,不存在就先创建再使用
type的值的说明:
- DirectoryOrCreate:目录存在就使用,不存在就先创建后使用。
- Directory:目录必须存在。
- FileOrCreate:文件存在就使用,不存在就先创建后使用。
- File:文件必须存在。
- Socket:unix套接字必须存在。
- CharDevice:字符设备必须存在。
- BlockDevice:块设备必须存在。
查看详细信息:
[root@master01 ~]# kubectl get pods volume-hostpath -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
volume-hostpath 2/2 Running 0 71s 10.244.186.224 node03 <none
发现已经到了node03节点上:
进入node03节点查看文件是否产生:
发现两个文件已经产生,挂载成功
在node03监听access.log,在master访问连接查看是否生成日志:
发现成功生成日志
删除pod,,文件依旧存在,不会被删除
17.3基本存储NFS
HostPath的问题在于如果挂载的NODE挂了,就再也挂载不了了,当然pod会自动转移到别的节点
此时需要准备单独的网络存储系统,比较常用的是NFS和CIFS。
- NFS是一个网络文件存储系统,可以搭建一台NFS服务器,然后将Pod中的存储直接连接到NFS系统上,这样,无论Pod在节点上怎么转移,只要Node和NFS的对接没有问题,数据就可以成功访问。
17.3.2 搭建NFS服务器
- 首先需要准备NFS服务器,这里为了简单,直接在Master节点做NFS服务器。
- 在Master节点上安装NFS服务器:
yum install -y nfs-utils rpcbind
创建目录:
mkdir -pv /root/data/nfs
共享目录以读写权限暴露给172.26.144.0/24
网段中的所有主机:-----这里写自己的内网
修改一下:
vim /etc/exports
加入这入行:
/root/data/nfs 172.26.144.0/24(rw,no_root_squash)
修改权限:
chmod 777 -R /root/data/nf
加载配置:
exportfs -r
启动nfs服务:
systemctl start rpcbind
设置开机自启:
systemctl enable rpcbind
启动nfs服务:
systemctl start nfs
systemctl enable nfs
如果有问题:
ubuntu 10.0开启配置nfs 服务service nfs start时出现:
Failed to start nfs.service: Unit nfs.service not found.
原因是ubuntu 10.0以上的版本取消了service nfs start。
改成了sudo service nfs-server start 。这样就完成启动了。
在执行sudo service nfs-server status就可以看到执行下面的
[root@master01 init.d]# sudo service nfs-server start
Redirecting to /bin/systemctl start nfs-server.service
[root@master01 init.d]# sudo service nfs-server status
Redirecting to /bin/systemctl status nfs-server.service
● nfs-server.service - NFS server and services
Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled; vendor preset: e>
Drop-In: /run/systemd/generator/nfs-server.service.d
└─order-with-mounts.conf
Active: active (exited) since Sun 2022-03-20 12:09:33 CST; 18min ago
Main PID: 1158035 (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 11711)
Memory: 0B
CGroup: /system.slice/nfs-server.service
Mar 20 12:09:32 master01 systemd[1]: nfs-server.service: Succeeded.
Mar 20 12:09:32 master01 systemd[1]: Stopped NFS server and services.
Mar 20 12:09:32 master01 systemd[1]: Starting NFS server and services...
Mar 20 12:09:33 master01 systemd[1]: Started NFS server and services.
lines 1-14/14 (END)
在Master节点测试是否挂载成功:----内网地址
showmount -e 172.26.144.85
挂载成功:
[root@master01 init.d]# showmount -e 172.26.144.85
Export list for 172.26.144.85:
/root/data/nfs 172.26.144.0/24
node节点安装NFS服务器:
在Node节点上都安装NFS服务器,目的是为了Node节点可以驱动NFS设备,而不是要启动服务器
yum -y install nfs-utils
在node节点查看是都挂载成功:
showmount -e 172.26.144.85
高可用备份::
- 高可用备份方式,在所有节点执行如下的命令:---改成自己的内网
mount -t nfs 172.26.144.85:/root/data/nfs /mnt
创建NFS存储卷:
1)创建volume-nfs.yaml文件:
apiVersion: v1
kind: Pod
metadata:
name: volume-nfs
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.17.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts: # 将logs-volume挂载到nginx容器中对应的目录,该目录为/var/log/nginx
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:1.30
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","tail -f /logs/access.log"] # 初始命令,动态读取指定文件
volumeMounts: # 将logs-volume挂载到busybox容器中的对应目录,该目录为/logs
- name: logs-volume
mountPath: /logs
volumes: # 声明volume
- name: logs-volume
nfs:
server: 172.26.144.85 # NFS服务器地址
path: /root/data/nfs # 共享文件路径
2)运行并查看详细信息:发现已经部署在node04
3)在master节点进入自己设置的目录查看 :
cd /root/data/nfs
ls
tail -f access.log
在任意节点访问,发现已经生成自己的log
18.存储高级存储
nfs要求用户会搭建NFS系统,并且会在yaml配置nfs
- PV(Persistent Volume)是持久化卷的意思,是对底层的共享存储的一种抽象。一般情况下PV由kubernetes管理员进行创建和配置,它和底层具体的共享存储技术有关,并通过插件完成和共享存储的对接。
- PVC(Persistent Volume Claim)是持久化卷声明的意思,是用户对于存储需求的一种声明。换言之,PVC其实就是用户向kubernetes系统发出的一种资源需求申请。
PV是管理员准备的接口
PVC是用户发起的申请
分工细化,专业化:
- 使用了PV和PVC之后,工作可以得到进一步的提升:
-
- 存储:存储工程师维护。
-
- PV:kubernetes管理员维护。
-
- PVC:kubernetes用户维护。
18.2PV
PV是集群级别的资源>namspace
1)PV的资源清单文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
nfs: # 存储类型,和底层正则的存储对应
path:
server:
capacity: # 存储能力,目前只支持存储空间的设置
storage: 2Gi
accessModes: # 访问模式
-
storageClassName: # 存储类别
persistentVolumeReclaimPolicy: # 回收策略
pv的关键配置参数说明:
- 存储类型:底层实际存储的类型,kubernetes支持多种存储类型,每种存储类型的配置有所不同。
- 存储能力(capacity):目前只支持存储空间的设置(storage=1Gi),不过未来可能会加入IOPS、吞吐量等指标的配置。
- 访问模式(accessModes):
- 用来描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
- ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载。
- ReadOnlyMany(ROX):只读权限,可以被多个节点挂载。
- ReadWriteMany(RWX):读写权限,可以被多个节点挂载。
- 需要注意的是,底层不同的存储类型可能支持的访问模式不同。
- 回收策略( persistentVolumeReclaimPolicy):
- 当PV不再被使用之后,对其的处理方式,目前支持三种策略:
- Retain(保留):保留数据,需要管理员手动清理数据。
- Recycle(回收):清除PV中的数据,效果相当于
rm -rf /volume/*
。
- Delete(删除):和PV相连的后端存储完成volume的删除操作,常见于云服务器厂商的存储服务。
- 需要注意的是,底层不同的存储类型可能支持的回收策略不同。
- 存储类别(storageClassName):PV可以通过storageClassName参数指定一个存储类别。
- 具有特定类型的PV只能和请求了该类别的PVC进行绑定。
- 未设定类别的PV只能和不请求任何类别的PVC进行绑定。
- 状态(status):一个PV的生命周期,可能会处于4种不同的阶段。
- Available(可用):表示可用状态,还未被任何PVC绑定。
- Bound(已绑定):表示PV已经被PVC绑定。
- Released(已释放):表示PVC被删除,但是资源还没有被集群重新释放。
- Failed(失败):表示该PV的自动回收失败。
18.2.2实验准备
使用nfs做存储来演示PV的使用,创建三个PV,对应NFS的三个暴露路径:
ubuntu 配置nfs 出现Failed to start nfs.service: Unit nfs.service not found_暖暖的纠结的博客-CSDN博客
1)在master节点上准备三个目录
sudo service nfs-server start
mkdir -pv /root/data/{pv1,pv2,pv3。pv4}
chmod 777 -R /root/data
vim /etc/exports
/root/data/pv1 172.26.144..0/24(rw,no_root_squash)
/root/data/pv2 172.26.144..0/24(rw,no_root_squash)
/root/data/pv3 172.26.144..0/24(rw,no_root_squash)
/root/data/pv4 172.26.144..0/24(rw,no_root_squash)
2)创建pv.yaml文件:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
nfs: # 存储类型吗,和底层正则的存储对应
path: /root/data/pv1
server: 192.168.18.100
capacity: # 存储能力,目前只支持存储空间的设置
storage: 1Gi
accessModes: # 访问模式
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain # 回收策略
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
nfs: # 存储类型吗,和底层正则的存储对应
path: /root/data/pv2
server:172.26.144.85
capacity: # 存储能力,目前只支持存储空间的设置
storage: 2Gi
accessModes: # 访问模式
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain # 回收策略
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv3
spec:
nfs: # 存储类型吗,和底层正则的存储对应
path: /root/data/pv3
server: 192.168.18.100
capacity: # 存储能力,目前只支持存储空间的设置
storage: 3Gi
accessModes: # 访问模式
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain # 回收策略
3)创建PV
kubectl create -f pv.yaml
4)查看pv
kubectl get pv -o wide
[root@master01 ~]# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
pv1 1Gi RWX Retain Available 8m20s Filesystem
pv2 2Gi RWX Retain Available 8m20s Filesystem
pv3 3Gi RWX Retain Available 8m20s Filesystem
18.3PVC
PVC是资源的申请,用来声明对存储空间、访问模式、存储类别需求信息,下面是PVC的资源清单文件:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc
namespace: dev
spec:
accessModes: # 访客模式
-
selector: # 采用标签对PV选择
storageClassName: # 存储类别
resources: # 请求空间
requests:
storage: 5Gi
-
18.3.2创建pvc
- 创建pvc.yaml文件,内容如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
namespace: dev
spec:
accessModes: # 访客模式
- ReadWriteMany
resources: # 请求空间
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc2
namespace: dev
spec:
accessModes: # 访客模式
- ReadWriteMany
resources: # 请求空间
requests:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc3
namespace: dev
spec:
accessModes: # 访客模式
- ReadWriteMany
resources: # 请求空间
requests:
storage: 5Gi
创建pvc
kubectl create -f pvc.yaml
查看pvc:
[root@master01 ~]# kubectl get pvc -n dev -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
pvc1 Bound pv1 1Gi RWX 3m38s Filesystem
pvc2 Bound pv2 2Gi RWX 3m38s Filesystem
pvc3 Pending 3m38s Filesystem
查看pv:
18.2.3创建pod使用pvc
用户做的:
配置:
apiVersion: v1
kind: Pod
metadata:
name: pod1
namespace: dev
spec:
containers:
- name: busybox
image: busybox:1.30
command: ["/bin/sh","-c","while true;do echo pod1 >> /root/out.txt; sleep 10; done;"]
volumeMounts:
- name: volume
mountPath: /root/
volumes:
- name: volume
persistentVolumeClaim:
claimName: pvc1
readOnly: false
---
apiVersion: v1
kind: Pod
metadata:
name: pod2
namespace: dev
spec:
containers:
- name: busybox
image: busybox:1.30
command: ["/bin/sh","-c","while true;do echo pod1 >> /root/out.txt; sleep 10; done;"]
volumeMounts:
- name: volume
mountPath: /root/
volumes:
- name: volume
persistentVolumeClaim:
claimName: pvc2
readOnly: false
创建pod使用pvc:
kubectl create -f pvc-pod.yaml
查看pod
kubectl get pod -n dev -o wide
查看pvc:
kubectl get pvc -n dev -o wide
19.搭建搭建DashBoard
更多推荐
所有评论(0)