K8s 概述

1. 基础知识

1. kubernets 是什么

Kubernetes是一个轻便、可扩展开源平台,用于管理容器化应用和服务。通过Kubernetes能够进行应用的自动化部署扩缩容。在Kubernetes中,会将组成应用的容器组合成一个逻辑单元以更易管理和发现。Kubernetes积累了作为Google生产环境运行工作负载15年的经验,并吸收了来自于社区的最佳想法和实践。Kubernetes经过这几年的快速发展,形成了一个大的生态环境,Google在2014年将Kubernetes作为开源项目。

2. Kubernetes的关键特性包括:

  • 自动化装箱:在不牺牲可用性的条件下,基于容器对资源的要求和约束自动部署容器。同时,为了提高利用率和节省更多资源,将关键和最佳工作量结合在一起。
  • 自愈能力:当容器失败时,会对容器进行重启;当所部署的Node节点有问题时,会对容器进行重新部署和重新调度;当容器未通过监控检查时,会关闭此容器;直到容器正常运行时,才会对外提供服务。
  • 水平扩容:通过简单的命令、用户界面或基于CPU的使用情况,能够对应用进行扩容和缩容。
  • 服务发现和负载均衡:开发者不需要使用额外的服务发现机制,就能够基于Kubernetes进行服务发现和负载均衡。
  • 自动发布和回滚:Kubernetes能够程序化的发布应用和相关的配置。如果发布有问题,Kubernetes将能够回归发生的变更。
  • 保密和配置管理:在不需要重新构建镜像的情况下,可以部署和更新保密和应用配置。
  • 存储编排:自动挂接存储系统,这些存储系统可以来自于本地、公共云提供商(例如:GCP和AWS)、网络存储(例如:NFS、iSCSI、Gluster、Ceph、Cinder和Floker等)。

2.kubernets 架构介绍

  • APISERVER:所有服务访问的统一接口
  • CrontrollerManager:维持副本期望值数目
  • Scheduler:负载介绍任务,选择合适的节点进行任务的分配
  • ETCD:键值对数据库,存储k8s集群所有重要信息(持久化)
  • kubelet:直接跟容器引擎交互实现容器的生命周期管理
  • kube-proxy:负责写入规则至 IPTABLES、IPVS 实现服务映射访问
  • COREDNS:可以为集群中SVC(交换虚拟电路)创建一个域名IP的对应关系解析
  • DASHBOARD:给 K8S 集群提供一个 B/S (浏览器/服务器模式)结构访问解析
  • INGRESS CONTROLLER:官方只能实现四层代理,INGRESS 可以实现七层代理

3. Pod 介绍

自主式 pod:

  • 自主式就是没有控制器管理的 pod,而 pod 就是多个容器的集合。
  • 这些容器的网络【容器开放的端口必须一致】和存储卷都和 pause 容器共享。
  • 在开启一个pod的时候,必然会开启 pause。

控制器管理的 pod:

  • RC 用来确保应用容器的副本数量始终和用户定义的数量一致。
  • RSRC 基础上,支持集合式的 selector(用标签批量操作pod)
  • deployment:管理多个 RS 然后再创建 pod ,并且可以创建新版本的RS,当新的 RS 创建之后,会停用老版本的RS而不是删除。
  • HPA:仅适用于DeploymentRS ,在V1 版本中仅支持根据Pod 的CPU 利用率扩所容,比如设置当 pod 的 cpu 利用率达到 80% 时就扩容新的 pod。
  • StatefulSet:是为了解决有状态服务的问题,比如数据库这种和用户交互的服务。
  • DaemonSet :当有Node 加入集群时,也会为他们新增一个Pod 。应用场景为:运行集群存储daemon、日志收集、服务监控
  • Job :负责批处理任务,保证批处理任务的一个或多个Pod 成功结束,即定时任务

4. 网络通讯方式

综述:

​ Kubernetes 的网络模型假定了所有Pod 都在一个可以直接连通的扁平的网络空间中【都在同一个网段,彼此可以互相ping通】,这在GCE(Google Compute Engine)里面是现成的网络模型,Kubernetes 假定这个网络已经存在。而在私有云里搭建Kubernetes 集群,我们需要自己实现这个网络假设,将不同节点上的Docker 容器之间的互相访问先打通,然后运行Kubernete。

不同 pod 同一主机之间的通讯:

​ Pod1 与Pod2 在同一台机器,由Docker0 网桥直接转发请求至Pod2。

不同 pod 不同主机之间的通讯:

Pod的地址是与 docker0 在同一个网段的,但 docker0 网段与宿主机网卡是两个完全不同的IP网段,并且不同Node之间的通信只能通过宿主机的物理网卡进行。将Pod的IP和所在Node的IP关联起来,通过这个关联让Pod可以互相访问。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R9LrBpAl-1653055923912)(D:\云计算工坊\图片\K8S\Snipaste_2021-05-25_10-18-09.png)]

不同层级的通讯:

如搭建 LAMP 和 Nginx 时,Nginx 要反向代理 Apache 集群,就不是直接访问 Apache 集群,而是通过访问 service,再访问 Nginx。外网访问也是如此。

2. K8S 集群部署

  • 环境准备

    172.16.1.142     -master         # 主节点
    172.16.1.143	  -n001          # 从节点 01
    172.16.1.144     -n002				 # 从节点 02
    
  • 系统优化

    # 安装依赖包
    yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wgetvimnet-tools git
    
    # 设置防火墙为 Iptables 并设置空规则
    systemctl  stop firewalld  &&  systemctl  disable firewalldyum -y install iptables-services  &&  systemctl  start iptables  &&  systemctl  enable iptables&&  iptables -F  &&  service iptables save
    
    # 关闭 Selinux
    swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab  # 禁用 sawpoff 
    setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
    
    # 调整内核参数,对于 K8S
    cat > kubernetes.conf <<EOF
    net.bridge.bridge-nf-call-iptables=1
    net.bridge.bridge-nf-call-ip6tables=1
    net.ipv4.ip_forward=1
    net.ipv4.tcp_tw_recycle=0
    vm.swappiness=0 
    vm.overcommit_memory=1
    fs.inotify.max_user_instances=8192
    fs.inotify.max_user_watches=1048576
    fs.file-max=52706963
    fs.nr_open=52706963
    net.ipv6.conf.all.disable_ipv6=1
    net.netfilter.nf_conntrack_max=2310720
    EOF
    cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
    sysctl -p /etc/sysctl.d/kubernetes.conf
    
    # 设置 rsyslogd 和 systemd journald
    mkdir /var/log/journal # 持久化保存日志的目录
    mkdir /etc/systemd/journald.conf.d
    cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
    [Journal]
    # 持久化保存到磁盘
    Storage=persistent
    # 压缩历史日志
    Compress=yes
    SyncIntervalSec=5m
    RateLimitInterval=30s
    RateLimitBurst=1000
    # 最大占用空间
    10GSystemMaxUse=10G
    # 单日志文件最大 200M
    SystemMaxFileSize=200M
    # 日志保存时间 2 周
    MaxRetentionSec=2week
    # 不将日志转发到 
    syslogForwardToSyslog=no
    EOF
    systemctl restart systemd-journald
    
    # 更换系统内核
    rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
    # 安装完成后检查 /boot/grub2/grub.cfg 中对应内核 menuentry 中是否包含 initrd16 配置,如果没有,再安装一次!
    yum --enablerepo=elrepo-kernel install -y kernel-lt
    # 设置开机从新内核启动
    grub2-set-default 'CentOS Linux (4.4.189-1.el7.elrepo.x86_64) 7 (Core)'
    reboot
    uname -r
    
  • 安装 K8S

    # kube-proxy开启ipvs的前置条件
    modprobe br_netfilter
    cat > /etc/sysconfig/modules/ipvs.modules <<EOF
    #!/bin/bash
    modprobe -- ip_vs
    modprobe -- ip_vs_rr
    modprobe -- ip_vs_wrr
    modprobe -- ip_vs_sh
    modprobe -- nf_conntrack_ipv4
    EOF
    chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules &&lsmod | grep -e ip_vs -e nf_conntrack_ipv4
    
    #  安装 Docker 软件
      ### 转到 docker 部署
      
    # 安装 Kubeadm (主从配置)
    cat <<EOF > /etc/yum.repos.d/kubernetes.repo
    [kubernetes]
    name=Kubernetes
    baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
    enabled=1
    gpgcheck=0
    repo_gpgcheck=0
    gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
    http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
    EOF
    yum -y  install  kubeadm-1.15.1 kubectl-1.15.1 kubelet-1.15.1
    systemctl enable kubelet.service
    
    # 配置 kubeadm 镜像文件
    	# 将 kubeadm-basic.images.tar.gz 文件传到 linux 主机中
    tar -zxvf kubeadm-basic.images.tar.gz 
     vim load.sh
     ------------------------------------------------------
     #!/bin/bash
    ls /usr/local/src/kubeadm-basic.images > /tmp/images.txt
    cd /usr/local/src/kubeadm-basic.images
    for i in $(cat /tmp/images.txt);do
    	docker load -i $i
    done
    -------------------------------------------------------
    sh load.sh && cd ~
    ###############################   以上无论主从都配    ###############################
    ###############################   以下只有主节点配    ###############################
    kubeadm config print init-defaults > kubeadm-config.yaml
    vim kubeadm-config.yaml   # 配置以下内容,有的就改没有的就添加
    -------------------------------------------------------
    localAPIEndpoint:
      advertiseAddress: 192.168.80.142
    kubernetesVersion: v1.15.1
    networking:
      dnsDomain: cluster.local
      podSubnet: "10.244.0.0/16"
      serviceSubnet: 10.96.0.0/12
    scheduler: {}
    ---   
    apiVersion: kubeproxy.config.k8s.io/v1alpha1    
    kind: KubeProxyConfiguration    
    featureGates:      
            SupportIPVSProxyMode: true    
    mode: ipvs
    -------------------------------------------------------
    kubeadm init --config=kubeadm-config.yaml --experimental-upload-certs | tee kubeadm-init.log
    cat kubeadm-init.log  # 根据 To start using your cluster, you need to run the following as a regular user: 下面的内容进行配置
    mkdir -p $HOME/.kube
    cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    chown $(id -u):$(id -g) $HOME/.kube/config
    kubectl get node    # 查看有没有节点,判断是否成功
    
    # 部署网络
    mkdir install-k8s/
    mv kubeadm-init.log kubeadm-config.yaml install-k8s/
    cd install-k8s/
    mkdir core
    mv * core/
    mkdir plugin
    cd plugin/
    mkdir flanne
    	# 将 kube-flannel.yml 文件传到该目录下
    kubectl create -f kube-flannel.yml
    kubectl get pod -n kube-system # 查看有没有 flannel
    kubectl get node    # 是不是 ready
    ###############################    从节点配置    ###############################
    kubeadm join 192.168.80.142:6443 --token abcdef.0123456789abcdef     --discovery-token-ca-cert-hash sha256:8bfee48fe1560b64828d3e375fb9944a460933e9057cf60bd5b7ede41437ea45   
    ## 以上两个都配
    

