概述

正常情况下,我们是使用普通用户来运行k8s的,也应该在普通用户下运行,这样有利于系统的管理。使用kubeadm初始化完k8s后就可以迁移至普通用户了。


首先,需要kubeadm init加一系列参数来初始化k8s集群信息。这是一个分水岭,只有初始化好了集群才能进行后续的学习,虽然kubeadm安装很简单,但我建议还是得先去简单了解一下k8s的集群架构,什么基本组件网络架构工作方式等等,不然,安装阶段也会踩很多坑,而且是那种错了你不知道啥原因,网上查找教程改好了你也不知道怎么好的。如果是想深入学习的,建议还是先了解k8s的基本架构,不要一头猛扎进来,最后踩了无数的坑,不仅没学到啥东西,还打击了自己的学习热情。好了,废话就这么多了,就先来了解一下k8s的基本命令吧。

学会查找帮助文件
k8s的命令都是以kubectl来提示运行的,就像docker命令行,也是以docker开头的。

运行`kubectl --help`就可以列出命令行下的指令了。不过,通过这种方式列出的指令我们可以称之为一级指令。主要就是各个资源的增删改查

资源类别

1.pod
2.svc,也叫service


命令行创建pod的基本流程

1.run指令创建pod
2.集群内访问pod中的服务
3.service层的妙用

1.run指令创建pod

帮助文档上是这么描述指令的Create and run a particular image in a pod.意思就是创建一个pod,然后指定image在其中运行
基本语法:kubectl run POD_NAME --image=IMAGE_NAME [--port=PORT] [--env="variables=value"]
> POD_NAME和image是必须选项。
> image可以附带版本,格式为image_name:version
> port可选,通常pod的端口都是会再进行端口转换再暴露到外部访问的,所以port选项没有实质意义
> env可选,如果需要附带一些变量到容器里面,可以通过env传参
[k8s@k8s-master deployment]$ kubectl get pods
NAME           READY   STATUS    RESTARTS   AGE
c-nginx        1/1     Running   1          21h
nginx-deploy   1/1     Running   0          7m1s
[k8s@k8s-master deployment]$ kubectl create namespace web-server #创建一个名称空间
namespace/web-server created
[k8s@k8s-master deployment]$ kubectl run nginx2 --image=nginx:latest --namespace=web-server #创建第二个pod
pod/nginx2 created
[k8s@k8s-master deployment]$ kubectl get pods #获取默认域名下的所有pod
NAME           READY   STATUS    RESTARTS   AGE
c-nginx        1/1     Running   1          22h
nginx-deploy   1/1     Running   0          50m
[k8s@k8s-master deployment]$ kubectl get pods -n web-server #获取指定域名下的所有pod,系统域名为kube-system
NAME     READY   STATUS    RESTARTS   AGE
nginx2   1/1     Running   0          39s

2.访问pod中的服务
服务已经在pod中创建好了,需要怎么访问呢?

方案有二:

a.使用kubectl describe pod POD_NAME找到pod的详细信息,包括pod的ip地址,然后就可以通过curl访问了,默认nginx的端口为80
b.使用kubctl get pods -o wide来查看pod的ip,然后通过curl访问

(1)通过kubectl get pod POD_NAME -o wide显示pod信息

[k8s@k8s-master deployment]$ kubectl get pod nginx-deploy -o wide
NAME           READY   STATUS    RESTARTS   AGE   IP           NODE        NOMINATED NODE   READINESS GATES
nginx-deploy   1/1     Running   0          80m   10.244.1.5   k8s-node1   <none>           <none>

(2)通过kubectl describe pod POD_NAME获取pod信息

[k8s@k8s-master deployment]$ kubectl describe pod nginx-deploy
Name:         nginx-deploy
Namespace:    default
Priority:     0
Node:         k8s-node1/192.168.99.109
Start Time:   Fri, 24 Jul 2020 16:14:15 +0800
Labels:       run=nginx-deploy
Annotations:  <none>
Status:       Running
IP:           10.244.1.5 #获取到pod的ip地址
IPs:
  IP:  10.244.1.5
... # 省略剩余部分

通过describe获取的信息很详细,也可通过kubectl get pod POD_NAME -o yaml将pod的信息以yaml格式输出更详细的信息,在写pod的yaml文件时墙裂建议参考此文件


3.service层的妙用
pod创建完了,pod提供的服务也可以访问了,但是如果有1000个pod服务,都需要手动去访问那这个系统就没有存在的意义了。因此,k8s有一个叫做service的中间层,service连接着很多个pod,只需要service层对外暴露一个地址,然后我们来访问这个地址就ok了,有点代理的意思。关于服务高可用这里暂时不做讨论,我们现在要做的是功能的实现,后面等k8s玩熟了再考虑这个问题。

