k8s学习
K8S学习之路1.介绍1.1单机部署1.2.虚拟化部署类似window上安装多个linux虚拟机,在虚拟机中部署程序,使得程序之间不会互相影响1.3.容器化部署共享了操作系统,保证每个系统拥有自己的文件系统,CPU,内存,进程空间;运行应用程序所需要的资源被容器包装,并和底层基础架构解耦;容器化的应用程序可以跨云服务商,跨linux操作系统发行版进行部署;1.3.2.存在问题一个容器故障停机了,怎
!!! 主节点配置一定要好!!!
K8S学习之路
1.介绍
1.1单机部署
1.2.虚拟化部署
类似window上安装多个linux虚拟机,在虚拟机中部署程序,使得程序之间不会互相影响
1.3.容器化部署
共享了操作系统,保证每个系统拥有自己的文件系统,CPU,内存,进程空间;运行应用程序所需要的资源被容器包装,并和底层基础架构解耦;容器化的应用程序可以跨云服务商,跨linux操作系统发行版进行部署;
1.3.2.存在问题
一个容器故障停机了,怎样让另外一个容器立刻启动去替补停机的容器;
当并发访问量变大的时候,怎么样做到横向扩展容器数量
容器编排:
Docker Swarm:
Apache Mesos:
Kubernets:
1.3.3.功能
一组服务器集群,实现资源管理的自动化
自我修复:一旦某个容器崩溃,能够在1s内迅速启动新的容器
弹性伸缩:自动对集群中正在运行的容器数量进行调整
服务发现:通过自动发现的形式找到它们所依赖的服务
负载均衡:如果一个服务启动了多个容器,能够自动实现请求的负载均衡
版本回退:如果发现新发布的程序版本有问题,可回退
存储编排:根据容器自身的需求自动创建存储卷
2.kubernetes组件
控制节点,工作节点
ApiServer:资源操作的唯一入口,接受用户输入的命令,提供认证,授权,API注册和发现机制
Scheduler:负载集群资源调度,按照预定的调度资源策略将Pod调度到相应的node节点上;
ControllerManager:负责维护集群的状态,比如程序部署安排,故障检测,自动扩展,滚动更新;
Etcd:负责存储集群中各种资源对象信息
node:集群的数据平面,负责为容器提供运行环境
Kubelet:负责维护容器生命周期;
KubeProxy:负责提供集群内部服务发现和负载均衡
Docker:负责节点上容器的各种操作;
P4
Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控;
Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行;
Pod:k8s的最小控制单元,容器运行在pod中,可包含多个容器;
Controller:控制器,通过它来实现对pod的管理,如启动pod,停止pod,伸缩pod数量等;
Service:pod对外服务的统一入口;
Label:标签,对pod进行分类,同一类pod拥有相同的标签(标签选择器机制);
Namespace:命名空间,用来隔离pod的运行环境;
3.环境配置
3.1.系统环境配置
集群类型:
一主多从:
多主多从:
安装:minikube(搭建单点k8s),kubeadm(搭建k8s集群),二进制包(下载每个组件二进制包,依次安装)
CentOS7.6: 101.34.72.43(从)
CentOs7.6:175.24.4.196(主)
(1)开启时间同步
systemctl start chronyd
systemctl enable chronyd
(2)禁用iptables和firewalld服务
//因为k8s docker本身会产生大量的iptables规则
systemctl stop firewalld
systemctl disable firewalld
systemctl stop iptables(ok)
systemctl disable iptables
(3)禁用selinux(ok)
vim /etc/selinux/config
SELINUX=disabled
(3)禁用swap分区(ok)
swap分区指的是虚拟内存分区,其作用是在物理内存使用完之后,将磁盘空间虚拟成内存来使用
启用swap设备会对系统的性能产生非常负面的影响
swapoff -a
vim /etc/fstab (ok)
注释掉swap分区一行
//加载网桥过滤模块 modprobe br_netfilter
//检查是否加载成功 lsmod | grep br_netfilter
(4)修改linux内核参数
//vim /etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-ip6tables=1
net.bridge.bridge-nf-call-iptables=1
net.ipv4.ip_forward=1
//重新加载配置 sysctl -p /etc/sysctl.d/kubernetes.conf
(5)配置ipvs
//Kubernetes内有2中代理模式,一种是基于iptables,一种是给予ipvs,ipvs性能较高,需手动载入ipvs模块
# 注意在高版本linux中, ipvsadmin 改为了 ipvsadm
yum install ipset ipvsadmin -y
cd /var/lib/rpm
rm -rf __db*
rpm --rebuilddb
yum install ipset ipvsadmin -y
# 注意 nf_conntrack_ipv4在更高版本的linux中改为了 nf_conntrack
cat <<EOF > /etc/sysconfig/modules/ipvs.modules
> #!/bin/bash
> modprobe -- ip_vs
> modprobe -- ip_vs_rr
> modprobe -- ip_vs_wrr
> modprobe -- ip_vs_sh
> modprobe -- nf_conntrack_ipv4
> EOF
chmod +x /etc/sysconfig/modules/ipvs.modules
/bin/bash /etc/sysconfig/modules/ipvs.modules
lsmod |grep -e ip_vs -e nf_conntrack_ipv4
rebot
### 3.2.环境搭建
#### 3.2.1.安装docker
```shell
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum list docker-ce --showduplicates
yum install --setopt=obsoletes=0 docker-ce-18.06.1.ce-3.el7 -y
//添加docker配置文件
//docker默认使用Cgroup Driver为cgroupfs,k8s推荐使用systemd来代替cgroupfs
mkdir /etc/docker
cat <<EOF > /etc/dockr/daemon.json
{
"exec-opts":["native.cgroupdriver=systemd"],
"registry-mirrors":["https://kn0t2bca.mirror.aliyuncs.com"]
}
EOF
systemctl start docker
docker version
systemctl enable docker
3.2.2.安装k8s
vim /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
yum install --setopt=obsoletes=0 kubeadm-1.17.4-0 kubelet-1.17.4-0 kubectl-1.17.4-0 -y
//配置kubelet
vim /etc/sysconfig/kubelet
//同docker,这里我竟然少写了一条横杠,导致后续一直错误
KUBELET_CGROUP_ARGS="--cgroup-driver=systemd"
//代理模式
KUBE_PROXY_MODE="ipvs"
systemctl enable kubelet
P9
//下载所需组件
//查看所需的组件 kubeadm config images list
//kubeadm init
//chmod +x xxx
imageList=(
kube-apiserver:v1.17.4
kube-controller-manager:v1.17.4
kube-scheduler:v1.17.4
kube-proxy:v1.17.4
pause:3.1
etcd:3.4.3-0
coredns:1.6.5
)
for image in ${imageList[@]}
do
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$image
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$image k8s.gcr.io/$image
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/$image
done
集群初始化
仅需在master节点初始化
kubeadm init --kubernetes-version=v1.17.4 --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=all --v=5 --image-repository="registry.aliyuncs.com/google_containers"
(1)问题1-hostname中不能包含 _
修改hostname
hostnamectl set-hostname liyuan-master
//修改完hostname后重新执行上述初始化命令
(2)CPU仅有一核
// 因为学习使用,CPU仅有1核心,因此加上参数 --ignore-preflight-errors=all
kubeadm reset
//查日志
journalctl -xeu kubelet
//tail /var/log/messages
To disable volume calculations, set to 0. (default 1m0s) (DEPRECATED: This parameter should be set via the config file specified by the Kubelet’s --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.)
Sep 14 17:33:49 VM-4-17-centos kubelet: F0914 17:33:49.563394 21612 server.go:156] unknown shorthand flag: ‘c’ in -cgroup-driver=systemd
通过查询日志得知,很明显时因为少些了一条横杆,我立马修改 /etc/sysconfig/kubelet 文件
//最后终于启动成功了
mkdir $HOME/kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown
(
i
d
−
u
)
:
(id -u):
(id−u):(id -g) $HOME/.kube/config
kubectl apply -f
与本机绑定
echo “export KUBECONFIG=/etc/kubernetes/admin.conf” >> /etc/profile
source /etc/profile
(3)网络重坑,腾讯云节点加入阿里云master中
//配置网络
//加入集群
kubeadm join 10.0.4.17:6443 --token 4hulf5.7u0tebesrmkci94i
–discovery-token-ca-cert-hash sha256:d910a3810d308eb8c77e708dc8c1d1683f048bae7f69f953367378ad312dd756
//现在出现了问题,由于初始化时未指定apiserver的地址,因此默认使用的是eth0的内网地址,外部的服务器就无法加入我的集群
因此需要将其配置未外网ip,好让其他节点加入master管理,
https://zhuanlan.zhihu.com/p/74134318
https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init-phase/
kubeadm join 101.34.72.43:6443 --token 4hulf5.7u0tebesrmkci94i
–discovery-token-ca-cert-hash sha256:d910a3810d308eb8c77e708dc8c1d1683f048bae7f69f953367378ad312dd756
–ignore-preflight-errors=all --v=5
//解决方案
https://blog.csdn.net/kavie2333/article/details/113353682
(1)kubeadm init --kubernetes-version=v1.17.4 --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address 101.34.72.43 --ignore-preflight-errors=all --v=5
//其中apiserver-advertise-address填写公网地址,就是云服务器的公网地址
(2)此时kubelet会持续监听 /etc/kubernetes/manifest/etcd.yaml文件的
listen-client-urls以及listen-peer-urls指定的ip地址,由于配置的是公网地址(由云服务器网关统一分配),而本机服务无该地址,因此会一直卡住,此时需要再打开一个新的ssh窗口修改该配置文件
将 --listen-client-urls的第二个ip删去
–listem-peer-urlss修改为https://127.0.0.1:2380
(3)c从节点加入k8s
kubeadm join 101.34.72.43:6443 --token 2t26xn.a9h13tsol044cmgt
–discovery-token-ca-cert-hash sha256:0dab7f29abad7257d577b1e2d4fefabaad562e86afcae59ea955240ce934e85b
(4)从节点执行抛错
原因:主节点的 /etc/kubernetes/admin.config
未同步至从机,将主机上的该文件复制到从机相同位置
vim /etc/profile
添加 export KUBECONFIG=/etc/kubernetes/admin.conf
source /etc/profile
再次运行上述命令即可
kubeadm join 81.68.209.55:6443 --token 12c1sk.xsdx8sow1oazp2z8 --discovery-token-ca-cert-hash sha256:5cfcb6911051469526f6d885df5d6f95316dcb3f4a6ecd5b4784378697388042 --v=5
主机也关闭了firewalld
systemcltl status firewalld
但经过排查确实还是这个原因
因此
firewall-cmd --list-port --zone=public
//开放端口
firewall-cmd --permanent --zone=public --add-port=xxx/tcp
firewall-cmd --reload
stackoverflow
iptables 重定向
iptables -t nat -A OUTPUT -d 81.68.209.55 -j DNAT --to-destination 10.0.4.2
iptables -t nat -A OUTPUT -d 10.0.4.2 -j DNAT --to-destination 81.68.209.55
//查看master节点, 发现其中 public-ip为内网ip
kubectl edit node master
#!/bin/bash 配置iptables 内网<-> 公网转发规则
#//将其写至/etc/profile 中,开机自动执行
iptables -t nat -A OUTPUT -d 10.0.4.2 -j DNAT --to-destination 81.68.209.55
iptables -t nat -A OUTPUT -d 10.0.4.17 -j DNAT --to-destination 101.34.72.43
iptables -t nat -A OUTPUT -d 10.0.4.7 -j DNAT --to-destination 81.68.187.197
(5) failed to set bridge addr: “cni0” already has an IP address different from
ifconfig 查看 cni0 以及 flannel,发现他们网段不一样
解决方案
sudo ifconfig cni0 down
sudo ip link delete cni0
重新创建该虚拟网卡
3.2.3.安装网络插件,使集群间可通信
在master节点安装flannel
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml --v=5
kubectl get pods --all-namespaces
//稍微等一会(1min)就好了
//新
kubectl get pod -n kube-system
//发现有几个pod未运行
kubectl describe pod kube-flannel-ds-884k4 -n kube-system
从机显示为<None>
给从机打标签(=:添加标签;-:移除标签)
kubectl label nodes liyuan-node2 node-role.kubernetes.io/node2=
标签名为:node2
4.资源管理
最小管理单元是Pod,不是容器,通过Pod控制器管理Pod;
Pod,Pod控制器,Service,存储
yaml语言:类似XML,json的结构化标记性语言,以数据作为中心;
缩进不允许使用Tab,仅允许使用空格,且层级需要对齐,类似python,详情间springboot的yaml
(1)命令式对象管理器:直接使用命令操作k8s资源
kubectl run nginx-pod --image=nginx:1.17.1 --port=80
(2)命令式对象配置:通过命令配置和配置文件去操作k8s资源
kubectl create/patch -f nginx-pod.yaml
(3)声明式对象配置:通过apply命令和配置文件去操作k8s资源
kubectl apply -f nginx-pod.yaml //创建,更新
4.1.命令式对象管理
kubectl [command] [type] [name] [flags]
command: 指定操作(create,get,delete)
type:资源类型(deployment, pod, service)
name: 指定资源名称,名称大小写敏感
flags: 指定额外的可选参数
kubectl get pod
kubectl get pod podName
kubectl get pod podName -o yaml/json
kubectl describe pod podName
//在test命名空间下运行nginx进程
kubectl run pod --image=nginx:1.17.1 -n test
//查询某一命名空间下的pods
kubectl get pods -n test
kubectl describe pods podName -n test
kubectl delete pods podName -n test
kubectl delete namespace test
//查看k8s的路由信息
iptables -t nat -nvL
docker rm dockerId;
docker search nacos
docker pull nacos/nacos-server
docker run --name nacos -d -p 8848:8848 -e JVM_XMX=256m -e MODE=standalone nacos/nacos-server
//容器没起来,查看相应容器日志
docker logs -f nacos
//nacos一直遇到各种问题,因此选择适用zookeeper
kubectl exec zk-0 – cat /opt/zookeeper/conf/zoo.cfg
部署之后如何让外部访问?
1.NodePort
(1)暴露端口
kubectl expose deployment countgame --port=8082 --target-port=8082 --type=NodePort -o yaml --dry-run > svc.yaml
(2)创建Service对象
kubectl describe svc serviceName
2.loadBalance
//为namespace = kubernetes-dashboard 下 kubernetes-dsahboard用户赋予管理员权限
kubectl create clusterrolebinding dashboard-cluster --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:kubernetes-dashboard
PersistentValue: 集群中由管理员配置的一段网络存储
PersistentValueClaim: 用于存储的请求,类似Pod,Pod消耗节点资源,PVC消耗存储资源
(1)Namespace
Namespace 实现多套环境资源隔离或多组的资源隔离, 如开发组,测试组;
结合资源配额机制,为不同租户设置不同资源大小;
kubectl get ns //查看命名空间列表
//deafult:默认
//kube-node-lease:集群节点之间的心跳维护
//kube-public:所有人均可访问
//kube-system:与k8s系统相关的资源
kubectl describe ns default
kubectl create ns dev
kubectl delete ns dev
kubectl get ns dev
//ns-dev.yaml方式
apiVersion: v1
kind: Namespace
metadata:
name: dev
kubectl apply -f ns-dev.yaml
kubectl delete -f ns-dev.yaml
kubectl create -f ns-dev.yaml
(2)Pod
Pod为K8s最小单元,程序运行在容器中,容器运行于Pod中;Pod为容器的封装,一个Pod可包含多个容器;
kubectl get pod -n liyuan
//kubectl无单独运行Pod的命令,都是通过Pod控制器实现
kubectl run nginx --image=nginx:1.17.1 --port=80 --namespace liyuan
kubectl describe pod zk -n liyuan
kubectl delete pod podName -n liyuan
//查看控制器
kubectl get deployment -n liyuan
//删除控制器
kubectl delete deployment 上述获取的名称 -n liyuan
//nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: liyuan
spec:
containers:
- image: nginx:1.17.1
imagePullPolicy: IfNotPresent
name: pod
ports:
- name: 80
containerPort:80
protocol: TCP
kubectl create -f nginx.yaml
kubectl delete -f nginx.yaml
(3)label标签
为资源添加标签,用来对他们进行区分和选择;
label:给某个资源打上标识
label selector: env!=dev; env not in (dev,test)
kubectl label pod nginx-pod version=1.0 -n liyuan
kubectl label pod nginx-pod version=2.0 -n liyuan --overwrite
kubectl get pod nginx-pod version=2.0 -n liyuan --show-labels
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: liyuan
labels:
version: "3.0"
env: "test"
spec:
containers:
- image: nginx:1.17.1
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
(4)Deployment
Pod为最小控制单元,但k8s很少直接控制Pod,一般都是通过Pod控制器来完成的,Pod控制器用于Pod管理,确保Pod资源符合预期状态,当Pod资源出现故障时,会尝试重启
kubectl run nginx --image=nginx:1.18.1 --port=80 --replicas=1 -n liyuan
//replicas 副本数
kubectl describe deploy deploymentName -n liyuan
kubectl delete deployment delpoymentName -n liyuan
//yaml方式
apiVersion: v1
kind: Deployment
metadata:
name: zookeeper
namespace: liyuan
spec:
replicas: 3
selector:
matchLabels:
run: zookeeper
template:
metadata:
labels:
run: zk
spec:
containers:
- image: nginx:1.17.1
name: nginx
ports:
- containerPort: 2181
protocol: TCP
(5)Service
Service可以看做是一组同类Pod对外访问接口,通过Service,可以方便的实现服务发现和负载均衡;
//集群内暴露
kubectl expose deploy nginx --na
me=svc-nginx1 --type=ClusterIp --port=80 --target-port=80 -n liyuan
//外部访问
kuebctl expose deploy zookeeper --name=svc-zookeeper-node-ip --type NodePort --port=2181 --target-port=2181 -n liyuan
//查询外部访问端口
kubectl get svc -o wide -n liyuan
//yaml
apiVersion: v1
kind: Service
metadata:
name: svc-zookeeper
namespace: liyuan
spec:
clusterIP: 10.1.191.143
ports:
- port: 2181
protocol: TCP
targetPort: 2181
selector:
run: nginx
type: ClusterIP
2.Pod文件解析
apiVersion: v1
kind: Pod
metadata:
name: string
namespace: string #默认为"default"
labels:
- name: string
spec:
containers:
- name: string #容器名称
image: string #容器镜像名称
imagePullPolicy: [Always|Never|IfNotPresent] #获取镜像的策略
command: [string] # 容器启动命令列表
args: [string] # 容器的启动命令参数列表
workingDir: string # 容器工作目录
volumnMounts: #挂载到容器内部的存储卷配置
- name: string
mountPath: string
readOnly: boolean
ports:
- name: string
containerPort: int #容器所需的端口号
hostPort: int # 容器所在主机需要监督的端口号,默认与Container相同
protocol: string # TCP/UDP
env: #环境变量列表
- name: string
value: string
resources:
limits: #环境资源的设置
cpu: string
memory: string
request:
cpu: string
memory: string
lifeCycle:
postStart: #容器启动时执行该狗钩子
preStop: #容器终止时执行该钩子
livenessProbe:
exec:
command: [string]
httpGet:
path: string
port: number
host: string
schema: string
HttpHeaders:
- name: string
value: string
tcpSocket:
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间
timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间
periodSeconds: 0
restartPolicy: [Never| OnFailure]
nodeName: string
...
kuebctl explain pod
kuebctl explain pod.metadata
apiVersion: v1
kind: Pod
metadata:
name: pod-base
namespace: liyuan
labels:
user: admin
spec:
containers:
- name: nginx
image: nginx:1.17.1
- name: busybox
image: busybox:1.30
# 另类程序,如busybox,为一个工具类集合,k8s集群启动管理后,其会自动关闭,解决方案是令其一直运行,这就要使用到command配置
apiVersion: v1
kind: Pod
metadta:
name: pod-command
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
- name: busybox
image: busybox:1.30
command: ["/bin/sh", "-c", "touch /tmp/hello.txt;while true;do /bin/echo $(data +%T) >> /tmp/hello.txt;sleep 3; done;"]
// kubectl exec pod-command -n liyuan -it -c busybox /bin/sh
ports:
name: string
hostIP: string #将外部端口绑定到主机IP上
containerPort: integer #容器端口
hostPort: integer #在主机上开的端口
protocol: string # TCP/UDP/SCTP
3.资源配额
容器的程序需要运行,需要占用一定的资源,如CPU,内存
//limits: 用于限制运行时容器的最大占用资源,当容器占用资源超过limits时会被终止,并进行重启
//requests: 用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动
apiVersion: v1
kind: Pod
metadata:
name: pod-resources
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
resources:
limits:
cpu: "2"
memory: "10Gi"
requests:
cpu: "1"
memory: "10Mi"
4.Pod生命周期
4.0状态
(1)挂起(Pending):apiserver已经创建了Pod资源对象,但它未被调度完成或仍处于下载镜像过程中
(2)运行中(Running):已调用完成,且所有容器均以创建成功
(3)成功(Succeeded):Pod中所有容器均已成功终止且不会被重启
(4)失败(Failed):所有容器均已终止,但至少有一个容器终止失败
(5)未知(Unknown):apiserver无法正常获取到Pod对象状态信息,通常由网络通信失败所导致
4.1.创建
(1)用户通过kubectl或其他api客户端提交需要创建的pod信息给apiServer
(2)apiServer开始生成pod对象信息,并将信息存入etcd,然后返回确认信息至客户端;
(3)apiServer开始反映etcd中的pod对象要创建,开始为Pod分配主机并将结果信息更新至apiServer
(4)scheduler发现有新的pod对象要创建,开始为Pod分配主机(调度算法)并将结果信息更新至apiServer
(5)node节点上的kubectl发现有pod调度过来,尝试调用docker启动容器,并将结果回送至apiServer
(6)apiServer将接收到的pod状态信息存入etcd中
4.2.初始化
(1)提供主容器镜像中不具备的工具程序或自定义代码
(2)可用于延后应用容器的启动直至其依赖条件得到满足
apiVersion: v1
kind: Pod
metadata:
name: pod-initcontainer
namespace: liyuan
spec:
containers:
- name: main-container
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
initContainers:
- name: test-mysql
image: busybox:1.30
command: ['sh', '-c', 'until ping 192.168.109.201 -c 1; do echo waiting for mysql...; sleep 2; done;']
- name: test-redis
image: busybox:1.30
command: ['sh', '-c', 'until ping x.x.x.x -c 1; do echo waiting for redis...; sleep 2; done;']
//ifconfig ens33:1 192.168.109.201 netmask 255.255.255.0 up
4.3.主容器运行
(1)Post Start 容器启动后钩子
(2)Pre Stop 容器终止前钩子
//Exec
lifecycle:
postStart:
exec:
command:
- cat
- /tmp/healthy
//TCPSocket
lifecycle:
postStart:
tcpSocket:
port: 8080
//HttpGet
lifecycle:
postStart:
httpGet:
path: /
port: 80
host: 192.168.109.100
schema: http #http/https
apiVersion: v1
kind: Pod
metadata:
name: pod-hook-exec
namespace: liyuan
spec:
containers:
- name: main-container
containerPort: 80
lifecycle:
postStart:
exec:
command: ['/bin/sh', "-c", "echo postStart... > /usr/share/nginx/html/index.html"]
preStop:
exec:
command: ["/usr/sbin/nginx", "-s", "quit"]
(3)容器探测
容器探测用于检测容器中的应用实例是否正常工作,若实例状态不符合预期,则k8s会把该问题实例移除;
存活性探测(liveness probe)
检测当前应用实例是否处于正常运行状态,若不是,则重启容器
就绪型探测(readiness probe)
检测应用实例是否可以接收到请求,若否,则不转发流量
(4) 三种探测方式
a.exec命令,在容器内执行一次命令, 若返回为0,则认为程序正常,否则不正常
b.TCPSocket命令,将会尝试访问一个用户容器端口,若能建立改条连接,则认为程序正常
c.HttpGet,调用Web应用的URL,若返回200-399,则认为程序正常
// exec方式
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-exec
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
exec:
command: ["/bin/ls","/tmp"]
resources:
limits: #环境资源的设置
cpu: "0.5"
memory: "500m"
requests:
cpu: "0.1"
memory: "400m"
//TCPSocket方式
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-exec
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
tcpSocket:
port: 80
resources:
limits: #环境资源的设置
cpu: "0.5"
memory: "500m"
requests:
cpu: "0.1"
memory: "400m"
//HttpGet
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-exec
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
httpGet:
port: 80
scheme: HTTP
path: /
resources:
limits: #环境资源的设置
cpu: "0.5"
memory: "500m"
requests:
cpu: "0.1"
memory: "400m"
//上述3种方式,均可配置一些参
initialDelaySeconds: 容器启动后等待多少秒执行第一次探测
timeoutSeconds: 探测超时时间
periodSeconds: 频率
failureThreshold: 连续探测多少次才被认定为失败,默认为3
successThreshold: 连续探测多少次才被认定为成功,默认为1
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-httpget
namespace: liyuan
spec:
containers;
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
httpGet:
scheme: HTTP
port: 80
path: /
initialDelaySeconds: 30
timeoutOutSeconds: 5
4.4.终止
(1)用户向apiServer发送删除Pod对象的命令
(2)apiServer中的Pod对象信息会随着时间的推移而更新,在宽限期内(默认30s内),Pod被视为dead
(3)将pod标记为terminating状态
(4)kubectl在监控到pod对象转为terminating状态的同时启动pod关闭过程
(5)端点控制器监控到pod对象的关闭行为时将其从所有匹配到此端点的service资源的端点列表中移除
(6)若当前pod对象定义了preStop钩子处理器,则在其标记为terminating后即执行该钩子
(7)pod对象中的容器进程收到停止信号
(8)宽限期结束后,若pod中还存在运行的进程,那么pod对象会收到立即终止的信号
(9)kubectl请求apiServer将此Pod资源的宽限期设置为0从而完成删除操作;
5.重启策略
若容器检测出现了问题,k8s就会被对容器所在的Pod进行重启,且可设置等待重启的时间;
Always: 容器失效,自动重启;
OnFailure: 容器种植且退出码不为0时重启;
Never: 不论状态为何,都不重启该容器;
apiVersion: v1
kind: Pod
metadata:
name: pod-liveness-httpget
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
livenessProbe:
httpGet:
scheme: HTTP
port: 80
path: /
initialDelaySeconds: 30
timeoutOutSeconds: 5
restartPolicy: Never
6.Pod调度
一个Pod在哪个Node节点上运行,是由scheduler组件采用相应算法计算出来的;但假如我想将某一Pod调度到某一节点上呢;
自动调度:运行在哪个节点上完全由Scheduler经过一系列算法计算得出;
定向调度:NodeName,NodeSelector
亲和性调度:NodeAffinity,PodAffinity
污点(容忍)调度:Taints,Toleration
6.1.定向调度
//nodeName
apiVersion: v1
kind: Pod
metadata:
name: pod-nodename
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
nodeName: liyuan-node2 #指定调度到该节点
//nodeSelector
apiVersion: v1
kind: Pod
metadata:
name: pod-nodename
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
nodeSelector:
# kubectl label nodes node1 nodeenv=pro
nodeenv: pro #调度到具有nodeenv=pro标签的节点上
6.2.亲和性调度
亲和性:若2个应用经常交互,因此pod可放置于同一节点;
反亲和性:当应用采用多副本部署时,有必要采用反亲和性将实例打散在各个node上,以提高服务可用性;
6.2.1.NodeAffinity
//nodeAffinity
pod.spec.affinity.nodeAffinity
# requiredDuringSchedulingIgnoredDruingExecution
# 需满足下述规则才可以调度
nodeSelectorTerms
matchFields
matchExpressions
key: xxx
values: xxx
operator: Exists, DoesNotExist, In, NotIn, Gt, Lt
# preferredDuringSchedulingIgnoredDuringExecution
# 优先调度到满足指定的规则的Node, 相当于软限制(倾向)
preference
matchFields
matchExpressions
key: xxx
values: xxx
operator: In/NotIn/Exists/DoesNotExist/Gt/Lt
weight: xxx
//NodeAffinity
apiVersion: v1
kind: Pod
metadata:
name: pod-nodeaffinity-required
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
resources:
requests:
cpu: "0.1"
memory: "300Mi"
limits:
cpu: "0.1"
memory: "400Mi"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: nodeenv
operator: In
values: ["xxx", "yyy"]
nodeAffinity:
(1)若nodeAffinity指定了多个nodeSelectorTerms,那么仅需其中一个能够匹配成功即可;
(2)若一个nodeSelectorTerms中有多个matchExpressions,则一个节点必须满足所有才能匹配成功
6.2.2.PodAffinity
pod.spec.affinity.podAffinity
requiredDuringSchedulingIgnoredDuringExecution
namespaces:
topologyKey:
labelSelector:
matchExpressions:
key: xxx
values: xxx
operator: In/NotIn/Exists/DoesNotExist
matchLabels:
preferredDuringSchedulingIgnoredDuringExecution
podAffinityTerm:
namespaces:
topologyKey:
labelSelector:
matchExpressions:
key: xxx
values: xxx
operator:
matchLabels:
weight:
apiVersion: v1
kind: Pod
metadata:
name: pod-pod-affinity-target
namespace: liyuan
labels:
podenv:pro
spec:
containers:
- name: nginx
image: nginx:1.17.1
nodeName: node1
apiVersion: v1
kind: Pod
metadata:
name: pod-podaffinity-required
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: podenv
operator: In
values: ["xxx","yyy"]
topologyKey: kubernetes.io/hostname
6.2.3.PodAntiAffinity
apiVersion: v1
kind: Pod
metadata:
name: pod-podantiaffinity-required
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExection:
- labelSelector:
matchExpressions:
- key: podenv
operator: In
values: ["pro"]
topologyKey: kubernetes.io/hostname
6.3.污点(容忍性)调度
key=value:effect
effect取如下3种:
污点取值 | 作用 |
---|---|
PreferNoSchedule | k8s将尽量避免将Pod调度到该节点上; |
NoSchedule | k8s将不会将Pod调度到具有该污点的Node上; |
NoExecute | K8s将不会将Pod调度到该节点上且同时对该节点已存在的Pod进行驱逐; |
//设置污点
kubectl taint nodes node1 key=value:effect
//去除污点
kubectl taint nodes node1 key:effect-
//去除所有污点
kubectl taint nodes node1 key-
//为什么master点一般不会被调度
因为master节点已经被标注了NoSchedule
apiVersion: v1
kind: Pod
metadata:
name: pod-toleration
namespace: liyuan
spec:
containers:
- name: nginx
image : nginx: 1.17.1
tolerations:
- key: "tag" #要容忍的污点的key
operator: "Equal" # 操作符,支持Equal和Exists
value: "liyuan" #容忍的污点的value
effect: "NoExecute" #添加容忍的规则,这里必须和标记的污点规则相同;
tolerationSeconds: 10 #容忍时间,当effect为NoExecute时生效,表示pod在Node上的停留时间
7.Pod控制器
Pod创建方式 | 作用 |
---|---|
自主式Pod | k8s直接创建出来的Pod,删除后不会自动重建 |
控制器Pod | 由控制器创建,删除后会自动重建 |
Pod控制器:管理Pod的中间层,使用Pod控制器之后,我们只需要告诉Pod控制器,想要多少个啥样的Pod即可,其就会依照限制条件创建满足条件的Pod并确保每一个Pod处于用户期望状态,若Pod在运行过程中出现故障,其会自动重建Pod
类型 | 解释 |
---|---|
ReplicationController | @Deprecated 由ReplicaSet代替 |
ReplicaSet | 保证指定数量的Pod运行,并支持Pod数量变更,镜像版本变更 |
Deployment | 通过控制ReplicaSet来控制Pod,支持回滚升级,版本回退 |
Horizontal Pod AutoScaler | 可根据集群负载自动调整Pod数量,实现削锋填谷 |
DaemonSet | 在集群中制定Node上均运行一个副本,一般用于守护进程类任务 |
Job | 一次性任务 |
CronJob | 周期性任务 |
StatefulSet | 有状态应用 |
7.1.ReplcationSet
保证一定数量的pod正常运行,持续监听这些Pod,一旦发现Pod故障,立马重启,支持Pod数量扩缩容和版本镜像升降级;
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: pc-replicaset
namespace: liyuan
labels:
cntroller: rs
spec:
replicas: 3 #副本数量,默认为1
selector:
matchLabels:
app: nginx-pod # 关联下面的容器
matchExpressions:
- {key: app, operator: In, values: [nginx-pod]}
template:
matadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx: 1.17.1
ports:
- containerPort: 80
resources:
requests:
memory: "500Mi"
cpu: "0.1"
limits:
memory: "500Mi"
cpu: "0.1"
7.1.1.ReplicaSet扩容
(1)kubectl edit rs xxx -n liyuan
(2) kubectl scale rs xxx --replicas=2 -n liyuan
7.1.2.镜像版本修改
(1)kubectl edit rs xxx -n liyuan
(2)kubectl set image rs xxx nginx=nginx:1.17.1 -n liyuan
7.1.3.删除replicaset
kubectl delete rs xxx -n liyuan
7.2.Deployment
Deployment用于通过管理ReplicaSet来间接管理Pod,即Deployment管理ReplicaSet,ReplicaSet管理Pod;
· 支持ReplicaSet所有功能
·支持发布的停止,继续
· 支持版本滚动更新和版本回退
# 记得加上 --record 参数 kubectl create -f xxx.yaml --record
apiVersion: apps/v1
kind: Deployment
metadata:
name: xxx
namespace: liyuan
labels:
controller: deploy
spec:
replicas: 3
revisionHistoryLimit: 3 #保留历史版本数量,默认10
paused: false # 暂停部署,默认false
progressDeadlineSeconds: 600 #部署超时时间
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 30% #最大进额外柯村仔的副本数
maxUnavailable: 30% #最大不可用的Pod的最大值
selector:
matchLabels:
app: nginx-pod
matchExpressions:
- {key: app, operator: In, values: [nginx-pod]}
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
resources:
limits:
memory: "500Mi"
cpu: "0.1"
requests:
memory: "500Mi"
cpu: "0.1"
7.2.1.Deployment扩缩容
(1)kubectl edit deploy xxx -n liyuan
(2)kubectl scale deploy xxx --replicas=5 -n liyuan
7.2.2.镜像更新策略
(1)重建更新:一次性更新全部旧版本
(2)滚动更新:逐渐更新全部旧版本
strategy:
type:
Recreaet: 重建更新
RollingUpdate: 滚动更新
rollingUpdate:
maxUnavailable: 指定在升级过程中不可用Pod的最大数量
maxSurge: 指定在升级过程中可以超过期望的Pod的最大数量,默认为25%
7.2.3.版本回退
修改镜像更新后发现ReplicaSet中确实产生了变化;
kubelet rollout
· status: 显示当前升级状态
· history:显示升级历史记录
· pause: 暂停版本升级过程
· resume:继续已经暂停的版本升级过程
· restart: 重启版本升级过程
· undo: 回滚到上一版本
# //需Kubectl create -f xxx.yaml --record
kubectl rollout status deploy pod-deployment -n liyuan
kubectl rollout history deploy pod-deployment -n liyuan
kubectl rollout undo deploy pod-deployment --to-revision=1 -n liyuan
7.2.4.金丝雀发布
部分更新,使得可以筛选一小部分请求路由到新版本上,以观察新版本是否正常;
kubectl set image deploy pod-deployment nginx=nginx:1.17.4 -n liyuan && kubectl rollout pause deployment pod-deployment -n liyuan
kubectl rollout resume deploy pod-deployment -n liyuan
名词 | 解释 |
---|---|
port | service暴露在cluster ip上的端口,提供给集群内部客户端访问 |
nodePort | 提供给集群外客户访问 |
targetPort | 一般同port,为pod上端口 |
7.3. Horizontal Pod Autoscaler (HPA)
通过监测Pod的使用情况,实现Pod数量自动调整;
HPA获取到每个Pod利用率,然后和HPA中定义的指标进行对别,同时计算出需要伸缩的具体值,最后实现pod数量的调整;
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: pc-hpa
namespace: liyuan
spec:
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 3
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
kubectl get hpa -n liyuan
7.4.DaemonSet
DaemonSet类型的控制器可以保证集群中每一个节点上都运行一个副本,一般用于日志收集,节点监控等场景。即一个Pod提供的功能是节点级别的(每个节点都仅需一个);
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: pc-daemonset
namespace: liyuan
labels:
controller: daemonset
spec:
revisionHistoryLimit: 3
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
selector:
matchLabels:
app: nginx-pod
matchExpressions:
- {key: app, operator: In, values:[nginx-pod]}
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
7.5. Job
主要用于负责批量处理的一次性任务
· 当Pod创建执行成功时,Job将记录成功结束的Pod数量
· 当成功结束的Pod达到制定的数量时,Job将完成执行
apiVersion: batch/v1
kind: Job
metadata:
name: xxx
namespace: liyuan
labels:
controller: job
spec:
completions: 1
parallelism: 1 # 同一时刻应该并发运行的Pod的数量
activeDeadlineSeconds: 30 # Job可运行的时间期限(s)
backoffLimit: 6 #失败后重试的次数
manualSelector: true
selector:
matchLabels:
app: counter-pod
matchExpressions:
- {key: app, operator: In, values: [counter-pod]}
template:
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never # 设置为Never或OnFailure
conatiners:
- name: counter
image: busybox:1.30
7.6. CronJob
在规定的时间点去运行Job任务;
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: xxx
namespace: liyuan
labels:
controller: cronjob
spec:
schedule: xxx #cron表达式
concurrencyPolicy: Allow|Forbid(上次执行未完成,调过本次执行)|Replce(替换,取消当前正在运行的作业并用新作业替换) #并发执行策略,定义前一次任务尚未完成时如何运行后一次任务
failedJobHistoryLimit: 1 #为失败任务保留的历史记录数
successfulJobHistoryLimit: 3 #为成功的任务执行保留的历史记录数,默认为3
startingDeadlineSeconds: 3 #为成功的任务保留的历史记录数,默认为3
jobTemplate:
metadata:
spec:
completions: 1
parallelism: 1
activeDeadlineSeconds: 30
backoffLimit: 6
manualSelector: true
selector:
matchLabels:
app: counter-pod
matchExpressions:
- {key: app, operator: In, values: [counter-pod]}
template:
metadata:
labels:
app: counter-pod
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox:1.30
command: ["bin/sh", "-c", "for i in 9 8 7 6 5 4 3 2 1 0; do echo $i; sleep 2; done"]
7.6.1.cron表达式
|/1||||*|
|–|–|–|–|–|–|
|分钟|小时|日|月|星期|
|0 - 59|0 - 23|1- 31|1 - 12| 0 - 6(0表示周日)|
/1: 表示每分钟
8.Service
8.1. Service 简介
应用程序部署在Pod中,但Pod的ip会变化,因此无法一致通过ip访问;
service会对提供同一个服务的多个Pod进行聚合,并提供方一个统一的入口地址;
Service仅是一个概念,真正起作用的是kube-proxy,每个节点上均运行这一个kube-proxy服务进程,当创建Service的时候会通过api-server向etcd写入创建的service信息,而kube-proxy会基于监听的机制发现折个中Service的变动,然后将最新的Service信息转换成对应的访问规则 -> 该规则会在所有节点上生成;
ipvsadmin -Ln
kube-proxy支持3种工作模式
|工作模式|功能|优缺点|
|–|–|–|–|
|userspace|kubec-proxy会给每一个Service创建一个监听端口,发向ClusterIP的请求被iptables规则重定向到kube-proxy监听的端口上,kube-proxy依据LB短发选择一个提供服务的Pod并和其建立链接,从而将请求转发至Pod上|kube-proxy充当四层负载均衡器,但其运行在usersapce中,因而转发处理时会增加内核和用户空间之间的数据拷贝|
|iptables|Kube-proxy为service后端的每个Pod创建对应的iptables规则,直接将发向ClusterIP的请求重定向到目标Pod上|此时,Kube-proxy仅充当创建iptables规则|
|ipvs|kube-proxy监控Pod的变化并创建相应的ipvs规则|效率高,支持LoadBalance算法|
# 开启ipvs
yum install ipvsadm
kubectl edit cm kube-proxy -n kube-system
kubectl delete pod -l k8s-app=kube-proxy -n kube-system
ipvsadm -Ln
8.2. Service格式
apiVersion: v1
kind: Service
metadata:
name: xxx
namespace: liyuan
spec:
selector:
app: nginx
type: #
clusterIP: #
sessionAffinity: # session亲和性,支持ClusterIP,None,类似sticky session
ports:
- protocol: TCP
port: 3017 #service端口
targetPort: 5003 #Pod端口
nodePort: 30001 #主机端口
|service|解释|
|–|–|–|
|ClusterIP|k8s自动分配的虚拟ip(集群内访问)|
|NodePort|将Service通过Node上的端口暴露给外部|
|LoadBalancer|使用负载均衡器完成到服务的负载转发(需要外部云环境支持)|
|ExternalName|将集群外部服务引入集群内使用|
(1)使用Deployment创建Pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: pc-deployment
namespace: liyuan
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
images: nginx:1.17.1
ports:
- containerPort: 80
# 测试nginx
kubectl exec -it xxxxx -n liyuan /bin/bash
echo "Hello World" > /usr/share/nginx/html/index.html
8.2.1.ClusterIP
apiVersion: v1
kind: Service
metadata:
name: service-clusterip
namespace: liyuan
spec:
sessionAffinity: ClusterIP # sticky hash
selector:
app: nginx-pod
clusterIP: x.x.x.x
type: ClusterIP
ports:
- port: 80
targetPort: 80
8.2.1.1.endPoints
Endpoint是k8s中的一个资源对象,存储在etcd中,用来记录一个service对应的所有Pod的访问地址,其会根据service配置文件中selector描述产生;
一个service由一组Pod组成,这些Pod通过endpoints暴露出来,endpoints是实现实际服务的端点集合。即service与Pod之间通过endpoints实现;
kubectl get endpoints -n liyuan
8.2.1.2.ipvs -Ln
负载均衡;(rr:轮询)
默认使用kube-proxy的轮询,随机策略
8.2.2. Headless Service
此类Service需要开发人员自己实现负载均衡策略,此类Service不会分配ClusterIP,若想要访问Service,仅可通过Service域名进行查询;
(1)将上述配置文件中的ClusterIP设置为None
8.2.3. NodePort
将service的端口映射至Node的一个端上,然后通过NodeIp:NodePort来访问Service;
配合之前生成nginx 的Deployment效果更好;
apiVersion: v1
kind: Service
metadta:
name: service-nodeport
namespace: liyuan
spec:
selector:
app: nginx-pod
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 31000
8.2.4.LoadBalancer
LoadBalancer类似NodePort,向外暴露一个端口,但其会在集群外部再做一个负载均衡设备,该设备需要外部设备环境支持,承担负载均衡功能;
8.2.5.ExternalName
用于引入集群外部的服务,通过externalName属性制定外部的一个服务地址,然后集群内部访问此service就可以访问到外部的服务;
appiVersion: v1
kind: Service
metadata:
name: service-externalname
namespace: liyuan
spec:
type: ExternalName
externalName: www.baidu.com
8.3.Ingress
对外暴露服务
|类型|缺点|
|–|–|–|
|NodePort|占用集群端口|
|LoadBalancer|每个Service均需外接一个Loadbalancer|
Ingress仅需要一个NodePort或一个LoadBalancer即可满足暴露多个Service的需求;
Ingress相当于一个7层负载均衡器,是k8s反向代理的一个抽象,其工作原理雷士nginx,即Ingress会监理映射规则并通过监听这些配置规则将其转换成nginx的配置,然后对外提供服务;
概念 | 描述 |
---|---|
Ingress | k8s的一个对象,作用是定义请求如何转发到service规则 |
Ingress Controller | 具体实现反向代理及负载均衡的程序,对Ingress定义的规则进行解析,根据配置来实现请求转发(nginx,counter,haproxy) |
8.3.1.具体工作方式
(1)用户编写Ingress规则,说明哪个域名对应k8s集群中哪个service
(2)Ingress控制器动态感知Ingress服务规则的变化,生成一段nginx配置
(3)Ingress controller 会将该配置写入运行的nginx服务中,并动态更新;
8.3.2.Ingress使用
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
# tomcat-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namspace: liyuan
spec:
replicas: 3
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
namespace: liyuan
spec:
replicas: 3
selector:
matchLabels:
app: tomcat-pod
template:
metadata:
labels:
app: tomcat-pod
spec:
containers:
- name: tonmcat
image: tomcat:8.5-jre10-slim
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: liyuan
spec:
selector:
app: nginx-pod
clusterIP: None
type: ClusterIP
ports:
- port: 80
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
namespace: liyuan
spec:
selector:
app: tomcat-pod
clusterIP: None
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
8.3.2.1.http代理
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-http
namespace: liyuan
spec:
rules:
- host: nginx.liyuan.com
http:
paths:
- path: /
backend:
serviceName: nginx-service
servicePort: 80
- host: tomcat.liyuan.com
http:
paths:
- path: /
backend:
serviceName: tomcat-service
servicePort: 8080
访问相应服务的http对应的端口即可
8.3.2.2.https代理
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/C=CN/ST=BJ/L=BJ/O=nginx/CN=liyuan.com"
kubectl create secret tls ${tls-secret} --key tls.key --cert tls.crt
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-https
namespace: liyuan
spec:
tls:
- hosts:
- nginx.liyuan.com
- tomcat.liyuan.com
secretName: ${tls-secret}
rules:
- host: nginx.liyuan.com
http:
paths:
- path: /
backend:
serviceName: nginx-service
servicePort: 80
- host: tomcat.liyua.com
http:
paths:
- path: /
backend:
serviceName: tomcat-service
servicePort: 8080
访问相应服务的https对应的端口即可
2.数据存储
容器的生命周期可能很短,会被频繁地创建和销毁容器被销毁的时候,保存在容器中的数据也会被清除,所以就有持久化容器中数据的概念;
volume是Po中可被多个容器访问的共享目录,定义在Pod上,被一个Pod里的多个容器挂载到具体文件目录下,实现同一个Pod中不同容器之间的数据共享及持久化存储;
类型 | |
---|---|
简单存储 | EmptyDir, HostPath, NFS |
高级存储 | PV, PVC |
配置存储 | ConfigMap, Secret |
2.1.简单存储
2.1.1.EmptyDir
一个EmptyDir对应Host上的一个空目录;
Pod销毁就会被删除;
(1)临时目录
(2)容器间共享资源
apiVersion: v1
kind: Pod
metadata:
name: volume-emptydir
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
volumeMounts:
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:1.30
command: ["/bin/sh", "-c", "tail -f /logs/access.log"]
volumeMounts:
- name: logs-volume
mountPath: /logs
volumes:
- name: log-volume
emptyDir: {}
2.1.2.HostPath
HostPath将Node主机中以及实际目录挂载到Pod中,以供容器使用,已达到持久化目的;
apiVersion: v1
kind: Pod
metadata:
name: volume-hostpath
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
volumeMounts:
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:1.30
command: ["/bin/sh", "-c", "tail -f /logs/access.log"]
volumeMounts:
- name: logs-volume
mountPath: /logs
volumes:
- name: logs-volume
hostPath:
path: /root/logs
type: DirectoryOrCreate
类型 | 描述 |
---|---|
DirectoryOrCreate | 目录存在则使用,否则先创建 |
Directory | 目录必须存在 |
FileOrCreate | 文件存在则使用,不存在则先创建再使用 |
File | 文件必须存在 |
Socket | 套接字必须存在 |
CharDevice | 字符设备必须存在 |
BlockDevice | 块设备必须存在 |
2.1.3.NFS
可以解决数据持久化问题,网路存储系统,常用的为NFS, CIFS;
# 在master上安装NFS服务
yum install nfs-utils -y
# 其他子节点也需要安装nfs-utils且启动
# 准备一个共享目录
mkdir /root/data/nfs -pv
#将共享目录以读写权限暴露给王端中所有的主机
vim /etc/exports
more /etc/exports
/root/data/nfs *(insecure,rw, no_root_squash)
chmod 777 /root/data/nfs
vim /etc/sysconfig/nfs
#启动NFS
systemctl restart nfs
# 使用
mount -t nfs -o rw 10.0.0.5:/root/nfs ./test
umount ./test
apiVersion: v1
kind: Pod
metadata:
name: volume-nfs
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
ports:
- containerPort: 80
volumeMounts:
- name: logs-volume
mountPath: /var/log/nginx
- name: busybox
image: busybox:1.30
command: ["/bin/sh","-c","tail -f /logs/access.log"]
volumeMounts:
- name: logs-volume
mountPath: /logs
volumes:
- name: logs-volume
nfs:
server: masterIP
path: /root/data/nfs
2.1.4.PV和PVC
PV:持久化卷,是对底层的共享存储的一种抽象;
PVC:持久化卷声明,是用户对于存储需求的一种声明;
2.1.4.1.PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv2
spec:
nfs:
capacity:
storage: 2Gi
accessNodes: #访问模式 ReadWriteOnce,仅可被单节点挂载;ReadOnlyManay, 只读权限,可被多节点挂载;ReadWriteMany, 读写权限,可被多节点挂载;
storageClassName: #存储类别
persistentVolumeReclaimPolicy: #回收策略;Retain:保留;Recycle:删除PV中数据;Delete:与PV相连的后端存储完成删除操作;
状态:
一个PV的生命周期中,可能处于4种不同状态;
PV状态 | 解释 |
---|---|
Available | 可用,未被任何PVC绑定 |
Bound | 已被PVC绑定 |
Released | 已释放,PVC已被删除但资源还未被集群重新声明 |
Failed | 失败,表示该PV自动回收失败 |
mkdir -pv /root/nfs/pv1
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /root/data/pv1
server: 82.68.209.55
kubectl get pv -o wide
2.1.4.2.PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadta:
name: pvc
namespace: liyuan
spec:
accessModes:
- ReadWriteMany
selector:
matchLabels:
releases: "stable"
storageClassName: # 存储类别
resources:
requests:
storage: 5Gi
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc1
namespace: liyuan
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
关键词 | 描述 |
---|---|
访问模式 | 描述用户对应对存储资源的访问权限 |
选择条件 | 通过设置LabelSelector,使PVS对于系统中已存在的PV进行筛查 |
存储类别 | PVC在定义时可以设置需要的后端存储类别,只有设置了该Class的PV才可以被系统选中 |
资源请求 | 描述对资源的请求 |
apiVersion: v1
kind: Pod
metadata:
name: pod1
namespace: liyuan
spec:
containers:
- name: busybox
image: busybox:1.30
command: ["/bin/sh", "-c", "while true; do echo pod1 >> /root/out.txt; sleep 10; done;"]
volumeMounts:
- name: volume
mountPath: /root/
volumes:
- name: volume
persistentVolumeClaim:
claimName: pvc1 #对应pvc的声明名称
readOnly: false
2.1.5.生命周期
阶段 | 描述 |
---|---|
资源供应 | 管理员手动创建底层存储和PV |
资源绑定 | 用户创建PVC,k8s负责根据PVC中的声明去寻找PV,并绑定用户定义好的PV |
资源使用 | 用户在Pod中像volume一样使用PVC |
资源释放 | 用户删除PVC释放PV |
资源回收 | k8s根据pv设置的回收策略进行资源的回收 |
2.2.ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: configmap
namespace: liyuan
data:
username: liyuan
password: liyuan
apiVersion: v1
kind: Pod
metadata:
name: pod-configmap
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
volumeMounts:
- name: config
mountPath: /cm/config
volumes:
- name: config
configMap:
name: configmap
2.2.1.Secret
类似ConfigMap,但一般用于存储敏感信息,例如密码,秘钥,证书…
echo -n 'liyuan' | base64
apiVersion: v1
kind: Secret
metadata:
name: secret
namespace: liyuan
type: Opaque
data:
username: liyuan
password: liyuan
apiVersion: v1
kind: Pod
metadata:
name: pod-secret
namespace: liyuan
spec:
containers:
- name: nginx
image: nginx:1.17.1
volumeMounts:
- name: config
mountPath: /secret/config
volumes:
- name: config
secret:
secretName: secret
3.安全认证
保证k8s的客户端进行认证和鉴权操作;
User Account
Service Account
阶段 | 描述 |
---|---|
Authentication(认证) | 账号密码 |
Authorization(授权) | 判断用户是否有权限访问特定资源 |
Admission Control(准入控制) | 用于补充授权机制以实现更加精细的访问控制功能 |
3.1.授权管理
公网部署k8s
kubeadm init --kubernetes-version=v1.17.4 --service-cidr=10.96.0.0/12 --pod_network_cidr=10.244.0.0/
16 --ignore-preflight-errors=all --v=10 --images-repository=“registry.aliyuncs.com/google_containers” --apiserver-advertise-address=81.68.209.55
更多推荐
所有评论(0)