Kubectl连接K8s集群配置(Cluster配置)

在我们搭建好K8s集群后,需要通过Kubectl 客户端连接集群并进行相关集群管控操作,一般我们只需要安装kubectl工具,然后将集群中生成的config文件,拷贝到我们需要连接集群的电脑的 ${HOME}/.kube/config 目录下,这样就可以操作K8s集群了。

但是有的时候我们一台客户端电脑需要连接多个K8s集群,这时我们就需要将不同的config文件合并在一起,以方便我们操作。

本节核心命令:

kubectl config get-contexts:获取客户端链接的所有上下文

kubectl config get-clusters:获取客户端连接的所有配置cluster

kubectl config use-context [context的名称]:切换当前集群的连接

kubectl get node -o wide:查看集群节点的详细信息

kubectl describe node [上述命令查询出的节点名称]:查看某个节点的详细信息


例如我们原有的minikube集群中的config文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: v1
clusters:
- cluster:
certificate-authority: /home/jjw/.minikube/ca.crt
server: https://172.17.0.3:8443
name: minikube
contexts:
- context:
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate: /home/jjw/.minikube/profiles/minikube/client.crt
client-key: /home/jjw/.minikube/profiles/minikube/client.key

我们现在合并另外一个集群的配置文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 指定版本
apiVersion: v1

# 配置clusters,这里就是可以配置连接多个K8s的集群
clusters:
- cluster:
certificate-authority: /home/jjw/.minikube/ca.crt
server: https://172.17.0.3:8443
name: minikube
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://172.19.8.113:6443
name: jplocal

# 配置context,
contexts:

# 第一个
- context:
cluster: minikube
user: minikube
name: minikube

# 第二个
- context:
cluster: jplocal
user: kube-admin-local
name: local

# 配置默认的连接
current-context: minikube
kind: Config
preferences: {}

# 配置连接集群的uers信息,包含身份认证信息等
users:
- name: minikube
user:
client-certificate: /home/jjw/.minikube/profiles/minikube/client.crt
client-key: /home/jjw/.minikube/profiles/minikube/client.key
- name: kube-admin-local
user:
client-certificate-data: REDACTED
client-key-data: REDACTED

配置完成后我们就可以通过命令查看我们的配置上下文等信息,如下:

1
2
3
4
5
6
7
8
9
10
# 注意:带*号表示是我们当前使用连接的context
jjw@jjw-PC:~/.kube$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
local jplocal kube-admin-local
* minikube minikube minikube

jjw@jjw-PC:~/.kube$ kubectl config get-clusters
NAME
minikube
jplocal

切换连接到名称为local的集群:

1
2
3
4
5
6
7
8
9
# 切换
jjw@jjw-PC:~/.kube$ kubectl config use-context local
Switched to context "local".

# 查看切换结果,发现切换成功
jjw@jjw-PC:~/.kube$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* local jplocal kube-admin-local
minikube minikube minikube

这样我们就可以操作我们的K8s集群了,例如完整如下:

1
2
3
4
5
6
7
8
9
10
11
12
# 获取当前local集群的节点信息,获取不到是因为这个配置是我瞎写的
jjw@jjw-PC:~/.kube$ kubectl get node
error: tls: failed to find any PEM data in certificate input

# 切换成之前的minikube集群
jjw@jjw-PC:~/.kube$ kubectl config use-context minikube
Switched to context "minikube".

# 能够获取到节点信息
jjw@jjw-PC:~/.kube$ kubectl get node
NAME STATUS ROLES AGE VERSION
minikube Ready master 15d v1.18.3

K8s集群网络(Cluster Networking)

K8s集群间网络现象及原理

当我们搭建了一套K8s集群后,我们在节点中创建Pod,并且查询出此Pod的IP地址,这时我们在任何一个节点或者任何一个节点的Pod中,我们ping这个IP地址,我们发现是都可以ping通的,这就是K8s集群中我们要讲的网络。

在之前的Swarm集群中,我们也有同样的现象,我们知道原理是它们通过一个Overlay的Network实现的,其实K8s集群也是这样,只不过这里是通过某个插件来实现的Overlay网络,远离同样是将Pod的网络代理到机器网关上,类似eth1,然后通过此网关来解析代理。

具体的插件有很多种(例如flannal网络插件),我们可以去K8s官网上查看,这些插件都需要遵循K8s网络的规定或者说协议:

  1. 所有的容器跟其他所有的容器之间可以直接通信,并且不需要NAT的转化

  2. 所有的Node都可以直接与其他Node的容器进行直接通信,并且不需要NAT的转化

  3. 我们的这个容器的IP地址是什么,那么其他容器或者节点就可以直接通过这个IP来访问这个容器

