0%

k8s学习日记day3

kubernetes的实战入门

1 前言

  • 介绍如何在kubernetes集群中部署一个Nginx服务,并且能够对其访问。

2 Namespace

2.1 概述

  • Namespace是kubernetes系统中一种非常重要的资源,它的主要作用是用来实现多套系统的资源隔离或者多租户的资源隔离

  • 默认情况下,kubernetes集群中的所有Pod都是可以相互访问的。但是在实际中,可能不想让两个Pod之间进行互相的访问,那么此时就可以将两个Pod划分到不同的Namespace下。kubernetes通过将集群内部的资源分配到不同的Namespace中,可以形成逻辑上的“组”,以方便不同的组的资源进行隔离使用和管理。

  • 可以通过kubernetes的授权机制,将不同的Namespace交给不同租户进行管理,这样就实现了多租户的资源隔离。此时还能结合kubernetes的资源配额机制,限定不同租户能占用的资源,例如CPU使用量、内存使用量等等,来实现租户可用资源的管理。

kubernetes在集群启动之后,会默认创建几个namespace。

1
2
3
4
5
6
7
8
9
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 2d14h #自动创建
dev Active 39h
kube-node-lease Active 2d14h #自动创建
kube-public Active 2d14h #自动创建
kube-system Active 2d14h #自动创建
kubernetes-dashboard Active 2d14h
test Active 23h
  • default:所有未指定的Namespace的对象都会被分配在default命名空间。

  • kube-node-lease:集群节点之间的心跳维护,v1.13开始引入。

  • kube-public:此命名空间的资源可以被所有人访问(包括未认证用户)。

  • kube-system:所有由kubernetes系统创建的资源都处于这个命名空间。

2.2 应用示例

  • 示例:查看所有的命名空间
1
2
3
4
5
6
7
8
9
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 2d14h
dev Active 39h
kube-node-lease Active 2d14h
kube-public Active 2d14h
kube-system Active 2d14h
kubernetes-dashboard Active 2d14h
test Active 23h
  • 示例:查看指定的命名空间
1
2
3
[root@master ~]# kubectl get ns default
NAME STATUS AGE
default Active 2d14h
  • 示例:指定命名空间的输出格式
1
2
3
[root@master ~]# kubectl get ns default -o wide
NAME STATUS AGE
default Active 2d14h
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
[root@master ~]# kubectl get ns default -o json
{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": {
"creationTimestamp": "2022-05-18T05:17:51Z",
"managedFields": [
{
"apiVersion": "v1",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:status": {
"f:phase": {}
}
},
"manager": "kube-apiserver",
"operation": "Update",
"time": "2022-05-18T05:17:51Z"
}
],
"name": "default",
"resourceVersion": "152",
"selfLink": "/api/v1/namespaces/default",
"uid": "de6edb5b-6b5d-4f5a-a901-f840831bc796"
},
"spec": {
"finalizers": [
"kubernetes"
]
},
"status": {
"phase": "Active"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@master ~]# kubectl get ns default -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2022-05-18T05:17:51Z"
managedFields:

- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:status:
f:phase: {}
manager: kube-apiserver
operation: Update
time: "2022-05-18T05:17:51Z"
name: default
resourceVersion: "152"
selfLink: /api/v1/namespaces/default
uid: de6edb5b-6b5d-4f5a-a901-f840831bc796
spec:
finalizers:
- kubernetes
status:
phase: Active
  • 示例:查看命名空间的详情
1
2
3
4
5
6
7
8
9
[root@master ~]# kubectl describe ns default
Name: default
Labels: <none>
Annotations: <none>
Status: Active #Active表示命名空间正在使用中,Terminating表示正在删除

No resource quota.

No LimitRange resource.
  • 示例:创建命名空间
1
2
3
4
5
6
7
8
9
10
[root@master ~]# kubectl create ns dev
namespace/dev created
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 2d14h
dev Active 45s
kube-node-lease Active 2d14h
kube-public Active 2d14h
kube-system Active 2d14h
kubernetes-dashboard Active 2d14h
  • 示例:删除命名空间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@master ~]# kubectl get ns 
NAME STATUS AGE
default Active 2d14h
dev Active 45s
kube-node-lease Active 2d14h
kube-public Active 2d14h
kube-system Active 2d14h
kubernetes-dashboard Active 2d14h
[root@master ~]# kubectl delete ns dev
namespace "dev" deleted
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 2d15h
kube-node-lease Active 2d15h
kube-public Active 2d15h
kube-system Active 2d15h
kubernetes-dashboard Active 2d14h
  • 示例:命令式对象配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@master ~]# cat ns-dev.yaml 
