Kubernetes(k3s)基础学习(三) -- Deployment、Service、Ingress

当决心要学习一门新的知识时,不要仅仅盯着知识点的价值,而是多想想它能帮我解决什么问题。 我曾经上过一门营销学的课程,课堂上的讲师讲出一个让我很深刻的观点:不要侃侃其谈你产品的卖点,多找别人的买点。 Kubernetes的知识很多,但互联网更广泛。不要一根针把头扎了进去,带着我们想解决的问题去研究获得最适合自己的学习方案。

回归主题,如果在中小型企业或者非互联网型的传统企业,Kubernetes的卖点(分布式微服务架构,高可用高并发,弹性扩容)未必会派上用场,但不代表Kubernetes没有可用武之地。它的服务隔离、可扩展性,再配合上Jenkins的可持续集成 可以让企业内部的IT治理变得有序可管。
简单地说,我的资源有限(有限的机器数),业务的项目无限(每年持 续增长)。Kubernetes的特性可以让有限资源尽可能充分有效地满足无限的业务量,榨干榨尽每一滴。

当从Kubernetes找到以下解决方案后,Kubernetes就可以在企业IT治理中发挥其价值的时候:

  1. 服务发布
  2. 健康监控
  3. 存储持久化
  4. 快速部署、高可用
  5. 故障排查

使用Deployment

通常来说,在编写yml 时,Pod与Deployment 成对出现。因为弹性伸缩的需要,Deployment 扮演着Pod 的监管者角色。

#本地终端,进入server节点容器的命令
multipass shell server

#如果看了上一章,并且按照指引创建了Pod:k3s-test,为了避免冲突麻烦,先删除掉旧的Pod吧。
#如果没有请略过。
ubuntu@server:~$ sudo kubectl delete pod k3s-test

#ubuntu@server:~$ sudo vi k3s-test-deployment.yml

#k3s-test-deployment.yml
apiVersion: apps/v1     #这里要注意了,单独创建Pod时是v1,换成Deployment后,这里要改写为apps/v1
kind: Deployment        #指定要创建的类型
metadata:                    #译名为元数据,即 Deployment 的一些基本属性和信息
  name: k3s-test-deployment         #deployment 的名称
  labels:   #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
    app: k3s-test    #app 为key ,k3s-test 为value,还可以定义多个
spec:           #这里开始就是Deployment的属性配置了
  replicas: 1        #指定Pod的数量
  selector:           #标签选择器,与上面的标签共同作用,目前不需要理解
    matchLabels:      #选择包含标签app:k3s-test的资源
      app: k3s-test
  template:              #Pod模板
    metadata:
      labels:                #Pod的标签,上面的selector即选择包含标签app:k3s-test的Pod
        app: k3s-test
    spec:                  #期望Pod实现的功能(即在pod中部署)
      containers:              #容器信息
      - name: k3s-test
        image: registry.cn-hangzhou.aliyuncs.com/dawson-project/hello-node:latest             #还是我们的Node Demo
        ports:              #这里代表Pod 可输出的端口,7001是我们Node Demo 默认可访问的端口
        - containerPort: 7001 

我们在server 节点的根目录下已经创建好k3s-test-deployment.yml 文件,继续执行kubectl 的通用引用命令。

ubuntu@server:~$ sudo kubectl apply -f k3s-test-deployment.yml

#输出内容
deployment/k3s-test-deployment created

#通过命令检查是否创建成功
ubuntu@server:~$ sudo kubectl get deployments -o wide

#得到的输出结果
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS    IMAGES                                                               SELECTOR
k3s-test-deployment   1/1     1            1           82s   k3s-test   registry.cn-hangzhou.aliyuncs.com/dawson-project/hello-node:latest   app=k3s-test

#再通过命令检查Pod
ubuntu@server:~$ sudo kubectl get pods -o wide

#得到的输出结果
NAME                                      READY   STATUS              RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
k3s-test-deployment-6f6b9977d9-2p598   1/1     Running             0          2m56s   10.42.1.50   node1   <none>           <none>

