美文网首页
k8s-01-入门

k8s-01-入门

作者: 西海岸虎皮猫大人 | 来源:发表于2020-08-12 21:58 被阅读0次

参考:
Kubernetes权威指南 从Docker到Kubernetes实践全接触.pdf

1.概述

service-服务

分布式集群架构核心
特征: 唯一名称\虚拟IP端口\提供远程服务\映射到一组容器之上
基于socket通信
k8s给pod贴标签(如mysql),然后给service定义标签选择器,从而将service与pod关联

pod

pod运行于node中,node可以是物理机或者虚拟机,通常一个node几百个pod
pod中运行pause容器,其他业务容器共享pause的网络和volume
pod是最小单元

master节点运行kube-apiserver\kube-controller-manager\kube-scheduler,实现资源管理\pod调度\安全监控等,全自动完成

node上运行kublet\kube-proxy,负责pod的创建\启动\监控\重启\销毁以及负载均衡

通过创建rc(replication controller),实现服务扩容,rc文件包括pod定义\副本数量\标签

环境准备
# centos 7虚拟机
# 修改网络配置
vi /etc/sysconfig/network-scripts/ifcfg-ens33
service network restart
# 设置主机名
hostnamectl set-hostname k8s-01
# 重启
# 配置阿里云镜像
yum install -y wget
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all && yum makecache
# 关闭防火墙
systemctl disable firewalld
systemctl stop firewalld

# k8s单机环境搭建
# 安装
yum install etcd kubernetes -y
# 按顺序启动所有服务
systemctl start etcd && \
systemctl start docker && \
systemctl start kube-apiserver && \
systemctl start kube-controller-manager && \
systemctl start kube-scheduler && \
systemctl start kubelet
启动MySQL服务
# 创建rc文件: mysql-rc.yaml
--------------
apiVersion: v1
kind: ReplicationController 
metadata: 
  name: mysql            # RC的名称,全局唯一 
spec: 
  replicas: 1            # Pod副本期待数量
  selector: 
    app: mysql           # 符合目标的Pod拥有此标签
  template:              # 根据此模板创建Pod的副本(实例)
    metadata: 
      labels: 
        app: mysql       # Pod副本拥有的标签,对应RC的Selector
    spec: 
      containers:        # Pod内容器的定义部分
      - name: mysql      # 容器的名称
        image: mysql     # 容器对应的DockerImage
        ports: 
        - containerPort: 3306 
        env: 
        - name: MYSQL_ROOT_ASSWORD 
          value: "123456"
-----------------

# 发布到集群
kubectl create -f mysql-rc.yaml
# 删除
# kubectl delete -f mysql-rc.yaml
# 查看创建的rc
kubectl get rc
# 查看pod
kubectl get pods 
# 查看创建情况
kubectl describe pods mysql-z1jr4

# 异常: No resources found.
# 异常解决
vi /etc/kubernetes/apiserver
# 找到这一行 "KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota",去掉ServiceAccount
# 重启apiserver
systemctl restart kube-apiserver
# 查看运行的容器
docker ps I grep mysql
# 创建与之关联的service定义文件
mysql-svc.yaml
-------------
apiVersion: v1
kind: Service
metadata: 
  name: mysql
spec: 
  ports: 
    - port: 3306
  selector:
    app: mysql
-------------
# 创建service
kubectl create -f mysql-svc.yaml 
# 查看service
kubectl get svc 
# 查看结果中cluster ip是虚地址,其他pod可以通过cluster ip+端口访问它
# cluster ip无法预先知道,k8s使用linux环境变量实现根据服务名找到cluster ip
启动tomcat应用
# myweb-rc.yaml
---------------
apiVersion: v1
kind: ReplicationController
metadata:
  name: myweb
spec:
  replicas: 2
  selector:
    app: myweb
  template:
    metadata:
      labels:
        app: myweb
    spec:
      containers:
        - name: myweb
          image: kubeguide/tomcat-app:v1
          ports: 
          - containerPort: 8080
---------------
# 创建rc
kubectl create -f myweb-rc.yaml 
kubectl get pods 
# 创建service
# myweb-svc.yaml
--------------
apiVersion: v1
kind: Service 
metadata: 
  name: myweb
spec:
  type: NodePort
  ports: 
    - port: 8080 
      nodePort: 30001 
  selector:
    app: myweb
---------------
kubectl create - f myweb-svc.yaml 
# 查看service
kubectl get services
# 访问:
192.168.68.151:30001/demo

2.概念

master

集群控制节点
api server 所有资源的crud
controller manager 所有资源的自动化控制
scheduler 资源调度
etcd 资源数据保存

