Kubernetes 的用法和解析 -- 4

一.Deployment 资源详解
如果Pod出现故障,对应的服务也会挂掉,所以Kubernetes提供了一个Deployment的概念 ,目的是让Kubernetes去管理一组Pod的副本,也就是副本集 ,这样就能够保证一定数量的副本一直可用,不会因为某一个Pod挂掉导致整个服务挂掉。

Deployment 还负责在 Pod 定义发生变化时,对每个副本进行滚动更新(Rolling Update)。

x 使用yaml创建Deployment

k8s deployment资源创建流程:

1. 用户通过 kubectl 创建 Deployment。

2. Deployment 创建 ReplicaSet。

3. ReplicaSet 创建 Pod。

对象的命名方式是:子对象的名字 = 父对象名字 + 随机字符串或数字  

 

Deployment是一个定义及管理多副本应用(即多个副本 Pod)的新一代对象,与Replication Controller相比,它提供了更加完善的功能,使用起来更加简单方便。

1.1 deployment 实例
例1:
apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
spec:
 selector:
   matchLabels:
     app: nginx
 replicas: 2
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: nginx:1.7.9
       ports:
       - containerPort: 80

 例2:在上面yaml的基础上添加了volume

[root@kube-master sa]# cat deployment.yaml 
apiVersion: apps/v1  #注意版本号
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:  #属性,选择器
    matchLabels:
      app: nginx
  replicas: 2  #管理的副本个数
  template:  #模板属性
    metadata: #对pod的描述
      labels:
        app: nginx
    spec:
      volumes:   #定义共享卷
      - name: nginx-vol
        emptyDir: {}
      containers:
      - name: nginx
        image: daocloud.io/library/nginx
        ports:
        - containerPort: 80
        volumeMounts:  #定义挂载卷
        - mountPath: "/usr/share/nginx/html"
          name: nginx-vol

1.2 文件说明 

#创建Deployment:
#将上述的YAML文件保存为deployment.yaml,然后创建Deployment:
[root@kube-master prome]# kubectl apply -f deployment.yaml
deployment.apps/nginx-deployment created
 
# 检查Deployment的列表:启动之后需要创建时间比较长
# 通过 kubectl get 命令检查这个 YAML 运行起来的状态:
[root@kube-master prome]# kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   2/2     2            2           2m22s
 
[root@kube-master prome]# kubectl get pods -l app=nginx
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-59c4b86474-2llrt   1/1     Running   0          2m51s
nginx-deployment-59c4b86474-n2r2m   1/1     Running   0          2m51s
 
# 在这里加上了一个 -l 参数,即获取所有匹配 app: nginx 标签的 Pod。需要注意的是,在命令行中,所有 key-value 格式的参数,都使用"="而非":"表示。
 
# 删除Deployment:
[root@kube-master ~]# kubectl delete deployments nginx-deployment
deployment "nginx-deployment" deleted
 
#或者
[root@kube-master ~]# kubectl delete -f deployment.yaml

 1.3 deployment可用字段

replicas: 1 # 声明副本数目
revisionHistoryLimit: 3 # 保留历史版本
selector: # 选择器

二.Service 服务 

k8s 内部域名访问方式 ..svc.cluster.local

2.1 创建service 

# 1.创建一个depl
[root@kub-k8s-master prome]# vim nginx-depl.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dep01
spec:
  selector:
    matchLabels:
      app: web
  replicas: 2
  template:
      metadata:
        labels:
          app: web
      spec:
        containers:
          - name: testnginx9
            image: daocloud.io/library/nginx
            ports:
              - containerPort: 80
[root@kub-k8s-master prome]# kubectl apply -f nginx-depl.yml 
deployment.apps/nginx-deployment created
 
#2. 创建service并且以nodePort的方式暴露端口给外网:
[root@kub-k8s-master prome]# vim nginx_svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysvc
spec:
  type: NodePort  #类型
  ports:
    - port: 8080
      nodePort: 30001
      targetPort: 80
  selector:   #选择器
    app: web
    
    