3. 资源清单

1. K8S 中的资源

综述:

​ K8s中所有的内容都抽象为资源,资源实例化之后,叫做对象;【自我理解:感觉就和 Java 中的类、模块差不多,需要时直接调用相应的需求即可。】

资源的分类:

(一)名称空间级别

  • 工作负载型资源:Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob
  • 服务发现及负载均衡型资源: Service、Ingress
  • 配置与存储型资源:Volume(存储卷)、CSI
  • 特殊类型的存储卷:ConfigMap(当配置中心来使用的资源类型)、Secret(保存敏感数据)、DownwardAPI(把外部环境中的信息输出给容器)

(二)集群级别的资源

  • Namespace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBinding

(三)元数据型资源

  • HPA、PodTemplate、LimitRange

2. K8S 中的常见字段介绍

(一)必须存在的字段

字段名字段类型说明
apiVersionstring[^2]指定 api 的版本,目前是 v1,可以用 **kubectl apiversions **查询
kindstringyml 文件中定义的资源类型是什么,比如 pod
metadataobject[^3]元数据对象
metadata.namestring元数据对象的名字,比如定义 pod 的名字
metadata.namespacestring元数据对象的命名空间,由我们自己定义
metadata.labelsobject元数据对象的标签
metadata.labels.versionstring元数据对象的标签的版本
specobject详细定义对象
spec.containers[]object定义容器某些属性
spec.containers[].namestring定义容器的名字
spec.containers[].imagestring定义容器使用那个镜像

3. 简单 pod 的定义

(一)定义 pod

mkdir /kubeyml
vim /kubeyml/pod001.yml
------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:						# 大前提
name: myapp-pod
labels:
app: myapp
version: v1
spec:							# 小前提
containers:
  - name: app
    image: 192.168.80.141:5000/codefun/myapp:v1
  - name: test
    image: 192.168.80.141:5000/codefun/myapp:v1
------------------------------------------------------------

(二)启动和排查错误

`kubectl` apply -f pod001.yml    # 将 yml 文件生成相应的资源

`kubectl` get pod				  # 查看 pod 是否建立成功
# NAME        READY      STATUS           RESTARTS      AGE
# myapp-pod     1/2     CrashLoopBackOff      8          4h28m
# pod 名    启动数/总数		状态				 重启次数		创建了多长时间

kubectl describe pod myapp-pod    # 查看指定 pod 的详细信息,比如 pod 的详细信息,容器的详细信息,容器的执行事件,存储卷信息

kubectl logs -p myapp-pod -c test  # 查看指定 pod 下的指定容器的日志

kubectl delete pod myapp-pod     # 删除指定pod

4. 容器的生命周期

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pi9s6Zxt-1653055923913)(D:\云计算工坊\图片\K8S\容器的生命周期.png)]

1. init C 的详解与模板应用

(一)Init 容器介绍

特点:

  • init容器总是运行到成功完成为止
  • 每个init容器都必须在下一个Init容器启动之前成功完成
  • 如果pod重启,所有init c容器必须重新执行
  • init 容器具有应用容器的所有字段,除了就绪检测和生存检测。
  • pod中的每个appinit容器的名称必须唯一

作用:

  • 它们可以包含并运行实用工具,但是出于安全考虑,是不建议在应用程序容器镜像中包含这些实用工具的【比如在主容器启动之前,我们需要梳理某些文件或者动作,但是这些动作或文件可能只运行一次,为了减少主容器的工作量】
  • 应用程序镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。【也就是一部分是构建代码init c,而另一部分运行代码 主容器】
  • Init容器使用LinuxNamespace它们能够具有访问Secret的权限,而应用程序容器则不能。
  • 若 pod 内有依赖性强的容器,则可以使用init c 来指定容器启动的顺序,从而保证 pod 的运行状态

总结

就是充分利用 init cmain c相互剥离但又能控制main c 的特点,以及优先于main c 执行的特点。

(二) 模板应用

vim /kubeyml/pod002.yml
------------------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:  
app: myapp
spec: 
containers:  
- name: myapp-container  
  image: busybox    
  command: ['sh','-c','echo The app is running! && sleep 3600'] 
initContainers:  
- name: init-myservice  # 检测 myservice 的 DNS,若不成功就返回 waiting for myservice 然后睡两秒再次检测。
  image: busybox   
  command: ['sh','-c','until nslookup myservice; do echo waiting for myservice; sleep 2;done;'] 
