Loading
0

Kubernetes/k8s入门教程及常见问题知识总结-持续更新
被墙跳转TG:@qianhenetwork QQ 851617266

301免备案跳转微信公众号
腾讯云服务器大促销。
华为服务器
前言:之前学习了docker容器,从今天开始本人将开始学习Kubernetes(k8s)容器了,本文章将记录从入门到提高的一系列问题,方便以后忘记查看,希望对大家也有帮助。
Docker容器教程:https://www.zfcdn.xyz/showinfo-3-36227-0.html
Kubernetes的核心概念:
K8s 功能:
(1)自动装箱
基于容器对应用运行环境的资源配置要求自动部署应用容器
(2)自我修复(自愈能力)
当容器失败时,会对容器进行重启
当所部署的 Node 节点有问题时,会对容器进行重新部署和重新调度
当容器未通过监控检查时,会关闭此容器直到容器正常运行时,才会对外提供服务
(3)水平扩展
通过简单的命令、用户 UI 界面或基于 CPU 等资源使用情况,对应用容器进行规模扩大
或规模剪裁
(3)服务发现
用户不需使用额外的服务发现机制,就能够基于 Kubernetes 自身能力实现服务发现和
负载均衡
(4)滚动更新
可以根据应用的变化,对应用容器运行的应用,进行一次性或批量式更新
(5)版本回退
可以根据应用部署情况,对应用容器运行的应用,进行历史版本即时回退
(6)密钥和配置管理
在不需要重新构建镜像的情况下,可以部署和更新密钥和应用配置,类似热部署。
(7)存储编排
自动实现存储系统挂载及应用,特别对有状态应用实现数据持久化非常重要
存储系统可以来自于本地目录、网络存储(NFS、Gluster、Ceph 等)、公共云存储服务
(8)批处理
提供一次性任务,定时任务;满足批量数据处理和分析的场景

1、什么是Pod:
答:
  • Pod是最小部署单元,一个容器中可以有多个Pod。
  • 是一组容器的集合
  •  一个容器中的Pod是共享网络的。
  • 生命周期是短暂的,比如重启服务器后重新部署了,之前的pod将丢失,会生成新的pod。
2、什么是Controller
答:
  • 可以确保逾期的Pod副本数量。
  • 无状态及有状态应用部署
  • 确保所有的node运行同一个pod。
  • 一次性任务和定时任务。

那什么是无状态应用?

  • 认为Pod都是一样的
  • 没有顺序要求
  • 不考虑应用在哪个node上运行
  • 能够进行随意伸缩和扩展

有状态应用:
上述的因素都需要考虑到

  • 让每个Pod独立的
  • 让每个Pod独立的,保持Pod启动顺序和唯一性
  • 唯一的网络标识符,持久存储
  • 有序,比如mysql中的主从

适合StatefulSet的业务包括数据库服务MySQL 和 PostgreSQL,集群化管理服务Zookeeper、etcd等有状态服务

StatefulSet的另一种典型应用场景是作为一种比普通容器更稳定可靠的模拟虚拟机的机制。传统的虚拟机正是一种有状态的宠物,运维人员需要不断地维护它,容器刚开始流行时,我们用容器来模拟虚拟机使用,所有状态都保存在容器里,而这已被证明是非常不安全、不可靠的。

使用StatefulSet,Pod仍然可以通过漂移到不同节点提供高可用,而存储也可以通过外挂的存储来提供 高可靠性,StatefulSet做的只是将确定的Pod与确定的存储关联起来保证状态的连续性。

3、什么是Service
答:
  • 定义一组Pod的访问规则

搭建K8S集群:
准备工作:
1、搭建K8S环境平台规划
单Master集群:多个node节点,只有一个Master节点。
多Master集群:多个node节点,多个Master节点,中间通过负载均衡调度。(高可用)
本次将先搭建单Master集群,后面根据情况搭建多Master集群。
2、服务器配置要求
测试环境:Master节点建议2核+4G节点以上。node节点建议4核+8G+50G以上硬盘。
生成环境:配置越高越好。
3、搭建K8S集群的部署方式
两种搭建方式:
kubeadm:Kubeadm 是一个 K8s 部署工具,提供 kubeadm init 和 kubeadm join,用于快速部署 Kubernetes 集群。
二进制:从 github 下载发行版的二进制包,手动部署每个组件,组成 Kubernetes 集群。
Kubeadm 降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。如果想更容易可控,推荐使用二进制包部署 Kubernetes 集群,虽然手动部署麻烦点,期间可以学习很多工作原理,也利于后期维护。
kubeadm部署方式介绍
安装要求
在开始之前,部署 Kubernetes 集群机器需要满足以下几个条件:
- 一台或多台机器,操作系统 CentOS7.x-86_x64
- 硬件配置:2GB 或更多 RAM,2 个 CPU 或更多 CPU,硬盘 30GB 或更多
- 集群中所有机器之间网络互通
- 可以访问外网,需要拉取镜像
- 禁止 swap 分区
系统初始化
关闭防火墙:

systemctl stop firewalld  && systemctl disable firewalld

关闭 selinux:

sed -i 's/enforcing/disabled/' /etc/selinux/config
# 永久

setenforce 0 # 临时

关闭 swap:

swapoff -a # 临时
vim /etc/fstab #将swap相关的挂载注释

主机名:

hostnamectl set-hostname <hostname>

在 master 添加 hosts:

cat >> /etc/hosts << EOF
172.19.81.11 k8s-master
172.19.81.12 k8s-node1
172.19.81.13 k8s-node2
EOF

在master和node节点中将桥接的 IPv4 流量传递到 iptables 的链:

cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sysctl --system # 生效

时间同步:

yum install ntpdate -y && ntpdate time.windows.com


所有节点都安装Docker/kubeadm/kubelet
kubernetes默认CRI(容器运行时)为Docker,因此先安装Docker。
1、所有节点安装Docker

wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
systemctl enable docker && systemctl start docker
docker --version

2、所有节点添加阿里云 YUM 软件源
设置仓库地址

cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF

所有节点添加 yum 源

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

所有节点安装 kubeadm,kubelet 和 kubectl
默认安装的是最新版

yum install -y kubelet kubeadm kubectl
systemctl enable kubelet

如果新版出现:[kubelet-check] Initial timeout of 40s passed.报错,则可卸载最新版安装如下老版本试下。(本人就出现了这个问题,换了版本后解决)

yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6 && systemctl enable kubelet

查看版本号:

kubelet --version
kubectl version
kubeadm version

启动kubelet

systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet

3、部署 Kubernetes Master
在 172.19.81.11(Master)执行

kubeadm init \
--apiserver-advertise-address=172.19.81.11 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.23.6 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16

由于默认拉取镜像地址 k8s.gcr.io 国内无法访问,这里指定阿里云镜像仓库地址。
安装完成maser节点会显示如下信息则表示正常安装。

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config


Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

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

kubeadm join 172.19.81.11:6443 --token 2wbu5k.a1eie02nqo4zmhh0 \
    --discovery-token-ca-cert-hash sha256:e7977da44729f54ed2e8223827a2eda24c4a9c315704a56d4554bc0b5efbf77b

如果安装过程中遇到问题,可以参考后面报错说明
如果使用 kubectl 工具,则执行如下命令(命令在安装好后会显示,可参考上面信息)(只在master上执行)

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

查看节点:

kubectl get nodes

执行结果:

[[email protected] lib]# kubectl get nodes
NAME         STATUS     ROLES                  AGE   VERSION
k8s-master   NotReady   control-plane,master   21m   v1.23.6

4、向集群添加新节点,执行在 kubeadm init 输出的 kubeadm join 命令(在node上执行)

kubeadm join 172.19.81.11:6443 --token 2wbu5k.a1eie02nqo4zmhh0 \
    --discovery-token-ca-cert-hash sha256:e7977da44729f54ed2e8223827a2eda24c4a9c315704a56d4554bc0b5efbf77b

