Docker$Kubernetes笔记
2023-12-25 16:34:54 0 举报AI智能生成
Docker$Kubernetes笔记
Kubernetes
Kubernetes详细介绍
k8s
模版推荐
作者其他创作
大纲/内容
Docker$Kubernetes笔记---01---Kubernetes的集群部署
<font color="#a66a30">概念及组件、工具解释</font>
k8s:kubernetes,因为k和s之间,有8个字母,所以通常又称为K8S。用来对容器进行调度和管理的,即用来对容器进行编排的。
CRI:容器运行时接口 container runtime interface
CNI: Container Network Interface 的缩写,它是一个用于定义和配置容器网络的标准接口。CNI 插件负责为容器设置网络连接,以使容器可以与其他容器和外部网络通信。
cri-containerd-cni:cri-containerd-cni组件包含了containerd、CNI 插件(Container Network Interface 插件)、crictl、Kubernetes CRI 接口(gRPC API)
containerd:containerd 是一个开源的容器运行时,由 Docker 团队维护。它负责容器的生命周期管理,包括创建、运行、停止和删除容器,以及镜像管理等。containerd 是 cri-containerd-cni 的核心组件,用于运行和管理容器。
CNI 插件(Container Network Interface 插件):CNI 插件是一组用于配置容器网络的插件,使容器能够与其他容器和外部网络进行通信。cri-containerd-cni 包括一组 CNI 插件,用于为容器配置网络,以确保它们可以正常工作。
crictl:crictl 是一个命令行工具,用于与 Kubernetes CRI(Container Runtime Interface)兼容的容器运行时进行交互。它允许管理员执行容器运行时操作,如创建、启动、停止和查看容器等。crictl 通常包括在 cri-containerd-cni 中,以便管理员可以与容器运行时交互。
Kubernetes CRI 接口(gRPC API):cri-containerd-cni 实现了 Kubernetes CRI 接口,这是 Kubernetes 控制平面与容器运行时之间的标准通信协议。它定义了 Kubernetes 控制平面如何与容器运行时进行交互,以管理容器。
runc:runc 是一个用于运行容器的命令行工具,它是 OCI(Open Container Initiative)标准的一部分,用于创建和运行容器。OCI 是一个定义容器规范的开放标准,旨在提供容器格式和运行时的一致性,以确保容器在不同容器运行时中具有可移植性。它通常用于容器运行时的创建和管理,但不包括高级容器编排功能,如容器编排、服务发现等。runc 主要关注容器的生命周期管理和资源隔离。
OCI 标准:runc 遵循 OCI 标准,这意味着它可以与符合 OCI 标准的容器镜像一起使用。这有助于确保容器可以在不同的容器运行时中运行,而无需修改容器镜像。
容器运行时:runc 是一个容器运行时,负责创建和运行容器。它提供了一种将容器启动的底层方法,但不提供高级容器编排功能。因此,通常需要与容器编排工具(如 Kubernetes、Docker Compose 等)一起使用,以实现容器的自动化部署和管理。
轻量级:runc 设计简单,轻量级,专注于容器的生命周期管理。它的目标是提供一个标准的接口,以便与各种容器编排平台和工具集成。
安全性:runc 非常关注安全性,它采用了许多安全机制,以确保容器在运行时的隔离性和安全性。这包括使用 Linux 的命名空间、控制组(cgroup)、Seccomp 等特性来隔离容器。
可移植性:runc 的标准接口使得容器可以在不同的容器运行时中运行,从而实现容器的可移植性。这有助于避免对特定容器运行时的依赖性。
nerdctl:nerdctl 是一个用于运行容器的命令行工具,它是 containerd 的封装器,旨在提供与 Docker CLI 相似的用户体验。nerdctl 可以用来管理和运行容器,而无需完全依赖于 Docker CLI。
兼容性:nerdctl 旨在与 Docker CLI 兼容,因此您可以使用类似的命令和选项来运行容器。这使得迁移到 nerdctl 相对容易,尤其是对于那些习惯于使用 Docker CLI 的用户。
依赖于 containerd:与 Docker 不同,nerdctl 不使用 Docker 引擎,而是依赖于 containerd。这意味着它可以提供更轻量级的容器运行时,同时保持 Docker 命令的兼容性。
支持 OCI 标准:nerdctl 遵循 OCI(Open Container Initiative)标准,这是一个定义容器规范的开放标准。这使得它可以与符合 OCI 标准的容器镜像一起使用。
不需要 root 权限:nerdctl 允许非特权用户运行容器,因此不需要 root 权限。这有助于提高安全性。
可用选项和功能:nerdctl 支持常见的 Docker 命令,如 run、build、ps 等,以及一些其他功能,例如多阶段构建、GPU 支持等。
crictl:crictl 是一个命令行工具,用于与 Kubernetes CRI(Container Runtime Interface)兼容的容器运行时进行交互。它允许您在 Kubernetes 集群中执行容器运行时操作,如创建、启动、停止、删除容器,查看容器状态以及获取容器日志等。
kubeadm,kubelet 和 kubectl<br>
kubeadm(Kubernetes Admin):<br>作用:kubeadm 是一个命令行工具,用于快速部署和初始化 Kubernetes 集群。它可以帮助管理员在不同的环境中设置 Kubernetes 主控节点(Master Node)。<br>用途:通常用于在新的集群中创建和配置 Master 节点,以便其他节点可以加入集群。kubeadm 可以自动处理大部分复杂的初始化工作。<br>
kubelet:<br>作用:kubelet 是每个 Kubernetes 节点上运行的主要代理。它负责维护节点的容器生命周期,确保容器正常运行。kubelet 还与 Master 节点通信,确保节点的状态和资源使用信息被汇报到集群的控制平面。<br>用途:kubelet 用于在节点上管理容器,它会监控 Pod 的创建、更新和销毁,并确保它们的状态与期望状态一致。<br>
kubectl:<br>作用:kubectl 是 Kubernetes 集群的命令行客户端工具,用于与集群进行交互。管理员和开发人员可以使用 kubectl 执行各种操作,如创建、管理和监视 Kubernetes 资源(如 Pod、Service、Deployment 等)。<br>用途:kubectl 允许用户执行各种操作,包括创建和部署应用程序、查看集群状态、调试故障、扩展集群等。<br>
K8S在1.24版本开始直接把dockershim代码删除了,直接弃用了docker;前因后果可以查看这篇文档:https://www.cnblogs.com/1234roro/p/16892031.html
Alpha 阶段:<br>在 Alpha 阶段,软件处于早期开发阶段,通常由内部开发团队进行测试。这个阶段的软件可能存在许多缺陷和问题,并且不适合正式发布给外部用户。Alpha 阶段的主要目标是内部测试和探索,以发现和修复问题。<br>
Beta 阶段<br>在 Beta 阶段,软件已经发展到足够成熟的程度,可以在有限的用户群体中进行测试。这些用户可能是开发者、测试人员或愿意承担一些风险的终端用户。在 Beta 阶段,软件可能仍然存在某些问题,但已经经过了内部 Alpha 测试,并进行了一些修复和改进。<br>
Stable 阶段<br>在 Stable 阶段,软件已经经历了广泛的测试,包括 Beta 测试和可能的公开测试。在这个阶段,软件被认为是相对稳定和可靠的,并且适合正式发布和广泛使用。稳定版本的软件应该在性能、安全性和可用性方面经过了充分验证。<br>
Docker安装部署---安装最新版本
如果之前有安装过docker的可以用以下命令移除掉旧版本<br><font color="#4669ea">yum remove docker \<br> docker-client \<br> docker-client-latest \<br> docker-common \<br> docker-latest \<br> docker-latest-logrotate \<br> docker-logrotate \<br> docker-selinux \<br> docker-engine-selinux \<br> docker-engine</font><br>
删除所有旧的数据<br><font color="#4669ea">rm -rf /var/lib/docker</font>
安装依赖包<br><font color="#4669ea">yum install -y yum-utils device-mapper-persistent-data lvm2</font><br>
添加docker的yum源,这里使用阿里云的镜像<br><font color="#4669ea">yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo</font><br>
配置缓存<br><font color="#4669ea">yum makecache fast</font><br>
安装最新稳定版本的docker<br><font color="#4669ea">yum install -y docker-ce</font><br>
配置镜像加速器<br><font color="#4669ea">mkdir -p /etc/docker<br>cat <<EOF > /etc/docker/daemon.json<br>{<br>"registry-mirrors": ["https://aoewjvel.mirror.aliyuncs.com"]<br>}<br>EOF</font><br>
启动docker引擎并设置开机启动<br><font color="#4669ea">systemctl start docker<br>systemctl enable docker</font><br>
查看docker当前的历史版本并使其倒叙排序,最新的在最上面<br><font color="#4669ea">yum list docker-ce --showduplicates | sort -r</font>
Docker安装部署---安装指定版本
如果之前有安装过docker的可以用以下命令移除掉旧版本<br><font color="#4669ea">yum remove docker \<br> docker-client \<br> docker-client-latest \<br> docker-common \<br> docker-latest \<br> docker-latest-logrotate \<br> docker-logrotate \<br> docker-selinux \<br> docker-engine-selinux \<br> docker-engine</font><br>
删除所有旧的数据<br><font color="#4669ea">rm -rf /var/lib/docker</font>
安装依赖包<br><font color="#4669ea">yum install -y yum-utils device-mapper-persistent-data lvm2</font><br>
添加docker的yum源,这里使用阿里云的镜像<br><font color="#4669ea">yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo</font><br>
查看docker当前的历史版本并使其倒叙排序,最新的在最上面<br><font color="#4669ea">yum list docker-ce --showduplicates | sort -r</font>
配置缓存<br><font color="#4669ea">yum makecache fast</font><br>
安装指定版本的docker<br><font color="#4669ea">yum install -y docker-ce-20.10.24 docker-ce-cli-20.10.24 containerd.io</font><br>
配置镜像加速器<br><font color="#4669ea">mkdir -p /etc/docker<br>cat <<EOF > /etc/docker/daemon.json<br>{<br>"registry-mirrors": ["https://aoewjvel.mirror.aliyuncs.com"]<br>}<br>EOF</font><br>
启动docker引擎并设置开机启动<br><font color="#4669ea">systemctl start docker<br>systemctl enable docker</font><br>
K8S一主多从安装部署步骤
准备工作---所有节点都需要运行
配置部署所需基础环境
安装常用工具,更改系统的默认yum源<br><font color="#4669ea">yum install -y wget<br>mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup<br>wget http://mirrors.163.com/.help/CentOS7-Base-163.repo -O /etc/yum.repos.d/CentOS-Base.repo<br>yum install -y vim</font><br>
关闭系统自带的防火墙<br><font color="#4669ea">systemctl stop firewalld && systemctl disable firewalld<br>setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config</font>
设置hostname,此处以1.197为master节点,其他两台为从节点<br><font color="#4669ea">echo -e "192.168.1.197 master\n192.168.1.198 node01\n192.168.1.199 node02" >> /etc/hosts</font><br>
关闭交换分区<br><font color="#4669ea">swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab</font><br>
配置时间服务器并同步时间<br><font color="#4669ea">yum install -y ntp<br>ntpdate ntp.aliyun.com</font><br>
添加网桥过滤和地址转发功能<br><font color="#4669ea">cat <<EOF > /etc/sysctl.d/kubernetes.conf<br>net.bridge.bridge-nf-call-ip6tables = 1<br>net.bridge.bridge-nf-call-iptables = 1<br>net.ipv4.ip_forward = 1<br>EOF</font><br><br>重新加载配置:<br><font color="#4669ea">sysctl -p</font><br>
加载网桥过滤器模块<br><font color="#4669ea">modprobe br_netfilter</font><br>
查看网桥过滤器模块是否加载成功<br><font color="#4669ea">lsmod | grep br_netfilter</font><br>
配置ipvs<br>安装ipset和ipvsadm软件<br><font color="#4669ea">yum -y install ipset ipvsadm</font><br>添加需要加载的模块写入脚本文件<br><font color="#4669ea">cat > /etc/sysconfig/modules/ipvs.modules <<EOF<br>modprobe -- ip_vs<br>modprobe -- ip_vs_rr<br>modprobe -- ip_vs_wrr<br>modprobe -- ip_vs_sh<br>modprobe -- nf_conntrack_ipv4<br>EOF</font><br>设置脚本权限<br><font color="#4669ea">chmod +x /etc/sysconfig/modules/ipvs.modules</font><br>执行脚本<br><font color="#4669ea">/etc/sysconfig/modules/ipvs.modules</font><br>查看对应的模块是否加载成功<br><font color="#4669ea">lsmod | grep -e ip_vs -e nf_conntrack_ipv4</font><br>
重启系统,使之前的配置生效<br><font color="#4669ea"> reboot</font><br>
安装容器
为什么部署K8S要安装容器<br>Kubernetes(简称k8s)是一个开源的容器编排平台,由Google发起并开源。它用于自动化容器化应用程序的部署、扩展和管理。Kubernetes支持多种容器运行时技术,其中最为广泛使用的就是Docker。通过Kubernetes,我们可以对容器进行分布式管理,实现容器的高可用、负载均衡和故障恢复等功能。<br>
Kubernetes 的两种调用链<br>1:用 CRI 接口调用 dockershim,然后 dockershim 调用 Docker,Docker 再走 containerd 去操作容器。<br>2:用 CRI 接口直接调用 containerd 去操作容器。<br><br>
方法一:安装docker,步骤参考上面的docker安装部署
安装完docker后在启动docker前需要更改以下配置,<br><font color="#4669ea">cat <<EOF > /etc/docker/daemon.json<br>{<br>"registry-mirrors": ["https://aoewjvel.mirror.aliyuncs.com"],<br>"exec-opts": ["native.cgroupdriver=systemd"]<br>}</font><br><font color="#ec6e6c">PS:第一条是配置了Docker 镜像仓库的镜像加速器<br>PS:第二条是指定了 Docker 在容器运行时中使用 systemd 作为 cgroup 驱动程序。这是一种容器运行时的配置,以便 Docker 与系统中的 cgroup(控制组)管理相集成;Docker默认使用的Cgroup Driver为默认文件驱动,而k8s默认使用的文件驱动为systemd,k8s要求驱动类型必须要一致,所以需要将docker文件驱动改成systemd</font>
方法二:K8S1.24版本后就不在使用dockershim调用docker,所以在部署k8s1.24及以上版本时就不能使用docker去操作容器,我们需要新的插件去操作容器;此处以cri-containerd-cni插件为例:<br>
选择所需的版本,点击进去拉倒最下面找对应的安装包,此处以为例:https://github.com/containerd/containerd/releases/download/v1.6.23/cri-containerd-cni-1.6.23-linux-amd64.tar.gz<br><font color="#4669ea">wget https://github.com/containerd/containerd/releases/download/v1.6.23/cri-containerd-cni-1.6.23-linux-amd64.tar.gz</font>
下载containerd 的二进制包并解压<br>
可以使用下列命令直接将安装包解压至根目录,但如果已经存文同名文件会直接覆盖掉,存在一定的风险。可以参考这个文档:https://www.cnblogs.com/zjl-throb/p/16528463.html<br><font color="#4669ea">tar -zxvf cri-containerd-cni-1.6.23-linux-amd64.tar.gz -C /<br>vim /etc/profile<br>export PATH=$PATH:/usr/local/bin:/usr/local/sbin<br>source /etc/profile</font><br>
但推荐先解压至指定目录 然后再将下列文件复制到对应的目录即可:可以参考这个文档中第三点:https://blog.51cto.com/flyfish225/5360370<br><font color="#4669ea">mkdir containerd<br>tar -zxvf cri-containerd-cni-1.6.23-linux-amd64.tar.gz -C containerd<br>cp -p /root/containerd/usr/local/bin/* /usr/local/bin/<br>cp -p /root/containerd/etc/systemd/system/containerd.service /usr/lib/systemd/system/<br>chmod +x /usr/lib/systemd/system/containerd.service</font><br>
生成containerd 的配置文件<br>
生成配置文件<br>Containerd 的默认配置文件为 `/etc/containerd/config.toml`,可以使用`containerd config default > /etc/containerd/config.toml`命令创建一份模块配置文件<br><font color="#4669ea">mkdir -p /etc/containerd<br>containerd config default > /etc/containerd/config.toml</font><br>
配置文件的部分解释
root 和 state<br>这些是 containerd 使用的文件系统根目录和运行时状态目录的路径。通常,/var/lib/containerd 是存储容器和运行时数据的根目录,而 /run/containerd 用于存储运行时状态<br>
grpc<br>这部分配置了 gRPC 通信的相关参数,包括 gRPC 通信的地址和一些身份验证和安全性设置。
cni<br>这部分包含 CNI(Container Network Interface) 插件的配置,用于容器的网络设置。它指定了 CNI 插件的二进制文件路径和配置文件路径。
containerd.default_runtime<br>这是容器的默认运行时配置,包括默认的运行时名称、容器注释等。
containerd.runtimes<br>这部分配置了不同运行时的选项,包括 runc 运行时和它的选项。
containerd.snapshotter<br>这部分配置了容器快照(snapshot)的存储后端,包括 aufs、btrfs、overlayfs、zfs 等。
stream_processors<br>这部分配置了容器图像流处理器,用于处理加密的容器图像流。
timeouts<br>这部分配置了容器操作的超时时间,以确保容器操作在合理的时间内完成。
ttrpc<br>这是 ttrpc(Type-Transparent Remote Procedure Call)通信的配置,它用于 containerd 内部的通信。
更改配置文件<br>备份下配置文件后再作更改<br><font color="#4669ea">cp -p /etc/containerd/config.toml /etc/containerd/config.toml.bak</font><br>
更改容器的 cgroup driver<br><font color="#4669ea">将SystemdCgroup = false改成true<br><br></font>
更改进项仓库的加速器<br>原本是国外镜像:<font color="#4669ea">sandbox_image = "registry.k8s.io/pause:3.6"</font><br><font color="#4669ea">可以改成sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9" </font><br><font color="#e74f4c">PS:这里pause:3.9的版本可以根据下面kubeadm config images list获取的版本来定,当前用的1.28.2版本对应的是3.9版本</font><font color="#4669ea"><br></font><br>
启动containerd并设置开机启动<br><font color="#4669ea">systemctl enable containerd<br>systemctl start containerd<br>systemctl status containerd</font><br><br>
查看containerd版本<br><font color="#4669ea">ctr version</font><br>
<font color="#e74f4c">安装runc</font>
<font color="#e74f4c">必须额外安装runc,因为cri-containerd-cni这个包里的runc有问题,输入runc无法调用命令,例如,输入runc不能提示帮助</font>
下载地址:https://github.com/opencontainers/runc/releases/download/v1.1.9/runc.amd64<br><font color="#4669ea">wget https://github.com/opencontainers/runc/releases/download/v1.1.9/runc.amd64</font><br><font color="#4669ea">chmod +x runc.amd64<br>which runc<br>mv runc.amd64 /usr/local/sbin/runc<br>runc --version<br></font><br>
安装kubeadm、kubelet、kubectl
配置K8S的yum源
配置阿里云上的K8S yum源<br><font color="#4669ea">cat <<EOF > /etc/yum.repos.d/kubernetes.repo<br>[kubernetes]<br>name=Kubernetes<br>baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64<br>enabled=1<br>gpgcheck=0<br>repo_gpgcheck=0<br>gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg<br>EOF<br></font><br><font color="#4669ea">yum repolist<br>yum makecache</font><br>
安装kubeadm、kubelet、kubectl最新版本<br><font color="#4669ea">yum install -y kubelet kubeadm kubectl</font><br>
安装kubeadm、kubelet、kubectl最新版本<br><font color="#4669ea">yum install -y kubelet-1.23.0 kubeadm-1.23.0 kubectl-1.23.0</font><br>
配置kubelet<br>为了实现docker使用的cgroupdriver与kubelet使用的cgroup的一致性,建议修改如下文件内容。<br><font color="#4669ea">vim /etc/sysconfig/kubelet<br>KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"</font><br><br>
启动kubectl并设置其开机自启动<br><font color="#4669ea">systemctl enable --now kubelet</font><br>
修改K8S证书有效期
<font color="#e855a4">为什么要修改证书有效期:<br>k8s各组件非常依赖证书;而默认情况下ca证书是十年,而其他证书都只有一年;Kubernetes中的如果证书过期了,会导致集群中的许多组件无法正常通信,从而影响整个集群的功能。</font><br>
查看证书有效期
方法一:<br><font color="#4669ea">cd /etc/kubernetes/pki<br>for i in $(ls *.crt); do echo "===== $i ====="; openssl x509 -in $i -text -noout | grep -A 3 'Validity' ; done</font><br><br>
方法二:<br><font color="#4669ea">kubeadm certs check-expiration</font><br><br>
安装GO并配置
下载源码<br><font color="#4669ea">wget https://go.dev/dl/go1.21.3.linux-amd64.tar.gz</font><br>
解压安装<br><font color="#4669ea">tar -xf go1.21.3.linux-amd64.tar.gz -C /usr/local/</font><br>
添加环境变量<br><font color="#4669ea">echo "export PATH=$PATH:/usr/local/go/bin" >>/etc/profile<br>source /etc/profile</font><br>
验证是否安装<br><font color="#4669ea">go version</font><br><br>
下载对应版本的k8s源码<br>查看版本然后去github上下载对应的版本<br><font color="#4669ea">kubectl version<br>wget https://github.com/kubernetes/kubernetes/archive/refs/tags/v1.28.2.tar.gz</font><br><br>
解压<br><font color="#4669ea">tar -zxf kubernetes-1.28.2.tar.gz</font><br>
修改两个证书的源文件<br><font color="#4669ea">cd kubernetes-1.28.2</font><br>
修改kubeadm证书;constants.go 文件<br><font color="#4669ea">vim cmd/kubeadm/app/constants/constants.go</font><br>
修改CA 证书:cert.go文件<br><font color="#4669ea">vim staging/src/k8s.io/client-go/util/cert/cert.go</font><br>
编译源代码<br>重新编辑之前先安装rsync ,不然会提示缺少这个工具<br><font color="#4669ea">yum -y install rsync</font><br><br><font color="#4669ea">make WHAT=cmd/kubeadm GOFLAGS=-v</font><br><br>
替换就文件,更换kubeadm
备份文件<br><font color="#4669ea">cp /usr/bin/kubeadm /usr/bin/kubeadm.bak</font><br>
替换文件<br><font color="#4669ea">cp _output/bin/kubeadm /usr/bin/</font><br>
备份证书<br><font color="#4669ea">cd /etc/kubernetes<br>cp -R pki pki.bak</font><br><br>
更新所有证书<br><font color="#4669ea">kubeadm certs renew all</font><br>重启服务或者重启机器,这边选择重启机器<br><font color="#4669ea">reboot</font>
查看证书<br><font color="#4669ea">kubeadm certs check-expiration</font><br><br>
下载集群所需镜像
使用命令列出集群在配置过程中需要哪些镜像:<br><font color="#4669ea">kubeadm config images list</font><br>
因为这个是外网的无法访问,需要替换成国内的镜像地址;
安装docker的直接通过docker去拉取
新建一个文件,将上面获取的镜像名称复制到文件中,然后遍历这个文件,依次进行镜像的下载<br>
示例:<br><span class="tag">#!/bin/bash</span><br><font color="#4669ea">images=(</font><br><font color="#4669ea">kube-apiserver:v1.28.2</font><br><font color="#4669ea">kube-controller-manager:v1.28.2</font><br><font color="#4669ea">kube-scheduler:v1.28.2</font><br><font color="#4669ea">kube-proxy:v1.28.2</font><br><font color="#4669ea">pause:3.9</font><br><font color="#4669ea">etcd:3.5.9-0</font><br><font color="#4669ea">coredns:v1.10.1</font><br><font color="#4669ea">)</font><br><font color="#4669ea">for</font> <font color="#4669ea">imageName</font> <font color="#4669ea">in</font> <font color="#4669ea">${images[@]};do</font><br><font color="#4669ea">docker</font> <font color="#4669ea">pull</font> <font color="#4669ea">registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName</font><br><font color="#4669ea">docker</font> <font color="#4669ea">tag</font> <font color="#4669ea">registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName</font> <font color="#4669ea">k8s.gcr.io/$imageName</font><br><font color="#4669ea">docker</font> <font color="#4669ea">rmi</font> <font color="#4669ea">registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName</font><br><font color="#4669ea">done</font><br><br>
再次查看镜像<br><font color="#4669ea">docker images</font><br><br>
安装containerd的通过ctr命令拉取
新建一个文件,将上面获取的镜像名称复制到文件中,然后遍历这个文件,依次进行镜像的下载
示例:<br><span class="tag">#!/bin/bash</span><br><br><font color="#4669ea">images=(</font><br><font color="#4669ea">kube-apiserver:v1.28.2</font><br><font color="#4669ea">kube-controller-manager:v1.28.2</font><br><font color="#4669ea">kube-scheduler:v1.28.2</font><br><font color="#4669ea">kube-proxy:v1.28.2</font><br><font color="#4669ea">pause:3.9</font><br><font color="#4669ea">etcd:3.5.9-0</font><br><font color="#4669ea">coredns:v1.10.1</font><br><font color="#4669ea">)</font><br><font color="#4669ea">for</font> <font color="#4669ea">imageName</font> <font color="#4669ea">in</font> <font color="#4669ea">"${images[@]}";</font> <font color="#4669ea">do</font><br><font color="#4669ea">ctr</font> <font color="#4669ea">-n</font> <font color="#4669ea">k8s.io</font> <font color="#4669ea">i</font> <font color="#4669ea">pull</font> <font color="#4669ea">registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName</font><br><font color="#4669ea">ctr</font> <font color="#4669ea">-n</font> <font color="#4669ea">k8s.io</font> <font color="#4669ea">i</font> <font color="#4669ea">tag</font> <font color="#4669ea">registry.cn-hangzhou.aliyuncs.com/google_containers/"$imageName"</font> <font color="#4669ea">k8s.gcr.io/"$imageName"</font><br><font color="#4669ea">ctr</font> <font color="#4669ea">-n</font> <font color="#4669ea">k8s.io</font> <font color="#4669ea">i</font> <font color="#4669ea">rm</font> <font color="#4669ea">registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName</font><br><font color="#4669ea">done<br></font><br>
再次查看镜像<br><font color="#4669ea">ctr -n k8s.io images list -q</font><br><br>
<font color="#ec6e6c">PS; 这个查看镜像需要先指定查看哪儿个命名空间才可以查看到,不然查看不到当前机器上已有的镜像,可以通过下列命令先查看当前有哪儿些命名空间,然后在指定命名空间查看已有镜像</font><br><font color="#4669ea">ctr namespace list<br>ctr images list -q<br></font><br>
初始化集群---Master节点运行
初始化
集群初始化<br><font color="#4669ea">kubeadm init \<br>--apiserver-advertise-address=192.168.1.197 \<br>--kubernetes-version=v1.28.2 \<br>--pod-network-cidr=10.244.0.0/16 \<br>--service-cidr=10.254.0.0/16 \<br>--image-repository registry.aliyuncs.com/google_containers</font><br>
在使用 `kubeadm init` 初始化 Kubernetes 控制平面时,通常需要配置一些常见选项,以确保集群的正确设置和性能。以下是一些常用的配置选项:<br>1. `--apiserver-advertise-address`: 指定 Kubernetes API Server 监听的网络接口地址。通常是控制平面节点的 IP 地址或主机名。<br>2. `--kubernetes-version`: 指定要安装的 Kubernetes 版本。<br>3. `--pod-network-cidr`: 指定 Pod 网络的 IP 地址范围。这个范围用于分配给容器的 IP 地址。<br>4. `--service-cidr`: 指定 Kubernetes 服务的 IP 地址范围。这个范围用于分配给 Kubernetes 服务的 IP 地址。<br>5. `--ignore-preflight-errors`: 允许忽略预安装检查中的特定错误,这在特定情况下可能很有用。<br>6. `--control-plane-endpoint`: 用于配置 Kubernetes 控制平面节点的端点地址。通常包括 IP 地址和 API 服务器的端口。<br>7. `--upload-certs`: 允许上传生成的证书和密钥到 Kubernetes 控制平面节点上的密钥存储区,以便其他节点可以加入集群。<br>8. `--config`: 通过配置文件指定初始化选项,这是一种更复杂但可扩展的方式,允许你自定义更多选项。<br>9. `--node-name`: 指定节点的名称,通常在初始化单个节点时使用。<br>
查看集群信息<br><br>
安装网络插件(我这里选择的安装安装calico作为网络插件)<br>
安装网络插件calico
<br><br>
安装calico<br>
<font color="#4669ea">kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.3/manifests/tigera-operator.yaml</font><br>
<font color="#4669ea">wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.3/manifests/custom-resources.yamlkubectl create -f custom-resources.yaml </font><br>
查看calico状态<br><font color="#4669ea">kubectl get pods -n calico-system -owide</font><br>
安装网络插件flannel
只在master节点安装flannel插件即可,该插件使用的是DaemonSet控制器,该控制器会在每个节点上都运行<br><font color="#4669ea">wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml<br>kubectl apply -f kube-flannel.yml</font><br>
初始化集群---Node节点运行
获取证书key<br>在master节点上运行<br><font color="#4669ea">kubeadm token create --print-join-command</font><br><br>
添加worker节点<br>分别在worker节点上运行上述命令<br>
node01上运行<br><font color="#4669ea">kubeadm join 192.168.1.197:6443 --token a81tq8.zsj9rd99h35q4sb2 --discovery-token-ca-cert-hash sha256:2f9a74d3c5033933b23c52fe9f00fdb76719bc259adb6f71dcce0d91630b78be</font><br><br>
node02上运行<br><font color="#4669ea">kubeadm join 192.168.1.197:6443 --token a81tq8.zsj9rd99h35q4sb2 --discovery-token-ca-cert-hash sha256:2f9a74d3c5033933b23c52fe9f00fdb76719bc259adb6f71dcce0d91630b78be</font><br><br>
Q&A
01:故障现象:运行kubectl get nodes提示如下报错<br><font color="#e855a4">E1101 16:19:06.496382 32806 memcache.go:265] couldn't get current server API group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080: connect: connection refused</font><br>
原因:kubectl命令需要使用kubernetes-admin来运行,需要admin.conf文件;而admin.conf 文件是通过 “kubeadmin init” 命令在 /etc/kubernetes 中创建的,从节点没有该配置文件;因此需要将admin.conf复制到从节点
解决方法:<br><font color="#4669ea">ls /etc/kubernetes/<br>mkdir ~/.kube<br>cp /etc/kubernetes/admin.conf ~/.kube/<br>cd ~/.kube<br>mv admin.conf config</font><br><br>
02:故障现象:master节点kubeadm初始化提示如下报错<br><br>
原因,之前的重启导致添加的网桥和地址转发功能失效了
解决方法:需要重新添加网桥过滤和地址转发功能,并将这个加入开机启动项<br><font color="#4669ea">cat <<EOF > /etc/sysctl.d/kubernetes.conf<br>net.bridge.bridge-nf-call-ip6tables = 1<br>net.bridge.bridge-nf-call-iptables = 1<br>net.ipv4.ip_forward = 1<br>EOF<br>sysctl --system</font><br><br>
03;故障现象:安装完网络插件calico后没有两个node节点没有正常运行起来对应的pod<br><br>
原因:两台node节点中/etc/containerd/config.toml配置文件中的镜像地址写错了,通过这个命令查看没起来的日志<br><font color="#4669ea">kubectl describe pod -n tigera-operator tigera-operator-597bf4ddf6-d5fr7</font><br><br>
解决方法:将配置文件中的镜像地址改成正确的地址,更改完后可以看到网络插件对应的pod都已正常启动<br><font color="#4669ea">kubectl get pods -n calico-system -owide</font><br><br>
Docker$Kubernetes笔记---02---常用docker&kubectl命令
docker pull
docker tag
删除容器<br>docker rm
查看容器状态<br>docker stats
查看容器配置文件<br>docker inspect 容器名称
查看容器日志<br>docker logs -f --tail 20 bb74
kubectl get nodes<br>查看所有节点
kubectl get pods -A 或者 kubectl get pod --all-namespaces<br>查看所有ns空间的pod<br>
kubectl get pods -A -owide<br>查看所有ns空间的pod的详细信息<br>
kubectl describe pod -n tigera-operator tigera-operator-597bf4ddf6-d5fr7<br>查看tigera-operator-597bf4ddf6-d5fr7这个Pod 的详细信息,包括容器、事件、标签等等。你可以用这些信息来诊断该 Pod 是否正常运行以及它是否有任何问题。<br>
Docker$Kubernetes笔记---03---Kubernetes资源管理及五大资源
资源管理
资源管理介绍
在kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理kubernetes
kubernetes的本质就是一个集群系统,用户可以在集群中部署各种服务,所谓部署服务就是在kubernetes集群中运行一个一个的容器,并将指定的程序跑在容器中
kubernetes的最小管理单元是pod而不是容器,所以只能将容器放在pod中,而kubernetes一般也不会直接管理pod,而是通过pod控制器来管理pod
pod可以提供服务之后,就要考虑如何访问pod中的服务,kubernetes提供的service资源实现这个功能,如果pod中程序的数据需要持久化,kubernetes还提供了各种存储系统
学习kubernetes的核心就是学习如何对集群上的Pod、Pod控制器、Service、存储等各种资源进行操作<br>
资源管理之YAML语言
YAML是一个类似于XML、JSON的标记性语言,它强调以数据为中心,并不是以标识语言为重点,因为YAML本身的定义比较简单,号称“一种人性化的数据格式语言”。
YAML的语法特点:
严格区分大小写<br>
使用缩进表示层级关系
缩进不允许使用tab键,只允许使用空格,缩进的空格数量没有严格要求,只要相同层级的元素左对齐即可
#号表示注释
书写YAML切记 : 后边要加一个空格
如果需要将多段YAML配置放在同一个文件中,中间需要用 --- 作为分格
下面是YAML转JSON语法网站,可用于验证yaml语法是否正确<br><font color="#e74f4c">http://json2yaml.com/convert-yaml-to-json</font><br>
资源管理方式介绍
在kubernetes中,所有内容都被抽象为资源对象,学习kubernetes主要学习如何管理资源对象<br> 类型 <font color="#a23735">操作对象</font> <font color="#a66a30">试用环境</font> <font color="#569230">优点</font> <font color="#314aa4"> 缺点</font><br>命令式对象管理 <font color="#a23735">对象</font> <font color="#a66a30">测试</font> <font color="#569230">简单 </font> <font color="#314aa4">只能操作活动对象,无法审计、跟踪</font><br>命令式对象配置 <font color="#a23735">文件</font> <font color="#a66a30">开发</font> <font color="#569230">可以审计、跟踪 </font> <font color="#314aa4">项目大时,配置文件多,操作麻烦</font><br>声明式对象配置 <font color="#a23735">目录 </font> <font color="#a66a30">开发</font> <font color="#569230">支持目录操作</font> <font color="#314aa4">意外情况下难以调试</font>
资源管理方式1---命令式对象管理---直接使用命令去操作kubernetes资源
<font color="#e74f4c">kubectl run nginx-pod --image=nginx:1.17.4 --port=80</font>
资源管理方式2---命令式对象配置---通过命令配置和配置文件去操作kubernetes资源
<font color="#e74f4c">kubectl create/patch -f nginx-pod.yaml</font>
资源管理方式3---声明式对象配置---通过apply命令和配置文件去创建和更新kubernetes资源
<font color="#e74f4c">kubectl apply -f nginx-pod.yaml</font>
命令式对象管理
命令式对象管理:直接使用命令去操作kubernetes资源<br>
kubectl命令介绍:kubectl是kubernetes集群的命令行工具,通过它能过够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署
命令格式:kubectl [command] [type] [name] [flags]
command:指定要对资源执行的操作,例如:create、get、delete
type:指定资源类型,例如:deployment、pod、service
name:指定资源名称,名称区分大小写
flags:指定额外的可选参数
ubenetes允许对资源进行多种操作,可以通过--help查看详细的操作指令<br>kubectl --help<br>
查看所有pod<br><font color="#e74f4c">kubectl get pod</font><br><br>
查看指定的pod(根据pod名字查找)<br><font color="#e74f4c">kubectl get pod nginx-696649f6f9-g5nds</font><br>
查看指定pod,通过额外参数显示pod详细信息,包括pod的IP地址,pod运行的节点等<br><font color="#e74f4c">kubectl get pod nginx-696649f6f9-g5nds -o wide</font><br>
查看指定pod,通过额外参数显示pod信息,以json格式显示<br><font color="#e74f4c">kubectl get pod nginx-696649f6f9-g5nds -o json<br></font>
查看指定pod,通过额外参数显示pod信息,以yaml格式显示<br><font color="#e74f4c">kubectl get pod nginx-696649f6f9-g5nds -o yaml<br></font>
显示指定pod资源内部信息<br><font color="#e74f4c">kubectl describe pod nginx-696649f6f9-g5nds</font><br><br>
显示当前Server和Client版本信息<br><font color="#e74f4c">kubectl version<br></font>
显示集群信息<br><font color="#e74f4c">kubectl cluster-info<br></font>
案例:以一个 namespace的创建和删除简单演示命令用法<br>
在namespace下创建dev空间<br><font color="#e74f4c">kubectl create ns dev</font><br>
获取namespace信息<br><font color="#e74f4c">kubectl get ns</font><br>
在dev空间下创建并运行一个nginx的pod<br><font color="#e74f4c">kubectl run pod --image=nginx:1.17.1 -n dev</font><br>
在dev空间下创建并运行一个nginx的pod并显示详细的创建过程<br><font color="#e74f4c">kubectl run pod --image=nginx:1.19.0 -n dev --v=9</font><br>
获取dev空间下pod信息<br><font color="#e74f4c">kubectl get pods -n dev</font><br>
显示dev空间下nginx资源内部信息<br><font color="#e74f4c">kubectl describe pods pod -n dev</font><br>
删除dev空间下nginx的pod<br><font color="#e74f4c">kubectl delete pods pod -n dev</font><br>
上面的创建方式删除pod后不会自动拉起一个新的,必须使用如下命令才会删除后自动拉起新的pod<br><font color="#e74f4c">kubectl create deployment nginx-dev --image=nginx:1.17.1 -n dev</font><br>
删除namespace下的dev空间,这里会连同删除ns中的pod一起删除<br><font color="#e74f4c">kubectl delete ns dev</font><br>
命令式对象配置
命令式对象配置:通过命令配置和配置文件去操作kubernetes资源
案例:通过yaml文件演示一个namespace的创建
创建一个yaml文件<br><font color="#e74f4c">vim nginx-dev.yaml</font><br>
执行create命令创建资源<br><font color="#e74f4c">kubectl create -f nginx-dev.yaml</font><br>
查看namespace信息<br><font color="#e74f4c">kubectl get ns</font><br>
查看namespace下的dev空间<br><font color="#e74f4c">kubectl get pods -n dev</font><br>
通过yaml文件查看资源<br><font color="#e74f4c">kubectl get -f nginx-dev.yaml </font><br>
通过yaml文件删除资源<br><font color="#e74f4c">kubectl delete -f nginx-dev.yaml</font><br>
声明式对象配置
声明式对象配置:通过apply命令和配置文件去创建和更新kubernetes资源
案例:声明式对象配置与命令式对象配置类似,但是它只有一个apply
执行kubernetes apply yaml文件创建资源<br><font color="#e74f4c">kubectl apply -f nginx-dev.yaml</font><br>
获取namespace信息<br><font color="#e74f4c">kubectl get ns</font><br>
查看dev空间下的pod信息<br><font color="#e74f4c">kubectl get pods -n dev</font><br>
可以通过修改yaml文件内容更新pod中的资源<br><font color="#e74f4c">vim nginx-dev.yaml</font><br>
执行yaml文件更新pod中的资源<br><font color="#e74f4c">kubectl apply -f nginx-dev.yaml</font><br>
显示资源内部信息<br><font color="#e74f4c">kubectl describe pods nginx-dev -n dev</font><br>
总结:
声明式对象配置就是使用apply描述一个资源最终的状态(在yaml中定义)
使用apply操作资源,如果资源不存在就创建资源,相当于 kubectl create
使用apply操作资源,如果资源已经存在就更新资源,相当于 kubectl patch
资源管理总结:三种资源管理方式的命令使用建议
创建/更新资源建议使用声明式对象配置:kubectl apply -f xx.yaml
删除资源建议使用命令式对象配置:kubectl delete -f xx.yaml
查询资源建议使用命令式对象管理:kubectl get(describe) 资源名称
五大资源之Namespace
Namespace介绍
Namespace是kubernetes系统中的一种非常重要的资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离<br>
默认情况下kubenetes集群中的所有Pod都是可以相互访问的,但是实际环境中可能需要隔离不同的Pod,那此时就可以将不同的Pod划分到不同的Namespace下,kubernetes通过将集群内部的资源分配到不同的Namespace中,可以形成逻辑上的“组”,以方便不同的组资源进行隔离使用和管理<br>
可以通过kubernetes的授权机制,将不同的Namespace交给不同的租户进行管理,这样就实现了多租户的资源隔离,此时还能结合kubernetes的资源配额机制,限定不同的租户能占用的资源,例如CPU使用量、内存使用量等来实现租户可用资源的管理
kubernetes在集群启动以后会默认创建几个Namespace<br>
default<br>所有未指定的Namespace的对象都会被分配在default名称空间<br>
kube-node-lease<br>集群节点之间的心跳维护,v1.13开始引入<br>
kube-public<br>该命名空间下的资源可以被所有人访问,包括未认证的用户<br>
kube-system<br>所有由kubernetes系统创建的资源都处于这个命名空间<br>
Namespace资源操作指令命令
查看命令
查看所有Namespace信息<br><font color="#e74f4c">kubectl get ns</font>
查看指定Namespace信息<br><font color="#e74f4c">kubectl get ns default</font><br>
查看指定Namespace详细信息<br><font color="#e74f4c">kubectl describe ns default</font><br>
Status: Active Active表示命名空间正在使用,Terminatind表示正在删除命名空间
No resource quota. 针对于Namespace做的资源限制
No LimitRange resource. 针对于Namespace中的每个组件做的资源限制
创建命令<br>
创建Namespace<br><font color="#e74f4c">kubectl create ns dev</font><br>
查看指定Namespace<br><font color="#e74f4c">kubectl get ns dev</font><br>
删除命令
删除指定Namespace<br><font color="#e74f4c">kubectl delete ns qa</font><br>
配置文件形式创建Namespace
通过yml文件创建Namespace<br><font color="#e74f4c">vim ns_qa.yml</font><br>
创建Namspace<br><font color="#e74f4c">kubectl create -f ns_qa.yml</font><br>
查看Namespace<br><font color="#e74f4c">kubectl get ns </font><br>
删除Namespace<br><font color="#e74f4c">kubectl delete -f ns_qa.yml </font><br>
五大资源之Pod
Pod介绍
Pod是kubernetes集群进行管理的最小单元,程序运行必须部署在容器中,而容器必须存在于Pod中。
Pod可以认为是容器的封装,一个Pod中可以存在一个或多个容器。
kubernetes集群启动以后,集群中的各个组件也都是以Pod方式运行,可以通过命令查看。
查看指定kube-system名称空间中的Pod<br><font color="#e74f4c">kubectl get pod -n kube-system</font><br>
Pod操作指令命令
创建并运行Pod命令(kubernetes没有提供单独运行Pod的命令,都是通过Pod控制器来实现)
<font color="#4ccbcd">命令格式:kubectl</font> <font color="#4ccbcd">run</font> <font color="#4ccbcd">(pod控制器名称)</font> <font color="#4ccbcd">[参数]</font><br>- --image 指定Pod的镜像<br>- --port 指定端口<br>- --namespace 指定Namespace<br>
创建Namespace,并将Pod运行在指定的Namespace中<br><font color="#e74f4c">kubectl create ns dev</font><br>
指定Pod运行在dev名称空间中<br><font color="#e74f4c">kubectl run nginx --image=nginx:1.17.1 --port=80 --namespace dev<br>kubectl create deployment nginx --image=nginx:1.17.1 --port=80 --namespace dev</font><br>
查看Pod命令
查看Namespace中Pod基本信息,默认为default名称空间Pod信息<br><font color="#e74f4c">kubectl get pods </font><br>
查看dev名称空间中的Pod信息<br><font color="#e74f4c">kubectl get pod -n dev</font><br>
查看Pod详细信息(-o wide)<br><font color="#e74f4c">kubectl get pod -n dev -o wide</font><br>
查看Pod详细描述信息<br><font color="#e74f4c">kubectl describe pods nginx -n dev</font><br>
访问Pod命令
可通过Pod的IP与端口访问Pod中运行的程序<br><font color="#e74f4c">curl http://10.244.196.141:80</font><br>
删除Pod命令(可根据Pod的NAME删除指定Pod)
查看Pod名称<br><font color="#e74f4c">kubectl get pod -n dev</font><br>
删除Pod<br><font color="#e74f4c">kubectl delete pods nginx-765d7cffb-t2rd2 -n dev</font><br>
查看pod信息---可以发现刚刚的pod被删除以后,新的pod又自动生成了,该原因是应为pod控制器又自动创建一个新pod,如果想永久删除可以将pod控制器删除<br><font color="#e74f4c">kubectl get pod -n dev</font><br>
查看pod控制器信息<br><font color="#e74f4c">kubectl get deployment -n dev</font><br>
删除pod控制器<br><font color="#e74f4c">kubectl delete deployment nginx -n dev</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get pod -n dev</font><br>
配置文件形式创建pod
创建配置文件<br><font color="#e74f4c">vim pod_nginx.yml</font><br>
通过配置文件创建Pod<br><font color="#e74f4c">kubectl create -f pod_nginx.yml</font><br>
查看dev名称空间下pod信息<br><font color="#e74f4c">kubectl get pods -n dev</font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get pod -n dev -o wide</font><br>
访问pod中nginx程序<br><font color="#e74f4c">curl http://10.244.140.70:80</font><br>
删除pod<br><font color="#e74f4c">kubectl delete -f pod_nginx.yml </font><br>
查看pod信息<br><font color="#e74f4c">kubectl get pod -n dev</font><br>
五大资源之Label
Label介绍
Label是kubernetes中在资源上添加标识,用来对他们进行区分和选择
Label特点:
一个Label会以key/value键值对的形式附加到各种对象上,如Node、Pod、Service等等
一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上
Label通常在资源对象定义时确定,也可以在对象创建后动态添加或者删除
通过Label实现资源的多维度分组,以便灵活方便的进行资源分配、调度、配置、部署等管理工作
常用的Label示例如下:
版本标签:"version":"1.0"
环境标签:"environment":"dev","environment":"test","environment":"pord"
架构标签:"tier":"frontend","tier":"backend"
标签定义完毕以后还要考虑标签的选择,这就要用到Label Selector,既:
Label用于给某个资源对象定义标识
Label Selector用于查询和筛选拥有某些标签的资源对象
定义标签的方式
基于等式的定义方式
version=1.0 等于
version!=1.0 不等于
基于集合的定义方式
version in (1.0,2.0) 在这里
version in (1.0,2.0) 不在这里
Label常用命令
创建Pod并为Pod资源打标签<br><font color="#e74f4c">kubectl create -f pod_nginx.yml </font><br>
查看pod<br><font color="#e74f4c">kubectl get pod -n dev</font><br>
查看pod标签:--show-labels<br><font color="#e74f4c">kubectl get pod -n dev --show-labels</font><br>
为nginx的pod打version标签<br><font color="#e74f4c">kubectl label pod nginx-file -n dev version=1.0</font><br>
查看pod标签<br><font color="#e74f4c">kubectl get pods -n dev --show-labels</font><br>
为nginx的pod打标签(一个资源对象可以定义任意数量的Label)<br><font color="#e74f4c">kubectl label pod nginx-file -n dev tier=frontend</font><br>
查看pod标签<br><font color="#e74f4c">kubectl get pods -n dev --show-labels</font><br>
更新version标签:--overwrite<br><font color="#e74f4c">kubectl label pod nginx-file -n dev version=2.0 --overwrite</font><br>
查看pod标签<br><font color="#e74f4c">kubectl get pods -n dev --show-labels</font><br>
基于等式的标签筛选(在创建一个nginx的pod并为其打标签进行筛选)
创建pod
<font color="#e74f4c">vim pod_nginx.yml</font><br>
<font color="#e74f4c">kubectl create -f pod_nginx.yml</font>
查看pod<br><font color="#e74f4c">kubectl get pods -n dev</font><br>
查看pod标签(nginx2默认没有标签)<br><font color="#e74f4c">kubectl get pods -n dev --show-labels</font><br>
为nginx2的pod打标签<br><font color="#e74f4c">kubectl label pods nginx2 -n dev version=1.0</font><br>
查看pod标签<br><font color="#e74f4c">kubectl get pods -n dev --show-labels</font><br>
根据标签选择器进行标签筛选:-l "标签" <br><font color="#e74f4c">kubectl get pods -l "version=1.0" -n dev --show-labels</font><br>
筛选不等于"version=1.0"的标签:"version!=1.0"<br><font color="#e74f4c">kubectl get pods -l "version!=1.0" -n dev --show-labels</font><br>
基于集合的标签筛选:in(筛选)<br><font color="#e74f4c">kubectl get pods -l "version in (1.0)" -n dev --show-labels</font><br>
基于集合的标签筛选:notin(不筛选)<br><font color="#e74f4c">kubectl get pods -l "version notin (1.0)" -n dev --show-labels</font><br>
删除标签:标签名-<br><font color="#e74f4c">kubectl label pod nginx-file -n dev tier-<br>kubectl label pod nginx-file -n dev version-</font><br>
查看标签<br><font color="#e74f4c">kubectl get pods -n dev --show-labels</font><br>
配置文件形式更新标签
修改yaml文件<br><font color="#e74f4c">vim pod_nginx.yml</font><br>
执行文件(apply通过配置文件对资源进行配置)<br><font color="#e74f4c">kubectl apply -f pod_nginx.yml</font><br>
查看标签<br><font color="#e74f4c">kubectl get pods nginx3 -n dev --show-labels -o wide</font><br>
<font color="#4ccbcd">PS:这里通过kubectl apply -f pod_nginx.yml更新标签的前提是这个pod创建时也是通过kubectl apply -f进行创建的 不然会提示报错,还有就是不能更改配置文件中的端口等不允许更改字段</font>
五大资源之Deployment
Deployment介绍
在kubernetes中,pod是最小的控制单元,但是kubernetes很少直接控制pod,一般都是通过控制器来完成,pod控制器用于pod的管理,确保pod资源符合预期的状态,当pod资源出现故障时,会尝试进行重启或重建pod
在kubernetes中pod控制器的种类有很多,这里介绍常用的控制器:Deployment控制器,其他控制器还有ReplicaSet、Job、CronJob、StatefulSet控制器和HPA控制器。<br>
Deploment常用命令
命令格式:kubectl run deployment名称 [参数]
--image 指定pod镜像
--port 指定端口
--replicas 指定创建pod数量
--namespace 指定namespace
创建pod(将前边创建好的pod先删除)<br><font color="#e74f4c">kubectl delete pod nginx -n dev<br>kubectl get pod -n dev</font><br>
创建pod<br><font color="#e74f4c">kubectl create deployment nginx --image=nginx:1.17.1 --port=80 --replicas=3 --namespace=dev</font><br>
查看pod控制器与pod信息<br><font color="#e74f4c">kubectl get deployment,pod -n dev</font><br>
查看pod控制器详细信息<br><font color="#e74f4c">kubectl describe deployment nginx -n dev</font><br>
查看pod标签信息<br><font color="#e74f4c">kubectl get pods -n dev --show-labels</font><br>
删除pod控制器(同时pod也会随着删除)<br><font color="#e74f4c">kubectl delete deployment nginx -n dev</font><br>
查看pod控制器与pod信息<br><font color="#e74f4c">kubectl get deployment,pod -n dev</font><br>
配置文件形式创建Deployment
创建配置文件<br><font color="#e74f4c">vim deployment_nginx.yml</font><br>
创建Deployment<br><font color="#e74f4c">kubectl create -f deployment_nginx.yml</font><br>
查看pod控制器与pod信息<br><font color="#e74f4c">kubectl get deployment,pod -n dev</font><br>
删除pod控制器<br><font color="#e74f4c">kubectl delete -f deployment_nginx.yml</font><br>
查看信息<br><font color="#e74f4c">kubectl get deployment,pod -n dev</font><br>
在通过配置文件创建一组pod并实现客户端访问<br><font color="#e74f4c">kubectl create -f deployment_nginx.yml</font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get pods -n dev -o wide</font><br>
访问nginx程序<br><font color="#e74f4c">curl http://10.244.140.82:80</font><br>
总结:通过对Deployment创建一组pod集群可以提高集群的高可用性
五大资源之Service
Service介绍
Service可以看作是一组同类Pod对外访问接口,借助Service应用可以方便的实现服务发现与负载均衡
创建集群内部可以访问Service<br>
暴露Service<br><font color="#e74f4c">kubectl expose deployment nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev</font><br>
查看Service信息<br><font color="#e74f4c">kubectl get svc -n dev</font><br>
客户端可通过Service的IP访问Pod中的程序<br><font color="#e74f4c">curl http://10.254.144.21:80</font><br>
PS:CLUSTER-IP是Servece的IP,在Service的生命周期中,这个地址永远不会改变
PS:上面创建的Service的type类型为ClusterIP,这个IP地址只能用于集群内部访问,如果需要创建外部可以访问的Service,需要修改type为NodePort
创建集群外部可以访问Service
暴露Service<br><font color="#e74f4c">kubectl expose deployment nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev</font><br>
查看Service信息;可以看到svc-nginx2的TYPE类型为NodePort的Service<br><font color="#e74f4c">kubectl get svc -n dev</font><br>
现在集群外部主机可以访问NodePort的端口<br>
浏览器访问http://192.168.1.197:32525/
直接curl命令访问<br><font color="#e74f4c">curl http://192.168.1.198:32525</font><br>
删除Service
查看Service<br><font color="#e74f4c">kubectl get svc -n dev</font><br>
按照Service的名称删除,删除svc-nginx1<br><font color="#e74f4c">kubectl delete svc svc-nginx1 -n dev</font><br>
新建配置文件<br><font color="#e74f4c">vim svc_nginx.yml</font><br>
配置文件形式创建Service
配置文件创建Service<br><font color="#e74f4c">kubectl create -f svc_nginx.yml </font><br>
查看Service信息<br><font color="#e74f4c">kubectl get svc -n dev</font><br>
配置文件删除Service<br><font color="#e74f4c">kubectl delete -f svc_nginx.yml </font><br>
Docker$Kubernetes笔记---04---Pod基础&生命周期
Pod基础---结构定义
每个pod中都包含一个或多个容器,这些容器可以分为两类:
用户自定义容器:数量可多可少
Pause根容器:每个pod都会有一个根容器,根容器的作用有两个
可以以根容器作为依据,评估整个pod的健康状态
可以在根容器上设置IP地址,用户可以通过根容器IP访问到其他容器(实现Pod内部通信)
pod之间相互通信可以采用虚拟二层网络技术来实现,我们当前实验环境为calico网络插件实现
Pod定义的资源清单
在kubernetes中基本所有资源的一级属性都是一样的,主要分为五部分
apiVersion 版本,由k8s内部定义,版本号必须可以通过kubectl api-versions 查询到
kind 类型,由k8s内部定义,类型必须可以通过kubectl api-resources查询到
metadata 主要是指定资源标识与说明,常用的有name、namespace、labels等
spec 描述,这是配置中最重要的一部分,里边对各种资源配置的详细描述
status 状态信息,里边的内容不需要定义,有k8s自动生成
explain选项用于查看资源文档
命令格式:kubect explain 资源名称
查看pod资源文档<br><font color="#e74f4c">kubectl explain pods</font><br>
以下是比较详细的资源清单介绍
KIND: Pod 资源类型类型<br>VERSION: v1 资源版本<br>DESCRIPTION: 资源描述<br>FIELDS: 资源可配置的属性,如下<br>
apiVersion: v1 必选的一级属性,版本号,例如v1
kind: Pod 必选的一级属性,资源类型,例如Pod
metadata: 必选的一级属性,元数据<br>
name: 必选的二级属性,Pod名称
namespace: dev 二级属性,Pod所属的名称空间,例如dev,默认为default名称空间
labels: 二级属性,自定义标签列表
name: 三级属性,标签名称
spec: 必选的一级属性,Pod中容器的详细定义
containers: 必选的二级属性,Pod中容器列表
name: 必选的三级属性,容器名称
image: 必选的三级属性,容器镜像名称
imagePullPolicy: 三级属性,镜像的拉取策略
command: 三级属性,容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: 三级属性,容器的启动命令参数列表
workingDir: 三级属性,容器的工作目录
volumeMounts: 三级属性,挂载到容器内部的存储卷配置
name: 四级属性,引用pod定义的共享存储卷的名称
mountPath: 四级属性,存储卷在容器内mount的绝对路径,应少于512字节
readOnly: 四级属性,是否为只读模式
ports: 三级属性,需要暴露的端口库号列表
name: 四级属性,端口的名称
containerPort: 四级属性,容器需要监听的端口号
hostPort: 四级属性,容器所在的主机需要监听的端口号,默认与Container相同
protocol: 四级属性,端口协议,支持TCP/UDP,默认为TCP
env: 三级属性,容器运行前需要设置的环境变量列表
name: 四级属性,环境变量名称
value: 四级属性,环境变量的值
resources: 三级属性,资源限制和请求的设置
limits: 四级属性,资源限制的设置
CPU: 五级属性,CPU资源限制,单位为core数,将用于docker run --cpu-shares参数
memory: 五级属性,内存资源限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: 四级属性,资源请求的设置
CPU: 五级属性,CPU请求,容器启动的初始可用数量
memory: 五级属性,内存请求,容器启动的初始可用数量
lifecycle: 三级属性,生命周期钩子
postStart: 四级属性,容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: 四级属性,容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: 三级属性,对Pod内个容器健康检查设置,当探测容器无响应后将自动重启该容器
tcpSocket: 三级属性,对Pod内容器健康检查方式
initialDelaySeconds: 三级属性,容器启动完成后,首次探测时间,单位为秒
timeoutSeconds: 三级属性,对容器健康检查探测等待相应的超时时间,单位秒,默认1秒
periodSeconds: 三级属性,对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
restartPolicy: 二级属性,Pod的重启策略
nodeName: 二级属性,设置pod调度到指定的node节点上
nodeSelector: 二级属性,设置Pod调度到指定的label的node节点上
imagePullSecrets: 二级属性,拉取镜像时,使用secret名称,以key:secretkey格式指定
hostNetwork: 二级属性,是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes: 二级属性,在该Pod上定义共享存储卷列表
name: 三级属性,共享存储卷名称
emptyDir: 三级属性,类型为emptyDir的存储卷,与Pod同生命周期的一个临时目录,为空值
hostPath: 三级属性,类型为hostPath的存储卷,挂载集群与定义的secret对象到容器内部
path: 四级属性,Pod所在宿主机的目录,将被用于容器中挂载的目录
secret: 三级属性,类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
configMap: 三级属性,类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
Pod基础---基本配置
以下是对spec属性下常见的子属性介绍
containers 容器列表,用于定义容器的详细信息,这是pod配置中最关键的一项配置
nodeName 根据nodeName的值将pod调度到指定的Node节点上
nodeSelector 根据NodeSelector中定义的信息选择将该pod调度到包含这些label的Node节点
hostNetwork 是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes 存储卷,用于定义pod上面挂载的存储信息
restartPolicy 重启策略,表示pod在遇到故障时的处理策略
以下是对containers属性的说明
通过下边命令可以获取containers支持的子属性<br>kubectl explain pod.spec.containers<br>
RESOURCE: containers <[]Object> 数组,代表可以有多个容器
FIELDS:
name <string> 容器名称,类型<字符串>
image <string> 容器镜像地址,类型<字符串>
imagePullPolicy <string> 镜像拉取策略,类型<字符串>
command <[]string> 容器启动的命令列表,如不指定,使用打包时使用的命令,类型<字符串>
args <[]string> 容器启动的命令需要的参数列表,类型<字符串>
env <[]Object> 容器环境变量的配置,类型<对象>
ports <[]Object> 容器需要暴露的端口号列表,类型<对象>
resources <Object> 资源限制和资源请求的设置,类型<对象>
以下是对containers下的name、image属性的案例演示
通过配置文件创建两个pod,nginx镜像用于提供web服务,busybox是一个小巧的linux命令集合,可以用来当测试工具使用
<font color="#e74f4c">vim pod-base.yml</font>
先删除dev名称空间,主要将dev下的pod删除,创建dev名称空间<br><font color="#e74f4c">kubectl delete ns dev<br>kubectl create ns dev</font><br>
通过配置文件创建pod<br><font color="#e74f4c">kubectl create -f pod-base.yml</font><br>
查看pod信息<br><font color="#e74f4c">kubectl describe pods pode-base -n dev</font><br><font color="#e855a4">NAME:pod名称<br>READY:准备好的pod数量<br>STATUS:pod状态,CrashLoopBackOff(崩溃)<br>RESTARTS:重启次数</font><br>
Pod基础---镜像拉取策略
imagePullPolicy用于设置镜像拉取策略,k8s支持三种拉取策略,可通过下边命令查看
Always:总是从远程仓库拉取镜像
IfNotPresent:本地有则使用本地镜像,本地没有则从远程仓库拉取镜像
Never:只使用本地镜像,从不去远程仓库拉取,本地如果没有就报错
默认值说明:如果镜像标签为具体版本号,默认策略是IfNotPresent,如果镜像标签为latest,默认策略是Always
imagePullPolicy属性案例演示
创建pod,并指定镜像拉取策略为Never,只使用本地镜像,不从远程仓库拉取<br>
<font color="#e74f4c">vim pod-imagepullpolicy.yml</font>
创建pod<br><font color="#e74f4c">kubectl create -f pod-imagepullpolicy.yml </font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看pod详细描述信息<br><font color="#e74f4c">kubectl describe pod pod-imagepullpolicy -n dev</font><br>
PS:提示:本实验集群环境默认没有下载过nginx:1.17.2镜像,所以会创建失败
创建pod,并指定镜像拉取策略为IfNotPresent,本地有则使用本地镜像,本地没有则从远程仓库拉取镜像
<font color="#e74f4c">vim pod-ifnotpresent.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-ifnotpresent.yml</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl describe pod pod-ifnotpresent -n dev</font><br>
Pod基础---启动命令
前边案例中,busybox容器没有运行成功,是应为busybox并不是一个程序,而是类似于一个工具类的集合,k8s集群启动管理后,会自动关闭,解决方式就是让其一直运行,这时候可以使用command属性配置
对command属性的案例演示
创建pod-command.yml文件,并设置busybox容器的启动命令
<font color="#e74f4c">vim pod-command.yml</font>
命令解释
"/bin/sh","-c", 使用sh执行命令(busybox内没有bash,使用bash会失败)
"touch /tmp/hello.txt; 创建文件在tmp目录
while true;do /bin/echo $(date +%T) >> /tmp/hello.txt;sleep 3;done;" 每隔3秒向文件写入当前时间
创建pod<br><font color="#e74f4c">kubectl create -f pod-command.yml</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
进入busybox容器,查看文件内容<br><font color="#e74f4c">kubectl exec pod-command -n dev -it -c busybox /bin/sh</font><br>
命令解释
exec 进入容器
pod-command pod名称
-it 交互进入容器,并为容器分配一个终端
-c 容器名称 指定容器名称,容器名称通过配置文件中定义的名称进入
/bin/sh 容器内执行命令的程序
容器内部查看文件内容<br><font color="#e74f4c">ls tmp<br>cat tmp/hello.txt</font><br>
Pod基础---环境变量
env属性是用于设置容器环境变量的列表,环境变量的定义要根据容器具体需求定义
对env属性的案例演示
<font color="#e74f4c">vim pod-env.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-env.yml </font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
进入容器并查看变量<br><font color="#e74f4c">kubectl exec -it pod-env -n dev -c busybox /bin/sh</font><br>
Pod基础---端口设置
ports属性用于配置容器需要暴露的端口列表
对ports属性的案例演示
通过下边命令可以获取ports属性可以使用的子属性<br><font color="#e74f4c">kubectl explain pod.spec.containers.ports</font><br>
<font color="#e855a4">name 端口名称,如果指定,必须保证name在pod中是唯一的<br>containerPort 容器要监听的端口<br>hostPort 容器要在主机上公开的端口,如果设置,主机上只能运行容器的一个副本(一般省略)<br>hostIP 要将外部端口帮定到的主机IP(一般省略)<br>protocol 端口协议,必须是TCP、UDP或SCTP,默认为TCP</font>
创建pod-ports.yml文件,指定容器暴露的端口<br><font color="#e74f4c">vim pod-ports.yml </font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-ports.yml</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看pod描述信息<br><font color="#e74f4c">kubectl describe po pod-ports -n dev</font><br>
访问pod中的容器需要访问pod的IP加容器端口<br><font color="#e74f4c">curl http://10.244.196.171:80</font><br>
Pod基础---资源配额
resources属性用于限制容器对系统的资源的使用量(资源配额),避免容器出现问题大量吞噬系统资源,k8s目前提供了对内存和CPU的资源限制;当我们对容器配置资源限额以后,如果容器超出资源使用量,k8s则会认位该容器出现故障,则重新启动该容器。<br><br>
对resources属性的案例演示
resources属性提供了两个子属性用于资源限制,可通过下边命令查看
<font color="#e74f4c">kubectl explain pod.spec.containers.resources</font>
limits 用于限制容器运行时最大的资源使用量,当容器超出该使用量时,容器会被终止,并进行重启(上限)
requests 用于限制容器需要的最小资源,如果环境资源不够,容器将无法启动(下限)
编写pod-resources.yml文件,设置容器资源的上下限<br><font color="#e74f4c">vim pod-resources.yml</font><br>
这里对cpu与memory的单位做一个说明:
cpu:cpu数量可以为整数或小数
memory:内存大小,单位可以使用Gi、Mi、G、M等形式
创建pod<br><font color="#e74f4c">kubectl create -f pod-resources.yml</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看pod描述信息<br><font color="#e74f4c">kubectl describe po pod-resources -n dev</font><br>
Pod生命周期---概述
我们将pod从创建到终止的这段时间范围称为pod的生命周期,主要包含下面几个过程:
pod创建过程:创建pod的过程
运行初始化容器(init container)过程
运行主容器(maincontainer)过程:主容器也叫用户容器,在运行主容器时又有很多的子过程
容器启动后钩子(post start)函数执行的过程
容器终止前钩子(pre stop)函数执行的过程
容器的存活性探测(liveness probe)过程
容器就绪性探测(readiness probe)过程
pod终止过程
在整个pod的生命周期中,pod会出现5种状态,分别如下:
挂起状态(Pending):pod正在被调度到node节点或者正在下载镜像的过程
运行中(Running):pod已经被调度到node节点,并且所有容器都已经创建完成
成功(Succeeded):pod中的所有容器执行完毕并且都成功终止且不会被再次重启
失败(Failed):终止失败的容器处于该状态
未知(Unknown):apiserver无法正常获取到pod的状态信息,通常由于网络通信失败导致(少见)
pod创建过程
1.用户通过kubectl或其他的api客户端提交需要创建的pod信息给apiServer
2.apiServer开始生成pod对象的信息,并将信息存储到etcd数据库,然后返回确认信息至客户端
3.apiServer开始反映etcd中的pod对象的变化,其他组件使用watch机制来跟踪检查apiServer上的变动
4.scheduler发现有新的pod对象要创建,开始为pod分配主机并将结果信息更新至apiServer
5.node节点上的kubelet发现有pod调度过来,调用docker启动容器,并将结果返回至apiServer
6.apiServer将接收到的pod状态信息存入etcd中
pod终止过程
1.用户向apiServer发送删除pod对象的命令
2.apiServer会将该pod标记为termination(终止)状态
3.kubelet在监控到pod转为terminating状态的同时启动pod关闭过程
4.端点控制器监控到pod关闭以后,会从对应的service列表中移除该pod
5.如果当前pod对象定义了preStop钩子处理器,则执行preStop中的参数,如果用户没定义,则不执行
6.pod对象中的容器进程收到停止信号
7.宽限期结束后(默认30s),若pod中还存在运行的进程,那么pod对象会收到强制终止的信号
8.kubelet请求apiServer将此pod的宽限期设置为0从而完成删除操作,此时pod对于用户已不可见
Pod生命周期---初始化容器
初始化容器是在pod的主容器启动之前要运行的容器,我们称为初始化容器,主要是做一些主容器的前置工作
初始化容器有两大特征:
1.初始化容器必须运行完成,主容器才可以运行,若某初始化容器运行失败,那么k8s需要重启它,直到启动成功为止
2.初始化容器必须按照定义的顺序执行,前一个运行成功,后一个才能运行
初始化容器有很多的应用场景,下面列举几个常见的:
提供主容器镜像中不具备的工具程序或自定义代码
初始化容器要先于应用容器启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足
如下案例模拟上边第二个需求:
假设要以主容器来运行nginx,但是要求在运行nginx之前先要能够连接上MySQL与Redis所在的服务器
为了简化测试,事先定义好MySQL地址(192.168.18.20)和Redis地址(192.168.18.21)
创建pod-initcontainer.yml文件<br><font color="#e74f4c">vim pod-initcontainer.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-initcontainer.yml </font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
动态查看该pod信息:-w动态查看<br><font color="#e74f4c">kubectl get po pod-initcontainer -n dev -w</font><br>
接下来为集群中的master节点添加以上两个IP地址,添加以后初始化容器则可以ping通该地址<br><font color="#e74f4c">ifconfig ens192:1 192.168.18.20 netmask 255.255.255.0 up<br>ifconfig ens192:2 192.168.18.21 netmask 255.255.255.0 up</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
Pod生命周期---钩子函数
钩子函数能够感知自生命周期的时间,并在相应的时刻到来时,运行用户指定的程序代码
k8s在主容器的启动之后和终止之前提供了两个钩子函数:
post start:容器启动后钩子,定义在该钩子中的代码在容器启动后被执行,如果代码执行失败,会重启容器
pre stop:容器终止前钩子,定义在该钩子中的代码在容器终止前执行,代码执行完毕后,容器将被终止
钩子处理器支持定义动作可通过下边命令查看:
<font color="#e74f4c">kubectl explain pod.spec.containers.lifecycle</font>
钩子处理器支持三种方式定义动作,可通过下边命令查看
<font color="#e74f4c">kubectl explain pod.spec.containers.lifecycle.postStart<br>kubectl explain pod.spec.containers.lifecycle.preStop</font><br>
exec 在容器内执行一次命令<br><font color="#4ccbcd">lifecycle:<br> postStart:<br> exec:<br> command:<br> - cat<br> - /etc/passwd</font><br>
httpGet: 在当前容器中向某url发起http请求<br><font color="#4ccbcd">lifecycle:<br> postStart:<br> tcpSocket:<br> port: 8080</font><br>
tcpSocket: 在当前容器尝试访问指定的socket<br><font color="#4ccbcd">lifecycle:<br> postStart:<br> httpGet:<br> path: / URL地址<br> port: 80 端口号<br> host: 192.168.18.10 主机地址<br> Scheme: HTTP 支持的协议,HTTP/HTTPS</font><br>
提示:以上三种钩子处理器定义方式,第一种exec使用场景较多,本案例也已exec定义方式演示
创建pod<br><font color="#e74f4c">kubectl create -f pod-hook-exec.yml </font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po pod-hook-exec -n dev -o wide</font><br>
访问nginx页面<br><font color="#e74f4c">curl http://10.244.196.174:80</font><br>
Pod生命周期---容器探测
容器探测类似于健康检查,用来探测容器中的程序是否可以正常工作,如果探测到容器出现故障,k8s会尝试重启,如果重启失败,k8s不会将流量分配给该容器,不承担业务流量
k8s提供了两种探针来实现容器的探测,可通过下边命令查看<br><font color="#e74f4c">kubectl explain pod.spec.containers</font><br>
livenessProbe 存活性探针,用于检测容器当前是否处于正常运行状态,如果不是,k8s会重启该容器
<font color="#e74f4c">kubectl explain pod.spec.containers.livenessProbe</font>
readinessProbe 就绪性探针,用于检测容器当前是否可以接收请求,如果不能,k8s不会转发流量
<font color="#e74f4c">kubectl explain pod.spec.containers.readinessProbe</font>
FIELDS:<br><font color="#4ccbcd">exec 命令探测方式<br>tcpSocket 端口探测方式<br>httpGet URL 请求探测方式<br>initialDelaySeconds 容器启动后等待多少秒执行第一次探测<br>timeoutSeconds 探测超时时间,默认1秒,最小可设置1秒<br>failureThreshold 连续探测失败多少次才被认定失败,默认3次为失败,最小可设置1<br>periodSeconds 执行探测频率,默认是10秒,最小可设置1秒<br>successThreshold 连续探测成功多少次才被认定为成功,默认1次</font>
这里给大家介绍三种常用的探测方式:
exec:命令探测方式,在容器内执行一次命令,如果命令执行的退出码为0,则认位程序正常,否则不正常<br><font color="#4ccbcd">livenessProbe:<br> exec:<br> command:<br> - cat<br> - /etc/passwd</font><br>
tcpSocket:端口探测方式,访问容器的端口,如果能够建立连接,则认位程序正常,否则不正常<br><font color="#4ccbcd">livenessProbe:<br> tcpSocket:<br> port: 8080</font><br>
httpGet:调用容器内web应用的URL,如果返回的状态码在200与399之间,则为程序正常,否则不正常<br><font color="#4ccbcd">livenessProbe:</font><br> <font color="#4ccbcd">httpGet:</font><br> <font color="#4ccbcd">path:</font> <font color="#4ccbcd">/</font> <span class="tag">#URL地址</span><br> <font color="#4ccbcd">port:</font> <font color="#4ccbcd">80</font> <span class="tag">#端口号</span><br> <font color="#4ccbcd">host:</font> <font color="#4ccbcd">192.168.18.10</font> <span class="tag">#主机地址</span><br> <font color="#4ccbcd">Scheme:</font> <font color="#4ccbcd">HTTP</font> <span class="tag">#支持的协议,HTTP/HTTPS</span><br>
下面以livenessProbe存活性探针做使用的讲解
方式一:exec
创建pod-livenessProbe-exec.yml文件,并用探针在容器执行一条命令,如果命令执行成功,容器则正常<br><font color="#e74f4c">vim pod-livenessProbe-exec.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-livenessProbe-exec.yml </font><br>
查看pod信息(pod启动失败)<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看pod详细描述<br><font color="#e74f4c">kubectl describe po pod-livenessprobe-exec -n dev</font><br>
修改pod-livenessProbe-exec.yml文件,并用探针在容器执行一条成功的命令测试<br><font color="#e74f4c">vim pod-livenessProbe-exec.yml</font><br>
创建pod<font color="#e74f4c"><br>kubectl create -f pod-livenessProbe-exec.yml </font>
查看pod信息 PS:提示:pod属于正常运行状态,并没有出现重启<font color="#e74f4c"><br>kubectl describe pod pod-livenessprobe-exec -n dev</font>
方式二:tcpSocket
创建pod-livenessProbe-tcpSocket.yml文件,探测容器端口是否可以访问<br><font color="#e74f4c">vim pod-livenessProbe-tcpSocket.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-livenessProbe-tcpSocket.yml</font><br>
查看pod信息 提示:发现pod在重启<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看pod描述信息<br><font color="#e74f4c">kubectl describe po pod-livenessprobe-tpcsocket -n dev</font><br>
修改 pod-livenessProbe-tcpSocket.yml文件,指定探测端口为80<br><font color="#e74f4c">vim pod-livenessProbe-tcpSocket.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-livenessProbe-tcpSocket.yml</font><br>
查看pod信息 提示:pod属于正常运行状态,并没有出现重启<br><font color="#e74f4c">kubectl get po -n dev</font><br>
方式三:httpGet
创建pod-livenessProbe-httpGet.yml文件,探测容器内不存在的一个路径<br><font color="#e74f4c">vim pod-livenessProbe-httpGet.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-livenessProbe-httpGet.yml</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看pod描述信息 提示:HTTP探测失败,状态码404<br><font color="#e74f4c">kubectl describe po pod-livenessprobe-httpget -n dev</font><br>
修改pod-livenessProbe-httpGet.yml文件,探测一个存在的路径<br><font color="#e74f4c">vim pod-livenessProbe-httpGet.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-livenessProbe-httpGet.yml </font><br>
查看pod信息 提示:pod运行正常,并没有出现重启<br><font color="#e74f4c">kubectl get po -n dev</font><br>
Pod生命周期---重启策略
容器一旦出现了问题,K8s就会对容器所在的pod进行重启,重启操作是由pod的重启策略决定的,pod的重启策略有三种,可通过下边命令查看
kubectl explain pod.spec.restartPolicy
Always:容器失效时,自动重启该容器,默认策略
OnFailure:容器终止运行且退出码不为0时重启
Never:无论容器状态如何,都不重启该容器
重启策略适用于pod对象中的所有容器,首次需要重启的容器,将在其需要时立即进行重启,随后再次需要重启的操作将由kubelet延迟一段时间后进行,且反复的重启操作延时时长为10s、20s、40s、80s、160s、300s,最长延时为300s,以后重启延时均为300s,直至重启成功
创建pod-restartpolicy.yml,通过探针探测一个不存在的路径,然后设置重启策略为Never<br><font color="#e74f4c">vim pod-restartpolicy.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-restartpolicy.yml </font><br>
查看pod信息 PS:提示:发现该pod并没有出现重启,但是该pod并没有运行<br><font color="#e74f4c">kubectl create -f pod-restartpolicy.yml</font><br>
查看pod描述信息 PS:提示:HTTP探测失败,状态码404,停止了该容器,容器并没有出现重启<br><font color="#e74f4c">kubectl describe po pod-restartpolicy -n dev</font><br>
Docker$Kubernetes笔记---05---Pod调度&控制器
Pod调度---Pod调度概述
在默认情况下,一个pod被调度到哪个Node节点运行是由Scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的,但是在实际工作中,我们想要控制某些pod调度到指定的Node节点,就需要用到pod调度
k8s提供了四种调度方式:
自动调度:pod运行在哪个Node节点上,完全由Scheduler经过算法分配
定向调度:NodeName、NodeSelector
亲和性调度与反亲和性调度:NodeAffinity、PodAffinity、PodAntiAffinity
污点(容忍)调度:Taints、Toleration
Pod调度---Pod定向调度
定向调度是通过在pod上声明NodeName或者NodeSelector,以此将pod调度到指定的节点上,但是定向调度属于强制调度,即使指定的Node节点不存在,也会向该节点进行调度,只不过pod运行失败而已;定向调度方式其实是直接跳过了Scheduler的调度逻辑,直接将pod调度到指定名称的节点
nodeName调度介绍
实验:创建一个pod,并通过nodeName名称进行调度
<font color="#e74f4c">vim pod-nodename.yml</font>
提示:node节点名称是在定义集群时指定的,名称通过下边命令查看<br><font color="#e74f4c">kubectl get nodes</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-nodename.yml</font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po pod-nodename -n dev -o wide </font><br>
为了验证调度的准确性,我们指定一个不存在的nodeName节点,修改文件内容<br><font color="#e74f4c">vim pod-nodename.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-nodename.yml </font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po pod-nodename -n dev -o wide</font><br>
查看pod详细信息 <font color="#4ccbcd">PS:可以发现,定向调度属于强制调度,即使节点不存在,也会执行调度,只是pod会运行失败</font>
NodeSelector调度介绍
nodeSelector用于将pod调度到添加了指定标签的node节点上,是通过label-selector机制实现的,也就是说在pod创建之前,会由Scheduler使用MatchNodeSelector调度策略进行label匹配,找出目标node,然后将pod调度到目标节点,该调度规则也是强制调度
实验:先为node节点打标签,然后创建一个pod,并通过nodeSelector进行调度
为node1与node2节点打标签<br><font color="#e74f4c">kubectl label nodes node01 nodeenv=pro<br>kubectl label nodes node02 nodeenv=test</font><br>
查看nodes标签<br><font color="#e74f4c">kubectl get nodes --show-labels</font><br>
创建pod-nodeselector.yml文件<br><font color="#e74f4c">vim pod-nodeselector.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-nodeselector.yml </font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po pod-nodeselector -n dev -o wide</font><br>
为了验证调度的准确性,我们指定一个不存在的标签节点,修改文件内容<br><font color="#e74f4c">vim pod-nodeselector.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-nodeselector.yml</font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po pod-nodeselector1 -n dev -o wide</font><br>
提示:当前pod处于Pending挂起状态,应为没有找到相对应标签的节点;<font color="#4ccbcd">总结:定向调度方式使用比较方便,但是定向调度如果没有满足条件的Node,那么pod将运行失败,即使集群中还有可用的Node节点也没用,这就限制了使用场景</font>
Pod调度---Pod亲和性调度-nodeAffinity
Affinity亲和性调度它可以优先选择满足条件的Node进行调度,如果没有,也可以调度到不满足条件的节点上,使调度更加灵活
Affinity主要分为三类,可通过下边命令查看:
<font color="#e74f4c">kubectl explain pod.spec.affinity</font>
nodeAffinity(node亲和性):以node为目标,指定pod可以调度到哪些node上
podAffinity(pod亲和性):以pod为目标,指定pod可以和哪些已存在的pod部署在同一个节点上
podAntiAffinity(pod反亲和性):以pod为目标,指定pod不能和哪些pod部署在同一个节点上
关于亲和性与反亲和性调度使用场景说明:
亲和性:如果两个应用频繁交互,那就有必要利用亲和性让两个应用尽可能的在同一个节点,这样可以减少因网络原因带来的性能问题
反亲和性:当应用采用多副本部署时,那就有必要利用反亲和性让各个应用实例分散部署在不同的node节点,这样可以提高服务的高可用性
NodeAffinity的可配置属性可通过下边命令查看:<br><font color="#e74f4c">kubectl explain pod.spec.affinity.nodeAffinity</font><br>
requiredDuringSchedulingIgnoredDuringExecution 优先调度到满足指定的规则的Node节点,相当于硬限制
<font color="#4ccbcd">nodeSelectorTerms 节点选择列表</font><br><font color="#4ccbcd"> matchFields 按节点字段列出的节点选择器要求列表<br> matchExpressions 按节点标签列出的节点选择器要求列表(推荐)<br> key 键<br> values 值<br> operator 关系符(支持:Exists、DoesNotExist、In、NotIn、Gt、Lt)</font>
preferredDuringSchedulingIgnoredDuringExecution Node节点必须满足指定所有规则才可以,相当于软限制
<font color="#4ccbcd">preference 一个节点选择器项,与相应的权重相关联</font><br><font color="#4ccbcd"> matchFields 按节点字段列出的节点选择器要求列表<br> matchExpressions 按节点标签列出的节点选择器要求列表(推荐)<br> key 键<br> values 值<br> operator 关系符(支持:Exists、DoesNotExist、In、NotIn、Gt、Lt、weight 倾向权重,范围在1-100之间)</font>
关于关系符的说明:<br><font color="#4ccbcd">matchExpressions:<br> - key: nodeenv 匹配存在标签的key为nodeenv的节点<br> operator: Exists<br> - key: nodeenv 匹配存在标签的key为nodeenv,且value在“zzz”或“yyy”的节点<br> operator: In<br> values: ["zzz","yyy"]<br> - key: nodeenv 匹配标签的key为nodeenv,且value大于“xxx”的节点<br> operator: Gt<br> values: "xxx"</font><br>
实验:创建pod-nodeaffinity-required.yml文件,设置pod亲和度为硬限制
新建yaml文件<br><font color="#e74f4c">vim pod-nodeaffinity-required.yml</font><br>
创建pod <br><font color="#e74f4c">kubectl create -f pod-nodeaffinity-required.yml </font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看pod描述信息<br><font color="#e74f4c">kubectl describe po pod-nodeaffinity-required -n dev</font> <br>
查看nodes节点标签<br><font color="#e74f4c">kubectl get nodes --show-labels</font><br>
修改pod-nodeaffinity-required.yml文件,选择一个存在的valus进行调度<br><font color="#e74f4c">vim pod-nodeaffinity-required.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-nodeaffinity-required.yml </font><br>
查看pod描述信息<br><font color="#e74f4c">kubectl describe po pod-node-required -n dev</font><br>
实验:创建pod-nodeaffinity-preferred.yml 文件,设置pod亲和度为软限制
新建yaml文件<br><font color="#e74f4c">vim pod-nodeaffinity-preferred.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-nodeaffinity-preferred.yml </font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po pod-nodeaffinity-preference created -n dev -o wide</font><br>
PS:虽然没有找到要调度的标签节点,但是该pod被调度到一台正常的node节点上运行<br>
nodeAffinity规则设置注意事项:
如果同时定义了nodeSelector和nodeAffinity,那么必须两个条件都要满足,pod才能运行在指定的node上
如果nodeAffinity指定了多个nodeSelectorTerms,那么只需要其中一个能够匹配成功即可
如果一个nodeSelectoryTerms中有多个matchExpressions,则一个节点必须满足所有的才能匹配成功
如果一个pod所在的node在pod运行期间其标签发生了改变,不在符合该pod的节点亲和性需求,则忽略此变化
Pod调度---Pod亲和性调度-podAffinity
podAffinity主要实现以pod为参照,实现让新创建的pod与被参照的pod运行在同一个节点上
通过下边命令可以查看podAffinity的可配置项<br>kubectl explain pod.spec.affinity.podAffinity<br>
硬限制<br>
requiredDuringSchedulingIgnoredDuringExecution: <span class="tag">#硬限制</span><br> namespaces: <span class="tag">#指定参照pod的namespace</span><br> topologyKey: <span class="tag">#指定调度的作用域</span><br> labelSelector: <span class="tag">#标签选择器</span><br> matchExpressions: <span class="tag">#匹配节点标签(推荐)</span><br> key: <span class="tag">#键</span><br> values: <span class="tag">#值</span><br> operator: <span class="tag">#关系符(支持:Exists、DoesNotExist、In、NotIn、Gt、Lt)</span><br> matchLabels: <span class="tag">#指多个matchExpressions映射内容</span>
软限制
preferredDuringSchedulingIgnoredDuringExecution: <span class="tag">#软限制</span><br> podAffinityTerm: <span class="tag">#选项</span><br> namespaces: <span class="tag">#指定参照pod的namespace</span><br> topologyKey: <span class="tag">#指定调度的作用域</span><br> labelSelector: <span class="tag">#标签选择器</span><br> matchExpressions: <span class="tag">#匹配节点标签(推荐)</span><br> key: <span class="tag">#键</span><br> values: <span class="tag">#值</span><br> operator: <span class="tag">#关系符(支持:Exists、DoesNotExist、In、NotIn、Gt、Lt)</span><br> matchLabels: <span class="tag">#指多个matchExpressions映射内容</span><br> weight: <span class="tag">#倾向权重,在范围1-100之间</span>
topologyKey指定调度的作用域说明:
如果指定kubernetes.io/hostname <span class="tag">#以node节点名称为区分范围</span>
如果指定beta.kubernetes.io/os <span class="tag">#以node节点的操作系统类型来区分范围</span>
实验:接下来以硬限制演示调度方式
创建一个参照的pod<br><font color="#e74f4c">vim pod-podaffinity-target.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-podaffinity-target.yml </font><br>
查看pod详细信息,并显示标签<br><font color="#e74f4c"> kubectl get po pod-podaffinity-target -n dev -o wide --show-labels</font><br>
创建pod,并参照pod-podaffinity-target的标签进行调度<br><font color="#e74f4c">vim pod-podaffinity-required.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-podaffinity-required.yml </font><br>
查看pod详细信息;PS:发现pod状态属于Pending(挂起)状态<br><font color="#e74f4c">kubectl get po pod-podeaffinity-required -n dev -o wide</font><br>
删除该pod,并重新分配节点进行调度<br><font color="#e74f4c">kubectl delete -f pod-podaffinity-required.yml</font><br>
修改配置文件,指定一个存在的标签值进行调度;<font color="#4ccbcd">PS:这个标签值可以只写values: ["pro"];这里或者的关系,符合其中一个即可</font><br><font color="#e74f4c">vim pod-podaffinity-required.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-podaffinity-required.yml </font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po pod-podaffinity-required -n dev -o wide</font><br>
PS:发现该pod已经被调度到所倾向的pod节点
Pod调度---Pod反亲和性调度-podAntiAffinity
podAntiAffinity(反亲和性调度)主要实现以运行的pod为参照,让新创建的pod跟参照的pod不在同一个区域中
podAntiAffinty的配置属性与上边podAffinity配置属性是一样的,就不重复讲解了。
实验:继续使用上一个案例中的pod-podaffinity-target作为参照,配置pod反亲和性调度
查看当前pod的标签<br><font color="#e74f4c">kubectl get po pod-nodeaffinity-target -n dev --show-labels</font><br>
创建pod-podantiaffinity-required.yml<br><font color="#e74f4c">vim pod-podantiaffinity-required.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-podantiaffinity-required.yml</font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po pod-podantiaffinity-required -n dev -o wide</font><br>
提示:可以发现,该pod被调度到了node2节点上
Pod调度---Pod调度污点-Taints
前面的调度方式都是站在pod的角度上,通过在pod上添加属性,来确定pod是否要调度到指定的node上,其实我们也可以站在node的角度上,通过在node上添加污点属性,来决定是否允许pod调度过来;node被设置上污点以后,就和pod之间存在了一种相互排斥的关系,进而拒绝pod调度进来,甚至可以将已经存在的pod驱逐出去。
污点的格式:key=value:污点,key和value是污点的标签,目前支持如下三个污点:
PreferNoSchedule:k8s将尽量避免把pod调度到具有该污点的node上,除非没有其他节点可调度
NoSchedule:k8s将不会把pod调度到具有该污点的node上,但不会影响当前node上已经存在的pod
NoExecute:k8s将不会把pod调度到具有该污点的node上,同时也会将node上已经存在的pod隔离
使用kubectl设置和去除污点的命令实例如下
设置污点<br><font color="#e74f4c">kubectl taint nodes node1 key=value:污点</font><br>
去除污点<br><font color="#e74f4c">kubectl taint nodes node1 key:污点-</font><br>
去除所有污点<br><font color="#e74f4c">kubectl taint nodes node1 key-</font><br>
实验描述:
实验步骤
1. 为了演示污点的效果更加明显,暂时停止node2节点,node2节点关机即可
2. 为node1节点设置一个污点:tag=abc:PreferNoSchedule;然后创建pod1
3. 修改node1污点为:tag=abc:NoSchedule;然后创建pod2
4. 修改node1污点为:tag=abc:NoExecute;然后创建pod3
查看node节点状态<br><font color="#e74f4c">kubectl get nodes</font><br>
为node1设置污点为PreferNoSchedule<br><font color="#e74f4c">kubectl taint nodes node1 tag=abc:PreferNoSchedule</font><br>
查看node1污点信息<br><font color="#e74f4c">kubectl describe nodes node1</font><br>
创建pod1<br><font color="#e74f4c">kubectl run taint1 --image=nginx:1.17.1 -n dev</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
为node1取消PreferNoSchedule污点,并重新设置污点为NoSchedule<br><font color="#e74f4c">kubectl taint nodes node1 tag:PreferNoSchedule-<br>kubectl taint nodes node1 tag=abc:NoSchedule</font><br>
创建pod2<br><font color="#e74f4c">kubectl run taint2 --image=nginx:1.17.1 -n dev</font><br>
查看pod信息 PS:可以发现当前的pod状态为Pending(挂起状态),而原有的pod并没有受到影响<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看node1污点信息<br><font color="#e74f4c">kubectl describe nodes node1</font><br>
为node1取消NoSchedule污点,并重新设置污点为NoExecute<br><font color="#e74f4c">kubectl taint nodes node1 tag:NoSchedule-<br>kubectl taint nodes node1 tag=abc:NoExecute</font><br>
创建pod3节点<br><font color="#e74f4c">kubectl run taint3 --image=nginx:1.17.1 -n dev</font><br>
查看pod状态<br><font color="#e74f4c">kubectl get po -n dev</font><br>
使用kubeadm搭建的集群,默认就会给master节点添加一个污点,所以pod不会被调度到master节点<br><font color="#e74f4c">kubectl describe nodes master</font><br>
Pod调度---Pod调度容忍-Toleration
上章节讲解了污点的作用,可以通过在node节点添加污点用于拒绝pod调度上来,但如果我们非要将一个pod调度到一个有污点的node上,通过容忍(忽略)可以实现
实验:上章节我们为node1节点打上了一个NoExecute的污点,此时pod是调度不上去的,我们通过为pod添加容忍,然后将pod调度到node1节点
新增配置文件<br><font color="#e74f4c">vim pod-toleration.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f pod-toleration.yml</font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po -n dev -o wide</font><br>
Pod控制器---Pod控制器概述
在k8s中,pod的创建方式分为两类
自主式pod:k8s直接创建出来的pod,这种pod删除后就没有了,也不会重建
控制器创建的pod:通过控制器创建的pod,这种pod删除了还会自动重建
Pod控制器
pod控制器是管理pod的中间层,使用了pod控制器之后,我们只需要告诉pod控制器,需要多少个什么样的pod就可以了,它就会创建出满足条件的pod,并确保每一个pod处于用户期望的状态,如果pod在运行中出现故障,控制器会基于指定的策略重新启动或重建pod
在k8s中,pod控制器的种类有很多,每种pod控制器的应用场景都不一样,常见的有下面这些
ReplicationController:比较原始的pod控制器,目前已经被废弃,由ReplicaSet代替
ReplicaSet:保证指定数量的pod运行,并支持pod数量变更,镜像版本变更
Deployment:通过控制ReplicaSet来控制pod,包含ReplicaSet所有功能,还支持滚动升级,版本回退
Horizontal Pod Autoscaler:可以根据集群负载自动调整pod数量,实现pod容缩
DaemonSet: 确保全部(或者一些)Node 上运行一个 Pod 的副本,当有 Node 加入集群时,也会为他们新增一个 Pod ,当有 Node 从集群移除时,这些 Pod 也会被回收,删除 DaemonSet 将会删除它创建的所有 Pod
Job:它创建的pod只要完成就立即退出
容器按照持续运行的时间可分为两类:服务类容器和工作类容器
服务类容器通常持续提供服务,需要一直运行,比如 **http server**,**daemon** 等
工作类容器则是一次性任务,比如批处理程序,完成后容器就退出
Cronjob:它创建的pod会周期性的执行,用于执行周期性任务(常用在数据备份工作)
StatefulSet:管理有状态应用
Pod控制器---Pod控制器-ReplicaSet(RS)
ReplicaSet的主要作用是保证一定数量的pod能够正常的运行,它会持续监听这些pod的运行状态,一旦pod发生故障,就会重启或重建pod,同时还支持对pod数量的扩缩容和版本镜像的升级
ReplicaSet的资源清单文件介绍:在下面配置中,需要了解的配置项是spec下面的配置项
创建rs-replicaset.yml文件<br><font color="#e74f4c">vim rs-replicaset.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f rs-replicaset.yml </font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
查看pod控制器详细信息<br><font color="#e74f4c">kubectl get rs rs-replicaset -n dev -o wide</font><br>
ReplicaSet 扩缩容功能
第一种方式
通过edit(配置文件形式)可直接修改pod的副本数量<br><font color="#e74f4c">kubectl edit rs rs-replicaset -n dev</font><br>
直接根据需求修改pod的副本数量即可<br><font color="#e74f4c">replicas: 6</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
第二种方式
直接通过scale命令修改rs的副本数量,--replicas=副本数量<br><font color="#e74f4c">kubectl scale rs rs-replicaset --replicas=3 -n dev</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
ReplicaSet 镜像版本升级
第一种方式
通过edit(配置文件形式)可直接修改镜像版本<br><font color="#e74f4c">kubectl edit rs rs-replicaset -n dev</font><br>
查看rs详细信息<br><font color="#e74f4c">kubectl get rs rs-replicaset -n dev -o wide</font><br>
第二种方式
通过命令修改:set image rs rs名称 容器名=镜像版本 -n namespace<br><font color="#e74f4c">kubectl set image rs rs-replicaset nginx=nginx:1.17.1 -n dev</font><br>
查看rs详细信息<br><font color="#e74f4c">kubectl get rs rs-replicaset -n dev -o wide</font><br>
删除ReplicaSet
使用delete命令可以删除此rs以及它管理的所有pod,也可以通过配置文件删除;删除的过程先将pod数量调整为0,然后在执行删除pod操作,在删除rs
命令删除方式
<font color="#e74f4c">kubectl delete rs rs-replicaset -n dev</font>
查看rs信息<br><font color="#e74f4c">kubectl get rs -n dev</font><br>
配置文件删除方式
<font color="#e74f4c">kubectl delete -f rs-replicaset.yml</font>
查看rs信息<br><font color="#e74f4c">kubectl get rs -n dev</font><br>
Pod控制器---Pod控制器-Deployment基础
为了更好的解决服务编排问题,k8s在v1.2版本开始,引入了Deployment(Deploy)控制器,该pod控制器不会去直接管理pod,而是通过管理ReplicaSet来间接的管理pod,所以Deployment比ReplicaSet功能更强大
Deployment功能如下
支持ReplicaSet所有功能
支持发布的停止、继续
支持版本滚动更新和版本回退
Deployment的资源清单文件介绍:
通过deployment.yml文件创建基本的pod<br><font color="#e74f4c">vim deployment.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f deployment.yml </font><br>
查看deploy详细信息<br><font color="#e74f4c">kubectl get deploy -n dev<br>kubectl get deploy -n dev -o wide</font><br><font color="#4ccbcd">PS:UP-TO-DATE:最新版本的pod数量;AVAILABLE:当前可用的pod数量</font><br>
查看rs控制器信息,应为deploy通过控制rs管理pod,所以rs控制器也会被创建出来<br><font color="#e74f4c">kubectl get rs -n dev <br></font><font color="#4ccbcd">PS:rs控制器的名称是在deploy基础上随机添加</font>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br><font color="#4ccbcd">PS:pod名称是在rs基础上随机添加</font>
Pod控制器---Pod控制器-Deployment扩缩容
Deployment控制器在对pod进行扩缩容时,可以通过命令与配置文件方式实现
通过命令扩容pod数量<br><font color="#e74f4c">kubectl scale deploy deployment --replicas=6 -n dev</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
通过edit(修改配置文件)方式缩减pod数量<br><font color="#e74f4c">kubectl edit deploy deployment -n dev</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
Pod控制器---Pod控制器-Deployment更新策略
Deployment支持两种镜像更新的策略:通过strategy属性进行配置
Recreate:重建更新策略,一次性将所有旧版本pod全部重建成新版本pod
RollingUpdat:滚动更新策略(默认策略),先删除一部分旧版本pod,在更新成新版本pod
Recreate:重建更新策略配置
修改deployment.yml文件,在spec属性下添加Recreate策略<br><font color="#e74f4c">vim deployment.yml</font><br>
更新pod<br><font color="#e74f4c">kubectl apply -f deployment.yml</font><br>
更新镜像版本<br><font color="#e74f4c">kubectl edit deploy deployment -n dev</font><br>
观察pod的重建过程 <font color="#4ccbcd">PS:在开一个终端动态观察pod的信息</font><br><font color="#e74f4c">kubectl get po -n dev -w</font><br>
第一步:会将运行的pod先终止(Terminating)
第二步:pod接下来处于等待状态(Pending)
第三步:重新创建容器
第四步:新的容器被创建且以成功运行(Running )
查看镜像版本<br><font color="#e74f4c">kubectl get deploy -n dev -o wide</font><br>
RollingUpdat:滚动更新策略(默认策略)
修改deployment.yml文件,在spec属性下设置RollingUpdat策略<br><font color="#e74f4c">vim deployment.yml</font><br>
更新pod<br><font color="#e74f4c">kubectl apply -f deployment.yml</font><br>
另外一个终端动态查看pod信息<br><font color="#e74f4c">kubectl get po -n dev -w<br></font><font color="#4ccbcd">PS:这里起了三个新的pod,依次先起一个然后再关闭一个</font>
更新镜像版本<br><font color="#e74f4c">kubectl edit deploy deployment -n dev</font><br><font color="#4ccbcd">PS:动态观察pod滚动更新过程;当pod滚动更新后,rs也会随之跟着更新,原有的rs中的pod会被删除</font>
查看rs信息<br><font color="#e74f4c">kubectl get rs -n dev </font><br><font color="#4ccbcd">PS:原有的rs并不会删除,用于做版本回退</font>
Pod控制器---Pod控制器-Deployment版本回退
deployment支持版本升级过程中的暂停、继续、回退等功能,具体功能如下:
kubectl rollout: 版本升级相关功能,支持下面的选项:
status <span class="tag">#显示当前升级状态</span>
history <span class="tag">#显示升级历史记录</span>
pause <span class="tag">#暂停版本升级过程</span>
resume <span class="tag">#继续已经暂停的版本升级过程</span>
restart <span class="tag">#重启版本升级过程</span>
undo <span class="tag">#回滚到上一级版本(可以通过--to-revision回滚到指定版本)</span>
显示当前升级版本的状态<br><font color="#e74f4c">kubectl rollout status deploy deployment -n dev</font><br>
显示升级历史记录<br><font color="#e74f4c">kubectl rollout history deploy deployment -n dev</font><br>
为了让效果更加明显,我们可以删除该pod,在重新通过--record创建pod<br><font color="#e74f4c">kubectl delete -f deployment.yml </font><br>
创建pod<br><font color="#e74f4c">kubectl create -f deployment.yml --record</font><br>
更新镜像版本<br><font color="#e74f4c">kubectl edit deploy deployment -n dev</font><br>
再次更新镜像版本<br><font color="#e74f4c">kubectl edit deploy deployment -n dev</font><br>
查看升级历史记录<br><font color="#e74f4c">kubectl rollout history deploy deployment -n dev</font><br>
查看当前所有版本(通过rs可以查看)<br><font color="#e74f4c">kubectl get rs -o wide -n dev</font><br>
查看当前使用版本(查看deploy)<br><font color="#e74f4c">kubectl get deploy -o wide -n dev</font><br>
版本回退:通过--to-revision=1,可直接回滚到1版本,如果省略这个选项,就是回退到上个版本<br><font color="#e74f4c">kubectl rollout undo deploy deployment --to-revision=1 -n dev</font><br>
查看当前使用的版本<br><font color="#e74f4c">kubectl get deploy -o wide -n dev</font><br>
查看升级历史记录<br><font color="#e74f4c">kubectl rollout history deploy deployment -n dev<br></font><font color="#4ccbcd">PS:发现没有1版本了,多了个4版本,4版本就是原先的1版本</font>
Pod控制器---Pod控制器-Deployment金丝雀发布
Deployment支持更新过程中的控制,如:暂停更新(pause),继续更新(resume)
应用场景类似于灰度发布
当需要对现有的一批pod进行升级时,当有一小部分pod已经升级到新版本,此时可以通过**暂停更新**阻止所有pod全部升级,此时会有一部分pod已经升级到新版本,而还有一部分pod仍然是原有的版本,这时可以将用户的请求路由到新版本的pod中,测试新版本pod是否稳定运行,确定新版本pod没有问题以后,在继续升级剩余的pod,否则立即回滚到旧版本。
通过命令更新pod的版本,并通过暂停更新阻止所有pod全部升级<br><font color="#e74f4c">kubectl set image deploy deployment nginx=nginx:1.21.1 -n dev && kubectl rollout pause deploy deployment -n dev</font><br>
查看更新状态<br><font color="#e74f4c">kubectl rollout status deploy deployment -n dev</font><br>
在开一个终端查看rs信息<br><font color="#e74f4c">kubectl get rs -n dev</font><br>
继续更新<br><font color="#e74f4c">kubectl rollout resume deploy deployment -n dev</font><br>
查看rs信息<br><font color="#e74f4c">kubectl get rs -n dev</font><br>
删除Deployment,rs与pod也同时会被删除<br><font color="#e74f4c">kubectl delete -f deployment.yml</font><br>
查看rs<br><font color="#e74f4c">kubectl get rs -n dev</font><br>
查看Deployment<br><font color="#e74f4c">kubectl get deploy -n dev</font><br>
Pod控制器---Pod控制器-HPA
Horizontal Pod Autoscaler(HPA)可以获取每个pod的资源利用率,然后和HPA中定义的资源利用率指标进行对比,同时计算出需要伸缩的具体值,最后实现pod的数量的自动(非手动)调整,其实HPA与之前的Deployment一样,也属于一种k8s资源对象,它通过追踪分析目标pod的负载变化情况,来确定是否需要针对性的调整目标pod的副本数量;HPA可以实现pod数量的自动扩缩容,对比于前边手动对pod数量进行调整,HPA更加的智能
实验:安装metrics-server可以用来收集集群中的资源使用情况 <font color="#4669ea"> ----这个实验先搁置下,原本的metrics-server版本与当前k8s版本不兼容,需要下载新版本,但是新版本的启动文件与老的不太一样,待后面再研究下如何操作,下载连接:https://github.com/kubernetes-sigs/metrics-server/releases/tag/v0.6.3</font>
下载metrics-server软件<br><font color="#e74f4c">kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.6.4/components.yaml</font><br><font color="#4ccbcd">PS:这边要下载与当前K8S对应版本的metrics,不然会提示版本兼容问题</font>
解压软件包&&进入解压后路径<br>
编辑metrics-server-deployment.yaml文件<br><font color="#4ccbcd">PS:1.metrics-server默认使用的是主机名方式访问kubelet,但是在集群DNS解析记录中并没有三台物理机器的主机名,需要改为使用主机IP地址;<br>2.验证客户端证书的问题,需要改为不验证;<br></font>
vim metrics-server-deployment.yaml
执行命令,安装metrics-server<br>kubectl apply -f ./<br>
查看pod运行状态<br>kubectl get po -n kube-system<br>
查看node资源使用情况:kubectl top node/pod<br>kubectl top node<br>
查看pod资源使用情况<br>kubectl top pod -n kube-system<br>
准备deployment和service
创建deployment<br><font color="#e74f4c">vim nginx-pod.yaml</font><br>
查看deploy信息<br><font color="#e74f4c">kubectl get deploy,pod -n dev</font><br>
创建service,暴露service端口<br><font color="#e74f4c">kubectl expose deployment nginx --type=NodePort --port=80 -n dev</font><br>
查看svc信息<br><font color="#e74f4c">kubectl get svc -n dev</font><br>
部署HPA
通过下边命令可以获取HPA支持的配置属性<br>kubectl explain HorizontalPodAutoscaler.spec<br>
创建hpa.yml文件<br>vim hpa.yml<br>
创建hpa<br><font color="#e74f4c">kubectl create -f hpa.yml</font><br>
查看hpa信息<br><font color="#e74f4c">kubectl get hpa -n dev</font><br>
另开终端动态查看deploy信息<br><font color="#e74f4c">kubectl get deploy -n dev -w</font><br>
另开终端动态查看pod信息<br><font color="#e74f4c">kubectl get po -n dev -w</font><br>
另开终端动态查看hpa信息<br><font color="#e74f4c">kubectl get hpa -n dev -w</font><br>
Pod控制器---Pod控制器-DaemonSet
DaemonSet(DS)控制器可以保障集群中的每一个(或指定)节点上都运行一个副本,如果一个pod提供的功能是节点级别的(每个节点都需要且只需要一个),一般适用于日志收集,节点监控场景,这种类型的pod就适合使用DaemonSet类型的控制器创建<br>
DaemonSet控制器的特点:
每当像集群添加一个节点时,指定的pod副本也将添加到该节点上
当节点从集群中移除时,pod也就被垃圾回收
DaemonSet资源清单介绍
实验:创建daemonset.yml文件
创建daemonset.yml文件<br><font color="#e74f4c">vim daemonset.yml</font><br>
创建pod<br><font color="#e74f4c">kubectl create -f daemonset.yml</font><br>
查看ds信息<br><font color="#e74f4c">kubectl get ds -n dev</font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po -n dev -o wide</font><br>
删除ds<br><font color="#e74f4c">kubectl delete -f daemonset.yml </font><br>
Pod控制器---Pod控制器-Job<br>
前边的控制器作用都是需要持续运行pod,如果只想运行完成工作后就终止的任务,job控制器主要负责处理仅运行一次就终止的pod
job特点如下
当job创建的pod执行成功结束时,job将记录成功结束的pod数量
当成功结束的pod达到指定的数量时,job将完成执行
应用场景
可以用来做数据备份,执行一次备份就结束任务
job的资源清单文件:
关于重启策略配置说明:
OnFailure(失败重启):则job会在pod出现故障时重启容器,而不是创建pod,failed次数不变
Never(失败不重启):则job会在pod出现故障时创建新的pod,并且故障pod不会消失,也不会重启,failed次数加1
Always(一直重启):就一直重启pod,就意味着job任务会重复去执行,所以不能设置为Always
实验:创建job.yml文件
创建job.yml文件<br><font color="#e74f4c">vim job.yml</font><br>
创建pod(可提前查看动态pod创建过程)<br><font color="#e74f4c">kubectl create -f job.yml </font><br>
动态查看job信息<br><font color="#e74f4c">kubectl get job -n dev -w</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br><font color="#4ccbcd">PS:提示:发现容器以执行完成,当前状态为Completed(完成状态)</font>
删除job控制器<br><font color="#e74f4c">kubectl delete -f job.yml </font><br>
Pod控制器---Pod控制器-Cronjob
CronJob(CJ)控制器通过控制job控制器管理pod资源,CronJob可以在指定的时间去运行pod
CronJob的资源清单文件:
实验:创建cronjob.yml文件
创建cronjob.yml文件<br><font color="#e74f4c">vim cronjob.yml</font><br>
创建cronjob(可提前动态查看pod、job、cronjob信息)<br><font color="#e74f4c">kubectl create -f cronjob.yml </font><br>
动态查看pod、job、cronjob信息<br><font color="#e74f4c">kubectl get cj -n dev -w<br>kubectl get po -n dev -w<br>kubectl get job -n dev -w</font><br>
删除cronjob<br><font color="#e74f4c">kubectl delete -f cronjob.yml</font><br><font color="#4ccbcd">总结:job只能运行一次性任务,而cronjob可以定义时间点去指定指定的任务</font><br>
Docker$Kubernetes笔记---06---k8s Service&Ingress
k8s的流量负载组件:
Service:Service用于4层流量的负载
ingress:ingress用于7层流量负载
Service---概述
在k8s中,pod是应用程序的载体,我们可以通过pod的IP访问容器中的应用程序,但是pod的IP地址不是固定的,所以不方便使用pod的IP进行访问服务;而Service可以对提供同一类服务的多个pod进行聚合,并提供一个统一的入口地址,这个地址在整个Service的生命周期中是不变的,通过Service的入口地址就能访问到后面的pod服务
Service在很多情况下只是一个概念,真正起作用的其实是kube-proxy服务进程,每个节点都运行着一个kube-proxy的服务进程,当创建Service的时候,会通过api-server向etcd写入创建的service的信息,而kube-proxy会基于监听的机制发现这种Service的信息,然后会**将最新的Service信息转换成对应的访问规则**,该规则在所有的集群节点都会生成,最终通过访问规则进行流量转发。<br>
kube-proxy目前支持三种工作模式:
userspace模式:最原始的转发模式,该模式在转发处理时会增加内核与用户空间的数据拷贝操作,转发效率低,已经很少用(作为了解)
iptables模式:该模式下kube-proxy不承担四层负载均衡器的角色,只创建iptables规则,然后用户的请求直接通过iptables转发规则被转发到后端的每个Pod中,但iptables模式不能提供灵活的负载均衡策略,只是随机的将流量转发到后端的Pod,当后端Pod不可用时也无法进行健康检查
ipvs(Virtual Server)模式:ipvs与iptables类似,kube-proxy也不承担四层负载均衡器的角色,只创建ipvs规则,然后用户的请求直接通过ipvs转发规则被转发到后端的每个Pod中,但是ipvs在转发时支持的负载均衡算法非常的灵活,例如轮询、随机、加权轮询、基于端口转发等
想要使用ipvs转发模式需要安装ipvs内核模块,否则会降级为iptables模式
查看ipvs模块(在第一章集群环境部署时已经安装)<br><font color="#e74f4c">lsmod | grep -e ip_vs -e nf_conntrack_ipv4</font><br>
开启ipvs,编辑kube-proxy文件 <font color="#4ccbcd">PS:修改为ipvs模式</font><br><font color="#e74f4c">kubectl edit cm kube-proxy -n kube-system</font><br><font color="#4ccbcd">PS:cm(cmconfigmaps)在K8s中属于配置资源</font>
删除当前正在使用的kube-proxy的pod(按照标签删除)<br><font color="#e74f4c">kubectl delete po -l k8s-app=kube-proxy -n kube-system</font><br>
查看kube-proxy的pod是否被重建<br><font color="#e74f4c">kubectl get po -n kube-system</font><br>
查看ipvs功能是否开启<br><font color="#e74f4c">ipvsadm -Ln</font><br>
Service---资源清单文件介绍
可通过 kubectl explain service查看service资源支持的属性
service的四种访问方式介绍
ClusterIP:默认访问方式,由k8s自动分配的虚拟IP,只能在集群内部访问
NodePort:将service通过指定的Node上的端口暴露给外部,通过此方式,就可以在集群外部访问服务
LoadBalancer:使用外接负载均衡器完成到服务的负载均衡分发,注意此模式需要外部云环境支持
ExternalName:把集群外部的服务引入集群内部,直接使用
实验:通过Deployment创建3个pod并设置标签为app=nginx-pod(使用前面的deployment.yml创建即可)
创建deployment.yml文件<br><font color="#e74f4c">vim deployment.yml</font><br>
创建deploy<br><font color="#e74f4c">kubectl create -f deployment.yml</font><br>
查看pod详细信息<br><font color="#e74f4c">kubectl get po -n dev -o wide</font><br>
为了更好的验证用户请求被分配到哪个pod中,修改3个pod中的nginx默认首页<br><font color="#e74f4c">kubectl exec -it deployment-6696798b78-6zl8p -n dev /bin/bash<br>echo "10.244.1.44" > /usr/share/nginx/html/index.html</font><br>
访问3个pod测试<br><font color="#e74f4c">curl http://10.244.196.129:80</font><br>
Service---ClusterIP类型
ClusterIP:默认访问方式,由k8s自动分配的虚拟IP,只能在集群内部访问
创建service-clusterip.yml文件<br><font color="#e74f4c">vim service-clusterip.yml</font>
创建service<br><font color="#e74f4c">kubectl create -f service-clusterip.yml </font><br>
查看service信息<br><font color="#e74f4c">kubectl get svc service -n dev</font><br>
查看service详细描述<br><font color="#e74f4c">kubectl describe svc service -n dev</font><br>
查看ipvs的映射规则 <font color="#4ccbcd">PS:rr为默认轮询策略:当service接收到请求后,会通过轮询算法将请求分配到对应的三个pod中</font><br>i<font color="#e74f4c">pvsadm -Ln</font><br>
访问测试
删除service<br><font color="#e74f4c">kubectl delete -f service-clusterip.yml </font><br>
总结:ClusterIP的访问方式只能用在集群内部主机之间访问,集群外部主机没办法访问<br><font color="#4ccbcd">PS:这边测试的时候用到了上面创建的三个pod作为测试</font>
Service---HeadLiness类型
在某些场景下,开发人员如果不想使用Service提供的负载均衡功能,而希望自己来控制负载均衡策略,针对这样的情况,k8s提供了HeadLiness,HeadLiness不会分配Cluster IP,如果想要访问Service,只能通过Service的域名进行访问<br>
创建service-headliness.yml文件<br><font color="#e74f4c">vim service-headliness.yml</font><br>
创建headliness<br><font color="#e74f4c">kubectl create -f service-headliness.yml</font> <br>
查看headliness<br><font color="#e74f4c">kubectl get svc service-headliness -n dev</font><br>
查看headliness描述信息<br><font color="#e74f4c">kubectl describe svc service-headliness -n dev</font><br>
进入容器查看当前容器使用的DNS解析地址<br><font color="#e74f4c">kubectl get po -n dev<br>kubectl exec -it deployment-6696798b78-6zl8p -n dev /bin/bash</font><br>
安装dig命令;PS:使用dig命令通过DNS服务器地址加上headliness名称与search名称进行访问<br><font color="#e74f4c">yum -y install bind-utils</font><br>
访问<br><font color="#e74f4c">dig @10.96.0.10 service-headliness.dev.svc.cluster.local</font><br>
Service---NodePort类型
前边创建的service只能用于在集群内部访问,但是在生产环境中,service是需要暴露给外部访问的,如果希望将service暴露给集群访问,那么就要用到NodePort类型的service,NodePort的工作原理其实就是将service的端口映射到Node的一个端口上,然后外部主机就可以通过NodeIP:NodePort来访问集群中的pod了<br>
实验:创建service-nodeport.yml文件<br><font color="#e74f4c">vim service-nodeport.yml</font><br>
创建service<br><font color="#e74f4c">kubectl create -f service-nodeport.yml </font><br>
查看service信息<br><font color="#e74f4c">kubectl get svc -n dev</font><br>
外部主机访问测试(通过宿主机主机IP加service端口,此时访问集群中任何一台节点IP都可以)<br><font color="#e74f4c">http://192.168.1.197:30000</font><br>
Service---Service之LoadBalancer类型
LoadBalancer和NodePort类似,目的都是向外部暴露一个端口,区别在于LoadBalancer会在集群外部在做一个负载均衡设备,而这个设备需要外部环境支持,外部服务器发送到这个设备的请求,会被设备负载之后转发到集群中<br>
Service---Service之ExternaIName类型
ExternaIName用于引入集群外部的服务,它通过externaIName属性指定外部一个服务的地址,然后在集群内部访问此service就可以访问到外部服务了
实验:创建service-externalname.yml<br><font color="#e74f4c">vim service-externalname.yml</font><br>
创建service<br><font color="#e74f4c">kubectl create -f service-externalname.yml</font><br>
查看service<br><font color="#e74f4c">kubectl get svc -n dev</font><br>
域名解析<br><font color="#e74f4c">dig @10.96.0.10 service-externalname.dev.svc.cluster.local</font><br>
Ingress---Ingress介绍
在前面的章节中通过通过Service对集群之外暴露服务的主要方式有两种:
NotePort:该方式的缺点是会占用很多集群机器的端口,当集群服务变多时,这个缺点就愈发的明显
LoadBalancer:该方式的缺点是每个service都需要一个外部负载均衡设备的支持才可以
基于这种现状,k8s提供了ingress资源对象,ingress只需要一个NodePort或者一个负载均衡设备就可以满足暴露多个service的需求
实际上Ingress相当于一个7层的负载均衡器,是k8s对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解成Ingress里建立诸多映射规则,Ingress Colltroller通过监听这些配置规则并转化成Nginx的反向代理配置,然后对外部提供服务,在这里有两个核心理念:
Ingress:k8s中的一个对象,作用是定义请求如何转发到service的规则
Ingress controller:具体实现反向代理及负载均衡的程序,对Ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现方式有很多,比如Nginx,Contour,Haproxy等等
Ingress(以nginx为例)的工作原理
1.用户编写Ingress规则,说明哪个域名对应K8s集群中的Service
2.Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx反向代理配置
3.Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新
4.到此为止,其实真正工作的就是一个Nginx了,内部配置了用户定义的请求转发规则
Ingress---ingress环境搭建
搭建ingress环境,先部署ingress-nginx控制器
到github中下载对应kubernetes版本的ingress-nginx版本<br><font color="#e74f4c">https://github.com/kubernetes/ingress-nginx/tags</font><br>
进入到对应的目录下通过yaml文件方式安装控制器<br><font color="#e74f4c">ingress-nginx-controller-v1.9.5/deploy/static/provider/cloud/</font><br>
创建ingress-nginx<br><font color="#e74f4c">kubectl apply -f deploy.yaml </font><br>
查看ns(会有一个ingress-nginx的名称空间产生)<br><font color="#e74f4c">kubectl get ns</font><br>
查看ingress-nginx名称空间的pod<br><font color="#e74f4c">kubectl get po -n ingress-nginx</font><br>
查看service<br><font color="#e74f4c">kubectl get svc -n ingress-nginx</font><br>
部署tomcat与nginx的pod,通过tomcat-nginx.yml文件创建
yml文件创建<br><font color="#e74f4c">vim tomcat-nginx.yml</font><br>
为了避免前边创建的nginx-pod存在,先删除dev名称空间<br><font color="#e74f4c">kubectl delete ns dev</font><br>
创建dev名称空间<br><font color="#e74f4c">kubectl create ns dev</font><br>
创建svc与pod<br><font color="#e74f4c">kubectl create -f tomcat-nginx.yml </font><br>
查看svc信息<br><font color="#e74f4c">kubectl get svc -n dev</font><br>
查看pod信息<br><font color="#e74f4c">kubectl get po -n dev</font><br>
Ingress---Ingress-HTTP代理
通过ingress代理http服务,创建ingress-http.yml<br><font color="#e74f4c">vim ingress-http.yml</font><br>
创建ingress<br><font color="#e74f4c">kubectl create -f ingress-http.yml </font><br>
查看ingress信息<br><font color="#e74f4c">kubectl get ing ingress-http -n dev</font><br>
查看详细描述<br><font color="#e74f4c">kubectl describe ing ingress-http -n dev</font><br>
测试HTTP代理
浏览器访问由于域名无法正常解析,需要在windows内进行解析:C:\Windows\System32\drivers\etc
添加解析
192.168.1.197 www.nginx.com
192.168.1.197 www.tomcat.com
访问测试
在访问测试时,通过域名与ingress对外暴露的端口进行访问
查看ingress-nginx暴露的端口<br><font color="#e74f4c">kubectl get svc -n ingress-nginx</font><br>
访问测试:注意80对应的是HTTP端口,443对应的是HTTPS端口
http://www.nginx.com:30256
http://www.tomcat.com:30256
Ingress---ingress-HTTPS代理
生成证书<br><font color="#e74f4c">openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=TJ/O=nginx/CN=thinkmo.com"</font><br>
创建密钥<br><font color="#e74f4c">kubectl create secret tls tls-secret --key tls.key --cert tls.crt</font><br>
创建ingress-https.yml<br><font color="#e74f4c">vim ingress-https.yml</font><br>
创建ingress<br><font color="#e74f4c">kubectl create -f ingress-https.yml </font><br>
查看ingress信息<br><font color="#e74f4c">kubectl get ing ingress-https -n dev</font><br>
查看详细信息<br><font color="#e74f4c">kubectl describe ing ingress-https -n dev</font><br>
查看ingress-nginx端口<br><font color="#e74f4c">kubectl get svc -n ingress-nginx</font><br>
访问测试:访问443对应的端口<br>
https://www.nginx.com:31232
https://www.tomcat.com:31232
Collect
Get Started
Collect
Get Started
Collect
Get Started
Collect
Get Started
评论
0 条评论
下一页