Article directory
3. Getting Started
This chapter will introduce how to deploy an nginx service in a kubernetes cluster and be able to access it.
3.1 Namespace
Namespace is a very important resource in the kubernetes system. Its main function is to realize resource isolation of multiple environments or resource isolation of multi-tenants .
By default, all Pods in a kubernetes cluster are mutually accessible. But in practice, you may not want to allow two Pods to access each other, then you can divide the two Pods into different namespaces. Kubernetes can form logical "groups" by allocating resources within the cluster to different Namespaces, so as to facilitate the isolated use and management of resources in different groups.
Through the kubernetes authorization mechanism, different namespaces can be handed over to different tenants for management, thus realizing multi-tenant resource isolation. At this time, the resource quota mechanism of kubernetes can also be combined to limit the resources that different tenants can occupy, such as CPU usage, memory usage, etc., to realize the management of tenants' available resources.
3.1.1 Test Pod connectivity between two different namespaces
[root@k8s-master ~]# mkdir manifest
[root@k8s-master ~]# cd manifest
[root@k8s-master manifest]# pwd
/root/manifest
[root@k8s-master manifest]# cat nginx-pod.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: dev
spec:
containers:
- name: nginx-containers
image: busybox:latest
command: ["/bin/sleep","6000"]
---
apiVersion: v1
kind: Pod
metadata:
name: apache # 不指定名称空间就是跑在默认的
spec:
containers:
- name: httpd
image: busybox:latest
command: ["/bin/sleep","6000"]
[root@k8s-master manifest]# kubectl get -n default pod
NAME READY STATUS RESTARTS AGE
apache 1/1 Running 0 19s
[root@k8s-master manifest]# kubectl get -n dev pod
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 25s
[root@k8s-master ~]# kubectl exec --help // 查看帮助命令
# kubectl exec pod-name -c container-name -it -n namespace-name -- /bin/sh
exec 在容器中执行命令
pod-name 指定那个Pod
-c 指定容器名字
-it 交互模式
-n 指定名称空间
-- 固定写法
/bin/sh 进入容器后执行的命令
# 进入 Pod 的 apache
[root@k8s-master manifest]# kubectl exec apache -it -- sh
/ # ls
bin dev etc home lib lib64 proc root sys tmp usr var
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue
link/ether 5e:19:37:e6:3e:5a brd ff:ff:ff:ff:ff:ff
inet 10.244.2.12/24 brd 10.244.2.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::5c19:37ff:fee6:3e5a/64 scope link
valid_lft forever preferred_lft forever
/ #
# 进入 Pod 的nginx-pod
[root@k8s-master manifest]# kubectl exec nginx-pod -i -t -n dev -- sh
/ #
/ # ls
bin dev etc home lib lib64 proc root sys tmp usr var
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue
link/ether 66:d3:72:81:17:00 brd ff:ff:ff:ff:ff:ff
inet 10.244.1.16/24 brd 10.244.1.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::64d3:72ff:fe81:1700/64 scope link
valid_lft forever preferred_lft forever
/ # ping 10.244.2.12
PING 10.244.2.12 (10.244.2.12): 56 data bytes
64 bytes from 10.244.2.12: seq=0 ttl=62 time=1.170 ms
64 bytes from 10.244.2.12: seq=1 ttl=62 time=0.397 ms
64 bytes from 10.244.2.12: seq=2 ttl=62 time=0.743 ms
After the cluster is started, kubernetes will create several namespaces by default
[root@k8s-master ~]# kubectl get namespace
NAME STATUS AGE
default Active 45h # 所有未指定Namespace的对象都会被分配在default命名空间
kube-node-lease Active 45h # 集群节点之间的心跳维护,v1.13开始引入
kube-public Active 45h # 此命名空间下的资源可以被所有人访问(包括未认证用户)
kube-system Active 45h # 所有由Kubernetes系统创建的资源都处于这个命名空间
Let's look at the specific operations of namespace resources:
**Check**
# 1 查看所有的ns 命令:kubectl get ns
[root@k8s-master ~]# kubectl get ns
NAME STATUS AGE
default Active 45h
kube-node-lease Active 45h
kube-public Active 45h
kube-system Active 45h
# 2 查看指定的ns 命令:kubectl get ns ns名称
[root@k8s-master ~]# kubectl get ns default
NAME STATUS AGE
default Active 45h
# 3 指定输出格式 命令:kubectl get ns ns名称 -o 格式参数
# kubernetes支持的格式有很多,比较常见的是wide、json、yaml
[root@k8s-master ~]# kubectl get ns default -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2023-01-08T02:04:00Z"
labels:
kubernetes.io/metadata.name: default
name: default
resourceVersion: "191"
uid: ed84973a-29b4-4286-ae46-d8df5c113334
spec:
finalizers:
- kubernetes
status:
phase: Active
[root@k8s-master ~]#
# 4 查看ns详情 命令:kubectl describe ns ns名称
[root@k8s-master ~]# kubectl describe ns default 或 kubectl describe pod apache
Name: default
Labels: kubernetes.io/metadata.name=default
Annotations: <none>
Status: Active # Active 命名空间正在使用中 Terminating 正在删除命名空间
No resource quota. # Resource Quota 针对namespace做的资源限制
No LimitRange resource. # LimitRange针对namespace中的每个组件做的资源限制
[root@k8s-master inventory]# pwd
/root/inventory
[root@k8s-master inventory]#
[root@k8s-master inventory]# kubectl describe pod apache
Name: apache // Pod 名字
Namespace: default // 在那个名称空间运行
Priority: 0
Service Account: default
Node: k8s-node1/192.168.192.4 // 在那台node节点上运行
Start Time: Fri, 28 Jul 2023 13:23:17 +0800 // 启动时间
Labels: <none>
Annotations: <none>
Status: Running // 现在的状态是Runing
IP: 10.244.1.15 // IP 地址
IPs:
IP: 10.244.1.15
Containers:
httpd:
Container ID: containerd://b7eeb63f0cb390657ad84dd42aa42acd74d56088e17a48b04b1633e1e12ab57a
Image: httpd // 运行那个镜像名
Image ID: // 镜像ID docker.io/library/httpd@sha256:33a91a69517f0642b3e8be5cc8d12f8c1ae245728a83947bfc098376be63c15e
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 28 Jul 2023 13:25:14 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-xmsjx (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-xmsjx:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
[root@k8s-master inventory]#
create
# 创建namespace(创建名称空间)
[root@k8s-master ~]# kubectl create ns dev
namespace/dev created
delete
# 删除namespace(创建名称空间)
[root@k8s-master ~]# kubectl delete ns dev
namespace "dev" deleted
configuration method
First prepare a yaml file: ns-dev.yaml
# 创建一个最简单的名称空间
apiVersion: v1
kind: Namespace
metadata:
name: dev
Then you can execute the corresponding create and delete commands:
Create: kubectl create -f ns-dev.yaml
Delete: kubectl delete -f ns-dev.yaml
3.2 Pod
Pod is the smallest unit of kubernetes cluster management. To run a program, it must be deployed in a container, and the container must exist in the Pod.
Pod can be regarded as the package of containers, and one or more containers can exist in a Pod.
Test a Pod running multiple containers
[root@k8s-master manifest]# cat testpodrun.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx-containers
image: httpd:latest
- name: nginx
image: nginx:latest
[root@k8s-master inventory]# kubectl apply -f test_pod_run.yaml
pod/nginx-pod created
[root@k8s-master ~]# kubectl get pod nginx-pod
NAME READY STATUS RESTARTS AGE
nginx-pod 1/2 CrashLoopBackOff 6 (3m49s ago) 10m
# 使用describe 命令查看nginx-pod 在做些什么事
[root@k8s-master manifest]# kubectl describe pod nginx-pod
After the kubernetes cluster is started, each component in the cluster also runs as a Pod. You can view it with the following command:
[root@k8s-master ~]# kubectl get pod -n kube-system
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-6955765f44-68g6v 1/1 Running 0 2d1h
kube-system coredns-6955765f44-cs5r8 1/1 Running 0 2d1h
kube-system etcd-master 1/1 Running 0 2d1h
kube-system kube-apiserver-master 1/1 Running 0 2d1h
kube-system kube-controller-manager-master 1/1 Running 0 2d1h
kube-system kube-flannel-ds-amd64-47r25 1/1 Running 0 2d1h
kube-system kube-flannel-ds-amd64-ls5lh 1/1 Running 0 2d1h
kube-system kube-proxy-685tk 1/1 Running 0 2d1h
kube-system kube-proxy-87spt 1/1 Running 0 2d1h
kube-system kube-scheduler-master 1/1 Running 0 2d1h
build and run
kubernetes does not provide commands to run Pods individually, they are all implemented through Pod controllers
# 命令格式: kubectl run (pod控制器名称) [参数]
# --image 指定Pod的镜像
# --port 指定端口
# --namespace 指定namespace
[root@k8s-master ~]# kubectl create namespace dev
namespace/dev created
[root@k8s-master ~]# kubectl get namespace
NAME STATUS AGE
default Active 204d
dev Active 7s
kube-flannel Active 204d
kube-node-lease Active 204d
kube-public Active 204d
kube-system Active 204d
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl run nginx --image=nginx:latest --port=80 --namespace dev
pod/nginx created
View pod information
# 查看Pod基本信息
[root@k8s-master ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 29s
# 查看Pod的详细信息
[root@k8s-master ~]# kubectl describe pod nginx -n dev
Name: nginx // Pod 名字
Namespace: dev // 名称空间名字
Priority: 0
Service Account: default
Node: k8s-node1/192.168.192.4
Start Time: Mon, 31 Jul 2023 15:21:53 +0800
Labels: run=nginx
Annotations: <none>
Status: Running // 表示在运行
IP: 10.244.1.18
IPs:
IP: 10.244.1.18
Containers:
nginx:
Container ID: containerd://a9607020f2f7170b104af0f35ec36f3b0f740a1abe9b5c543b114f145b6e0494
Image: nginx:latest
Image ID: docker.io/library/nginx@sha256:67f9a4f10d147a6e04629340e6493c9703300ca23a2f7f3aa56fe615d75d31ca
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Mon, 31 Jul 2023 15:21:56 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-726tm (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-726tm:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m default-scheduler Successfully assigned dev/nginx to k8s-node1
Normal Pulling 119s kubelet Pulling image "nginx:latest"
Normal Pulled 117s kubelet Successfully pulled image "nginx:latest" in 2.32545784s (2.325463331s including waiting)
Normal Created 117s kubelet Created container nginx
Normal Started 117s kubelet Started container nginx
[root@k8s-master ~]#
Access Pods
# 获取podIP
[root@k8s-master ~]# kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 3m38s 10.244.1.18 k8s-node1 <none> <none>
[root@k8s-master ~]#
#访问POD
[root@k8s-master ~]# curl 10.244.1.18
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html {
color-scheme: light dark; }
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>
[root@k8s-master ~]#
Delete the specified Pod
[root@k8s-master ~]# kubectl delete pod nginx -n dev // 删除Pod
pod "nginx" deleted
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get pods -n dev
No resources found in dev namespace.
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get ns
NAME STATUS AGE
default Active 204d
dev Active 6m12s
kube-flannel Active 204d
kube-node-lease Active 204d
kube-public Active 204d
kube-system Active 204d
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl delete namespace dev // 删除名称空间
namespace "dev" deleted
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get ns
NAME STATUS AGE
default Active 204d
kube-flannel Active 204d
kube-node-lease Active 204d
kube-public Active 204d
kube-system Active 204d
[root@k8s-master ~]#
configuration operation
Create a pod-nginx.yaml with the following content:
[root@k8s-master inventory]# pwd
/root/inventory
[root@k8s-master inventory]# cat pod-nginx.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:
- image: nginx:latest
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
[root@k8s-master inventory]#
[root@k8s-master inventory]# kubectl apply -f pod-nginx.yaml
namespace/dev created
pod/nginx created
[root@k8s-master inventory]#
[root@k8s-master inventory]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 14s
[root@k8s-master inventory]#
[root@k8s-master inventory]# kubectl get -f pod-nginx.yaml
NAME STATUS AGE
namespace/dev Active 6m47s
NAME READY STATUS RESTARTS AGE
pod/nginx 1/1 Running 0 6m47s
[root@k8s-master inventory]#
Then you can execute the corresponding create and delete commands:
Create: kubectl create -f pod-nginx.yaml
Delete: kubectl delete -f pod-nginx.yaml
3.3 Label
Label is an important concept in the kubernetes system. Its role is to add identification to resources to distinguish and select them.
Label features:
- A Label will be attached to various objects in the form of key/value key-value pairs, such as Node, Pod, Service, etc.
- A resource object can define any number of Labels, and the same Label can also be added to any number of resource objects
- Label is usually determined when the resource object is defined, of course, it can also be dynamically added or deleted after the object is created
Multi-dimensional grouping of resources can be realized through Label, so that resource allocation, scheduling, configuration, deployment and other management work can be performed flexibly and conveniently.
Some commonly used Label examples are as follows:
- Version tags: "version": "release", "version": "stable"…
- Environment tags: "environment": "dev", "environment": "test", "environment": "prod"
- Schema tags: "tier": "frontend", "tier": "backend"
After the label is defined, the selection of the label must also be considered, which requires the use of the Label Selector, namely:
Label is used to define an identifier for a resource object
Label Selector is used to query and filter resource objects with certain labels
There are currently two Label Selectors:
-
Equation-based Label Selector
name = slave: Select all objects containing key="name" and value="slave" in Label
env != production: select all objects including key="env" in Label and value not equal to "production"
-
Set-based Label Selector
name in (master, slave): Select all objects containing key="name" and value="master" or "slave" in Label
name not in (frontend): Select all objects that contain the key="name" in the Label and the value is not equal to "frontend"
Multiple label selection criteria can be used. In this case, multiple Label Selectors can be combined and separated by commas ",". For example:
name=slave,env!=production
name not in (frontend),env!=production
command mode
[root@k8s-master ~]# kubectl get pods -n dev // 查看名称空间dev中有哪些Pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 1 (39m ago) 4d17h
[root@k8s-master ~]#
# 1.查看是否已有标签
[root@k8s-master ~]# kubectl describe -n dev pods nginx | grep -i labels
Labels: <none>
[root@k8s-master ~]#
# 2.查看是否已有标签
[root@k8s-master ~]# kubectl get pods nginx -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 1 (42m ago) 4d17h <none> // 标签
[root@k8s-master ~]#
# 为pod资源打标签
[root@k8s-master ~]# kubectl label pod nginx app=test -n dev
pod/nginx labeled
[root@k8s-master ~]# kubectl describe -n dev pod nginx | grep -i labels
Labels: app=test
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl label -n dev pod nginx app=test1
error: 'app' already has a value (test), and --overwrite is false
// 需要带 [--overwrite] 不然会报错
# 为pod资源更新标签
[root@k8s-master ~]# kubectl label pod nginx app=test1 -n dev --overwrite
pod/nginx labeled
# 查看标签
[root@k8s-master ~]# kubectl get -n dev pod nginx --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 1 (49m ago) 4d17h app=test1
[root@k8s-master ~]#
# 筛选标签
[root@k8s-master ~]# kubectl get -n dev pod -l app=test1 --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 1 (52m ago) 4d17h app=test1
[root@k8s-master ~]#
# 取反
[root@k8s-master ~]# kubectl get pod -n dev -l app!=test1 --show-labels
No resources found in dev namespace.
#删除标签
[root@k8s-master ~]# kubectl label pod nginx -n dev app-
pod/nginx unlabeled
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get pod nginx -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 1 (54m ago) 4d17h <none>
[root@k8s-master ~]#
configuration method
[root@k8s-master manifest]# cat test.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
version: web
name: httpd
namespace: default
spec:
containers:
- image: httpd:latest
imagePullPolicy: IfNotPresent
name: httpd
ports:
- containerPort: 80
name: httpd-port
hostPort: 8080
protocol: TCP
[root@k8s-master manifest]# kubectl apply -f test.yaml
pod/httpd created
[root@k8s-master manifest]# kubectl get pod httpd --show-labels
NAME READY STATUS RESTARTS AGE LABELS
httpd 1/1 Running 0 101s version=web
Then you can execute the corresponding update command: kubectl apply -f pod-nginx.yaml
3.4 Deployment
In kubernetes, pod is the smallest control unit, but kubernetes seldom directly controls pods, usually through the pod controller. The pod controller is used for pod management to ensure that the pod resources meet the expected state. When the pod resources fail, it will try to restart or rebuild the pod.
There are many types of Pod controllers in kubernetes, and this chapter only introduces one: Deployment.
command operation
# 命令格式: kubectl create deployment 名称 [参数]
# --image 指定pod的镜像
# --port 指定端口
# --replicas 指定创建pod数量
# --namespace 指定namespace
[root@k8s-master ~]# kubectl get namespace
NAME STATUS AGE
default Active 209d
dev Active 4d21h
kube-flannel Active 209d
kube-node-lease Active 209d
kube-public Active 209d
kube-system Active 209d
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl create namespace test // 创建一个名称空间
namespace/test created
[root@k8s-master ~]# kubectl get ns test // 指定查看名称空间
NAME STATUS AGE
test Active 18s
[root@k8s-master ~]#
# 查看[名称空间test] namespace,以yaml格式展示结果
[root@k8s-master ~]# kubectl get ns test -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2023-08-05T05:34:26Z"
labels:
kubernetes.io/metadata.name: test
name: test
resourceVersion: "1093635"
uid: f9ddabdc-d52f-4952-ae39-4fa93cc2751c
spec:
finalizers:
- kubernetes
status:
phase: Active
[root@k8s-master ~]# kubectl get ns test --show-labels
NAME STATUS AGE LABELS
test Active 23m kubernetes.io/metadata.name=test
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl create deployment nginx --image=nginx:latest --port=80 --replicas=4 -n test
deployment.apps/nginx created
# 查看创建的Pod
[root@k8s-master ~]# kubectl get -n test pods
NAME READY STATUS RESTARTS AGE
my-deploy-6648745bcc-7ttcf 1/1 Running 0 3m3s
my-deploy-6648745bcc-vm4vg 1/1 Running 0 3m3s
my-deploy-6648745bcc-x87ng 1/1 Running 0 3m3s
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get -n test pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-deploy-6648745bcc-7ttcf 1/1 Running 0 3m38s 10.244.1.22 k8s-node1 <none> <none>
my-deploy-6648745bcc-vm4vg 1/1 Running 0 3m38s 10.244.2.16 k8s-node2 <none> <none>
my-deploy-6648745bcc-x87ng 1/1 Running 0 3m38s 10.244.2.15 k8s-node2 <none> <none>
[root@k8s-master ~]#
# 查看deployment的信息
[root@k8s-master ~]# kubectl get deploy -n test -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-deploy 3/3 3 3 4m38s nginx nginx:latest app=my-deploy
[root@k8s-master ~]#
# UP-TO-DATE:成功升级的副本数量
# AVAILABLE:可用副本的数量
# 加参数 --show-labels 查看标签
[root@k8s-master ~]# kubectl get deploy -n test --show-labels
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
my-deploy 3/3 3 3 5m53s app=my-deploy
[root@k8s-master ~]# kubectl get pods -n test --show-labels
NAME READY STATUS RESTARTS AGE LABELS
my-deploy-6648745bcc-7ttcf 1/1 Running 0 6m33s app=my-deploy,pod-template-hash=6648745bcc
my-deploy-6648745bcc-vm4vg 1/1 Running 0 6m33s app=my-deploy,pod-template-hash=6648745bcc
my-deploy-6648745bcc-x87ng 1/1 Running 0 6m33s app=my-deploy,pod-template-hash=6648745bcc
[root@k8s-master ~]#
# 查看deployment的详细信息
[root@k8s-master ~]# kubectl describe deployment my-deploy -n test
Name: my-deploy
Namespace: test
CreationTimestamp: Sat, 05 Aug 2023 13:42:53 +0800
Labels: app=my-deploy
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=my-deploy
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: app=my-deploy
Containers:
nginx:
Image: 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: my-deploy-6648745bcc (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 8m58s deployment-controller Scaled up replica set my-deploy-6648745bcc to 3
[root@k8s-master ~]#
# 查看deployment,以yaml 格式展示结果 查看某个pod,以yaml格式展示结果
[root@k8s-master ~]# kubectl get deployment my-deploy -o yaml -n test
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2023-08-05T05:42:53Z"
generation: 1
labels:
app: my-deploy
name: my-deploy
namespace: test
resourceVersion: "1094451"
uid: cf361c04-0c57-46f1-be24-4fc93680c493
spec:
progressDeadlineSeconds: 600
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app: my-deploy
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: my-deploy
spec:
containers:
- image: nginx:latest
imagePullPolicy: Always
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources: {
}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {
}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 3
conditions:
- lastTransitionTime: "2023-08-05T05:43:00Z"
lastUpdateTime: "2023-08-05T05:43:00Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: "2023-08-05T05:42:53Z"
lastUpdateTime: "2023-08-05T05:43:00Z"
message: ReplicaSet "my-deploy-6648745bcc" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 1
readyReplicas: 3
replicas: 3
updatedReplicas: 3
[root@k8s-master ~]#
// 如果要写yaml格式的创建名称空间[namespace]或者是deployment、pod的都是可以手动先创建出来然后执行[kubectl get pod pod_name -o yaml]展示出来后,可以照着展示出来的内容写。
# 删除
[root@k8s-master ~]# kubectl delete -n test deployment my-deploy
deployment.apps "my-deploy" deleted
[root@k8s-master ~]#
configuration operation
Create a deploy-nginx.yaml with the following content:
[root@k8s-master ~]# cd inventory/
[root@k8s-master inventory]#
[root@k8s-master inventory]# cat deploy-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: my-deploy-nginx
name: my-deploy-nginx // Pod 名字叫做:my-deploy-nginx
namespace: test
spec:
replicas: 4 // 在这个Pod下运行4个容器
selector:
matchLabels:
app: my-deploy
template:
metadata:
labels:
app: my-deploy
spec:
containers:
- image: nginx:latest
imagePullPolicy: IfNotPresent // 如果镜像存在本地,不拉取,如果没有存在本地着拉取
name: nginx-containers // Pod 中容器的名称
ports:
- containerPort: 80
protocol: TCP
[root@k8s-master inventory]#
[root@k8s-master inventory]# kubectl apply -f deploy-nginx.yaml
deployment.apps/my-deploy-nginx created
[root@k8s-master inventory]#
[root@k8s-master inventory]# kubectl get -f deploy-nginx.yaml
NAME READY UP-TO-DATE AVAILABLE AGE
my-deploy-nginx 4/4 4 4 17m
[root@k8s-master inventory]# kubectl get -f deploy-nginx.yaml -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-deploy-nginx 4/4 4 4 17m nginx-containers nginx:latest app=my-deploy
[root@k8s-master inventory]#
[root@k8s-master inventory]# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
my-deploy-nginx-6bdd87fd6d-c5sxz 1/1 Running 0 18m
my-deploy-nginx-6bdd87fd6d-cnjrd 1/1 Running 0 18m
my-deploy-nginx-6bdd87fd6d-v8b8z 1/1 Running 0 18m
my-deploy-nginx-6bdd87fd6d-wd25q 1/1 Running 0 18m
[root@k8s-master inventory]#
# 查看deployment的标签[--show-labels]
[root@k8s-master inventory]# kubectl get deploy -n test --show-labels
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
my-deploy-nginx 4/4 4 4 19m app=my-deploy-nginx
[root@k8s-master inventory]#
# 查看Pod的标签[--show-labels]
[root@k8s-master inventory]# kubectl get pods -n test --show-labels
NAME READY STATUS RESTARTS AGE LABELS
my-deploy-nginx-6bdd87fd6d-c5sxz 1/1 Running 0 20m app=my-deploy,pod-template-hash=6bdd87fd6d
my-deploy-nginx-6bdd87fd6d-cnjrd 1/1 Running 0 20m app=my-deploy,pod-template-hash=6bdd87fd6d
my-deploy-nginx-6bdd87fd6d-v8b8z 1/1 Running 0 20m app=my-deploy,pod-template-hash=6bdd87fd6d
my-deploy-nginx-6bdd87fd6d-wd25q 1/1 Running 0 20m app=my-deploy,pod-template-hash=6bdd87fd6d
[root@k8s-master inventory]#
[root@k8s-master ~]# kubectl get -n test pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-deploy-nginx-6bdd87fd6d-c5sxz 1/1 Running 0 29m 10.244.1.24 k8s-node1 <none> <none>
my-deploy-nginx-6bdd87fd6d-cnjrd 1/1 Running 0 29m 10.244.2.18 k8s-node2 <none> <none>
my-deploy-nginx-6bdd87fd6d-v8b8z 1/1 Running 0 29m 10.244.2.17 k8s-node2 <none> <none>
my-deploy-nginx-6bdd87fd6d-wd25q 1/1 Running 0 29m 10.244.1.23 k8s-node1 <none> <none>
[root@k8s-master ~]#
[root@k8s-master ~]# curl 10.244.2.17 // 只能在内部访问
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html {
color-scheme: light dark; }
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>
[root@k8s-master ~]#
You can execute the corresponding create and delete commands:
Create: kubectl create -f deploy-nginx.yaml
Delete: kubectl delete -f deploy-nginx.yaml
3.5 Service
Through the study of the previous chapter, you have been able to use Deployment to create a set of Pods to provide services with high availability.
Although each Pod will be assigned a separate Pod IP, there are two problems as follows:
- Pod IP will change as the Pod is rebuilt
- Pod IP is only a virtual IP visible in the cluster and cannot be accessed externally
This makes it difficult to access the service. Therefore, kubernetes designed Service to solve this problem.
Service can be regarded as an external access interface for a group of Pods of the same type . With Service, applications can easily implement service discovery and load balancing.
Operation 1: Create a Service accessible within the cluster
# 在上面已经使用yaml格式创建了4个容器,使用deployment
[root@k8s-master ~]# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
my-deploy-nginx-6bdd87fd6d-c5sxz 1/1 Running 0 87m
my-deploy-nginx-6bdd87fd6d-cnjrd 1/1 Running 0 87m
my-deploy-nginx-6bdd87fd6d-v8b8z 1/1 Running 0 87m
my-deploy-nginx-6bdd87fd6d-wd25q 1/1 Running 0 87m
[root@k8s-master ~]#
[root@k8s-master ~]# kubectl get deployment -n test // deployment名为:my-deploy-nginx
NAME READY UP-TO-DATE AVAILABLE AGE
my-deploy-nginx 4/4 4 4 90m
[root@k8s-master ~]#
# 默认的名称空间[default]
[root@k8s-master ~]# kubectl get service // 查看当前有那些service服务
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 209d // 系统自带的
[root@k8s-master ~]#
# 查看指定的名称空间[-n 指定查看那个的名称空间]
[root@k8s-master ~]# kubectl get -n test service
No resources found in dev namespace.
[root@k8s-master ~]#
# 暴露Service
[root@k8s-master ~]# kubectl expose deployment my-deploy-nginx --name=svc-my-deploy-nginx --port=80 --target-port=80 --type=ClusterIP -n test
service/svc-my-deploy-nginx exposed
[root@k8s-master ~]#
# 查看service
[root@k8s-master ~]# kubectl get -n test service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-my-deploy-nginx ClusterIP 10.103.51.241 <none> 80/TCP 3m24s
[root@k8s-master ~]#
# 这里产生了一个CLUSTER-IP,这就是service的IP,在Service的生命周期中,这个地址是不会变动的
# 可以通过这个IP访问当前service对应的POD
[root@k8s-master ~]# curl 10.103.51.241:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html {
color-scheme: light dark; }
body {
width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1> # 欢迎使用nginx!
<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>
[root@k8s-master ~]#
Operation 2: Create a Service that can also be accessed outside the cluster
# 上面创建的Service的type类型为ClusterIP,这个ip地址只用集群内部可访问
# 如果需要创建外部也可以访问的Service,需要修改type为NodePort
[root@k8s-master ~]# kubectl expose deployment my-deploy-nginx --name=svc-nginx --port=80 --target-port=80 --type=NodePort -n test
service/svc-nginx exposed
[root@k8s-master ~]#
# 此时查看,会发现出现了NodePort类型的Service,而且有一对Port(80:30044/TC)
[root@k8s-master ~]# kubectl get -n test service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-my-deploy-nginx ClusterIP 10.103.51.241 <none> 80/TCP 14m
svc-nginx NodePort 10.103.113.161 <none> 80:30044/TCP 9s
[root@k8s-master ~]#
# 接下来就可以通过集群外的主机访问 节点IP:30044 访问服务了
# 例如在的电脑主机上通过浏览器访问下面的地址
http://192.168.192.4:30044/ 或者 http://192.168.192.5:30044/
Delete Service
[root@k8s-master ~]# kubectl delete -n test service svc-my-deploy-nginx svc-nginx
service "svc-my-deploy-nginx" deleted
service "svc-nginx" deleted
[root@k8s-master ~]# kubectl get -n test service
No resources found in test namespace.
[root@k8s-master ~]#
configuration method
Create a svc-nginx.yaml with the following content:
[root@k8s-master inventory]# kubectl get pods -n test --show-labels
NAME READY STATUS RESTARTS AGE LABELS
my-deploy-nginx-6bdd87fd6d-c5sxz 1/1 Running 0 3h1m app=my-deploy,pod-template-hash=6bdd87fd6d
my-deploy-nginx-6bdd87fd6d-cnjrd 1/1 Running 0 3h1m app=my-deploy,pod-template-hash=6bdd87fd6d
my-deploy-nginx-6bdd87fd6d-v8b8z 1/1 Running 0 3h1m app=my-deploy,pod-template-hash=6bdd87fd6d
my-deploy-nginx-6bdd87fd6d-wd25q 1/1 Running 0 3h1m app=my-deploy,pod-template-hash=6bdd87fd6d
[root@k8s-master inventory]#
[root@k8s-master ~]# cd inventory/
[root@k8s-master inventory]#
[root@k8s-master inventory]# cat svc-nginx.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: test
spec:
clusterIP: 10.109.179.231 # 固定service的内网IP。也可以不写它自动创建一个IP出来
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: my-deploy # 指定容器标签my-deploy
type: NodePort
[root@k8s-master inventory]#
[root@k8s-master inventory]# kubectl apply -f svc-nginx.yaml
service/svc-nginx created
[root@k8s-master inventory]#
[root@k8s-master inventory]# kubectl get svc -n test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx NodePort 10.109.179.231 <none> 80:30726/TCP 9s
[root@k8s-master inventory]#
[root@k8s-master inventory]# curl 10.109.179.231
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html {
color-scheme: light dark; }
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>
[root@k8s-master inventory]#
# 查看端口没有发现有30726端口,因为这个端口在iptables规则里
[root@k8s-master inventory]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.1:10248 *:*
LISTEN 0 128 127.0.0.1:10249 *:*
LISTEN 0 128 192.168.192.3:2379 *:*
LISTEN 0 128 127.0.0.1:2379 *:*
LISTEN 0 128 192.168.192.3:2380 *:*
LISTEN 0 128 127.0.0.1:2381 *:*
LISTEN 0 128 127.0.0.1:10257 *:*
LISTEN 0 128 127.0.0.1:10259 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 127.0.0.1:43905 *:*
LISTEN 0 128 [::]:10250 [::]:*
LISTEN 0 128 [::]:6443 [::]:*
LISTEN 0 128 [::]:10256 [::]:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 100 [::1]:25 [::]:*
[root@k8s-master inventory]#
[root@k8s-master ~]# iptables -t nat -nvL | grep 30726 // 查看iptables规则
0 0 KUBE-EXT-WUUAWPAQCWK2NLSB tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* test/svc-nginx */ tcp dpt:30726
[root@k8s-master ~]#
# 接下来就可以通过集群外的主机访问 节点IP:30726 访问服务了
# 例如在的电脑主机上通过浏览器访问下面的地址
http://192.168.192.4:30726
You can execute the corresponding create and delete commands:
Create: kubectl create -f svc-nginx.yaml
Delete: kubectl delete -f svc-nginx.yaml
apiVersion: v1
kind: Service
metadata:
name: svc-nginx
namespace: test
spec:
clusterIP: 10.109.179.231
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: my-deploy
type: ClusterIP
summary
So far, you have mastered the basic operations of Namespace, Pod, Deployment, and Service resources. With these operations, you can implement simple deployment and access of a service in a kubernetes cluster, but if you want to use kubernetes better, you need Learn the details and rationale of each of these resources in depth.