CoreDNS 部署及分析

Kubernetes DNS服务基础知识

CoreDNS作用

  • Server实现了POD地址的固定,DNS可以实现访问Server的名称访问到POD(服务发现)
  • 对于一些服务提前不知道Server地址,但是要基于服务配置,就可以直接使用Server的名称,后期只要创建这样名称即可

CoreDNS 部署

  • DNS服务是依赖于server访问,地址就是ClusterIP,需要固定IP(需要和kubelet的参数指定一样–cluster-dns=10.0.0.2)
  • DNS服务基于deployment部署
  • 集群认证问题,k8s-api.json中的host地址必须要有所有的节点和server的kubernetes(kubectl get svc第一个)
  • DNS认证和授权,基于ServiceAccount服务账号
  • DNS需要ConfigMap存储配置文件
  • DNS创建Service需要指定固定IP

集群认证问题

这个认证问题主要是在kube-api阶段创建认证证书的配置中hosts字段的IP地址

cat k8s-api.json
{
    
    
    "CN": "k8s-api",
    "hosts": [
        "192.168.12.2",
        "192.168.12.3",
        "192.168.12.4",
        "192.168.12.5",
        "10.0.0.1",
        "${k8s_res1}",
        "${k8s_res2}"
    ],
    "key": {
    
    
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
    
    
            "C": "CN",
            "L": "SHANGHAI",
            "ST": "SHANGHAI"
        }
    ]
}
#hosts字段里需要加上Server的默认创建的第一个服务,修正之前的通过${k8s_res1}传参,测试根本没用

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server k8s-api.json | cfssljson -bare /opt/etcd/ssl/k8s/k8s-api
scp k8s* [email protected]:/usr/local/k8s/ssl
#重新生成证书,并复制到master节点中替换
systemctl restart kube-apiserver.service
#重启服务

分析为什么要加这个地址,先看下信息
在这里插入图片描述
看下详细信息
在这里插入图片描述
地址和端口就是kube-api服务,这个其实给集群内部POD访问api的方式,而集群外部访问通过master节点地址访问,所有需要10.0.0.1也要有认证权限

DNS认证和授权

ServiceAccount服务账号

用于POD资源容器调用kubenetes API或其他服务,如调度器、控制器等等所使用的服务账号

  • POD默认服务账号,每个pod都会挂载默认命名空间的default服务账号

在这里插入图片描述在这里插入图片描述
挂载点下存在三个文件,ca.crt、namespace、token

  • token:API Server的CA公钥证书,用于Pod中的Process对API Server的服务端数字证书进行校验时使用的
  • ca.ctr:用于token令牌签名
  • namespace:namespace默认服务账号

在这里插入图片描述
POD服务账号的自动化

  • Server Account准入控制器:属于API server的一部分,负责完成命名空间管理资源
    • 如果pod没有设置ServiceAccount,则将ServiceAccount设置为default
    • 确保pod引用的ServiceAccount存在,否则将会拒绝请求。
    • 如果pod不包含任何ImagePullSecrets,则将ServiceAccount的ImagePullSecrets会添加到pod中
    • 为包含API访问的Token的pod添加了一个volume
    • 把volumeSource添加到安装在pod
  • List item

的每个容器中,挂载在/var/run/secrets/kubernetes.io/serviceaccount

  • 令牌控制器:是controller-manager的子组件,完成如下
    • 观察serviceAccount的创建,并创建一个相应的Secret 来允许API访问
    • 观察serviceAccount的删除,并删除所有相应的ServiceAccountToken Secret
    • 观察secret 添加,并确保关联的ServiceAccount存在,并在需要时向secret 中添加一个Token
    • 观察secret 删除,并在需要时对应 ServiceAccount 的关联

kube-controller-manager需要使用–service-account-private-key-file 参数选项将Service Account 密匙(key)文件传递给controller-manager中的Tokencontroller,key用于 Service Account Token签名
kube-apiserver也需要使用–service-account-key-file参数选项将相应的(public key)公匙传递给kube-apiserver ,公钥用于在认证期间验证Token

RBAC授权

2种角色,定义角色

  • role:用于授权单个命名空间
  • clusterrole:用于授权整个集群,全部的命名空间

用户(服务用户或者普通用户)绑定到角色

  • rolebinding:role的绑定
  • clusterrolebinding:clusterrole的绑定

整个CoreDNSyaml文件

CoreDNS配置信息:点击访问

