Kubernetes中的核心机制

1 RBAC访问控制

用户在访问Kubernets集群时都要经过api server作认证、鉴权和准入控制才能访问到对应的资源。

其中**认证(Authentication)**是对用户身份作判断,只有通过的用户才能对集群进行访问,常用方式有

  • https证书认证,基于ca证书
  • http token认证,通过token来识别用户
  • http基本认证,用户名 + 密码认证

**鉴权(Authorization)**就是对用户是否拥有访问特定资源的权利作判断。

准入控制 Admission Control用于拦截请求的一种方式,是权限认证链上的最后一环,对请求API资源对象进行修改和校验。

其中鉴权常用到方式是基于角色的访问控制(Role Based Access Control,RBAC),其中不同的角色 Role对不同的命名空间 namespace访问权限,将用户进行角色绑定 RoleBinding之后,就成为了该角色并且可以访问对应的资源

如下所示为在K8S中使用RBAC进行鉴权的过程

首先创建命名空间roledemo

kubectl create ns roledemo

创建pod,通过参数-n指定分配到空间roledemo

kubectl run nginx --image=nginx -n roledemo

创建角色,如下所示为角色对应的配置文件rbac-role.yaml,

kind: Role
apiVersion: rbac.authorization.k8s.io/vl
metadata:
  namespace: ctnrs
  name: pod-reader
rules:
- apiGroups: [""] 
  resources: [ r,pods ”]
  # 角色只对pod 有 get、list权限
  verbs: ["get", "watch", "list"]
kubectl apply -f rbac-role.yaml

创建角色绑定,通过配置文件role-rolebinding.yaml创建角色绑定

kind: RoleBinding                                
apiVersion: rbac.authorization.k8s.io/vl
metadata:
  name: read-pods
  namespace: roletest
subjects:
- kind: User
  name: lucy
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role 
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f rbac-rolebinding.yaml

最后在指定命名空间查看pod可以返回结果,但是无法查看svc,因为角色没有权限

# 用get命令查看 pod 【有权限】
kubectl get pods -n roledemo
# 用get命令查看svc 【没权限】
kubectl get svc -n roledmeo

在这里插入图片描述

2 Ingress服务管理

在pod部署容器之后,通过NodePort对外暴露服务的 ip + 端口号,从而可以访问到应用。但这样带来的弊端是

  1. 一个应用占用一个端口,容易造成端口号冲突
  2. 服务是有状态的,服务对应到特定pod的端口,当pod挂掉后,新启一个pod还需要再次配置IP和端口号。

因此采用Ingress对所有服务进行统一管理,将域名映射到对应的service,然后再由service统一管理相同的pod
在这里插入图片描述

域名映射

首先创建一个nginx应用,对外暴露端口

# 创建pod
kubectl create deployment web --image=nginx
# 对外暴露端口
kubectl expose deployment web --port=80 --target-port=80 --type:NodePort

接下来需要通过配置文件ingress-con.yaml部署ingress,可以从ingress官网获取该文件,K8S会根据他自动下载和安装好ingress

apiVersion: v1
kind: Namespace
metadata:
  name: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
......
kubectl apply -f ingress-con.yaml

接下来配置ingress的访问规则ingress-http.yaml,如下所示将对example.ctnrs.com/的所有请求映射到名为web到service的80端口

# http
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  # 配置访问的域名
  - host: example.ctnrs.com
    http:
      paths:
      # 要映射的后台应用
      - path: /
        backend:
          serviceName: web
          servicePort: 80
kubectl apply -f ingress-http.yaml

配置完成后就可以通过域名example.ctnrs.com访问容器的nginx服务了。这里如果该域名如果不是真实域名,需要在hosts文件中指定该域名映射的IP地址。

路径重写

通过ingress可以对请求的域名进行重写,例如将example.ctnrs.com/service重新映射到容器内的example.ctnrs.com/nginx

apiVersion: networking.k8s.io/v1
kind: Ingress  
metadata:
  annotations:
  	# 配置路径重写的规则
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: ingress-host-bar
spec:
  ingressClassName: nginx
  rules:
  - host: "hello.atguigu.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-server
            port:
              number: 8000
  - host: "demo.atguigu.com"
    http:
      paths:
      - pathType: Prefix
        # 将路径映射到/nginx
        path: "/nginx(/|$)(.*)"
        backend:
          service:
            name: nginx-demo  ## java,比如使用路径重写,去掉前缀nginx
            port:
              number: 8000