这是官方提供的语法模式,能添加的内容还是很多的。
kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name]
[--name=name] [--external-ip=external-ip-of-service] [--type=type] [options]

选项解析:
-f: 这个选项是使用yaml文件来创建服务,目前我们等级不够,暂时不考虑
TYPE NAME: 这个用于指定资源的类型,我们现在要暴露的是pod服务,因此type为pod
--port: 指定`service`暴露的端口
--protocol: 指定此服务的协议类型
--target-port: 这个是pod的端口,默认情况下会跟--port选项一致,如果后端pod的端口与你配置的--port值不同,那么服务将不可访问。因此target-port必须要跟pod的端口一致
--name: 指定服务的名称
--external-ip: 额外的ip,指的是另外指定一个ip,这个ip不属于k8s集群,但是这个ip可以访问service
--type: 服务对外暴露的模式,有ClusterIP,NodePort,LoadBalancer,ExternalName,默认为CLusterIP,也就是集群内可以访问

ClusterIP
根据nginx-deploy这个pod来创建一个服务:

[k8s@k8s-master deployment]$ kubectl expose pod  nginx-deploy --port=8080 --protocol=TCP --target-port=80 --name=svc-nginx --type=ClusterIP
service/svc-nginx exposed
[k8s@k8s-master deployment]$ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP    26h
svc-nginx    ClusterIP   10.107.122.189   <none>        8080/TCP   7s

NodePort
ClusterIP模式是用于集群内部访问的,集群以外的网络是不能访问的,如果需要将服务暴露到集群外部,那么就需要将服务的–type模式设置为NodePort模式。如果服务已经开启了再想修改服务的模式就需要通过kubectl edit svc SVC_NAME来修改。

[k8s@k8s-master ~]$ kubectl edit svc web-nginx2 #这时候会以yaml格式打开svc的详细信息。其中有些信息是只读的,不能修改,我们只需要修改其中的type字段就可以了
type: ClusterIP  修改为==>  type: NodePort然后保存退出即可

修改完毕,这时候再来看服务,就会发现输出的PORT列发生了改变,在原有的端口后面又加了一个端口。
服务模式是修改成功了,但是要怎么访问呢?观察服务列出的信息,我们发现在集群外部,10.98.131.101是不能访问的。因为10.98.131.101和集群外部的网络根本就不属于一个网络。而且连路由都没有,难道我们还要配路由吗,那也太麻烦了。
其实我们稍微想一想NodePort这个单词的字面意思,就是节点端口的意思,再想一想,节点指的不就是集群中的各个角色吗,比如master节点,node节点啥的。想到这里就好办了,NodePort模式就是通过节点然后对外暴露端口来访问的,所以我们只需要在集群外部访问节点ip加暴露的端口即可。


[k8s@k8s-master ~]$ kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          33h
web-nginx    ClusterIP   10.106.66.233   <none>        8080/TCP         25m
web-nginx2   NodePort    10.98.131.101   <none>        8080:30748/TCP   21m

笔记本界面打开cmd,然后输入curl -I 192.168.99.114:30748就可以访问集群的服务了,192.168.99.114是master节点的ip,其实也可以使用其他node节点的ip,30748是服务暴露的端口。

我们再来了解一下service的几种模式,使用kubectl explain svc.spec来查看官方文档的解释。

   type	<string>
     type determines how the Service is exposed. Defaults to ClusterIP. Valid
     options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
     "ExternalName" maps to the specified externalName. "ClusterIP" allocates a
     cluster-internal IP address for load-balancing to endpoints. Endpoints are
     determined by the selector or if that is not specified, by manual
     construction of an Endpoints object. If clusterIP is "None", no virtual IP
     is allocated and the endpoints are published as a set of endpoints rather
     than a stable IP. "NodePort" builds on ClusterIP and allocates a port on
     every node which routes to the clusterIP. "LoadBalancer" builds on NodePort
     and creates an external load-balancer (if supported in the current cloud)
     which routes to the clusterIP. More info:
     https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types

看完上面一段英文,大概了解到type是一个字符串类型。用于定义服务的暴露模式,默认情况下是ClusterIP模式,另外还有3中方式可供配置。
service的几种暴露模式

ExternalName: 使用域名暴露服务
ClusterIP: 在群集内部IP上公开服务。选择此值将使服务仅可从群集内访问
NodePort: 在每个节点上打开一个端口,通过这个端口,可以路由到后端`service`的ClusterIP,这就是为什么我们可以通过所有节点的IP来访问服务的原因。因此这个模式需要借助ClusterIP模式
LoadBalancer:这个模式需要借助NodePort模式,间接的也需要借助ClusterIP模式。借助云服务商的负载均衡来暴露集群内部的服务。
总结

本文主要介绍了pod在命令行下的创建方式,以及serviceClusterIP模式和NodePort模式下的不同体现。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