[root@kub-k8s-master prome]# kubectl apply -f nginx_svc.yaml 
service/mysvc created
 
# 3.测试
[root@kub-k8s-master prome]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          5d18h
mysvc        NodePort    10.100.166.208   <none>        8080:30001/TCP   21s

 2.2 页面请求测试

2.3 pod内部请求测试 

# 进入docker容器
[root@kube-master sa]# kubectl exec -it dep01-694c5dbcd-ccdsv /bin/bash
# 请求
 
root@dep01-694c5dbcd-ccdsv:/# curl mysvc.default.svc.cluster.local:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
 
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
 
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 2.4 端口解析

# 解析
port
port是暴露在cluster ip上的端口,port提供了集群内部客户端访问service的入口,即clusterIP:port。

nodeport
nodePort 提供了集群外部客户端访问 Service 的一种方式,nodePort 提供了集群外部客户端访问 Service 的端口,通过 nodeIP:nodePort 提供了外部流量访问k8s集群中service的入口。

targetPort
targetPort是pod的端口,从port和nodePort来的流量经过kube-proxy流入到后端pod的targetPort上,最后进入容器。

containerPort
containerPort是pod内部容器的端口,targetPort映射到containerPort。

2.5 kube-proxy 使用ipvs 

[root@kube-master ~]# kubectl get configmap kube-proxy -n kube-system -o yaml > kube-proxy-configmap.yaml
[root@kube-master ~]# sed -i 's/mode: ""/mode: "ipvs"/' kube-proxy-configmap.yaml
[root@kube-master ~]# kubectl apply -f kube-proxy-configmap.yaml
[root@kube-master ~]# rm -f kube-proxy-configmap.yaml
[root@kube-master ~]# kubectl get pod -n kube-system | grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}' 
 