- name: init-mydb   
  image: busybox   
  command: ['sh','-c','until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
------------------------------------------------------------------------------------------------------
`kubectl` apply -f pod002.yml

kubectl get pod
# NAME        READY   STATUS     RESTARTS   AGE
# myapp-pod   0/1     Init:0/2   0          10m

cat /kubeyml/svs001.yml 
------------------------------------------------------------------------------------------------------
kind: Service
apiVersion: v1
metadata:  
name: myservice
spec:  
ports:    
  - protocol: TCP      
    port: 80      
    targetPort: 9376
------------------------------------------------------------------------------------------------------
`kubectl` apply -f svs001.yml
kubectl get pod
# NAME        READY   STATUS     RESTARTS   AGE
# myapp-pod   0/1     Init:1/2   0          10m

cat /kubeyml/svc002.yml 
-----------------------------------------------------------------------------------------------------
kind: Service
apiVersion: v1
metadata:  
name: mydb
spec:  
ports:
  - protocol: TCP
    port: 80
    targetPort: 9377
-----------------------------------------------------------------------------------------------------
`kubectl` apply -f svc002.yml
kubectl get pod
# NAME        READY   STATUS    RESTARTS   AGE
# myapp-pod   1/1     Running   0          13m

总结一下

  • 使用 initContainers创建 init c 容器,并执行检测 DNS 解析命令
  • 当一个 init c 容器执行完后就会死亡,并且执行下一个 init c 容器
2. 探针的使用

(一)什么是探针

  • 探针是由kubelet对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的Handler

(二)探针的三种处理程序

  • ExecAction:在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。

  • TCPSocketAction:对指定端口上的容器的 IP地址进行TCP检查。如果端口打开,则诊断被认为是成功的。

  • HTTPGetAction:对指定的端口和路径上的容器的IP地址执行HTTP Get请求。如果响应码大于等于200且小于400,则成功

  • 探测结果:

  • 成功:容器通过了诊断。

  • 失败:容器未通过诊断。

  • 未知:诊断失败,因此不会采取任何行动

(三)探测方式

  • livenessProbe:指示容器是否正在运行。如果存活探测失败,则kubelet会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为Success
  • readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success

(四)readinessProbe探测实例

cat /kubeyml/pod003.yml 
---------------------------------------
apiVersion: v1
kind: Pod
metadata:  
name: readiness-httpget-pod
namespace: default
spec:
containers:
- name: readiness-httpget-container
  image: wangyanglinux/myapp:v1
  imagePullPolicy: IfNotPresent           # 镜像拉取规则,如果本地有就不向远程拉取
  readinessProbe:                    # 就绪检测
    httpGet:                       # 检测方案:httpget 方案
      port: 80
      path: /index1.html               # 检测的路径本来就没有
    initialDelaySeconds: 1              # 初始化的延迟
    periodSeconds: 3                  # 重试的时间
---------------------------------------
`kubectl` get pod
# NAME              READY                 STATUS    RESTARTS      AGE
# readiness-httpget-pod   0/1 # 没有真正的开启        Running   1          86m

kubectl exec -it readiness-httpget-pod -- /bin/sh   ###  进入容器的命令,还可跟 -c 命令
/ # cd /usr/share/nginx/html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html # echo "hello world" > index1.html
/usr/share/nginx/html # exit
[root@master ~]# kubectl get pod
# NAME                READY   STATUS    RESTARTS       AGE
# readiness-httpget-pod   1/1##     Running   1            91m

(五)生存检测案例

cat pod004.yml ## ExecAction 类型
-----------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: live-exec-pod
namespace: default
spec:
containers:
- name: live-exec-con
  image: busybox
  imagePullPolicy: IfNotPresent
  command: ["/bin/sh","-c","touch /tmp/live;sleep 10;rm -rf /tmp/live;sleep 3600"]   # 创建一个文件
  livenessProbe:
    exec:
      command: ["test","-e","/tmp/live"]    # 检测是否有该文件
    initialDelaySeconds: 1
    periodSeconds: 3
------------------------------------------------------------------------------------------
`kubectl` get pod -w   # 获得 pod 的持续性状态
# AME            READY   STATUS    RESTARTS   AGE
# live-exec-pod   1/1     Running   0          5s
# live-exec-pod   1/1     Running   1          49s   # 在这里重启了一次

cat /kubeyml/pod005.yml ## HTTPGetAction 类型
------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: live-httpget-pod
namespace: default
spec:
containers:
  - name: live-httpget-con
    image: 192.168.80.141:5000/codefun/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 8080    # 对外开放 80 端口
    livenessProbe:
      httpGet:
        port: http
        path: /index.html   # 使用 http 协议进行 get 请求,并且访问 80 端口
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 10
------------------------------------------------------------------------------------------
`kubectl` exec -it live-httpget-pod --  rm -rf /usr/share/nginx/html/index.html
`kubectl` get pod
# NAME            READY   STATUS    RESTARTS   AGE
# live-httpget-pod   1/1     Running   1       2m45s   # 这里重启了一次,因为检测不到 index.html

cat /kubeyml/pod006.yml
------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: live-tcp-pod
namespace: default
spec:
containers:
- name: live-tcp-con
  image: 192.168.80.141:5000/codefun/myapp:v1
  livenessProbe:
    initialDelaySeconds: 5
    timeoutSeconds: 1
    tcpSocket:
      port: 8080
    periodSeconds: 3
------------------------------------------------------------------------------------------
# kubectl get pod
# NAME        READY   STATUS          RESTARTS   AGE
# live-tcp-pod   0/1    CrashLoopBackOff   3        57s    # 检测到 8080 没有监听,所以一直重启
3. 启动程序和停止程序的定义

(一) 案例实施

cat /kubeyml/pod007.yml 
------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-pod
spec:
containers:
- name: lifecycle-con
  image: 192.168.80.141:5000/codefun/myapp:v1
  lifecycle:
    postStart:
      exec:
        command: ["/bin/sh","-c","echo hello world > /usr/share/message"]
    preStop:
      exec:
        command: ["/bin/sh","-c","echo hello bad > /usr/share/message"]
------------------------------------------------------------------------------------------
`kubectl` apply -f /kubeyml/pod007.yml # 启动时向 /usr/share/message 中插入 hello world
pod/lifecycle-pod created
`kubectl` exec -it lifecycle-pod -- cat /usr/share/message
hello world
4. pod 的五种状态
  • 挂起(Pending):Pod已被Kubernetes系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间,这可能需要花点时间
  • 运行中(Running):该Pod已经绑定到了一个节点上,Pod中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态
  • 成功(Succeeded):Pod中的所有容器都被成功终止,并且不会再重启
  • 失败(Failed):Pod中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止
  • 未知(Unknown):因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败

4. 创建控制器

控制器:

​ 用来控制和管理 pod 的工具

1. Deployment 控制器

1. 使用环境
  • 确保容器应用的副本数始终保持在用户定义的副本数
  • 定义Deployment来创建Pod和ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续Deployment
2. 控制器基础案例

(一) 部署 RS

cat /kubeyml/rs001.yml
--------------------------------------------------------------------------------------------
apiVersion: extensions/v1beta1     # 定义 api 版本,控制器好像都是这个版本
kind: ReplicaSet              # 创建的类型
metadata:							 # 大前提
name: frontend
spec:								 # 小前提,细节
replicas: 3
selector:							 # 选择器:即定义选择那些 pod 加入 RS
matchLabels:
tier: frontend          # 定义一个标签,有此标签的 pod 加入 RS
template:							 # 设置模板 pod
metadata:
labels:
  tier: frontend        # 定义标签
spec:
containers:
   - name: rs-nginx
     image: 192.168.80.141:5000/codefun/myapp:v1
     env:
     - name: GET_HOST_FROM
       value: dns
     ports:
     - containerPort: 80
--------------------------------------------------------------------------------------------
`kubectl` label pod frontend-7w77k tier=codefun --overwrite=True
pod/frontend-7w77k labeled

`kubectl` get pod --show-labels    # 又多了一个 pod 
NAME             READY   STATUS    RESTARTS   AGE     LABELS
frontend-72nzv   1/1     Running   0          5s      tier=frontend
frontend-7w77k   1/1     Running   0          4h14m   tier=codefun
frontend-mhfwb   1/1     Running   0          4h14m   tier=frontend
frontend-sq98s   1/1     Running   0          4h14m   tier=frontend

(二)部署 Deployment

cat /kubeyml/dep001.yml 
--------------------------------------------------------------------------------------------
apiVersion: extensions/v1beta1
kind: Deployment				# 就 kind 值不一样,其他基本相同
metadata:
name: nginx-dep
spec:
replicas: 3
selector:						# 创建没有什么意义
 matchLabels:
   app: nginx
template:
 metadata:
   labels:
     app: nginx
 spec:
   containers:
      - name: nginx-con
        image: 192.168.80.141:5000/codefun/myapp:v1
        ports:
        - containerPort: 80
--------------------------------------------------------------------------------------------
`kubectl` create -f /kubeyml/dep001.yml --record## --record参数可以记录命令,我们可以很方便的查看每次 revision 的变化
`kubectl` get deployment
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
nginx-dep   3/3     3            3           13m

(三)Deployment 控制器的应用

(1)扩容副本

`kubectl` scale deployment deployment-name --replicas 扩容数   # 语法
## 实例:
`kubectl` scale deployment nginx-dep --replicas 5          # 将副本数扩容为 5 个
deployment.extensions/nginx-dep scaled
kubectl get deployment                            # 只是在原来的基础上扩容,而不是新增 rs
NAME  DESIRED  CURRENT   READY   AGE
nginx 5     5         5       21m

(2)更新镜像

`kubectl` set image deployment/deployment-name container-name=image-name  # 语法
## 示例:
`kubectl` set image deployment/nginx-dep nginx-con=wangyanglinux/myapp:v2  
`kubectl` get rs       # 新增一个 RS, 将 pod 滚动更新到 新的 RS
NAME                   DESIRED   CURRENT   READY   AGE
nginx-dep-6f58ddf7d9   0         0         0       28m
nginx-dep-768b498b9f   5         5         5       93s

(3)回滚 RS

### 基础命令
`kubectl` rollout undo deployment/deployment-name  # 语法
## 示例:
`kubectl` rollout undo deployment/nginx-dep  # 默认回滚到上一个 rs
deployment.extensions/nginx-dep rolled back
`kubectl` get rs
NAME                   DESIRED   CURRENT   READY   AGE
nginx-dep-6f58ddf7d9   5         5         4       36m
nginx-dep-768b498b9f   0         0         0       8m42s

查看回滚状态

kubectl rollout status deployment/devloyment-name

查看历史版本的 rs

kubectl rollout history deployment/devloyment-name
deployment.extensions/nginx-dep
REVISION CHANGE-CAUSE
2 kubectl apply --filename=/kubeyml/dep001.yml --record=true
4 kubectl apply --filename=/kubeyml/dep001.yml --record=true
5 kubectl apply --filename=/kubeyml/dep001.yml --record=true

回滚到指定的版本

kubectl rollout undo deployment/deployment --to-revision=REVISION

暂停deployment更新

kubectl rollout pause deployment/deployment-name

回滚策略

如果创建了10个 v1 版本的 deployment,当创建到第三个的时候,执行 v1 版本 改为 v2 版本的操作,这时就不会再创建 v1 版本的,而是将 v1 的三个杀死,创建 v2 版本的。

deployment 更新策略

· Deployment 可以保证在升级时只有一定数量的 Pod 是 down 的。默认的,它会确保至少有比期望的Pod数量少一个是up状态(最多一个不可用)
· eployment 同时也可以确保只创建出超过期望数量的一定数量的 Pod。默认的,它会确保最多比期望的Pod数量多一个的 Pod 是 up 的(最多1个 surge )

设置历史版本的个数

您可以通过设置.spec.revisonHistoryLimit项来指定 deployment 最多保留多少 revision 历史记录。默认的会保留所有的 revision;如果将该项设置为0,Deployment 就不允许回退了.

实现:

vim /kubeyml/dep001.yml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dep
spec:
replicas: 3

revisionHistoryLimit: 1 # 保留两个


2. DaemonSet 控制器

1. 使用环境

DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。

  • 运行集群存储
  • 运行日志收集
  • 运行监控
2. 控制器基础案例
cat /kubeyml/dae.yml 
--------------------------------------------------------------------------------------------
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: dae
  labels:
    app: dae-v1           # 一样
spec:
  selector:
    matchLabels:
      name: dae-v1        # 一样
  template:
    metadata:
      labels:
        name: dae-v1      # 一样
    spec:
      containers:
      - name: dae-v1
        image: 192.168.80.141:5000/codefun/myapp:v1 
--------------------------------------------------------------------------------------------
 `kubectl` create -f /kubeyml/dae.yml

3. Job 和 Cronjob 控制器

1. 使用环境

Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束

Cron Job 基于时间的 Job,即:

  • 在给定时间点只运行一次
  • 周期性地在给定时间点运行
2. 控制器的基础案例

(一) job

cat /kubeyml/job001.yml 
--------------------------------------------------------------------------------------------
apiVersion: batch/v1
kind: Job
metadata:
name: demo-job
spec:
parallelism: 3       # 设置并行 pod 的数目,默认为一,增大可以增加执行效率
template:
metadata:
name: demo-job
spec:
containers:
    - name: demo-job
      image: busybox
      command: ["echo","hello world Job!"]
    restartPolicy: OnFailure      # 失败了就重启 pod ,Never 从不重启
--------------------------------------------------------------------------------------------
`kubectl` get pod   # 当 status 为 Completed 时为执行成功
NAME             READY   STATUS      RESTARTS   AGE
demo-job-5zwm9   0/1     Completed   0          3m2s

`kubectl` get job
NAME       COMPLETIONS   DURATION   AGE
demo-job   3/1 of 3      36s        4m11s

(二)Cronjob

cat /kubeyml/cro001.yml 
--------------------------------------------------------------------------------------------
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"    # 每秒执行一次
jobTemplate:
spec:
template:
  spec:
    containers:
        - name: hello
          image: busybox
          args:
          - /bin/sh
          - -c
          - date;echo hello world CronJob!
        restartPolicy: OnFailure
--------------------------------------------------------------------------------------------

`kubectl` get pod
NAME                     READY   STATUS      RESTARTS   AGE
hello-1622117340-pgtcj   0/1     Completed   0          92s
hello-1622117400-xx6wg   0/1     Completed   0          32s
`kubectl` get job    # cronjob 也是 job 的一种,只不过加了定时任务而已
NAME               COMPLETIONS   DURATION   AGE
hello-1622117340   1/1           18s        2m7s
hello-1622117400   1/1           19s        67s
hello-1622117460   0/1           7s         7s
`kubectl` get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        28s             6m57s

ronjob 各参数详解

  • spec.schedule:调度,必需字段,指定任务运行周期,格式同 Cron

  • .spec.jobTemplate:Job 模板,必需字段,指定需要运行的任务,格式同 Job

  • .spec.startingDeadlineSeconds:启动 Job 的期限(秒级别)如果没有指定,则没有期限.

  • spec.concurrencyPolicy:并发策略,该字段也是可选的。只允许指定下面策略中的一种:

  • Allow(默认):允许并发运行

  • JobForbid:禁止并发运行,如果前一个还没有完成,则直接跳过下一个

  • Replace:取消当前正在运行的 Job,用一个新的来替换。

  • .spec.suspend:挂起,该字段也是可选的。如果设置为true,后续所有执行都会被挂起。它对已经开始执行的 Job 不起作用。默认值为false。

  • .spec.successfulJobsHistoryLimit和.spec.failedJobsHistoryLimit:历史限制,是可选的字段。它们指定了可以保留多少完成和失败的 Job。默认情况下,它们分别设置为3和1。设置限制的值为0,相关类型的 Job 完成后将不会被保留

5. service 介绍

1. 基础概念

1. service 的定义

一种可以访问pod集群的策略 —— 通常称为微服务。这一组Pod能够被Service访问到,通常是通过Label Selector

  • service 的限制:只提供 4 层负载均衡能力,而没有 7 层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kRY5cCnE-1653055923915)(D:\云计算工坊\图片\K8S\service定义.png)]

