新林的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

尝试访问:外网内网都可以访问就没问题

Welcome to nginx!

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

搭建DashBoard · 语雀

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