!!! 主节点配置一定要好!!!

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): (idu):(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

云服务器、公网搭建k8s集群问题解决思路

(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种:

污点取值作用
PreferNoSchedulek8s将尽量避免将Pod调度到该节点上;
NoSchedulek8s将不会将Pod调度到具有该污点的Node上;
NoExecuteK8s将不会将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创建方式作用
自主式Podk8s直接创建出来的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

名词解释
portservice暴露在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的配置,然后对外提供服务;

概念描述
Ingressk8s的一个对象,作用是定义请求如何转发到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

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