2. service 的分类

ClusterIp:默认类型,自动分配一个仅集群内部可以访问的虚拟 IP

NodePort:在ClusterIP基础上为Service 在每台机器上绑定一个端口,这样就可以通过主机IP:NodePort来访问该服务

LoadBalancer:在NodePort 的基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到NodePort

NodePortExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有 kubernetes 1.7 或更高版本的 kube-dns 才支持

监听服务和端点是由apiserver负责的,通过 kube-proxy 去监控对应的 pod ,并提取相应的信息,将其写入到 iptables,当客户端想要访问 service 的时候,其实访问的的是 iptables 规则,然后导向到后端的 pod 的地址信息

客户端访问到我们的节点是由 iptables 实现的
iptables 的规则是由 kube-proxy 写入的,apiserver通过监控 kube-proxy 进行 服务和端点的发现 ,kube-proxy 会通过 pod 的标签去判断这个端点是否写入到端点集合里去。

2. 基础案例实践

(一)ClusterIP 和 NodePort

cat /kubeyml/svc003.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Service
metadata:
name: svc003
namespace: default
spec:
type: NodePort
selector:
app: nginx
ports:
- name: http
  port: 80
  targetPort: 80
--------------------------------------------------------------------------------------------
`kubectl` apply -f /kubeyml/svc003.yml
`kubectl` get svc
# NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
# svc003       NodePort    10.108.138.100   <none>        80:32181/TCP   18m

(二)externalName

kind: Service
apiVersion: v1
metadata: 
name: my-service-1 
namespace: default
spec:
type: ExternalName  
externalName: hub.atguigu.com

3. nginx-ingress

(一)service 只能实现四层暴露,而nginx-ingress 可以实现七层暴露

(二)部署过程

