上一篇筆記中,我嘗試了使用 k8s 1.6 版本安裝一個最簡單的集羣。這一次,我但願可以增長 node 的數量而且安裝網絡插件,而後配置內部的域名解析功能。html
在起初的設想中,我仍然但願不配置各個組件間的認證,只關心功能的正常運行。但在配置的過程當中發現 pod 中運行的組件若是要和 kube-apiserver 通訊的話,必需要有相關的認證信息,要麼使用 ServiceAccount ,要麼配置 kubeconfig 。那麼在仍然但願安裝所進行的配置最少的狀況下,我選擇在 kube-apiserver 和 kube-controller-manager 之間配置 CA 和一組服務端證書,來支持 ServiceAccount 的正常使用。node
主機名 | IP地址 | 角色 | CPU/內存 |
---|---|---|---|
u16-1 | 192.168.112.148 | master | 2核/2G |
u16-2 | 192.168.112.149 | node | 2核/2G |
u16-3 | 192.168.112.150 | node | 2核/2G |
另外預先規定 clusterIP 使用的網段 10.244.0.0/16,kube-dns 的 service 使用的 IP 爲 10.244.0.10linux
首先仍然是下載 kubernetes 1.6.0 和 對應版本的 etcd,並上傳到服務器。nginx
關閉 swap並在 /etc/fstab 文件中取消掉自動掛載git
sudo swapoff -a # vim /etc/fstab 或者其餘方式
若是系統上安裝了SELinux,須要將其關閉。另外還須要在防火牆上放開下面步驟中全部須要使用的端口,或者關閉防火牆管理軟件,我這裏選擇將ubuntu16.04默認的ufw關閉github
sudo ufw disable
安裝 docker-ce ,這裏我選擇添加阿里雲的源並使用 apt-get 安裝:docker
# step 1: 安裝必要的一些系統工具 sudo apt-get update sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common # step 2: 安裝GPG證書 curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - # Step 3: 寫入軟件源信息 sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" # Step 4: 更新並安裝 Docker-CE sudo apt-get -y update sudo apt-get -y install docker-ce
爲了可以使集羣節點之間、集羣內外可以通訊,須要在 docker 的服務文件 /lib/systemd/system/docker.service 的 [Service] 段中添加下面內容,含義爲在啓動 docker 以後,修改 FORWARD 鏈的默認規則爲 ACCEPT。ubuntu
ExecStartPost=/sbin/iptables -P FORWARD ACCEPT
在 /etc/hosts 中配置各個節點的解析,若是這裏不配置節點之間可能沒法經過 node 的 name 互相找到。vim
# 添加以下幾行 192.168.112.148 u16-1 192.168.112.149 u16-2 192.168.112.150 u16-3
tar xf etcd-v3.0.14-linux-amd64.tar.gz # 把解壓後的 etcd 和 etcdctl 複製到 /usr/bin 目錄下 sudo cp etcd-v3.0.14-linux-amd64/etcd{,ctl} /usr/bin/ # 建立 etcd 工做路徑和配置存放路徑 sudo mkdir /var/lib/etcd/ sudo mkdir /etc/etcd/ # 而後建立管理腳本 /lib/systemd/system/etcd.service 和配置文件 /etc/etcd/etcd.conf。內容以下 cat /lib/systemd/system/etcd.service [Unit] Description=Etcd Server After=network.target [Service] Type=notify WorkingDirectory=/var/lib/etcd/ EnvironmentFile=-/etc/etcd/etcd.conf ExecStart=/usr/bin/etcd $ETCD_ARGS [Install] WantedBy=multi-user.target cat /etc/etcd/etcd.conf ETCD_ARGS="--listen-client-urls 'http://192.168.112.148:2379' --advertise-client-urls 'http://192.168.112.148:2379'" # 啓動並設置爲開機自啓動 sudo systemctl daemon-reload sudo systemctl start etcd sudo systemctl enable etcd # 完成後能夠檢查一下服務是否正常運行 systemctl status etcd # 也可使用 etcdctl 來檢查 etcd 健康情況 etcdctl --endpoints http://192.168.112.148:2379 cluster-health member 8e9e05c52164694d is healthy: got healthy result from http://192.168.112.148:2379 cluster is healthy
這裏並無像上一篇筆記中那樣使用默認配置讓 etcd 只監聽本地迴環的 2379 端口,由於如今除了 kube-apiserver 以外各個 node 上運行 flanneld 也須要使用 etcd ,因此選擇監聽了本機IP的 2379 端口。api
參數說明:
--listen-client-urls 指定要監聽客戶端流量的URL列表,也就是對客戶端開放的地址和端口。
--advertise-client-urls 指定向客戶端告知的URL列表。
tar xf kubernetes-server-linux-amd64.tar.gz # 將 kube-apiserver、kube-controller-manager 和 kube-scheduler 的二進制文件複製到 /usr/bin 目錄下 sudo cp kubernetes/server/bin/kube-{apiserver,controller-manager,scheduler} /usr/bin/ # 順帶把 kubectl 也放在系統 PATH 中 sudo cp kubernetes/server/bin/kubectl /usr/bin # 建立日誌存放目錄和配置存放目錄 sudo mkdir /var/log/kubernetes sudo mkdir /etc/kubernetes
下面須要建立 apiserver 與 controller-manager 之間認證所須要的證書。
# 這裏我準備使用 easy-rsa 工具生成證書。先下載 easy-rsa curl -L -O https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz tar xf easy-rsa.tar.gz cd easy-rsa-master/easyrsa3/ # 初始化工具 ./easyrsa init-pki # 建立根證書(CA) ./easyrsa --batch "--req-cn=192.168.112.148@`date +%s`" build-ca nopass # 建立服務端證書和祕鑰,這裏的 IP 一個是 master 所在 host 的 IP,另外一個是 apiserver 的 clusterIP ./easyrsa --subject-alt-name="IP:192.168.112.148,IP:10.244.0.1" build-server-full server nopass # 建立證書存放目錄並把須要的證書及祕鑰複製 sudo mkdir /etc/kubernetes/pki sudo cp pki/ca.crt pki/issued/server.crt pki/private/server.key /etc/kubernetes/pki
而後建立管理腳本 /lib/systemd/system/kube-apiserver.service 和配置文件 /etc/kubernetes/apiserver
cat /lib/systemd/system/kube-apiserver.service [Unit] Description=Kubernetes API Server After=etcd.service Wants=etcd.service [Service] EnvironmentFile=/etc/kubernetes/apiserver ExecStart=/usr/bin/kube-apiserver $KUBE_API_ARGS Restart=on-failure Type=notify LimitNOFILE=65536 [Install] WantedBy=multi-user.target cat /etc/kubernetes/apiserver KUBE_API_ARGS="--storage-backend=etcd3 \ --etcd-servers=http://192.168.112.148:2379 \ --insecure-bind-address=0.0.0.0 \ --insecure-port=8080 \ --service-cluster-ip-range=10.244.0.0/16 \ --service-node-port-range=1-65535 \ --admission_control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \ --client-ca-file=/etc/kubernetes/pki/ca.crt \ --tls-cert-file=/etc/kubernetes/pki/server.crt \ --tls-private-key-file=/etc/kubernetes/pki/server.key \ --logtostderr=false \ --log-dir=/var/log/kubernetes \ --v=2" # 啓動並設置爲開機自啓動 sudo systemctl daemon-reload sudo systemctl start kube-apiserver sudo systemctl enable kube-apiserver
kube-apiserver 的參數說明:
--service-cluster-ip-range :指定集羣 Cluster IP 網段。由於但願使用 10.244.0.0/16 做爲使用的網段,因此在這裏指定。
--admission_control :Kubernetes 集羣的准入控制設置,各控制模塊以插件形式依次生效。由於 pod 中運行的插件須要使用 serviceaccount ,因此此次不刪除 ServiceAccount 模塊。
--client-ca-file :指定CA根證書文件
--tls-cert-file :指定服務端證書文件
--tls-private-key-file :指定服務端私鑰文件
上一步已經將須要的二進制可執行文件和證書祕鑰放在相應的位置了,下面須要建立管理腳本 /lib/systemd/system/kube-controller-manager.service 和 配置文件 /etc/kubernetes/controller-manager
cat /lib/systemd/system/kube-controller-manager.service [Unit] Description=Kubernetes Controller Manager After=kube-apiserver.service Requires=kube-apiserver.service [Service] EnvironmentFile=/etc/kubernetes/controller-manager ExecStart=/usr/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target cat /etc/kubernetes/controller-manager KUBE_CONTROLLER_MANAGER_ARGS="--master=http://192.168.112.148:8080 \ --service-account-private-key-file=/etc/kubernetes/pki/server.key \ --root-ca-file=/etc/kubernetes/pki/ca.crt \ --logtostderr=false \ --log-dir=/var/log/kubernetes \ --v=2"
kube-controller-manager 參數說明:
--service-account-private-key-file :指定服務端私鑰。用於簽署 serviceaccount 的 token。
--root-ca-file :指定 ca 跟證書文件。配置了此項後,ca證書將被包含在 serviceaccount 中,而後就可使用 serviceaccount 認證 組件與apiserver 間的通信。
啓動並設置爲開機自啓動
sudo systemctl daemon-reload sudo systemctl start kube-controller-manager sudo systemctl enable kube-controller-manager
這部分配置與上一篇筆記徹底相同。編輯 systemd 服務文件 /lib/systemd/system/kube-scheduler.service
[Unit] Description=Kubernetes Scheduler Server After=kube-apiserver.service Requires=kube-apiserver.service [Service] EnvironmentFile=/etc/kubernetes/scheduler ExecStart=/usr/bin/kube-scheduler $KUBE_SCHEDULER_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target
環境變量文件 /etc/kubernetes/scheduler 中定義了 kube-scheduler 啓動參數 KUBE_SCHEDULER_ARGS。咱們建立這個文件並填入以下內容
KUBE_SCHEDULER_ARGS="--master=http://192.168.112.148:8080 \ --logtostderr=false \ --log-dir=/var/log/kubernetes \ --v=2"
安裝完 kube-controller-manager 和 kube-scheduler 以後將其啓動並設置爲開機自啓動
sudo systemctl daemon-reload sudo systemctl start kube-scheduler sudo systemctl enable kube-scheduler
以上,master 角色的功能已經安裝完成。下面須要在全部的節點安裝 node 角色的功能。
安裝 kubelet 和 kube-proxy 的過程與上篇筆記基本相同。
tar xf kubernetes-server-linux-amd64.tar.gz # 將 kubelet 和 kube-proxy 的二進制文件複製到 /usr/bin 目錄下 sudo cp kubernetes/server/bin/kube{let,-proxy} /usr/bin/ # 建立 kubelet 的工做路徑 /var/lib/kubelet 、配置文件的存放路徑 /etc/kubernetes 和 日誌路徑 /var/log/kubernetes。master 節點上已經建立過的文件夾則不須要再次建立 sudo mkdir /var/lib/kubelet sudo mkdir /var/log/kubernetes sudo mkdir /etc/kubernetes # 下一步分別建立 kubelet 和 kube-proxy 的管理腳本與配置文件,內容以下 cat /lib/systemd/system/kubelet.service [Unit] Description=Kubernetes Kubelet Server After=docker.service Requires=docker.service [Service] WorkingDirectory=/var/lib/kubelet EnvironmentFile=/etc/kubernetes/kubelet ExecStart=/usr/bin/kubelet $KUBELET_ARGS Restart=on-failure [Install] WantedBy=mulit-user.targe cat /lib/systemd/system/kube-proxy.service [Unit] Description=Kubernetes Kube-Proxy Server After=networking.service Requires=networking.service [Service] EnvironmentFile=/etc/kubernetes/proxy ExecStart=/usr/bin/kube-proxy $KUBE_PROXY_ARGS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target cat /etc/kubernetes/kubelet KUBELET_ARGS="--api-servers=http://192.168.112.148:8080 \ --hostname-override=u16-1 \ --cgroups-per-qos=false \ --enforce-node-allocatable="" \ --logtostderr=false \ --log-dir=/var/log/kubernetes \ --v=2" cat /etc/kubernetes/proxy KUBE_PROXY_ARGS="--master=http://192.168.112.148:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2" # 將這兩個服務啓動並設置爲開機自動啓動 sudo systemctl start kubelet kube-proxy && sudo systemctl enable kubelet kube-proxy
--hostname-override ,設置本節點顯示的名字,須要與/etc/hosts 中的解析對應
wget 下載 flannel 對應版本的二進制程序包,也能夠在 github 上下載。
wget https://github.com/coreos/flannel/releases/download/v0.10.0/flannel-v0.10.0-linux-amd64.tar.gz # 解壓出須要的程序放在 /usr/bin 下 tar xf flannel-v0.10.0-linux-amd64.tar.gz sudo cp flanneld /usr/bin/ sudo cp mk-docker-opts.sh /usr/bin/
建立 systemd 管理腳本 /lib/systemd/system/flanneld.service。內容以下:
cat /lib/systemd/system/flanneld.service [Unit] Description=Flanneld overlay address etcd agent After=network.target Before=docker.service [Service] EnvironmentFile=-/etc/kubernetes/flanneld ExecStart=/usr/bin/flanneld ${FLANNEL_ETCD} ${FLANNEL_OPTIONS} ExecStartPost=/usr/bin/mk-docker-opts.sh -d /run/flannel/docker Type=notify [Install] WantedBy=multi-user.target RequiredBy=docker.service
建立 flanneld 的配置文件:
cat /etc/kubernetes/flanneld FLANNEL_ETCD="-etcd-endpoints=http://192.168.112.148:2379" FLANNEL_ETCD_KEY="/coreos.com/network"
同時還須要修改 /lib/systemd/system/docker.service 。在 After= 和 Requires= 後添加 flanneld.service 。添加環境變量文件 EnvironmentFile=-/run/flannel/docker ,同時在 ExecStart= 後面添加環境變量 DOCKER_OPTS , 好比:ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_OPTS
flannel 網絡插件使用 etcd 存儲和同步信息,在啓動 flanneld 以前首先在 etcd 中設置初始的配置:
etcdctl --endpoints http://192.168.112.148:2379 set /coreos.com/network/config '{ "Network": "10.244.0.0/16" }'
而後就能夠啓動 flanneld 了
sudo systemclt daemon-reload sudo systemctl start flanneld && sudo systemctl enable flanneld # 啓動 flanneld 以後還須要重啓 docker 和 kubelet sudo systemctl restart docker kubelet # 以後查看本機網卡信息,docker0 的 ip 地址已經變爲指定的 ip 段。
下面咱們能夠建立幾個 在不用 node 上運行的 pod 來測試網絡是否已經聯通。
# 仍是先解決基礎鏡像的問題 sudo docker image pull mirrorgooglecontainers/pause-amd64:3.0 sudo docker tag mirrorgooglecontainers/pause-amd64:3.0 gcr.io/google_containers/pause-amd64:3.0 # 而後建立一個 yaml 文件用於配置測試用的資源 cat test.yml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx spec: replicas: 1 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest --- apiVersion: v1 kind: Pod metadata: name: client spec: restartPolicy: OnFailure containers: - name: curl image: appropriate/curl args: - /bin/sh - -c - sleep 6000 # 建立資源 kubectl apply -f test.yml kubectl get pod -o wide # 檢查 NODE 列,由於要測試不一樣 node 上是否能夠互相通訊,因此但願這裏2個 pod 不在一個 node 上。 NAME READY STATUS RESTARTS AGE IP NODE client 1/1 Running 0 2m 10.244.62.2 u16-1 nginx-3406752312-7z5fs 1/1 Running 0 2m 10.244.18.2 u16-2 # 以後進入 client pod 的 容器內測試鏈接 nginx POD 的服務,看是否可以正常訪問。 kubectl exec -it client /bin/sh # 下面爲在容器內操做 curl 10.244.18.2 # 顯示訪問正常 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> …………
我在這裏只嘗試安裝了 kube-dns 插件,但願達到的目標是 k8s 內的容器在建立時都會指定 kube-dns 插件的地址爲 dns 服務器,而且這個 dns 能夠解析集羣建立的 service 的地址。
kube-dns 的安裝是將 kube-dns 做爲一個 deployment 部署,它的 yaml 文件在 k8s 源碼包內。
# 源碼包已經包含在咱們下載的二進制安裝包內了,先解壓 cd kubernetes/ tar xf kubernetes-src.tar.gz cd cluster/addons/dns # 將須要修改的文件複製一份並做出修改,將模板改中的變量改成實際的值 cp kubedns-svc.yaml.sed kubedns-svc.yaml cp kubedns-controller.yaml.sed kubedns-controller.yaml sed -i 's/$DNS_SERVER_IP/10.244.0.10/g' kubedns-svc.yaml sed -i 's/$DNS_DOMAIN/cluster.local/g' kubedns-controller.yaml # 建立 kube-dns 所須要的 configmap、serviceaccount、service和deployment kubectl apply -f kubedns-cm.yaml kubectl apply -f kubedns-sa.yaml --namespace=kube-system # sa 的模板中並無指定 namespace ,其餘模板中指定了,不知道什麼緣由,但我在這裏須要將 serviceaccount 建立在 kube-system 的 namespace 下。 kubectl apply -f kubedns-svc.yaml kubectl apply -f kubedns-controller.yaml # 查看 dns 是否正常運行,這裏 READY 爲 3/3,STATUS 爲 Running 表示運行成功 kubectl get pod -n kube-system
安裝完成 kube-dns 後,還須要在全部 kubelet 的啓動參數中增長下面參數,而後重啓 kubelet。
--cluster-dns=10.244.0.10 --cluster-domain=cluster.local
測試一下功能
# 回到剛纔的 test.yml 所在的目錄,刪除掉剛纔的資源並從新建立 kubectl delete -f test.yml kubectl apply -f test.yml # 再建立文件用於 nginx 的svc cat test-svc.yml apiVersion: v1 kind: Service metadata: name: nginx-svc spec: selector: app: nginx ports: - port: 80 targetPort: 80 protocol: TCP # 建立 svc kubectl apply -f test-svc.yml # 以後進入 client pod 的容器內測試經過 svc 的名字鏈接 nginx POD 的服務,看是否可以正常訪問。 kubectl exec -it client /bin/sh # 下面爲在容器內操做 curl http://nginx-svc <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ………… # 由於此時新部署的pod都已經自動配置了 kube-dns 做爲 dns 服務器。能夠查看 /etc/resolv.conf cat /etc/resolv.conf nameserver 10.244.0.10 search default.svc.cluster.local svc.cluster.local cluster.local localdomain options ndots:5
至此,一個多 node 間的 pod 能夠互相通訊,而且能夠經過 dns 來訪問或者進行服務發現的 k8s 集羣已經部署完成。