Run kubernetes build from terraform - kubernetes

I'm trying to make a simple test to build a simple nginx on kubernetes from terraform.
This is the first time working terraform.
This is the basic terraform file:
provider "kubernetes" {
host = "https://xxx.xxx.xxx.xxx:8443"
client_certificate = "${file("~/.kube/master.server.crt")}"
client_key = "${file("~/.kube/master.server.key")}"
cluster_ca_certificate = "${file("~/.kube/ca.crt")}"
username = "xxxxxx"
password = "xxxxxx"
}
resource "kubernetes_service" "nginx" {
metadata {
name = "nginx-example"
}
spec {
selector {
App = "${kubernetes_pod.nginx.metadata.0.labels.App}"
}
port {
port = 80
target_port = 80
}
type = "LoadBalancer"
}
}
resource "kubernetes_pod" "nginx" {
metadata {
name = "nginx-example"
labels {
App = "nginx"
}
}
spec {
container {
image = "nginx:1.7.8"
name = "example"
port {
container_port = 80
}
}
}
}
I'm getting the following error after running the terraform apply.
Error: Error applying plan:
1 error(s) occurred:
kubernetes_pod.nginx: 1 error(s) occurred:
kubernetes_pod.nginx: the server has asked for the client to provide credentials (post pods)
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with any
resources that successfully completed. Please address the error above
and apply again to incrementally change your infrastructure.
I have admin permissions on kubernetes and everything is working correctly.
But for some reason I'm getting that error.
What I'm doing wrong?
Thanks
Regarding #matthew-l-daniel question
When I'm only using the username/password I get this error:
Error: Error applying plan:
1 error(s) occurred:
kubernetes_pod.nginx: 1 error(s) occurred:
kubernetes_pod.nginx: Post https://xxx.xxx.xxx.xxx:8443/api/v1/namespaces/default/pods:
x509: certificate signed by unknown authority
Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with any
resources that successfully completed. Please address the error above
and apply again to incrementally change your infrastructure.
I tried using the server name or the server ip and got the same error everytime.
When using the certs I got the error from the original post, regarding the "credentials"
I forgot to mention that this is an openshift installation. I don't believe it will have any impact in the end, but I thought I should mention it.

The solution was rather simple, I was using the master crt and key from openshift on terraform.
Then I tested it using the admin crt and key from openshift and it worked.

Aside from the official kubernetes provider documentation suggesting only certificate or basic (user/pass) should be required, this sounds like an OpenShift issue. Have you been able to obtain any logs from the OpenShift cluster?
Some searching links the message you are seeing to some instability bugs within Kubernetes wherein the kubelet does not properly register after a reboot. I would manually confirm the node shows as Ready in OpenShift before you attempt a deployment, as until this occurs Terraform will not be able to interact with it.
If in fact the node is not Ready, Terraform is just surfacing the underlying error passed back from OpenShift.
Separately, the error you are seeing when trying to authenticate using purely certificate parameters is indicative of a misconfiguration. A similar question was raised on the Kubernetes GitHub, and the suggestion there was to investigate the Certificate Authority loaded on to the cluster.

Related

Private docker.io registry in microk8s

I have issue with microk8s hitting rate limit for docker.io registry
ctr: failed to copy: httpReaderSeeker: failed open: unexpected status code https://registry-1.docker.io/v2/calico/kube-controllers/manifests/sha256:bf58609ff39089533b80ff2a10fffd1302346f153c66e24d0572fb8b198daea1: 429 Too Many Requests - Server message: toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
I wanted to configure private repository authorization for docker.io. I've followed following instruction
It looks like that it's not working with docker.io registry
I've modified configuration file
/var/snap/microk8s/current/args/containerd-template.toml
with following content
[plugins."io.containerd.grpc.v1.cri".registry]
# 'plugins."io.containerd.grpc.v1.cri".registry.mirrors' are namespace to mirror mapping for all namespaces.
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = ["https://registry-1.docker.io", ]
[plugins."io.containerd.grpc.v1.cri".registry.configs]
[plugins."io.containerd.grpc.v1.cri".registry.configs."docker.io".auth]
username = ""
password = ""
auth = ""
email = ""
However it looks like this is not working for docker.io registry
I'm aware of this solution, however if I recall correctly this needs to be applied to every namespace separately. I'm looking for a one-shot solution for whole kubernetes cluster.
Is there such solution, or kubernetes secrets are the only way to go ?