kubectl apply -f /root/install-k8s/plugin/ingress/mandatory.yml
kubectl apply -f /root/install-k8s/plugin/ingress/service-nodePort.yml

(三)简单案例的部署

cat /kubeyml/ingress/dep-demo.yml
--------------------------------------------------------------------------------------------
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dep
spec:
replicas: 2
template:
metadata:
labels:
name: nginx
spec:
containers:
  - name: nginx
    image: wangyanglinux/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
      - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc                  # 与 ingress 的唯一标识
spec:
ports:
- port: 80
  targetPort: 80
  protocol: TCP
selector:
name: nginx
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-demo
spec:
rules:
- host: www1.codefun.com
  http:
    paths:
    - path: /
      backend:
        serviceName: nginx-svc    # 管理那个 service
        servicePort: 80
--------------------------------------------------------------------------------------------
kubectl apply -f /kubeyml/ingress/dep-demo.yml
curl www1.codefun.com:30051   # 发现可以访问该域名

(四)实现 https

# 创建 https 密钥
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"
kubectl create secret tls tls-sercret --key tls.key --cert tls.crt
# 编写 yml 文件
vim /kubeyml/ingress/https_ingress.yml
--------------------------------------------------------------------------------------------
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ing001
spec:
tls:      # 注意该字段下与之前建立的密钥相对应
  - hosts:
    - www.code666.com
    secretName: tls-secret
rules:
  - host: www.code666.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc001
          servicePort: 80
--------------------------------------------------------------------------------------------
# 在 网页上访问 https://www.code666.com:32458,注意此时映射的端口为 443!

(五)实现用户认证

# 创建密码文件
yum install -y httpd
mkdir htpasswd && cd htpasswd
htpasswd -c auth codefun 
kubectl create secret generic basic-auth --from-file=auth
# 编写 yml 文件
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-dev004
spec:
replicas: 2
template:
 metadata:
   labels:
     name: nginx004
 spec:
   containers:
        - name: nginx004
          image: wangyanglinux/myapp:v2
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc004
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx004
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ing004
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - codefun'
spec:
  rules:
    - host: www.codeau.com
      http:
        paths:
        - path: /
          backend:
            serviceName: nginx-svc004
            servicePort: 80
---

(六)域名重定向

cat /kubeyml/ingress/rew_sour.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: rew-sour-ing
annotations:
 nignx.ingress.kubernetes.io/rewrite-target: http://www.code.com:30051/
spec:
rules:
    - host: www.codefun.com
      http:
        paths:
        - path: /
          backend:
            serviceName: rewrite-svc02
            servicePort: 80

6. k8s 中的存储

1. 保存对象为环境变量的 configMap

(一) 特点:

  • ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者 JSON 二进制大对象

(二)以目录为单位创建 configmap

# 创建相关目录和文件,并向文件中输入信息
mkdir /root/configmap/ && cd /root/configmap
cat game.properties 
--------------------------------------------------------------------------------------------
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=no
GoodRottensecret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=truesecret.code.lives=30
--------------------------------------------------------------------------------------------
cat ui.properties 
--------------------------------------------------------------------------------------------
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
--------------------------------------------------------------------------------------------
# 创建 configmap
`kubectl` create configmap config-dir --from-file=/root/configmap/ # config-dir 为 configmap 的名字,/root/configmap/ 是 名为 config-dir 的 configmap 保存那些资源。
# --from-file 指定的资源,以文件为键,以内容为值。

(三)以字面值为单位创建 configmap

kubectl create configmap config-word --from-literal=key1=value1 --from-literal=key2=value2
kubectl describe config-world  # 查看包括那些键值

四)使用 yml 文件来创建 configmap

vim /kubeyml/env_cm.yml
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: ConfigMap
metadata:
name: config-yml
namespace: default
data:
key: value
--------------------------------------------------------------------------------------------
kubectl create -f /kubeyml/env_cm.yml

(五)在 pod 中使用 configMap 中的键值

cat /kubeyml/env_pod.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: env-pod
spec:
containers:
    - name: env-con
      image: wangyanglinux/myapp:v2
      command: ["/bin/sh","-c","env"]     # 打印所有的环境变量
      env:									
        - name: SPECIAL_LEVEL_KEY	 # 定义在 pod 中的 key
          valueFrom:			# 变量来自于哪里
            configMapKeyRef:
              name: game-config			# 变量的 configmap 的名字
              key: game.propreties		# 变量的 key
     envFrom:			# z直接导入整个 configmap 中的键和值
      - configMapKeyRef:
         name: config-map-name 
  restartPolicy: Never
--------------------------------------------------------------------------------------------

(六)通过数据卷插件使用 configmap

cat /kubeyml/env_vol_pod.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: env-vol-pod
spec:
containers:
    - name: env-vol-con
      image: wangyanglinux/myapp:v1
      command: ["/bin/sh","-c","sleep 360s"]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: game-config
  restartPolicy: Never
--------------------------------------------------------------------------------------------
kubectl apply -f /kubeyml/env_vol_pod.yml
 kubectl exec -it env-vol-pod -- /bin/sh
/ # cd /etc/config
/etc/config # ls      # 由此发现,将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容
kubectl edit cm game-config   # 修改环境变量,容器也跟着改变,实现热部署

2. 加密存储的 secret

(一)secret 存在的意义

  • Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec中。Secret 可以以 Volume 或者环境变量的方式使用

(二)secret 的分类

  • ervice Account:用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod 的/run/secrets/kubernetes.io/serviceaccount目录中
  • Opaquebase64编码格式的Secret,用来存储密码、密钥等
  • kubernetes.io/dockerconfigjson:用来存储私有 docker registry 的认证信息

(三)创建 Opaque 类型的 secret

  • 将 secret 导入到 volume 中

    # 获取 base64 加密的信息
    cho -n "admin" | base64
    YWRtaW4=		# 此加密信息就是个假的,很容易反解密
    echo -n "123456" | base64
    MTIzNDU2
    # 编写有关 secret 的 yml 文件
    cat /kubeyml/secrets.yml 
    --------------------------------------------------------------------------------------------
    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecret
    type: Opaque
    data:
      password: MTIzNDU2
      username: YWRtaW4=
    --------------------------------------------------------------------------------------------
    # 编写使用 secret 的 pod
    cat /kubeyml/sec_vol_pod.yml 
    --------------------------------------------------------------------------------------------
    apiVersion: v1
    kind: Pod
    metadata:
      name: sec-pod
      labels:
        name: sec-pod
    spec:
      volumes:
      - name: secrets
        secret:
          secretName: mysecret     # 与上文定义的相同
      containers:
      - image: wangyanglinux/myapp:v2
        name: sec-con
        volumeMounts:
        - name: secrets
          mountPath: /etc/config
          readOnly: true
    --------------------------------------------------------------------------------------------
    
  • 将 secret 导入到环境变量中

    cat /kubeyml/sec_env_pod.yml 
    --------------------------------------------------------------------------------------------
    apiVersion: v1
    kind: Pod
    metadata:
      name: sec-env-pod
    spec:
      containers:
      - name: sec-env-con
        image: wangyanglinux/myapp:v1
        command: ["/bin/sh","-c","echo $ADMIN"]
        ports:
        - containerPort: 80
        env:
          - name: ADMIN
            valueFrom:
              secretKeyRef:    ###
                name: mysecret
                key: username
    --------------------------------------------------------------------------------------------
    
  • 拉取私有仓库免登录

    # 创建密钥
    kubectl create secret docker-registry myregistrykey --docker-server=192.168.80.141:5000 --docker-username=admin --docker-password=Gx123456 --docker-email=3061552332@qq.com
    # 编写 yml 文件
    cat /kubeyml/reg_pod.yml 
    --------------------------------------------------------------------------------------------
    apiVersion: v1
    kind: Pod
    metadata:
      name: reg-pod
    spec:
      containers:
      - name: reg-con
        image: 192.168.80.141:5000/codefun/nginx01:v1
      imagePullSecrets:
      - name: myregistrykey
    --------------------------------------------------------------------------------------------
    

3. 可以共享的 volume