流量限制

ingress还可以对请求路径的流量进行限制。这里的pathType设置匹配路径对模式为精确匹配,即只匹配根路径/,对于/nginx不会匹配到

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-limit-rate
  annotations:
  	# 配置每秒允许一个请求
    nginx.ingress.kubernetes.io/limit-rps: "1"
spec:
  ingressClassName: nginx
  rules:
  - host: "haha.atguigu.com"
    http:
      paths:
      # 路径精确匹配
      - pathType: Exact
        path: "/"
        backend:
          service:
            name: nginx-demo
            port:
              number: 8000

3 包管理工具Helm

之前在进行应用部署的时候都需要通过deployment、service和ingress等配置文件对应用进行设置和部署,当应用过多时,这些yaml配置文件数量将成倍增加并且难以维护和管理。这时就需要一个管理系统对每个应用的配置文件作为整体进行管理。Helm 是一个 Kubernetes 的包管理工具,类似于Linux 下的包管理器 yum/apt 等,可以很方便的将之前打包好的 yaml 文件部署到 K8S 上。

Helm将一系列用于描述 k8s应用的相关资源文件集合称作Chart,并通过命令行工具对应用的Chart进行创建、打包、发 布和管理。一个 chart 被 Helm 运行后将会生成对应的一个release,根据不同的release对应用的版本进行管理,例如更新和回滚等。

3.1 安装配置

只需要从官网下载并解压到指定文件夹即可。首先在官网找到对应版本的下载地址:https://github.com/helm/helm/releases ,通过wget下载该文件,并解压到/usr/bin目录下

wget https://get.helm.sh/helm-vv3.2.1-linux-amd64.tar.gz 

tar zxvf helm-v3.2.1-linux-amd64.tar.gz 
mv linux-amd64/helm /usr/bin/
# 添加镜像源
helm repo add stable http://mirror.azure.cn/kubernetes/charts helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts helm repo update

3.2 部署应用

通过Helm可以很便捷地部署一个k8s应用,首先在仓库中搜索要安装的chart并查看其信息

#查找 chart 
helm search repo weave 

NAME CHART VERSION APP VERSION DESCRIPTION 
aliyun/weave-cloud 0.1.2 Weave Cloud is a add-on to Kubernetes which pro... 
aliyun/weave-scope 0.9.21.6.5 A Helm chart for the Weave Scope cluster visual... 
stable/weave-cloud 0.3.71.4.0 Weave Cloud is a add-on to Kubernetes which pro... 
stable/weave-scope 1.1.101.12.0 A Helm chart for the Weave Scope cluster visual... 
#查看 chart 信息 
helm show chart stable/mysql 

通过install命令安装指定chart,并查看其安装信息

#安装包 
helm install ui stable/weave-scope 

#查看应用 
helm list 
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION 
ui default 12020-05-2817:45:01.696109626 +0800 CST deployed weave-scope-1.1.101.12.0 

# 查看发布状态
helm status ui 
NAME: ui
LAST DEPLOYED: Thu May 2817:45:012020 
NAMESPACE: default 
STATUS: deployed 
REVISION: 1 
NOTES: You should now be able to access the Scope frontend in your web browser, by using kubectl port-forward: kubectl -n default port-forward $(kubectl -n default get endpoints \ ui-weave-scope -o jsonpath='{.subsets[0].addresses[0].targetRef.name}') 8080:4040 then browsing to http://localhost:8080/. For more details on using Weave Scope, see the Weave Scope documentation: https://www.weave.works/docs/scope/latest/introducing/ 

最后修改 service Type: NodePort 暴露端口即可访问 ui

3.3 构建chart

通过以上几步就完成了weave-scope的部署,而我们在使用中一般不会直接部署仓库上下载的chart,而是根据自己的实际需要进行配置,这时我们可以手动对chart包进行构建、打包和发布

首先创建一个chart包 mychart

helm create nginx 

