• 学习k8s(一)


    一、安装及介绍

    1、k8s架构

    2、核心组件

     3、其他组件

     4、安装方式

    yum安装:        1.5 最简单,版本低,适合学习
    二进制安装:      最繁琐,可以用saltstack安装
    kubeadm安装:    谷歌推荐的自动化安装工具,网络有要求
    go源码编译安装:  最难,需要go环境
    minikube:      单机版,只适合体验

    5、环境介绍

    主机

    ip地址

    cpu核数

    内存

    swap

    host解析

    软件版本

    k8s-master

    192.168.4.11

    1+

    2G+

    关闭

    需要

    docker-1.12.6-71

    k8s-node

    192.168.4.12

    1+

    2G+

    关闭

    需要

    kubernetes-1.5.2

    # hostnamectl set-hostname k8s-master
    # hostnamectl set-hostname k8s-node
    
    192.168.4.11     k8s-master
    192.168.4.12     k8s-node
    
    # setenforce 0
    # systemctl stop firewalld.service
    # systemctl stop NetworkManager.service

    6、配置yum源

    # cat /etc/yum.repos.d/mnt.repo 
    [old-os]
    name=old
    baseurl=https://mirrors.aliyun.com/centos/7/os/x86_64/
    enabled=1
    gpgcheck=0
    
    [new-os]
    name=os
    baseurl=https://mirrors.aliyun.com/centos/7.7.1908/os/x86_64/
    enabled=0
    gpgcheck=0
    
    [extras]
    name=extras
    baseurl=https://mirrors.aliyun.com/centos/7.7.1908/extras/x86_64/
    enabled=0
    gpgcheck=0
    
    [epel]
    name=epel
    baseurl=https://mirrors.aliyun.com/epel/7Server/x86_64/
    enabled=0
    gpgcheck=0
    
    [vault]
    name=va
    baseurl=http://vault.centos.org/7.4.1708/extras/x86_64
    enabled=1
    gpgcheck=0

    7、安装配置k8s-master

    1)安装配置etcd

    1、安装etcd(数据库kv类型存储,原生支持做集群)
    # yum install -y etcd
    
    2、配置etcd
    # grep '^[a-Z]' /etc/etcd/etcd.conf 
    ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
    ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
    ETCD_NAME="default"
    ETCD_ADVERTISE_CLIENT_URLS="http://192.168.4.11:2379"
    
    3、启动服务
    # systemctl enable etcd
    # systemctl start  etcd
    
    4、取值检验
    # etcdctl set   testdir/testkey test
    # etcdctl get   testdir/testkey
    
    5、健康状态检查
    # etcdctl -C http://192.168.4.11:2379 cluster-health

    6、netstat -lntp | grep etcd
    # 2379:对外提供服务,k8s写入数据
    # 2380:集群间数据同步

    2)安装配置K8s-master

    1、安装
    # yum install kubernetes-master  -y
    
    2、修改api配置文件
    # grep '^[a-Z]' /etc/kubernetes/apiserver  8:KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
    17:KUBE_ETCD_SERVERS="--etcd-servers=http://192.168.4.11:2379"
    20:KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
    23:KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
    26:KUBE_API_ARGS=""
    #删除23行ServiceAccount 服务认证,会很坑。
    
    3、修改config配置文件(公共配置文件)
    # grep '^[a-Z]' /etc/kubernetes/config 13:KUBE_LOGTOSTDERR="--logtostderr=true"
    16:KUBE_LOG_LEVEL="--v=0"
    19:KUBE_ALLOW_PRIV="--allow-privileged=false"
    22:KUBE_MASTER="--master=http://192.168.4.11:8080"
    # 指定apiserver地址,给controller-manager和scheduler使用,日志默认在/var/log/messages,可修改。
    
    4、启动服务
    # systemctl enable kube-apiserver.service
    # systemctl start  kube-apiserver.service
    # systemctl enable kube-controller-manager.service
    # systemctl start  kube-controller-manager.service
    # systemctl enable kube-scheduler.service
    # systemctl start  kube-scheduler.service
    
    5、检查服务是否安装正常
    # kubectl  get cs
    NAME                 STATUS    MESSAGE             ERROR
    scheduler            Healthy   ok                  
    controller-manager   Healthy   ok                  
    etcd-0               Healthy   {"health":"true"}   
    
    组件作用
    api-server:   接受并响应用户的请求
    controller:   控制器管理,保证容器始终存活
    scheduler:    调度器,选择启动容器的node节点

    8、安装配置k8s-node

    1、安装
    # yum install kubernetes-node  -y
    
    2、配置
    # grep '^[a-Z]' /etc/kubernetes/config -n
    13:KUBE_LOGTOSTDERR="--logtostderr=true"
    22:KUBE_MASTER="--master=http://192.168.4.11:8080"
    
    # grep '[^a-Z]'/etc/kubernetes/kubelet
    5行:KUBELET_ADDRESS="--address=0.0.0.0"
    8行:KUBELET_PORT="--port=10250"
    11行:KUBELET_HOSTNAME="--hostname-override=192.168.4.12"
    14行:KUBELET_API_SERVER="--api-servers=http://192.168.4.11:8080"
    
    3、启动服务
    # systemctl enable kubelet.service
    # systemctl start kubelet.service
    # systemctl enable kube-proxy.service
    # systemctl start kube-proxy.service
    
    4、在master节点检查
    # kubectl get nodes
    NAME           STATUS    AGE
    192.168.4.12   Ready     4d

    组件作用
    kubelet: 调用docker,管理容器生命周期
    kube-proxy: 提供容器的网络访问

    8、所有节点安装flannel网络

    flannel:不同宿主机之间容器的通信

    1、安装
    # yum install flannel -y
    # yum install docker-1.12.6-71.git3e8e77d.el7.centos.x86_64(master节点要配置镜像仓库)
    
    2、配置 # grep '^[a-Z]' /etc/sysconfig/flanneld -n 4:FLANNEL_ETCD_ENDPOINTS="http://192.168.4.11:2379" 8:FLANNEL_ETCD_PREFIX="/atomic.io/network" #也可以用sed替换 # sed -i s#127.0.0.1:2379#192.168.4.11:2379#g /etc/sysconfig/flanneld 3、master节点 # etcdctl mk /atomic.io/network/config '{"Network":"172.16.0.0/16"}' #docker网段 如果设置错了,删除重新设置 # etcdctl get /atomic.io/network/config # etcdctl rm /atomic.io/network/config 4、启动服务 # systemctl enable flanneld.service # systemctl restart flanneld.service # systemctl restart docker # systemctl enable docker master节点: # systemctl restart kube-apiserver.service # systemctl restart kube-controller-manager.service # systemctl restart kube-scheduler.service node节点: # systemctl restart kubelet.service # systemctl restart kube-proxy.service

    5、检查服务
    # ifconfig flannel0

    docker1.13版本中的一个问题,需要修改iptables,否则容器之间不通
    # vim /usr/lib/systemd/system/docker.service
    ExecStartPost=/sbin/iptables -P FORWARD ACCEPT

    容器网络互通测试

    1、所有节点启动容器并获取容器ip地址
    # docker run -it busybox /bin/sh   
    
    2、网络互通性测试
    # ping 172.16.30.2      ping自己
    # ping 172.16.30.1      ping网关
    # ping 172.16.20.2      ping容器

    配置master为镜像仓库

    1、所有节点,配置镜像加速,以及私有仓库地址
    1.13版本之前
    # vim /etc/sysconfig/docker
    OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false --registry-mirror=https://registry.docker-cn.com --insecure-registry=192.168.4.11:5000'
    1.13版本之后
    # vim /etc/docker/daemon.json  
    {
      "registry-mirror": ["registry.docker-cn.com"],
      "insecure-registries":["192.168.4.11:5000"]
    }
    重启服务
    # systemctl restart docker
    
    2、启动私有仓库 # docker run -d -p 5000:5000 --restart=always --name registry -v /opt/registry:/var/lib/registry registry 3、推送镜像测试 master节点: # docker tag docker.io/busybox:latest 192.168.4.11:5000/busybox:latest # docker push 192.168.4.11:5000/busybox:latest node节点: # docker images
    # docker pull 192.168.4.11:5000/busybox:latest

    二、功能和基础架构

    1、k8s有什么功能

    k8s是一个docker集群的管理工具

    k8s是容器的编排工具

    2、k8s的核心功能

    自愈: 重新启动失败的容器,在节点不可用时,替换和重新调度节点上的容器,对用户定义的健康检查不响应的容器会被中止,并且,在容器准备好服务之前不会把容器向客户端广播。
    
    弹性伸缩: 通过监控容器的cpu的使用负载,如果这个容器评价高于80%,增加容器的数量,平均值低于10%,减少容器数量。
    
    服务的自动发现和负载均衡: 不需要修改您的应用程序来使用不熟悉的服务发现机制,kubernetes为容器提供了自己的ip地址和一组容器的单个DNS名称,并可以在他们之间进行负载均衡。
    
    滚动升级和一键回滚: kubernetes 逐渐部署对应用程序或者其配置的更改,同时监视应用程序运行状况,以确保它不会同时终止所有实例。如果出现问题,kubernetes会为你恢复更改,利用日益增长的部署,解决方案的生态系统。
    
    私密配置文件管理: web容器里面,数据库的账户密码(测试库密码)

    3、k8s的应用场景

    最适合跑微服务项目!

    微服务的好处

    能承载更高的并发
    业务健壮性,高可用
    修改代码,重新编译时间短
    
    持续集成,持续发布
    jenkins代码自动上线

     

     三、k8s常用的资源

    1、pod资源

    pod是最小的资源单位

    任何一个k8s资源都可以有yml清单文件来定义

    k8s yaml的主要组成

    apiVersion: v1  api版本
    kind: pod       资源类型
    metadata:       属性
    spec:           详细

    pod基本操作

    创建
    # kubectl create –f  ks8_pod.yaml
    
    查询
    # kubectl get pod  
    # kubectl describe pod
    # kubectl get pod -o wide  查看资源列表 删除 # kubectl delete pod nginx # kubectl delete
    -f ks8_pod.yaml 更新 # Kubectl replace ks8_pod.yaml

    一个最简单的pod

    编辑k8s_pod.yml文件

    apiVersion: v1  #版本
    kind: Pod       #资源类型
    metadata:       #元数据(属性)
      name: nginx   #pod名字
      labels:       #标签  键值对
        app: web
    spec:           #详细
      containers:   #容器
        - name: nginx  #名字
          image: 192.168.4.11:5000/nginx:latest #镜像
          ports:
            - containerPort: 80         #端口

    启动pod

    # kubectl  create -f ks8_pod.yaml

    获取pod详细信息kubectl describe(排错常用命令)

    # kubectl describe pod nginx

    构建成失败,此处有坑
    错误是无法从registry.access.redhat.com仓库获取镜像

    解决办法:
    1、下载redhat-ca.crt证书
    2、下载镜像文件,tag改名,上传到私有仓库

    node节点
    # vim /etc/kubernetes/kubelet
    KUBELET_POD_INFRA_CONTAINER="--pod-infra-container image=192.168.4.11:5000/pod-infrastructure:latest"
    重启服务
    # systemctl restart kubelet.service

    pod资源:至少由两个容器组成,pod基础容器和业务容器组成(最多1+4)

    pod网络类型是container

    Nginx没有IP地址

    # docker ps -a
    CONTAINER ID        IMAGE
    b28f849335a7        192.168.4.11:5000/nginx:latest
    2bed13c3afda        192.168.4.11:5000/pod-infrastructure:latest
    
    # docker inspect b28f849335a7| tail -22
    "NetworkSettings": {
                "Bridge": "",
                "SandboxID": "",
                "HairpinMode": false,
                "LinkLocalIPv6Address": "",
                "LinkLocalIPv6PrefixLen": 0,
                "Ports": null,
                "SandboxKey": "",
                "SecondaryIPAddresses": null,
                "SecondaryIPv6Addresses": null,
                "EndpointID": "",
                "Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "IPAddress": "",
                "IPPrefixLen": 0,
                "IPv6Gateway": "",
                "MacAddress": "",
                "Networks": {}
            }

    访问的IP实际是pod-infrastructure容器的ip

    # docker inspect 01549ff0cf31| tail -22
                "IPPrefixLen": 24,
                "IPv6Gateway": "",
                "MacAddress": "02:42:ac:10:0e:02",
                "Networks": {
                    "bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "NetworkID": "91b2a8f0e6bc27e794c236206658ff980174af5af50f5c8960da2920d3936eca",
                        "EndpointID": "32d012474893339123e7ce707d89528831a50fd05374bb773fe5abab050b1e81",
                        "Gateway": "172.16.30.1",
                        "IPAddress": "172.16.30.2",
                        "IPPrefixLen": 24,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "MacAddress": "02:42:ac:10:0e:02"
                    }
                }

    原理:Nginx只提供web服务,pod-infrastructure的基础容器提供IP,实现k8s负载均衡、服务自愈等高级功能。

    一个pod两个容器nginx+redis(端口不冲突即可)

    1、编辑pod文件
    # cat ks8_pod.yaml apiVersion: v1 kind: Pod metadata: name: test labels: app: web spec: containers:
    - name: nginx image: nginx:latest ports: - containerPort: 80 - name: redis image: redis:latest
    imagePullPolicy: IfNotPresent(使用本地镜像,不要pull) ports:
    - containerPort: 6379 2、创建并验证 # kubectl create -f ks8_pod.yaml # kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE po/test 2/2 Running 0 25s 172.16.30.2 192.168.4.12
    访问Nginx和Redis,共用一个ip # curl -I 172.16.30.2 # telnet 172.16.30.2 6379
    node1节点上有3个容器 Nginx+ Redis + pod # docker ps CONTAINER ID IMAGE COMMAND 922e73599020 redis:latest "docker-entrypoint..." 28690cdbc403 nginx:latest "nginx -g 'daemon off" c630ef8c2216 pod-infrastructure:latest "/pod"

    k8s每启动一个容器,都需要先启动一个pod容器,启动的容器共用pod容器的ip地址

    2、ReplicationController 资源

    通过metadata标签,选择器selector管理pod
    rc:保证指定数量的pod始终存活,确保pod数量,确保pod健康,弹性伸缩,滚动升级

    创建yaml文件

    # vim   myweb-rc.yml
    apiVersion: v1
    kind: ReplicationController       
    metadata:
      name: myweb         #rc的名字
    spec:
      replicas: 3         #副本数
      selector:
        app: myweb        #选择器,管理pod
      template:
        metadata:
          labels:
            app: myweb    #此为pod的标签
        spec:
          containers:
          - name: nginx
            image: 192.168.4.11:5000/nginx:latest
            ports:
            - containerPort: 80

    故障自愈(多次删除自动新启动容器)

    1、创建
    # kubectl create -f myweb-rc.yaml 
    2、查看 # kubectl get all -o wide
    NAME DESIRED CURRENT READY AGE CONTAINER(S) IMAGE(S) SELECTOR rc
    /myweb 3 3 3 21s nginx nginx:latest app=myweb NAME READY STATUS RESTARTS AGE IP NODE po/myweb-9gngt 1/1 Running 0 21s 172.16.30.4 192.168.4.12 po/myweb-blrwr 1/1 Running 0 21s 172.16.30.3 192.168.4.12 po/myweb-wk6gm 1/1 Running 0 21s 172.16.30.2 192.168.4.12 3、删除pod,rc会自动创建 # kubectl delete pod myweb-9gngt # kubectl delete pod myweb-wk6gm
    # kubectl
    get pods -o wide
    NAME             READY     STATUS    RESTARTS   AGE       IP            NODE
    po/myweb-blrwr   1/1       Running   0          51s       172.16.30.3   192.168.4.12
    po/myweb-8dkee   1/1       Running   0          21s       172.16.30.5   192.168.4.12
    po/myweb-7wsek   1/1       Running   0          21s       172.16.30.6   192.168.4.12

    弹性伸缩—手动

    方式一:kubectl scale rc 【rc-name】 --replicas=1

    1、查看rc名字
    # kubectl get rc  -o wide 
    
    2、修改副本数
    # kubectl scale rc myweb --replicas=5
    
    3、查看结果
    # kubectl  get pods -o wide --selector app=myweb

    方式二 :手动编辑 

    # kuberctl  edit rc myweb
    设置 replicas

    服务发现和负载均衡

    1、查看当前rc和pod
    # kubectl  get all  -o wide  --show-labels
    NAME       DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)       SELECTOR    LABELS
    rc/myweb   3         3         3         21s       nginx          nginx:latest   app=myweb   app=myweb NAME             READY     STATUS    RESTARTS   AGE       IP            NODE           LABELS
    po/myweb-blrwr   1/1       Running   0          51s       172.16.30.3   192.168.4.12   app=myweb
    po/myweb-8dkee   1/1       Running   0          21s       172.16.30.5   192.168.4.12 app=myweb po/myweb-7wsek   1/1       Running   0          21s       172.16.30.6   192.168.4.12 app=myweb
    po/test    1/1       Running   0          56s       172.16.30.2   192.168.4.12 app=web
    2、修改test标签:app=myweb
    # kubectl edit pod test app: myweb kubectl
    get pod NAME READY STATUS RESTARTS AGE po/myweb-blrwr 1/1 Running 0 8m po/myweb-8dkee 1/1 Running 0 8m po/test 1/1 Running 0 1h

    3、小结
    1)因为rc控制器设置最少保持3个副本
    2)rc控制器是根据Labels 标签来区分的
    3)test的标签和myweb控制器的标签一样,所以就删除了存活时间最短的容器(rc认为pod存活久的比较稳定,默认删除新的pod)

    rc滚动的升级和回滚

    1、创建nginx两个版本yaml文件
    # cat nginx-1.13-rc.yaml 
    kind: ReplicationController apiVersion: v1 metadata: name: nginx spec: replicas:
    1 selector: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.13 ports: - containerPort: 80 # cat nginx-1.15-rc.yaml kind: ReplicationController apiVersion: v1 metadata: name: nginx spec: replicas: 1 selector: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.15 ports: - containerPort: 80 2、滚动升级 # kubectl create -f nginx-1.13-rc.yaml 创建旧版本nginx # kubectl rolling-update nginx -f nginx-1.15-rc.yaml --update-period=20s # curl -I 172.16.30.2 检查版本
    3、一键回滚 # kubectl rolling-update nginx -f nginx-1.13-rc.yaml --update-period=10s # curl -I 172.16.30.2 检查版本

    3、deployment资源

    rc在滚动升级之后,会造成服务访问中断,于是k8s引入了deployment资源

    对比rc的好处:

    升级服务不中断
    不依赖yaml文件
    rc标签选择器不支持模糊匹配,rs标签选择器支持模糊匹配

    通过文件创建deployment

    1、创建yaml文件
    # cat nginx-dep.yaml 
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: nginx-dep
    spec:
      replicas: 3
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: 192.168.4.11:5000/nginx:1.13
            ports:
            - containerPort: 80
    2、启动
    # kubectl create -f nginx-dep.yaml 
    
    3、查看
    # kubectl get deploy
    
    DESIRED :   Pod副本数量的期望值,即Deployment里定义的Replica。
    CURRENT:   当前实际的Replica数量,当这个值不断增加,达到DESIRED时表明部署完成。
    UP-TO-DATE:最新版本的Pod副本数量,用于指示在滚动升级过程中有多少Pod副本已经成功升级。
    AVAILABLE:  当前集群中可用的Pod副本数量(当前存活的Pod数量)

    自动加载deployment配置

    deployment编辑配置之后可以自动加载,不想rc还需要删除再启动。
    1、修改副本数
    # kubectl edit deployment nginx-dep
     replicas: 2
    
    2、查看
    # kubectl get all -o wide

    通过命令行创建deployment

    1、命令创建
    # kubectl run nginx-dep2 --image=192.168.4.11:5000/nginx:1.15 --replicas=1 --record
    
    2、查看
    # kubectl get all

    手动扩容缩容

    # kubectl scale deployment nginx-dep2  --replicas=2
    # kubectl get all
    

    升级pod镜像版本

    1、查看pod镜像版本及名字
    # kubectl get rs -o wide
    
    2、升级镜像
    # kubectl
    set image deploy nginx-dep2 nginx-dep2=192.168.4.11:5000/nginx:1.15 nginx-dep2=192.168.4.11:5000/nginx:1.15 的名字
    3、查看升级结果 # kubectl get rs -o wide 4、查看升级状态 # kubectl rollout status deployment nginx-dep2 5、查看升级历史 # kubectl rollout history deployment nginx-dep2 6、查看历史版本详情 # kubectl rollout history deployment nginx-dep2 --revision=2

    回滚pod镜像版本

    1、查看历史版本
    # kubectl rollout history deployment nginx-dep2
    
    2、执行回滚指定版本
    # kubectl rollout undo deployment nginx-dep2 --to-revision=1
    
    3、检查回滚结果
    # kubectl get pods -o wide 
    # curl -I 172.16.30.2

    生产建议--record

    --record参数: 记录执行的操作步骤和相关信息,生产建议采用这种方式创建deployment

    rc和deployment的升级区别

    rc:
    # kubectl rolling-update nginx -f nginx-1.15-rc.yaml  --update-period=20s  升级
    # kubectl rolling-update nginx -f nginx-1.13-rc.yaml  --update-period=20s  回滚
    
    deploy:
    # kubectl create   -f nginx-dep.yaml  --record                             文件创建
    # kubectl set image deploy nginx-dep nginx=192.168.4.11:5000/nginx:1.15    升级或回滚
    
    # kubectl run nginx-dep2 --image=192.168.4.11:5000/nginx:1.15 --replicas=1 --record
    # kubectl set image deploy nginx-dep2 nginx-dep2=192.168.4.11:5000/nginx:1.15
    
    # kubectl rollout history deployment nginx-dep2                            查看历史版本
    # kubectl rollout undo deployment nginx-dep2 --to-revision=1               回滚指定版本

    rc修改(edit)配置文件,需要启动新容器才生效
    deploy修改配置文件,立即生效

    4、service资源

    介绍

    Pod挂掉后ip地址会改变,外部不能访问容器内的服务,service是提供了一个固定IP,cluster ip(vip),通过该固定的IP来进行通信
    service的作用:帮助外界用户访问k8s内的服务,并且提供负载均衡 service默认使用iptables来实现负载均衡, k8s
    1.8新版本中推荐使用lvs(四层负载均衡 传输层tcp,udp)
    Service同RC一样,都是通过Label来关联Pod的。在Service的yaml文件中定义了selector中的label为app:my
    -web,那么这个Service会将Pod-->metadata-->labeks中label为app:my-web的Pod作为分发请求的后端。当Pod发生变化时(增加、减少、重建等),Service会及时更新。这样一来,Service就可以作为Pod的访问入口,起到代理服务器的作用,而对于访问者来说,通过Service进行访问,无需直接感知Pod。 需要注意的是,Kubernetes分配给Service的固定IP是一个虚拟IP,并不是一个真实的IP,在外部是无法寻址的。真实的系统实现上,Kubernetes是通过Kube-proxy组件来实现的虚拟IP路由及转发。所以在之前集群部署的环节上,我们在每个Node上均部署了Proxy这个组件,从而实现了Kubernetes层级的虚拟转发网络。

    kubernetes中的三种IP

    Node IP:    Node节点IP地址
    Cluster IP: Service的IP地址
    Pod IP:     Pod的IP地址

    Service负载均衡

    1、创建
    # kubectl create -f myweb-svc.yaml 
    # cat myweb-svc.yaml 
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
    spec:
      type: NodePort        #转发方式
      ports:
        - port: 80          #clusterIP(vip)端口
          nodePort: 30001   #node端口
          targetPort: 80    #pod 端口
      selector:         
        run: nginx-dep2     #标签选择器(选择rc的pod资源)
    
    2、查看service状态
    # kubectl describe svc nginx                             
    Name:                   nginx
    Namespace:              default
    Labels:                 <none>
    Selector:               run=nginx-deployment2    #搜索标签
    Type:                   NodePort                 #转发方式
    IP:                     10.254.18.231            #虚拟IP
    Port:                   <unset> 80/TCP
    NodePort:               <unset> 30001/TCP        #node暴露端口
    Endpoints:              172.16.30.2:80,172.16.30.3:80,172.16.30.5:80 + 2 more... #pod
    Session Affinity:       None
    
    3、访问测试
    是由kuber-proxy服务提供的
    # curl   192.168.4.11:30000
    # curl   192.168.4.12:30000

    修改Service的nodePort范围

    默认分配30000-32767
    1、修改默认端口
    # vim /etc/kubernetes/apiserver
    KUBE_API_ARGS="--service-node-port-range=10000-50000"
    
    2、启动服务
    # systemctl restart kube-apiserver.service

    命令行创建service资源

    # kubectl expose rc  nginx --type=NodePort --port=80
    # kubectl expose 资源类型  资源名称  端口类型  暴漏端口

    其他

    1、非交互式修改副本数量
    # kubectl scale rc nginx --replicas=2 调度 名称 副本数 2、进入容器
    # kubectl exec
    -it nginx-ld22v /bin/bash

    3、网站curl 不通 排错思路:
    内核转发参数,iptables规则
    重启服务flanneld,docker , kubelet ,kube-proxy

    四、项目实践

    1、简单web应用tomcat+mysql

    准备镜像

    1、下载
    # docker pull kubeguide/tomcat-app:v2
    # docker pull mysql:5.7
    
    2、改名并上传
    # docker tag docker.io/kubeguide/tomcat-app:v1  192.168.4.11:5000/tomcat-app:v1
    # docker tag docker.io/mysql:5.7    192.168.4.11:5000/mysql:5.7
    # docker push  192.168.4.11:5000/tomcat-app:v1
    # docker push  192.168.4.11:5000/mysql:5.7

    部署mysql 服务

    1、创建yaml文件
    # vim mysql-dep.yaml
    apiVersion: extensions/v1beta1
    kind: Deployment                       
    metadata:  
      name: mysql                          #Deployment的名称,全局唯一
    spec:
      replicas: 1                          #Pod副本的数量
      selector:
        matchLabels:                       #定义RS的标签
          app: mysql                       #符合目标的Pod拥有此标签
      template:                            #根据此模版创建Pod的副本(实例)
        metadata:
           labels:
             app: mysql                    #Pod拥有的标签,对应Deployment的selector
        spec:
           containers:                     #Pod内,定义容器
           - name: mysql                   #容器名称
             image: 192.168.0.136:5000/mysql:5.7             
             ports:
             - containerPort: 3306         #容器应用监听的端口
             env:                          #环境变量
             - name: MYSQL_ROOT_PASSWORD   #设置root初始密码
               value: "123456"
    
    # vim mysql-rc.yaml
    apiVersion: v1
    kind: ReplicationController            #副本控制器RC
    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: 192.168.0.136:5000/mysql:5.7             
             ports:
             - containerPort: 3306         #容器应用监听的端口
             env:                          #环境变量
             - name: MYSQL_ROOT_PASSWORD   #设置root初始密码
               value: "123456"
    
    2、创建mysql-deployment
    # kubectl create -f mysql-dep.yaml
    
    3、创建mysql serveice文件
    # vim mysql-svc.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: mysql
    spec:
      type: NodePort
      ports:
      - port: 3306
        nodePort: 30001
      selector:
        app: mysql
    
    4、创建MySQL svc
    # kubectl create -f mysql-svc.yaml

    部署web服务

    1、创建yaml文件
    # vim   tomcat-app-dep.yaml
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: tomcat-app
    spec:
      replicas: 3
      template:
        metadata:
          labels:
            app: tomcat-app
        spec:
          containers:
          - name: tomcat-app
            image: 192.168.0.136:5000/tomcat-app:v1
            ports:
            - containerPort: 8080
            env:
            - name: MYSQL_SERVICE_HOST
              value: 'mysql'                  #这是一个坑,最好写mysql服务的Cluster IP
            - name: MYSQL_SERVICE_PORT
              value: '3306'
    
    # vim  tomcat-app-rc.yaml 
    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: myweb
    spec:
      replicas: 1
      selector:
        app: myweb
      template:
        metadata:
          labels:
            app: myweb
        spec:
          containers:
            - name: myweb
              image: kubeguide/tomcat-app:v2
              ports:
              - containerPort: 8080
              env:
              - name: MYSQL_SERVICE_HOST
                value: 'mysql'               mysql为域名要解析
              - name: MYSQL_SERVICE_PORT
                value: '3306'
    
    2、创建tomcat-app-deployment
    # kubectl create -f tomcat-app-dep.yaml 
    
    3、创建tomcat-app service文件
    # vim tomcat-app-svc.yaml 
    apiVersion: v1
    kind: Service
    metadata:
      name: tomcat-app
    spec:
      type: NodePort
      ports:
        - port: 8080
          name: myweb-svc
          nodePort: 30002
      selector:
        app: tomcat-app
    
    4、创建tomcat-app service
    # kubectl create -f tomcat-app-svc.yaml 

    测试

    1、查看所有svc、pod的状态及端口
    # kubectl get all -o wide 
    
    2、测试pod
    # curl    172.16.30.2:8080 -I
    # telnet  172.16.30.3 3306
    
    3、测试svc
    # curl    10.254.102.27:8080 -I
    # telnet  10.254.217.119 3306
    
    4、测试node
    # curl 192.168.4.12:30008 -I
    http://192.168.4.11:30008
    http://192.168.4.11:30008/demo
    插入一条数据
    
    5、主要
    # cat tomcat-app-dep.yaml
    env:
            - name: MYSQL_SERVICE_HOST
              value:  '10.254.217.119'
    tomcat-app-dep.yaml 文件mysql是域名要解析,没有dns,只能写cluster IP MySQL没有持久化,pod的数据是临时的,如果删除pod或者重启deployment,数据会丢失

     2、持久化存储

     数据持久化方式:

    1、Volume
    Docker数据持久化方案
    
    2、k8s支持的数据卷类型
    1)本地数据卷
    EmptyDir:Pod配置了EmpyDir数据卷,只要Pod 存在,数据卷就会存在,Pod被删除,数据卷也会被删除,并且永久丢失,适合实现Pod中容器的文件共享。
    HostPath:数据卷将容器宿主机上的文件系统挂载到Pod中。
    
    2)网络共享数据卷
    网络数据卷包含以下几种:NFS、iSCISI、GlusterFS、RBD(Ceph Block Device)、Flocker、AWS Elastic Block Store、GCE Persistent Disk
    
    3)PV和PVC
    PV(Persistent Volume):由管理员添加的的一个存储的描述,是一个全局资源,包含存储的类型,存储的大小和访问模式等。它的生命周期独立,例如当使用它的Pod销毁时对PV没有影响。
    PVC(Persistent Volume Claim):是Namespace里的资源,描述对PV的一个请求。请求信息包含存储大小,访问模式等。
    
    4)信息数据卷
    信息数据卷:主要用来给容器传递配置信息,如Secret(处理敏感配置信息,密码、Token等)、Downward API(通过环境变量的方式告诉容器Pod的信息)、Git Repo(将Git仓库下载到Pod中),都是将Pod的信息以文件形式保存,然后以数据卷方式挂载到容器中,容器通过读取文件获取相应的信息

    通过NFS实现持久化存储

    配置NFS存储服务

    1、环境
    k8s-master  nfs-server
    k8s-node    nfs-client
    
    2、配置nfs
    master:
    # yum install -y nfs-utils      安装
    # mkdir -p /data/tomcat         创建共享目录
    # cat /etc/exports              创建共享配置文件
    /data 192.168.4.0/24(rw,no_root_squash,no_all_squash,sync)
    # systemctl start nfs           启动服务
    node:
    # yum install -y nfs-utils      安装客户端

    创建PV-持久卷

    1、创建pv文件
    # cat  pv_nfs.yaml
    apiVersion: v1
    kind: PersistentVolume                     #资源类型
    metadata:
      name: mysql-tomcat
      labels:
        type: mysql-tomcat-nfs
    spec:
      capacity:
        storage: 5Gi 
      accessModes:
        - ReadWriteMany                       #访问模式,多个客户端读写
      persistentVolumeReclaimPolicy: Recycle  #回收策略-可以回收
      nfs:
        path: "/data/tomcat"
        server: 192.168.4.11                  #k8s-nfs matser
        readOnly: false                       #只读
    
    2、创建pv
    # kubectl create  -f pv_nfs.yaml 
    
    3、查看PV信息
    # kubectl describe pv

    创建PVC-持久卷

    1、创建PVC文件
    # cat pvc_nfs.yaml 
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mysql-tomcat-pvc
    spec:
      accessModes:
      - ReadWriteMany      
      resources:
         requests:
           storage: 1Gi
    
    2、创建pvc
    # kubectl create  -f pv_nfs.yaml 

    3、查看pvc
    # kubectl get pvc

    MySQL挂载共享存储

    1、重新修改mysql的yaml文件
    # cat mysql-dep.yaml 
    apiVersion: extensions/v1beta1
    kind: Deployment                       #控制器Deployment
    metadata:  
      name: mysql                          #Deployment的名称,全局唯一
    spec:
      replicas: 1                          #Pod副本的数量
      template:                            #根据此模版创建Pod的副本(实例)
        metadata:
           labels:
             app: mysql                    #Pod副本拥有的标签,对应Deployment的selector
        spec:
           containers:                     #Pod内,定义容器
           - name: mysql                   #容器名称
             image: 192.168.0.136:5000/mysql:5.7          
             ports:
             - containerPort: 3306         #容器监听的端口
             
             volumeMounts:
             - name: mysql-data-pvc        #容器内挂载点名称
               mountPath: /var/lib/mysql   #容器内挂载目录
             env:                          #注入容器内的环境变量
             - name: MYSQL_ROOT_PASSWORD   #这里设置root初始密码
               value: "123456"
           volumes:  
           - name: mysql-data-pvc           #数据卷名称,要和容器内挂载点名称一致
             persistentVolumeClaim:
               claimName: mysql-tomcat-pvc  #pvc名称
    
    2、更新yaml文件
    # kubectl apply -f mysql-dep.yaml
    
    3、检查
    # ls /data/tomcat/
    # df -h
    http:
    //192.168.4.12:30008/demo 插入一条数据
    进入数据库,查看插入的数据 删除pod,自动新建pod,再次查看数据 # kubectl delete pod mysql-1215028969-3d366 http://192.168.4.12:30008/demo 查看数据是否存在

    不创建pv和pvc,使用nfs实现持久化存储

    1、创建mysql的Deployment定义文件
    # vim  mysql-dep.yaml
    apiVersion: extensions/v1beta1                  #apiserver的版本
    kind: Deployment                                #副本控制器deployment,管理pod和RS
    metadata:
      name: mysql                                   #deployment的名称,全局唯一
    spec:
      replicas: 1                                   #Pod副本期待数量
      selector:
        matchLabels:                                #定义RS的标签
          app: mysql                                #符合目标的Pod拥有此标签
      strategy:                                     #定义升级的策略
        type: RollingUpdate                         #滚动升级,逐步替换的策略
      template:                                     #根据此模板创建Pod的副本(实例)
        metadata:
          labels:
            app: mysql                              #Pod副本的标签,对应RS的Selector
        spec:
          containers:                               #Pod里容器的定义部分
          - name: mysql                             #容器的名称
            image: mysql:5.7                        #容器对应的docker镜像
            volumeMounts:                           #容器内挂载点的定义部分       
    - name: mysql-data #容器内挂载点名称 mountPath: /var/lib/mysql #容器内挂载路径,mysql的数据目录 ports: - containerPort: 3306 #容器暴露的端口号 env: #写入到容器内的环境容量 - name: MYSQL_ROOT_PASSWORD #定义了一个mysql的root密码的变量 value: "123456" volumes: #本地需要挂载到容器里的数据卷定义部分
    - name: mysql-data #数据卷名称,需要与容器内挂载点名称一致 nfs:
    server: 192.168.4.11
    path: "/data/tomcat"
    2、创建deployment、RS、Pod和容器 # kubectl create -f mysql-dep.yaml 3、创建mysql的service定义文件 # vim mysql-svc.yaml apiVersion: v1 kind: Service #表示Kubernetes Service metadata: name: mysql #Service的名称 spec: ports: - port: 3306 #Service提供服务的端口号 selector: app: mysql #Service对应的Pod的标签 4、创建Service # kubectl create -f mysql-svc.yaml 5、测试
    http://192.168.4.12:30008/demo   插入一条数据
    进入数据库,查看插入的数据
    删除pod,自动新建pod,再次查看数据
    # kubectl  delete pod mysql-761066058-bgh3r
    http://192.168.4.12:30008/demo   查看数据是否存在

    emptyDir类型

    删除容器后数据会保存,但是删除pod后数据丢失
    # cat mysql-rc.yml 
    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: mysql
      namespace: tomcat
    spec:
      replicas: 1
      selector:
        app: mysql
      template:
        metadata:
          labels:
            app: mysql
        spec:
          volumes:        *
          - name: mysql   *
            emptyDir: {}  *
          containers:
            - name: mysql
              image: 192.168.4.11:5000/mysql:5.7
              volumeMounts:                  *
              - name: mysql                  *
                mountPath: /var/lib/mysql    *
              ports:
              - containerPort: 3306
              env:
              - name: MYSQL_ROOT_PASSWORD
                value: '123456'

    HostPath类型

    删除容器与删除pod,数据都会保存
    # cat mysql-rc.yml 
    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: mysql
      namespace: tomcat
    spec:
      replicas: 1
      selector:
        app: mysql
      template:
        metadata:
          labels:
            app: mysql
        spec:
          nodeName: 10.0.0.13  
          volumes:
          - name: mysql
            hostPath:            *
              path: /data/mysql  *
          containers:
            - name: mysql
              image: 10.0.0.11:5000/mysql:5.7
              volumeMounts:      *
              - name: mysql      *
                mountPath: /var/lib/mysql  *
              ports:
              - containerPort: 3306
              env:
              - name: MYSQL_ROOT_PASSWORD
                value: '123456'

    五、HPA水平自动伸缩

    HPA简介

    Horizontal Pod Autoscaling,简称HPA,是Kubernetes中实现POD水平自动伸缩的功能。
    自动扩展主要分为两种: 水平扩展(scale
    out),针对于实例数目的增减 垂直扩展(scal up),即单个实例可以使用的资源的增减, 比如增加cpu和增大内存

    自动伸缩

    1、创建测试yaml文件
    # vim k8s_deploy.yaml
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 3
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: 10.0.0.11:5000/nginx:1.13
            ports:
            - containerPort: 80
            resources:    # 资源限制
              limits:    # 最大资源是多少
                cpu: 100m
              requests:    # 最小需要多少资源
                cpu: 100m
    
    2、命令行创建一个svc资源
    # kubectl expose deployment nginx-deployment --port=80 --target-port=80 --type=NodePort
    
    3、命令行方式创建弹性伸缩规则
    # kubectl autoscale deployment nginx-deployment --max=10 --min=2 --cpu-percent=10
    # cpu生产建议设为60。能有一个40的缓冲
    
    4、查看dpa描述
    # kubectl describe hpa
    Name:                nginx-deployment
    Namespace:            default
    Labels:                <none>
    Annotations:            <none>
    CreationTimestamp:        Tue, 24 Dec 2019 05:06:45 +0800
    Reference:            Deployment/nginx-deployment
    Target CPU utilization:        10%
    Current CPU utilization:    0%
    Min replicas:            2
    Max replicas:            10
    
    5、修改副本数为1
    # kubectl edit deployment nginx-deployment
    # kubectl get all    查看pod数量
    
    6、开始压测
    # ab -n 400000 -c 50 http://192.168.4.11:30008

    调用原理

    1、创建pod和service
    # kubectl run php-apache --image=gcr.io/google_containers/hpa-example --requests=cpu=200m --expose --port=80
    
    2、创建autoscaler
    # kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
    
    3、增加负载
    # kubectl run -i --tty load-generator --image=busybox /bin/sh
    $ while true; do wget -q -O- http://php-apache.default.svc.cluster.local; done
    
    4、查看负载及pod
    # kubectl get hpa
    # kubectl get deployment
    pod增加到7个
    5、删除创建的负载
    pod数量自动降回1个 # kubectl
    get hpa # kubectl get deployment

    小结
    1、首先最底层的资源永远都是pod
    2、比pod高级一点的资源叫rc副本控制器
    3、在pod上面有一个高级的rs
    4、那谁来管理rs呢?是deployment
    5、HPA自动管理deployment,deployment设置为1,HPA最低设置为3,deployment这就会被自动设计为3个
    HPA-yaml文件
    # vim nginx-hpa.yaml apiVersion: autoscaling
    /v1 kind: HorizontalPodAutoscaler metadata: name: nginx # 名称 namespace: default #k8s命名空间 spec: maxReplicas: 10 # 最大副本数 minReplicas: 3 # 最小副本数 scaleTargetRef: apiVersion: apps/v1beta1 kind: Deployment name: nginx # 监控名为nginx的Deployment targetCPUUtilizationPercentage: 80 # cpu 阈值

    六、其他项目

    1、安装部署Dashboard

    1、 获取kubernetes-dashboard.yaml文件
    去官网,github上下载对应版本的源码包文件。
    https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.5.md#downloads-for-v152
    
    # wget https://dl.k8s.io/v1.5.2/kubernetes.tar.gz
    # cd kubernetes/cluster/addons/dashboard/
    # cp dashboard-controller.yaml  /root/dashboard-dep.yaml
    # cp dashboard-service.yaml     /root/dashboard-svc.yaml
    
    2、修改yaml文件 # vim dashboard-dep.yaml image: gcr.io/google_containers/kubernetes-dashboard-amd64:v1.5.0 arg: - --apiserver-host=http://192.168.4.11:8080 3、启动 # kubectl create -f dashboard-dep.yaml # kubectl create -f dashboard-svc.yaml 4、查看 # kubectl get -n kube-system all http://192.168.4.11:8080/ui

     dashboard-dep.yaml文件内容

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
    # Keep the name in sync with image version and
    # gce/coreos/kube-manifests/addons/dashboard counterparts
      name: kubernetes-dashboard-latest
      namespace: kube-system
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            k8s-app: kubernetes-dashboard
            version: latest
            kubernetes.io/cluster-service: "true"
        spec:
          nodeName: k8s-node2
          containers:
          - name: kubernetes-dashboard
            image: index.tenxcloud.com/google_containers/kubernetes-dashboard-amd64:v1.4.1
            imagePullPolicy: IfNotPresent
            resources:
              # keep request = limit to keep this container in guaranteed class
              limits:
                cpu: 100m
                memory: 50Mi
              requests:
                cpu: 100m
                memory: 50Mi
            ports:
            - containerPort: 9090
            args:
             -  --apiserver-host=http://192.168.4.11:8080
            livenessProbe:
              httpGet:
                path: /
                port: 9090
              initialDelaySeconds: 30
              timeoutSeconds: 30

    dashboard-svc.yaml文件内容

    apiVersion: v1
    kind: Service
    metadata:
      name: kubernetes-dashboard
      namespace: kube-system
      labels:
        k8s-app: kubernetes-dashboard
        kubernetes.io/cluster-service: "true"
    spec:
      selector:
        k8s-app: kubernetes-dashboard
      ports:
      - port: 80
        targetPort: 9090
    没用nodeport,不做端口映射

     Pod控制器

    Kubernetes中内建了很多controller(控制器),分为有状态应用和无状态应用
    Pod控制器有多种类型:
    Deployment:工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能,还提供声明式配置。
    DaemonSet:确保集群中的每一个节点只运行特定的pod副本,通常用于实现系统级后台任务。比如ELK,要求:服务是无状态的;服务必须是守护进程
    Job:只要完成就立即退出,不需要重启或重建。
    Cronjob:周期性任务控制,不需要持续后台运行,
    StatefulSet:管理有状态应用,如mysql,redis等。
    ReplicaSet: 代用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。

    DaemonSet:一个node节点只能启动一个,监控pod、日志收集pod
    pet sets: 有状态,适合数据库之类的

    namespace

    1、介绍
    Namespace(命名空间):在很多情况下用于实现多租户的资源隔离。
    同一个namespace下面不允许出现两个service叫mysql
    生产环境中把不同的应用放到不同的namespace中。
    
    2、namespace管理命令
    创建namespace
    # kubectl create namespace nginx
     
    查看namespace
    # kubectl get namespace 
     
    删除namespace
    # kubectl delete namespace qiangge
    注:特别危险!会删除namespace下所有的k8s资源
    
    3、yaml文件
    # vim nginx-rc.yaml 
    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: myweb
      namespace: nginx-nm
    spec:
      replicas: 2
      selector:
        app: myweb
      template:
        metadata:
          labels:
            app: myweb
        spec:
          containers:
          - name: myweb
            image: 10.0.0.11:5000/nginx:1.13
            ports:
            - containerPort: 80
    
    # vim nginx-svc.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: myweb
      namespace: nginx-nm
    spec:
      type: ClusterIP
      ports:
        - port: 80
          targetPort: 80
      selector:
        app: myweb

    通过apiservice反向代理访问service

    访问k8s中应用,在svc中配置
    第一种:NodePort类型 
      type: NodePort
      ports:
        - port: 80
          targetPort: 80
          nodePort: 30008
    
    第二种:ClusterIP类型
      type: ClusterIP
      ports:
        - port: 80
          targetPort: 80
          
    http://192.168.4.11:8080/api/v1/proxy/namespaces/命令空间/services/service的名字/

    2、部署dns组件

    dns服务的作用:将svc的名字解析成VIP地址
    1、获取yaml文件
    去官网,github上下载对应版本的源码包文件。
    https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.5.md#downloads-for-v152
    # wget https://dl.k8s.io/v1.5.2/kubernetes.tar.gz
    # cd kubernetes/cluster/gce/coreos/kube-manifests/addons/dns/
    # cp skydns-rc.yamll    /root/skydns-rc.yaml
    # cp skydns-svc.yaml    /root/skydns-svc.yaml
    
    2、修改yaml文件
         image: myhub.fdccloud.com/library/kubedns-amd64:1.9
         - --domain=cluster.local.
         - --kube-master-url=http://192.168.4.11:8080
         image: myhub.fdccloud.com/library/kube-dnsmasq-amd64:1.4
         image: myhub.fdccloud.com/library/dnsmasq-metrics-amd64:1.0
         image: myhub.fdccloud.com/library/exechealthz-amd64:1.2
         - --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null
         - --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1:10053 >/dev/null
    
    3、启动dns
    # kubectl create -f skydns-rc.yaml
    # kubectl create -f skydns-svc.yaml
    
    4、修改node节点kubelet配置文件并重启服务
    # cat /etc/kubernetes/kubelet
    KUBELET_ARGS="--cluster_dns=10.254.230.254 --cluster_domain=cluster.local"
    # systemctl restart kubelet
    
    5、测试
    # cat  test_dns_pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        name: busybox
        role: master
      name: busybox2
    spec:
      containers:
      - name: busybox
        image: docker.io/busybox:latest
        imagePullPolicy: IfNotPresent
        command:
        - sleep
        - "3600"
    
    # kubectl exec -it busybox sh
    # cat /etc/resolv.conf 
    测试
    # nslookup kubernetes
    # nslookup kubernetes.default.cluster.local
    # nslookup kubernetes.default.svc.cluster.local

    skydns-rc.yaml的内容

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: kube-dns
      namespace: kube-system
      labels:
        k8s-app: kube-dns
        kubernetes.io/cluster-service: "true"
    spec:
      # replicas: not specified here:
      # 1. In order to make Addon Manager do not reconcile this replicas parameter.
      # 2. Default is 1.
      # 3. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
      strategy:
        rollingUpdate:
          maxSurge: 10%
          maxUnavailable: 0
      selector:
        matchLabels:
          k8s-app: kube-dns
      template:
        metadata:
          labels:
            k8s-app: kube-dns
          annotations:
            scheduler.alpha.kubernetes.io/critical-pod: ''
            scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
        spec:
          containers:
          - name: kubedns
            image: myhub.fdccloud.com/library/kubedns-amd64:1.9
            resources:
              # TODO: Set memory limits when we've profiled the container for large
              # clusters, then set request = limit to keep this container in
              # guaranteed class. Currently, this container falls into the
              # "burstable" category so the kubelet doesn't backoff from restarting it.
              limits:
                memory: 200Mi
              requests:
                cpu: 100m
                memory: 100Mi
            livenessProbe:
              httpGet:
                path: /healthz-kubedns
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 60
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 5
            readinessProbe:
              httpGet:
                path: /readiness
                port: 8081
                scheme: HTTP
              # we poll on pod startup for the Kubernetes master service and
              # only setup the /readiness HTTP server once that's available.
              initialDelaySeconds: 3
              timeoutSeconds: 5
            args:
            # command = "/kube-dns"
            - --domain=cluster.local.
            - --dns-port=10053
            - --config-map=kube-dns
            - --kube-master-url=http://192.168.4.11:8080
            env:
              - name: PROMETHEUS_PORT
                value: "10055"
            ports:
            - containerPort: 10053
              name: dns-local
              protocol: UDP
            - containerPort: 10053
              name: dns-tcp-local
              protocol: TCP
            - containerPort: 10055
              name: metrics
              protocol: TCP
          - name: dnsmasq
            image: myhub.fdccloud.com/library/kube-dnsmasq-amd64:1.4
            livenessProbe:
              httpGet:
                path: /healthz-dnsmasq
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 60
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 5
            args:
            - --cache-size=1000
            - --no-resolv
            - --server=127.0.0.1#10053
            - --log-facility=-
            ports:
            - containerPort: 53
              name: dns
              protocol: UDP
            - containerPort: 53
              name: dns-tcp
              protocol: TCP
          - name: dnsmasq-metrics
            image: myhub.fdccloud.com/library/dnsmasq-metrics-amd64:1.0
            livenessProbe:
              httpGet:
                path: /metrics
                port: 10054
                scheme: HTTP
              initialDelaySeconds: 60
              timeoutSeconds: 5
              successThreshold: 1
              failureThreshold: 5
            args:
            - --v=2
            - --logtostderr
            ports:
            - containerPort: 10054
              name: metrics
              protocol: TCP
            resources:
              requests:
                memory: 10Mi
          - name: healthz
            image: myhub.fdccloud.com/library/exechealthz-amd64:1.2
            resources:
              limits:
                memory: 50Mi
              requests:
                cpu: 10m
                # Note that this container shouldn't really need 50Mi of memory. The
                # limits are set higher than expected pending investigation on #29688.
                # The extra memory was stolen from the kubedns container to keep the
                # net memory requested by the pod constant.
                memory: 50Mi
            args:
            - --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1 >/dev/null
            - --url=/healthz-dnsmasq
            - --cmd=nslookup kubernetes.default.svc.cluster.local 127.0.0.1:10053 >/dev/null
            - --url=/healthz-kubedns
            - --port=8080
            - --quiet
            ports:
            - containerPort: 8080
              protocol: TCP
          dnsPolicy: Default  # Don't use cluster DNS.

    skydns-svc.yaml 的内容

    apiVersion: v1
    kind: Service
    metadata:
      name: kube-dns
      namespace: kube-system
      labels:
        k8s-app: kube-dns
        kubernetes.io/cluster-service: "true"
        kubernetes.io/name: "KubeDNS"
    spec:
      selector:
        k8s-app: kube-dns
      clusterIP: 10.254.230.254 
      ports:
      - name: dns
        port: 53
        protocol: UDP
      - name: dns-tcp
        port: 53
        protocol: TCP

     3、部署heapster监控

     介绍

    Heapster是kubernetes集群监控工具。在kubernetes中,cAdvisor被集成到kubelet中。通过netstat可以查看到kubelet新开了一个4194的端口,这就是cAdvisor监听的端口,现在我们然后可以通过http://<node-ip>:4194的方式访问到cAdvisor。Heapster就是通过每个node上的kubelet,也就是实际的cAdvisor上收集数据并汇总,保存到后端存储中。
    Heapster支持多种后端存储,包括influxDB,Elasticsearch,Kafka等,我们使用influxDB作为后端存储来展示heapster的相关配置。需要说明的是,heapster依赖kubernetes dns配置

    部署

    1、 获取yaml文件
    去官网,github上下载对应版本的源码包文件。
    https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.5.md#downloads-for-v152
    # wget https://dl.k8s.io/v1.5.2/kubernetes.tar.gz
    # cd kubernetes/cluster/addons/cluster-monitoring/influxdb/
    # mkdir  -p  /data/yaml
    # cp *.yaml  /data/yaml
    
    2、修改yaml文件
    查看image地址,添加本地查找
    # grep 'image' heapster-controller.yaml 
            - image: gcr.io/google_containers/heapster:v1.2.0
              imagePullPolicy: IfNotPresent    #本地找镜像
            - image: gcr.io/google_containers/heapster:v1.2.0
              imagePullPolicy: IfNotPresent
            - image: gcr.io/google_containers/addon-resizer:1.6
               imagePullPolicy: IfNotPresent
            - image: gcr.io/google_containers/addon-resizer:1.6
               imagePullPolicy: IfNotPresent
    # grep 'image' influxdb-grafana-controller.yaml 
            - image: gcr.io/google_containers/heapster_influxdb:v0.7
              imagePullPolicy: IfNotPresent
            - image: gcr.io/google_containers/heapster_grafana:v3.1.1
              imagePullPolicy: IfNotPresent
    3、下载镜像文件并修改
    # docker search heapster:v1.2.0
    # docker pull   heapster:v1.2.0
    # docker tag  heapster:v1.2.0   gcr.io/google_containers/heapster:v1.2.0
    
    4、启动
    # kubectl create -f /data/yaml  批量创建
    
    5、报错处理
    修改heapster-controller.yaml
    command:
            - /heapster
            - --source=kubernetes:http://192.168.4.11:8080?inClusterConfig=false   数据源在从哪里,apiserver拿数据
            - --sink=influxdb:http://monitoring-influxdb:8086                      数据存储到哪里,influxdb存数据
    heapster依赖kubernetes dns

    heapster-controller.yaml 文件内容

    apiVersion: v1
    kind: ReplicationController
    metadata:
      labels:
        k8s-app: heapster
        name: heapster
        version: v6
      name: heapster
      namespace: kube-system
    spec:
      replicas: 1
      selector:
        k8s-app: heapster
        version: v6
      template:
        metadata:
          labels:
            k8s-app: heapster
            version: v6
        spec:
          nodeSelector:
             kubernetes.io/hostname: k8s-master
          containers:
          - name: heapster
            image: kubernetes/heapster:canary
            imagePullPolicy: IfNotPresent
            command:
            - /heapster
            - --source=kubernetes:http://192.168.4.11:8080?inClusterConfig=false
            - --sink=influxdb:http://monitoring-influxdb:8086

    influxdb-grafana-controller.yaml 文件内容

    apiVersion: v1
    kind: ReplicationController
    metadata:
      labels:
        name: influxGrafana
      name: influxdb-grafana
      namespace: kube-system
    spec:
      replicas: 1
      selector:
        name: influxGrafana
      template:
        metadata:
          labels:
            name: influxGrafana
        spec:
          containers:
          - name: influxdb
            image: kubernetes/heapster_influxdb:v0.5
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /data
              name: influxdb-storage
          - name: grafana
            imagePullPolicy: IfNotPresent
            image: kubernetes/heapster_grafana:v2.6.0
            env:
              - name: INFLUXDB_SERVICE_URL
                value: http://monitoring-influxdb:8086- name: GF_AUTH_BASIC_ENABLED
                value: "false"
              - name: GF_AUTH_ANONYMOUS_ENABLED
                value: "true"
              - name: GF_AUTH_ANONYMOUS_ORG_ROLE
                value: Admin
              - name: GF_SERVER_ROOT_URL
                value: /api/v1/proxy/namespaces/kube-system/services/monitoring-grafana/
            volumeMounts:
            - mountPath: /var
              name: grafana-storage
          nodeSelector:
             kubernetes.io/hostname: k8s-master
          volumes:
          - name: influxdb-storage
            emptyDir: {}
          - name: grafana-storage
            emptyDir: {}

     原理

    heapster读取kubelet中cadvisor(http://192.168.4.12:4194/containers/)的数据,存到influxdb中,再由grafana读取出图,最后由dashboard呈现
    监控数据获得,是从cadvisor获得的,现在cadvisor集成到了kubelete中,访问cadvisor,可以修改kubelet配置文件,添加--cadvisor参数
    
    # cat /etc/kubernetes/kubelet 
    KUBELET_ARGS="--cluster_dns=10.254.230.254 --cluster_domain=cluster.local --cadvisor-port=8080"
    重启
    systemctl restart kubelet.service 
  • 相关阅读:
    linux运维、架构之路-Kubernetes离线、二进制部署集群
    linux运维、架构之路-Kubernetes集群部署
    创建SpringMVC项目过程
    Spring AOP使用方式
    Java动态代理
    Java工厂模式解耦 —— 理解Spring IOC
    Neural Turing Machine
    小米路由器mini刷锐捷
    目前深度学习开源数据集整理
    Spring编译后没有xml配置文件解决方法
  • 原文地址:https://www.cnblogs.com/wuhg/p/12162583.html
Copyright © 2020-2023  润新知