(一)同 pod 共享存储的 emptyDir

  • 当 Pod 被分配给节点时,首先创建emptyDir卷,并且只要该 Pod 在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir中的数据将被永久删除

  • 暂存空间,例如用于基于磁盘的合并排序用作长时间;计算崩溃恢复时的检查点;Web服务器容器提供数据时,保存内容管理器容器提取的文件

  • 案例示例

    cat /kubeyml/vol_pod.yml 
    --------------------------------------------------------------------------------------------
    apiVersion: v1
    kind: Pod
    metadata:
      name: vol-pod
      namespace: default
    spec:
      containers:
      - name: vol-con001
        image: wangyanglinux/myapp:v1
        volumeMounts:
        - mountPath: /cache
          name: cache-volume   # 定义相同的名字
      - name: vol-con002
        image: busybox
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh","-c","sleep 360s"]
        volumeMounts:
        - mountPath: /test
          name: cache-volume   # 定义相同的名字
      volumes:
      - name: cache-volume   
        emptyDir: {}
    --------------------------------------------------------------------------------------------
    kubectl apply -f /kubeyml/vol_pod.yml 
    kubectl exec -it vol-pod -c vol-con001 -- /bin/sh
    / # cd cache/
    /cache # date > test.txt
    /cache # cat test.txt 
    Wed Jun  2 09:19:41 UTC 2021
    kubectl exec -it vol-pod -c vol-con002 -- /bin/sh
    / # cd test
    /test # cat test.txt 
    Wed Jun  2 09:19:41 UTC 2021
    

(二)共享到本地的 hostpath

综述

  • hostPath卷将主机节点的文件系统中的文件或目录挂载到集群中

用途

  • 运行需要访问 Docker 内部的容器:使用/var/lib/docker的hostPath
  • 在容器中运行 cAdvisor;使用/dev/cgroups的hostPath
  • 允许 pod 指定给定的 hostPath 是否应该在 pod 运行之前存在,是否应该创建,以及它应该以什么形式存在

参数总结

k

行为
pathnode 节点的目录路径
null空字符串用于向后兼容,意味着在挂载 hostpath 卷之间不会执行任何检查
DirectoryOrCreate如果在给定的路径上没有任何东西存在,那么将根据需要在那里创建一个空目录,权限设置为 077 ,与 kubelet 具有相同的组和所有权
Directory给定的路径下必须存在目录
FileOrCreate如果在给定的路径上没有任何东西存在,那么会根据需要创建一个空文件,权限设为 0644,与 kubelet 具有相同的组和权限
File给定路径下必须存在文件
Socket给定路径下必须存在 UNIX 套接字
CharDevice给定路径下必须存在字符设备
BlockDevice给定的路径下必须存在块设备

案例实现

cat /kubeyml/vol_host_pod.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: vol-host-pod
spec:
containers:
  - name: vol-host-con
    image: wangyanglinux/myapp:v2
    volumeMounts:
    - name: vol-host-vol
      mountPath: /test
  volumes:
  - name: vol-host-vol
    hostPath:
      path: /data
      type: Directory
--------------------------------------------------------------------------------------------
kubectl apply -f /kubeyml/vol_host_pod.yml
kubectl exec -it vol-host-pod -- /bin/sh
/ # date > /test/test.txt
/ # cat /test/test.txt 
Thu Jun  3 00:42:28 UTC 2021
[root@n002 ~]# mkdir /data
[root@n002 ~]# cat /data/test.txt 
Thu Jun  3 00:42:28 UTC 2021

4. 持久卷

概念

  • PV 持久卷,由运维设置的存储。是集群中的资源,类似于 volume 之类的卷插件,但具有独立于 pod 的生命周期。此 API 对象包含存储实现的细节,如使用 NFS 来达到目录共享的功能。
  • PVC 持久卷声明,由开发设置的类型。类似于 pod ,pod 消耗节点资源,PVC 消耗 PV 资源。
  • 静态 PV ,集群管理员创建的 PV。
  • 动态 PV , 当管理员创建的静态 PV 都不匹配用户的 PVC 时,集群可能会自己尝试动态的为 pvc 创建卷。
  • PV 访问模式:
    • ReadWriteOnce – 单个节点读写模式挂载
    • ReadOnlyMany – 多个节点只读模式挂载
    • ReadWriteMany – 多个节点读写模式挂载
  • 状态:
    • Available – 可用的空闲资源
    • Bound – 卷已被声明绑定
    • Released– 声明已被删除
  • 回收策略:
    • Retain – 手动回收
    • Delete– 直接删除
    • Failed – 自动回收失败
  • PV 和 PVC 匹配规则
    • PVC 和 PV 的 storageClassName 必须一致
    • PVC 和 PV 的 accessModes 必须一致
    • PVC 的大小要小于或等于 PV 的大小

持久化演示说明 - NFS

# 安装 nfs 服务
yum install -y nfs-utils rpcbind
mkdir /nfs{0..3}
chown nfsnobody /nfs{0..3}
chmod 777 /nfs{0..3}
vim /etc/exports
--------------------------------------------------------------------------------------------
/nfs0 *(rw,sync,no_root_squash,no_all_squash)
/nfs1 *(rw,sync,no_root_squash,no_all_squash)
/nfs2 *(rw,sync,no_root_squash,no_all_squash)
/nfs3 *(rw,sync,no_root_squash,no_all_squash)
--------------------------------------------------------------------------------------------
systemctl restart rpcbind
systemctl restart nfs

# 编写 pv 的 yml 文件
cat /kubeyml/mode_pv.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: PersistentVolume
metadata:
name: mode-pv
spec:
capacity:
 storage: 2Gi		# 定义 PV 的容量
accessModes:		# 定义 PV 的访问模式
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle		# 定义 PV 的回收策略
  storageClassName: nfs		# 与 PVS 的唯一标识
  nfs:		# 设置持久卷类型为 NFS
    path: /nfs0    # 远程的挂载目录
    server: 192.168.80.141		# 远程挂载目录主机的 IP
--------------------------------------------------------------------------------------------
kubectl apply -f /kubeyml/mode_pv.yml

# 编写 pvc 及其他的 yml 文件
cat /kubeyml/mode_pvc.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Service
metadata:
  name: mode-pvc-svc
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None		# 定义 statefulSet 时,service 必须是无头服务
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mode-pvc-ss
spec:
  selector:
    matchLabels:
      app: nginx		# 与 container 互相标识
  serviceName: "mode-pvc-svc"		# 与 service 的唯一标识
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx				# 与 statefulset 互相标识
    spec:
      containers:
      - name: mode-pvc-con
        image: wangyanglinux/myapp:v2
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www  # PVC 的名字
    spec:
      accessModes: [ "ReadWriteOnce" ]		# 与 PV 的标识
      storageClassName: "nfs"		# 与 PV 的标识
      resources:
        requests:
          storage: 1Gi		# 大小
--------------------------------------------------------------------------------------------
kubectl apply -f /kubeyml/mode_pvc.yml 

# 另一种写法
cat mode_pv003.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mode-pv003
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Delete
  storageClassName: mode-pvoo3
  nfs:
    path: /nfs3
    server: 192.168.80.141
--------------------------------------------------------------------------------------------
cat mode_pvc001.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mode-pvc001
spec:
  storageClassName: mode-pvoo3
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 500Mi
--------------------------------------------------------------------------------------------
cat mod_pv_pod.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
  name: mode-pv-pod
spec:
  containers:
  - name: mode-pv-con
    image: wangyanglinux/myapp:v1
    ports:
    - containerPort: 80
      protocol: TCP
    volumeMounts:
    - name: mode-pv-vol
      mountPath: /test
  volumes:
    - name: mode-pv-vol
      persistentVolumeClaim:
        claimName: mode-pvc001
--------------------------------------------------------------------------------------------

statefulSet 模型

  • StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享存储。
  • 每一个pod不能被随意取代,pod名称不变,而pod IP是变化的,所以pod名称是pod唯一性的标识符,必须持久稳定有效。这时候要用到无头服务,它可以给每个Pod一个唯一的名称 。
  • StatefulSet 为每个 Pod 副本创建了一个 DNS 域名,这个域名的格式为: $(podname).(headless servername),
  • 共享存储这里用的是 NFS

7. 集群的调度器

1. 调度说明

简介

Scheduleer 是 K8S 的调度器,主要任务是把定义的 pod 分配到集群的 node上。分配时需要考虑的问题:

  • 公平:如何保证每个节点都能被分配资源
  • 资源的高效利用:集群所有资源最大化被使用
  • 效率:能够尽快地对大批量的 pod 完成调度工作
  • 灵活:允许用户根据自己的需求控制调度逻辑

