kubernetes須要存儲不少東西,像它自己的節點信息,組件信息,還有經過kubernetes運行的pod,deployment,service等等。都須要持久化。etcd就是它的數據中心。生產環境中爲了保證數據中心的高可用和數據的一致性,通常會部署最少三個節點。咱們這裏以學習爲主就只在主節點部署一個實例。node
若是你的環境已經有了etcd服務(不論是單點仍是集羣),能夠忽略這一步。前提是你在生成配置的時候填寫了本身的etcd endpoint哦~nginx
etcd的二進制文件和服務的配置咱們都已經準備好,如今的目的就是把它作成系統服務並啓動。docker
#把服務配置文件copy到系統服務目錄 $ cp ~/kubernetes-starter/target/master-node/etcd.service /lib/systemd/system/ #enable服務 $ systemctl enable etcd.service #建立工做目錄(保存數據的地方) $ mkdir -p /var/lib/etcd # 啓動服務 $ service etcd start # 查看服務日誌,看是否有錯誤信息,確保服務正常 $ journalctl -f -u etcd.service $ etcdctl -C http://10.0.94.112:2379 cluster-health member 8e9e05c52164694d is healthy: got healthy result from http://10.0.94.112:2379 cluster is healthy
kube-apiserver是Kubernetes最重要的核心組件之一,主要提供如下的功能api
生產環境爲了保證apiserver的高可用通常會部署2+個節點,在上層作一個lb作負載均衡,好比haproxy。因爲單節點和多節點在apiserver這一層說來沒什麼區別,因此咱們學習部署一個節點就足夠啦安全
APIServer的部署方式也是經過系統服務。部署流程跟etcd徹底同樣,再也不註釋bash
$ cp target/master-node/kube-apiserver.service /lib/systemd/system/ $ systemctl enable kube-apiserver.service $ systemctl daemon-reload $ service kube-apiserver start $ journalctl -f -u kube-apiserver
[Unit]
Description=Kubernetes API Server
...
[Service]
#可執行文件的位置
ExecStart=/home/michael/bin/kube-apiserver \
#非安全端口(8080)綁定的監聽地址 這裏表示監聽全部地址
--insecure-bind-address=0.0.0.0 \
#不使用https
--kubelet-https=false \
#kubernetes集羣的虛擬ip的地址範圍
--service-cluster-ip-range=10.68.0.0/16 \
#service的nodeport的端口範圍限制
--service-node-port-range=20000-40000 \
#不少地方都須要和etcd打交道,也是惟一能夠直接操做etcd的模塊
--etcd-servers=http://192.168.1.102:2379\
...網絡
Controller Manager由kube-controller-manager和cloud-controller-manager組成,是Kubernetes的大腦,它經過apiserver監控整個集羣的狀態,並確保集羣處於預期的工做狀態。 kube-controller-manager由一系列的控制器組成,像Replication Controller控制副本,Node Controller節點控制,Deployment Controller管理deployment等等 cloud-controller-manager在Kubernetes啓用Cloud Provider的時候才須要,用來配合雲服務提供商的控制app
controller-manager、scheduler和apiserver 三者的功能緊密相關,通常運行在同一個機器上,咱們能夠把它們當作一個總體來看,因此保證了apiserver的高可用便是保證了三個模塊的高可用。也能夠同時啓動多個controller-manager進程,但只有一個會被選舉爲leader提供服務。負載均衡
經過系統服務方式部署less
$ cp target/master-node/kube-controller-manager.service /lib/systemd/system/ $ systemctl enable kube-controller-manager.service $ service kube-controller-manager start $ journalctl -f -u kube-controller-manager
[Unit]
Description=Kubernetes Controller Manager
...
[Service]
ExecStart=/home/michael/bin/kube-controller-manager \
#對外服務的監聽地址,這裏表示只有本機的程序能夠訪問它
--address=127.0.0.1 \
#apiserver的url
--master=http://127.0.0.1:8080\
#服務虛擬ip範圍,同apiserver的配置
--service-cluster-ip-range=10.68.0.0/16 \
#pod的ip地址範圍
--cluster-cidr=172.20.0.0/16 \
#下面兩個表示不使用證書,用空值覆蓋默認值
--cluster-signing-cert-file= \
--cluster-signing-key-file= \
...
kube-scheduler負責分配調度Pod到集羣內的節點上,它監聽kube-apiserver,查詢還未分配Node的Pod,而後根據調度策略爲這些Pod分配節點。咱們前面講到的kubernetes的各類調度策略就是它實現的。
經過系統服務方式部署
$ cp target/master-node/kube-scheduler.service /lib/systemd/system/ $ systemctl enable kube-scheduler.service $ service kube-scheduler start $ journalctl -f -u kube-scheduler
[Unit]
Description=Kubernetes Scheduler
...
[Service]
ExecStart=/home/michael/bin/kube-scheduler \
#對外服務的監聽地址,這裏表示只有本機的程序能夠訪問它
--address=127.0.0.1 \
#apiserver的url
--master=http://127.0.0.1:8080\
...
Calico實現了CNI接口,是kubernetes網絡方案的一種選擇,它一個純三層的數據中心網絡方案(不須要Overlay),而且與OpenStack、Kubernetes、AWS、GCE等IaaS和容器平臺都有良好的集成。 Calico在每個計算節點利用Linux Kernel實現了一個高效的vRouter來負責數據轉發,而每一個vRouter經過BGP協議負責把本身上運行的workload的路由信息像整個Calico網絡內傳播——小規模部署能夠直接互聯,大規模下可經過指定的BGP route reflector來完成。 這樣保證最終全部的workload之間的數據流量都是經過IP路由的方式完成互聯的。
calico是經過系統服務+docker方式完成的
$ cp target/all-node/kube-calico.service /lib/systemd/system/ $ systemctl enable kube-calico.service $ service kube-calico start $ journalctl -f -u kube-calico
查看容器運行狀況
$ docker ps CONTAINER ID IMAGE COMMAND CREATED ... 4d371b58928b calico/node:v2.6.2 " start_runit " 3 hours ago...
查看節點運行狀況
$ calicoctl node status Calico process is running. IPv4 BGP status +---------------+-------------------+-------+----------+-------------+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +---------------+-------------------+-------+----------+-------------+ | 192.168.1.103 | node-to-node mesh | up | 13:13:13 | Established | +---------------+-------------------+-------+----------+-------------+ IPv6 BGP status No IPv6 peers found.
查看端口BGP 協議是經過TCP 鏈接來創建鄰居的,所以能夠用netstat 命令驗證 BGP Peer
$ netstat -natp | grep ESTABLISHED | grep 179 tcp 0 0 192.168.1.102:60959 192.168.1.103:179 ESTABLISHED 29680/bird
查看集羣ippool狀況
$ calicoctl get ipPool -o yaml - apiVersion: v1 kind: ipPool metadata: cidr: 172.20.0.0/16 spec: nat-outgoing: true
[Unit]
Description=calico node
...
[Service]
#以docker方式運行
ExecStart=/usr/bin/docker run --net=host --privileged --name=calico-node \
#指定etcd endpoints(這裏主要負責網絡元數據一致性,確保Calico網絡狀態的準確性)
-e ETCD_ENDPOINTS=http://192.168.1.102:2379\
#網絡地址範圍(同上面ControllerManager)
-e CALICO_IPV4POOL_CIDR=172.20.0.0/16 \
#鏡像名,爲了加快你們的下載速度,鏡像都放到了阿里雲上
registry.cn-hangzhou.aliyuncs.com/imooc/calico-node:v2.6.2
kubectl是Kubernetes的命令行工具,是Kubernetes用戶和管理員必備的管理工具。 kubectl提供了大量的子命令,方便管理Kubernetes集羣中的各類功能。
使用kubectl的第一步是配置Kubernetes集羣以及認證方式,包括:
咱們這沒有安全相關的東西,只須要設置好api-server和上下文就好啦:
#指定apiserver地址(ip替換爲你本身的api-server地址) kubectl config set-cluster kubernetes --server=http://10.0.94.112:8080 #指定設置上下文,指定cluster kubectl config set-context kubernetes --cluster=kubernetes #選擇默認的上下文 kubectl config use-context kubernetes
經過上面的設置最終目的是生成了一個配置文件:~/.kube/config,固然你也能夠手寫或複製一個文件放在那,就不須要上面的命令了。
每一個工做節點上都運行一個kubelet服務進程,默認監聽10250端口,接收並執行master發來的指令,管理Pod及Pod中的容器。每一個kubelet進程會在API Server上註冊節點自身信息,按期向master節點彙報節點的資源使用狀況,並經過cAdvisor監控節點和容器的資源。
經過系統服務方式部署,但步驟會多一些,具體以下:
#確保相關目錄存在 $ mkdir -p /var/lib/kubelet $ mkdir -p /etc/kubernetes $ mkdir -p /etc/cni/net.d #複製kubelet服務配置文件 $ cp target/worker-node/kubelet.service /lib/systemd/system/ #複製kubelet依賴的配置文件 $ cp target/worker-node/kubelet.kubeconfig /etc/kubernetes/ #複製kubelet用到的cni插件配置文件 $ cp target/worker-node/10-calico.conf /etc/cni/net.d/ $ systemctl enable kubelet.service $ service kubelet start $ journalctl -f -u kubelet
kubelet.service
[Unit]
Description=Kubernetes Kubelet
[Service]
#kubelet工做目錄,存儲當前節點容器,pod等信息
WorkingDirectory=/var/lib/kubelet
ExecStart=/home/michael/bin/kubelet \
#對外服務的監聽地址
--address=192.168.1.103 \
#指定基礎容器的鏡像,負責建立Pod 內部共享的網絡、文件系統等,這個基礎容器很是重要:K8S每個運行的 POD裏面必然包含這個基礎容器,若是它沒有運行起來那麼你的POD 確定建立不了
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/imooc/pause-amd64:3.0 \
#訪問集羣方式的配置,如api-server地址等
--kubeconfig=/etc/kubernetes/kubelet.kubeconfig \
#聲明cni網絡插件
--network-plugin=cni \
#cni網絡配置目錄,kubelet會讀取該目錄下得網絡配置
--cni-conf-dir=/etc/cni/net.d \
#指定 kubedns 的 Service IP(能夠先分配,後續建立 kubedns 服務時指定該 IP),--cluster-domain 指定域名後綴,這兩個參數同時指定後纔會生效
--cluster-dns=10.68.0.2 \
...
kubelet.kubeconfig
kubelet依賴的一個配置,格式看也是咱們後面常常遇到的yaml格式,描述了kubelet訪問apiserver的方式
apiVersion: v1
clusters:
- cluster:
#跳過tls,便是kubernetes的認證
insecure-skip-tls-verify: true
#api-server地址
server:http://192.168.1.102:8080
...
10-calico.conf
calico做爲kubernets的CNI插件的配置
{ "name": "calico-k8s-network", "cniVersion": "0.1.0", "type": "calico", <!--etcd的url--> "etcd_endpoints": "http://192.168.1.102:2379", "logevel": "info", "ipam": { "type": "calico-ipam" }, "kubernetes": { < !--api-server的url--> "k8s_api_root": "http://192.168.1.102:8080" } }
到這裏最基礎的kubernetes集羣就能夠工做了。下面咱們就來試試看怎麼去操做,控制它。 咱們從最簡單的命令開始,嘗試一下kubernetes官方的入門教學:playground的內容。瞭解如何建立pod,deployments,以及查看他們的信息,深刻理解他們的關係。
#經常使用命令 237 kubectl version 238 kubectl get nodes 239 kubectl get --help 241 kubectl run kubernetes-bootcamp --image=jocatalin/kubernetes-bootcamp:v1 --port=8080 242 kubectl get deployments 243 kubectl get pods 244 kubectl get pods -o wide 245 docker ps 246 kubectl get deployments 248 kubectl delete deployments kubernetes-bootcamp 250 kubectl run kubernetes-bootcamp --image=jocatalin/kubernetes-bootcamp:v1 --port=8080 255 docker ps 256 journalctl -f 259 kubectl describe deploy kubernetes-bootcamp 260 kubectl proxy 262 kubectl scale deploy kubernetes-bootcamp --replicas=4 266 kubectl scale deploy kubernetes-bootcamp --replicas=2 269 kubectl describe deploy 272 kubectl set image deploy kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2 274 kubectl rollout status deploy kubernetes-bootcamp 277 kubectl rollout undo deploy kubernetes-bootcamp nginx-pod.yaml文件 apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 284 kubectl create -f ~/services/nginx-pod.yaml 285 curl http://localhost:8001/api/v1/proxy/namespaces/default/pods/nginx/ nginx-deployment.yaml apiVersion: apps/v1beta1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 2 template: metadata: labels: app: nignx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 323 kubectl create -f ~/services/nginx-deployment.yaml 324 kubectl get pods -l app=nginx 235 kubectl get deployment -n kube-system
每臺工做節點上都應該運行一個kube-proxy服務,它監聽API server中service和endpoint的變化狀況,並經過iptables等來爲服務配置負載均衡,是讓咱們的服務在集羣外能夠被訪問到的重要方式。
經過系統服務方式部署:
#確保工做目錄存在 $ mkdir -p /var/lib/kube-proxy #複製kube-proxy服務配置文件 $ cp target/worker-node/kube-proxy.service /lib/systemd/system/ #複製kube-proxy依賴的配置文件 $ cp target/worker-node/kube-proxy.kubeconfig /etc/kubernetes/ $ systemctl enable kube-proxy.service $ service kube-proxy start $ journalctl -f -u kube-proxy
kube-proxy.service
[Unit]
Description=Kubernetes Kube-Proxy Server ...
[Service]
#工做目錄
WorkingDirectory=/var/lib/kube-proxy
ExecStart=/home/michael/bin/kube-proxy \
#監聽地址
--bind-address=192.168.1.103 \
#依賴的配置文件,描述了kube-proxy如何訪問api-server
--kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig \
...
kube-proxy.kubeconfig配置了kube-proxy如何訪問api-server,內容與kubelet雷同,再也不贅述。
剛纔咱們在基礎集羣上演示了pod,deployments。下面就在剛纔的基礎上增長點service元素。
423 kubectl expose deploy kubernetes-bootcamp --type="NodePort" --target-port=8080 --port=80 424 kubectl get services 425 curl 10.0.94.182:39741 426 kubectl get pods -o wide 427 kubectl get services server01 # docker exec -it cc6aa3fc38a0 bash 1 curl 10.68.34.35 2 curl 172.20.60.133 428 vi ~/services/nginx-service.yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: ports: - port: 8080 targetPort: 80 nodePort: 20000 selector: app: nginx type: NodePort 429 kubectl create -f ~/services/nginx-service.yaml 430 kubectl get services 431 curl 10.0.94.182:20000
kube-dns爲Kubernetes集羣提供命名服務,主要用來解析集羣服務名和Pod的hostname。目的是讓pod能夠經過名字訪問到集羣內服務。它經過添加A記錄的方式實現名字和service的解析。普通的service會解析到service-ip。headless service會解析到pod列表。
經過kubernetes應用的方式部署kube-dns.yaml文件基本與官方一致(除了鏡像名不一樣外)。 裏面配置了多個組件,之間使用」---「分隔
#到kubernetes-starter目錄執行命令 $ kubectl create -f target/services/kube-dns.yaml
請直接參考配置文件中的註釋。
這了主要演示增長kube-dns後,經過名字訪問服務的原理和具體過程。演示啓動dns服務和未啓動dns服務的經過名字訪問狀況差異。