node

node可以运行时动态增加到集群
kubelet向master定时汇报自身情况

# 查看某个node信息
kubectl describe node 127.0.0.1
# 显示:
# 1.node基本信息
# 2.node当前运行状态,磁盘不足\内存不足等
# 3.node资源总量
# 4.node可分配资源量
# 5.主机系统信息
pod

pause 所有pod根容器,以其状态代表整个容器总体状态,并解决通信和文件共享问题
任意两个pod可以通信,采用flannel等虚拟二层网络
静态pod不存在etcd中,而是放在某个node的文件中,普通node存在etcd中
k8s所有资源都可用yaml或者json格式文件定义
event记录事件信息,用于排查故障

kubectl describe pod ***

pod可对服务器资源进行限额,cpu与内存,cpu是一个绝对值
cpu配额通常以千分之一为最小单位,用m表示,100-300m表示0.1-0.3个cpu
k8s中配额设定两个参数 requests(最小申请量)\limits(最大允许量,超额可能被kill重启)

# 配置mysql配额为0.5个cpu和128m内存
spec: 
  containers: 
  - name: db 
    image:  mysql 
    resources: 
      requests: 
        memory: "64Mi" 
        cpu: "250m" 
      limits: 
        memory: "128Mi" 
        cpu: "500m" 
Label标签

kv键值对,可以负载在pod\node\service\rc等各种资源上
一个资源对象可以定义任意数量的label,一个label也可以被添加到任意数量的资源对象上
label可以在对象创建后动态添加
通过label可以实现多维度的资源分组管理,版本\环境\架构\分区等
通过类似sql的label selector选择资源对象
label selector 2种,基于等式和基于集合

# 匹配不具有标签的对象
env ! = production 
# 集合中的
name in (redis-master, redis-slave)
# 可以通过多个表达式组合实现复杂的条件选择
# 示例myweb pod
metadata: 
  name: myweb 
  labels: 
    app: myweb 
# rc和service在spec中定义selector
spec: 
  replicas: 1 
  selector: 
    app: myweb 
...
# 基于集合筛选
selector: 
  matchLabels: 
    app: myweb 
  matchExpressions: 
  - {key: tier, operator:In, values: [frontend]} 
  - {key: environment, operator: NotIn, values: [dev]} 

Label Selector使用场景:
kube-controller控制pod副本数量
kube-proxy实现负载均衡
kube-scheduler定向pod调度

rc

定义pod副本数,label selector,pod模板
通过rc实现集群高可用,减少运维工作
pod意外终止,pod数目小于定义的副本数自动创建新pod
运行时可修改rc副本数量动态缩放

kubectl scale rc redis-slave --replicas=3

删除rc不会删除pod,需要先设置replicas为0,然后跟新rc,可通过stop和delete命令一次性删除rc和rc控制的所有pod
系统升级时,如10个旧版本pod,每次停止一个旧pod并创建一个新版本pod,这称为滚动升级
k8s1.2后rc升级为replica set,支持基于集合的label selector,功能更强

deployment

rc的升级,可以随时知道pod部署进度
场景:
创建pod副本
查看部署是否完成
创建新pod(如镜像升级)
...

# deployment定义,
apiVersion: extensions/v1beta
kind:Deployment 
metadata: 
  name: nginx-deployment

# replica set定义
apiVersion: v1 
kind: ReplicaSet 
metadata: 
  name: nginx-repset

# 创建deployment
# tomcat-deployment.yaml
----------------
apiVersion: extensions/v1beta1 
kind: Deployment
metadata: 
  name: frontend 
spec: 
  replicas: 1 
  selector: 
    matchLabels: 
      tier: frontend
    matchExpressions: 
    - {key: tier, operator: In, values: [frontend]}
  template: 
    metadata: 
      labels: 
        app: app-demo 
        tier: frontend
    spec: 
      containers: 
      - name: tomcat-demo 
        image: tomcat 
        imagePullPolicy: IfNotPresent 
        ports: 
        - containerPort: 8080
----------------
kubectl create -f tomcat-deployment.yaml
# 查看deployment
kubectl get deployments 
# 查看replica set
kubectl get rs
# 可以看到rs命名与deployment有关
# 查看pod
kubectl get pods
# 可以看到pod命名以rs为前缀
Horizontal Pod Autoscaler

横向自动扩容
通过scale扩容不符合k8s自动化定位,需要根据负载水平扩展或缩容,这一过程频繁发生,手工控制不现实
两种度量指标,CPUUtilizationPercentage()cpu使用率)和自定义指标(TPS或QPS)
通常使用1min内的平均CPU使用量,需要安装Heapster插件

