为什么要解决这个问题呢?
因为kuberntes中的所有pod都是基于service域名解析后,再负载均衡分发到service后端的各个pod服务中,那么如果没有DNS解析,则无法查到各个服务对应的service服务,以下举个例子。
1.首先上传一个基于centos的工具镜像
[root@server81 registry]# docker push 172.16.5.181:5000/networkbox
The push refers to repository [172.16.5.181:5000/networkbox]
6793eb3b0692: Pushed
4b398ee02e06: Pushed
b91100adb338: Pushed
5f70bf18a086: Pushed
479d1ea9f888: Pushed
latest: digest: sha256:0159b2282815ecd59809dcca4d74cffd5b75a9ca5deec8a220080c254cc43ff2 size: 1987
[root@server81 registry]#
2.创建pod以及svc
[root@server81 test_yaml]# vim networkbox.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: networkbox
labels:
app: networkbox
spec:
replicas: 10
template:
metadata:
labels:
app: networkbox
spec:
terminationGracePeriodSeconds: 60
containers:
- name: networkbox
image: 172.16.5.181:5000/networkbox
apiVersion: v1
kind: Service
metadata:
name: networkbox
labels:
name: networkbox
spec:
ports:
- port: 8008
selector:
name: networkbox
[root@server81 test_yaml]# vim networkbox.yaml
[root@server81 test_yaml]#
[root@server81 test_yaml]# kubectl apply -f networkbox.yaml
deployment.extensions/networkbox configured
service/networkbox unchanged
[root@server81 test_yaml]#
[root@server81 test_yaml]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
networkbox-85bd85cd54-7hsgp 1/1 Terminating 0 1m 10.1.0.196 172.16.5.181
networkbox-85bd85cd54-7sr5f 1/1 Terminating 0 1m 10.1.0.65 172.16.5.87
networkbox-85bd85cd54-9j8cg 1/1 Running 0 1m 10.1.0.194 172.16.5.181
networkbox-85bd85cd54-btcvz 1/1 Terminating 0 1m 10.1.0.198 172.16.5.181
networkbox-85bd85cd54-btmwm 1/1 Terminating 0 1m 10.1.0.200 172.16.5.181
networkbox-85bd85cd54-dfngz 1/1 Terminating 0 1m 10.1.0.197 172.16.5.181
networkbox-85bd85cd54-gp525 1/1 Terminating 0 1m 10.1.0.66 172.16.5.87
networkbox-85bd85cd54-llrw6 1/1 Running 0 1m 10.1.0.193 172.16.5.181
networkbox-85bd85cd54-psh4r 1/1 Running 0 1m 10.1.0.195 172.16.5.181
networkbox-85bd85cd54-zsg8m 1/1 Terminating 0 1m 10.1.0.199 172.16.5.181
[root@server81 test_yaml]#
[root@server81 test_yaml]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.6.1 <none> 443/TCP 1h
networkbox ClusterIP 10.0.6.138 <none> 8008/TCP 1m
[root@server81 test_yaml]#
3.进入networkbox的容器内,ping service域名,确认是否返回IP地址
[root@server81 test_yaml]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.6.1 <none> 443/TCP 1h
networkbox ClusterIP 10.0.6.138 <none> 8008/TCP 1m
[root@server81 test_yaml]#
[root@server81 test_yaml]# kubectl exec -it networkbox-85bd85cd54-9j8cg bash
[root@networkbox-85bd85cd54-9j8cg /]#
[root@networkbox-85bd85cd54-9j8cg /]# ping networkbox
ping: unknown host networkbox
[root@networkbox-85bd85cd54-9j8cg /]#
[root@networkbox-85bd85cd54-9j8cg /]# ping kubernetes
ping: unknown host kubernetes
[root@networkbox-85bd85cd54-9j8cg /]#
可以看出在容器内由于没有kubernetes的DNS服务解析,容器是找不到service的IP地址,那么也就找不到后面的服务了,所以CoreDNS的解析服务是必须要安装好的。
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
kubernetes CLUSTER_DOMAIN REVERSE_CIDRS {
pods insecure
upstream
fallthrough in-addr.arpa ip6.arpa
}FEDERATIONS
prometheus :9153
proxy . UPSTREAMNAMESERVER
cache 30
reload
loadbalance
}STUBDOMAINS
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: coredns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.io/name: "CoreDNS"
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
selector:
matchLabels:
k8s-app: kube-dns
template:
metadata:
labels:
k8s-app: kube-dns
spec:
serviceAccountName: coredns
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
- key: "CriticalAddonsOnly"
operator: "Exists"
containers:
- name: coredns
image: coredns/coredns:1.2.2
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:
- NET_BIND_SERVICE
drop:
- all
readOnlyRootFilesystem: true
livenessProbe:
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
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: CLUSTER_DNS_IP
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
下载deploy.sh部署配置脚本。
#!/bin/bash
# Deploys CoreDNS to a cluster currently running Kube-DNS.
show_help () {
cat << USAGE
usage: $0 [ -r REVERSE-CIDR ] [ -i DNS-IP ] [ -d CLUSTER-DOMAIN ] [ -t YAML-TEMPLATE ] [ -k KUBECONFIG ]
-r : Define a reverse zone for the given CIDR. You may specifcy this option more
than once to add multiple reverse zones. If no reverse CIDRs are defined,
then the default is to handle all reverse zones (i.e. in-addr.arpa and ip6.arpa)
-i : Specify the cluster DNS IP address. If not specificed, the IP address of
the existing "kube-dns" service is used, if present.
-s : Skips the translation of kube-dns configmap to the corresponding CoreDNS Corefile configuration.
USAGE
exit 0
# Simple Defaults
CLUSTER_DOMAIN=cluster.local
YAML_TEMPLATE=`pwd`/coredns.yaml.sed
STUBDOMAINS=""
UPSTREAM=\\/etc\\/resolv\.conf
FEDERATIONS=""
# Translates the kube-dns ConfigMap to equivalent CoreDNS Configuration.
function translate-kube-dns-configmap {
kube-dns-federation-to-coredns
kube-dns-upstreamnameserver-to-coredns
kube-dns-stubdomains-to-coredns
function kube-dns-federation-to-coredns {
fed=$(kubectl -n kube-system get configmap kube-dns -ojsonpath='{.data.federations}' 2> /dev/null | jq . | tr -d '":,')
if [[ ! -z ${fed} ]]; then
FEDERATIONS=$(sed -e '1s/^/federation /' -e 's/^/ /' -e '1i\\' <<< "${fed}") # add federation to the stanza
function kube-dns-upstreamnameserver-to-coredns {
up=$(kubectl -n kube-system get configmap kube-dns -ojsonpath='{.data.upstreamNameservers}' 2> /dev/null | tr -d '[",]')
if [[ ! -z ${up} ]]; then
UPSTREAM=${up}
function kube-dns-stubdomains-to-coredns {
STUBDOMAIN_TEMPLATE='
SD_DOMAIN:53 {
errors
cache 30
proxy . SD_DESTINATION
function dequote {
str=${1#\"} # delete leading quote
str=${str%\"} # delete trailing quote
echo ${str}
function parse_stub_domains() {
sd=$1
# get keys - each key is a domain
sd_keys=$(echo -n $sd | jq keys[])
# For each domain ...
for dom in $sd_keys; do
dst=$(echo -n $sd | jq '.['$dom'][0]') # get the destination
dom=$(dequote $dom)
dst=$(dequote $dst)
sd_stanza=${STUBDOMAIN_TEMPLATE/SD_DOMAIN/$dom} # replace SD_DOMAIN
sd_stanza=${sd_stanza/SD_DESTINATION/$dst} # replace SD_DESTINATION
echo "$sd_stanza"
sd=$(kubectl -n kube-system get configmap kube-dns -ojsonpath='{.data.stubDomains}' 2> /dev/null)
STUBDOMAINS=$(parse_stub_domains "$sd")
# Get Opts
while getopts "hsr:i:d:t:k:" opt; do
case "$opt" in
h) show_help
s) SKIP=1
r) REVERSE_CIDRS="$REVERSE_CIDRS $OPTARG"
i) CLUSTER_DNS_IP=$OPTARG
d) CLUSTER_DOMAIN=$OPTARG
t) YAML_TEMPLATE=$OPTARG
k) KUBECONFIG=$OPTARG
# Set kubeconfig flag if config specified
if [[ ! -z $KUBECONFIG ]]; then
if [[ -f $KUBECONFIG ]]; then
KUBECONFIG="--kubeconfig $KUBECONFIG"
KUBECONFIG=""
# Conditional Defaults
if [[ -z $REVERSE_CIDRS ]]; then
REVERSE_CIDRS="in-addr.arpa ip6.arpa"
if [[ -z $CLUSTER_DNS_IP ]]; then
# Default IP to kube-dns IP
CLUSTER_DNS_IP=$(kubectl get service --namespace kube-system kube-dns -o jsonpath="{.spec.clusterIP}" $KUBECONFIG)
if [ $? -ne 0 ]; then
>&2 echo "Error! The IP address for DNS service couldn't be determined automatically. Please specify the DNS-IP with the '-i' option."
exit 2
if [[ "${SKIP}" -ne 1 ]] ; then
translate-kube-dns-configmap
orig=$'\n'
replace=$'\\\n'
sed -e "s/CLUSTER_DNS_IP/$CLUSTER_DNS_IP/g" \
-e "s/CLUSTER_DOMAIN/$CLUSTER_DOMAIN/g" \
-e "s?REVERSE_CIDRS?$REVERSE_CIDRS?g" \
-e "s@STUBDOMAINS@${STUBDOMAINS//$orig/$replace}@g" \
-e "s@FEDERATIONS@${FEDERATIONS//$orig/$replace}@g" \
-e "s/UPSTREAMNAMESERVER/$UPSTREAM/g" \
"${YAML_TEMPLATE}"
6.配置文件并部署服务
首先第一步要知道集群使用的DNS的IP地址
-e s/CLUSTER_DNS_IP/$CLUSTER_DNS_IP/g
-e s/CLUSTER_DOMAIN/$CLUSTER_DOMAIN/g
-e "s?REVERSE_CIDRS?$REVERSE_CIDRS?g"
$YAML_TEMPLATE
其中REVERSE_CIDRS就是上游的IP地址。
in-addr.arpa ip6.arpa
查看配置在模板yaml文件的位置
REVERSE_CIDRS="10.0.6.0/24" ## 配置 kubernetes svc 网段
CLUSTER_DNS_IP="10.0.6.200" ## 配置 kubernetes DNS IP
CLUSTER_DOMAIN="cluster.local" ## 配置 kubernetes 的域名
YAML_TEMPLATE=$basedir/coredns.yaml.sed ## coredns 的模板yaml文件
## function
function create_coredns_yaml(){
local TEMPLATE=$basedir/coredns.yaml.simple
local YAML=$basedir/coredns.yaml
cat $YAML_TEMPLATE > $TEMPLATE
sed -e s/CLUSTER_DNS_IP/$CLUSTER_DNS_IP/g -e s/CLUSTER_DOMAIN/$CLUSTER_DOMAIN/g -e "s?REVERSE_CIDRS?$REVERSE_CIDRS?g" $TEMPLATE > $YAML
create_coredns_yaml
执行配置脚本,生成部署coreDNS.yaml文件
留下一个问题
在经过上面的一系列部署之后,kuberntes的虚拟集群网络的DNS解析的确是可以的了。但是kubernetes之外的物理机node也是需要DNS解析的,那么该怎么去管理呢?
下面后续一个篇章,我会介绍使用dnsmasq的部署,方便管理kuberntes集群以及多台物理机服务器的DNS统一管理。