Shedeler是作为单独运行程序,启动之后会一直坚挺 API Server,获取PodSpec.NodeName为空的 pod,对每个 pod 都会创建一个 binding,表明该 pod 应该放到哪个节点上。

调度过程

  1. 预选:首先过滤掉不满足条件的节点,称为 predicate
  2. 优选:根据节点优先级来最终决定 pod 的归属,称为priority

预选算法:

  • PodFitsResources:节点上剩余的资源是否大于 pod 请求的资源
  • PodFitsHost:如果 pod 指定了 NodeName,检查节点名称是否和 NodeName 匹配
  • PodFitsHostPorts:节点上已经使用的 port 是否和 pod 申请的 port 冲突
  • PodSelectorMatches:过滤掉和 pod 指定的 label 不匹配的节点
  • NoDiskConflict:已经 mount 的 volume 和 pod 指定的 volume 不冲突,除非它们都是只读

优选算法:

  • eastRequestedPriority:通过计算 CPU 和 Memory 的使用率来决定权重,使用率越低权重越高。换句话说,这个优先级指标倾向于资源使用比例更低的节点
  • BalancedResourceAllocation:节点上 CPU 和 Memory 使用率越接近,权重越高。这个应该和上面的一起使用,不应该单独使用
  • ImageLocalityPriority:倾向于已经有要使用镜像的节点,镜像总大小值越大,权重越高

选择细节:

  • 如果在 predicate 过程中没有合适的节点,pod 会一直在pending状态,不断重试调度,直到有节点满足条件。经过这个步骤,如果有多个节点满足条件,就继续 priorities 过程:按照优先级大小对节点排序
  • 通过算法对所有的优先级项目和权重进行计算,得出最终的结果

自定义调度器

apiVersion: v1
kind: Pod
metadata:
name: annotation-second-scheduler
labels:
name: multischeduler-example
spec:  
schedulername: my-scheduler  
containers:  
  - name: name-com
    image: image-name:tag

2. 节点亲和性

软策略

​ —— 不必须匹配的策略

# 实现方法:
cat /kubeyml/affinity/pre_pod001.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: pre-pod
labels:
 app: pre-pod
spec:
containers:
  - name: pre-con
    image: wangyanglinux/myapp:v2
    imagePullPolicy: IfNotPresent
  affinity:						# 策略
    nodeAffinity:			  # 节点匹配策略
      preferredDuringSchedulingIgnoredDuringExecution:    # 软策略
      - weight: 1		# 权重
        preference:		# 软策略详情
          matchExpressions:		# 选择详请
          - key: kubernetes.io/hostname		# 选择 key 和 value 是什么的 node,kubectl get node --show-labels 显示可选键值
            values:
            -  n001
            operator: In		# 执行的操作
--------------------------------------------------------------------------------------------

operator 操作的种类

-In		 # label 的值在某个列表中
-NotIn  # label 的值在某个列表中
-Gt		 # label 的值大于某个值
-Lt		 # label 的值小于某个值
-Exsist	 # 某个 label 存在
-DoesNotExist # 某个 label 不存在

硬策略

​ —— 必须匹配的策略,不然 pod处于 pending

cat /kubeyml/affinity/req_pod001.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: req-pod
labels:
 app: req-pod
spec:
containers:
  - name: pre-con
    image: wangyanglinux/myapp:v2
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:  # 和软开头不一样
       nodeSelectorTerms:		# 和软一点都不一样
       - matchExpressions:
         - key: kubernetes.io/hostname
           values:
           - n002
           operator: In
--------------------------------------------------------------------------------------------

pod 亲和性

​ —— 即 pod 和 pod 直接根据 label 判断是否在同一个 拓扑域

cat /kubeyml/affinity/req_pod002.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: req-pod002
labels:
 app: req-pod002
spec:
containers:
  - name: req-con002
    image: wangyanglinux/myapp:v2
    imagePullPolicy: IfNotPresent
  affinity:
    podAffinity:  ###
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            values:
            - req-pod
            operator: In
        topologyKey: kubernetes.io/hostname
#    podAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app
              values:
              - pre-pod
              operator: In
          topologyKey: kubernetes.io/hostname   ## 选择拓扑域,即 hostname 相同的 node
--------------------------------------------------------------------------------------------

3. 污点和容忍

污点

  • Node 被设置上污点之后就和 Pod 之间存在了一种相斥的关系,可以让 Node 拒绝 Pod 的调度执行,甚至将 Node 已经存在的 Pod 驱逐出去

容忍

  • 设置了容忍的 Pod 将可以容忍污点的存在,可以被调度到存在污点的 Node 上

设置污点

`kubectl taint nodes` node-name key1=value1:effect
## effect 支持的三个选项:
	-NoSchedule  # 不会将 pod 调度到有该污点的 node 上
	-PreferNoSchedule  # 尽量避免将 pod 调度到有该污点的 node 上
	-NoExecute  # 不会将 pod 调度到有该污点的 node 上,同时会将 node 上已经存在的 pod 驱逐出去

查看污点

`kubectl describe node` node-name  | grep -i "taints:"

删除污点

`kubectl taint nodes` node-name key1=value1:effect- # 加个减号即可

设置容忍

cat /kubeyml/affinity/req_pod001.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Pod
metadata:
name: req-pod002
labels:
 app: req-pod002
spec:
containers:
  - name: pre-con002
    image: wangyanglinux/myapp:v2
    imagePullPolicy: IfNotPresent
  tolerations:				 # 设置容忍的 key value effect 必须一致!
  - key: auth    		  # 不指定 key 值时,表示容忍所有的污点 key      
    value: codefun 			
    operator: Equal			# 当值为 Exists 将会忽略 value 值
    effect: NoSchedule 		# 当不指定 effect 值时,表示容忍所有的污点作用
    tolerationSeconds: 3600 # 描述当 Pod 需要被驱逐时可以在 Pod 上继续保留运行的时间
--------------------------------------------------------------------------------------------
当不指定 key 值时,表示容忍所有的污点

4. 固定节点调度

 cat /kubeyml/dep002.yml 
 --------------------------------------------------------------------------------------------
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: dep-dep002
spec:
  replicas: 4
  template:
    metadata:
      labels:
        app: dep-dep002
    spec:
      nodeName: n001		# 设置指定节点的名字
#      nodeSelector:		# 根据标签选择,`kubectl label nodes` node-name key1=value1 给 pod 设置标签
#        app: myapp
      containers:
      - name: dep-con001
        image: wangyanglinux/myapp:v2
        ports:
        - containerPort: 80
--------------------------------------------------------------------------------------------

8. 集群安全

(一)机制说明

  • Kubernetes 作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。
  • API Server 是集群内部各个组件通信的中介,也是外部控制的入口。
  • 所以 Kubernetes 的安全机制基本就是围绕保护 API Server 来设计的。
  • Kubernetes 使用了认证(Authentication)、鉴权(Authorization)、准入控制(AdmissionControl)三步来保证API Server的安全

(二)认证介绍

  • 一共有三种认证方式(HTTP TOKENHTTP BaseHTTPS 证书),这里我们使用最为严格的HTTPS 证书认证
  • HTTPS 证书认证过程:首先客户端和服务端都需要向CA 架构申请证书,然后客户端和服务端通过证书来进行身份认证,最后通过随机私钥进行通讯
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zUmCPKI5-1653055923917)(D:\云计算工坊\图片\K8S\HTTPS 证书认证.png)]

(三)鉴权过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z89txgtv-1653055923918)(D:\云计算工坊\图片\K8S\鉴权.png)]

(四)实现鉴权

