YAZONG 我的开源

Kubernetes(九)资源对象(9.1)Namespace---集群的共享与隔离

  , , ,
0 评论0 浏览

命名空间,隔离的作用,也可以把代码隔离开来。

好像分成了一个个的组,各个之间感知不到对方的存在。

image.png

image.png

image.png


#获取到所有的命名空间。
[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

image.png

测试

总结论:总体来说,namespace的隔离其实就是对名字的隔离,而不是物理的隔离,这样设计起来就非常灵活了,让用户可以有更大的空间。

image.png

#实验1:是否加命名空间dev的配置对比

[root@node-1 1-namespace]# vimdiff /root/deep-in-kubernetes/1-namespace/web-dev.yaml  /root/mooc-k8s-demo/configs/web.yaml

image.png

#加dev只能看到dev下的服务。其中的replicaset暂时不用关注。
[root@node-1 configs]# kubectl get all -n dev -o wide

image.png

[root@node-1 1-namespace]# kubectl get all -o wide -n default

image.png

#实验2:相同命名空间namespace的隔离性

#结论:在同样的命名空间namespace下,通过服务名可以互相访问到。

image.png

#启动终端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)是跟命名空间无关的。

image.png

#实验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