unable to access a service from another pod, using xmlhttprequest object

So, I wrote an API that is listening on the the path /api/v1/books and is deployed as a deployment on my k8s cluster, created service (restapi-service) so that we can call that from another pods.
Now I created another deployment (restapi-ui-deployment) that just has a .html page and and its being deployed on nginx, which eventually calls the the service that we have created earlier to get the response.
Now, the issue is when I exec into the pods of restapi-ui-deployment I am successfully able to curl http://restapi-service:8081/api/v1/books. But if we are trying to do the same thing from .html page that is deployed I get
GET http://restapi-service:8081/api/v1/books net::ERR_NAME_NOT_RESOLVED
Below is the code that is being deployed as restapi-ui-deployment
if (xmlObj != null){
xmlObj.open("GET", "http://restapi-service:8081/api/v1/books", true)
xmlObj.onreadystatechange = processResponse;
xmlObj.send(null)
}
else{
console.log("There was an error getting the object.")
}
function processResponse(){
if (xmlObj.status == 200 && xmlObj.readyState == 4){
console.log("Got the response successfully")
response = xmlObj.responseText
}
else{
console.log("There was an issue getting the response.")
}
}
I am afraid that you are confused about the way your application works. The XmlHttpRequest is originating in a webbrowser, therefore outside of the kubernetes cluster, not from nginx inside your cluster. (nginx serves the html page)
The kubernetes dns is not available outside of kubernetes, nor would a connection to a ClusterIP work from the outside.
Solution: Create an appropriate Ingress and call that from your frontend or provide a proxy on your nginx where you got the frontend delivered. (That would lead to really getting the request origin as your nginx)

Terraform with Google Container Engine (Kubernetes): Error executing access token command "...\gcloud.cmd"