本节核心命令:

kubectl get svc:获取集群上所有的Services信息

kubectl get pods –show-labels:查看集群中所有Pod的Label

kubectl expose pods [pod名称]:将已有Pod导出创建Service

kubectl expose depolyment [depolyment名称]:将已有depolyment导出创建为Service

kubectl create -f [service的yml文件名称]:通过yml文件创建service

kubectl edit depolyment [depolyment名称]:创建service后,直接编辑此depolymet升级此depolyment

kubectl apply -f [新的depolyment yml文件] –record:创建service滚动升级depolyment

kubectl delete svc/[service名称]:删除service

kubectl delete -f [service的yml文件名称]:通过文件删除service

K8s集群中应用对外提供网络

Service

在上述现象中,我们所描述的Pod提供的IP都只是在K8s集群中可以互访,但是我们部署应用后,需要对外界提供服务,这样我们就需要将网络暴露给外界,这时应该怎么做呢?

首先我们看看在K8s集群中直接使用和管理Pod的缺点:

  1. 当我们使用ReplicaSet或者ReplicationController做水平扩展scale的时候,Pods就有可能被终止掉

  2. 当我们使用Depolyment的时候,我们去更新Docker Image Version ,旧的Pod就会被终止,然后创建新的Pod

当我们使用上述两种方式做扩展,如果我们直接管理的是Pod,对外提供的是Pod的IP,那么我们在扩展后,Pod的IP地址就会发生变化,这时我们外界再通过之前的IP就不能访问我们的Pod中提供的服务了。或者是说我们在Pod中部署了数据库服务,其他集群中的Pod可以访问,但是我们对数据库进行升级的时候,这样其他集群中的服务就不能访问数据库了,因为在升级的过程中,数据库的IP地址就发生了变化

为了解决上述问题,我们同样可以使用之前学习过的Service来解决,K8s中管理最常用的也是Service,使用Service我们可以管理多个Pod,并且将这些Pod集中管理起来,可以随意扩展或降级升级,并且保证我们对外提供的IP地址是一个,且不发生变化,而且有负载均衡的作用。

Service主要有三种类型:

  1. ClusterIP:这个IP地址是Cluster可以访问的,及K8s集群中任何一个节点都可以访问,但是外界不能访问,这个IP是不会变的,是Service所对应的IP地址,它会代理到我们service中的Pod上,Pod的IP地址是可以变化的,一般应用与只在系统间内部可以访问,比如数据库服务

  2. NodePort:这个Service是对外提供IP地址,这是与ClusterIP类型的Service最大的不同

  3. LoadBalancer:这个一般需要云服务商提供,我们通过这个LoadBalancer就可以访问集群中的Pod,并且提供负载均衡

Service的创建方式:

  1. 通过kubectl expose 命令,会给我们的Pod创建一个service,供外部访问

  2. 定义一个yml文件,我们在此文件中描述Service的具体信息及资源

创建ClusterIP类型Servcice示例

  • 通过Pod直接创建Service
1
2
3
4
5
6
7
8
9
10
11
12
1. 首先创建好Pod
kubectl create -f [yml文件的路径名称]

2. 查看我们创建的Pod的具体信息,包括pod的名称和IP等
kubectl get pods -o wide

3. 根据pod的名称,创建service
kubectl expose pods [pod名称]

4. 查看我们创建的service的具体信息,这里会查看到我们创建的service的IP地址和端口,这里我们查看到的Service的IP地址是不会变化的,而上面我们查看到的Pod的IP地址是会随着服务的扩展升级等发生变化
注意:这里查询出的ServiceIP只能在K8s集群内部访问,因为我们创建的是一个ClusterIP类型的Service
kubectl get svc
  • 通过Depolyment创建Service,测试升级或者扩展此应用,Service IP不发生变化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
1. 首先我们创建一个Depolyment,此Depolyment中Pod的个数可以是多个
kubectl create -f [deployment的yml文件]
jjw@jjw-PC:~$ kubectl create -f deployment_nginx.yml
deployment.apps/nginx-deployment created


2. 查看我们创建好的pod的具体信息
kubectl get pods -o wide
jjw@jjw-PC:~$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-5cc6c7559b-j5v57 1/1 Running 0 16s 172.18.0.5 minikube <none> <none>
nginx-deployment-5cc6c7559b-t5z92 1/1 Running 0 16s 172.18.0.4 minikube <none> <none>
nginx-deployment-5cc6c7559b-wfbts 1/1 Running 0 16s 172.18.0.6 minikube <none> <none>