输出如下结果表示正常

[[email protected] ~]# kubeadm join 172.19.81.11:6443 --token 2wbu5k.a1eie02nqo4zmhh0 \
>     --discovery-token-ca-cert-hash sha256:e7977da44729f54ed2e8223827a2eda24c4a9c315704a56d4554bc0b5efbf77b
[preflight] Running pre-flight checks
    [WARNING Hostname]: hostname "k8s-node2" could not be reached
    [WARNING Hostname]: hostname "k8s-node2": lookup k8s-node2 on 114.114.114.114:53: no such host
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

此时在master节点执行如下命令会显示加入的节点:

kubectl get nodes

执行结果:(NotReady未就绪

[[email protected] lib]# kubectl get nodes
NAME         STATUS     ROLES                  AGE     VERSION
k8s-master   NotReady   control-plane,master   30m     v1.23.6
k8s-node1    NotReady   <none>                 5m40s   v1.23.6
k8s-node2    NotReady   <none>                 5m41s   v1.23.6

5、部署CNI网络插件:(master节点)
执行命令:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

该地址在海外,可能无法访问,届时可以用ping方法看其他节点然后hosts解析。
执行结果:

[[email protected] lib]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
namespace/kube-flannel created
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.apps/kube-flannel-ds created

执行如下命令查看是否正常:

kubectl get pods -n kube-system

返回如下则表示正常了(Running状态)

[[email protected] lib]# kubectl get pods -n kube-system
NAME                                 READY   STATUS    RESTARTS      AGE
coredns-6d8c4cb4d-lddvj              1/1     Running   0             42m
coredns-6d8c4cb4d-tsstd              1/1     Running   0             42m
etcd-k8s-master                      1/1     Running   1 (43m ago)   42m
kube-apiserver-k8s-master            1/1     Running   1 (44m ago)   42m
kube-controller-manager-k8s-master   1/1     Running   1 (44m ago)   42m
kube-proxy-fjdc6                     1/1     Running   0             17m
kube-proxy-skgdv                     1/1     Running   0             17m
kube-proxy-tdwsw                     1/1     Running   0             42m
kube-scheduler-k8s-master            1/1     Running   1 (44m ago)   42m

执行如下命令:

kubectl get nodes

返回结果:显示Ready则表示正常准备好了。可能需要等待几十秒或几分钟。

[[email protected] lib]#  kubectl get nodes
NAME         STATUS   ROLES                  AGE   VERSION
k8s-master   Ready    control-plane,master   46m   v1.23.6
k8s-node1    Ready    <none>                 21m   v1.23.6
k8s-node2    Ready    <none>                 21m   v1.23.6

至此,k8s集群搭建完成。
6、测试K8s集群是否正常。
在k8s集群中创建一个pod,验证是否运行正常。
1、拉取一个nignx镜像:

kubectl create deployment nginx --image=nginx

返回结果:

[[email protected] lib]# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created

此时可以使用如下命令查看拉取情况。

kubectl get pod

显示如下:显示Running   则表示拉取完成

[[email protected] lib]# kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-85b98978db-mfks4   1/1     Running   0          59s

2、对外暴露80端口使其可以访问。

kubectl expose deployment nginx --port=80 --type=NodePort

执行结果:表示执行成功。

[[email protected] lib]# kubectl expose deployment nginx --port=80 --type=NodePort
service/nginx exposed

3、执行如下命令查看pod的情况以及端口等信息

kubectl get pod,svc

执行如下:

[[email protected] lib]# kubectl get pod,svc
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-85b98978db-mfks4   1/1     Running   0          3m35s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        55m
service/nginx        NodePort    10.110.177.174   <none>        80:32588/TCP   77s

测试方法:
node节点ip+端口号,例如如上:可以使用http://172.19.81.13:32588/ 或者 http://172.19.81.12:32588/ 访问显示nginx的默认页面则表示部署成功。


 

安装过程中常见问题:
1、在master上初始化集群失败报错“[kubelet-check] Initial timeout of 40s passed.
解决方法:查找了一下资料是说k8s版本太高,已经不支持docker导致,重新安装k8s低版本的,可执行如下命令卸载后并重新安装:
注意:卸载前请务必核实是否有数据,建议做好备份或做好快快照操作。
若是生产环境,不建议轻易操作。
卸载K8s:

yum remove -y kubelet kubeadm kubectl
kubeadm reset -f
modprobe -r ipip
lsmod
rm -rf ~/.kube/
rm -rf /etc/kubernetes/
rm -rf /etc/systemd/system/kubelet.service.d
rm -rf /etc/systemd/system/kubelet.service
rm -rf /usr/bin/kube*
rm -rf /etc/cni
rm -rf /opt/cni
rm -rf /var/lib/etcd
rm -rf /var/etcd

重新在所有节点安装k8s低版本:

yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6
systemctl enable kubelet

2、master初始化集群报错“The kubelet is not running”。
原因:kubelet没启动,尝试执行命令service kubelet start启动但失败。
解决方法:
1、执行如下命令看具体启动失败原因:

journalctl -xeu kubelet | grep Failed

输出:

[[email protected] ~]# journalctl -xeu kubelet | grep Failed
1月 07 17:07:41 k8s-master kubelet[17877]: E0107 17:07:41.164885   17877 server.go:302] "Failed to run kubelet" err="failed to run Kubelet: misconfiguration: kubelet cgroup driver: \"systemd\" is different from docker cgroup driver: \"cgroupfs\""

编辑:vi /etc/docker/daemon.json文件,在大括号内增加如下:


 "exec-opts": ["native.cgroupdriver=systemd"]

添加后如下:(注意是否有中文符号,否则docker将启动失败,本人为了一个符号折腾了1小时

{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]

}

重启docker:

sudo systemctl daemon-reload && sudo systemctl restart docker

重启k8s:

systemctl daemon-reload  &&  systemctl restart kubelet && netstat -lunpt


报错:The connection to the server localhost:8080 was refused - did you specify the right host or port?
原因是在node节点上执行了命令,是需要在master节点执行才可以。
采用二进制搭建K8s集群方法:
1、创建多台虚拟机(已创建略过)
2、系统初始化:
初始化方法可参考上面教程。
3、为etcd和apiserver自签证书
准备 cfssl 证书生成工具
cfssl 是一个开源的证书管理工具,使用 json 文件生成证书,相比 openssl 更方便使用。
找任意一台服务器操作,这里用 Master 节点。
下载很慢,甚至可能下载不了,可以ping其他节点ip然后hosts解析。

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

生成 Etcd 证书
自签证书颁发机构(CA)
创建工作目录:

mkdir -p ~/TLS/{etcd,k8s}
cd TLS/etcd

自签 CA:

cat > ca-config.json<< EOF
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"www": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF

cat > ca-csr.json<< EOF
{
"CN": "etcd CA",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing"
}
]
}
EOF

生成证书:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -

ls *pem
ca-key.pem ca.pem

执行结果如下:

[root@master etcd]#     cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
2023/03/21 20:58:58 [INFO] generating a new CA key and certificate from CSR
2023/03/21 20:58:58 [INFO] generate received request
2023/03/21 20:58:58 [INFO] received CSR
2023/03/21 20:58:58 [INFO] generating key: rsa-2048
2023/03/21 20:58:58 [INFO] encoded CSR
2023/03/21 20:58:58 [INFO] signed certificate with serial number 14951914944477411348481876419999757812811653542

[root@master etcd]# ll
总用量 20
-rw-r--r--. 1 root root  175 3月  21 20:58 ca-config.json
-rw-r--r--. 1 root root  956 3月  21 20:58 ca.csr
-rw-r--r--. 1 root root  121 3月  21 20:58 ca-csr.json
-rw-------. 1 root root 1679 3月  21 20:58 ca-key.pem
-rw-r--r--. 1 root root 1265 3月  21 20:58 ca.pem
[root@master etcd]# ls *pem
ca-key.pem  ca.pem