apiVersion: v1
kind: Namespace
metadata:
name: dev
[root@master ~]# kubectl create -f ns-dev.yaml
namespace/dev created
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 2d15h
dev Active 4s
kube-node-lease Active 2d15h
kube-public Active 2d15h
kube-system Active 2d15h
kubernetes-dashboard Active 2d14h
[root@master ~]# kubectl delete -f ns-dev.yaml
namespace "dev" deleted
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 2d15h
kube-node-lease Active 2d15h
kube-public Active 2d15h
kube-system Active 2d15h
kubernetes-dashboard Active 2d14h

3 Pod

3.1 概述

  • Pod是kubernetes集群进行管理的最小单元,程序要运行必须部署在容器中,而容器必须存在于Pod中。

  • Pod可以认为是容器的封装,一个Pod中可以存在一个或多个容器。

  • kubernetes在集群启动之后,集群中的各个组件也是以Pod方式运行的,可以通过下面的命令查看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-6fcfc67db4-6tdxr 1/1 Running 0 2d15h
coredns-6fcfc67db4-b6m9j 1/1 Running 0 2d15h
etcd-master 1/1 Running 0 2d15h
kube-apiserver-master 1/1 Running 0 2d15h
kube-controller-manager-master 1/1 Running 0 2d15h
kube-flannel-ds-l4trs 1/1 Running 0 2d14h
kube-flannel-ds-lbrnt 1/1 Running 1 2d14h
kube-flannel-ds-xpdl2 1/1 Running 0 2d14h
kube-proxy-d7vxn 1/1 Running 0 2d15h
kube-proxy-gfnq5 1/1 Running 0 2d14h
kube-proxy-x8qgm 1/1 Running 0 2d14h
kube-scheduler-master 1/1 Running 0 2d15h

3.2 语法及应用示例

  • 语法:创建并运行Pod
1
2
3
4
kubectl run (Pod的名称) [参数]
# --image 指定Pod的镜像
# --port 指定端口
# --namespace 指定namespace
  • 示例:在名称为dev的namespace下创建一个Nginx的Pod
1
2
[root@master ~]# kubectl run nginx --image=192.168.20.119/library/nginx:latest --port 80 -n dev
pod/nginx created
  • 语法: 查询所有Pod的基本信息
