本章将介绍如何在kubernetes集群中部署一个nginx服务,并且能够对其访问
Namespace
Namespace是k8s系统中一个非常重要的资源,它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。
默认情况下,k8s集群中的所有的Pod都是可以相互访问的。但是在实际中,可能不想让两个pod之间进行互相访问,那此时就可以将两个pod划分到不同的namespace下。k8s通过集群内部的资源分配到不同的namespace中,可以形成逻辑上的组,以方便不同的组的资源进行隔离使用和管理。
可以通过k8s的授权机制,将不同的namespace交给不同租户进行管理,这样就实现了多租户的资源隔离。此时还能结合k8s的资源配额机制,限定不同租户能占用的资源,例如CPU使用量,内存使用量等,来实现租户可用资源的管理。
k8s在集群启动之后,会默认创建几个namespace
shell
[root@k8s-master ~]# kubectl get ns
NAME STATUS AGE
default Active 11m
kube-node-lease Active 11m
kube-public Active 11m
kube-system Active 11m
查看
shell
#1.查看所有的ns
[root@k8s-master ~]# kubectl get ns
NAME STATUS AGE
default Active 11m
kube-node-lease Active 11m
kube-public Active 11m
kube-system Active 11m
#2.查看指定的ns
[root@k8s-master ~]# kubectl get ns default
NAME STATUS AGE
default Active 18m
#3.输出指定格式-o wide json yaml
[root@k8s-master ~]# kubectl get ns default -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: "2024-11-13T02:30:46Z"
labels:
kubernetes.io/metadata.name: default
name: default
resourceVersion: "206"
uid: b80ba6be-a00f-42e7-868b-9319501d5cf9
spec:
finalizers:
- kubernetes
status:
phase: Active
#4.查看详情
[root@k8s-master ~]# kubectl describe ns default
Name: default
Labels: kubernetes.io/metadata.name=default
Annotations: <none>
Status: Active
No resource quota.
No LimitRange resource.
创建
shell
[root@k8s-master ~]# kubectl create ns dev
namespace/dev created
删除
shell
[root@k8s-master ~]# kubectl delete ns dev
namespace "dev" deleted
配置方式
首先准备一个yaml配置文件,ns-dev.yaml
yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
然后就可以执行对应的创建和删除
shell
#创建
kubectl create -f ns-dev.yaml
#删除
kubectl delete -f ns-dev.yaml
Pod
Pod是k8s集群进行管理的最小单元,程序要运行必须部署在容器中,而容器必须存在Pod中。Pod可以认为是容器的封装,一个Pod中可以存在一个或者多个容器
k8s在集群启动后,集群中的各个组件也都是以Pod方式运行。可以通过下面命令查看
shell
[root@k8s-master ns]# kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-cd8566cf-m7gzh 1/1 Running 0 4h5m
calico-node-2h55h 1/1 Running 0 4h5m
calico-node-586wp 1/1 Running 0 4h5m
calico-node-n5wk7 1/1 Running 0 4h5m
coredns-6d8c4cb4d-66rzr 1/1 Running 0 4h7m
coredns-6d8c4cb4d-8nsnk 1/1 Running 0 4h7m
etcd-k8s-master 1/1 Running 1 4h8m
kube-apiserver-k8s-master 1/1 Running 1 4h8m
kube-controller-manager-k8s-master 1/1 Running 18 4h8m
kube-proxy-2bxnm 1/1 Running 0 4h7m
kube-proxy-qpvzh 1/1 Running 0 4h7m
kube-proxy-tdrjj 1/1 Running 0 4h7m
kube-scheduler-k8s-master 1/1 Running 18 4h8m
创建并运行
k8s没有提供单独运行Pod的命令,都是通过Pod控制器来实现
shell
#命令格式:kubectl run (pod控制器名称)[参数]
#--image 指定pod的镜像
#--port 指定端口
#--namespace 指定namespace
[root@k8s-master ns]# kubectl run nginx --image=nginx:1.17.1 --port=80 --namespace dev
pod/nginx created
查看pod信息
shell
#查看pod基本信息
[root@k8s-master ns]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 22s
#查看pod的详细信息
[root@k8s-master ns]# kubectl get pod -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 4m46s 10.244.169.129 k8s-node2 <none> <none>
[root@k8s-master ns]# kubectl describe pod nginx -n dev
删除指定pod
shell
[root@k8s-master ns]# kubectl delete pod nginx2 -n dev
pod "nginx2" deleted
配置操作
创建一个pod-nginx.yaml
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
spec:
containers:
- image: nginx:1.17.1
imagePullPolicy: IfNotPresent
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
执行对应的创建和删除
shell
#创建
kubectl create -f pod-nginx.yaml
#删除
kubectl delete -f pod-nginx.yaml
Label
Label是k8s中一个重要概念。它的作用就是在资源上添加标识,用来对它们进行区分和选择。
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"或"slave"的对象
name not in (frontend):选择所有包含Label中的key="name"且value不等于"frontend"的对象
标签的选择条件可以使用多个,此时将多个Label Selector进行组合,使用逗号","进行分隔即可。例如:
name=slave,env!=production
name not in (frontend),env!=production
命令方式
shell
#为pod资源打标签
[root@k8s-master pod]# kubectl label pod nginx version=1.0 -n dev
pod/nginx labeled
#为pod资源更新标签
[root@k8s-master pod]# kubectl label pod nginx version=2.0 -n dev --overwrite
pod/nginx labeled
#查看标签
[root@k8s-master pod]# kubectl get pod nginx -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 2m20s version=2.0
#筛选标签
[root@k8s-master pod]# kubectl get pod -n dev -l version=2.0 --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 3m14s version=2.0
[root@k8s-master pod]# kubectl get pod -n dev -l version!=2.0 --show-labels
No resources found in dev namespace.
#删除标签
[root@k8s-master pod]# kubectl label pod nginx -n dev version-
pod/nginx unlabeled
配置方式
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: dev
labels:
version: "3.0"
env: "test"
spec:
containers:
- image: nginx:1.17.1
name: pod
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
更新命令可以是:kubectl apply -f pod-nginx.yaml
Deployment
在k8s中,Pod是最小的控制单元,但是k8s很少直接控制pod,一般都是通过pod控制器来完成的。pod控制器用于pod的管理,确保pod资源符合预期的状态,当pod的资源出现故障时,会尝试进行重启或重建pod.
在k8s中pod控制器的种类有很多,现只介绍Deployment
配置方式
创建一个deployment-nginx.yaml
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx:1.17.1
ports:
- containerPort: 80
protocol: TCP
执行:kubectl create -f deployment-nginx.yaml
shell
#查看deployment的信息
[root@k8s-master deployment]# kubectl get deployment -n dev
NAME READY UP-TO-DATE AVAILABLE AGE
my-deployment 3/3 3 3 2m36s
[root@k8s-master deployment]# kubectl get deploy -n dev -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
my-deployment 3/3 3 3 3m48s my-container nginx:1.17.1 app=my-app
#删除deployment
[root@k8s-master deployment]# kubectl delete deployment my-deployment -n dev
deployment.apps "my-deployment" deleted
Service
虽然每个pod都会分配一个单独的pod ip,然而却存在如下问题:
- pod ip会随着pod的重建产生变化
- pod ip仅仅是集群内可见的虚拟ip,外部无法访问
这样对于访问这个服务带来的难度。因此,k8s设计了service来解决这个问题。
service可以看作是一组同类pod对外访问接口。借助service,应用可以方便地实现服务发现和负载均衡
操作一:创建集群内部可访问的service
暴露service 绑定对应的deployment是解决如果deployment控制的pod如果重建会产生不同的ip不会影响到外部访问
shell
#暴露service
[root@k8s-master deployment]# kubectl expose deploy my-deployment --name=svc-nginx --type=ClusterIP --port=80 --target-port=80 -n dev
service/svc-nginx exposed
#查看service
[root@k8s-master deployment]# kubectl get service -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc-nginx ClusterIP 10.108.254.244 <none> 80/TCP 9s
[root@k8s-master deployment]# kubectl get svc svc-nginx -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx ClusterIP 10.108.254.244 <none> 80/TCP 69s app=my-app
#访问
[root@k8s-master deployment]# curl 10.108.254.244: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>
操作二:创建集群外部也可以访问的Service
shell
#上面创建的Service的type类型为ClusterIP,这个ip地址只在集群内部可访问
#如果需要创建外部也可以访问的Service,需要修改type为NodePort
[root@k8s-master deployment]# kubectl expose deploy my-deployment --name=svc-nginx2 --type=NodePort --port=80 --target-port=80 -n dev
service/svc-nginx2 exposed
#查看
[root@k8s-master deployment]# kubectl get svc -n dev -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
svc-nginx ClusterIP 10.108.254.244 <none> 80/TCP 51m app=my-app
svc-nginx2 NodePort 10.100.160.81 <none> 80:30081/TCP 13s app=my-app
#在集群外通过节点IP:30081访问服务了
http://192.168.225.10:30081/
删除Service
shell
[root@k8s-master deployment]# kubectl delete svc svc-nginx -n dev
service "svc-nginx" deleted
配置方式
创建一个svc-nginx.yaml
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:
app: my-app
type: ClusterIP
执行创建和删除命令
kubectl create -f svc-nginx.yaml
kubectl delete -f svc-nginx.yaml