使用自签 CA 签发 Etcd HTTPS 证书
创建证书申请文件:

cat > server-csr.json<< EOF
{
"CN": "etcd",
"hosts": [
"172.22.139.11",
"172.22.139.22",
"172.22.139.33"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF

注:上述文件 hosts 字段中 IP 为所有 etcd 节点的集群内部通信 IP,一个都不能少!为了
方便后期扩容可以多写几个预留的 IP。
生成证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server

执行后如下:

[root@master etcd]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
2023/03/21 21:04:23 [INFO] generate received request
2023/03/21 21:04:23 [INFO] received CSR
2023/03/21 21:04:23 [INFO] generating key: rsa-2048
2023/03/21 21:04:23 [INFO] encoded CSR
2023/03/21 21:04:23 [INFO] signed certificate with serial number 551743223946492829929705690629601704728862091398
2023/03/21 21:04:23 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").

从 Github 下载二进制文件

wget https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz







4、部署etcd集群

5、部署master组件
需安装组件:kube-apiserver、kube-controller-manager、kube-scheduler、etcd

6、部署node组件
需安装组件:kubelet、kube-proxy、docker、etcd

7、部署集群网络插件
 
kubernetes集群命令行工具kubectl
1、kubectl概述:
kubectl 是 Kubernetes 集群的命令行工具,通过 kubectl 能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署。
2、kubectl 命令的语法

kubectl [command] [type] [name] [flags]

(1)comand:指定要对资源执行的操作,例如 create、get、describe 和 delete
(2)TYPE:指定资源类型,资源类型是大小写敏感的,开发者能够以单数、复数和缩略的
形式。例如:

kubectl get pod pod1
kubectl get pods pod1
kubectl get po pod1

执行结果:

(3)NAME:指定资源的名称,名称也大小写敏感的。如果省略名称,则会显示所有的资源,
例如:

kubectl get pods

[root@master ~]# kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-85b98978db-nh2m4   1/1     Running   0          45h

flags:指定可选的参数。例如,可用-s 或者–server 参数指定 Kubernetes APIserver 的地址和端口。
kubectl help 获取更多信息
命令:

kubectl --help

Kubectl 子命令使用分类
详细命令可参考:https://blog.csdn.net/freellf/article/details/128343111
 

基础命令

create

通过文件名或标准办输入创建资源

expose

将一个资源公开为一个新的Service

run

在集群中运行一个特定的镜像

set

在对象上设置特定的镜像

get

显示一个或多个资源

explain

文档参考资料

edit

使用默认的编辑器编辑一个资源

delete

通过文件名、标准输入、资源名称或标签选择器来删除资源

部署命令

rollout

管理资源的发布

rolling-update

对给定的复制控制器滚动更新

scale

扩容或缩容Pod数时,Deployment、ReplicaSet、RC或Job

autoacale

创建一个自动选择扩容或缩容并设置Pod数量

集群管理命令

certificate

修改证书资源

cluster-info

显示集群信息

top

显示资源(CPU/Memory/Storage)使用。需要Heapster运行

cordon

标记节点不可调度

uncordon

标记节点可调度

drain

驱逐节点上的应用,准备下线维护

taint

修改节点taint标记

故障诊断和调试命令

describe

显示特定资源或资源组的详细信息

logs

在一个Pod中打印一个容器日志,如果Pod只有一个容器,容器名称是可选的

attach

附加到一个运行的容器

exec

执行命令到容器

port-forward

转发一个或多个本地端口到一个pod

proxy

运行一个proxy到Kubernetes API server

cp

拷贝文件或目录到容器中

auth

检查授权

高级命令

apply

通过文件名或标准输入对资源应用配置

patch

使用补丁修改、更新资源的字段

replace

通过文件名或标准输入替换一个资源

convert

不同的API版本之间转换配置文件

 

设置命令

label

更新资源上的标签

annotate

更新资源上的注解

completion

用于实现kubectl工具自动补全

其他命令

api-versions

打印受支持的API版本

config

修改kubeconfig文件(用于访问API, 比如配置认证信息)

help

所用命令帮助

plugin

运行一个命令行插件

version

打印客户端和服务版本信息

 

 
kubernetes 集群 YAML 文件详
1、YAML 文件概述
k8s 集群中对资源管理和资源对象编排部署都可以通过声明样式(YAML)文件来解决,也就是可以把需要对资源对象操作编辑到 YAML 格式文件中,我们把这种文件叫做资源清单文件(或资源编排),通过 kubectl 命令直接使用资源清单文件就可以实现对大量的资源对象进行编排部署
了。
2、YAML 文件书写格式
(1)YAML 介绍
YAML :仍是一种标记语言。为了强调这种语言以数据做为中心,而不是以标记语言为重点。
YAML 是一个可读性高,用来表达数据序列的格式。
(2)YAML 基本语法
* 使用空格做为缩进
* 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
* 低版本缩进时不允许使用 Tab 键,只允许使用空格
* 使用#标识注释,从这个字符一直到行尾,都会被解释器忽略
*一般开头缩进两个空格
*字符后缩进一个空格,比如冒号和逗号后面都需要空格。
*
使用“---”表示新的yaml文件开始
*使用“#”表示注释。
(3)YAML 文件组成部分
一个简单的nginx的yaml文件:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      name: nginx

  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
        - name: nginx
          image: harbor.xxx.cn/official_hub/nginx:1.13-alpine
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80

另一个版本的详细说明:

apiVersion: apps/v1    #与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment    #该配置的类型,我们使用的是 Deployment
metadata:            #译名为元数据,即 Deployment 的一些基本属性和信息
  name: nginx-deployment    #Deployment 的名称
  labels:        #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
    app: nginx    #为该Deployment设置key为app,value为nginx的标签
spec:            #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
  replicas: 1    #使用该Deployment创建一个应用程序实例
  selector:        #标签选择器,与上面的标签共同作用,目前不需要理解
    matchLabels: #选择包含标签app:nginx的资源
      app: nginx

  template:        #这是选择或创建的Pod的模板
    metadata:    #Pod的元数据
      labels:    #Pod的标签,上面的selector即选择包含标签app:nginx的Pod
        app: nginx
    spec:        #期望Pod实现的功能(即在pod中部署)
      containers:    #生成container,与docker中的container是同一种
      - name: nginx    #container的名称
        image: nginx:1.7.9    #使用镜像nginx:1.7.9创建container,该container默认80端口可访问

其中,红色部分表示“控制器定义”(要控制那些事),蓝色部分是“被控制对象”( 控制的具体的事 )。
常用字段含义
参数名 字段类型 说明
version string k8s api的版本号,目前是v1,可以通过kubectl api-version查看
kind string 指定资源类型,例如Pod,Deployment,Service等
metadata object 自定义metadata
metadata.name string 对象名字,用户自定义
metadata.namespace string 对象的命名空间,用户自定义
spec Object 对象的详细信息
spc.restartPolicy string

pod重启策略

Always:pod一旦退出就要进行重启

OnFailure:只有非正常退出才进行重启

Nerver:退出后不再拉起

spec.hostNetwork bool

是否使用主机网络,默认值false

设置为true,表示与主机在同一个网络空间

spec.nodeSelector object 标签选择器,k-v形式
spec.containers[] list 容器对象列表
spec.containers[].name string 容器的名称
spec.containers[].image string 容器使用的镜像
spec.containers[].imagePullPolicy string

Always:每次都重新下载

IfNotPresent:如果本地存在则使用本地镜像,不重新拉取

Never:表示仅使用本地镜像

spec.containers[].command[] list 指定容器启动命令,可以是多个命令,如果不指定则使用镜像中启动命令
spec.containers[].args[] list 启动命令参数,可以多个
spec.containers[].workingDir string 容器的工作目录
spec.containers[].volumeMounts[] list 指定容器的挂在卷,可以多个
spec.containers[].volumeMounts[].name string 挂在卷名称
spec.containers[].volumeMounts[].mountPath string 挂在卷路径
spec.containers[].volumeMounts[].readOnly bool 读写模式,true只读(默认值),false读写
spec.containers[].ports[] list 容器用到端口
spec.containers[].ports[].name string 端口名称
spec.containers[].ports[].containerPort number 端口号
spec.containers[].ports[].hostPort number 指定host主机使用端口。主要适用于端口映射,默认值是和容器内端口相同
spec.containers[].ports[].protocol string 监听协议,tcp、udp,默认是tcp
spec.containers[].env[] list 容器的环境变量列表
spec.containers[].env[].name string 环境变量name
spec.containers[].env[].value string 环境变量value
spec.containers[].resources object 用于设置资源限制和资源请求
spec.containers[].resources.limits object 设置资源上限
spec.containers[].resources.limits.cpu string 对cpu的限制,k8s将一个逻辑cpu划分成1000个millicore(毫核)。例如 limits.cpu=500m相当于0.5个cpu。 limits.cpu=2表示占用2个cpu
spec.containers[].resources.limits.memory string 对内存的限制
spec.containers[].resources.requests object 容器启动和调度是的限制设置
spec.containers[].resources.requests.cpu string 对cpu的限制,k8s将一个逻辑cpu划分成1000个millicore(毫核)。例如 limits.cpu=500m相当于0.5个cpu。 limits.cpu=2表示占用2个cpu
spec.containers[].resources.requests.memory string 对内存的限制

kind种类:
kind种类:
分类 说明 其他
Pod k8s最基本管理单元  

ReplicationController(RC)

副本控制器,用于控制Pod副本数,目前官方不建议使用 保证副本数,始终为用户指定数目

ReplicaSet(RS)

是RC的升级版本,比RC多了一个选择器,其他都一样。 保证副本数,始终为用户指定数目,不能动态扩缩容
Deployment 支持动态扩缩容,滚动升级,版本回滚,RS不支持  
DeamonSet 确保全部或部分Node 上运行一个 Pod 的副本 例如:要求每个node上都有监控系统,日志系统等
Job 执行脚本,linux命令等 适用于批处理任务
CronJob 定时执行脚本,linux命令等 定时批处理任务
Service 提供负载均衡和服务自动发现,底层通过EndPoint实现  
EndPoints pod名字和ip映射关系集合,支撑Service  
ConfigMap 配置集合,用于给pod/容器传递参数 1、 将环境变量直接定义在configMap中,当Pod启动时,通过env来引用configMap中定义的环境变量。
2、 将一个完整配置文件封装到configMap中,然后通过共享卷的方式挂载到Pod中,实现给应用传参。

举例
被墙跳转TG:@qianhenetwork QQ 851617266

这个例子摘自其他网友

apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中  
kind: Pod #指定创建资源的角色/类型  
metadata: #资源的元数据/属性  
  name: web04-pod #资源的名字,在同一个namespace中必须唯一  
  labels: #设定资源的标签,详情请见http://blog.csdn.net/liyingke112/article/details/77482384
    k8s-app: apache  
    version: v1  
    kubernetes.io/cluster-service: "true"  
  annotations:            #自定义注解列表  
    - name: String        #自定义注解名字  
spec:   #specification of the resource content 指定该资源的内容  
  restartPolicy: Always #表明该容器一直运行,默认k8s的策略,在此容器退出后,会立即创建一个相同的容器  
  nodeSelector:     #节点选择,先给主机打标签kubectl label nodes kube-node1 zone=node1  
    zone: node1  
  containers:  
  - name: web04-pod #容器的名字  
    image: web:apache #容器使用的镜像地址  
    imagePullPolicy: Never #三个选择Always、Never、IfNotPresent,每次启动时检查和更新(从registery)images的策略,
                           # Always,每次都检查
                           # Never,每次都不检查(不管本地是否有)
                           # IfNotPresent,如果本地有就不检查,如果没有就拉取
    command: ['sh'] #启动容器的运行命令,将覆盖容器中的Entrypoint,对应Dockefile中的ENTRYPOINT  
    args: ["$(str)"] #启动容器的命令参数,对应Dockerfile中CMD参数  
    env: #指定容器中的环境变量  
    - name: str #变量的名字  
      value: "/etc/run.sh" #变量的值  
    resources: #资源管理,请求请见http://blog.csdn.net/liyingke112/article/details/77452630
      requests: #容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行  
        cpu: 0.1 #CPU资源(核数),两种方式,浮点数或者是整数+m,0.1=100m,最少值为0.001核(1m)
        memory: 32Mi #内存使用量  
      limits: #资源限制  
        cpu: 0.5  
        memory: 32Mi  
    ports:  
    - containerPort: 80 #容器开发对外的端口
      name: httpd  #名称
      protocol: TCP  
    livenessProbe: #pod内容器健康检查的设置,详情请见http://blog.csdn.net/liyingke112/article/details/77531584
      httpGet: #通过httpget检查健康,返回200-399之间,则认为容器正常  
        path: / #URI地址  
        port: 80  
        #host: 127.0.0.1 #主机地址  
        scheme: HTTP  
      initialDelaySeconds: 180 #表明第一次检测在容器启动后多长时间后开始  
      timeoutSeconds: 5 #检测的超时时间  
      periodSeconds: 15  #检查间隔时间  
      #也可以用这种方法  
      #exec: 执行命令的方法进行监测,如果其退出码不为0,则认为容器正常  
      #  command:  
      #    - cat  
      #    - /tmp/health  
      #也可以用这种方法  
      #tcpSocket: //通过tcpSocket检查健康   
      #  port: number   
    lifecycle: #生命周期管理  
      postStart: #容器运行之前运行的任务  
        exec:  
          command:  
            - 'sh'  
            - 'yum upgrade -y'  
      preStop:#容器关闭之前运行的任务  
        exec:  
          command: ['service httpd stop']  
    volumeMounts:  #详情请见http://blog.csdn.net/liyingke112/article/details/76577520
    - name: volume #挂载设备的名字,与volumes[*].name 需要对应    
      mountPath: /data #挂载到容器的某个路径下  
      readOnly: True  
  volumes: #定义一组挂载设备  
  - name: volume #定义一个挂载设备的名字  
    #meptyDir: {}  
    hostPath:  
      path: /opt #挂载设备类型为hostPath,路径为宿主机下的/opt,这里设备类型支持很多种 

如何快速编写yaml文件:
1、使用kubectl create 命令生产yaml文件,然后根据生产的文件修改。(一般用于还没部署情况)
不真正运行,只是输出yaml文件。
命令范例:

kubectl create deployment web --image=nginx -o yaml  --dry-run

说明,生产一个nginx的,名称为web,-o yaml 是生成yaml文件,--dry-run是尝试运行(不是真正运行,只输出yaml文件)。
执行结果如下:

[root@master ~]# kubectl create deployment web --image=nginx -o yaml  --dry-run
W0323 15:20:01.966640     584 helpers.go:598] --dry-run is deprecated and can be replaced with --dry-run=client.
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}
[root@master ~]#

