Inicializando Controllers
Neste laboratório, você inicializará o control plane do Kubernetes nas instâncias dos controllers e que será configurará para alta disponibilidade. Você também criará um balanceador de carga externo que expõe os servidores da API Kubernetes a clientes remotos. Os seguintes componentes serão instalados em cada nó: Kubernetes API Server, Scheduler e Controller Manager.
Atenção: Caso ainda tenha as 3 janelas de shell conectadas ssh nos controllers não precisa executar o passo Pre-Requisitos
Pre Requisitos
for instance in controller-0 controller-1 controller-2; do external_ip=$(aws ec2 describe-instances --filters \ "Name=tag:Name,Values=${instance}" \ "Name=instance-state-name,Values=running" \ --output text --query 'Reservations[].Instances[].PublicIpAddress') echo ssh -i kubernetes.id_rsa ubuntu@$external_ip done
Em cada janela ssh execute os comandos abaixo
Provisionando o Control Plane
sudo mkdir -p /etc/kubernetes/config wget -q --show-progress --https-only --timestamping \ "https://storage.googleapis.com/kubernetes-release/release/v1.18.6/bin/linux/amd64/kube-apiserver" \ "https://storage.googleapis.com/kubernetes-release/release/v1.18.6/bin/linux/amd64/kube-controller-manager" \ "https://storage.googleapis.com/kubernetes-release/release/v1.18.6/bin/linux/amd64/kube-scheduler" \ "https://storage.googleapis.com/kubernetes-release/release/v1.18.6/bin/linux/amd64/kubectl" chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/
Configurando API Server
O endereço IP interno da instância será usado para informar o API Server os membros do cluster
sudo mkdir -p /var/lib/kubernetes/ sudo mv ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \ service-account-key.pem service-account.pem \ encryption-config.yaml /var/lib/kubernetes/ INTERNAL_IP=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4) echo "$INTERNAL_IP" cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service [Unit] Description=Kubernetes API Server Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-apiserver \\ --advertise-address=${INTERNAL_IP} \\ --allow-privileged=true \\ --apiserver-count=3 \\ --audit-log-maxage=30 \\ --audit-log-maxbackup=3 \\ --audit-log-maxsize=100 \\ --audit-log-path=/var/log/audit.log \\ --authorization-mode=Node,RBAC \\ --bind-address=0.0.0.0 \\ --client-ca-file=/var/lib/kubernetes/ca.pem \\ --enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\ --etcd-cafile=/var/lib/kubernetes/ca.pem \\ --etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\ --etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\ --etcd-servers=https://10.0.1.10:2379,https://10.0.1.11:2379,https://10.0.1.12:2379 \\ --event-ttl=1h \\ --encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\ --kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\ --kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\ --kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\ --kubelet-https=true \\ --runtime-config='api/all=true' \\ --service-account-key-file=/var/lib/kubernetes/service-account.pem \\ --service-cluster-ip-range=10.32.0.0/24 \\ --service-node-port-range=30000-32767 \\ --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\ --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF cat /etc/systemd/system/kube-apiserver.service
Configurando o Controller Manager
sudo mv kube-controller-manager.kubeconfig /var/lib/kubernetes/ cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service [Unit] Description=Kubernetes Controller Manager Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-controller-manager \\ --bind-address=0.0.0.0 \\ --cluster-cidr=10.200.0.0/16 \\ --cluster-name=kubernetes \\ --cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \\ --cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \\ --kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\ --leader-elect=true \\ --root-ca-file=/var/lib/kubernetes/ca.pem \\ --service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \\ --service-cluster-ip-range=10.32.0.0/24 \\ --use-service-account-credentials=true \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF cat /etc/systemd/system/kube-controller-manager.service
Configurando o Scheduler
sudo mkdir -p /etc/kubernetes/config/ sudo mv kube-scheduler.kubeconfig /var/lib/kubernetes/ cat <<EOF | sudo tee /etc/kubernetes/config/kube-scheduler.yaml apiVersion: kubescheduler.config.k8s.io/v1alpha1 kind: KubeSchedulerConfiguration clientConnection: kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig" leaderElection: leaderElect: true EOF cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service [Unit] Description=Kubernetes Scheduler Documentation=https://github.com/kubernetes/kubernetes [Service] ExecStart=/usr/local/bin/kube-scheduler \\ --config=/etc/kubernetes/config/kube-scheduler.yaml \\ --v=2 Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF
Iniciando o serviço de Controller
sudo systemctl daemon-reload sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler
Atenção: Aguarde um minuto para o serviço subir
Testando o serviço
kubectl get componentstatuses
Resultado Esperado
NAME STATUS MESSAGE ERROR controller-manager Healthy ok scheduler Healthy ok etcd-0 Healthy {"health":"true"} etcd-2 Healthy {"health":"true"} etcd-1 Healthy {"health":"true"}
Se o resultado for o mesmo, os Controladores estão funcionando
Criando as regras RBAC para o Kubelet
Vamos configur as permissões RBAC para permitir que o servidor da API Kubernetes acesse a API Kubelet em cada nó de trabalho. O acesso à API Kubelet é necessário para recuperar métricas, registros e executar comandos em pods.
definiremos o Kubelet --authorization-mode como Webhook. O modo Webhook usa a API SubjectAccessReview para determinar a autorização.
O comando abaixo afetará todo o cluster e só precisam ser executados uma vez a partir de um controller.
external_ip=$(aws ec2 describe-instances --filters \ "Name=tag:Name,Values=controller-0" \ "Name=instance-state-name,Values=running" \ --output text --query 'Reservations[].Instances[].PublicIpAddress') echo "$external_ip" ssh -i kubernetes.id_rsa ubuntu@${external_ip}
Aplicaremos as permissões para acessar a API Kubelet e realizar as tarefas mais comuns associadas ao gerenciamento de pods:
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f - apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:kube-apiserver-to-kubelet rules: - apiGroups: - "" resources: - nodes/proxy - nodes/stats - nodes/log - nodes/spec - nodes/metrics verbs: - "*" EOF
O servidor da API do Kubernetes se autentica no Kubelet como o usuário do kubernetes usando o certificado do cliente, conforme definido pela sinalização --kubelet-client-certificate.
Vincularemos o sistema: kube-apiserver-to-kubelet ClusterRole ao usuário kubernetes
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f - apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: system:kube-apiserver namespace: "" roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:kube-apiserver-to-kubelet subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: kubernetes EOF exit
Verificação do Cluster
Atenção: Feche as janelas dos controllers e permaneça apenas com a janela da sua máquina O comando abaixo deverá ser executado na sua máquina local, na mesma sessão usada até agora, pois vamos precisar do endereço do balanceador de carga do kubernetes-the-hard-way:
KUBERNETES_PUBLIC_ADDRESS=$(aws elbv2 describe-load-balancers \ --load-balancer-arns ${LOAD_BALANCER_ARN} \ --output text --query 'LoadBalancers[].DNSName') echo "$KUBERNETES_PUBLIC_ADDRESS" curl -k --cacert ca.pem https://${KUBERNETES_PUBLIC_ADDRESS}/version
Resultado Esperado
{ "major": "1", "minor": "18", "gitVersion": "v1.18.6", "gitCommit": "dff82dc0de47299ab66c83c626e08b245ab19037", "gitTreeState": "clean", "buildDate": "20210-237-22T23:51:04Z", "goVersion": "go1.13.9", "compiler": "gc", "platform": "linux/amd64" }