今回の記事では、Centos7サーバーで1からKubernetes環境を構築し、Ingressでの外部公開・TLSの設定まで行う手順についてまとめていきたいと思います。
今回は、本番環境を試すような設定をしたいと思っているため、CentOS7サーバー1台でマスターノードとワーカーので両方を稼働させるような構築をします。
#前提条件
- CentOS7のサーバー1台が稼働している。
- Route53にドメインの登録が完了している。
#Docker・Kubernetesの初期設定
システムアップデートを行う
# yum update
swapを無効にする
kubeletを正常に動作させるため、SWAPの無効化が必要になる。
# swapoff -a
SWAPの無効を永続化
# /dev/mapper/centos-swap swap swap defaults 0 0
Dockerのインストールと起動
# yum install yum-utils device-mapper-persistent-data lvm2
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# yum install docker-ce
# mkdir -m 644 /etc/docker
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
# systemctl enable docker && systemctl start docker
Kubernetesのインストールと起動
クラスター構築はkubeadmを使用。
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kube*
# yum install kubelet kubeadm --disableexcludes=kubernetes
# systemctl enable kubelet && systemctl start kubelet
Kubernetesに必要なポートを解放
# firewall-cmd --permanent --new-zone=k8s
# firewall-cmd --permanent --zone=k8s --add-port 6443/tcp
# firewall-cmd --permanent --zone=k8s --add-port 2379-2380/tcp
# firewall-cmd --permanent --zone=k8s --add-port 10250/tcp
# firewall-cmd --permanent --zone=k8s --add-port 10251/tcp
# firewall-cmd --permanent --zone=k8s --add-port 10252/tcp
# firewall-cmd --permanent --zone=k8s --add-port 30000-32767/tcp
# firewall-cmd --reload
Kubernetesクラスターの初期構築と設定
バージョン指定が間違っているとエラーが出るので、エラー内容に従って各環境でバージョン指定を行なってください。
# echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
# kubeadm init --pod-network-cidr=10.244.0.0/16 --kubernetes-version v1.22.2
# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo chown $(id -u):$(id -g) $HOME/.kube/config
(Kubernetesクラスターの初期構築と設定に失敗した場合)
エラーなどが出て失敗した場合は、resetしてやり直す。
# kubeadm reset
# echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables
# kubeadm init --pod-network-cidr=10.244.0.0/16 --kubernetes-version v1.22.2
# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo chown $(id -u):$(id -g) $HOME/.kube/config
flannelをインストールする
コンテナ間通信を行うために必要で、これがないとYAMLファイルを実行してもPod生成が< pending >で止まってしまう。
またコンテナ間通信には、bridgeネットワークcni0の接続を許可するfirewallの設定が必要。
# firewall-cmd --permanent --zone=trusted --change-interface=cni0
# firewall-cmd --reload
# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
1台でマスターノードとワーカーノードの両方の役割を持つ設定に変える
デフォルトではマスターノードとワーカーノードは別々のサーバーで動かす前提となっているため、今回の1台のサーバーで両方の役割を持つ設定に変える。
# kubectl taint nodes --all node-role.kubernetes.io/master-
テストでDeploymentのYAMLを実行
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.17
# kubectl apply -f deploy.yml
# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-db719865c-nnf24 1/1 Running 0 17s
nginx-deployment-db744865c-sklvc 1/1 Running 0 17s
#TLSの設定
Route53で設定したドメインについて、Let's EncryptのDNSの認証を行う。
Kubernetes上でTLSの設定を自動化できるcert-managerを使用。
cert-managerのインストール
Kubernetes上でTLS証明書の発行、更新、管理を自動化してくれる。
# kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.yaml
Route53にアクセス権を持つIAMを作成
クラスターからRoute53にリモートアクセスするため、IAMの作成をAWSであらかじめ行う。
公式の設定方法
IAMのシークレットアクセスキーをクラスター内に登録
Secretリソースをroute53-credentials-secretという名前で登録。
# kubectl -n cert-manager create secret generic route53-credentials-secret --from-literal=secret-access-key=<SECRET_ACCESS_KEY>
ClusterIssuerの作成
証明書を要求するためのClusterIssuer(クラスター全体で使えるIssuer)を作成。
severに関しては一旦テストで実行したのち、問題なければ本番で実行する。
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-issuer
spec:
acme:
# server: https://acme-v02.api.letsencrypt.org/directory #本番
server: https://acme-staging-v02.api.letsencrypt.org/directory #テスト
email: <Mail_Address>
privateKeySecretRef:
name: letsencrypt-issuer
solvers:
- selector:
dnsZones:
- "test.com" #Route53で設定しているドメイン名
dns01:
route53:
region: ap-northeast-1
accessKeyID: <ACCESS_KEY>
secretAccessKeySecretRef:
name: route53-credentials-secret #登録したSecretリソース
key: secret-access-key
# kubectl apply -f letsencrypte-issuer.yml
# kubectl describe clusterissuer
Status:
Acme:
Last Registered Email: <Mail_Address>
Uri: https://acme-v02.api.letsencrypt.org/acme/acct/xxxxxxxx
Conditions:
Last Transition Time: 2021-09-21T05:28:09Z
Message: The ACME account was registered with the ACME server
Reason: ACMEAccountRegistered
Status: True
Type: Ready
Events: <none>
Certificateの作成
証明書の作成を行う。
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: test-com
spec:
secretName: test-com-tls
duration: 2160h
renewBefore: 360h
organization:
- test
commonName: "*.test.com"
isCA: false
keySize: 2048
keyAlgorithm: rsa
keyEncoding: pkcs1
usages:
- server auth
- client auth
dnsNames:
- test.com
- "*.test.com"
issuerRef:
name: letsencrypt-issuer
kind: ClusterIssuer
# kubectl apply -f certificate.yml
しばらく経ったのち、成功すればtest-com-tlsが作成される。
# kubectl describe certificate -A
---
Normal Issued 30m cert-manager Certificate issued successfully
---
# kubectl describe secret test-com-tls
#Ingressの設定
設定したTLSとIngressリソースを使って、ドメイン名でTLSの外部公開を行う。
Nginx Ingress Controllerをインストール
Ingressを外部公開して使うためには、Nginx Ingress Controllerのインストールが必要。
# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/deploy.yaml
今回は外部のロードバランサーなどを使用しないため、以下を編集し追記する。
# kubectl edit service ingress-nginx-controller -n ingress-nginx
---
type: LoadBalancer
externalIPs:
- <SERVER_IP> #自身のサーバーのIPアドレス
---
テストでNGINXのトップページを表示
Deploymentに関しては、上記で記載したdeployment.ymlを使用。
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: ClusterIP
ports:
- port: 80
selector:
app: nginx
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/tls-acme: "true"
ingress.kubernetes.io/ssl-redirect: "false"
cert-manager.io/cluster-issuer: "letsencrypt-issuer"
spec:
tls:
- hosts:
- example.test.com #Route53で登録したAレコードのドメイン名
secretName: test-com-tls
rules:
- host: example.test.com #Route53で登録したAレコードのドメイン名
http:
paths:
- backend:
service:
name: nginx-service
port:
number: 80
path: /
pathType: Prefix
Hostで記載したURLのhttpsにアクセスし、Nginxのトップページがひらけば成功。
参考にさせていただいた記事のURL
https://qiita.com/shikigamix/items/3f3078cb4c9883554689
https://qiita.com/zembutsu/items/399774c5071050f07975
https://qiita.com/jlandowner/items/9f3c4c0a03d2ae3d2189
https://qiita.com/iqustechtips/items/1ec6b32a98b3fab427d6