也可以将生成的yaml文件输出到文件。

kubectl create deployment web --image=nginx -o yaml  --dry-run > www.zfcdn.xyz.yaml

输出结果:

[root@master ~]# kubectl create deployment web --image=nginx -o yaml  --dry-run > www.zfcdn.xyz.yaml
W0323 15:22:30.634903    1788 helpers.go:598] --dry-run is deprecated and can be replaced with --dry-run=client.
[root@master ~]# ll
总用量 8
-rw-------. 1 root root 1322 3月  20 20:07 anaconda-ks.cfg
-rw-r--r--  1 root root  376 3月  23 15:22 www.zfcdn.xyz.yaml

2、使用kubectl get 命令从部署好的项目中导出yaml文件。
查看已部署的项目:

kubectl get deploy

执行结果:

[root@master ~]# kubectl get deploy
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   1/1     1            1           47h

有运行一个nginx,我们将nginx的yaml文件导出。

kubectl get deploy nginx -o=yaml

执行结果:

[root@master ~]# kubectl get deploy nginx -o=yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2023-03-21T07:33:46Z"
  generation: 1
  labels:
    app: nginx
  name: nginx
  namespace: default
  resourceVersion: "1255"
  uid: e91408dd-7e3e-4961-aa7a-0b3fa7b4e5b6
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        imagePullPolicy: Always
        name: nginx
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: "2023-03-21T07:34:14Z"
    lastUpdateTime: "2023-03-21T07:34:14Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: "2023-03-21T07:33:46Z"
    lastUpdateTime: "2023-03-21T07:34:14Z"
    message: ReplicaSet "nginx-85b98978db" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 1
  replicas: 1
  updatedReplicas: 1
