实践出真知—-k8s初步熟悉使用介绍,实践搭建nginx集群

✍️Auth:star皆空       Date:2021/11/19       Cat:Linux服务器       👁️:941 次浏览

k8s部署搭建参考:基于Linux(Ubuntu20.04)初步搭建k8s集群


一、前言

三个基本概念,Pod,Service,Namespace。

Pod:k8s最小单元,pod和容器的区别,容器包含在pod中,一个pod中有一个pause容器和若干个业务容器,而容器就是单独的一个容器,简而言之,pod是一组容器,而容器单指一个容器。

Service:pod每次动态创建后,自动分配的ip会不同,所以引入了service(即服务的注册与发现),通俗的讲,就是管理上网功能的,相关于网络管理员,保证网络正常就行。

namespace:命名空间,主要用于隔离

k8s一切皆容器,所有的服务也好,插件也好,都是运行在docker容器之中。

部署项目,类似docker-compose通过yaml文件拉取生成项目布置,docker-compose只能单机本机上部署,但k8s可以集群部署多台服务器,即node节点。

环境介绍:
k8s-master:Ubuntu–192.168.152.100
k8s-node01:Ubuntu–192.168.152.101
k8s-node02:Ubuntu–192.168.152.102

布置之前,先完善kubectl 命令自动补全,因为默认kubectl按快捷键没有补齐的。

#安装bash-completion(如果已经安装忽略即可):
sudo apt install bash-completion
#测试一下:
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
#测试没问题后,对 /root/.bashrc 加2行代码 ,方便以后每次登录自动生效:
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)


二、直接创建pod部署nginx(非必要,测试熟悉用,熟悉k8s者可跳过这步)

在yaml文件中,有个kind参数,用来指定创建资源的角色/类型。
正常创建是创建Deployment和Service两个 yaml文件,及kind分别是deployment,Service来搭建。

这里可以直接创建pod 测试来熟悉k8s相关操作。而且只能单个创建pod,无法达到集群的要求。

一般不直接kind: Pod创建pod,而是通过controller来创建pod。deployment为其中一种controller。这里先演示测试最基本的搭建,所以设置为kind:Pod

#编辑
sudo vim nginx_pod.yaml

内容如下,相关参数说明见本文最后。

apiVersion: v1    #核心,对象pod、service等
kind: Pod
metadata:        #资源的元数据/属性
  name: nginx
  labels:
    app: nginx
spec:            #设置该资源的内容
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80    #容器端口
      hostPort: 8081    #让外部访问端口,官方及其不推荐这种方式,走的防火墙iptables方式,本人测试没成功,仍然无法从外部访问。

yaml创建完成后,使用命令 kubectl apply或者kubectl create加入k8s并创建 pod

两者命令区别:
kubectl create:是先删除所有现有的东西,重新根据yaml文件生成新的。无法覆盖,报错。
ubectl apply:根据配置文件里面列出来的内容,升级现有的,直接覆盖原来的。(建议使用)

kubectl apply -f nginx_pod.yaml
#或者用以下命令
kubectl create -f nginx_pod.yaml

创建完成后,可查看pod 的状态,执行命令:

kubectl get pods -o wide    # 列出所有 pod 并显示详细信息
kubectl get pods nginx -o wide    # 列出所有nginx pod 并显示详细信息

显示如下,可以看到 nginx pod 已处于 Running 状态,表示刚创建的 pod 已成功运行起来。

ubuntu@k8s-master:~$ kubectl apply -f nginx_pod.yaml
pod/nginx created
ubuntu@k8s-master:~$ kubectl get pods nginx -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          35s   172.16.58.193   k8s-node02   <none>           <none>

通过查看pods状态,可以得到信息,pods的内部IP为172.16.58.193,master已将nginx自动部署至node02节点(如没有特殊设置,k8s会通过服务器负载均衡自动布置合适的node节点上)。

在node2节点的机器上,查看docker可以看到,docker nginx已经运行。

在master主节点上,同样可用类似docker exec的命令,进入容器查看状态。

#进入容器
kubectl exec -it nginx -- /bin/sh
#进入容器后,执行命令访问nginx。可正常返回nginx页面。
curl localhost

测试完成后,可以用以下命令删除此pod

kubectl delete -f nginx_pod.yaml

通过测试可以看出,使用hostPort的方式,这种很难通过外网访问内部容器。
所以通过其他方式访问,最常用的是NodePort的方式,对比这两种方式:

1、使用hostPort的方式,这种还会占用其他宿主机的端口,同时会引发其他错误,官方也不推荐。
2、使用NodePort的方式,k8s广泛应用的服务暴露方式,普遍运用的方式,这种也是Service默认的网络端口模式。

接下来用Deployment和Service正常创建多个pod。



三、正式部署nginx集群

1、创建 deployment

通过deployment创建Pod,创建deployment yaml文件

sudo vim nginx-dep.yml

内容为

apiVersion: apps/v1    #Deployment用这个
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:            #标签选择器,与metadata中的labels:标签共同作用,目前不需要理解
    matchLabels:    #选择包含标签app:nginx的资源
      app: nginx
  replicas: 3        # 镜像副本数量
  template:            #这是选择或创建的Pod的模板
    metadata:        #Pod的元数据
      labels:        #Pod的标签,上面的selector即选择包含标签app:nginx的Pod
        app: nginx
    spec:             #即在pod中部署功能
      containers:     #以下容器内容
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

完成后,加入k8s创建pod

kubectl apply -f nginx-dep.yaml

查看pod

kubectl get deploy -o wide

可以看到,3个pod创建完成,分别分布在两个node节点机器上。

ubuntu@k8s-master:~$ kubectl get pods -o wide
NAME                               READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
nginx-deployment-585449566-547fh   1/1     Running   0          78s   172.16.85.193   k8s-node01   <none>           <none>
nginx-deployment-585449566-pjs7n   1/1     Running   0          78s   172.16.58.195   k8s-node02   <none>           <none>
nginx-deployment-585449566-txzvf   1/1     Running   0          78s   172.16.58.196   k8s-node02   <none>           <none>

2、创建 Service

创建Service yaml文件

sudo vim nginx-service.yaml

内容为

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080 #端口范围只能是 30000-32767,外部通过此端口访问
  type: NodePort    #nodePort方式,必须声明这类型

完成后,加入k8s创建

kubectl create -f nginx-service.yaml

此时需要用kubectl get svc查看服务了,而不是查看pod。

kubectl get svc -o wide

查看如下已正常启动

ubuntu@k8s-master:~$ kubectl get svc -o wide
NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE    SELECTOR
kubernetes      ClusterIP   10.96.0.1       <none>        443/TCP        25h    <none>
nginx-service   NodePort    10.101.18.212   <none>        80:30080/TCP   106s   app=nginx

3、测试访问nginx

在浏览器输入节点IP:30080访问
master主节点IP访问测试:

master节点IP访问测试:


测试完成,这时候正式nginx集群搭建完成。



四、Namespace 命名空间 (扩展)

1、简介

命名空间适用于存在很多跨多个团队或项目的用户的场景。对于只有几到几十个用户的集群,根本不需要创建或考虑命名空间。当需要名称空间提供的功能时,请开始使用它们。

简单理解,不同团队之间的项目,隔离作用,互不干扰。但是必要情况下,也是可以互相通信的。

Kubernetes中的集群默认会有一个叫default的namespace。实际上,应该是3个:

  • default:你的service和app默认被创建于此。
  • kube-system:kubernetes系统组件使用。
  • kube-public:公共资源使用。但实际上现在并不常用。

命令kubectl get ns可查看命名空间。

ubuntu@k8s-master:~$ kubectl get ns
NAME              STATUS   AGE
default           Active   42h
kube-node-lease   Active   42h
kube-public       Active   42h
kube-system       Active   42h

所有没有指定namespace下,集群都默认在default 命名空间。


2、创建Namespace

两种方式:命令和yaml文件
1)命令:kubectl create namespace test
2)使用yaml文件:

  sudo vim namespace.yaml
   kind: Namespace
   apiVersion: v1
   metadata:
    name: test
   labels:
    name: test

然后,执行kubectl apply -f namespace.yaml


3、在namespace中创建资源

也有两种方式:
1)命令最后指定命名空间:kubectl apply -f pod.yaml –namespace=test
2)在yaml文件指定:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
  namespace: test    #指定命名空间
  labels:
    name: mypod
spec:
  containers:
  - name: mypod
    image: nginx

一旦指定命名空间后,在查看Pod或者Service,也必须指定命名空间,否则查看不到,因为没指定之前,所有命令默认是default的命名空间。

查看test命名空间的pod

kubectl get pods --namespace=test

4、kubens切换namespace

如上所示,所有命令默认是default的命名空间,所有用其他命名空间,必须指定命令。所以可以切换至命名空间,就不需要在命令后指定了。