# nginx包的目录结构 
nginx/ 
├── charts 				目录里存放这个 chart 依赖的所有子 chart
├── Chart.yaml 			 用于描述这个 Chart 的基本信息,包括名字、描述信息以及版本等
├── templates 			目录里面存放所有 yaml 模板文件
│ ├── deployment.yaml 
│ ├── _helpers.tpl 		放置模板助手的地方,可以在整个 chart 中重复使用
│ ├── ingress.yaml
│ ├── NOTES.txt 		用于介绍 Chart 帮助信息
│ └── service.yaml 
└── values.yaml 		用于存储 templates 目录中模板文件中用到变量的值

之后编辑Chart的信息

vim nginx/Chart.yaml 

apiVersion: v2 
name: nginx 
description: A Helm chart for Kubernetes 
type: application 
version: 0.1.0 
appVersion: 1.15

其中的values.yaml文件用于存放一些全局的变量,然后在templates中可以读取变量的值,进而利用模板实现动态化地构建chart

vim nginx/values.yaml 

replicas: 3 
image: nginx 
tag: 1.15 
serviceport: 80 
targetport: 80 
label: nginx

之后对配置文件deployment.yaml 和service.yaml进行个性化修改,其中可以通过{{.Values.变量名称}}的方式访问到定义在values.yaml文件中的变量

vim nginx/templates/deployment.yaml 

apiVersion: apps/v1 
kind: Deployment
metadata: 
  labels: 
    app: {{ .Values.label }} 
  name: {{ .Release.Name }} 
spec: 
  replicas: {{ .Values.replicas }} 
  selector: 
    matchLabels: 
      app: {{ .Values.label }} 
  template: 
    metadata: 
      labels: 
        app: {{ .Values.label }} 
    spec: 
      containers: 
      - image: {{ .Values.image }}:{{ .Values.tag }} 
        name: web
vim nginx/templates/service.yaml 

apiVersion: v1 
kind: Service 
metadata: 
  labels: 
    app: {{ .Values.label }} 
  name: {{ .Release.Name }} 
spec: 
  ports: 
  - port: {{ .Values.serviceport }} 
    protocol: TCP 
    targetPort: {{ .Values.targetport }} 
  selector: 
    app: {{ .Values.label }} 
  type: NodePort

最后就可以安装改chart包nginx,作为应用web

helm install web nginx

还可以通过helm对应用的版本进行升级、回滚

# 升级镜像
helm upgrade --set imageTag=1.17 web nginx
# 更新配置
helm upgrade -f values.yaml web nginx 
# 将应用回滚到第一个版本
helm rollback web 1 
# 卸载发行版
helm uninstall web 
# 查看历史版本配置信息 
helm get all --revision 1 web

3.4 模板语法

Helm模板提供了类似于if分支、range循环等功能用于处理更为复杂的模板渲染过程

如下所示使用if根据不同情况进行模板deployment.yaml的渲染

template: 
  metadata: 
    labels:
      app: nginx 
{{ if eq .Values.devops "k8s" }} 
      devops: 123 
{{ else }}
      devops: 456 
{{ end }}

如下所示通过range遍历arr数组中的内容,其中的 .代表当前读取的元素

apiVersion: v1 
kind: ConfigMap 
metadata: 
  name: {{ .Release.Name }} 
data: 
  test: | 
  {{- range .Values.arr }} 
    {{ . }} 
  {{- end }}

其中使用{{.Release.Name}}将 release 的名称插入到模板中。这里的 Release 就是 Helm 的内置对象

5 Secret

Kubernets可以将一些共用的配置文件放在etcd中存储,当其他Pod需要时可以直接从中获取而不必逐个进行手动配置。对于一般的配置文件可以使用Config Map进行存放,而对于涉密内容可以使用Secret。

加密数据如密码等一般存放在Secret文件中,然后让Pod容器以挂载Volume方式进行访问,Secret会对数据进行编码加密从而保证数据安全。

有两种访问Secret内容的方式,一种是直接以变量的形式写入配置文件挂载到Pod;另一种是作为文件的形式挂载到Pod,然后在其中访问该文件

5.1 变量挂载

首先创建加密文件mysecret,如下所示为其配置文件 secret.yaml,可以看到其中有编码后的username和password

apiVersion: vl
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  # 通过变量的形式挂载到pod
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

根据上面的文件创建加密文件mysecret