[root@master ~]#

将导出的yaml文件放到指定文件:

kubectl get deploy nginx -o=yaml --export > www.zfcdn.xyzs.yaml

执行后出现下面错误。

error: unknown flag: --export
See 'kubectl get --help' for usage.

原因:原因是 --export在所使用的版本中已经被去除了,将--export删除即可。

kubectl get deploy nginx -o=yaml  > www.zfcdn.xyzs.yaml

执行后没有任何提示则表示正常,可以打开生成的www.zfcdn.xyzs.yaml看下:
kubernetes 核心技术-Pod
1、Pod 概述
Pod 是 k8s 系统中可以创建和管理的最小单元,是资源对象模型中由用户创建或部署的最小资源对象模型,也是在 k8s 上运行容器化应用的资源对象,其他的资源对象都是用来支撑或者扩展 Pod 对象功能的,比如控制器对象是用来管控 Pod 对象的,Service 或者Ingress 资源对象是用来暴露 Pod 引用对象的,PersistentVolume 资源对象是用来为 Pod提供存储等等,k8s 不会直接处理容器,而是 PodPod 是由一个或多个 container 组成Pod 是 Kubernetes 的最重要概念,每一个 Pod 都有一个特殊的被称为”根容器“的 Pause容器。Pause 容器对应的镜 像属于 Kubernetes 平台的一部分,除了 Pause 容器,每个 Pod还包含一个或多个紧密相关的用户业务容器。
2、Pod 特性
(1)资源共享
一个 Pod 里的多个容器可以共享存储和网络,可以看作一个逻辑的主机。共享的如namespace,cgroups 或者其他的隔离资源。多个容器共享同一 network namespace,由此在一个 Pod 里的多个容器共享 Pod 的 IP 和端口 namespace,所以一个 Pod 内的多个容器之间可以通过 localhost 来进行通信,所需要注意的是不同容器要注意不要有端口冲突即可。不同的 Pod 有不同的 IP,不同 Pod 内的多个容器之前通信,不可以使用 IPC(如果没有特殊指定的话)通信,通常情况下使用 Pod的 IP 进行通信。
一个 Pod 里的多个容器可以共享存储卷,这个存储卷会被定义为 Pod 的一部分,并且可以挂载到该 Pod 里的所有容器的文件系统上。
(2)生命周期短暂
Pod 属于生命周期比较短暂的组件,比如,当 Pod 所在节点发生故障,那么该节点上的 Pod会被调度到其他节点,但需要注意的是,被重新调度的 Pod 是一个全新的 Pod,跟之前的Pod 没有半毛钱关系。
(3)平坦的网络
K8s 集群中的所有 Pod 都在同一个共享网络地址空间中,也就是说每个 Pod 都可以通过其他 Pod 的 IP 地址来实现访问。
Pod存在的意义:
1、创建容器使用docker,一个docker对应是一个容器,一个容器有进程,一个容器运行一个应用程序。(单进程管理)
2、pod是多进程设计,一个pod中有多个容器,一个容器运行一个应用程序
3、pod的存在也是为了亲密性应用例如,两个应用之间进行交互或者网络之间调用以及两个应用之间要频繁调用。所以叫“亲密性应用”
pod实现机制:
1、共享网络
容器之间本身是相互隔离的比如用namespace 几group方式隔离。
同一个pod中的容器是如何实现网络共享的。
创建容器时系统会先创建一个根容器Pause(info容器),后面创建的业务容器会自动加入到Pause(info容器)根容器是包含ip 、mac port等信息,在同一个名称空间中即可实现网络共享(类似阿里云的vpc,在同一个vpc下网络互通)
2、共享存储
实际上是将数据做持久化存储(数据卷 Volume),将数据保存在一个地方,多个容器可以访问这个持久化存储数据。
Pod镜像拉去策略:
主要有三种:Always 、Never 、IfNotPresent
Always
总是从镜像仓库获取镜像。当标签为latest,默认为Always
Never
禁止从仓库中获取镜像,只能使用本地镜像
IfNotPresent
仅当本地没有镜像时,才从镜像仓库获取镜像。当标签为自定义时(不是latest),默认为IfNotPresent
范例:

containers:
  - name: redis
    image: redis:6.0
    imagePullPolicy: Always

Pod资源限制:
pod中,容器的程序要运行肯定是要占用一定资源的,比如CPU和内存等,如果不对某个容器的资源对限制,那么它就可能消耗大量资源,导致其他容器无法运行,针对这样情况,kubernetes提供了对内存和CPU资源进行配额的机制,这种机制主要通过配置pod中容器的resources选项实现,resources提供了2个主要的参数,如下:

limits:用于限制运行时容器的最大占用资源,当容器占用资源超过limit时就会被终止,进进行重启;
requests:用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动;(最低配额,保证被调度的节点上至少有的资源配额)

可以通过上面两个选项设置资源的上下线;

[root@master ~]# cat pod-busybox.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-command
  labels:
    env: dev
  namespace: default
spec:
  containers:
  - image: busybox
    name: busybox-container
    command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt;sleep 3;done;"]
    resources:                    #资源配额
      limits:                    #限制最大资源,上限
        cpu: 2                    #CPU限制,单位是code数
        memory: 2G                #内存最大限制
      requests:                    #请求资源(最小,下限)
        cpu: 1                    #CPU请求,单位是code数
        memory: 500G            #内存最小请求
[root@master ~]#

资源限制另外的说明:
Pod 资源配置(资源限制):

每个 Pod 都可以对其能使用的服务器上的计算资源设置限额,Kubernetes 中可以设置限额的计算资源有 CPU 与 Memory 两种,其中 CPU 的资源单位为 CPU 数量,是一个绝对值而非相对值。Memory 配额也是一个绝对值,它的单 位是内存字节数。
Kubernetes 里,一个计算资源进行配额限定需要设定以下两个参数: Requests 该资源最小申请数量,系统必须满足要求 Limits 该资源最大允许使用的量,不能突破,当容器试图使用超过这个量的资源时,可能会被 Kubernetes Kill 并重启
(1)举例

sepc
containers:
- name: db
image: mysql
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"

上述代码表明 MySQL 容器申请最少 0.25 个 CPU 以及 64MiB 内存,在运行过程中容器所能使用的资源配额为 0.5 个 CPU 以及 128MiB 内存。
容器健康检查:
应用层面健康检查
健康检查相关说明可参考https://www.zfcdn.xyz/showinfo-3-36270-0.html
关于节点标签的创建、修改、删除及使用方法可访问:https://www.zfcdn.xyz/showinfo-3-36271-0.html地址详细查看:
kubernetes调度策略
创建pod过程:

master节点:
1、创建一个pod,首先会进入到apiserver并将pod信息存储到etcd里面。
2、pod创建后会进入scheduler,首先会监听apiserver是否有新的pod创建,有新的pod创建,则通过etcd读取pod,然后调度分配到node节点中。
node节点:
首先kubelet会先访问apiserver,然后读取etcd获取分配给当前节点的pod,然后通过docker创建对应容器,创建好后将容器信息返回给apiserver然后再etcd中存储。
在创建pod过程中有什么因素会影响pod调度过程:
影响调度的属性:
1、pod资源限制对pod调用产生影响,例如内存和cpu限制。具体说明可参考上面“Pod 资源配置(资源限制)”说明。
2、节点选择器会对pod调度产生影响,具体可参考“https://www.zfcdn.xyz/showinfo-3-36271-0.html”说明
3、节点亲和性对pod调度影响。
关于节点亲和性的说明可访问https://www.zfcdn.xyz/showinfo-3-36273-0.html
4、污点和污点容忍影响调度。
关于污点及污点容忍设置及使用方法可访问https://www.zfcdn.xyz/showinfo-3-36272-0.html
controller概述和应用场景:
1、什么是controller控制器
在集群中管理和运行容器的对象,controller中还有很多controller。
2、pod和controller是什么关系
pod是通过controller实现应用的运维,比如伸缩、滚动升级等都是controller实现的。
pod和controller之间是通过label标签建立关系。
3、deployment控制器应用场景
部署无状态应用
管理pod和replicaset
部署,滚动升级等功能
web服务、微服务。
4、yaml文件字段说明

5、deployment控制器实际部署应用
通过label标签建立关系

kubectl create deployment web --image=nginx --dry-run -o yaml >web.yaml   #导出yaml文件。

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web

  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web

    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

通过yaml文件部署。

kubectl apply -f web.yaml

查看创建情况

kubectl get pods
[root@master ~]# kubectl get pods
NAME                   READY   STATUS    RESTARTS      AGE
web-76b56fd968-r8djm   1/1     Running   1 (23m ago)   47h

对外发布,暴露端口,生成一个yaml文件

kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web11 -o yaml >web11.yaml

通过上面生成的yaml文件部署

kubectl apply -f web11.yaml

执行如下命令查看pod及端口情况。

kubectl get pods,svc

[root@master ~]# kubectl get pods,svc
NAME                       READY   STATUS    RESTARTS      AGE
pod/web-76b56fd968-r8djm   1/1     Running   1 (29m ago)   2d

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        5d23h
service/nginx        NodePort    10.96.241.120    <none>        80:31261/TCP   5d23h
service/web11        NodePort    10.100.177.151   <none>        80:31247/TCP   2m56s

 

通过新的yaml文件生成新的pod。

[root@master ~]# kubectl apply -f web.yaml
deployment.apps/web configured 
[root@master ~]# kubectl get pods
NAME                   READY   STATUS              RESTARTS      AGE
web-5c48757fd6-x5wbz   0/1     ContainerCreating   0             13s
web-76b56fd968-r8djm   1/1     Running             1 (44m ago)   2d



6、升级回滚
升级:

编辑之前的 web.yaml 文件,将 image: nginx 改成 image: nginx:1.14 (也就是指定版本)

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web
    spec:
      containers:
      - image: nginx:1.14
        name: nginx
        resources: {}
status: {}

现在nignx版本是1.14,我们升级到1.15版本,命令如下。

[root@master ~]# kubectl set image deployment web nginx=nginx:1.15
deployment.apps/web image updated
[root@master ~]# kubectl get pods
NAME                   READY   STATUS              RESTARTS   AGE
web-5c48757fd6-x5wbz   1/1     Running             0          4m5s
web-9b696bd8f-p5p7l    0/1     ContainerCreating   0          5s

查看升级状态是否成功:

[root@master ~]# kubectl rollout status deployment web
deployment "web" successfully rolled out

在node节点执行docker images 可以看到最新的1.15的nginx镜像。
回滚:
1、查看历史版本

kubectl rollout history deployment web

[root@master ~]# kubectl rollout history deployment web
deployment.apps/web
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
3         <none>

还原版本:
还原到上一个版本,例如现在升级到了1.15,要还原到1.14

kubectl rollout undo deployment web

[root@master ~]# kubectl rollout undo deployment web
deployment.apps/web rolled back

查看状态,成功:

[root@master ~]# kubectl rollout status deployment web
deployment "web" successfully rolled out

还原到指定版本:

kubectl rollout undo deployment web --to-revision=1

还原成功:

[root@master ~]# kubectl rollout undo deployment web --to-revision=1
deployment.apps/web rolled back
[root@master ~]# kubectl rollout status deployment web
Waiting for deployment "web" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "web" rollout to finish: 1 old replicas are pending termination...
deployment "web" successfully rolled out

7、弹性伸缩

kubectl scale deployment web --replicas=10

一次性创建10个副本。

[root@master ~]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-76b56fd968-rp2n2   1/1     Running   0          3m24s
[root@master ~]# kubectl scale deployment web --replicas=10
deployment.apps/web scaled
[root@master ~]# kubectl get pods
NAME                   READY   STATUS              RESTARTS   AGE
web-76b56fd968-4qf6x   0/1     ContainerCreating   0          2s
web-76b56fd968-62xb7   0/1     ContainerCreating   0          2s
web-76b56fd968-7hg5r   0/1     ContainerCreating   0          2s
web-76b56fd968-dts64   0/1     ContainerCreating   0          2s
web-76b56fd968-fm79d   0/1     ContainerCreating   0          2s
web-76b56fd968-kb97w   0/1     ContainerCreating   0          2s
web-76b56fd968-ms22c   0/1     ContainerCreating   0          2s
web-76b56fd968-rp2n2   1/1     Running             0          3m29s
web-76b56fd968-szmtp   0/1     ContainerCreating   0          2s
web-76b56fd968-vmn2p   0/1     ContainerCreating   0          2s
[root@master ~]#

 
Service
1、sevice存在的意义:防止pod失联(服务发现)
因为Pod每次创建都对应一个IP地址,而这个IP地址是短暂的,每次随着Pod的更新都会变化,假设当我们的前端页面有多个Pod时候,同时后端也多个Pod,这个时候,他们之间的相互访问,就需要通过注册中心,拿到Pod的IP地址,然后去访问对应的Pod。
2、定义一组pod访问策略(负载均衡)
页面前端的Pod访问到后端的Pod,中间会通过Service一层,而Service在这里还能做负载均衡,负载均衡的策略有很多种实现策略,
例如:    随机    轮询    响应比。
Pod 和 Service 的关系
这里Pod 和 Service 之间还是根据 label 和 selector 建立关联的 【和Controller一样】
例如:service中定义:app:nginx联系的。

selector:
   app:nginx

pod中定义:

labels:
   app:nginx

service中有vip(虚拟ip)一般用于做高可用,当访问时先访问到虚拟ip。然后service在通过服务发现或负载均衡方式访问到后面的pod。
Service常用类型
Service 常用类型有三种:
  •     ClusterIp:集群内部访问
  •     NodePort:对外访问应用使用(对外暴露端口)
  •     LoadBalancer:可以做到NodePort一样的效果,但功能更强大,对外访问应用使用,公有云

举例

我们可以导出一个文件 包含service的配置信息

kubectl expose deployment web --port=80 --target-port=80 --dry-run -o yaml > service.yaml

service.yaml 如下所示:

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web11
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web
status:
  loadBalancer: {}

执行如下命令创建pod,

kubectl apply -f service.yaml

执行如下命令后显示:如果我们没有做设置的话,默认使用的是第一种方式 ClusterIp,也就是只能在集群内部使用

