Kubernetes组件详解

在前面,我们大概讲解了Kubernetes包含的组件,今天,我们就来详细讲解一下这些组件的作用与使用

Pod

在Kubernetes中,最小的管理元素不是一个个独立的容器,而是Pod,Pod是最小的,管理,创建,计划的最小单元.

使用方法

1.创建一个pod的yaml文件,名称为nginx_pod.yaml
apiVersion: v1                 // 版本号
kind: Pod                      //类别
metadata:
  name: nginx-pod              //Pod名称
  labels:
    app: nginx                 //Pod label
spec:
  containers:                  //容器
  - name: nginx-container      //容器名称
    image: nginx                //镜像
    ports:
    - containerPort: 80          //端口号
2.根据该nginx_pod.yaml文件创建pod
kubectl apply -f nginx_pod.yaml
3.查看
kubectl get pods
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          29s
kubectl get pods -o wide
NAME       READY     STATUS   RESTARTS   AGE             IP             NODE   
nginx-pod   1/1     Running      0       40m       192.168.80.194        w2 
kubectl describe pod nginx-pod
Name:               nginx-pod
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               w2/192.168.0.62
Start Time:         Sun, 06 Oct 2019 20:45:35 +0000
Labels:             app=nginx
Annotations:        cni.projectcalico.org/podIP: 192.168.80.194/32
                    kubectl.kubernetes.io/last-applied-configuration:
                      {
    
    "apiVersion":"v1","kind":"Pod","metadata":{
    
    "annotations":{
    
    },"labels":{
    
    "app":"nginx"},"name":"nginx-pod","namespace":"default"},"spec":{
    
    "c...
Status:             Running
IP:                 192.168.80.194
Containers:
  nginx-container:
    Container ID:   docker://eb2fd0b2906f53e9892e22a6fd791c9ac68fb8e5efce3bbf94ec12bae96e1984
    Image:          nginx
    Image ID:       docker-pullable:/
4.删除
kubectl delete -f nginx_pod.yaml

ReplicationController(RC)

Replication Controller 就像一个进程管理器,监管着不同node上的多个pod,而不是单单监控一个node上的pod,Replication Controller 会委派本地容器来启动一些节点上服务(Kubelet ,Docker)
ReplicationController定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值,所以RC的定义包含以下几个部分:

  • Pod期待的副本数(replicas)
  • 用于筛选目标Pod的Label Selector
  • 当Pod的副本数量小于预期数量时,用于创建新Pod的Pod模板(template)

也就是说通过RC实现了集群中Pod的高可用,减少了传统IT环境中手工运维的工作

使用方法

1.创建名为nginx_replication.yaml
apiVersion: v1
kind: ReplicationController       //表示要新建对象的类型
metadata:
  name: nginx
spec:
  replicas: 3                       //Pod期待的副本数
  selector:
    app: nginx                     //表示需要管理的Pod的label,这里表示包含app: nginx的label的Pod都会被该RC管理
  template:                        //表示用于定义Pod的模板,比如Pod名称、拥有的label以及Pod中运行的应用等
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
2.根据nginx_replication.yaml创建pod
kubectl apply -f nginx_replication.yaml
3.查看
kubectl get pods -o wide
   NAME      READY     STATUS
nginx-hksg8   1/1     Running   0          44s   192.168.80.195   w2   
nginx-q7bw5   1/1     Running   0          44s   192.168.190.67   w1  
nginx-zzwzl   1/1     Running   0          44s   192.168.190.68   w1    
kubectl get rc
NAME    DESIRED   CURRENT   READY   AGE
nginx   3         3         3       2m54s
4.扩容
kubectl scale rc nginx --replicas=5

kubectl get pods
nginx-8fctt   0/1     ContainerCreating   0          2s
nginx-9pgwk   0/1     ContainerCreating   0          2s
nginx-hksg8   1/1     Running             0          6m50s
nginx-q7bw5   1/1     Running             0          6m50s
nginx-wzqkf   1/1     Running             0          99s
5.删除
kubectl delete -f nginx_replication.yaml

ReplicaSet(RS)

在Kubernetes v1.2时,RC就升级成了另外一个概念:Replica Set,官方解释为“下一代RC”
ReplicaSet和 Replication Controller之间的唯一区别是现在的选择器支持。Replication Controller只支持基于等式的selector(env=dev或environment!=qa),但ReplicaSet还支持新的,基于集合的selector(version in (v1.0, v2.0)或env notin (dev, qa))
在试用时官方推荐ReplicaSet

注意:一般情况下,我们很少单独使用Replica Set,它主要是被Deployment这个更高的资源对象所使用,从而形成一整套Pod创建、删除、更新的编排机制。当我们使用Deployment时,无须关心它是如何创建和维护Replica Set的,这一切都是自动发生的。同时,无需担心跟其他机制的不兼容问题(比如ReplicaSet不支持rolling-update但Deployment支持)。

使用方法

1.创建frontend.yaml
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
  name: frontend
spec:
  replicas: 3
  selector:                               //选择器,可以使用IN
    matchLabels:
      tier: frontend
    matchExpressions:
      - {
    
    key: tier, operator: In, values: [frontend]}
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v3
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:                             //环境设置
        - name: GET_HOSTS_FROM
          value: dns
        ports:
        - containerPort: 80
2.根据frontend.yaml创建pod
kubectl create -f frontend.yaml
3.查看
kubectl get pods
NAME             READY     STATUS    RESTARTS   AGE
frontend-9si5l   1/1       Running   0          1m
frontend-dnjpy   1/1       Running   0          1m
frontend-qhloh   1/1       Running   0          1m
kubectl describe rs/frontend
Name:          frontend
Namespace:     default
Image(s):      gcr.io/google_samples/gb-frontend:v3
Selector:      tier=frontend,tier in (frontend)
Labels:        app=guestbook,tier=frontend
Replicas:      3 current / 3 desired
Pods Status:   3 Running / 0 Waiting / 0 Succeeded / 0 Failed
No volumes.
Events:
  FirstSeen    LastSeen    Count    From                SubobjectPath    Type        Reason            Message
  ---------    --------    -----    ----                -------------    --------    ------            -------
  1m           1m          1        {
    
    replicaset-controller }             Normal      SuccessfulCreate  Created pod: frontend-qhloh
  1m           1m          1        {
    
    replicaset-controller }             Normal      SuccessfulCreate  Created pod: frontend-dnjpy
  1m           1m          1        {
    
    replicaset-controller }             Normal      SuccessfulCreate  Created pod: frontend-9si5l
4.删除
kubectl delete -f frontend.yaml

Deployment

Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新。
Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。典型的应用场景包括:

  • 定义Deployment来创建Pod和ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续Deployment

使用方法

1.创建nginx_deployment.yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:                    //匹配的模板
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
2.根据nginx_deployment.yaml文件创建pod
kubectl apply -f nginx_deployment.yaml
3.扩容
kubectl scale deployment nginx-deployment --replicas 10
4.更新
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
5.回滚
kubectl rollout undo deployment/nginx-deployment

Namespace

Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的pods, services, replication controllers和deployments等都是属于某一个namespace的(默认是default),而node, persistentVolumes等则不属于任何namespace。

Namespace常用来隔离不同的用户,比如Kubernetes自带的服务一般运行在kube-system namespace中

使用方法

1.创建myns-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: myns
2.根据myns-namespace.yaml创建namespace
kubectl apply -f myns-namespace.yaml
3.查询
kubectl get namespaces
NAME              STATUS   AGE
default           Active   38m
kube-system       Active   38m
myns              Active   6s
4.指定空间
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  namespace: myns
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 80
5.删除
kubectl delete namespaces myns-namespace

Network

Network 提供了基于策略的网络控制,用于隔离应用并减少攻击面

1.同一个Pod中container之间的通信

每个pod中都会有一个pause container,所有创建的container都会链接到它上面,从而实现网络互通

2.同一个集群Pod之间

我们先来看一个例子:
准备两个Pod,一个nginx,一个busybox

nginx_pod.yaml

apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
 app: nginx
spec:
containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 80

busybox_pod.yaml

apiVersion: v1
kind: Pod
metadata:
name: busybox
labels:
 app: busybox
spec:
containers:
  - name: busybox
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']

运行并查看情况

kubectl apply -f nginx_pod.yaml

kubectl apply -f busybox_pod.yaml

kubectl get pods -o wide
NAME      READY  STATUS    RESTARTS   AGE         IP                NODE  
busybox    1/1   Running      0       49s    192.168.221.70   worker02-kubeadm-k8s   
nginx-pod  1/1   Running      0      7m46s   192.168.14.1     worker01-kubeadm-k8s 

接下来,我们分别测试两种不同场景下它们之间能否通信

1.同一台Node

来到worker01:ping 192.168.14.1

PING 192.168.14.1 (192.168.14.1) 56(84) bytes of data.
64 bytes from 192.168.14.1: icmp_seq=1 ttl=64 time=0.063 ms
64 bytes from 192.168.14.1: icmp_seq=2 ttl=64 time=0.048 ms
2.不同的Node

来到worker02:ping 192.168.14.1

PING 192.168.14.1 (192.168.14.1) 56(84) bytes of data.
64 bytes from 192.168.14.1: icmp_seq=1 ttl=63 time=0.680 ms
64 bytes from 192.168.14.1: icmp_seq=2 ttl=63 time=0.306 ms
64 bytes from 192.168.14.1: icmp_seq=3 ttl=63 time=0.688 ms

我们发现,无论是同一台Node还是不同的Node之间都是可以相互通信的,这得益于网络插件calico,为每个Pod都生成了一个Ip,且只限于集群内使用
但有一个坏处就是:每个Pod是不稳定的,比如通过Deployment管理的Pod,随时可能对Pod进行扩容或删减,从而导致Pod的Ip不断变化
这时,就需要一个固定的Ip,使得集群内方便使用

Service

Kubernete Service 是一个定义了一组Pod的策略的抽象,我们也有时候叫做宏观服务。这些被服务标记的Pod都是(一般)通过label Selector决定的
使用Kubernetes,您无需修改应用程序即可使用不熟悉的服务发现机制。 Kubernetes为Pods提供自己的IP地址和一组Pod的单个DNS名称,并且可以在它们之间进行负载平衡
我们先来看下Service的几种类型:

Cluster IP

顾名思义。就是集群内部使用的IP

1.创建whoami-deployment.yaml文件,并且apply
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami-deployment
  labels:
    app: whoami
spec:
  replicas: 3
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
      - name: whoami
        image: jwilder/whoami
        ports:
        - containerPort: 8000
2.创建whoami的service
kubectl expose deployment whoami-deployment
3.查看
 kubectl get svc
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP    19h
whoami-deployment   ClusterIP   10.105.147.59   <none>        8000/TCP   23s
4.访问
[root@master-kubeadm-k8s ~]# curl 10.105.147.59:8000
I'm whoami-deployment-678b64444d-b2695
5.查看service的详情
kubectl describe svc whoami-deployment
Name:              whoami-deployment
Namespace:         default
Labels:            app=whoami
Annotations:       <none>
Selector:          app=whoami
Type:              ClusterIP
IP:                10.105.147.59
Port:              <unset>  8000/TCP
TargetPort:        8000/TCP
Endpoints:         192.168.14.8:8000,192.168.221.81:8000,192.168.221.82:8000
Session Affinity:  None
Events:            <none>

发现有一个Endpoints连接了具体3个Pod,从而实现集群内的通信

NodePort

顾名思义,就是给每个Node暴露出一个端口,让集群外的服务可以访问集群内的Pod

1.创建Pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami-deployment
  labels:
    app: whoami
spec:
  replicas: 3
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
      - name: whoami
        image: jwilder/whoami
        ports:
        - containerPort: 8000
2.创建NodePort类型的service
kubectl expose deployment whoami-deployment --type=NodePort
3.查看
[root@master-kubeadm-k8s ~]# kubectl get svc
NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes          ClusterIP   10.96.0.1      <none>        443/TCP          21h
whoami-deployment   NodePort    10.99.108.82   <none>        8000:32041/TCP   7s

注意上述的端口32041,实际上就是暴露在集群中物理机器上的端口

4.访问

浏览器通过物理机器的IP访问http://192.168.0.51:32041

NodePort虽然能够实现外部访问Pod的需求,但是真的好吗?其实不好,占用了各个物理主机上的端口,所以,一般生产环境上不建议使用

HostPort

与NodePort作用类似,都是暴露主机上的任何可用端口,方便外部访问,与NodePort不同的是:HostPort只会为当前机器生成一个端口

Ingress

通常情况下,service和pod的IP仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到service在Node上暴露的NodePort上,然后再由kube-proxy将其转发给相关的Pod。
而Ingress就是为进入集群的请求提供路由规则的集合
Ingress可以给service提供集群外部访问的URL、负载均衡、SSL终止、HTTP路由等。为了配置这些Ingress规则,集群管理员需要部署一个Ingress controller,它监听Ingress和service的变化,并根据规则配置负载均衡并提供访问入口
Ingress提供了很多的解决方案,今天,我们以Nginx Ingress Controller为例,来讲讲Ingress的使用

使用方法

1.创建tomcat-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat-deployment
  labels:
    app: tomcat
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: tomcat
        image: tomcat
        ports:
        - containerPort: 8080
2.创建tomcat-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: tomcat-service
spec:
  ports:
  - port: 80   
    protocol: TCP
    targetPort: 8080
  selector:
    app: tomcat
  type: NodePort  
3.安装Nginx Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.34.1/deploy/static/provider/cloud/deploy.yaml

4.创建nginx-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  rules:                             //nginx.conf配置规则
  - host: tomcat.jack.com
    http:
      paths:
      - path: /
        backend:
          serviceName: tomcat-service
          servicePort: 80
5.修改win的hosts文件,添加dns解析
192.168.8.61 tomcat.jack.com
6.访问

打开浏览器,访问tomcat.jack.com

大致的流程图如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/xzw12138/article/details/108258493