k8s有一个很重要的服务特性(服务发现)。一个service被创建,那么这个service的IP和port都可以注入pod使用。
Kubernetes主要支持两种service发现机制:环境变量和DNS。
没有dns服务的时候,kubernetes会采用环境变量的形式,一旦有很多个service,环境变量会变得很复杂,为了解决这个问题,我们使用DNS服务。

root@k8s-master1:/etc/kubeasz# kubectl get pod -o wide
NAME        READY   STATUS    RESTARTS   AGE     IP             NODE        NOMINATED NODE   READINESS GATES
net-test1   1/1     Running   0          6d22h   10.200.218.1   10.0.0.48   <none>           <none>
net-test2   1/1     Running   0          6d22h   10.200.218.2   10.0.0.48   <none>           <none>

我们进入容器ping 另一个容器的IP是可以ping通的 ,但是我无法ping域名
root@k8s-master1:/etc/kubeasz# kubectl exec -it net-test1 sh
/ #ping: bad address 'www.baidu.com'
/ # ping 10.200.218.2
PING 10.200.218.2 (10.200.218.2): 56 data bytes
64 bytes from 10.200.218.2: seq=0 ttl=63 time=0.174 ms

#k8s容器的第一个地址都是被apiserver占用了
root@k8s-master1:/etc/kubeasz# kubectl get svc -A
NAMESPACE   NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
default     kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   6d23h

安装Core-dns (方法1)

  • dns安装有多重方法 有kubedns和coredns ,现在基本都是coredns,因为1.18以后不支持kube-dns
    我们可以进入刚才升级的k8s包里找到kubedns文件

    root@k8s-master1:/etc/kubeasz# cd /usr/local/src/kubernetes/cluster/addons/dns/coredns/
    里面都是官方定义好的模板,稍微修改一下就可以使用

    我们拷贝一到root下面,然后进行修改

    cp coredns.yaml.base /root/

    cd /root/

    root@k8s-master1:~# mv coredns.yaml.base coredns.yaml

  • 定义dns配置文件

    查看部署k8s定义好的集群名称
    

    root@k8s-master1:~# cat /etc/kubeasz/clusters/k8s-01/hosts ‘grep -i “cluster_dns_domain=”
    CLUSTER_DNS_DOMAIN=”yhtzjy.local”

  • 开始编辑dns配置文件 指定dns名称

    root@k8s-master1:~# vim coredns.yaml
    

    kubernetes yhtzjy.local in-addr.arpa ip6.arpa { #定义dns名称
    forward . 223.6.6.6 { #如果解析不了的域名会转发到这个配置文件当中,可以直接转发到阿里解析,默认我们的dns只能解析公司内部 默认配置文件forward . /etc/resolv.conf
    image: 10.0.0.81/baseimages/coredns:1.8.4 #默认镜像是从google下载,可能无法下载,我们可以在网址搜索 ( hub.docker.com )上搜索 coredns/coredns 手动下载
    memory: 512m #内存显示,生产建议在大些
    cpu: 200m #CPU限制
    clusterIP: 10.100.0.2 #定义DNS的service地址

  • 手动下载dns镜像以及上传至我们的harbor服务器

    root@k8s-master1:# docker pull coredns/coredns:1.8.4
    root@k8s-master1:
    # docker tag coredns/coredns:1.8.4 10.0.0.81/baseimages/coredns:1.8.4
    root@k8s-master1:~# docker push 10.0.0.81/baseimages/coredns:1.8.4

  • dns优化方案

  • coredns只负责查询和记录,所以占用CPU 较高,如果网站访问慢,可以优化dns(说明域名解析慢)

    1 、把限制调高,或者主机增加内存和CPU。如果上千个容器至少需要三台coredns 每台服务器配置要求 4C 4G
    2 、宿主机添加缓存,这样也可以增加速度 需要安装 (dnsmasq组件、nodelocaldns 都可以域名解析加速 )

启动dns的yaml文件

root@k8s-master1:~# kubectl apply -f coredns.yaml
- 查看dns是否启动成功
root@k8s-master1:~# kubectl get pod -A'grep -i coredns
kube-system   coredns-6949dff4db-ppt2k                  0/1     Running   0          2m3s
- 如果启动失败就查看日志是什么原因   -n指定namespace   出现Readiness probe failed: HTTP probe failed with statuscode: 503 (代表服务没有启动成功)
root@k8s-master1:~# kubectl describe pod  coredns-6949dff4db-ppt2k -n kube-system

因为没启动,我们删除文件,重建一下,可能是网络问题,或者yaml文件配置错误

root@k8s-master1:~# kubectl delete -f coredns.yaml
root@k8s-master1:~# kubectl apply -f coredns.yaml
root@k8s-master1:~# kubectl get pod -A

安装Core-dns (方法2)

方法1 可能会启动失败,需要换成1.8.3的镜像,可以直接用下面的yaml文件去创建,clusterip 是提前指定的service地址段 10.100.0.0

root@k8s-master1:/opt# cat coredns1.8.3.yml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: coredns
  namespace: kube-system
---
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
  - apiGroups:
    - discovery.k8s.io
    resources:
    - endpointslices
    verbs:
    - list
    - watch
---
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 yhtzjy.local in-addr.arpa ip6.arpa {
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . 223.6.6.6 {
          max_concurrent 1000
        }
        cache 30
        loop
        reload
        loadbalance
    }
---
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:
        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.3
        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
---
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.100.0.2
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP
  - name: metrics
    port: 9153
    protocol: TCP
  • 查看启动成功

    # kubectl apply -f coredns1.8.3.yml
    

    kubectl get pod -A

    kube-system coredns-f97dc456d-wn4js 1/1 Running 0 19s

  • 为了让我们的dns兼容性更好,可以使用官方的脚本,前提是必须dns跑起来才能下载

    进入github  把这个dns克隆下来
    

    root@k8s-master1:/opt# git clone https://github.com/coredns/deployment.git
    root@k8s-master1:/opt# cd deployment/
    root@k8s-master1:/opt/deployment# cd kubernetes/
    root@k8s-master1:/opt/deployment/kubernetes# ./deploy.sh >coredns.1.8.4.yml
    把早期部署好的dns文件删除
    root@k8s-master1:/opt/deployment/kubernetes# kubectl delete -f /opt/coredns1.8.3.yml
    编辑刚生成的文件,地址会自动获取
    kubernetes yhtzjy.local in-addr.arpa ip6.arpa