[root@master ~]# kubectl get pod,svc
NAME                       READY   STATUS    RESTARTS      AGE
pod/web-76b56fd968-4qf6x   1/1     Running   2 (29m ago)   2d18h
pod/web-76b56fd968-62xb7   1/1     Running   2 (29m ago)   2d18h
pod/web-76b56fd968-7hg5r   1/1     Running   2 (29m ago)   2d18h
pod/web-76b56fd968-dts64   1/1     Running   2 (29m ago)   2d18h
pod/web-76b56fd968-fm79d   1/1     Running   2 (29m ago)   2d18h
pod/web-76b56fd968-kb97w   1/1     Running   2 (29m ago)   2d18h
pod/web-76b56fd968-ms22c   1/1     Running   2 (29m ago)   2d18h
pod/web-76b56fd968-rp2n2   1/1     Running   2 (29m ago)   2d18h
pod/web-76b56fd968-szmtp   1/1     Running   2 (29m ago)   2d18h
pod/web-76b56fd968-vmn2p   1/1     Running   2 (29m ago)   2d18h

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        8d
service/nginx        NodePort    10.96.241.120    <none>        80:31261/TCP   8d
service/web11        ClusterIP   10.100.177.151   <none>        80/TCP         2d19h

我们可以添加一个type字段,用来设置我们的service类型为:NodePort

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: web
  name: web11
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: web
  type: NodePort
status:
  loadBalancer: {}

修改完命令后,我们使用创建一个pod

kubectl apply -f service.yaml

执行命令后显示如下,可以看到是:NodePort   

[root@master ~]# kubectl get pod,svc
NAME                       READY   STATUS    RESTARTS      AGE
pod/web-76b56fd968-4qf6x   1/1     Running   2 (33m ago)   2d18h
pod/web-76b56fd968-62xb7   1/1     Running   2 (33m ago)   2d18h
pod/web-76b56fd968-7hg5r   1/1     Running   2 (33m ago)   2d18h
pod/web-76b56fd968-dts64   1/1     Running   2 (33m ago)   2d18h
pod/web-76b56fd968-fm79d   1/1     Running   2 (33m ago)   2d18h
pod/web-76b56fd968-kb97w   1/1     Running   2 (33m ago)   2d18h
pod/web-76b56fd968-ms22c   1/1     Running   2 (33m ago)   2d18h
pod/web-76b56fd968-rp2n2   1/1     Running   2 (33m ago)   2d18h
pod/web-76b56fd968-szmtp   1/1     Running   2 (33m ago)   2d18h
pod/web-76b56fd968-vmn2p   1/1     Running   2 (33m ago)   2d18h

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        8d
service/nginx        NodePort    10.96.241.120    <none>        80:31261/TCP   8d
service/web11        ClusterIP   10.100.177.151   <none>        80/TCP         2d19h
service/web21        NodePort    10.111.156.174   <none>        80:31990/TCP   55s

node一般是在内网进行部署,而外网一般是不能访问到的,那么如何访问的呢?
找到一台可以通过外网访问机器,安装nginx,反向代理
    手动把可以访问的节点添加到nginx中
    如果我们使用LoadBalancer,就会有负载均衡的控制器,类似于nginx的功能,就不需要自己添加到nginx上
删除pod以及删除service方法
删除pod和service可访问https://www.zfcdn.xyz/showinfo-3-36274-0.html
无状态和有状态
1、无状态:
之前用deployment创建的pod都是无状态。
  • 无状态认为pod都是一样的。
  • 没有顺序要求
  • 不用考虑在哪一个node运行
  • 随意进行伸缩和扩展
2、有状态:
  • 在无状态下不用考虑的问题在有状态下都有考虑。
  • 让每个pod独立的,保持pod启动顺序和唯一性。
  • 唯一的网络标识符,持久存储。
  • 有顺序,比如mysql主从。
部署有状态应用:
无头service
什么是无头service
ClusterIP是none 则表示无头service
如何部署有状态应用:
1、用StatefulSet部署有状态应用

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None  #这里可以有IP,也可以无IP,推荐无IP,也就是 无头service
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web-statefulset
spec:
  serviceName: "nginx"
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.2
        ports:
        - containerPort: 80
          name: web

执行如下命令生成pod

kubectl apply -f stat.yaml

执行后如下:

[root@master ~]# kubectl apply -f stat.yaml
service/nginx unchanged
statefulset.apps/web-statefulset created

[root@master ~]# kubectl get pod,svc
NAME                    READY   STATUS    RESTARTS   AGE
pod/web-statefulset-0   1/1     Running   0          57s
pod/web-statefulset-1   1/1     Running   0          39s
pod/web-statefulset-2   1/1     Running   0          8s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   8d
service/nginx        ClusterIP   None         <none>        80/TCP    4m57s
[root@master ~]# kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
web-statefulset-0   1/1     Running   0          74s
web-statefulset-1   1/1     Running   0          56s
web-statefulset-2   1/1     Running   0          25s

查看pod,每个都有是唯一的名称。
deployment和statefueset区别:有身份的唯一表示。
是根据主机名+按照一定规则生成域名。例如web-statefulset-0到 web-statefulset-2
每个pod有唯一主机名
唯一域名:
格式:

主机名称.service名称.名称空间.svc.cluster.local

web-StatefulSet-0.nginx.default.svc.cluster.local

部署守护进程DaemonSet:
有时需要在集群中的所有node上运行一个pod的副本。当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
范例:
在每个node节点安装数据采集工具,编写ds.yaml文件

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ds-test
  labels:
    app: filebeat
spec:
  # 标签选择器
  selector:
    matchLabels:
      app: filebeat
  # 标签类型
  template:
    metadata:
      labels:
        app: filebeat
    spec:
      # 配置容器
      containers:
      - name: logs
        image: nginx
        ports:
        - containerPort: 80
        # 挂载目录
        volumeMounts:
        - name: varlog
          mountPath: /tmp/log
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

部署应用:

kubectl apply -f ds.yaml

执行后如下

[root@master ~]# kubectl apply -f ds.yaml
daemonset.apps/ds-test created
[root@master ~]# kubectl get pods
NAME                READY   STATUS    RESTARTS   AGE
ds-test-crpsf       1/1     Running   0          72s
ds-test-glnql       1/1     Running   0          72s

创建后可以进入这个pod看下情况。
进入pod命令:

kubectl exec -it ds-test-crpsf bash

进入后显示如下:

[root@master ~]# kubectl exec -it ds-test-crpsf bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@ds-test-crpsf:/#

进入后执行如下命令查看。

ls /tmp/log

root@ds-test-crpsf:/# ls /tmp/log
anaconda       containers           maillog-20230402   tallylog        vmware-network.8.log
audit           cron               messages          tuned            vmware-network.9.log
boot.log       cron-20230402       messages-20230402  vmware-network.1.log    vmware-network.log
boot.log-20230327  dmesg           pods          vmware-network.2.log    vmware-vgauthsvc.log.0
boot.log-20230330  dmesg.old           rhsm          vmware-network.3.log    vmware-vmsvc-root.log
boot.log-20230402  firewalld           secure          vmware-network.4.log    vmware-vmtoolsd-root.log
btmp           grubby_prune_debug  secure-20230402      vmware-network.5.log    wtmp
btmp-20230402       lastlog           spooler          vmware-network.6.log    yum.log
chrony           maillog           spooler-20230402   vmware-network.7.log

退出pod:

exit

Job和Cronjob任务部署方法
被墙跳转TG:@qianhenetwork QQ 851617266

job是一次性任务。
cronjob是定时任务
部署方法及范例可访问https://www.zfcdn.xyz/showinfo-3-36275-0.html
Secret加密数据创建及挂载
Secret详细说明及演示访问https://www.zfcdn.xyz/showinfo-3-36277-0.html
ConfigMap
configmap创建及挂载可访问https://www.zfcdn.xyz/showinfo-3-36278-0.html
 

3、Pod 定义
(1)下面是 yaml 文件定义的 Pod 的完整内容