apiVersion: v1
kind: ServiceAccount
metadata:
  name: coredns
  namespace: kube-system
  #创建用于Pod访问的服务账号,指明了命名空间,那么创建Deployment也要指明
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:coredns
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  - services
  - pods
  - namespaces
  verbs:
  - list
  - watch
  #定义集群角色,叫system:coredns,以system一般作为系统使用,为了区分角色功能
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:coredns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:coredns
subjects:
- kind: ServiceAccount
  name: coredns
  namespace: kube-system
  #绑定服务用户到角色
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
    
    
        errors
        health {
    
    
          lameduck 5s
        }
        ready
        kubernetes cluster.local 10.0.0.0/24 {
    
    
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf {
    
    
          max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
    #定义配置文件,方便Pod使用及修改和扩展,官网最后括号旁边STUBDOMAINS需要删除,不然Pod启动失败,提示未知参数
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: coredns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/name: "CoreDNS"
spec:
  # replicas: not specified here:
  # 1. Default is 1.
  # 2. Will be tuned in real time if DNS horizontal auto-scaling is turned on.
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  selector:
    matchLabels:
      k8s-app: kube-dns
  template:
    metadata:
      labels:
        k8s-app: kube-dns
    spec:
      priorityClassName: system-cluster-critical
      serviceAccountName: coredns
      tolerations:
        - key: "CriticalAddonsOnly"
          operator: "Exists"
      nodeSelector:
        beta.kubernetes.io/os: linux
      affinity:
         podAntiAffinity:
           preferredDuringSchedulingIgnoredDuringExecution:
           - weight: 100
             podAffinityTerm:
               labelSelector:
                 matchExpressions:
                   - key: k8s-app
                     operator: In
                     values: ["kube-dns"]
               topologyKey: kubernetes.io/hostname
      containers:
      - name: coredns
        image: coredns/coredns:1.8.0
        imagePullPolicy: IfNotPresent
        resources:
          limits:
            memory: 170Mi
          requests:
            cpu: 100m
            memory: 70Mi
        args: [ "-conf", "/etc/coredns/Corefile" ]
        volumeMounts:
        - name: config-volume
          mountPath: /etc/coredns
          readOnly: true
        ports:
        - containerPort: 53
          name: dns
          protocol: UDP
        - containerPort: 53
          name: dns-tcp
          protocol: TCP
        - containerPort: 9153
          name: metrics
          protocol: TCP
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            add:
            - NET_BIND_SERVICE
            drop:
            - all
          readOnlyRootFilesystem: true
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          timeoutSeconds: 5
          successThreshold: 1
          failureThreshold: 5
        readinessProbe:
          httpGet:
            path: /ready
            port: 8181
            scheme: HTTP
      dnsPolicy: Default
      volumes:
        - name: config-volume
          configMap:
            name: coredns
            items:
            - key: Corefile
              path: Corefile
              #创建Deployment
---
apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  annotations:
    prometheus.io/port: "9153"
    prometheus.io/scrape: "true"
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "CoreDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 10.0.0.2
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP
  - name: metrics
    port: 9153
    protocol: TCP
    #创建Server,暴露端口,指定集群IP

以上的内容只是大致理解整个配置的过程,详细的还需要学习,比如认证和授权,包括Pod的整个操作

配置文件修改及注意点

  1. CLUSTER_DNS_IP:就是kubelet里定义的cluster-dns
  2. CLUSTER_DOMAIN:就是kubelet里定义的cluster-domain,没有最后的点
  3. REVERSE_CIDRS:kubernetes svc 网段,Server的网段
  4. UPSTREAMNAMESERVER:不在 Kubernetes 集群域内的任何查询都将转发到 预定义的解析器 (/etc/resolv.conf)
  5. nodeSelector:节点选择器,这个是要根据需求匹配到希望安装到的节点上
 kubectl get nodes --show-labels 
 #查看节点标签label,以逗号为分隔符K/V形式(=等于号分隔),在配置中使用V的=号变成冒号:
 kubectl label nodes k8s-node1 name=coredns
 kubectl label nodes k8s-node1 name.dns/dns=coredns
 #创建节点标签
  1. replicas::副本默认为1,可以根据需求增加

参考:https://kubernetes.io/zh/docs/tasks/administer-cluster/dns-custom-nameservers/

故障问题

1、确保Pod已经运行正常,注意READY要1/1,如果是0/1说明还是容器没有正常运行
在这里插入图片描述
2、kubectl logs -n kube-system coredns-7cccdb8747-qztnd

通过log日志查看原因

3、kubectl describe pod -n kube-system coredns-7cccdb8747-qztnd

也可以通过describe 查看详细的信息及错误提示

测试

kubectl run -it --image=busybox:1.28.4 --rm --restart=Never bash
#开启一个busybox用于测试
#尝试ping Server的定义的名称ping kubernetes   
#查看域名解析地址和信息nslookup 

CoreDNS是个很好学习K8s的实验,涉及到整个K8s的大部分功能,有些功能自己也还没有学深入,但是对于理解整个K8S有很好的帮助

补充知识

docker exec -it a cat /etc/resolv.conf
nameserver 10.0.0.2
search default.svc.cluster.local. svc.cluster.local. cluster.local. idcos.com
options ndots:5

nameserver:就是coredns的地址,由kubelet指定
search:用于直接访问域名前缀时进行后缀自动补充,search是个列表,比如访问Server的name就能直接访问到Pod,其实后缀是自动补充的
在这里插入图片描述
options:

  1. 如果用户传入的域名是绝对'域名,即域名以.'结尾(如上面的www.baidu.),则查询的仅是该域名
  2. 如果传入的域名是相对'域名,且该域名中包含的.'的数目大于或等于option ndots:${n}命令指定的数,则查询的仅是该域名
  3. 如果传入的域名是相对'域名,且该域名中包含的.'的数目小于option ndots:${n}命令指定的数,依次加上search列表中的后缀,解析出IP为止

猜你喜欢

转载自blog.csdn.net/yangshihuz/article/details/112545836
今日推荐