kubectl create -f secret.yaml

创建容器mypod,在其中通过变量的形式直接应用mysecret中定义的加密数据

apiVersion: vl
kind: Pod
metadata:
   name: mypod
spec:
   containers:
   - name: nginx
     image: nginx
     env:
       - name: SECRET_USERMAME
         valueFrom:
           # 以变量的方式进行挂载username
           secretKeyRef:
             name: mysecret
             key: username
       - name: SECRET_PASSWORD
         valueFrom:
           # 以变量的方式进行挂载password
           secretKeyRef:
             name: mysecret
             key: password

在命令行执行如下命令,可以看到输出变量的内容

# 进入容器内部
kubectl exec -it mypod bash
# 查看变量
echo $SECRET_USERNAME
admin
echo $SECRET PAS9/VORD
If2dle2e67df

如果要删除这个Pod

kubectl delete -f secret-val.yaml

5.2 volume挂载

跟上面相似,首先需要创建好加密文件mysecret

然后根据如下文件创建容器mypod,将加密文件挂载到指定的目录下,这样在容器中就可以在该目录下访问到加密文件的内容

apiVersion: vl
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: nginxj
    image: nginx
    # 将加密文件挂载到/etc/foo目录
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readonly: true
  volumes:
  # 挂载加密文件
  - name: foo
    secret:
      secretName: mysecret
# 进入容器
kubectl exec -it mypod bash
# 查看
ls /etc/foo

在这里插入图片描述

6 ConfigMap

ConfigMap作用是存储不加密的数据到etcd中,然后以变量或数据卷Volume挂载到容器中。例如可以将不需要加密的配置文件放到ConfigMap

例如下面有一个redis的配置文件 redis.properties

redis.port=127.0.0.1
redis.port=6379
redis.password=123456

根据上面的文件创建ConfigMap文件redis-config并进行查看

kubectl create configmap redis-config --from-file=redis.properties
# 查看其详细信息
kubectl describe cm redis-config

Name:         redis-config
Namespace:    default
Labels:       <none>
Annotations:  <none>
Data

redis.properties:
redis.host=127.0.0.1
redis.port=6379
redis.pa$sword=123456
Events: <none>

6.1 Volume数据卷形式挂载

如下所示将上面创建的ConfigMap文件以Volume的形式挂载到指定的目录

apiVersion: vl                          
kind: Pod
metadata:
   name: mypod
spec:
  containers:
    - name: busybox
      image: busybox
      # 以命令行的形式输出挂载文件的内容
      command: [ "/bin/sh","-c", "cat /etc/config/redis.properties" ]
      volumeMounts:
      # 将文件挂载到指定目录
      - name: config-volume
        mountPath: /etc/config
  volumes:
  # 将配置文件redis-config以数据卷的形式进行挂载
    - name: config-volume
      configMap:
        name: redis-config
  restartPolicy: Never

然后使用该yaml文件创建pod,由于配置文件中通过命令行的形式对文件内容进行了输出,通过查看日志信息便可以看到内容

# 创建
kubectl apply -f cm.yaml
# 查看日志
kubectl logs mypod

在这里插入图片描述

6.2 变量挂载

首先创建 ConfigMap文件myconfig,在其中的data字段声明变量信息

apiVersion: vl
kind: ConfigMap
metadata:
  name: myconfig
  namespace: default
data:
  # 声明变量信息
  special.level: info
  special.type: hello

根据上面的配置文件创建ConfigMap

# 创建pod
kubectl apply -f myconfig.yaml

之后在创建Pod的时候就可以变量的形式访问上面ConfigMap中的信息

apiVersion: vl                               
kind: Pod
metadata:
   name: mypod
spec:
  containers:
    - name: busybox
      image: busybox
      command: [ "/bin/sh", "echo $(LEVEL) $(TYPE)"]
      env:
        - name: LEVEL
          valueFrom:
            # 以变量的形式访问ConfigMap中的内容
            configMapKeyRef:
              name: myconfig
              key: special.level
        - name: TYPE
          valueFrom:
            # 以变量的形式访问ConfigMap中的内容
            configMapKeyRef:
              name: myconfig
              key: special.type
  restartPolicy: Never

查看日志输出配置文件中的内容

kubectl logs mypod

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值