# HPA例子
# 目标对象为php-apache,pod副本的CPUUtilizationPercentage超过90%时自动扩容
apiVersion: autoscaling/v1 
kind: HorizontalPodAutoscaler 
metadata: 
  name: php-apache 
  namespace: default 
  spec: 
    maxReplicas: 10 
    minReplicas: 1 
    scaleTargetRef: 
      kind: Deploynent
      name: php-apache 
    targetCPUUtilizationPercentage: 90

# 还可以通过命令创建HPA对象
kubectl autoscale deployment php-apache --cpu-percent=90 - - min=1 --max=10
StatefulSet

Deployment/RC的一个特殊变种
特性:
假设StatefulSet的名字叫kafka,,那么第l个Pod叫kafka-0,第2个叫kafk-1,以此类推
Pod副本的启停顺序是受控的
pod使用稳定的持久化存储卷,通过pv/pvc实现,删除pod不会删除存储卷
要与HeadlessService配合使用,HeadlessService没有cluster ip
如一个3节点的Kafka的StatefulSet集群,对应的HeadlessService的名字为kafka,StatefulSet的名字为kafka,则StatefulSet里面的3个Pod的DNS名称分别为kafka-0.kafka、kafka-1.kafka、kafka-3.kafka,这些DNS名称可以直接在集群的配置文件中固定下来

service

就是微服务
k8s为service定义入口地址,通过该地址访问背后的pod副本,service和pod通过label selector对接,rc保证service质量
客户端pod转发到哪个pod由负载算法决定
kube proxy机负载均衡器,k8s为每一个服务分配全局唯一的虚拟ip

# 创建service
# tomcat-service.yaml
------------
apiVersion: v1 
kind: Service 
metadata: 
  name: tomcat-service
spec: 
  ports: 
  - port: 8080 
  selector:
    tier: frontend
------------
kubectl create -f tomcat-service.yaml
# 查看endpoint列表
kubectl get endpoints 
# 查看service的cluster ip
kubectl get svc tomcat-service -o yaml 
# targetPort确定容器暴露的端口号,默认与port相同
# 很多服务存在多端口问题, service支持多endpoint
-------
spec: 
  ports: 
  - port:8080 
    name: service-port 
  - port: 8080 
    name: shutdown-port
-------
服务发现机制

大多数分布式系统通过api接口实现服务发现导致侵入性比较强
k8s中服务有唯一的cluster ip和name,k8s最早采用环境变量的方式通过服务名找到cluster ip,后来引入dns系统

外部系统访问Service

区别3种ip:
node ip即每个节点的物理网卡ip
pod id是docker0网桥分配,真实流量通过node ip网卡流出
cluster ip,仅作用与service对象,无法被ping,结合service port组成具体通信端口,无法在集群外使用,集群外访问通过定义NodePort实现

# 修改上述tomcat-service.yaml,增加type和nodePort
------------
apiVersion: v1 
kind: Service 
metadata: 
  name: tomcat-service
spec: 
  ports: 
  type: NodePort 
  - port: 8080 
    nodePort: 31002 
  selector:
    tier: frontend
-------------------
# 浏览器访问: NodeIp:31002
volume

volume定义在pod,被pod多个容器挂载到具体的目录
容器停止,volume数据不丢失
k8s支持多种类型的volume,如gluster fs和ceph

template: 
  metadata: 
    labels: 
      app: app-demo 
      tier:frontend 
  spec: 
    volumes: 
    - name: datavol 
      emptyDir: {} 
    containers:
    - name: tomcat-demo 
      image: tomcat 
      volumeMounts: 
      - mountPath: /mydata-data 
        name: datavol 
      imagePullPolicy: IfNotPresent

volume扩展出配置管理,通过ConfigMap实现

Namespace

多租户资源隔离

# 默认pod\rc\service都被创建到default中
kubectl get namespaces
# 定义namespace
-----------
apiVersion: v1 
kind: Namespace 
metadata: 
  name: development
------------
# 定义pod指定namespace
-----------
kind: Pod 
metadata: 
  name: busybox 
  namespace: development
----------
# get命令查看无法显示
kubectl get pods
# 需指定namespace参数
kubectl get pods --namespace=development 

多租户namespace资源隔离可以配合资源配额管理

Annotation

与label类似,kv形式
定义附加信息,如构建信息\团队信息等

相关文章

网友评论

      本文标题:k8s-01-入门

      本文链接:https://www.haomeiwen.com/subject/gnwydktx.html