3. 查看我们此depolyment的具体信息,包括depolyment的名称
kubectl get depolyment

4. 通过此depolyment创建Service
kubectl expose depolyment [depolyment名称]
jjw@jjw-PC:~$ kubectl expose deployment nginx-deployment
service/nginx-deployment exposed

5. 查看我们创建的service,这时,我们的Service的IP信息也就被查看到了
kubectl get svc
jjw@jjw-PC:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19d
nginx-deployment ClusterIP 10.96.161.226 <none> 80/TCP 26s

6. 然后我们访问此IP,发现是可以访问到我们Pod提供的服务的,并且它还实现了负载均衡的功能

7. 升级此depoluyment,我们可以直接编辑此depolyment来实现升级,使用命令
kubectl edit depolyment [depolyment名称]

8. 编辑完此depolyment要升级的内容后,我们的服务就会自动升级

9. 查看现在的Pod信息,发现pod已经不是我们之前创建的了,而是新的,但是这时我们的Service IP还是没有变化,还是可以通过此IP访问到服务
kubectl get pods -o wide

这里我们的升级它不是零宕机的升级,它还是会中断一会,我们可以通过其他方法实现滚动升级,即优雅上下线升级

滚动升级的实现其实就是我们重新定义一个yml,及针对与之前depolyment的yml的升级后的yml,然后通过命令:

  • kubectl apply -f [新的depolyment yml文件] –record

这样就可以实现滚动升级,如果不加 –record 参数,则旧的depolymeng不会被删除,它还会存在,只是Pod数变成了0

创建NodePort类型Servcice示例

  • 通过Pod直接创建Service
1
2
3
4
5
6
7
8
9
10
11
12
1. 首先创建好Pod
kubectl create -f [yml文件的路径名称]

2. 查看我们创建的Pod的具体信息,包括pod的名称和IP等
kubectl get pods -o wide

3. 根据pod的名称,指定参数,创建NodePort类型Service
kubectl expose pods [pod名称] --type=NodePort

4. 查看我们创建的service的具体信息
注意:这里也会查询出ClusterIP,但是在端口信息上,与ClusterIP类型的Service不同,它会指定一个IP映射(80:31404/TCP),这里就表示我们将Pod的端口映射到了主机上,我们可以通过此映射及Port通过主机的IP来访问此Pod服务。这样如果我们的主机是有公网IP的,那么我们这个服务就可以直接暴露给外界来使用
kubectl get svc
  • 通过Depolyment创建NodePort类型的Service

创建方式与上述创建ClusterIP类型的Service一样,不同的是在创建的命令中指定–type=NodePort即可

kubectl expose depolyment [depolyment名称] –type=NodePort即可

  • 通过Service.yml文件创建Service
  1. 通过yml文件创建service,我们首先要创建好Pod,然后指定Pod的Label,如下Pod的yml文件,nginx-pod.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod

# 注意:这里我们指明了Pod的Label
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx
ports:
- name: nginx-port
containerPort: 80
  1. 创建service的yml文件,如下service_nginx.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:

# 指定端口映射,这里表示将Pod的端口映射为本地的8080和NodePort的8080
ports:
- port: 32333
nodePort: 32333

# 这里就表示我们创建service要引用的Pod的,这里指定的是Pod的Label,所以我们创建service的文件是用Label来确定具体Pod的
targetPort: nginx-port
protocol: TCP
selector:
app: nginx
type: NodePort
  1. 创建service
1
kubectl create -f service_nginx.yml

创建LoadBalance类型Servcice示例

创建LoadBalance类型的Servcie需要借助于云服务,所以这里不再演示,比较复杂,具体用的时候查资料或者视频即可

具体创建命令:

kubectl expose pods [pod名称] –type=LoadBalance

kubectl expose depolyment [depolyment名称] –type=LoadBalance

secret使用

secret的使用与Swarm很类似,具体就是先在集群中创建secret,然后在service的yml文件中要使用的地方引入此secret名称即可

创建secret:

  1. kubectl create secret generic [secret名称] –from-literal=[key]=[value]:通过命令直接指定创建

  2. kubectl create secret generic [secret名称] –from-file=[file路径]:通过编辑好的文件创建

示例如下:

1
2
# 创建一个名称为mysql-pass的 键为password 值为jjw0923的secret
kubectl create secret generic mysql-pass --from-literal=password=jjw0923

然后在service的yml文件引入即可,具体使用查资料

最后更新: 2020年07月10日 20:50

原始链接: https://jjw-story.github.io/2020/06/30/Kebernetes-进阶/

× 请我吃糖~
打赏二维码