后续请求时,可以发现已经通过了算法进行调度
[root@kube-master ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.17.0.1:30001 rr
  -> 10.244.1.34:80               Masq    1      0          0         
  -> 10.244.2.31:80               Masq    1      0          0         
TCP  192.168.96.143:30001 rr
  -> 10.244.1.34:80               Masq    1      0          12        
  -> 10.244.2.31:80               Masq    1      0          12

三.k8s服务暴露 

3.1 ClusterIP

此类型会提供一个集群内部的虚拟IP(与Pod不在同一网段),以供集群内部的pod之间通信使用。ClusterIP也是Kubernetes service的默认类型。

3.2 NodePort 

外网client--->nodeIP+nodePort--->podIP+PodPort

为每个节点暴露一个端口,通过nodeip + nodeport可以访问这个服务,同时服务依然会有cluster类型的ip+port。内部通过clusterip方式访问,外部通过nodeport方式访问。

3.3 loadbalance

LoadBalancer在NodePort基础上,K8S可以请求底层云平台创建一个负载均衡器,将每个Node作为后端,进行服务分发。

3.4 Ingress 

Ingress是一种HTTP方式的路由转发机制,为K8S服务配置HTTP负载均衡器,通常会将服务暴露给K8S群集外的客户端。

四.Ingress 暴露服务 

> 要理解ingress,需要区分两个概念,ingress和ingress-controller:

> ingress对象:
> 指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发到service的规则,可以理解为配置模板。

> ingress-controller:
> 具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。

> 简单来说,ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到ingress-controller,而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名哪些path要转发到哪些服务等等。


> service 的表现形式为IP:PORT,即工作在第四层传输层(TCP/IP层),对于不同的URL地址经常对应用不同的后端服务或者虚拟服务器,这些应用层的转发机制仅通过kubernetes的service机制是无法实现的,这种情况我么可以使用ingress策略定义和一个具体的ingress Controller.

> Ingress提供七层负载均衡能力,可以通过 Ingress 配置提供外部可访问的 URL、负载均衡、SSL、基于名称的虚拟主机等。作为集群流量接入层,Ingress 的高可靠性显得尤为重要。

 4.1 ingress详解

这个负载均衡是基于nginx七层反向代理来实现的,ingress工作原理如下图:

外部客户端通过访问负载均衡器,然后调度到service上,然后在调度到IngressController,IngressController通过Ingress规则(域名或虚拟主机)访问到后端pod,而在Ingress规则当中对应的主机是由service分组来设定的,可以看到,这幅图有2种service,最上面的service是用来对外提供服务的,而下面2个service仅仅是用来分pod组的

Kubernetes 并没有自带 Ingress Controller,实际上ingress-controller只是一个统称,具体实现有多种,需要自己单独安装,目前,由k8s维护的ingress-controller只有google云的GCE与ingress-nginx两个,常用的是 Ingress-nginx Controller.

Ingress 一般由三个组件组成:

1. Nginx 反向代理负载均衡器
2. Ingress Controller 可以理解为控制器,它通过不断的跟 Kubernetes API 交互,实时获取后端 Service、Pod 等的变化,比如新增、删除等,然后结合 Ingress 定义的规则生成配置,然后动态更新上边的 Nginx 负载均衡器,并刷新使配置生效,来达到服务自动发现的作用。
3. Ingress 则是定义规则,通过它定义某个域名的请求过来之后转发到集群中指定的 Service。它可以通过 Yaml 文件定义,可以给一个或多个 Service 定义一个或多个 Ingress 规则。

4.2 如何创建 Ingress 资源 

Ingress 中的spec字段是Ingress资源的核心组成部分,主要包含以下3个字段:

rules:用于定义当前Ingress资源的转发规则列表;由rules定义规则,或没有匹配到规则时,所有的流量会转发到由backend定义的默认后端。

backend:默认的后端,用于服务那些没有匹配到任何规则的请求;定义Ingress资源时,必须要定义backend或rules两者之一,该字段用于让负载均衡器指定一个全局默认的后端。

tls:TLS配置,目前仅支持通过默认端口443提供服务,如果要配置指定的列表成员指向不同的主机,则需要通过SNI TLS扩展机制来支持该功能。

4.3 部署 Ingress 控制器(Nginx)


4.3.1 下载ingress controller

[root@k8s-master ~]# cd /mnt/
[root@k8s-master mnt]# wget https://codeload.github.com/kubernetes/ingress-nginx/tar.gz/refs/tags/controller-v1.3.1
[root@k8s-master mnt]# tar xf ingress-nginx-controller-v1.3.1.tar.gz
[root@k8s-master mnt]# cd ingress-nginx-controller-v1.3.1/deploy/static/provider/cloud
[root@k8s-master cloud]# ls
deploy.yaml  kustomization.yaml
[root@k8s-master cloud]# cd
[root@k8s-master ~]# vim deploy.yaml #修改配置文件
找到已下apiserver的版本:
# 390行修改
kind: DaemonSet  #将原来的Deployment修改为DaemonSet
 
# 415行下边添加
hostNetwork: true  #添加此配置

需要修改的地方:

kind: DaemonSet:

官方原始文件使用的是deployment,replicate 为 1,这样将会在某一台节点上启动对应的nginx-ingress-controller pod。外部流量访问至该节点,由该节点负载分担至内部的service。测试环境考虑防止单点故障,改为DaemonSet然后删掉replicate ,配合亲和性部署在制定节点上启动nginx-ingress-controller pod,确保有多个节点启动nginx-ingress-controller pod,后续将这些节点加入到外部硬件负载均衡组实现高可用性。

hostNetwork: true:

添加该字段,暴露nginx-ingress-controller pod的服务端口(80) 

4.3.2 创建ingress-controller 

[root@k8s-master ~]# kubectl apply -f deploy.yaml
 
查看ingress-controller资源
[root@k8s-master ~]# kubectl get pods -n ingress-nginx
NAME                             READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-s8vnl   1/1     Running   0          98m
nginx-ingress-controller-ztxz4   1/1     Running   0          97m
 
[root@k8s-master cloud]# kubectl get ingressclass
NAME    CONTROLLER             PARAMETERS   AGE
nginx   k8s.io/ingress-nginx   <none>       38m

测试ingress

创建两个应用和service

[root@k8s-master ~]# vim my-apache.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: my-apache
spec:
 selector:
   matchLabels:
     run: my-apache
 replicas: 2
 template:
  metadata:
   labels:
    run: my-apache
  spec:
   containers:
   - name: my-apache
     image: daocloud.io/library/httpd:2.4
     ports:
     - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
 name: my-apache
 labels:
  run: my-apache
spec:
 #type: NodePort
 ports:
 - port: 80
   targetPort: 80
   #nodePort: 30002
 selector:
  run: my-apache
  
  
[root@k8s-master ~]# cat my-nginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
 name: my-nginx
spec:
 selector:
   matchLabels:
     run: my-nginx
 replicas: 2
 template:
  metadata:
   labels:
    run: my-nginx
  spec:
   containers:
   - name: my-nginx
     image: daocloud.io/library/nginx:1.7.9
     ports:
     - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
 name: my-nginx
 labels:
  run: my-nginx
spec:
 #type: NodePort
 ports:
 - port: 80
   targetPort: 80
   #nodePort: 30001
 selector:
  run: my-nginx
  
  
创建pod和service
[root@k8s-master ~]# kubectl apply -f my-apache.yaml
[root@k8s-master ~]# kubectl apply -f my-nginx.yaml
 
查看资源
[root@k8s-master ~]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
my-apache-d49c8b95c-8z8l9   1/1     Running   0          125m
my-apache-d49c8b95c-d9q5s   1/1     Running   0          125m
my-nginx-5fdc96f9b4-bmf6s   1/1     Running   0          124m
my-nginx-5fdc96f9b4-qfw8c   1/1     Running   0          124m
[root@k8s-master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        20d
my-apache    NodePort    10.99.178.186   <none>        80/TCP   125m
my-nginx     NodePort    10.97.171.188   <none>        80/TCP   124m

配置ingress转发文件

[root@k8s-master ~]# cat ingress-test.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: test-ingress
 namespace: default
 annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
 ingressClassName: nginx
 rules:  #定义转发规则
 - host: test.apache.ingress  #指定域名方式
   http:
    paths:
    - path: /  #指定访问的路径
      pathType: Prefix  #定义路径的类型
      backend:   #定义转发后端的服务
       service:  #定义转发的service
         name: my-apache
         port:
          number: 80
 - host: test.nginx.ingress
   http:
    paths:
    - path: /
      pathType: Prefix
      backend:
       service:
         name: my-nginx
         port:
          number: 80
          
[root@k8s-master ~]# kubectl apply -f ingress-test.yaml
[root@k8s-master ~]# kubectl get ingress
NAME           CLASS    HOSTS                                    ADDRESS   PORTS   AGE
test-ingress   <none>   test.apache.ingress,test.nginx.ingress             80      119m

 

 4.3.3 修改ingress转发类型

[root@k8s-master ~]# kubectl edit svc ingress-nginx-controller -n ingress-nginx
# 将type修改为NodePort

nginx-ingress-controller运行在node1,node2两个节点上。

如果网络中有dns服务器,在dns中把这两个域名映射到nginx-ingress-controller运行的任意一个节点上,如果没有dns服务器只能修改host文件了。

任意一个节点上操作:(客户端解析)

我这里有两个节点部署了控制器,ip分别为172.16.229.5,172.16.229.6 ,如果有多个,可以随便选。

在wind电脑设置本地解析

172.16.229.5 test.nginx.ingress
172.16.229.6 test.apache.ingress

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值