所以需要用到插件kubens,插件地址:https://github.com/ahmetb/kubectx#manual-installation-macos-and-linux
这里面包含两个插件,需要的话都可以安装。下载安装:

sudo git clone https://github.com/ahmetb/kubectx /opt/kubectx
sudo ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx
sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubens

安装完成,当你运行kubens命令,它会高亮当前的namespace,
切换test空间,kubens test,再次查看所在空间,已切换完成,查看test所在空间的资源,输入命令也无需在次指定test的命名空间。



五、yaml参数参考(参考)

 apiVersion: v1             #指定api版本,此值必须在kubectl apiversion,命令kubectl api-versions可查看 
 kind: Pod                  #指定创建资源的角色/类型  
 metadata:                  #资源的元数据/属性  
   name: django-pod         #资源的名字,在同一个namespace中必须唯一  
   labels:                  #设定资源的标签,使这个标签在service网络中备案,以便被获知
     k8s-app: django
     version: v1  
     kubernetes.io/cluster-service: "true"  
   annotations:             #设置自定义注解列表  
    - name: String         #设置自定义注解名字  
 spec:                      #设置该资源的内容  
   restartPolicy: Always    #表示自动重启,一直都会有这个容器运行
   nodeSelector:            #选择node节点14     zone: node1  
   containers:  
   - name: django-pod        #容器的名字  
     image: django:v1.1      #容器使用的镜像地址  
     imagePullPolicy: Never #三个选择Always、Never、IfNotPresent,每次启动时检查和更新(从registery)images的策略,
                            # Always,每次都检查
                            # Never,每次都不检查(不管本地是否有)
                            # IfNotPresent,如果本地有就不检查,如果没有就拉取
     command: ['sh']        #启动容器的运行命令,将覆盖容器中的Entrypoint,对应Dockefile中的ENTRYPOINT  
     args: ["$(str)"]       #启动容器的命令参数,对应Dockerfile中CMD参数  
     env:                   #指定容器中的环境变量  
     - name: str            #变量的名字  
       value: "/etc/run.sh" #变量的值  
     resources:             #资源管理
       requests:            #容器运行时,最低资源需求,也就是说最少需要多少资源容器才能正常运行  
         cpu: 0.1           #CPU资源(核数),两种方式,浮点数或者是整数+m,0.1=100m,最少值为0.001核(1m)
         memory: 32Mi       #内存使用量  
       limits:              #资源限制  
         cpu: 0.5  
         memory: 32Mi  
     ports:  
     - containerPort: 8080    #容器开发对外的端口
       name: uwsgi          #名称
       protocol: TCP  
     livenessProbe:         #pod内容器健康检查的设置
       httpGet:             #通过httpget检查健康,返回200-399之间,则认为容器正常  
         path: /            #URI地址  
         port: 8080  
         #host: 127.0.0.1   #主机地址  
         scheme: HTTP  
       initialDelaySeconds: 180 #表明第一次检测在容器启动后多长时间后开始  
       timeoutSeconds: 5    #检测的超时时间  
       periodSeconds: 15    #检查间隔时间  
       #也可以用这种方法  
       #exec: 执行命令的方法进行监测,如果其退出码不为0,则认为容器正常  
       #  command:  
       #    - cat  
       #    - /tmp/health  
       #也可以用这种方法  
       #tcpSocket: //通过tcpSocket检查健康   
       #  port: number   
     lifecycle:             #生命周期管理(钩子)  
       postStart:           #容器运行之前运行的任务  
         exec:  
           command:  
             - 'sh'  
             - 'yum upgrade -y'  
       preStop:             #容器关闭之前运行的任务  
         exec:  
           command: ['service httpd stop']  
     volumeMounts:          #挂载设置
     - name: volume         #挂载设备的名字,与volumes[*].name 需要对应    
       mountPath: /data     #挂载到容器的某个路径下  
       readOnly: True  
   volumes:                 #定义一组挂载设备  
   - name: volume           #定义一个挂载设备的名字  
     #meptyDir: {}  
     hostPath:  
       path: /opt           #挂载设备类型为hostPath,路径为宿主机下的/opt
打赏作者

实践出真知—-k8s初步熟悉使用介绍,实践搭建nginx集群》有1个想法

  1. Pingback引用通告: 基于Linux(Ubuntu20.04)初步搭建k8s集群基础,详细教程 - 运维笔记(ywbj.cc)

发表评论