1
2
3
[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 6s
  • 语法:查看Pod的详细信息
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
45
46
47
48
49
50
51
[root@master ~]# kubectl describe pods -n dev
Name: nginx
Namespace: dev
Priority: 0
Node: node2/192.168.20.124
Start Time: Fri, 20 May 2022 20:29:32 +0000
Labels: run=nginx
Annotations: <none>
Status: Running
IP: 10.244.2.13
IPs:
IP: 10.244.2.13
Containers:
nginx:
Container ID: docker://a524a5ec4c57ed61996ef2e06580cafe19254aa2ed2ac079a07e5e0e1bfda589
Image: 192.168.20.119/library/nginx:latest
Image ID: docker-pullable://192.168.20.119/library/nginx@sha256:416d511ffa63777489af47f250b70d1570e428b67666567085f2bece3571ad83
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Fri, 20 May 2022 20:29:33 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-chm54 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-chm54:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-chm54
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message

---- ------ ---- ---- -------

Normal Scheduled 2m3s default-scheduler Successfully assigned dev/nginx to node2
Normal Pulling 2m2s kubelet, node2 Pulling image "192.168.20.119/library/nginx:latest"
Normal Pulled 2m2s kubelet, node2 Successfully pulled image "192.168.20.119/library/nginx:latest"
Normal Created 2m2s kubelet, node2 Created container nginx
Normal Started 2m2s kubelet, node2 Started container nginx
  • 语法:Pod的访问
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
[root@master ~]# kubectl get pods -o wide -n dev
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 3m18s 10.244.2.13 node2 <none> <none>
[root@master ~]# curl 10.244.2.13:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
  • 语法:删除指定的Pod
1
2
3
4
[root@master ~]# kubectl delete pods nginx -n dev
pod "nginx" deleted
[root@master ~]# kubectl get pods -n dev
No resources found in dev namespace.
  • 示例:命令式对象配置
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
[root@master ~]# cat pod-nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:

- image: 192.168.20.119/library/nginx:latest
imagePullPolicy: IfNotPresent
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
[root@master ~]# kubectl create -f pod-nginx.yaml
pod/nginx created
[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 6s
[root@master ~]# kubectl delete -f pod-nginx.yaml
pod "nginx" deleted
[root@master ~]# kubectl get pods -n dev
No resources found in dev namespace.

4 Label

4.1 概述

  • Label是kubernetes的一个重要概念。它的作用就是在资源上添加标识,用来对它们进行区分和选择。

  • Label的特点:

    • 一个Label会以key/value键值对的形式附加到各种对象上,如Node、Pod、Service等。
    • 一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上去。
    • Label通常在资源对象定义时确定,当然也可以在对象创建后动态的添加或删除。
  • 可以通过Label实现资源的多纬度分组,以便灵活、方便地进行资源分配、调度、配置和部署等管理工作。

一些常用的Label标签示例如下:

  • 版本标签:“version”:”release”,”version”:”stable”。。。

  • 环境标签:“environment”:”dev”,“environment”:”test”,“environment”:”pro”。。。

  • 架构标签:“tier”:”frontend”,”tier”:”backend”。。。

  • 标签定义完毕之后,还要考虑到标签的选择,这就要用到Label Selector,即:

    • Label用于给某个资源对象定义标识。
    • Label Selector用于查询和筛选拥有某些标签的资源对象。
  • 当前有两种Label Selector:

    • 基于等式的Label Selector。
      • name=slave:选择所有包含Label中的key=“name”并且value=“slave”的对象。
      • env!=production:选择所有包含Label中的key=“env”并且value!=“production”的对象。
    • 基于集合的Label Selector。
      • name in (master,slave):选择所有包含Label中的key=“name”并且value=“master”或value=“slave”的对象。
      • name not in (master,slave):选择所有包含Label中的key=“name”并且value!=“master”和value!=“slave”的对象。
  • 标签的选择条件可以使用多个,此时将多个Label Selector进行组合,使用逗号(,)进行分隔即可。

    • name=salve,env!=production。
    • name not in (master,slave),env!=production。

4.2 语法及应用示例

  • 语法:为资源打标签
1
2
3
4
5
[root@master ~]# kubectl label pod nginx version=2.0 -n dev
pod/nginx labeled
[root@master ~]# kubectl get pods -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 13m version=2.0
  • 语法:更新资源的标签
1
2
3
4
5
[root@master ~]# kubectl label pod nginx version=3.0 -n dev --overwrite
pod/nginx labeled
[root@master ~]# kubectl get pods -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 15m version=3.0
  • 示例:显示Nginx的Pod的标签
1
2
3
[root@master ~]# kubectl get pods -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 15m version=3.0
  • 语法:筛选标签
1
2
3
[root@master ~]# kubectl get pods -l version=3.0 -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 16m version=3.0
  • 语法:删除标签
1
2
3
4
5
[root@master ~]# kubectl label pods nginx -n dev version-
pod/nginx labeled
[root@master ~]# kubectl get pods -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 18m <none>
  • 示例:命令式对象配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@master ~]# cat pod-nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
labels:
version: "3.0"
env: "test"
spec:
containers:
- image: 192.168.20.119/library/nginx:latest
imagePullPolicy: IfNotPresent
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
[root@master ~]# kubectl apply -f pod-nginx.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
pod/nginx configured
[root@master ~]# kubectl get pods -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 20m env=test,version=3.0

5 Deployment

5.1 概述

  • 在kubernetes中,Pod是最小的控制单元,但是kubernetes很少直接控制Pod,一般都是通过Pod控制器来完成的。

  • Pod控制器用于Pod的管理,确保Pod资源符合预期的状态,当Pod的资源出现故障的时候,会尝试进行重启或重建Pod。

  • 在kubernetes中Pod控制器的种类有很多,本章节只介绍一种:Deployment。

5.2 语法及应用示例

特别注意:在v1.18版之后,kubectl run nginx –image=nginx –replicas=2 –port=80,会反馈Flag –replicas has been deprecated, has no effect and will be removed in the future,并且只会创建一个Nginx容器实例。

  • 示例:在名称为test的命名空间下创建名为nginx的deployment
1
2
3
4
5
6
7
[root@master ~]# kubectl create ns test
namespace/test created
[root@master ~]# kubectl create deploy nginx --image=192.168.20.119/library/nginx:latest -n test
deployment.apps/nginx created
[root@master ~]# kubectl get deploy -n test
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 18s
  • 示例:在名称为test的命名空间下根据名为nginx的deployment创建3个Pod
1
2
3
4
5
6
7
[root@master ~]# kubectl scale deploy nginx --replicas=3 -n test
deployment.apps/nginx scaled
[root@master ~]# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
nginx-56669589d9-h67ng 1/1 Running 0 3s
nginx-56669589d9-l2vb5 1/1 Running 0 3s
nginx-56669589d9-lmp9k 1/1 Running 0 2m55s
  • 语法:命令式对象配置
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
[root@master ~]# cat deploy-nginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- image: 192.168.20.119/library/nginx:latest
name: nginx
ports:
- containerPort: 80
protocol: TCP
[root@master ~]# kubectl create -f deploy-nginx.yaml
deployment.apps/nginx created
[root@master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx-85dbb646-fqft8 1/1 Running 0 3s
nginx-85dbb646-lnhjp 1/1 Running 0 3s
nginx-85dbb646-w4pjb 1/1 Running 0 3s
[root@master ~]# kubectl get deploy -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 46s
  • 示例:查看名为dev的namespace下的名为nginx的deployment的详细信息
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
[root@master ~]# kubectl describe deploy nginx -n dev
Name: nginx
Namespace: dev
CreationTimestamp: Fri, 20 May 2022 22:59:19 +0000
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=nginx
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: run=nginx
Containers:
nginx:
Image: 192.168.20.119/library/nginx:latest
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason

---- ------ ------

Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-85dbb646 (3/3 replicas created)
Events:
Type Reason Age From Message

---- ------ ---- ---- -------

Normal ScalingReplicaSet 2m17s deployment-controller Scaled up replica set nginx-85dbb646 to 3
  • 示例:删除名为dev的namespace下的名为nginx的deployment
1
2
3
4
[root@master ~]# kubectl delete deploy nginx -n dev
deployment.apps "nginx" deleted
[root@master ~]# kubectl get pods -n dev
No resources found in dev namespace.

6 Service

6.1 概述

  • 我们已经能够利用Deployment来创建一组Pod来提供具有高可用性的服务,虽然每个Pod都会分配一个单独的Pod的IP地址,但是却存在如下的问题:

    • Pod的IP会随着Pod的重建产生变化。
    • Pod的IP仅仅是集群内部可见的虚拟的IP,外部无法访问。
  • 这样对于访问这个服务带来了难度,因此,kubernetes设计了Service来解决这个问题。

  • Service可以看做是一组同类的Pod对外的访问接口,借助Service,应用可以方便的实现服务发现和负载均衡。

6.2 语法及应用示例

6.2.1 创建集群内部可访问的Service

  • 示例:暴露名为test的namespace下的名为nginx的deployment,并设置服务名为svc-nginx1
1
2
[root@master ~]# kubectl expose deploy nginx --name=svc-nginx1 --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx1 exposed
  • 示例:查看名为test的命名空间的所有Service
1
2
3
[root@master ~]# kubectl get svc -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx1 ClusterIP 10.103.119.55 <none> 80/TCP 20s run=nginx

6.2.2 创建集群外部可访问的Service

  • 示例:暴露名为test的namespace下的名为nginx的deployment,并设置服务名为svc-nginx2
1
2
[root@master ~]# kubectl expose deploy nginx --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev
service/svc-nginx2 exposed
  • 示例:查看名为test的命名空间的所有Service
1
2
3
4
[root@master ~]# kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx1 ClusterIP 10.103.119.55 <none> 80/TCP 37m
svc-nginx2 NodePort 10.105.235.109 <none> 80:30763/TCP 12s

6.2.3 删除服务

  • 示例:删除服务
1
2
3
4
5
[root@master ~]# kubectl delete svc svc-nginx1 -n dev
service "svc-nginx1" deleted
[root@master ~]# kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx2 NodePort 10.105.235.109 <none> 80:30763/TCP 3m35s

6.2.4 对象配置方式

  • 示例:对象配置方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@master ~]# cat svc-nginx.yaml 
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: dev
spec:
clusterIP: 10.109.179.231
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: nginx
type: ClusterIP
[root@master ~]# kubectl create -f svc-nginx.yaml
service/svc-nginx created
[root@master ~]# kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx ClusterIP 10.109.179.231 <none> 80/TCP 12s
svc-nginx2 NodePort 10.105.235.109 <none> 80:30763/TCP 7m20s