useradd devuser && passwd devuser # 创建实体用户 
mkdir /root/install-k8s/cert/devuser/ && vim  /root/install-k8s/cert/devuser/devuser-csr.json		# 编写 json 文件
--------------------------------------------------------------------------------------------
{
"CN": "devuser",   # 用户名
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048  
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
--------------------------------------------------------------------------------------------
# 下载 SSL 证书生成工具
	# 我们这里是直接将相关文件直接导入到 /usr/local/bin/ 下
chmod a+x *  # 给相关文件增加可执行权限
cd /etc/kubernetes/pki/
cfssl genecrt -ca=ca.crt -ca-key=ca.key -profile=kubernetes `/root/install-k8s/cert/devuser/devuser-csr.json` | cfssljson -bare `devuser`		# 有飘号的需要根据情况改动 
cd /root/install-k8s/cert/devuser/
export KUBE_APISERVER="https://192.168.80.142:6443"		# 设置集群参数
kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --server=${KUBE_APISERVER} --kubeconfig=devuser.kubeconfig		# 设置集群参数
kubectl config set-credentials devuser --client-certificate=/etc/kubernetes/pki/devuser.pem --client-key=/etc/kubernetes/pki/devuser-key.pem --embed-certs=true --kubeconfig=devuser.kubeconfig		# 设置客户端认证参数
kubectl create namespace dev		# 创建用户管理的名称空间
kubectl config set-context kubernetes --cluster=kubernetes --user=devuser --namespace=dev --kubeconfig=devuser.kubeconfig		# 设置上下文
kubectl create rolebinding devuser-admin-binding --clusterrole=admin --user=devuser --namespace=dev		# 创建角色绑定,注意相关参数
mkdir /home/devuser/./kube
cp devuser.kubeconfig /home/devuser/.kube/
chown devuser:devuser /home/devuser/.kube/devuser.kubeconfig 
mv /home/devuser/.kube/devuser.kubeconfig /home/devuser/.kube/config
su - devuser
kubectl config use-context kubernetes --kubeconfig=config
kubectl run nginx --image=wangyanglinux/myapp:v2  # 创建 pod 并查看他属于能够名称空间

(五)准入控制

  • 准入控制是API Server的插件集合,通过添加不同的插件,实现额外的准入控制规则。甚至于API Server的一些主要的功能都需要通过 Admission Controllers 实现,比如 ServiceAccount

9. Helm

1. 基础知识

1. 什么是 Helm

我们在部署各种 pod 的时候,需要编写各种组件的 yml 文件,非常繁琐。而 helm就像是 yum一样,将服务的所需的文件,组件打包到一起,从而实习服务的一键化部署。

helm 的重要组件

  • chart 是创建一个应用的信息集合,包括各种 Kubernetes 对象的配置模板、参数定义、依赖关系、文档说明等。chart 是应用部署的自包含逻辑单元。可以将 chart 想象成 aptyum 中的软件安装包

  • releasechart 的运行实例,代表了一个正在运行的应用,当 chart 被安装到 Kubernetes 集群,就生成一个 releasechart 能够多次安装到同一个集群,每次安装都是一个 release

2. Helm的架构

Helm 包含两个组件:Helm 客户端和 Tiller 服务器。Helm 客户端负责 chartrelease 的创建和管理以及和 Tiller 的交互。Tiller 服务器运行在 Kubernetes 集群中,它会处理 Helm 客户端的请求,与 Kubernetes API Server 交互

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H1YNijK3-1653055923919)(D:\云计算工坊\图片\K8S\helm 架构.png)]

2. Helm部署

cd /usr/local/src
wget https://storage.googleapis.com/kubernetes-helm/helm-v2.13.1-linux-amd64.tar.gz
tar -zxvf helm-v2.13.1-linux-amd64.tar.gz 
cd linux-amd64/ && mv helm /usr/local/bin/
mkdir  /root/install-k8s/helm/
vim /root/install-k8s/helm/rbac-config.yml
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: ServiceAccount
metadata:
name: tiller
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system
--------------------------------------------------------------------------------------------
$ kubectl create -f rbac-config.yml
$ helm init --service-account tiller --skip-refresh
$ kubectl get pod -n kube-system # 查看相应的 pod 是否启动成功

3. 编写自定义chart

# 1. 编写 Chart.yaml 文件    必须以 yaml 结尾,不然不识别
mkdir /root/install-k8s/helm/hello-world/templates  && cd /root/install-k8s/helm/hello-world
vim Chart.yaml
--------------------------------------------------------------------------------------------
name: hello-world    # 必须存在的字段
version: 1.0.0		  # 必须存在的字段
--------------------------------------------------------------------------------------------
# 2. 编写服务相应的 yml 文件,且都在 templates 目录下
cd /root/install-k8s/helm/hello-world/templates
vim deployment.yml
--------------------------------------------------------------------------------------------
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: hello-world
spec:
replicas: 1
template:
 metadata:
   labels:
     app: hello-world
 spec:
   containers:
      - name: hello-world
        image: wangyanglinux/myapp:v1
        ports:
        - containerPort: 80
          protocol: TCP
--------------------------------------------------------------------------------------------
cat service.yml 
--------------------------------------------------------------------------------------------
apiVersion: v1
kind: Service
metadata:
  name: hello-world
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: hello-world
--------------------------------------------------------------------------------------------
# 3. 回到有 Chart.yaml 文件的目录下进行安装操作
$ helm install .
# 4. 列出已经部署的 Release
$ helm list
NAME       REVISION	UPDATED     STATUS  	CHART      APP VERSION	NAMESPACE
voting-giraffe	1        	   DEPLOYED	   hello-world-1.0.0	      default  
# 5. 查询一个特定的 Release 的状态
$ helm status RELEASE_NAME
# 6. 移除所有与这个 Release 相关的 Kubernetes 资源
$ helm delete voting-giraffe
# 7. 显示没有完全删除的 release
$ helm list --deleted
NAME       REVISION	UPDATED     STATUS  	CHART      APP VERSION	NAMESPACE
voting-giraffe	1        	   DEPLOYED	   hello-world-1.0.0	      default  
# 8. helm rollback RELEASE_NAME REVISION_NUMBER  回滚操作
$ helm rollback voting-giraffe 1
# 9. 完全删除
$  helm delete --purge voting-giraffe
# 更新一个 release
$ helm upgrade voting-giraffe .
# 查看操作 release 历史
helm history voting-giraffe

设置参数

# 1. 在 Chart.yaml 文件的同级目录下创建参数文件
vim /root/install-k8s/helm/hello-world/values.yaml
--------------------------------------------------------------------------------------------
image:  
  repository: wangyanglinux/myapp  
  tag: 'v2'
--------------------------------------------------------------------------------------------
# 2. 修改原来的 deployment 文件的 image 字段
--------------------------------------------------------------------------------------------
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
--------------------------------------------------------------------------------------------
# 3. 更新 release
$ helm upgrade voting-giraffe .

4. 使用 helm 部署 dashboard

# 1. 获取安装文件源
$ helm repo add stable http://mirror.azure.cn/kubernetes/charts/
# 2. 拉取安装文件压缩包并解压
$ mkdir /root/install-k8s/helm/dashboard && cd !$
$ helm fetch stable/kubernetes-dashboard
$ tar -zxvf kubernetes-dashboard-1.11.1.tgz
# 3. 编写自定义配置文件
vim kubernetes-dashboard/kubernetes-dashboard.yaml 
--------------------------------------------------------------------------------------------
image:
repository: k8s.gcr.io/kubernetes-dashboard-amd64
tag: v1.10.1
ingress:
enabled: true
hosts:
    - k8s.frognew.com
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
  tls:
    - secretName: frognew-com-tls-secret
      hosts:
      - k8s.frognew.com
rbac:
  clusterAdminRole: true
--------------------------------------------------------------------------------------------
# 4. 安装 dashborad
$ helm install . -n kubernetes-dashboard --namespace kube-system  -f kubernetes-dashboard.yaml
# 5. 获取相关镜像
$ docker pull sacred02/kubernetes-dashboard-amd64:v1.10.1
$ docker tag sacred02/kubernetes-dashboard-amd64:v1.10.1 k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
$ docker rmi -f sacred02/kubernetes-dashboard-amd64:v1.10.1
# 6. 将 ClusterIP 改为 NodePort
$ kubectl get svc -n kube-system
$ kubectl edit svc kubernetes-dashboard -n kube-system
# 7. 获取 token 令牌
$ kubectl -n kube-system get secret | grep kubernetes-dashboard-token   
$ kubectl describe secrect kubernetes-dashboard-token-cflxj -n kube-system
# 8. 在浏览器上访问

10. 普罗米修斯

1. 基础知识

1. 普罗米修斯的特点
  • 多维数据模型:由度量名称和键值对标识的时间序列数据(查找速度快)
  • 内置时间序列数据库:TSDB
  • promQL:灵活的查询语言,可以利用多维数据完成复杂查询
  • 基于HTTPpull的方式采集时间序列数据(export:比如 MySQL 没有相应的 HTTP 接口,就用 export来暴露,然后交由服务端)
  • 同时支持PushGateway组件收集数据(对于转瞬即逝的数据,export不能及时,由他来做)
  • 通过服务发现静态配置发现目标
  • 支持作为数据源接入Grafana
Logo

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

更多推荐