执行完上述命令后,我们在输出终端也看到有一个Pod 被创建出来,IP地址为\color{#FF0000}{10.42.1.50}。这个IP地址如Kubernetes(k3s)学习(二) -- 基于最小的pod单元来创建应用所讲,只允许被Kubenetes 内部环境所访问,外网不能正常访问。

#在server 节点访问的结果
ubuntu@server:~$ curl http://10.42.1.50:7001
#输出
Hello K8s!

#在node1节点以及node2访问的结果
ubuntu@node1:~$ curl http://10.42.1.50:7001
#输出
Hello K8s!

#在本机正常环境的访问
#输出
curl http://10.42.1.50:7001

#输出
#没有结果

怎样才能让外界能够访问容器呢?先不急,我们再来看看弹性扩容的。方法很简单,修改k3s-test.deployment.yml的replicas 节点就好,我们把节点数量调节成3,然后再重新运行后,检查输出结果。

#server 环境
#ubuntu@server:~$ sudo vi k3s-test-deployment.yml
#修改replicas 的节点, 把1 改为3,并保存

#执行命令
ubuntu@server:~$ sudo kubectl apply -f k3s-test-deployment.yml 

#输出结果
deployment.apps/k3s-test-deployment configured

#再看查看pods
ubuntu@server:~$ sudo kubectl get pods -o wide

#输出结果
NAME                                   READY   STATUS              RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
k3s-test-deployment-5975994799-8rfrv   1/1     Running             0          7m44s   10.42.1.50   node1    <none>           <none>
k3s-test-deployment-5975994799-jnd4z   0/1     Running             0          27s     10.42.2.44   server   <none>           <none>
k3s-test-deployment-5975994799-r7l8t   0/1     Running             0          27s     10.42.0.36   node2    <none>           <none>

简单的使用,成功地扩容成三个节点,并且IP为\color{#FF0000}{10.42.1.50}的Pod还保留着。至于缩小节点数,执行步骤是一样的。这里就忽略了。

使用Service

本来是同一套服务,但经过动态扩容后,得到了三个IP地址。这时我们需要有一个统一的负载IP提供统一入口管理,这时候就由Service 发挥作用了。

#server 环境
#ubuntu@server:~$ sudo vi k3s-test-service.yml

apiVersion: v1             #apiVersion 需要回到v1 命名
kind: Service              #指定要创建的类型
metadata:
  name: k3s-test-service
  labels: 
    app: k3s-test
spec:
  selector:                    #选择器,需要与pod 的命名是一致
    app: k3s-test
  type: NodePort          #先介绍NodePort,后面再介绍ClusterIp
  ports:
  - name:  k3s-test-service-port
    protocol: TCP
    port:  80
    nodePort: 31600
    targetPort:  7001

#targetPort:  要映射去Pod 的可访问端口
#port:        Kubenetes 内部环境可访问的端口
#nodePort :   外部环境可访问,但Kubenetes内部环境不能访问的端口。
#如果不指定,将由Kubenetes 自动分配端口

执行kubectl 的通用引用命令

ubuntu@server:~$ sudo kubectl apply -f k3s-test-service.yml

#输出内容
service/k3s-test-service created

#通过命令检查是否创建成功
ubuntu@server:~$ sudo kubectl get services -o wide

#得到的输出结果
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
kubernetes         ClusterIP   10.43.0.1       <none>        443/TCP        21d   <none>
k3s-test-service   NodePort    10.43.194.131   <none>        80:31600/TCP   65s   app=k3s-test

这里,我们分别在节点server、node1、node2、“终端”环境验证IP:\color{#FF0000}{10.43.194.131}以及端口\color{#FF0000}{31600}\color{#FF0000}{80}

#server 节点,允许直接访问80端口
ubuntu@server:~$ curl http://10.43.194.131
#输出
Hello K8s!

#不允许访问31600端口
ubuntu@server:~$ curl http://10.43.194.131:31600
#没有输出,不允许访问31600端口


#node1 、node2 节点,允许直接访问80端口
ubuntu@node1:~$ curl http://10.43.194.131
#输出
Hello K8s!

ubuntu@node1:~$ curl http://10.43.194.131:31600
#没有输出,不允许访问31600端口


#终端环境
#其中192.168.64.2是server节点的IP地址,
#31600端口对外暴露输出
xxx@xxxx ~ % curl http://192.168.64.2:31600
Hello K8s!

#如何获取192.168.64.2地址请回第一章
#Kubernetes(k3s)学习(一) -- 使用集群部署
#https://www.jianshu.com/p/64c34d69ea39


xxx@xxxx ~ % curl http://192.168.64.2
#输出了404,终端不能直接访问80端口
404 page not found

Service 除了\color{#FF0000}{NodePort}类型外,默认选择是\color{#FF0000}{ClusterIp}。其区别在于不能定义对外暴露端口\color{#FF0000}{NodePort}
实际项目执行中,我偏向于使用\color{#FF0000}{ClusterIp}类型,减少Master节点被过多暴露端口。

服务发布

Kubenetes 提供了一种基于 Ingress 的服务发布式,通过配置 Ingress 和外部实现的 Ingress Controller 可以方便的实现服务发布的功能。

k3s 默认集成了基于 Traefix 的 Ingress Controller,所以直接使用即可,不需要手工再安装 Traefix。

新建 k3s-test-ingress.yml 配置规则吧。

#server 环境
#ubuntu@server:~$ sudo vi k3s-test-ingress.yml

apiVersion: networking.k8s.io/v1     #apiVersion 需要回到networking.k8s.io/v1 命名
kind: Ingress         #需要创建的类型
metadata:
  name: k3s-test-ingress
  labels:
    name: k3s-test
spec:
  rules:
  - host: www.k3s-test.com           #这里是外界入口可访问的域名配置
    http:
      paths:
      - pathType: Prefix
        path: "/"                              #可配置访问的入口路径
        backend:
          service:
            name: k3s-test-service           #选择器,代表访问Service:k3s-test-service 
            port: 
              number: 80                 #对外暴露的端口

其中 rules[].host 设置了一个域名:www.k3s-test.com,这只是一个测试域名,非本人所有,所以提供给外界访问,但本机环境下,我们可以通过修改 hosts 文件来达到跳过域名解析的目的。下面是具体操作。


#server节点环境执行
ubuntu@server:~$ sudo kubectl apply -f k3s-test-ingress.yml

#输出


#返回到本机的“终端”
# 修改 本机的hosts
xxx@xxx % sudo vi /etc/hosts
# 在该文件中添加一条解析记录
192.168.64.2  www.k3s-test.com

#192.168.64.2 为server节点的IP地址
#如何获取192.168.64.2地址请回第一章
#Kubernetes(k3s)学习(一) -- 使用集群部署
#https://www.jianshu.com/p/64c34d69ea39

我们来进行最后测试吧,本机访问

xxx@xxx % http://www.k3s-test.com
#成功输出结果
Hello K8s!

说明 Ingress 已正常工作。

希望大家通过阅读完此章后以及一些实战例子,能够轻松地掌握Kubernetes的基础。后面我再深入聊Kubenetes 其他的实战特性。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容