apiVersion: v1
kind: Pod
metadata: //元数据
name: string
namespace: string
labels:
-name: string
annotations:
-name: string
spec:
containers: //pod 中的容器列表,可以有多个容器
- name: string //容器的名称
image: string //容器中的镜像
imagesPullPolicy: [Always|Never|IfNotPresent]//获取镜像的策略,默认值为
Always,每次都尝试重新下载镜像
command: [string] //容器的启动命令列表(不配置的话使用镜像内部的命令) args:
[string] //启动参数列表
workingDir: string //容器的工作目录 volumeMounts: //挂载到到容器内部的存储
卷设置
-name: string
mountPath: string //存储卷在容器内部 Mount 的绝对路径 readOnly: boolean //
默认值为读写
ports: //容器需要暴露的端口号列表
-name: string
containerPort: int //容器要暴露的端口
hostPort: int //容器所在主机监听的端口(容器暴露端口映射到宿主机的端口,设置
hostPort 时同一 台宿主机将不能再启动该容器的第 2 份副本)
protocol: string //TCP 和 UDP,默认值为 TCP env: //容器运行前要设置的环境
列表
-name: string value: string
resources:
limits: //资源限制,容器的最大可用资源数量 cpu: Srting
memory: string
requeste: //资源限制,容器启动的初始可用资源数量 cpu: string
memory: string
livenessProbe: //pod 内容器健康检查的设置 exec:
command: [string] //exec 方式需要指定的命令或脚本 httpGet: //通过 httpget 检
查健康
path: string port: number host: string scheme: Srtring httpHeaders:
- name: Stirng value: string
tcpSocket: //通过 tcpSocket 检查健康
port: number initialDelaySeconds: 0//首次检查时间 timeoutSeconds: 0 //检查超时
时间
periodSeconds: 0 //检查间隔时间
successThreshold: 0
failureThreshold: 0 securityContext: //安全配置
privileged: falae
restartPolicy: [Always|Never|OnFailure]//重启策略,默认值为 Always
nodeSelector: object //节点选择,表示将该 Pod 调度到包含这些 label 的 Node 上,以
key:value 格式指定
imagePullSecrets:
-name: string
hostNetwork: false //是否使用主机网络模式,弃用 Docker 网桥,默认否
volumes: //在该 pod 上定义共享存储卷列表
-name: string emptyDir: {} hostPath:
path: string secret:
secretName: string item:
-key: string path: string
configMap: name: string items:
-key: string
path: string

4、Pod 的基本使用方法
在 kubernetes 中对运行容器的要求为:容器的主程序需要一直在前台运行,而不是后台运行。应用需要改造成前 台运行的方式。如果我们创建的 Docker 镜像的启动命令是后台执行程序,则在 kubelet 创建包含这个容器的 pod 之 后运行完该命令,即认为 Pod 已经结束,将立刻销毁该 Pod。如果为该 Pod 定义了 RC,则创建、销毁会陷入一个无 限循环的过程中。Pod 可以由 1 个或多个容器组合而成。
(1)一个容器组成的 Pod 的 yaml 示例
# 一个容器组成的 Pod

apiVersion: v1 kind: Pod metadata:
name: mytomcat labels:
name: mytomcat spec:
containers:
- name: mytomcat image: tomcat ports:
- containerPort: 8000

(2)多个容器组成的 Pod 的 yaml 示例
#两个紧密耦合的容器

apiVersion: v1 kind: Pod metadata:
name: myweb labels:
name: tomcat-redis
spec:
containers:
-name: tomcat image: tomcat ports:
-containerPort: 8080
-name: redis image: redis ports:
-containerPort: 6379

(3)创建

kubectl create -f xxx.yaml

(4)查看

kubectl get pod/po <Pod_name>
kubectl get pod/po <Pod_name> -o wide
kubectl describe pod/po <Pod_name>

(5)删除

kubectl delete -f pod pod_name.yaml
kubectl delete pod --all/[pod_name]

5、Pod 的分类
Pod 有两种类型
(1)普通 Pod
普通 Pod 一旦被创建,就会被放入到 etcd 中存储,随后会被 Kubernetes Master 调度到某个具体的 Node 上并进行绑定,随后该 Pod 对应的 Node 上的 kubelet 进程实例化成一组相关的 Docker 容器并启动起来。在默认情 况下,当 Pod 里某个容器停止时,Kubernetes 会自动检测到这个问题并且重新启动这个 Pod 里某所有容器, 如果 Pod 所在的 Node 宕机,则会将这个 Node 上的所有 Pod 重新调度到其它节点上。
(2)静态 Pod
静态 Pod 是由 kubelet 进行管理的仅存在于特定 Node 上的 Pod,它们不能通过 API Server进行管理,无法与 ReplicationController、Deployment 或 DaemonSet 进行关联,并且kubelet 也无法对它们进行健康检查。
6、Pod 生命周期和重启策略
pod在整个生命周期中被系统定义为各种状态,熟悉pod的各种状态对于理解如何设置pod的调度策略、重启策略是很有必要的
pod状态如下:
状态值 描述
Pending API Server已经创建了pod,但在pod内还有一个或多个容器的镜像没有创建,包括正在下载镜像的过程
Running pod内所有容器均已创建,且至少有一个容器处于运行状态、正在启动状态或正在重启状态
Succeeded pod内所有容器均成功执行后退出,且不会在重启
Failed pod内所有容器均已退出,但至少有一个容器为退出失败状态
Unknown 由于某种原因无法获取该Pod的状态,可能由于网络通信不畅导致的
(2)Pod 重启策略:
pod的重启策略(RestartPolicy)应用于pod内的所有容器,并且仅在pod所处的 node 上 由kubelet 进行判断和重启操作。
当某个容器异常退出或者健康检查 失败时,kubelet将根据RestartPolicy的设置进行相应的操作,pod的重启策略包括Always、OnFailure和Never(默认值为Always):
 
重启策略 描述
Always 当容器失效时,由kubelet自动重启该容器
OnFailure 当容器终止运行且退出码不为0时,由kubelet自动重启该容器
Never 不论容器运行状态如何,kubelet都不会重启该容器
范例:

[root@master test]# vim never.yaml
apiVersion: v1
kind: Pod
metadata:
  name: foo01
  namespace: zy
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 30; exit 3
  restartPolicy: Never


kubelet重启失效容器的时间间隔以symc-frequency乘以2n来计算,例如1、 2、4、8倍等,最长延时5min,并且在成功重启后的10min后重置该时间。
pod的重启策略与控制方式息息相关,当前可用于管理pod的控制器包括
ReplicationController、Job、DaemonSet,还可以通过kubelet管理(静态
pod)。每种控制器对Pod的重启策略要求如下:
控制器 要求
RC和DaemonSet 必须设置为Always,需要保证该容器持续运行
Job OnFailure或Never,确保容器执行完成后不再重启
kubelet 在Pod失效时自动重启它,不论将RestartPolicy设置为什么值,也不会对Pod进行健康检查

(3)常见状态转换:
Pod的容器数 Pod当前状态 发生的事件 Pod结果状态    
      RestartPolicy=Always RestartPolicy=OnFailure RestartPolicy=Never
包含一个容器 Running 容器成功退出 Running Succeeded Succeeded
包含一个容器 Running 容器失败退出 Running Running Failure
包含两个容器 Running 1个容器失败退出 Running Running Running
包含两个容器 Running 容器被OOM杀掉 Running Running Failure











 
301免备案跳转微信公众号
华为服务器
腾讯云服务器大促销。

声明:站长码字很辛苦啊,转载时请保留本声明及附带文章链接:https://www.zfcdn.xyz/showinfo-3-36255-0.html
亲爱的:被墙域名跳转TG:@qianhenetwork QQ:851617266,可否收藏+评论+分享呢?
上一篇:Linux系统通过LVM扩容逻辑卷方法
下一篇:Linux系统设置SSH远程登录时的欢迎或提示信息方法