命名空间,隔离的作用,也可以把代码隔离开来。
好像分成了一个个的组,各个之间感知不到对方的存在。
#获取到所有的命名空间。
[root@node-1 ~]# kubectl get namespace
NAME STATUS AGE
default Active 11d
ingress-nginx Active 5d16h
kube-node-lease Active 11d
kube-public Active 11d
kube-system Active 11d
[root@node-1 ~]# kubectl get ns
NAME STATUS AGE
default Active 11d
ingress-nginx Active 5d16h
kube-node-lease Active 11d
kube-public Active 11d
kube-system Active 11d
K8S启动会创建名为default的默认命名空间。
如果不指定命令空间,POD、service那么默认都会创建到default命名空间中。
#获取到所有的POD
[root@node-1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 10 8d
nginx-ds-h54bb 1/1 Running 10 8d
nginx-ds-x5lns 1/1 Running 11 8d
tomcat-demo-54cbbcffdb-frhb9 1/1 Running 6 5d12h
[root@node-1 ~]# kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 10 8d
nginx-ds-h54bb 1/1 Running 10 8d
nginx-ds-x5lns 1/1 Running 11 8d
tomcat-demo-54cbbcffdb-frhb9 1/1 Running 6 5d12h
创建命名空间
#创建自己的namespace,namespace本质也是K8S的一种资源,也是通过配置文件来描述的。
[root@node-1 ~]# mkdir deep-in-kubernetes
[root@node-1 ~]# cd deep-in-kubernetes/
[root@node-1 deep-in-kubernetes]# mkdir 1-namespace
[root@node-1 deep-in-kubernetes]# cd 1-namespace
[root@node-1 1-namespace]# cat namespace-dev.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
[root@node-1 1-namespace]# kubectl create -f namespace-dev.yaml
namespace/dev created
[root@node-1 1-namespace]# kubectl get namespace|grep dev
NAME STATUS AGE
dev Active 15s
使用命名空间
命名空间创建出来了,如何使用。在这个命名空间中创建一些内容。
配置
#编辑win10的 C:\Windows\System32\drivers\etc\hosts 文件加入。执行ipconfig /flushdns。
10.0.0.22 web-dev.mooc.com
#三个节点也加入
[root@node-1/2/3 ~ ]# cat /etc/hosts
10.0.0.22 web-dev.mooc.com
[root@node-1 1-namespace]# pwd
/root/deep-in-kubernetes/1-namespace
[root@node-1 1-namespace]# ll
total 12
-rw-r--r-- 1 root root 53 Jun 3 2019 namespace-dev.yaml
drwxr-xr-x 3 root root 4096 Nov 16 16:30 web-dev
-rw-r--r-- 1 root root 869 Nov 16 16:11 web-dev.yaml
[root@node-1 1-namespace]# ll web-dev
total 12
-rw-r--r-- 1 root root 199 Nov 16 15:35 Dockerfile
drwxr-xr-x 2 root root 4096 Nov 16 15:59 ROOT
-rw-r--r-- 1 root root 95 Jan 27 2022 start.sh
[root@node-1 1-namespace]# ll web-dev/ROOT/
total 17472
-rw-r--r-- 1 root root 17887876 Nov 16 15:56 web-demo-1.0-SNAPSHOT.war
[root@node-1 1-namespace]# cat web-dev.yaml
#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-demo
namespace: dev
spec:
selector:
matchLabels:
app: web-demo
replicas: 1
template:
metadata:
labels:
app: web-demo
spec:
hostNetwork: true
nodeName: node-2
containers:
- name: web-demo
image: hub.mooc.com/kubernetes/web:v1
ports:
- containerPort: 8080
---
#service
apiVersion: v1
kind: Service
metadata:
name: web-demo
namespace: dev
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: web-demo
type: ClusterIP
---
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-demo
namespace: dev
spec:
rules:
- host: web-dev.mooc.com
http:
paths:
- path: /
backend:
serviceName: web-demo
servicePort: 80
[root@node-1 web-dev]# cat Dockerfile
FROM hub.mooc.com/kubernetes/tomcat:8.0.51-alpine
COPY ROOT /usr/local/tomcat/webapps/ROOT
COPY start.sh /usr/local/tomcat/bin/start.sh
ENTRYPOINT ["sh" , "/usr/local/tomcat/bin/start.sh"]
[root@node-1 web-dev]# cat start.sh
#!/bin/bash
sh /usr/local/tomcat/bin/startup.sh
tail -f /usr/local/tomcat/logs/catalina.out
[root@node-1 web-dev]# docker build -t web:v1 .
[root@node-1 web-dev]# docker run -it web:v1
[root@node-1 web-dev]# docker tag web:v1 hub.mooc.com/kubernetes/web:v1
[root@node-1 web-dev]# docker push hub.mooc.com/kubernetes/web:v1
[root@node-1 ~ ]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
web v1 0d9200b59e63 46 minutes ago 162MB
hub.mooc.com/kubernetes/web v1 0d9200b59e63 46 minutes ago 162MB
[root@node-1 1-namespace]# kubectl apply -f web-dev.yaml
[root@node-1 configs]# kubectl describe po/web-demo-8689dbf78d-8rtjf -n dev
#docker push到harbor,如果crictl的机器已经有镜像了,那么要先删除,再拉取,否则不能覆盖。用的还是老的镜像。
[root@node-2 ~]# crictl images list -n k8s.io
IMAGE TAG IMAGE ID SIZE
hub.mooc.com/kubernetes/web v1 0d9200b59e63a 94.5MB
[root@node-2 ~]# crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
3d72551265969 0d9200b59e63a 15 minutes ago Running web-demo 0 115d031a54c95
[root@node-1 configs]# kubectl get all -n dev
测试
总结论:总体来说,namespace的隔离其实就是对名字的隔离,而不是物理的隔离,这样设计起来就非常灵活了,让用户可以有更大的空间。
#实验1:是否加命名空间dev的配置对比
[root@node-1 1-namespace]# vimdiff /root/deep-in-kubernetes/1-namespace/web-dev.yaml /root/mooc-k8s-demo/configs/web.yaml
#加dev只能看到dev下的服务。其中的replicaset暂时不用关注。
[root@node-1 configs]# kubectl get all -n dev -o wide
[root@node-1 1-namespace]# kubectl get all -o wide -n default
#实验2:相同命名空间namespace的隔离性
#结论:在同样的命名空间namespace下,通过服务名可以互相访问到。
#启动终端bash
[root@node-1 1-namespace]# kubectl exec -it tomcat-demo-54cbbcffdb-frhb9 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
bash-4.4# ping nginx-ds
#这个名字是可以正常解析到IP的
#说明在同一个命名空间下,POD之间是可以通过名字互相访问的,可以解析到serviceIP,也可以通过serviceIP把最终的结果返回回来,也是没啥问题的。
PING nginx-ds (10.233.188.137): 56 data bytes
64 bytes from 10.233.188.137: seq=0 ttl=64 time=0.088 ms
64 bytes from 10.233.188.137: seq=1 ttl=64 time=0.086 ms
bash-4.4# wget nginx-ds -O idx
#ping这个service服务名,这个名字是可以正常访问并可以下载下来这个
Connecting to nginx-ds (10.233.188.137:80)
idx 100% |***********************************************************************************| 612 0:00:00 ETA
bash-4.4# ls
LICENSE RELEASE-NOTES bin idx lib native-jni-lib webapps
NOTICE RUNNING.txt conf include logs temp work
bash-4.4# cat idx
Welcome to nginx!
#看下DNS设置,搜索范围是default.svc。
bash-4.4# cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 169.254.25.10
options ndots:5
#实验3:不同命名空间namespace的隔离性
#结论:在不同的命名空间namespace下,通过服务名不可以互相访问到,但SERVICEIP(PODIP)是可以互相访问的,没有限制。说明SERVICEIP(PODIP)是跟命名空间无关的。
#实验3.1:测试在不同的命名空间namespace下,通过服务名不可以互相访问到。
#最后要指定命名空间,否则还是会在默认的命名空间下寻找。
[root@node-1 ~]# kubectl exec -it web-demo-7f8fbc77b5-hgq99 bash -n dev
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
#在命名空间dev访问命名空间default的服务失败
bash-4.4# ping tomcat-demo
ping: bad address 'tomcat-demo'
#看下DNS设置,搜索范围是dev.svc。
#命名空间dev和default它们搜索名字的范围是不一样的,所以在名字上是隔离的。
bash-4.4# cat /etc/resolv.conf
search dev.svc.cluster.local svc.cluster.local cluster.local
nameserver 169.254.25.10
options ndots:5
#实验3.2:SERVICEIP(PODIP)是可以互相访问的,没有限制。说明SERVICEIP(PODIP)是跟命名空间无关的。
[root@node-1 ~]# kubectl exec -it web-demo-7f8fbc77b5-hgq99 bash -n dev
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
#访问命名空间default的service的IP
bash-4.4# wget 10.233.215.44
#这里说明,不同命名空间下的serviceIP是可以互相访问的,没有限制。
Connecting to 10.233.215.44 (10.233.215.44:80)
index.html 100% |***********************************************************************************| 11230 0:00:00 ETA
bash-4.4# cat index.html
<title>Apache Tomcat/8.0.51</title>
#访问不同命名空间default的POD的IP,POD的IP是可以互相访问的,没有命名空间限制的。
Connecting to 10.200.139.83 (10.200.139.83:80)
wget: can't open 'index.html': File exists
bash-4.4# wget 10.200.139.85
bash-4.4# wget 10.200.139.85:8080
Connecting to 10.200.139.85:8080 (10.200.139.85:8080)
wget: can't open 'index.html': File exists
命名空间namespace隔离:资源对象隔离
使用kubectl的时候要访问dev下的资源,都需要加上-n dev,那么开发人员只有dev的开发权限的话,每次都要带上-n dev。有什么方法可以让开发人员只能访问到dev资源,并在运行命令的时候不需要加上-n参数呢?
#案例:设置上下文参数
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=admin \
--kubeconfig=kube.kubeconfig
use-context设置默认上下文,在设置上下文时就可以指定命名空间,意思是这个上下文属于某个命名空间,在使用上下文时就可以使用上次设置的上下文,就可以实现对上述设置的某个上下文来访问使用。
但是真正要区分权限的话,让dev的用户没办法看其他namespace的资源,就得使用不同的用户了,那么这里就不能使用admin了。
因为admin这个的用户权限是足够看系统的所有东西的,如果要区分权限,那么就要从用户开始,给不同的用户赋不同的权限。
这块不困难,但这块工作量还是很大的,这里就暂时不讲权限配置了。
这里直接使用admin用户来配置指定不同命名空间的上下文。
#先备份
[root@node-1 ~]# cp .kube/config .kube/config.backup
#执行:设置上下文参数
[root@node-1 ~]# kubectl config set-context ctx-dev --cluster=kubernetes --user=admin --namespace=dev --kubeconfig=/root/.kube/config
Context "ctx-dev" created.
(set-context ctx-dev:设置上下文名称)
(--namespace=dev:指定namespace)
(--kubeconfig=/root/.kube/config:更新这个config文件)
#执行:设置默认上下文
[root@node-1 ~]# kubectl config use-context ctx-dev --kubeconfig=/root/.kube/config Switched to context "ctx-dev".
#测试
#通过上下文的设置,就让当前用户完全沉浸在了dev的命名空间中。
#此时只看到一个dev的POD,这样就是默认的dev的namespace命名空间中。这样现在就不是以前的default命名空间了。这样跟以前-n dev是一样的了。
[root@node-1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-demo-7f8fbc77b5-hgq99 1/1 Running 0 150m
[root@node-1 ~]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
web-demo-7f8fbc77b5-hgq99 1/1 Running 0 150m
[root@node-1 ~]# kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 10 9d
nginx-ds-h54bb 1/1 Running 10 9d
nginx-ds-x5lns 1/1 Running 11 9d
tomcat-demo-54cbbcffdb-frhb9 1/1 Running 6 5d21h
命名空间namespace如何划分
一种常见的方式:环境划分。比如开发环境dev,开发人员可以在dev任意修改和发布服务。test环境只能由管理员去操作,对项目进行部署。
还有一种方式是按照团队/项目这种维度划分,每个团队有资源的资源和空间,每个团队可以在自己的资源空间下做自己想做的事儿。
上述都是是单维度的划分。
本身namespace就是一个字符串,是扁平的结构,没有父子/继承的关系,但是当namespace下的服务特别多的情况,再次去细分,比如某个服务维度太大了,多拆几个子维度的办法呢?
比如:将namespace设计成一定格式的字符串,比如中划线,第一级表示环境,第二级表示项目组。这样实现了多级划分的命名空间的方案。
标题:Kubernetes(九)资源对象(9.1)Namespace---集群的共享与隔离
作者:yazong
地址:https://blog.llyweb.com/articles/2022/11/16/1668614039268.html