I'm trying to deploy some module (Docker image) to google Google Container Engine. What I got in my Terraformconfig file:
terraform.tf
# Google Cloud provider
provider "google" {
credentials = "${file("google_credentials.json")}"
project = "${var.google_project_id}"
region = "${var.google_region}"
}
# Google Container Engine (Kubernetes) cluster resource
resource "google_container_cluster" "secureskye" {
name = "secureskye"
zone = "${var.google_kubernetes_zone}"
additional_zones = "${var.google_kubernetes_additional_zones}"
initial_node_count = 2
}
# Kubernetes provider
provider "kubernetes" {
host = "${google_container_cluster.secureskye.endpoint}"
username = "${var.google_kubernetes_username}"
password = "${var.google_kubernetes_password}"
client_certificate = "${base64decode(google_container_cluster.secureskye.master_auth.0.client_certificate)}"
client_key = "${base64decode(google_container_cluster.secureskye.master_auth.0.client_key)}"
cluster_ca_certificate = "${base64decode(google_container_cluster.secureskye.master_auth.0.cluster_ca_certificate)}"
}
# Module UI
module "ui" {
source = "./modules/ui"
}
My problem is: google_container_cluster was created successfully, but it fails on module ui creation (which contains 2 resource kubernetes_service and kubernetes_pod) with error
* kubernetes_pod.ui: Post https://<ip>/api/v1/namespaces/default/pods: error executing access token command "<user_path>\\AppData\\Local\\Google\\Cloud SDK\\google-cloud-sdk\\bin\\gcloud.cmd config config-helper --format=json": err=exec: "<user_path>\\AppData\\Local\\Google\\Cloud SDK\\google-cloud-sdk\\bin\\gcloud.cmd": file does not exist output=
So, questions:
1. Do I need gcloud + kubectl installed? Even though google_container_cluster was created successfully before I install gcloud or kubectl installed.
2. I want to use independent, separated credentials info, project, region from the one in gcloud, kubectl CLI. Am I doing this right?
I have been able to reproduce your scenario running the Terraform config file you provided (except the Module UI part), in a Linux machine, so your issue should be related to that last part of the code.
Regarding your questions:
I am not sure, because I tried from Google Cloud Shell, and both gcloud and kubectl are already preinstalled there, although I would recommend you to install them just to make sure that is not the issue here.
For the credentials part, I added two new variables to the variables.tf Terraform configuration file, as in this example (those credentials do not need to be the sames as in gcloud or kubectl:
Use your prefered credentials in this case.
variable "google_kubernetes_username" {
default = "<YOUR_USERNAME>"
}
variable "google_kubernetes_password" {
default = "<YOUR_PASSWORD>"
}
Maybe you could share more information regarding what can be found in your Module UI, in order to understand which file does not exist. I guess you are trying the deployment from a Windows machine, as for the notation in the paths to your files, but that should not be an important issue.

Issue connecting composer to Blockchain on Bluemix - identity or token does not match

I have fabric composer 0.72 installed on my mac, and I was able to follow this thread to get it connected to my Blockchain (v.61 of Fabric) on Bluemix.
fabric-composer-integration-with-bluemix-blockchain-service
Now I am trying to build an ubuntu (16.04) docker container and run composer-rest-server there. When I try to connect to my blockchain service from my docker container (using the same id, WebAppAdmin, that I used on my mac) I get an error:
Discovering types from business network definition ...
Connection fails: Error: Identity or token does not match.
It will be retried for the next request.
{ Error: Identity or token does not match.
at /home/composer/.nvm/versions/node/v6.10.3/lib/node_modules /composer-rest-server/node_modules/grpc/src/node/src/client.js:417:17 code: 2, metadata: Metadata { _internal_repr: {} } }
I tried copying the cert from my mac to my docker container:
/home/composer/.composer-credentials/member.WebAppAdmin
but when I did that I got a different error that says "signature does not verify". I did some additional testing, and I discovered that if I used an id that I had not previously used with composer (i.e. user_type1_0) then I could connect, and I could see a new cert in my .composer-credentials directory.
I tried deleting that container and building a new one (I dorked something else up) I could not use that same userid again.
Does anybody know how security and these certs are supposed to work? It would seem as though something to do with certificate generation/validation is tied to the client (i.e. hardware address), such that if I try to re-use an id on a different machine, the certs or keys or something don't match. I have a way to make things work, but it doesn't seem like it's the right way if I can't use the same id from different machines.
Thanks!
Hi i tried to recreate this by having blockchain running on a unix machine and then i copied my connection profile and certificate to my mac and then edited my connection profile to update the ip address and key store. I then did a composer network ping and it worked fine.
I am using composer v0.7.4 so you could try that?
I have also faced this issue, and concluded that
There is inconsistent behavior while deploying network using composer on Cloud environment includeing Bluemix. Problem is not with composer, but with fabric 0.6.
I am assuming that this issue is also indirectly related to following known bugs into fabric 0.6, which will not be fixed in fabric 0.6.
ERROR:
"
throw er; // Unhandled 'error' event
^
Error
at ClientDuplexStream._emitStatusIfDone (/home/ubuntu/.nvm/versions/node/v6.9.5/lib/node_modules/composer-cli/node_modules/grpc/src/node/src/client.js:189:19)
at ClientDuplexStream._readsDone (/home/ubuntu/.nvm/versions/node/v6.9.5/lib/node_modules/composer-cli/node_modules/grpc/src/node/src/client.js:158:8)
at readCallback (/home/ubuntu/.nvm/versions/node/v6.9.5/lib/node_modules/composer-cli/node_modules/grpc/src/node/src/client.js:217:12)
"
So far, We have understood that following three JIRA are root cause , where essentially the cloud networking layer ends up killing the idle event hub connection after a period of inactivity and the fabric SDK cannot handle this.
https://jira.hyperledger.org/browse/FAB-4002 FAB-3310
https://jira.hyperledger.org/browse/FAB-3310
or FAB-2787
Conclusion:
There is no alternative way of fixing this issue with Bluemix or any cloud environment with fabric 0.6
You may not experience this issue with Fabric 1.0, but there is still possibilities as all above mentioned defects are not fixed yet.

SQLDB status code 500

I received a FAILED Server error, status code: 500, error code: 10001,
message: Service broker error : {"description"=>"Service Broker provisioned at this url state is not operational 10002"} message, when trying to create a new SQLDB service instance.
What is the issue?
I was able to confirm that there was a brief issue earlier with the "Free" plan but it has since been resolved.
I was able to create a service successfully from the CF command line:
$ cf create-service sqldb sqldb_free randalstTestSQLDB515
Creating service randalstTestSQLDB515 in org johndoe#myemail.com /
space dev as johndoe#myemail.com...
OK
Try to create the service from the command line using the following syntax:
$ cf create-service sqldb sqldb_small mySQLDB
where
The first attribute sqldb is the service name.
The second attribute is the plan, either sqldb_small, sqldb_free, or sqldb_premium.
The last attribute mySQLDB is the unique name that you are giving to this service instance.